@wordpress/ui 0.4.1-next.76cff8c98.0 → 0.5.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 (240) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/build/badge/badge.cjs.map +2 -2
  3. package/build/badge/types.cjs.map +1 -1
  4. package/build/button/button.cjs +401 -0
  5. package/build/button/button.cjs.map +7 -0
  6. package/build/button/icon.cjs +47 -0
  7. package/build/button/icon.cjs.map +7 -0
  8. package/build/button/index.cjs +39 -0
  9. package/build/button/index.cjs.map +7 -0
  10. package/build/button/types.cjs +19 -0
  11. package/build/button/types.cjs.map +7 -0
  12. package/build/form/primitives/field/root.cjs.map +2 -2
  13. package/build/form/primitives/fieldset/context.cjs +40 -0
  14. package/build/form/primitives/fieldset/context.cjs.map +7 -0
  15. package/build/form/primitives/fieldset/description.cjs +101 -0
  16. package/build/form/primitives/fieldset/description.cjs.map +7 -0
  17. package/build/form/primitives/fieldset/details.cjs +103 -0
  18. package/build/form/primitives/fieldset/details.cjs.map +7 -0
  19. package/build/form/primitives/fieldset/index.cjs +40 -0
  20. package/build/form/primitives/fieldset/index.cjs.map +7 -0
  21. package/build/form/primitives/fieldset/legend.cjs +94 -0
  22. package/build/form/primitives/fieldset/legend.cjs.map +7 -0
  23. package/build/form/primitives/fieldset/root.cjs +86 -0
  24. package/build/form/primitives/fieldset/root.cjs.map +7 -0
  25. package/build/form/primitives/fieldset/types.cjs +19 -0
  26. package/build/form/primitives/fieldset/types.cjs.map +7 -0
  27. package/build/form/primitives/index.cjs +11 -2
  28. package/build/form/primitives/index.cjs.map +2 -2
  29. package/build/form/primitives/input/index.cjs +31 -0
  30. package/build/form/primitives/input/index.cjs.map +7 -0
  31. package/build/form/primitives/input/input.cjs +148 -0
  32. package/build/form/primitives/input/input.cjs.map +7 -0
  33. package/build/form/primitives/input/types.cjs +19 -0
  34. package/build/form/primitives/input/types.cjs.map +7 -0
  35. package/build/form/primitives/input-layout/context.cjs +49 -0
  36. package/build/form/primitives/input-layout/context.cjs.map +7 -0
  37. package/build/form/primitives/input-layout/index.cjs +35 -0
  38. package/build/form/primitives/input-layout/index.cjs.map +7 -0
  39. package/build/form/primitives/input-layout/input-layout.cjs +196 -0
  40. package/build/form/primitives/input-layout/input-layout.cjs.map +7 -0
  41. package/build/form/primitives/input-layout/slot.cjs +165 -0
  42. package/build/form/primitives/input-layout/slot.cjs.map +7 -0
  43. package/build/form/primitives/input-layout/types.cjs +19 -0
  44. package/build/form/primitives/input-layout/types.cjs.map +7 -0
  45. package/build/icon/icon.cjs +46 -0
  46. package/build/icon/icon.cjs.map +7 -0
  47. package/build/icon/index.cjs +31 -0
  48. package/build/icon/index.cjs.map +7 -0
  49. package/build/icon/types.cjs +19 -0
  50. package/build/icon/types.cjs.map +7 -0
  51. package/build/index.cjs +4 -0
  52. package/build/index.cjs.map +2 -2
  53. package/build-module/badge/badge.mjs.map +2 -2
  54. package/build-module/button/button.mjs +366 -0
  55. package/build-module/button/button.mjs.map +7 -0
  56. package/build-module/button/icon.mjs +22 -0
  57. package/build-module/button/icon.mjs.map +7 -0
  58. package/build-module/button/index.mjs +14 -0
  59. package/build-module/button/index.mjs.map +7 -0
  60. package/build-module/button/types.mjs +1 -0
  61. package/build-module/button/types.mjs.map +7 -0
  62. package/build-module/form/primitives/field/root.mjs.map +2 -2
  63. package/build-module/form/primitives/fieldset/context.mjs +14 -0
  64. package/build-module/form/primitives/fieldset/context.mjs.map +7 -0
  65. package/build-module/form/primitives/fieldset/description.mjs +66 -0
  66. package/build-module/form/primitives/fieldset/description.mjs.map +7 -0
  67. package/build-module/form/primitives/fieldset/details.mjs +68 -0
  68. package/build-module/form/primitives/fieldset/details.mjs.map +7 -0
  69. package/build-module/form/primitives/fieldset/index.mjs +12 -0
  70. package/build-module/form/primitives/fieldset/index.mjs.map +7 -0
  71. package/build-module/form/primitives/fieldset/legend.mjs +59 -0
  72. package/build-module/form/primitives/fieldset/legend.mjs.map +7 -0
  73. package/build-module/form/primitives/fieldset/root.mjs +51 -0
  74. package/build-module/form/primitives/fieldset/root.mjs.map +7 -0
  75. package/build-module/form/primitives/fieldset/types.mjs +1 -0
  76. package/build-module/form/primitives/fieldset/types.mjs.map +7 -0
  77. package/build-module/form/primitives/index.mjs +7 -1
  78. package/build-module/form/primitives/index.mjs.map +2 -2
  79. package/build-module/form/primitives/input/index.mjs +6 -0
  80. package/build-module/form/primitives/input/index.mjs.map +7 -0
  81. package/build-module/form/primitives/input/input.mjs +113 -0
  82. package/build-module/form/primitives/input/input.mjs.map +7 -0
  83. package/build-module/form/primitives/input/types.mjs +1 -0
  84. package/build-module/form/primitives/input/types.mjs.map +7 -0
  85. package/build-module/form/primitives/input-layout/context.mjs +22 -0
  86. package/build-module/form/primitives/input-layout/context.mjs.map +7 -0
  87. package/build-module/form/primitives/input-layout/index.mjs +10 -0
  88. package/build-module/form/primitives/input-layout/index.mjs.map +7 -0
  89. package/build-module/form/primitives/input-layout/input-layout.mjs +161 -0
  90. package/build-module/form/primitives/input-layout/input-layout.mjs.map +7 -0
  91. package/build-module/form/primitives/input-layout/slot.mjs +130 -0
  92. package/build-module/form/primitives/input-layout/slot.mjs.map +7 -0
  93. package/build-module/form/primitives/input-layout/types.mjs +1 -0
  94. package/build-module/form/primitives/input-layout/types.mjs.map +7 -0
  95. package/build-module/icon/icon.mjs +21 -0
  96. package/build-module/icon/icon.mjs.map +7 -0
  97. package/build-module/icon/index.mjs +6 -0
  98. package/build-module/icon/index.mjs.map +7 -0
  99. package/build-module/icon/types.mjs +1 -0
  100. package/build-module/icon/types.mjs.map +7 -0
  101. package/build-module/index.mjs +2 -0
  102. package/build-module/index.mjs.map +2 -2
  103. package/build-types/badge/badge.d.ts.map +1 -1
  104. package/build-types/badge/stories/index.story.d.ts +1 -7
  105. package/build-types/badge/stories/index.story.d.ts.map +1 -1
  106. package/build-types/badge/types.d.ts +0 -3
  107. package/build-types/badge/types.d.ts.map +1 -1
  108. package/build-types/box/stories/index.story.d.ts +1 -1
  109. package/build-types/box/stories/index.story.d.ts.map +1 -1
  110. package/build-types/button/button.d.ts +3 -0
  111. package/build-types/button/button.d.ts.map +1 -0
  112. package/build-types/button/icon.d.ts +10 -0
  113. package/build-types/button/icon.d.ts.map +1 -0
  114. package/build-types/button/index.d.ts +10 -0
  115. package/build-types/button/index.d.ts.map +1 -0
  116. package/build-types/button/stories/index.story.d.ts +23 -0
  117. package/build-types/button/stories/index.story.d.ts.map +1 -0
  118. package/build-types/button/test/button.test.d.ts +2 -0
  119. package/build-types/button/test/button.test.d.ts.map +1 -0
  120. package/build-types/button/test/icon.test.d.ts +2 -0
  121. package/build-types/button/test/icon.test.d.ts.map +1 -0
  122. package/build-types/button/types.d.ts +63 -0
  123. package/build-types/button/types.d.ts.map +1 -0
  124. package/build-types/form/primitives/field/control.d.ts +1 -1
  125. package/build-types/form/primitives/field/description.d.ts +1 -1
  126. package/build-types/form/primitives/field/label.d.ts +1 -1
  127. package/build-types/form/primitives/field/root.d.ts +3 -1
  128. package/build-types/form/primitives/field/root.d.ts.map +1 -1
  129. package/build-types/form/primitives/field/stories/index.story.d.ts +1 -1
  130. package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
  131. package/build-types/form/primitives/fieldset/context.d.ts +8 -0
  132. package/build-types/form/primitives/fieldset/context.d.ts.map +1 -0
  133. package/build-types/form/primitives/fieldset/description.d.ts +9 -0
  134. package/build-types/form/primitives/fieldset/description.d.ts.map +1 -0
  135. package/build-types/form/primitives/fieldset/details.d.ts +21 -0
  136. package/build-types/form/primitives/fieldset/details.d.ts.map +1 -0
  137. package/build-types/form/primitives/fieldset/index.d.ts +6 -0
  138. package/build-types/form/primitives/fieldset/index.d.ts.map +1 -0
  139. package/build-types/form/primitives/fieldset/legend.d.ts +9 -0
  140. package/build-types/form/primitives/fieldset/legend.d.ts.map +1 -0
  141. package/build-types/form/primitives/fieldset/root.d.ts +15 -0
  142. package/build-types/form/primitives/fieldset/root.d.ts.map +1 -0
  143. package/build-types/form/primitives/fieldset/stories/index.story.d.ts +18 -0
  144. package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -0
  145. package/build-types/form/primitives/fieldset/test/index.test.d.ts +2 -0
  146. package/build-types/form/primitives/fieldset/test/index.test.d.ts.map +1 -0
  147. package/build-types/form/primitives/fieldset/types.d.ts +32 -0
  148. package/build-types/form/primitives/fieldset/types.d.ts.map +1 -0
  149. package/build-types/form/primitives/index.d.ts +3 -0
  150. package/build-types/form/primitives/index.d.ts.map +1 -1
  151. package/build-types/form/primitives/input/index.d.ts +2 -0
  152. package/build-types/form/primitives/input/index.d.ts.map +1 -0
  153. package/build-types/form/primitives/input/input.d.ts +10 -0
  154. package/build-types/form/primitives/input/input.d.ts.map +1 -0
  155. package/build-types/form/primitives/input/stories/index.story.d.ts +13 -0
  156. package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -0
  157. package/build-types/form/primitives/input/test/index.test.d.ts +2 -0
  158. package/build-types/form/primitives/input/test/index.test.d.ts.map +1 -0
  159. package/build-types/form/primitives/input/types.d.ts +27 -0
  160. package/build-types/form/primitives/input/types.d.ts.map +1 -0
  161. package/build-types/form/primitives/input-layout/context.d.ts +17 -0
  162. package/build-types/form/primitives/input-layout/context.d.ts.map +1 -0
  163. package/build-types/form/primitives/input-layout/index.d.ts +4 -0
  164. package/build-types/form/primitives/input-layout/index.d.ts.map +1 -0
  165. package/build-types/form/primitives/input-layout/input-layout.d.ts +7 -0
  166. package/build-types/form/primitives/input-layout/input-layout.d.ts.map +1 -0
  167. package/build-types/form/primitives/input-layout/slot.d.ts +6 -0
  168. package/build-types/form/primitives/input-layout/slot.d.ts.map +1 -0
  169. package/build-types/form/primitives/input-layout/stories/index.story.d.ts +24 -0
  170. package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -0
  171. package/build-types/form/primitives/input-layout/test/index.test.d.ts +2 -0
  172. package/build-types/form/primitives/input-layout/test/index.test.d.ts.map +1 -0
  173. package/build-types/form/primitives/input-layout/types.d.ts +41 -0
  174. package/build-types/form/primitives/input-layout/types.d.ts.map +1 -0
  175. package/build-types/icon/icon.d.ts +14 -0
  176. package/build-types/icon/icon.d.ts.map +1 -0
  177. package/build-types/icon/index.d.ts +2 -0
  178. package/build-types/icon/index.d.ts.map +1 -0
  179. package/build-types/icon/stories/index.story.d.ts +11 -0
  180. package/build-types/icon/stories/index.story.d.ts.map +1 -0
  181. package/build-types/icon/test/icon.test.d.ts +2 -0
  182. package/build-types/icon/test/icon.test.d.ts.map +1 -0
  183. package/build-types/icon/types.d.ts +15 -0
  184. package/build-types/icon/types.d.ts.map +1 -0
  185. package/build-types/index.d.ts +2 -0
  186. package/build-types/index.d.ts.map +1 -1
  187. package/build-types/stack/stories/index.story.d.ts +1 -1
  188. package/build-types/stack/stories/index.story.d.ts.map +1 -1
  189. package/build-types/visually-hidden/stories/index.story.d.ts +1 -1
  190. package/build-types/visually-hidden/stories/index.story.d.ts.map +1 -1
  191. package/package.json +14 -5
  192. package/src/badge/badge.tsx +0 -7
  193. package/src/badge/stories/index.story.tsx +1 -14
  194. package/src/badge/types.ts +0 -3
  195. package/src/box/stories/index.story.tsx +1 -2
  196. package/src/button/button.tsx +57 -0
  197. package/src/button/icon.tsx +24 -0
  198. package/src/button/index.ts +16 -0
  199. package/src/button/stories/index.story.tsx +192 -0
  200. package/src/button/style.module.css +232 -0
  201. package/src/button/test/button.test.tsx +89 -0
  202. package/src/button/test/icon.test.tsx +13 -0
  203. package/src/button/types.ts +72 -0
  204. package/src/form/primitives/field/root.tsx +2 -0
  205. package/src/form/primitives/field/stories/index.story.tsx +1 -1
  206. package/src/form/primitives/fieldset/context.tsx +13 -0
  207. package/src/form/primitives/fieldset/description.tsx +36 -0
  208. package/src/form/primitives/fieldset/details.tsx +46 -0
  209. package/src/form/primitives/fieldset/index.ts +6 -0
  210. package/src/form/primitives/fieldset/legend.tsx +17 -0
  211. package/src/form/primitives/fieldset/root.tsx +42 -0
  212. package/src/form/primitives/fieldset/stories/index.story.tsx +67 -0
  213. package/src/form/primitives/fieldset/style.module.css +12 -0
  214. package/src/form/primitives/fieldset/test/index.test.tsx +135 -0
  215. package/src/form/primitives/fieldset/types.ts +35 -0
  216. package/src/form/primitives/index.ts +3 -0
  217. package/src/form/primitives/input/index.ts +1 -0
  218. package/src/form/primitives/input/input.tsx +28 -0
  219. package/src/form/primitives/input/stories/index.story.tsx +40 -0
  220. package/src/form/primitives/input/style.module.css +34 -0
  221. package/src/form/primitives/input/test/index.test.tsx +13 -0
  222. package/src/form/primitives/input/types.ts +31 -0
  223. package/src/form/primitives/input-layout/context.tsx +36 -0
  224. package/src/form/primitives/input-layout/index.ts +6 -0
  225. package/src/form/primitives/input-layout/input-layout.tsx +49 -0
  226. package/src/form/primitives/input-layout/slot.tsx +39 -0
  227. package/src/form/primitives/input-layout/stories/index.story.tsx +67 -0
  228. package/src/form/primitives/input-layout/style.module.css +82 -0
  229. package/src/form/primitives/input-layout/test/index.test.tsx +23 -0
  230. package/src/form/primitives/input-layout/types.ts +44 -0
  231. package/src/icon/icon.tsx +30 -0
  232. package/src/icon/index.ts +1 -0
  233. package/src/icon/stories/index.story.tsx +47 -0
  234. package/src/icon/test/icon.test.tsx +13 -0
  235. package/src/icon/types.ts +14 -0
  236. package/src/index.ts +2 -0
  237. package/src/stack/stories/index.story.tsx +1 -2
  238. package/src/stories/introduction.mdx +6 -0
  239. package/src/utils/css/focus.module.css +31 -0
  240. package/src/visually-hidden/stories/index.story.tsx +1 -1
@@ -0,0 +1,39 @@
1
+ import clsx from 'clsx';
2
+ import { forwardRef } from '@wordpress/element';
3
+ import styles from './style.module.css';
4
+ import type { InputLayoutSlotProps } from './types';
5
+ import { useInputLayoutSlotContext } from './context';
6
+
7
+ /**
8
+ * A layout helper to add paddings in a prefix or suffix.
9
+ */
10
+ export const InputLayoutSlot = forwardRef<
11
+ HTMLDivElement,
12
+ InputLayoutSlotProps
13
+ >( function InputLayoutSlot(
14
+ { type: typeProp, padding = 'default', ...restProps },
15
+ ref
16
+ ) {
17
+ const typeContext = useInputLayoutSlotContext();
18
+ const type = typeProp ?? typeContext;
19
+
20
+ if ( ! type ) {
21
+ throw new Error(
22
+ 'InputLayoutSlot requires a `type` prop or must be used within an InputLayout prefix/suffix slot.'
23
+ );
24
+ }
25
+
26
+ return (
27
+ <div
28
+ ref={ ref }
29
+ className={ clsx(
30
+ styles[ 'input-layout-slot' ],
31
+ styles[ `is-${ type }` ],
32
+ styles[ `is-padding-${ padding }` ]
33
+ ) }
34
+ { ...restProps }
35
+ />
36
+ );
37
+ } );
38
+
39
+ InputLayoutSlot.displayName = 'InputLayout.Slot';
@@ -0,0 +1,67 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { InputLayout } from '../../../..';
3
+
4
+ const meta: Meta< typeof InputLayout > = {
5
+ title: 'Design System/Components/Form/Primitives/InputLayout',
6
+ component: InputLayout,
7
+ subcomponents: {
8
+ Slot: InputLayout.Slot,
9
+ },
10
+ };
11
+ export default meta;
12
+
13
+ type Story = StoryObj< typeof InputLayout >;
14
+
15
+ export const Default: Story = {
16
+ args: {},
17
+ };
18
+
19
+ /**
20
+ * By default, the `prefix` and `suffix` slots are rendered with no padding.
21
+ */
22
+ export const WithPrefix: Story = {
23
+ args: {
24
+ prefix: (
25
+ <div
26
+ style={ {
27
+ display: 'flex',
28
+ alignItems: 'center',
29
+ justifyContent: 'center',
30
+ height: '100%',
31
+ aspectRatio: '1 / 1',
32
+ background: '#eee',
33
+ } }
34
+ >
35
+ $
36
+ </div>
37
+ ),
38
+ },
39
+ };
40
+
41
+ /**
42
+ * The `InputLayout.Slot` component can be used to add standard padding in
43
+ * the `prefix` or `suffix` slot.
44
+ *
45
+ * The `padding="minimal"` setting will work best when the slot content is a button or icon.
46
+ */
47
+ export const WithPaddedPrefix: Story = {
48
+ args: {
49
+ prefix: <InputLayout.Slot>https://</InputLayout.Slot>,
50
+ },
51
+ };
52
+
53
+ export const Compact: Story = {
54
+ args: {
55
+ size: 'compact',
56
+ },
57
+ };
58
+
59
+ /**
60
+ * The `small` size is intended only for rare cases like the trigger
61
+ * button of a low-profile `select` element.
62
+ */
63
+ export const Small: Story = {
64
+ args: {
65
+ size: 'small',
66
+ },
67
+ };
@@ -0,0 +1,82 @@
1
+ @layer wp-ui-utilities, wp-ui-components, wp-ui-compositions, wp-ui-overrides;
2
+
3
+ @layer wp-ui-components {
4
+ .input-layout {
5
+ /* TODO: Use padding tokens */
6
+ --wp-ui-input-layout-padding-inline: calc(var(--wpds-dimension-base) * 3);
7
+
8
+ display: flex;
9
+ height: 40px;
10
+ background-color: var(--wpds-color-bg-interactive-neutral-weak);
11
+ border-width: var(--wpds-border-width-surface-xs);
12
+ border-style: solid;
13
+ border-color: var(--wpds-color-stroke-interactive-neutral);
14
+ border-radius: var(--wpds-border-radius-surface-sm);
15
+ font-family: var(--wpds-font-family-body);
16
+ font-size: max(var(--wpds-font-size-md), 16px); /* avoid mobile zoom */
17
+ line-height: 1;
18
+ color: var(--wpds-color-fg-interactive-neutral);
19
+
20
+ @media (min-width: 600px) {
21
+ font-size: var(--wpds-font-size-md);
22
+ }
23
+
24
+ &.is-size-compact {
25
+ /* TODO: Use padding tokens */
26
+ --wp-ui-input-layout-padding-inline: calc(var(--wpds-dimension-base) * 2);
27
+ height: 32px;
28
+ }
29
+
30
+ &.is-size-small {
31
+ /* TODO: Use padding tokens */
32
+ --wp-ui-input-layout-padding-inline: calc(var(--wpds-dimension-base) * 2);
33
+ height: 24px;
34
+ }
35
+
36
+ &.is-disabled {
37
+ background-color: var(--wpds-color-bg-interactive-neutral-weak-disabled);
38
+ border-color: var(--wpds-color-stroke-interactive-neutral-disabled);
39
+ color: var(--wpds-color-fg-interactive-neutral-disabled);
40
+
41
+ @media (forced-colors: active) {
42
+ border-color: GrayText;
43
+ color: GrayText;
44
+ }
45
+ }
46
+
47
+ &.is-borderless {
48
+ border-color: transparent;
49
+ }
50
+
51
+ /* Don't show focus ring when the focus is in the prefix or suffix slots */
52
+ &:has(.input-layout-slot:focus-within) {
53
+ outline: none;
54
+ }
55
+
56
+ &:hover:not(.is-disabled, .is-borderless) {
57
+ border-color: var(--wpds-color-stroke-interactive-neutral-active);
58
+ }
59
+ }
60
+
61
+ .input-layout-slot {
62
+ display: flex;
63
+ align-items: center;
64
+
65
+ &.is-padding-minimal {
66
+ --wp-ui-input-layout-prefix-padding-start:
67
+ calc(var(--wp-ui-input-layout-padding-inline) -
68
+ var(--wpds-dimension-base));
69
+ --wp-ui-input-layout-suffix-padding-end:
70
+ calc(var(--wp-ui-input-layout-padding-inline) -
71
+ var(--wpds-dimension-base));
72
+ }
73
+
74
+ &.is-prefix {
75
+ padding-inline-start: var(--wp-ui-input-layout-prefix-padding-start, var(--wp-ui-input-layout-padding-inline));
76
+ }
77
+
78
+ &.is-suffix {
79
+ padding-inline-end: var(--wp-ui-input-layout-suffix-padding-end, var(--wp-ui-input-layout-padding-inline));
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,23 @@
1
+ import { render } from '@testing-library/react';
2
+ import { createRef } from '@wordpress/element';
3
+ import { InputLayout } from '../index';
4
+ import { InputLayoutSlot } from '../slot';
5
+
6
+ describe( 'InputLayout', () => {
7
+ it( 'forwards ref', () => {
8
+ const layoutRef = createRef< HTMLDivElement >();
9
+ const slotRef = createRef< HTMLDivElement >();
10
+
11
+ render(
12
+ <InputLayout
13
+ ref={ layoutRef }
14
+ prefix={
15
+ <InputLayoutSlot ref={ slotRef }>Prefix</InputLayoutSlot>
16
+ }
17
+ />
18
+ );
19
+
20
+ expect( layoutRef.current ).toBeInstanceOf( HTMLDivElement );
21
+ expect( slotRef.current ).toBeInstanceOf( HTMLDivElement );
22
+ } );
23
+ } );
@@ -0,0 +1,44 @@
1
+ export interface InputLayoutProps
2
+ extends Omit< React.HTMLAttributes< HTMLDivElement >, 'prefix' > {
3
+ /**
4
+ * Whether the field should be visually styled as disabled.
5
+ */
6
+ visuallyDisabled?: boolean;
7
+ /**
8
+ * The size of the field.
9
+ *
10
+ * @default 'default'
11
+ */
12
+ size?: 'default' | 'compact' | 'small';
13
+ /**
14
+ * Whether the field should hide the border.
15
+ */
16
+ isBorderless?: boolean;
17
+ /**
18
+ * Element to render before the input.
19
+ */
20
+ prefix?: React.ReactNode;
21
+ /**
22
+ * Element to render after the input.
23
+ */
24
+ suffix?: React.ReactNode;
25
+ }
26
+
27
+ export type InputLayoutSlotType = 'prefix' | 'suffix';
28
+
29
+ export interface InputLayoutSlotProps
30
+ extends Omit< React.HTMLAttributes< HTMLDivElement >, 'type' > {
31
+ /**
32
+ * The type of the slot.
33
+ *
34
+ * When not provided, the type will be automatically inferred from the
35
+ * `InputLayout` context if the slot is used within a `prefix` or `suffix`.
36
+ */
37
+ type?: InputLayoutSlotType;
38
+ /**
39
+ * The padding of the slot.
40
+ *
41
+ * `minimal` will work best when the slot content is a button or icon.
42
+ */
43
+ padding?: 'default' | 'minimal';
44
+ }
@@ -0,0 +1,30 @@
1
+ import { forwardRef } from '@wordpress/element';
2
+ import { SVG } from '@wordpress/primitives';
3
+ import type { IconProps } from './types';
4
+
5
+ /**
6
+ * Renders an SVG icon with a 24px default size.
7
+ *
8
+ * If no `fill` colors are explicitly set on the icon itself, it will be rendered with a `currentColor` fill.
9
+ *
10
+ * ```jsx
11
+ * import { wordpress } from '@wordpress/icons';
12
+ *
13
+ * <Icon icon={ wordpress } />
14
+ * ```
15
+ */
16
+ export const Icon = forwardRef< SVGSVGElement, IconProps >( function Icon(
17
+ { icon, size = 24, ...restProps },
18
+ ref
19
+ ) {
20
+ return (
21
+ <SVG
22
+ ref={ ref }
23
+ fill="currentColor"
24
+ { ...icon.props }
25
+ { ...restProps }
26
+ width={ size }
27
+ height={ size }
28
+ />
29
+ );
30
+ } );
@@ -0,0 +1 @@
1
+ export { Icon } from './icon';
@@ -0,0 +1,47 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { wordpress } from '@wordpress/icons';
3
+ import { Icon } from '../index';
4
+
5
+ const meta: Meta< typeof Icon > = {
6
+ title: 'Design System/Components/Icon',
7
+ component: Icon,
8
+ decorators: [
9
+ ( Story ) => {
10
+ return (
11
+ <div
12
+ style={ {
13
+ color: 'var( --wpds-color-fg-content-neutral )',
14
+ } }
15
+ >
16
+ <Story />
17
+ </div>
18
+ );
19
+ },
20
+ ],
21
+ };
22
+ export default meta;
23
+
24
+ type Story = StoryObj< typeof Icon >;
25
+
26
+ export const Default: Story = {
27
+ args: {
28
+ icon: wordpress,
29
+ },
30
+ };
31
+
32
+ /**
33
+ * Explicit `fill` colors in the icon will be preserved.
34
+ */
35
+ export const WithIntrinsicFillColor: Story = {
36
+ args: {
37
+ icon: (
38
+ <svg
39
+ xmlns="http://www.w3.org/2000/svg"
40
+ viewBox="0 0 24 24"
41
+ fill="blue"
42
+ >
43
+ <rect x="0" y="0" width="24" height="24" />
44
+ </svg>
45
+ ),
46
+ },
47
+ };
@@ -0,0 +1,13 @@
1
+ import { render } from '@testing-library/react';
2
+ import { createRef } from '@wordpress/element';
3
+ import { Icon } from '../index';
4
+
5
+ describe( 'Icon', () => {
6
+ it( 'forwards ref', () => {
7
+ const ref = createRef< SVGSVGElement >();
8
+
9
+ render( <Icon ref={ ref } icon={ <svg /> } /> );
10
+
11
+ expect( ref.current ).toBeInstanceOf( SVGSVGElement );
12
+ } );
13
+ } );
@@ -0,0 +1,14 @@
1
+ export type IconProps = React.ComponentProps< 'svg' > & {
2
+ /**
3
+ * The icon to render, which must be an svg element or an `SVG` from `@wordpress/primitives`.
4
+ *
5
+ * In most cases, you should use an icon from
6
+ * [the `@wordpress/icons` package](https://wordpress.github.io/gutenberg/?path=/story/icons-icon--library).
7
+ */
8
+ icon: React.ReactElement< React.ComponentProps< 'svg' > >;
9
+ /**
10
+ * The size (width and height) of the icon.
11
+ * @default 24
12
+ */
13
+ size?: number;
14
+ };
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './badge';
2
2
  export * from './box';
3
+ export * from './button';
3
4
  export * from './form/primitives';
5
+ export * from './icon';
4
6
  export * from './stack';
5
7
  export * from './visually-hidden';
@@ -1,11 +1,10 @@
1
- import type { Meta, StoryObj } from '@storybook/react-webpack5';
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { Stack } from '../index';
3
3
  import { Box } from '../../box';
4
4
 
5
5
  const meta: Meta< typeof Stack > = {
6
6
  title: 'Design System/Components/Stack',
7
7
  component: Stack,
8
- tags: [ 'status-experimental' ],
9
8
  };
10
9
  export default meta;
11
10
 
@@ -0,0 +1,6 @@
1
+ import { Meta, Markdown } from '@storybook/addon-docs/blocks';
2
+ import Readme from '../../README.md?raw';
3
+
4
+ <Meta title="Design System/Components/Introduction" />
5
+
6
+ <Markdown>{Readme}</Markdown>
@@ -0,0 +1,31 @@
1
+ @layer wp-ui-utilities, wp-ui-components, wp-ui-compositions, wp-ui-overrides;
2
+
3
+ @layer wp-ui-utilities {
4
+ .outset-ring--focus,
5
+ .outset-ring--focus-except-active,
6
+ .outset-ring--focus-visible,
7
+ .outset-ring--focus-within,
8
+ .outset-ring--focus-within-except-active,
9
+ .outset-ring--focus-within-visible {
10
+ @media not ( prefers-reduced-motion ) {
11
+ transition: outline 0.1s ease-out;
12
+ }
13
+
14
+ /* Outline width must be kept at 0 even with a transparent color,
15
+ or else the outline will be visible in forced-colors mode. */
16
+ outline-width: 0;
17
+ outline-style: solid;
18
+ outline-color: transparent;
19
+ outline-offset: 1px;
20
+ }
21
+
22
+ .outset-ring--focus:focus,
23
+ .outset-ring--focus-except-active:focus:not(:active),
24
+ .outset-ring--focus-visible:focus-visible,
25
+ .outset-ring--focus-within:focus-within,
26
+ .outset-ring--focus-within-except-active:focus-within:not(:has(:active)),
27
+ .outset-ring--focus-within-visible:focus-within:has(:focus-visible) {
28
+ outline-width: var(--wpds-border-width-interactive-focus);
29
+ outline-color: var(--wpds-color-stroke-focus-brand);
30
+ }
31
+ }
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from '@storybook/react-webpack5';
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { VisuallyHidden } from '../';
3
3
 
4
4
  const meta: Meta< typeof VisuallyHidden > = {