@wordpress/ui 0.3.1-next.8b30e05b0.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CONTRIBUTING.md +25 -0
  2. package/README.md +1 -1
  3. package/build/box/box.js +87 -0
  4. package/build/box/box.js.map +7 -0
  5. package/build/box/index.js +31 -0
  6. package/build/box/index.js.map +7 -0
  7. package/build/box/types.js +19 -0
  8. package/build/box/types.js.map +7 -0
  9. package/build/index.js +25 -0
  10. package/build/index.js.map +7 -0
  11. package/build/lock-unlock.js +37 -0
  12. package/build/lock-unlock.js.map +7 -0
  13. package/build/stack/index.js +31 -0
  14. package/build/stack/index.js.map +7 -0
  15. package/build/stack/stack.js +75 -0
  16. package/build/stack/stack.js.map +7 -0
  17. package/build/stack/types.js +19 -0
  18. package/build/stack/types.js.map +7 -0
  19. package/build/types/css-modules.d.js +2 -0
  20. package/build/types/css-modules.d.js.map +7 -0
  21. package/build/types/react.d.js +5 -0
  22. package/build/types/react.d.js.map +7 -0
  23. package/build/utils/element.js +45 -0
  24. package/build/utils/element.js.map +7 -0
  25. package/build/utils/types.js +19 -0
  26. package/build/utils/types.js.map +7 -0
  27. package/build-module/box/box.js +62 -0
  28. package/build-module/box/box.js.map +7 -0
  29. package/build-module/box/index.js +6 -0
  30. package/build-module/box/index.js.map +7 -0
  31. package/build-module/box/types.js +1 -0
  32. package/build-module/box/types.js.map +7 -0
  33. package/build-module/index.js +3 -0
  34. package/build-module/index.js.map +7 -0
  35. package/build-module/lock-unlock.js +11 -0
  36. package/build-module/lock-unlock.js.map +7 -0
  37. package/build-module/stack/index.js +6 -0
  38. package/build-module/stack/index.js.map +7 -0
  39. package/build-module/stack/stack.js +40 -0
  40. package/build-module/stack/stack.js.map +7 -0
  41. package/build-module/stack/types.js +1 -0
  42. package/build-module/stack/types.js.map +7 -0
  43. package/build-module/types/css-modules.d.js +1 -0
  44. package/build-module/types/css-modules.d.js.map +7 -0
  45. package/build-module/types/react.d.js +3 -0
  46. package/build-module/types/react.d.js.map +7 -0
  47. package/build-module/utils/element.js +20 -0
  48. package/build-module/utils/element.js.map +7 -0
  49. package/build-module/utils/types.js +1 -0
  50. package/build-module/utils/types.js.map +7 -0
  51. package/build-types/box/box.d.ts.map +1 -1
  52. package/build-types/box/stories/index.story.d.ts.map +1 -1
  53. package/build-types/box/test/box.test.d.ts +2 -0
  54. package/build-types/box/test/box.test.d.ts.map +1 -0
  55. package/build-types/box/types.d.ts +13 -0
  56. package/build-types/box/types.d.ts.map +1 -1
  57. package/build-types/stack/index.d.ts +5 -0
  58. package/build-types/stack/index.d.ts.map +1 -0
  59. package/build-types/stack/stack.d.ts +7 -0
  60. package/build-types/stack/stack.d.ts.map +1 -0
  61. package/build-types/stack/stories/index.story.d.ts +18 -0
  62. package/build-types/stack/stories/index.story.d.ts.map +1 -0
  63. package/build-types/stack/test/stack.test.d.ts +2 -0
  64. package/build-types/stack/test/stack.test.d.ts.map +1 -0
  65. package/build-types/stack/types.d.ts +38 -0
  66. package/build-types/stack/types.d.ts.map +1 -0
  67. package/build-types/utils/element.d.ts +12 -4
  68. package/build-types/utils/element.d.ts.map +1 -1
  69. package/package.json +9 -5
  70. package/src/box/box.tsx +22 -2
  71. package/src/box/stories/index.story.tsx +4 -1
  72. package/src/box/test/box.test.tsx +40 -0
  73. package/src/box/types.ts +30 -0
  74. package/src/stack/index.ts +4 -0
  75. package/src/stack/stack.tsx +42 -0
  76. package/src/stack/stories/index.story.tsx +120 -0
  77. package/src/stack/style.module.css +7 -0
  78. package/src/stack/test/stack.test.tsx +24 -0
  79. package/src/stack/types.ts +47 -0
  80. package/src/types/css-modules.d.ts +4 -0
  81. package/src/types/react.d.ts +7 -0
  82. package/src/utils/element.ts +25 -12
  83. package/tsconfig.json +1 -1
  84. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/box/box.tsx"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { forwardRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { type BoxProps } from './types';\nimport { renderElement } from '../utils/element';\n\n/**\n * Default render function that renders a div element with the given props.\n *\n * @param props The props to apply to the HTML element.\n */\nconst DEFAULT_RENDER = ( props: React.ComponentPropsWithoutRef< 'div' > ) => (\n\t<div { ...props } />\n);\n\n/**\n * Capitalizes the first character of a string.\n *\n * @param str The string to capitalize.\n * @return The capitalized string.\n */\nconst capitalize = ( str: string ): string =>\n\tstr.charAt( 0 ).toUpperCase() + str.slice( 1 );\n\n/**\n * Converts a size value to a CSS design token property reference (with\n * fallback) or a calculated value based on the base unit.\n *\n * @param property The CSS property name.\n * @param target The design system token target.\n * @param value The size value, either a number (multiplier of base unit) or a string (token name).\n * @return A CSS value string with variable references.\n */\nconst getSpacingValue = (\n\tproperty: string,\n\ttarget: string,\n\tvalue: number | string\n): string =>\n\ttypeof value === 'number'\n\t\t? `calc(var(--wpds-dimension-base) * ${ value })`\n\t\t: `var(--wpds-dimension-${ property }-${ target }-${ value }, var(--wpds-dimension-${ property }-surface-${ value }))`;\n\n/**\n * Generates CSS styles for properties with optionally directional values,\n * normalizing single values and objects with directional keys for logical\n * properties.\n *\n * @param property The CSS property name from BoxProps.\n * @param target The design system token target.\n * @param value The property value (single or object with directional keys).\n * @return A CSSProperties object with the computed styles.\n */\nconst getDimensionVariantStyles = < T extends keyof BoxProps >(\n\tproperty: T,\n\ttarget: string,\n\tvalue: NonNullable< BoxProps[ T ] >\n): React.CSSProperties =>\n\ttypeof value !== 'object'\n\t\t? { [ property ]: getSpacingValue( property, target, value ) }\n\t\t: Object.keys( value ).reduce(\n\t\t\t\t( result, key ) => ( {\n\t\t\t\t\t...result,\n\t\t\t\t\t[ property + capitalize( key ) ]: getSpacingValue(\n\t\t\t\t\t\tproperty,\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tvalue[ key ]\n\t\t\t\t\t),\n\t\t\t\t} ),\n\t\t\t\t{} as Record< string, string >\n\t\t );\n\n/**\n * A low-level visual primitive that provides an interface for applying design\n * token-based customization for background, text, padding, and more.\n */\nexport const Box = forwardRef< HTMLDivElement, BoxProps >( function Box(\n\t{\n\t\ttarget = 'surface',\n\t\tbackgroundColor,\n\t\tcolor,\n\t\tpadding,\n\t\tborderRadius,\n\t\tborderWidth,\n\t\tborderColor,\n\t\trender = DEFAULT_RENDER,\n\t\t...props\n\t},\n\tref\n) {\n\tconst style: React.CSSProperties = { ...props.style };\n\n\tif ( backgroundColor ) {\n\t\tstyle.backgroundColor = `var(--wpds-color-bg-${ target }-${ backgroundColor }, var(--wpds-color-bg-surface-${ backgroundColor }))`;\n\t}\n\n\tif ( color ) {\n\t\tstyle.color = `var(--wpds-color-fg-${ target }-${ color }, var(--wpds-color-fg-content-${ color }))`;\n\t}\n\n\tif ( padding ) {\n\t\tObject.assign(\n\t\t\tstyle,\n\t\t\tgetDimensionVariantStyles( 'padding', target, padding )\n\t\t);\n\t}\n\n\tif ( borderRadius ) {\n\t\tstyle.borderRadius = `var(--wpds-border-radius-${ target }-${ borderRadius }, var(--wpds-border-radius-surface-${ borderRadius }))`;\n\t}\n\n\tif ( borderWidth ) {\n\t\tstyle.borderWidth = `var(--wpds-border-width-${ target }-${ borderWidth }, var(--wpds-border-width-surface-${ borderWidth }))`;\n\t\tstyle.borderStyle = 'solid';\n\t}\n\n\tif ( borderColor ) {\n\t\tstyle.borderColor = `var(--wpds-color-stroke-${ target }-${ borderColor }, var(--wpds-color-stroke-surface-${ borderColor }))`;\n\t}\n\n\treturn renderElement< 'div' >( {\n\t\trender,\n\t\tref,\n\t\tprops: { ...props, style },\n\t} );\n} );\n"],
5
+ "mappings": ";AAGA,SAAS,kBAAkB;AAM3B,SAAS,qBAAqB;AAQ7B;AADD,IAAM,iBAAiB,CAAE,UACxB,oBAAC,SAAM,GAAG,OAAQ;AASnB,IAAM,aAAa,CAAE,QACpB,IAAI,OAAQ,CAAE,EAAE,YAAY,IAAI,IAAI,MAAO,CAAE;AAW9C,IAAM,kBAAkB,CACvB,UACA,QACA,UAEA,OAAO,UAAU,WACd,qCAAsC,KAAM,MAC5C,wBAAyB,QAAS,IAAK,MAAO,IAAK,KAAM,0BAA2B,QAAS,YAAa,KAAM;AAYpH,IAAM,4BAA4B,CACjC,UACA,QACA,UAEA,OAAO,UAAU,WACd,EAAE,CAAE,QAAS,GAAG,gBAAiB,UAAU,QAAQ,KAAM,EAAE,IAC3D,OAAO,KAAM,KAAM,EAAE;AAAA,EACrB,CAAE,QAAQ,SAAW;AAAA,IACpB,GAAG;AAAA,IACH,CAAE,WAAW,WAAY,GAAI,CAAE,GAAG;AAAA,MACjC;AAAA,MACA;AAAA,MACA,MAAO,GAAI;AAAA,IACZ;AAAA,EACD;AAAA,EACA,CAAC;AACD;AAMG,IAAM,MAAM,WAAwC,SAASA,KACnE;AAAA,EACC,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,GAAG;AACJ,GACA,KACC;AACD,QAAM,QAA6B,EAAE,GAAG,MAAM,MAAM;AAEpD,MAAK,iBAAkB;AACtB,UAAM,kBAAkB,uBAAwB,MAAO,IAAK,eAAgB,iCAAkC,eAAgB;AAAA,EAC/H;AAEA,MAAK,OAAQ;AACZ,UAAM,QAAQ,uBAAwB,MAAO,IAAK,KAAM,iCAAkC,KAAM;AAAA,EACjG;AAEA,MAAK,SAAU;AACd,WAAO;AAAA,MACN;AAAA,MACA,0BAA2B,WAAW,QAAQ,OAAQ;AAAA,IACvD;AAAA,EACD;AAEA,MAAK,cAAe;AACnB,UAAM,eAAe,4BAA6B,MAAO,IAAK,YAAa,sCAAuC,YAAa;AAAA,EAChI;AAEA,MAAK,aAAc;AAClB,UAAM,cAAc,2BAA4B,MAAO,IAAK,WAAY,qCAAsC,WAAY;AAC1H,UAAM,cAAc;AAAA,EACrB;AAEA,MAAK,aAAc;AAClB,UAAM,cAAc,2BAA4B,MAAO,IAAK,WAAY,qCAAsC,WAAY;AAAA,EAC3H;AAEA,SAAO,cAAwB;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,OAAO,EAAE,GAAG,OAAO,MAAM;AAAA,EAC1B,CAAE;AACH,CAAE;",
6
+ "names": ["Box"]
7
+ }
@@ -0,0 +1,6 @@
1
+ // packages/ui/src/box/index.ts
2
+ import { Box } from "./box";
3
+ export {
4
+ Box
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/box/index.ts"],
4
+ "sourcesContent": ["export { Box } from './box';\n"],
5
+ "mappings": ";AAAA,SAAS,WAAW;",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ // packages/ui/src/index.ts
2
+ export * from "./box";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["export * from './box';\n"],
5
+ "mappings": ";AAAA,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ // packages/ui/src/lock-unlock.ts
2
+ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from "@wordpress/private-apis";
3
+ var { lock, unlock } = __dangerousOptInToUnstableAPIsOnlyForCoreModules(
4
+ "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
5
+ "@wordpress/dataviews"
6
+ );
7
+ export {
8
+ lock,
9
+ unlock
10
+ };
11
+ //# sourceMappingURL=lock-unlock.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/lock-unlock.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis';\n\nexport const { lock, unlock } =\n\t__dangerousOptInToUnstableAPIsOnlyForCoreModules(\n\t\t'I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.',\n\t\t'@wordpress/dataviews'\n\t);\n"],
5
+ "mappings": ";AAGA,SAAS,wDAAwD;AAE1D,IAAM,EAAE,MAAM,OAAO,IAC3B;AAAA,EACC;AAAA,EACA;AACD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,6 @@
1
+ // packages/ui/src/stack/index.ts
2
+ import { Stack } from "./stack";
3
+ export {
4
+ Stack
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/stack/index.ts"],
4
+ "sourcesContent": ["/**\n * Internal dependencies\n */\nexport { Stack } from './stack';\n"],
5
+ "mappings": ";AAGA,SAAS,aAAa;",
6
+ "names": []
7
+ }
@@ -0,0 +1,40 @@
1
+ // packages/ui/src/stack/stack.tsx
2
+ import clsx from "clsx";
3
+ import { forwardRef } from "@wordpress/element";
4
+ import { renderElement } from "../utils/element";
5
+
6
+ // packages/ui/src/stack/style.module.css
7
+ var css = `@layer wp-ui-utilities, wp-ui-components, wp-ui-compositions, wp-ui-overrides;
8
+
9
+ @layer wp-ui-components {
10
+ .style-module__stack__Gc4EG {
11
+ display: flex;
12
+ }
13
+ }
14
+ `;
15
+ document.head.appendChild(document.createElement("style")).appendChild(document.createTextNode(css));
16
+ var style_default = {
17
+ "stack": "style-module__stack__Gc4EG"
18
+ };
19
+
20
+ // packages/ui/src/stack/stack.tsx
21
+ var Stack = forwardRef(function Stack2({ direction, gap, align, justify, wrap, render, ...props }, ref) {
22
+ const className = clsx(props.className, style_default.stack);
23
+ const style = {
24
+ gap: gap && `var(--wpds-dimension-gap-${gap})`,
25
+ alignItems: align,
26
+ justifyContent: justify,
27
+ flexDirection: direction,
28
+ flexWrap: wrap,
29
+ ...props.style
30
+ };
31
+ return renderElement({
32
+ render,
33
+ ref,
34
+ props: { ...props, style, className }
35
+ });
36
+ });
37
+ export {
38
+ Stack
39
+ };
40
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/stack/stack.tsx", "../../src/stack/style.module.css"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { forwardRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { renderElement } from '../utils/element';\nimport { type StackProps } from './types';\nimport styles from './style.module.css';\n\n/**\n * A flexible layout component using CSS Flexbox for consistent spacing and alignment.\n * Built on design tokens for predictable spacing values.\n */\nexport const Stack = forwardRef< HTMLDivElement, StackProps >( function Stack(\n\t{ direction, gap, align, justify, wrap, render, ...props },\n\tref\n) {\n\tconst className = clsx( props.className, styles.stack );\n\n\tconst style: React.CSSProperties = {\n\t\tgap: gap && `var(--wpds-dimension-gap-${ gap })`,\n\t\talignItems: align,\n\t\tjustifyContent: justify,\n\t\tflexDirection: direction,\n\t\tflexWrap: wrap,\n\t\t...props.style,\n\t};\n\n\treturn renderElement< 'div' >( {\n\t\trender,\n\t\tref,\n\t\tprops: { ...props, style, className },\n\t} );\n} );\n", "const css = `@layer wp-ui-utilities, wp-ui-components, wp-ui-compositions, wp-ui-overrides;\n\n@layer wp-ui-components {\n\t.style-module__stack__Gc4EG {\n\t\tdisplay: flex;\n\t}\n}\n`;\ndocument.head\n .appendChild(document.createElement(\"style\"))\n .appendChild(document.createTextNode(css));\nexport {css};\nexport default {\n \"stack\": \"style-module__stack__Gc4EG\"\n};"],
5
+ "mappings": ";AAGA,OAAO,UAAU;AAKjB,SAAS,kBAAkB;AAK3B,SAAS,qBAAqB;;;ACb9B,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQZ,SAAS,KACJ,YAAY,SAAS,cAAc,OAAO,CAAC,EAC3C,YAAY,SAAS,eAAe,GAAG,CAAC;AAE7C,IAAO,gBAAQ;AAAA,EACb,SAAS;AACX;;;ADOO,IAAM,QAAQ,WAA0C,SAASA,OACvE,EAAE,WAAW,KAAK,OAAO,SAAS,MAAM,QAAQ,GAAG,MAAM,GACzD,KACC;AACD,QAAM,YAAY,KAAM,MAAM,WAAW,cAAO,KAAM;AAEtD,QAAM,QAA6B;AAAA,IAClC,KAAK,OAAO,4BAA6B,GAAI;AAAA,IAC7C,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,UAAU;AAAA,IACV,GAAG,MAAM;AAAA,EACV;AAEA,SAAO,cAAwB;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,OAAO,EAAE,GAAG,OAAO,OAAO,UAAU;AAAA,EACrC,CAAE;AACH,CAAE;",
6
+ "names": ["Stack"]
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=css-modules.d.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ // packages/ui/src/types/react.d.ts
2
+ import "react";
3
+ //# sourceMappingURL=react.d.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/types/react.d.ts"],
4
+ "sourcesContent": ["import 'react';\n\ndeclare module 'react' {\n\tinterface CSSProperties {\n\t\t[ key: `--${ string }` ]: string | number | undefined;\n\t}\n}\n"],
5
+ "mappings": ";AAAA,OAAO;",
6
+ "names": []
7
+ }
@@ -0,0 +1,20 @@
1
+ // packages/ui/src/utils/element.ts
2
+ import { cloneElement, createElement } from "@wordpress/element";
3
+ var renderElement = ({
4
+ render,
5
+ defaultTagName = "div",
6
+ props,
7
+ ref
8
+ }) => {
9
+ const propsWithRef = ref ? { ...props, ref } : props;
10
+ if (render === void 0) {
11
+ return createElement(defaultTagName, propsWithRef);
12
+ } else if (typeof render === "function") {
13
+ return render(propsWithRef);
14
+ }
15
+ return cloneElement(render, propsWithRef);
16
+ };
17
+ export {
18
+ renderElement
19
+ };
20
+ //# sourceMappingURL=element.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/element.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { cloneElement, createElement } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport type { ComponentProps } from './types';\n\ntype RenderProp< E extends React.ElementType > = NonNullable<\n\tComponentProps< E >[ 'render' ]\n>;\n\n/**\n * Renders an element from a render prop (a component or an element), with\n * merged props and ref.\n *\n * @param options Render options.\n * @param options.render The render prop (component or element).\n * @param options.defaultTagName The default tag name to use if no render prop\n * is provided.\n * @param options.props Props to pass to or merge with the element.\n * @param options.ref Optional ref to attach to the element.\n * @return The rendered element.\n */\nexport const renderElement = < E extends React.ElementType >( {\n\trender,\n\tdefaultTagName = 'div',\n\tprops,\n\tref,\n}: {\n\trender?: RenderProp< E >;\n\tdefaultTagName?: keyof JSX.IntrinsicElements;\n\tprops: Omit< ComponentProps< E >, 'render' >;\n\tref?: React.Ref<\n\t\tE extends keyof HTMLElementTagNameMap\n\t\t\t? HTMLElementTagNameMap[ E ]\n\t\t\t: Element\n\t>;\n} ): React.ReactElement => {\n\tconst propsWithRef = ref ? { ...props, ref } : props;\n\n\tif ( render === undefined ) {\n\t\treturn createElement( defaultTagName, propsWithRef );\n\t} else if ( typeof render === 'function' ) {\n\t\treturn render( propsWithRef );\n\t}\n\n\treturn cloneElement( render, propsWithRef );\n};\n"],
5
+ "mappings": ";AAGA,SAAS,cAAc,qBAAqB;AAuBrC,IAAM,gBAAgB,CAAiC;AAAA,EAC7D;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AACD,MAS2B;AAC1B,QAAM,eAAe,MAAM,EAAE,GAAG,OAAO,IAAI,IAAI;AAE/C,MAAK,WAAW,QAAY;AAC3B,WAAO,cAAe,gBAAgB,YAAa;AAAA,EACpD,WAAY,OAAO,WAAW,YAAa;AAC1C,WAAO,OAAQ,YAAa;AAAA,EAC7B;AAEA,SAAO,aAAc,QAAQ,YAAa;AAC3C;",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/box/box.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAoExC;;;GAGG;AACH,eAAO,MAAM,GAAG,qGA6Bb,CAAC"}
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/box/box.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAoExC;;;GAGG;AACH,eAAO,MAAM,GAAG,qGAiDb,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.story.d.ts","sourceRoot":"","sources":["../../../src/box/stories/index.story.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;GAEG;AACH,OAAO,oCAAoC,CAAC;AAE5C;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAE,OAAO,GAAG,CAI3B,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAE,OAAO,GAAG,CAAE,CAAC;AAEpC,eAAO,MAAM,OAAO,EAAE,KAarB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAUhC,CAAC"}
1
+ {"version":3,"file":"index.story.d.ts","sourceRoot":"","sources":["../../../src/box/stories/index.story.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;GAEG;AACH,OAAO,oCAAoC,CAAC;AAE5C;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,QAAA,MAAM,IAAI,EAAE,IAAI,CAAE,OAAO,GAAG,CAI3B,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAE,OAAO,GAAG,CAAE,CAAC;AAEpC,eAAO,MAAM,OAAO,EAAE,KAgBrB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAUhC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=box.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.test.d.ts","sourceRoot":"","sources":["../../../src/box/test/box.test.tsx"],"names":[],"mappings":""}
@@ -6,6 +6,7 @@ type SizeToken = '2xs' | 'xs' | 'sm' | 'md' | 'lg';
6
6
  type Size = number | SizeToken;
7
7
  type BackgroundColor = 'neutral' | 'neutral-strong' | 'neutral-weak' | 'brand' | 'success' | 'success-weak' | 'info' | 'info-weak' | 'warning' | 'warning-weak' | 'caution' | 'caution-weak' | 'error' | 'error-weak';
8
8
  type ForegroundColor = 'neutral' | 'neutral-weak' | 'success' | 'success-weak' | 'info' | 'info-weak' | 'warning' | 'warning-weak' | 'caution' | 'caution-weak' | 'error' | 'error-weak';
9
+ type StrokeColor = 'brand' | 'brand-strong' | 'error' | 'error-strong' | 'info' | 'info-strong' | 'neutral' | 'neutral-strong' | 'neutral-weak' | 'success' | 'success-strong' | 'warning' | 'warning-strong';
9
10
  type DimensionVariant<T> = {
10
11
  block?: T;
11
12
  blockStart?: T;
@@ -31,6 +32,18 @@ export interface BoxProps extends ComponentProps<'div'> {
31
32
  * The surface spacing design token or base unit multiplier for box padding.
32
33
  */
33
34
  padding?: Size | DimensionVariant<Size>;
35
+ /**
36
+ * The surface border radius design token.
37
+ */
38
+ borderRadius?: Exclude<SizeToken, '2xs'>;
39
+ /**
40
+ * The surface border width design token.
41
+ */
42
+ borderWidth?: Exclude<SizeToken, '2xs'>;
43
+ /**
44
+ * The surface border stroke color design token.
45
+ */
46
+ borderColor?: StrokeColor;
34
47
  /**
35
48
  * The content to be rendered inside the component.
36
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/box/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD,KAAK,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/B,KAAK,eAAe,GACjB,SAAS,GACT,gBAAgB,GAChB,cAAc,GACd,OAAO,GACP,SAAS,GACT,cAAc,GACd,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,SAAS,GACT,cAAc,GACd,OAAO,GACP,YAAY,CAAC;AAEhB,KAAK,eAAe,GACjB,SAAS,GACT,cAAc,GACd,SAAS,GACT,cAAc,GACd,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,SAAS,GACT,cAAc,GACd,OAAO,GACP,YAAY,CAAC;AAEhB,KAAK,gBAAgB,CAAE,CAAC,IAAK;IAC5B,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,UAAU,CAAC,EAAE,CAAC,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,CAAC;IACb,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,CAAC;CACd,CAAC;AAEF,MAAM,WAAW,QAAS,SAAQ,cAAc,CAAE,KAAK,CAAE;IACxD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IAExB;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,GAAG,gBAAgB,CAAE,IAAI,CAAE,CAAC;IAE1C;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/box/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD,KAAK,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/B,KAAK,eAAe,GACjB,SAAS,GACT,gBAAgB,GAChB,cAAc,GACd,OAAO,GACP,SAAS,GACT,cAAc,GACd,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,SAAS,GACT,cAAc,GACd,OAAO,GACP,YAAY,CAAC;AAEhB,KAAK,eAAe,GACjB,SAAS,GACT,cAAc,GACd,SAAS,GACT,cAAc,GACd,MAAM,GACN,WAAW,GACX,SAAS,GACT,cAAc,GACd,SAAS,GACT,cAAc,GACd,OAAO,GACP,YAAY,CAAC;AAEhB,KAAK,WAAW,GACb,OAAO,GACP,cAAc,GACd,OAAO,GACP,cAAc,GACd,MAAM,GACN,aAAa,GACb,SAAS,GACT,gBAAgB,GAChB,cAAc,GACd,SAAS,GACT,gBAAgB,GAChB,SAAS,GACT,gBAAgB,CAAC;AAEpB,KAAK,gBAAgB,CAAE,CAAC,IAAK;IAC5B,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,UAAU,CAAC,EAAE,CAAC,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,CAAC;IACb,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,SAAS,CAAC,EAAE,CAAC,CAAC;CACd,CAAC;AAEF,MAAM,WAAW,QAAS,SAAQ,cAAc,CAAE,KAAK,CAAE;IACxD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;IAExB;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,GAAG,gBAAgB,CAAE,IAAI,CAAE,CAAC;IAE1C;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAE,SAAS,EAAE,KAAK,CAAE,CAAC;IAE3C;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAE,SAAS,EAAE,KAAK,CAAE,CAAC;IAE1C;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ export { Stack } from './stack';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stack/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type StackProps } from './types';
2
+ /**
3
+ * A flexible layout component using CSS Flexbox for consistent spacing and alignment.
4
+ * Built on design tokens for predictable spacing values.
5
+ */
6
+ export declare const Stack: import("react").ForwardRefExoticComponent<StackProps & import("react").RefAttributes<HTMLDivElement>>;
7
+ //# sourceMappingURL=stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/stack/stack.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C;;;GAGG;AACH,eAAO,MAAM,KAAK,uGAoBf,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { Meta, StoryObj } from '@storybook/react';
5
+ /**
6
+ * WordPress dependencies
7
+ */
8
+ import '@wordpress/theme/design-tokens.css';
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { Stack } from '../index';
13
+ declare const meta: Meta<typeof Stack>;
14
+ export default meta;
15
+ type Story = StoryObj<typeof Stack>;
16
+ export declare const Default: Story;
17
+ export declare const Nested: Story;
18
+ //# sourceMappingURL=index.story.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.story.d.ts","sourceRoot":"","sources":["../../../src/stack/stories/index.story.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;GAEG;AACH,OAAO,oCAAoC,CAAC;AAE5C;;GAEG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGjC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAE,OAAO,KAAK,CAI7B,CAAC;AACF,eAAe,IAAI,CAAC;AAYpB,KAAK,KAAK,GAAG,QAAQ,CAAE,OAAO,KAAK,CAAE,CAAC;AAEtC,eAAO,MAAM,OAAO,EAAE,KA4DrB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,KAsBpB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stack.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.test.d.ts","sourceRoot":"","sources":["../../../src/stack/test/stack.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { type ComponentProps } from '../utils/types';
5
+ export type SizeToken = '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
6
+ export interface StackProps extends ComponentProps<'div'> {
7
+ /**
8
+ * The direction of the stack.
9
+ */
10
+ direction?: Exclude<React.CSSProperties['flexDirection'], 'row-reverse' | 'column-reverse'>;
11
+ /**
12
+ * The amount of space between each child element using design system tokens.
13
+ *
14
+ * @default undefined
15
+ */
16
+ gap?: SizeToken;
17
+ /**
18
+ * The alignment of the stack items along the cross axis.
19
+ *
20
+ * @default 'initial'
21
+ */
22
+ align?: React.CSSProperties['alignItems'];
23
+ /**
24
+ * The alignment of the stack items along the main axis.
25
+ *
26
+ * @default 'initial'
27
+ */
28
+ justify?: React.CSSProperties['justifyContent'];
29
+ /**
30
+ * Whether the stack items should wrap to the next line.
31
+ */
32
+ wrap?: Exclude<React.CSSProperties['flexWrap'], 'wrap-reverse'>;
33
+ /**
34
+ * The content to be rendered inside the component.
35
+ */
36
+ children?: React.ReactNode;
37
+ }
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stack/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjE,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAE,KAAK,CAAE;IAC1D;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAClB,KAAK,CAAC,aAAa,CAAE,eAAe,CAAE,EACtC,aAAa,GAAG,gBAAgB,CAChC,CAAC;IAEF;;;;OAIG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAEhB;;;;OAIG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAE,YAAY,CAAE,CAAC;IAE5C;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAE,gBAAgB,CAAE,CAAC;IAElD;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAE,KAAK,CAAC,aAAa,CAAE,UAAU,CAAE,EAAE,cAAc,CAAE,CAAC;IAEpE;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B"}
@@ -7,11 +7,19 @@ type RenderProp<E extends React.ElementType> = NonNullable<ComponentProps<E>['re
7
7
  * Renders an element from a render prop (a component or an element), with
8
8
  * merged props and ref.
9
9
  *
10
- * @param render The render prop (component or element).
11
- * @param props Props to pass to or merge with the element.
12
- * @param ref Optional ref to attach to the element.
10
+ * @param options Render options.
11
+ * @param options.render The render prop (component or element).
12
+ * @param options.defaultTagName The default tag name to use if no render prop
13
+ * is provided.
14
+ * @param options.props Props to pass to or merge with the element.
15
+ * @param options.ref Optional ref to attach to the element.
13
16
  * @return The rendered element.
14
17
  */
15
- export declare const renderElement: <E extends React.ElementType>(render: RenderProp<E>, props: Omit<ComponentProps<E>, "render">, ref?: React.Ref<E extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[E] : Element>) => React.ReactElement;
18
+ export declare const renderElement: <E extends React.ElementType>({ render, defaultTagName, props, ref, }: {
19
+ render?: RenderProp<E>;
20
+ defaultTagName?: keyof JSX.IntrinsicElements;
21
+ props: Omit<ComponentProps<E>, "render">;
22
+ ref?: React.Ref<E extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[E] : Element>;
23
+ }) => React.ReactElement;
16
24
  export {};
17
25
  //# sourceMappingURL=element.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/utils/element.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,KAAK,UAAU,CAAE,CAAC,SAAS,KAAK,CAAC,WAAW,IAAK,WAAW,CAC3D,cAAc,CAAE,CAAC,CAAE,CAAE,QAAQ,CAAE,CAC/B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GAAK,CAAC,SAAS,KAAK,CAAC,WAAW,EACzD,QAAQ,UAAU,CAAE,CAAC,CAAE,EACvB,OAAO,IAAI,CAAE,cAAc,CAAE,CAAC,CAAE,EAAE,QAAQ,CAAE,EAC5C,MAAM,KAAK,CAAC,GAAG,CACd,CAAC,SAAS,MAAM,qBAAqB,GAClC,qBAAqB,CAAE,CAAC,CAAE,GAC1B,OAAO,CACV,KACC,KAAK,CAAC,YAMR,CAAC"}
1
+ {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/utils/element.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,KAAK,UAAU,CAAE,CAAC,SAAS,KAAK,CAAC,WAAW,IAAK,WAAW,CAC3D,cAAc,CAAE,CAAC,CAAE,CAAE,QAAQ,CAAE,CAC/B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,GAAK,CAAC,SAAS,KAAK,CAAC,WAAW,EAAI,yCAK3D;IACF,MAAM,CAAC,EAAE,UAAU,CAAE,CAAC,CAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,iBAAiB,CAAC;IAC7C,KAAK,EAAE,IAAI,CAAE,cAAc,CAAE,CAAC,CAAE,EAAE,QAAQ,CAAE,CAAC;IAC7C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CACd,CAAC,SAAS,MAAM,qBAAqB,GAClC,qBAAqB,CAAE,CAAC,CAAE,GAC1B,OAAO,CACV,CAAC;CACF,KAAI,KAAK,CAAC,YAUV,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/ui",
3
- "version": "0.3.1-next.8b30e05b0.0",
3
+ "version": "0.4.0",
4
4
  "description": "Themeable React UI components for the WordPress Design System.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -22,6 +22,8 @@
22
22
  "node": ">=20.10.0",
23
23
  "npm": ">=10.2.3"
24
24
  },
25
+ "main": "build/index.js",
26
+ "module": "build-module/index.js",
25
27
  "exports": {
26
28
  ".": {
27
29
  "types": "./build-types/index.d.ts",
@@ -31,13 +33,15 @@
31
33
  "./package.json": "./package.json"
32
34
  },
33
35
  "wpScript": false,
36
+ "types": "build-types",
34
37
  "sideEffects": false,
35
38
  "dependencies": {
36
- "@wordpress/element": "^6.36.1-next.8b30e05b0.0",
37
- "@wordpress/private-apis": "^1.36.1-next.8b30e05b0.0"
39
+ "@wordpress/element": "^6.37.0",
40
+ "@wordpress/private-apis": "^1.37.0",
41
+ "clsx": "^2.1.1"
38
42
  },
39
43
  "devDependencies": {
40
- "@wordpress/theme": "^0.3.1-next.8b30e05b0.0"
44
+ "@wordpress/theme": "^0.4.0"
41
45
  },
42
46
  "peerDependencies": {
43
47
  "react": "^18.0.0",
@@ -46,5 +50,5 @@
46
50
  "publishConfig": {
47
51
  "access": "public"
48
52
  },
49
- "gitHead": "2466f6bc223f8be98c55e1ac7270e8c3e413eaaf"
53
+ "gitHead": "2cf13ec6cf86153c9b3cf369bf5c59046f5cd950"
50
54
  }
package/src/box/box.tsx CHANGED
@@ -84,12 +84,15 @@ export const Box = forwardRef< HTMLDivElement, BoxProps >( function Box(
84
84
  backgroundColor,
85
85
  color,
86
86
  padding,
87
+ borderRadius,
88
+ borderWidth,
89
+ borderColor,
87
90
  render = DEFAULT_RENDER,
88
91
  ...props
89
92
  },
90
93
  ref
91
94
  ) {
92
- const style: React.CSSProperties = {};
95
+ const style: React.CSSProperties = { ...props.style };
93
96
 
94
97
  if ( backgroundColor ) {
95
98
  style.backgroundColor = `var(--wpds-color-bg-${ target }-${ backgroundColor }, var(--wpds-color-bg-surface-${ backgroundColor }))`;
@@ -106,5 +109,22 @@ export const Box = forwardRef< HTMLDivElement, BoxProps >( function Box(
106
109
  );
107
110
  }
108
111
 
109
- return renderElement< 'div' >( render, { style, ...props }, ref );
112
+ if ( borderRadius ) {
113
+ style.borderRadius = `var(--wpds-border-radius-${ target }-${ borderRadius }, var(--wpds-border-radius-surface-${ borderRadius }))`;
114
+ }
115
+
116
+ if ( borderWidth ) {
117
+ style.borderWidth = `var(--wpds-border-width-${ target }-${ borderWidth }, var(--wpds-border-width-surface-${ borderWidth }))`;
118
+ style.borderStyle = 'solid';
119
+ }
120
+
121
+ if ( borderColor ) {
122
+ style.borderColor = `var(--wpds-color-stroke-${ target }-${ borderColor }, var(--wpds-color-stroke-surface-${ borderColor }))`;
123
+ }
124
+
125
+ return renderElement< 'div' >( {
126
+ render,
127
+ ref,
128
+ props: { ...props, style },
129
+ } );
110
130
  } );
@@ -6,7 +6,7 @@ import { type Meta, type StoryObj } from '@storybook/react';
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
- import '@wordpress/theme/design-tokens.css'; // eslint-disable-line no-restricted-syntax
9
+ import '@wordpress/theme/design-tokens.css';
10
10
 
11
11
  /**
12
12
  * Internal dependencies
@@ -28,6 +28,9 @@ export const Default: Story = {
28
28
  backgroundColor: 'info',
29
29
  color: 'info',
30
30
  padding: 'sm',
31
+ borderColor: 'brand',
32
+ borderRadius: 'md',
33
+ borderWidth: 'sm',
31
34
  },
32
35
  argTypes: {
33
36
  padding: {
@@ -0,0 +1,40 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { createRef } from '@wordpress/element';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import { Box } from '../box';
15
+
16
+ describe( 'Box', () => {
17
+ it( 'forwards ref', () => {
18
+ const ref = createRef< HTMLDivElement >();
19
+
20
+ render( <Box ref={ ref }>Content</Box> );
21
+
22
+ expect( ref.current ).toBeInstanceOf( HTMLDivElement );
23
+ } );
24
+
25
+ it( 'merges props', () => {
26
+ render(
27
+ <Box backgroundColor="brand" style={ { width: '10px' } }>
28
+ Content
29
+ </Box>
30
+ );
31
+
32
+ const box = screen.getByText( 'Content' );
33
+
34
+ expect( box ).toHaveStyle( {
35
+ 'background-color':
36
+ 'var(--wpds-color-bg-surface-brand, var(--wpds-color-bg-surface-brand))',
37
+ width: '10px',
38
+ } );
39
+ } );
40
+ } );
package/src/box/types.ts CHANGED
@@ -37,6 +37,21 @@ type ForegroundColor =
37
37
  | 'error'
38
38
  | 'error-weak';
39
39
 
40
+ type StrokeColor =
41
+ | 'brand'
42
+ | 'brand-strong'
43
+ | 'error'
44
+ | 'error-strong'
45
+ | 'info'
46
+ | 'info-strong'
47
+ | 'neutral'
48
+ | 'neutral-strong'
49
+ | 'neutral-weak'
50
+ | 'success'
51
+ | 'success-strong'
52
+ | 'warning'
53
+ | 'warning-strong';
54
+
40
55
  type DimensionVariant< T > = {
41
56
  block?: T;
42
57
  blockStart?: T;
@@ -67,6 +82,21 @@ export interface BoxProps extends ComponentProps< 'div' > {
67
82
  */
68
83
  padding?: Size | DimensionVariant< Size >;
69
84
 
85
+ /**
86
+ * The surface border radius design token.
87
+ */
88
+ borderRadius?: Exclude< SizeToken, '2xs' >;
89
+
90
+ /**
91
+ * The surface border width design token.
92
+ */
93
+ borderWidth?: Exclude< SizeToken, '2xs' >;
94
+
95
+ /**
96
+ * The surface border stroke color design token.
97
+ */
98
+ borderColor?: StrokeColor;
99
+
70
100
  /**
71
101
  * The content to be rendered inside the component.
72
102
  */
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ export { Stack } from './stack';