,
+ 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..b545fe8e5
--- /dev/null
+++ b/components/box/index.ts
@@ -0,0 +1,4 @@
+import Box from './box'
+
+export type { BoxProps } from './box'
+export default Box
diff --git a/components/index.ts b/components/index.ts
index 8e69423d0..530539366 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..f3e50689b 100644
--- a/components/use-scale/utils.ts
+++ b/components/use-scale/utils.ts
@@ -3,7 +3,9 @@ import {
GetScalePropsFunction,
ScaleProps,
ScalePropKeys,
+ DynamicLayoutPipe,
} from './scale-context'
+import { isCSSNumberValue } from '../utils/collections'
export const generateGetScaleProps = (
props: P & ScaleProps,
@@ -37,3 +39,32 @@ 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..7a15f051a 100644
--- a/components/use-scale/with-scale.tsx
+++ b/components/use-scale/with-scale.tsx
@@ -1,14 +1,11 @@
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 +44,41 @@ 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..3f0560651
--- /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}