From c4e1ef0644ca296c02c220c5cb7d8c59ee73e7a4 Mon Sep 17 00:00:00 2001 From: HDAnzo Date: Tue, 15 Nov 2022 10:40:36 -0300 Subject: [PATCH 1/2] Add box component Add box component documentation Refactor with-scale file --- components/box/__tests__/index.test.tsx | 51 ++++++++++++ components/box/box.tsx | 102 ++++++++++++++++++++++++ components/box/index.ts | 4 + components/index.ts | 3 + components/use-scale/utils.ts | 28 ++++++- components/use-scale/with-scale.tsx | 59 ++++---------- pages/en-us/components/box.mdx | 55 +++++++++++++ 7 files changed, 259 insertions(+), 43 deletions(-) create mode 100644 components/box/__tests__/index.test.tsx create mode 100644 components/box/box.tsx create mode 100644 components/box/index.ts create mode 100644 pages/en-us/components/box.mdx diff --git a/components/box/__tests__/index.test.tsx b/components/box/__tests__/index.test.tsx new file mode 100644 index 000000000..8a3129e82 --- /dev/null +++ b/components/box/__tests__/index.test.tsx @@ -0,0 +1,51 @@ +import React from 'react' +import {mount} from 'enzyme' +import {Box} from 'components' + +describe('Button', () => { + it('should render correctly', () => { + const wrapper = mount(Box) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('should render as the provided element', async () => { + const wrapper = mount(Box) + + expect(wrapper.exists('a[href="https://geist.com"]')).toBe(true) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('should render with provided styles', async () => { + document.body.innerHTML = '
'; + const wrapper = mount(Box, { + attachTo: document.querySelector('#root') as HTMLDivElement + }) + + expect(wrapper.find('div').getDOMNode()).toHaveStyle({ + display: 'block', + lineHeight: '100px', + fontSize: 'calc(1 * 16px)', + width: '300px', + height: '100px', + margin: '2rem 0px 2rem 0px', + visibility: 'visible', + padding: '0px 2rem 0px 2rem' + }) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('filter out scale related props', () => { + const wrapper = mount(Box) + + expect(wrapper.exists('div')).toBe(true) + expect(wrapper.getDOMNode().hasAttribute('px')).toBe(false) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('should forward the provided ref', () => { + const ref = React.createRef() + const wrapper = mount(Box) + expect(wrapper.find('div').getDOMNode()).toEqual(ref.current) + expect(() => wrapper.unmount()).not.toThrow() + }) +}) diff --git a/components/box/box.tsx b/components/box/box.tsx new file mode 100644 index 000000000..3504b4863 --- /dev/null +++ b/components/box/box.tsx @@ -0,0 +1,102 @@ +import React from 'react' +import {DynamicScales, makeScaleHandler, ScaleProps} from "../use-scale"; +import useClasses from "../use-classes"; +import useTheme from "../use-theme"; + +type PropsOf> = + JSX.LibraryManagedAttributes>; + +export interface BoxOwnProps { + as?: E; +} + +export type BoxProps = BoxOwnProps & + Omit, keyof BoxOwnProps> & ScaleProps; + +const defaultElement = 'div'; + +export type BoxComponent = ( + props: BoxProps, +) => React.ReactElement | null + +export const Box: BoxComponent = React.forwardRef( + + ({as, children, className, ...restProps}: BoxProps, ref: typeof restProps.ref | null) => { + const Element = as || defaultElement; + const {layout} = useTheme() + const { + paddingLeft, + pl, + paddingRight, + pr, + paddingTop, + pt, + paddingBottom, + pb, + marginTop, + mt, + marginRight, + mr, + marginBottom, + mb, + marginLeft, + ml, + px, + py, + mx, + my, + width, + height, + font, + w, + h, + margin, + padding, + unit = layout.unit, + scale = 1, + ...innerProps + } = restProps + + const SCALES: DynamicScales = { + pt: makeScaleHandler(paddingTop ?? pt ?? py ?? padding, scale, unit), + pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding, scale, unit), + pb: makeScaleHandler(paddingBottom ?? pb ?? py ?? padding, scale, unit), + pl: makeScaleHandler(paddingLeft ?? pl ?? px ?? padding, scale, unit), + px: makeScaleHandler(px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding, scale, unit), + py: makeScaleHandler(py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding, scale, unit), + mt: makeScaleHandler(marginTop ?? mt ?? my ?? margin, scale, unit), + mr: makeScaleHandler(marginRight ?? mr ?? mx ?? margin, scale, unit), + mb: makeScaleHandler(marginBottom ?? mb ?? my ?? margin, scale, unit), + ml: makeScaleHandler(marginLeft ?? ml ?? mx ?? margin, scale, unit), + mx: makeScaleHandler(mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin, scale, unit), + my: makeScaleHandler(my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin, scale, unit), + width: makeScaleHandler(width ?? w, scale, unit), + height: makeScaleHandler(height ?? h, scale, unit), + font: makeScaleHandler(font, scale, unit), + } + + return ( + + {children} + + + ); + }, +); + +// Box.displayName = 'GeistBox' + +export default Box diff --git a/components/box/index.ts b/components/box/index.ts new file mode 100644 index 000000000..5a21c2fa6 --- /dev/null +++ b/components/box/index.ts @@ -0,0 +1,4 @@ +import Box from './box' + +export type { BoxProps } from './box' +export default Box \ No newline at end of file diff --git a/components/index.ts b/components/index.ts index 8e69423d0..b3fe2b185 100644 --- a/components/index.ts +++ b/components/index.ts @@ -10,6 +10,9 @@ export type { AvatarProps, AvatarGroupProps } from './avatar' export { default as Badge } from './badge' export type { BadgeProps, BadgeAnchorProps } from './badge' +export {default as Box} from './box' +export type {BoxProps} from './box' + export { default as Breadcrumbs } from './breadcrumbs' export type { BreadcrumbsProps, diff --git a/components/use-scale/utils.ts b/components/use-scale/utils.ts index ef5f8ba55..8f40ffc2a 100644 --- a/components/use-scale/utils.ts +++ b/components/use-scale/utils.ts @@ -2,8 +2,9 @@ import { GetAllScalePropsFunction, GetScalePropsFunction, ScaleProps, - ScalePropKeys, + ScalePropKeys, DynamicLayoutPipe, } from './scale-context' +import {isCSSNumberValue} from "../utils/collections"; export const generateGetScaleProps =

( props: P & ScaleProps, @@ -37,3 +38,28 @@ export const generateGetAllScaleProps =

( } return getAllScaleProps } + +export const reduceScaleCoefficient = (scale: number) => { + if (scale === 1) return scale + const diff = Math.abs((scale - 1) / 2) + return scale > 1 ? 1 + diff : 1 - diff +} + +export const makeScaleHandler = + (attrValue: string | number | undefined, scale: number, unit: string): DynamicLayoutPipe => + (scale1x, defaultValue) => { + // 0 means disable scale and the default value is 0 + if (scale1x === 0) { + scale1x = 1 + defaultValue = defaultValue || 0 + } + const factor = reduceScaleCoefficient(scale) * scale1x + if (typeof attrValue === 'undefined') { + if (typeof defaultValue !== 'undefined') return `${defaultValue}` + return `calc(${factor} * ${unit})` + } + + if (!isCSSNumberValue(attrValue)) return `${attrValue}` + const customFactor = factor * Number(attrValue) + return `calc(${customFactor} * ${unit})` + } diff --git a/components/use-scale/with-scale.tsx b/components/use-scale/with-scale.tsx index 0d7ad21d2..933b3c109 100644 --- a/components/use-scale/with-scale.tsx +++ b/components/use-scale/with-scale.tsx @@ -1,14 +1,7 @@ import React, { forwardRef } from 'react' -import { DynamicLayoutPipe, ScaleConfig, ScaleContext, ScaleProps } from './scale-context' +import { ScaleConfig, ScaleContext, ScaleProps } from './scale-context' import useTheme from '../use-theme' -import { isCSSNumberValue } from '../utils/collections' -import { generateGetAllScaleProps, generateGetScaleProps } from './utils' - -const reduceScaleCoefficient = (scale: number) => { - if (scale === 1) return scale - const diff = Math.abs((scale - 1) / 2) - return scale > 1 ? 1 + diff : 1 - diff -} +import {generateGetAllScaleProps, generateGetScaleProps, makeScaleHandler} from './utils' const withScale = ( Render: React.ComponentType

}>, @@ -47,43 +40,25 @@ const withScale = ( scale = 1, ...innerProps } = props - const makeScaleHandler = - (attrValue: string | number | undefined): DynamicLayoutPipe => - (scale1x, defaultValue) => { - // 0 means disable scale and the default value is 0 - if (scale1x === 0) { - scale1x = 1 - defaultValue = defaultValue || 0 - } - const factor = reduceScaleCoefficient(scale) * scale1x - if (typeof attrValue === 'undefined') { - if (typeof defaultValue !== 'undefined') return `${defaultValue}` - return `calc(${factor} * ${unit})` - } - - if (!isCSSNumberValue(attrValue)) return `${attrValue}` - const customFactor = factor * Number(attrValue) - return `calc(${customFactor} * ${unit})` - } const value: ScaleConfig = { unit: unit, SCALES: { - pt: makeScaleHandler(paddingTop ?? pt ?? py ?? padding), - pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding), - pb: makeScaleHandler(paddingBottom ?? pb ?? py ?? padding), - pl: makeScaleHandler(paddingLeft ?? pl ?? px ?? padding), - px: makeScaleHandler(px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding), - py: makeScaleHandler(py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding), - mt: makeScaleHandler(marginTop ?? mt ?? my ?? margin), - mr: makeScaleHandler(marginRight ?? mr ?? mx ?? margin), - mb: makeScaleHandler(marginBottom ?? mb ?? my ?? margin), - ml: makeScaleHandler(marginLeft ?? ml ?? mx ?? margin), - mx: makeScaleHandler(mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin), - my: makeScaleHandler(my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin), - width: makeScaleHandler(width ?? w), - height: makeScaleHandler(height ?? h), - font: makeScaleHandler(font), + pt: makeScaleHandler(paddingTop ?? pt ?? py ?? padding, scale, unit), + pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding, scale, unit), + pb: makeScaleHandler(paddingBottom ?? pb ?? py ?? padding, scale, unit), + pl: makeScaleHandler(paddingLeft ?? pl ?? px ?? padding, scale, unit), + px: makeScaleHandler(px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding, scale, unit), + py: makeScaleHandler(py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding, scale, unit), + mt: makeScaleHandler(marginTop ?? mt ?? my ?? margin, scale, unit), + mr: makeScaleHandler(marginRight ?? mr ?? mx ?? margin, scale, unit), + mb: makeScaleHandler(marginBottom ?? mb ?? my ?? margin, scale, unit), + ml: makeScaleHandler(marginLeft ?? ml ?? mx ?? margin, scale, unit), + mx: makeScaleHandler(mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin, scale, unit), + my: makeScaleHandler(my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin, scale, unit), + width: makeScaleHandler(width ?? w, scale, unit), + height: makeScaleHandler(height ?? h, scale, unit), + font: makeScaleHandler(font, scale, unit), }, getScaleProps: generateGetScaleProps(props), getAllScaleProps: generateGetAllScaleProps(props), diff --git a/pages/en-us/components/box.mdx b/pages/en-us/components/box.mdx new file mode 100644 index 000000000..44b64d8b9 --- /dev/null +++ b/pages/en-us/components/box.mdx @@ -0,0 +1,55 @@ +import { Box } from 'components' +import { Layout, Playground, Attributes } from 'lib/components' + +export const meta = { + title: 'Box', + group: 'Layout', +} + +## Box + +Polymorphic scalable component. + + + Hello + +`} +/> + + + I am an anchor tag + +`} +/> + + + I am scalable + +`} +/> + + +Box.Props + +| Attribute | Description | Type | Accepted values | Default | +| --------------- | ---------------------------------- | --------------------------------- | --------------------------- | --------- | +| **as** | render mode | `React.ElementType` | `'span', 'p', 'form', ...` | `div` | +| ... | scale props | `ScaleProps` | `'width', 'px', 'font', ...`| - | +| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - | + + + +export default ({ children }) => {children} From e4a4d6b0eccaf03dda606e260a1bec58770c0b8c Mon Sep 17 00:00:00 2001 From: HDAnzo Date: Fri, 18 Nov 2022 09:22:15 -0300 Subject: [PATCH 2/2] Modify BoxComponent type to support displayName Apply formatting rules --- components/box/__tests__/index.test.tsx | 101 +++++++------ components/box/box.tsx | 186 +++++++++++++----------- components/box/index.ts | 2 +- components/index.ts | 4 +- components/use-scale/utils.ts | 41 +++--- components/use-scale/with-scale.tsx | 30 +++- pages/en-us/components/box.mdx | 10 +- 7 files changed, 213 insertions(+), 161 deletions(-) diff --git a/components/box/__tests__/index.test.tsx b/components/box/__tests__/index.test.tsx index 8a3129e82..c84403e27 100644 --- a/components/box/__tests__/index.test.tsx +++ b/components/box/__tests__/index.test.tsx @@ -1,51 +1,60 @@ import React from 'react' -import {mount} from 'enzyme' -import {Box} from 'components' +import { mount } from 'enzyme' +import { Box } from 'components' describe('Button', () => { - it('should render correctly', () => { - const wrapper = mount(Box) - expect(() => wrapper.unmount()).not.toThrow() - }) - - it('should render as the provided element', async () => { - const wrapper = mount(Box) - - expect(wrapper.exists('a[href="https://geist.com"]')).toBe(true) - expect(() => wrapper.unmount()).not.toThrow() - }) - - it('should render with provided styles', async () => { - document.body.innerHTML = '

'; - const wrapper = mount(Box, { - attachTo: document.querySelector('#root') as HTMLDivElement - }) - - expect(wrapper.find('div').getDOMNode()).toHaveStyle({ - display: 'block', - lineHeight: '100px', - fontSize: 'calc(1 * 16px)', - width: '300px', - height: '100px', - margin: '2rem 0px 2rem 0px', - visibility: 'visible', - padding: '0px 2rem 0px 2rem' - }) - expect(() => wrapper.unmount()).not.toThrow() - }) - - it('filter out scale related props', () => { - const wrapper = mount(Box) - - expect(wrapper.exists('div')).toBe(true) - expect(wrapper.getDOMNode().hasAttribute('px')).toBe(false) - expect(() => wrapper.unmount()).not.toThrow() - }) - - it('should forward the provided ref', () => { - const ref = React.createRef() - const wrapper = mount(Box) - expect(wrapper.find('div').getDOMNode()).toEqual(ref.current) - expect(() => wrapper.unmount()).not.toThrow() + it('should render correctly', () => { + const wrapper = mount(Box) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('should render as the provided element', async () => { + const wrapper = mount( + + Box + , + ) + + expect(wrapper.exists('a[href="https://geist.com"]')).toBe(true) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('should render with provided styles', async () => { + document.body.innerHTML = '
' + const wrapper = mount( + + Box + , + { + attachTo: document.querySelector('#root') as HTMLDivElement, + }, + ) + + expect(wrapper.find('div').getDOMNode()).toHaveStyle({ + display: 'block', + lineHeight: '100px', + fontSize: 'calc(1 * 16px)', + width: '300px', + height: '100px', + margin: '2rem 0px 2rem 0px', + visibility: 'visible', + padding: '0px 2rem 0px 2rem', }) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('filter out scale related props', () => { + const wrapper = mount(Box) + + expect(wrapper.exists('div')).toBe(true) + expect(wrapper.getDOMNode().hasAttribute('px')).toBe(false) + expect(() => wrapper.unmount()).not.toThrow() + }) + + it('should forward the provided ref', () => { + const ref = React.createRef() + const wrapper = mount(Box) + expect(wrapper.find('div').getDOMNode()).toEqual(ref.current) + expect(() => wrapper.unmount()).not.toThrow() + }) }) diff --git a/components/box/box.tsx b/components/box/box.tsx index 3504b4863..17126155a 100644 --- a/components/box/box.tsx +++ b/components/box/box.tsx @@ -1,102 +1,120 @@ import React from 'react' -import {DynamicScales, makeScaleHandler, ScaleProps} from "../use-scale"; -import useClasses from "../use-classes"; -import useTheme from "../use-theme"; +import { DynamicScales, makeScaleHandler, ScaleProps } from '../use-scale' +import useClasses from '../use-classes' +import useTheme from '../use-theme' type PropsOf> = - JSX.LibraryManagedAttributes>; + JSX.LibraryManagedAttributes> export interface BoxOwnProps { - as?: E; + as?: E } export type BoxProps = BoxOwnProps & - Omit, keyof BoxOwnProps> & ScaleProps; + Omit, keyof (BoxOwnProps & ScaleProps)> & + ScaleProps -const defaultElement = 'div'; +const defaultElement = 'div' -export type BoxComponent = ( +export type BoxComponent = { + ( props: BoxProps, -) => React.ReactElement | null + ): React.ReactElement | null + displayName?: string +} export const Box: BoxComponent = React.forwardRef( - - ({as, children, className, ...restProps}: BoxProps, ref: typeof restProps.ref | null) => { - const Element = as || defaultElement; - const {layout} = useTheme() - const { - paddingLeft, - pl, - paddingRight, - pr, - paddingTop, - pt, - paddingBottom, - pb, - marginTop, - mt, - marginRight, - mr, - marginBottom, - mb, - marginLeft, - ml, - px, - py, - mx, - my, - width, - height, - font, - w, - h, - margin, - padding, - unit = layout.unit, - scale = 1, - ...innerProps - } = restProps + ( + { as, children, className, ...restProps }: BoxProps, + ref: typeof restProps.ref | null, + ) => { + const Element = as || defaultElement + const { layout } = useTheme() + const { + paddingLeft, + pl, + paddingRight, + pr, + paddingTop, + pt, + paddingBottom, + pb, + marginTop, + mt, + marginRight, + mr, + marginBottom, + mb, + marginLeft, + ml, + px, + py, + mx, + my, + width, + height, + font, + w, + h, + margin, + padding, + unit = layout.unit, + scale = 1, + ...innerProps + } = restProps - const SCALES: DynamicScales = { - pt: makeScaleHandler(paddingTop ?? pt ?? py ?? padding, scale, unit), - pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding, scale, unit), - pb: makeScaleHandler(paddingBottom ?? pb ?? py ?? padding, scale, unit), - pl: makeScaleHandler(paddingLeft ?? pl ?? px ?? padding, scale, unit), - px: makeScaleHandler(px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding, scale, unit), - py: makeScaleHandler(py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding, scale, unit), - mt: makeScaleHandler(marginTop ?? mt ?? my ?? margin, scale, unit), - mr: makeScaleHandler(marginRight ?? mr ?? mx ?? margin, scale, unit), - mb: makeScaleHandler(marginBottom ?? mb ?? my ?? margin, scale, unit), - ml: makeScaleHandler(marginLeft ?? ml ?? mx ?? margin, scale, unit), - mx: makeScaleHandler(mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin, scale, unit), - my: makeScaleHandler(my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin, scale, unit), - width: makeScaleHandler(width ?? w, scale, unit), - height: makeScaleHandler(height ?? h, scale, unit), - font: makeScaleHandler(font, scale, unit), - } + const SCALES: DynamicScales = { + pt: makeScaleHandler(paddingTop ?? pt ?? py ?? padding, scale, unit), + pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding, scale, unit), + pb: makeScaleHandler(paddingBottom ?? pb ?? py ?? padding, scale, unit), + pl: makeScaleHandler(paddingLeft ?? pl ?? px ?? padding, scale, unit), + px: makeScaleHandler( + px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding, + scale, + unit, + ), + py: makeScaleHandler( + py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding, + scale, + unit, + ), + mt: makeScaleHandler(marginTop ?? mt ?? my ?? margin, scale, unit), + mr: makeScaleHandler(marginRight ?? mr ?? mx ?? margin, scale, unit), + mb: makeScaleHandler(marginBottom ?? mb ?? my ?? margin, scale, unit), + ml: makeScaleHandler(marginLeft ?? ml ?? mx ?? margin, scale, unit), + mx: makeScaleHandler( + mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin, + scale, + unit, + ), + my: makeScaleHandler( + my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin, + scale, + unit, + ), + width: makeScaleHandler(width ?? w, scale, unit), + height: makeScaleHandler(height ?? h, scale, unit), + font: makeScaleHandler(font, scale, unit), + } - return ( - - {children} - - - ); - }, -); + return ( + + {children} + + + ) + }, +) -// Box.displayName = 'GeistBox' +Box.displayName = 'GeistBox' export default Box diff --git a/components/box/index.ts b/components/box/index.ts index 5a21c2fa6..b545fe8e5 100644 --- a/components/box/index.ts +++ b/components/box/index.ts @@ -1,4 +1,4 @@ import Box from './box' export type { BoxProps } from './box' -export default Box \ No newline at end of file +export default Box diff --git a/components/index.ts b/components/index.ts index b3fe2b185..530539366 100644 --- a/components/index.ts +++ b/components/index.ts @@ -10,8 +10,8 @@ export type { AvatarProps, AvatarGroupProps } from './avatar' export { default as Badge } from './badge' export type { BadgeProps, BadgeAnchorProps } from './badge' -export {default as Box} from './box' -export type {BoxProps} from './box' +export { default as Box } from './box' +export type { BoxProps } from './box' export { default as Breadcrumbs } from './breadcrumbs' export type { diff --git a/components/use-scale/utils.ts b/components/use-scale/utils.ts index 8f40ffc2a..f3e50689b 100644 --- a/components/use-scale/utils.ts +++ b/components/use-scale/utils.ts @@ -2,9 +2,10 @@ import { GetAllScalePropsFunction, GetScalePropsFunction, ScaleProps, - ScalePropKeys, DynamicLayoutPipe, + ScalePropKeys, + DynamicLayoutPipe, } from './scale-context' -import {isCSSNumberValue} from "../utils/collections"; +import { isCSSNumberValue } from '../utils/collections' export const generateGetScaleProps =

( props: P & ScaleProps, @@ -46,20 +47,24 @@ export const reduceScaleCoefficient = (scale: number) => { } export const makeScaleHandler = - (attrValue: string | number | undefined, scale: number, unit: string): DynamicLayoutPipe => - (scale1x, defaultValue) => { - // 0 means disable scale and the default value is 0 - if (scale1x === 0) { - scale1x = 1 - defaultValue = defaultValue || 0 - } - const factor = reduceScaleCoefficient(scale) * scale1x - if (typeof attrValue === 'undefined') { - if (typeof defaultValue !== 'undefined') return `${defaultValue}` - return `calc(${factor} * ${unit})` - } + ( + attrValue: string | number | undefined, + scale: number, + unit: string, + ): DynamicLayoutPipe => + (scale1x, defaultValue) => { + // 0 means disable scale and the default value is 0 + if (scale1x === 0) { + scale1x = 1 + defaultValue = defaultValue || 0 + } + const factor = reduceScaleCoefficient(scale) * scale1x + if (typeof attrValue === 'undefined') { + if (typeof defaultValue !== 'undefined') return `${defaultValue}` + return `calc(${factor} * ${unit})` + } - if (!isCSSNumberValue(attrValue)) return `${attrValue}` - const customFactor = factor * Number(attrValue) - return `calc(${customFactor} * ${unit})` - } + if (!isCSSNumberValue(attrValue)) return `${attrValue}` + const customFactor = factor * Number(attrValue) + return `calc(${customFactor} * ${unit})` + } diff --git a/components/use-scale/with-scale.tsx b/components/use-scale/with-scale.tsx index 933b3c109..7a15f051a 100644 --- a/components/use-scale/with-scale.tsx +++ b/components/use-scale/with-scale.tsx @@ -1,7 +1,11 @@ import React, { forwardRef } from 'react' import { ScaleConfig, ScaleContext, ScaleProps } from './scale-context' import useTheme from '../use-theme' -import {generateGetAllScaleProps, generateGetScaleProps, makeScaleHandler} from './utils' +import { + generateGetAllScaleProps, + generateGetScaleProps, + makeScaleHandler, +} from './utils' const withScale = ( Render: React.ComponentType

}>, @@ -48,14 +52,30 @@ const withScale = ( pr: makeScaleHandler(paddingRight ?? pr ?? px ?? padding, scale, unit), pb: makeScaleHandler(paddingBottom ?? pb ?? py ?? padding, scale, unit), pl: makeScaleHandler(paddingLeft ?? pl ?? px ?? padding, scale, unit), - px: makeScaleHandler(px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding, scale, unit), - py: makeScaleHandler(py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding, scale, unit), + px: makeScaleHandler( + px ?? paddingLeft ?? paddingRight ?? pl ?? pr ?? padding, + scale, + unit, + ), + py: makeScaleHandler( + py ?? paddingTop ?? paddingBottom ?? pt ?? pb ?? padding, + scale, + unit, + ), mt: makeScaleHandler(marginTop ?? mt ?? my ?? margin, scale, unit), mr: makeScaleHandler(marginRight ?? mr ?? mx ?? margin, scale, unit), mb: makeScaleHandler(marginBottom ?? mb ?? my ?? margin, scale, unit), ml: makeScaleHandler(marginLeft ?? ml ?? mx ?? margin, scale, unit), - mx: makeScaleHandler(mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin, scale, unit), - my: makeScaleHandler(my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin, scale, unit), + mx: makeScaleHandler( + mx ?? marginLeft ?? marginRight ?? ml ?? mr ?? margin, + scale, + unit, + ), + my: makeScaleHandler( + my ?? marginTop ?? marginBottom ?? mt ?? mb ?? margin, + scale, + unit, + ), width: makeScaleHandler(width ?? w, scale, unit), height: makeScaleHandler(height ?? h, scale, unit), font: makeScaleHandler(font, scale, unit), diff --git a/pages/en-us/components/box.mdx b/pages/en-us/components/box.mdx index 44b64d8b9..3f0560651 100644 --- a/pages/en-us/components/box.mdx +++ b/pages/en-us/components/box.mdx @@ -44,11 +44,11 @@ Polymorphic scalable component. Box.Props -| Attribute | Description | Type | Accepted values | Default | -| --------------- | ---------------------------------- | --------------------------------- | --------------------------- | --------- | -| **as** | render mode | `React.ElementType` | `'span', 'p', 'form', ...` | `div` | -| ... | scale props | `ScaleProps` | `'width', 'px', 'font', ...`| - | -| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - | +| Attribute | Description | Type | Accepted values | Default | +| --------- | ------------ | ------------------- | ---------------------------- | ------- | +| **as** | render mode | `React.ElementType` | `'span', 'p', 'form', ...` | `div` | +| ... | scale props | `ScaleProps` | `'width', 'px', 'font', ...` | - | +| ... | native props | `HTMLAttributes` | `'id', 'className', ...` | - |