@wordpress/components 25.11.1-next.f8d8eceb.0 → 25.13.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 (317) hide show
  1. package/CHANGELOG.md +58 -1
  2. package/build/angle-picker-control/index.js +0 -1
  3. package/build/angle-picker-control/index.js.map +1 -1
  4. package/build/custom-select-control-v2/index.js +87 -0
  5. package/build/custom-select-control-v2/index.js.map +1 -0
  6. package/build/custom-select-control-v2/styles.js +85 -0
  7. package/build/custom-select-control-v2/styles.js.map +1 -0
  8. package/build/custom-select-control-v2/types.js +6 -0
  9. package/build/custom-select-control-v2/types.js.map +1 -0
  10. package/build/disclosure/index.js +37 -7
  11. package/build/disclosure/index.js.map +1 -1
  12. package/build/disclosure/types.js +6 -0
  13. package/build/disclosure/types.js.map +1 -0
  14. package/build/divider/component.js +5 -3
  15. package/build/divider/component.js.map +1 -1
  16. package/build/divider/types.js.map +1 -1
  17. package/build/dropdown-menu-v2-ariakit/index.js +74 -35
  18. package/build/dropdown-menu-v2-ariakit/index.js.map +1 -1
  19. package/build/dropdown-menu-v2-ariakit/styles.js +82 -59
  20. package/build/dropdown-menu-v2-ariakit/styles.js.map +1 -1
  21. package/build/dropdown-menu-v2-ariakit/types.js.map +1 -1
  22. package/build/form-token-field/index.js +6 -2
  23. package/build/form-token-field/index.js.map +1 -1
  24. package/build/form-token-field/token-input.js.map +1 -1
  25. package/build/form-token-field/types.js.map +1 -1
  26. package/build/gradient-picker/index.js +1 -1
  27. package/build/gradient-picker/index.js.map +1 -1
  28. package/build/heading/hook.js +6 -3
  29. package/build/heading/hook.js.map +1 -1
  30. package/build/heading/types.js.map +1 -1
  31. package/build/index.native.js +8 -1
  32. package/build/index.native.js.map +1 -1
  33. package/build/mobile/audio-player/index.native.js +8 -9
  34. package/build/mobile/audio-player/index.native.js.map +1 -1
  35. package/build/mobile/global-styles-context/utils.native.js +44 -3
  36. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  37. package/build/mobile/utils/alignments.native.js +1 -1
  38. package/build/mobile/utils/alignments.native.js.map +1 -1
  39. package/build/private-apis.js +3 -2
  40. package/build/private-apis.js.map +1 -1
  41. package/build/radio-group/context.js +22 -0
  42. package/build/radio-group/context.js.map +1 -0
  43. package/build/radio-group/index.js +27 -23
  44. package/build/radio-group/index.js.map +1 -1
  45. package/build/radio-group/radio.js +58 -0
  46. package/build/radio-group/radio.js.map +1 -0
  47. package/build/radio-group/types.js +6 -0
  48. package/build/radio-group/types.js.map +1 -0
  49. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
  50. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  51. package/build/slot-fill/types.js.map +1 -1
  52. package/build/tabs/index.js +6 -4
  53. package/build/tabs/index.js.map +1 -1
  54. package/build/tabs/styles.js +14 -7
  55. package/build/tabs/styles.js.map +1 -1
  56. package/build/tabs/tab.js +5 -7
  57. package/build/tabs/tab.js.map +1 -1
  58. package/build/tabs/tablist.js +3 -5
  59. package/build/tabs/tablist.js.map +1 -1
  60. package/build/tabs/tabpanel.js +7 -10
  61. package/build/tabs/tabpanel.js.map +1 -1
  62. package/build/tabs/types.js.map +1 -1
  63. package/build/text/types.js.map +1 -1
  64. package/build/text-control/index.js +5 -1
  65. package/build/text-control/index.js.map +1 -1
  66. package/build/text-control/types.js.map +1 -1
  67. package/build/toggle-group-control/toggle-group-control/component.js +4 -2
  68. package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
  69. package/build/toggle-group-control/toggle-group-control/styles.js +13 -9
  70. package/build/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  71. package/build/toggle-group-control/types.js.map +1 -1
  72. package/build/tools-panel/tools-panel-item/hook.js +5 -1
  73. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  74. package/build-module/angle-picker-control/index.js +0 -1
  75. package/build-module/angle-picker-control/index.js.map +1 -1
  76. package/build-module/custom-select-control-v2/index.js +74 -0
  77. package/build-module/custom-select-control-v2/index.js.map +1 -0
  78. package/build-module/custom-select-control-v2/styles.js +71 -0
  79. package/build-module/custom-select-control-v2/styles.js.map +1 -0
  80. package/build-module/custom-select-control-v2/types.js +2 -0
  81. package/build-module/custom-select-control-v2/types.js.map +1 -0
  82. package/build-module/disclosure/index.js +33 -8
  83. package/build-module/disclosure/index.js.map +1 -1
  84. package/build-module/disclosure/types.js +2 -0
  85. package/build-module/disclosure/types.js.map +1 -0
  86. package/build-module/divider/component.js +3 -3
  87. package/build-module/divider/component.js.map +1 -1
  88. package/build-module/divider/types.js.map +1 -1
  89. package/build-module/dropdown-menu-v2-ariakit/index.js +72 -34
  90. package/build-module/dropdown-menu-v2-ariakit/index.js.map +1 -1
  91. package/build-module/dropdown-menu-v2-ariakit/styles.js +69 -40
  92. package/build-module/dropdown-menu-v2-ariakit/styles.js.map +1 -1
  93. package/build-module/dropdown-menu-v2-ariakit/types.js.map +1 -1
  94. package/build-module/form-token-field/index.js +6 -2
  95. package/build-module/form-token-field/index.js.map +1 -1
  96. package/build-module/form-token-field/token-input.js.map +1 -1
  97. package/build-module/form-token-field/types.js.map +1 -1
  98. package/build-module/gradient-picker/index.js +1 -1
  99. package/build-module/gradient-picker/index.js.map +1 -1
  100. package/build-module/heading/hook.js +6 -3
  101. package/build-module/heading/hook.js.map +1 -1
  102. package/build-module/heading/types.js.map +1 -1
  103. package/build-module/index.native.js +1 -1
  104. package/build-module/index.native.js.map +1 -1
  105. package/build-module/mobile/audio-player/index.native.js +9 -10
  106. package/build-module/mobile/audio-player/index.native.js.map +1 -1
  107. package/build-module/mobile/global-styles-context/utils.native.js +43 -4
  108. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  109. package/build-module/mobile/utils/alignments.native.js +1 -1
  110. package/build-module/mobile/utils/alignments.native.js.map +1 -1
  111. package/build-module/private-apis.js +4 -3
  112. package/build-module/private-apis.js.map +1 -1
  113. package/build-module/radio-group/context.js +14 -0
  114. package/build-module/radio-group/context.js.map +1 -0
  115. package/build-module/radio-group/index.js +24 -23
  116. package/build-module/radio-group/index.js.map +1 -1
  117. package/build-module/radio-group/radio.js +46 -0
  118. package/build-module/radio-group/radio.js.map +1 -0
  119. package/build-module/radio-group/types.js +2 -0
  120. package/build-module/radio-group/types.js.map +1 -0
  121. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +1 -1
  122. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  123. package/build-module/slot-fill/types.js.map +1 -1
  124. package/build-module/tabs/index.js +7 -5
  125. package/build-module/tabs/index.js.map +1 -1
  126. package/build-module/tabs/styles.js +11 -5
  127. package/build-module/tabs/styles.js.map +1 -1
  128. package/build-module/tabs/tab.js +7 -9
  129. package/build-module/tabs/tab.js.map +1 -1
  130. package/build-module/tabs/tablist.js +3 -5
  131. package/build-module/tabs/tablist.js.map +1 -1
  132. package/build-module/tabs/tabpanel.js +9 -10
  133. package/build-module/tabs/tabpanel.js.map +1 -1
  134. package/build-module/tabs/types.js.map +1 -1
  135. package/build-module/text/types.js.map +1 -1
  136. package/build-module/text-control/index.js +6 -1
  137. package/build-module/text-control/index.js.map +1 -1
  138. package/build-module/text-control/types.js.map +1 -1
  139. package/build-module/toggle-group-control/toggle-group-control/component.js +4 -2
  140. package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
  141. package/build-module/toggle-group-control/toggle-group-control/styles.js +13 -9
  142. package/build-module/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  143. package/build-module/toggle-group-control/types.js.map +1 -1
  144. package/build-module/tools-panel/tools-panel-item/hook.js +6 -2
  145. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  146. package/build-style/style-rtl.css +52 -8
  147. package/build-style/style.css +52 -8
  148. package/build-types/angle-picker-control/index.d.ts.map +1 -1
  149. package/build-types/box-control/stories/index.story.d.ts +1944 -0
  150. package/build-types/box-control/stories/index.story.d.ts.map +1 -0
  151. package/build-types/card/card-divider/component.d.ts +1 -1
  152. package/build-types/card/card-divider/hook.d.ts +162 -162
  153. package/build-types/color-palette/styles.d.ts +4 -1
  154. package/build-types/color-palette/styles.d.ts.map +1 -1
  155. package/build-types/custom-select-control-v2/index.d.ts +6 -0
  156. package/build-types/custom-select-control-v2/index.d.ts.map +1 -0
  157. package/build-types/custom-select-control-v2/stories/index.story.d.ts +19 -0
  158. package/build-types/custom-select-control-v2/stories/index.story.d.ts.map +1 -0
  159. package/build-types/custom-select-control-v2/styles.d.ts +47 -0
  160. package/build-types/custom-select-control-v2/styles.d.ts.map +1 -0
  161. package/build-types/custom-select-control-v2/types.d.ts +57 -0
  162. package/build-types/custom-select-control-v2/types.d.ts.map +1 -0
  163. package/build-types/date-time/date/styles.d.ts +4 -1
  164. package/build-types/date-time/date/styles.d.ts.map +1 -1
  165. package/build-types/disclosure/index.d.ts +7 -1
  166. package/build-types/disclosure/index.d.ts.map +1 -1
  167. package/build-types/disclosure/types.d.ts +12 -0
  168. package/build-types/disclosure/types.d.ts.map +1 -0
  169. package/build-types/divider/component.d.ts +5 -1
  170. package/build-types/divider/component.d.ts.map +1 -1
  171. package/build-types/divider/stories/index.story.d.ts.map +1 -1
  172. package/build-types/divider/styles.d.ts +1 -1
  173. package/build-types/divider/types.d.ts +2 -2
  174. package/build-types/divider/types.d.ts.map +1 -1
  175. package/build-types/dropdown-menu-v2-ariakit/index.d.ts +11 -2
  176. package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +1 -1
  177. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +1 -1
  178. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +26 -18
  179. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +1 -1
  180. package/build-types/dropdown-menu-v2-ariakit/types.d.ts +1 -7
  181. package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +1 -1
  182. package/build-types/form-token-field/index.d.ts.map +1 -1
  183. package/build-types/form-token-field/token-input.d.ts.map +1 -1
  184. package/build-types/form-token-field/types.d.ts +1 -1
  185. package/build-types/form-token-field/types.d.ts.map +1 -1
  186. package/build-types/heading/component.d.ts +4 -1
  187. package/build-types/heading/component.d.ts.map +1 -1
  188. package/build-types/heading/hook.d.ts.map +1 -1
  189. package/build-types/heading/types.d.ts +20 -1
  190. package/build-types/heading/types.d.ts.map +1 -1
  191. package/build-types/navigation/styles/navigation-styles.d.ts +4 -1
  192. package/build-types/navigation/styles/navigation-styles.d.ts.map +1 -1
  193. package/build-types/palette-edit/styles.d.ts +4 -1
  194. package/build-types/palette-edit/styles.d.ts.map +1 -1
  195. package/build-types/private-apis.d.ts.map +1 -1
  196. package/build-types/radio-group/context.d.ts +10 -0
  197. package/build-types/radio-group/context.d.ts.map +1 -0
  198. package/build-types/radio-group/index.d.ts +7 -9
  199. package/build-types/radio-group/index.d.ts.map +1 -1
  200. package/build-types/radio-group/radio.d.ts +8 -0
  201. package/build-types/radio-group/radio.d.ts.map +1 -0
  202. package/build-types/radio-group/stories/index.story.d.ts +14 -0
  203. package/build-types/radio-group/stories/index.story.d.ts.map +1 -0
  204. package/build-types/radio-group/types.d.ts +40 -0
  205. package/build-types/radio-group/types.d.ts.map +1 -0
  206. package/build-types/slot-fill/bubbles-virtually/slot.d.ts +1 -1
  207. package/build-types/slot-fill/types.d.ts +16 -6
  208. package/build-types/slot-fill/types.d.ts.map +1 -1
  209. package/build-types/tabs/index.d.ts +4 -3
  210. package/build-types/tabs/index.d.ts.map +1 -1
  211. package/build-types/tabs/stories/index.story.d.ts.map +1 -1
  212. package/build-types/tabs/styles.d.ts +10 -0
  213. package/build-types/tabs/styles.d.ts.map +1 -1
  214. package/build-types/tabs/tab.d.ts +1 -1
  215. package/build-types/tabs/tab.d.ts.map +1 -1
  216. package/build-types/tabs/tablist.d.ts +1 -1
  217. package/build-types/tabs/tablist.d.ts.map +1 -1
  218. package/build-types/tabs/tabpanel.d.ts +4 -1
  219. package/build-types/tabs/tabpanel.d.ts.map +1 -1
  220. package/build-types/tabs/types.d.ts +7 -31
  221. package/build-types/tabs/types.d.ts.map +1 -1
  222. package/build-types/text/types.d.ts +15 -2
  223. package/build-types/text/types.d.ts.map +1 -1
  224. package/build-types/text-control/index.d.ts +2 -1
  225. package/build-types/text-control/index.d.ts.map +1 -1
  226. package/build-types/text-control/types.d.ts +6 -0
  227. package/build-types/text-control/types.d.ts.map +1 -1
  228. package/build-types/toggle-group-control/toggle-group-control/component.d.ts +1 -0
  229. package/build-types/toggle-group-control/toggle-group-control/component.d.ts.map +1 -1
  230. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts +2 -2
  231. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts.map +1 -1
  232. package/build-types/toggle-group-control/types.d.ts +6 -0
  233. package/build-types/toggle-group-control/types.d.ts.map +1 -1
  234. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  235. package/package.json +19 -20
  236. package/src/angle-picker-control/index.tsx +0 -1
  237. package/src/box-control/stories/index.story.tsx +82 -0
  238. package/src/button/style.scss +10 -2
  239. package/src/combobox-control/README.md +1 -3
  240. package/src/custom-select-control-v2/README.md +73 -0
  241. package/src/custom-select-control-v2/index.tsx +99 -0
  242. package/src/custom-select-control-v2/stories/index.story.tsx +149 -0
  243. package/src/custom-select-control-v2/styles.ts +76 -0
  244. package/src/custom-select-control-v2/types.ts +63 -0
  245. package/src/disclosure/index.tsx +44 -0
  246. package/src/disclosure/types.tsx +10 -0
  247. package/src/divider/component.tsx +3 -3
  248. package/src/divider/stories/index.story.tsx +8 -0
  249. package/src/divider/types.ts +2 -2
  250. package/src/dropdown-menu/style.scss +4 -0
  251. package/src/dropdown-menu-v2-ariakit/README.md +19 -12
  252. package/src/dropdown-menu-v2-ariakit/index.tsx +116 -51
  253. package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +205 -94
  254. package/src/dropdown-menu-v2-ariakit/styles.ts +153 -117
  255. package/src/dropdown-menu-v2-ariakit/test/index.tsx +5 -36
  256. package/src/dropdown-menu-v2-ariakit/types.ts +1 -8
  257. package/src/form-toggle/style.scss +37 -7
  258. package/src/form-token-field/index.tsx +11 -3
  259. package/src/form-token-field/token-input.tsx +1 -3
  260. package/src/form-token-field/types.ts +1 -0
  261. package/src/gradient-picker/index.tsx +1 -1
  262. package/src/heading/README.md +6 -1
  263. package/src/heading/hook.ts +6 -3
  264. package/src/heading/types.ts +23 -1
  265. package/src/index.native.js +1 -0
  266. package/src/mobile/audio-player/index.native.js +9 -13
  267. package/src/mobile/global-styles-context/utils.native.js +52 -3
  268. package/src/mobile/utils/alignments.native.js +1 -0
  269. package/src/navigable-container/README.md +1 -1
  270. package/src/private-apis.ts +4 -2
  271. package/src/radio-group/context.tsx +18 -0
  272. package/src/radio-group/index.tsx +65 -0
  273. package/src/radio-group/radio.tsx +55 -0
  274. package/src/radio-group/stories/index.story.tsx +90 -0
  275. package/src/radio-group/types.ts +39 -0
  276. package/src/slot-fill/README.md +1 -1
  277. package/src/slot-fill/bubbles-virtually/slot-fill-provider.tsx +1 -1
  278. package/src/slot-fill/types.ts +18 -6
  279. package/src/tabs/README.md +3 -33
  280. package/src/tabs/index.tsx +12 -2
  281. package/src/tabs/stories/index.story.tsx +17 -1
  282. package/src/tabs/styles.ts +16 -0
  283. package/src/tabs/tab.tsx +10 -10
  284. package/src/tabs/tablist.tsx +21 -20
  285. package/src/tabs/tabpanel.tsx +26 -25
  286. package/src/tabs/test/index.tsx +90 -16
  287. package/src/tabs/types.ts +7 -32
  288. package/src/text/README.md +5 -1
  289. package/src/text/types.ts +15 -2
  290. package/src/text-control/index.tsx +5 -1
  291. package/src/text-control/style.scss +5 -0
  292. package/src/text-control/types.ts +6 -0
  293. package/src/toggle-control/README.md +2 -2
  294. package/src/toggle-group-control/toggle-group-control/component.tsx +8 -2
  295. package/src/toggle-group-control/toggle-group-control/styles.ts +13 -4
  296. package/src/toggle-group-control/types.ts +6 -0
  297. package/src/toolbar/toolbar-button/style.scss +0 -5
  298. package/src/tools-panel/tools-panel-item/hook.ts +11 -2
  299. package/tsconfig.tsbuildinfo +1 -1
  300. package/build/radio-group/radio/index.js +0 -49
  301. package/build/radio-group/radio/index.js.map +0 -1
  302. package/build/radio-group/radio-context/index.js +0 -18
  303. package/build/radio-group/radio-context/index.js.map +0 -1
  304. package/build-module/radio-group/radio/index.js +0 -40
  305. package/build-module/radio-group/radio/index.js.map +0 -1
  306. package/build-module/radio-group/radio-context/index.js +0 -10
  307. package/build-module/radio-group/radio-context/index.js.map +0 -1
  308. package/build-types/radio-group/radio/index.d.ts +0 -7
  309. package/build-types/radio-group/radio/index.d.ts.map +0 -1
  310. package/build-types/radio-group/radio-context/index.d.ts +0 -6
  311. package/build-types/radio-group/radio-context/index.d.ts.map +0 -1
  312. package/src/box-control/stories/index.story.js +0 -75
  313. package/src/disclosure/index.js +0 -11
  314. package/src/radio-group/index.js +0 -51
  315. package/src/radio-group/radio/index.js +0 -40
  316. package/src/radio-group/radio-context/index.js +0 -11
  317. package/src/radio-group/stories/index.story.js +0 -83
@@ -0,0 +1,99 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ // eslint-disable-next-line no-restricted-imports
5
+ import * as Ariakit from '@ariakit/react';
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { createContext, useContext } from '@wordpress/element';
10
+ import { __, sprintf } from '@wordpress/i18n';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import * as Styled from './styles';
16
+ import type {
17
+ CustomSelectProps,
18
+ CustomSelectItemProps,
19
+ CustomSelectContext as CustomSelectContextType,
20
+ } from './types';
21
+
22
+ export const CustomSelectContext =
23
+ createContext< CustomSelectContextType >( undefined );
24
+
25
+ function defaultRenderSelectedValue( value: CustomSelectProps[ 'value' ] ) {
26
+ const isValueEmpty = Array.isArray( value )
27
+ ? value.length === 0
28
+ : value === undefined || value === null;
29
+
30
+ if ( isValueEmpty ) {
31
+ return __( 'Select an item' );
32
+ }
33
+
34
+ if ( Array.isArray( value ) ) {
35
+ return value.length === 1
36
+ ? value[ 0 ]
37
+ : // translators: %s: number of items selected (it will always be 2 or more items)
38
+ sprintf( __( '%s items selected' ), value.length );
39
+ }
40
+
41
+ return value;
42
+ }
43
+
44
+ export function CustomSelect( props: CustomSelectProps ) {
45
+ const {
46
+ children,
47
+ defaultValue,
48
+ label,
49
+ onChange,
50
+ size = 'default',
51
+ value,
52
+ renderSelectedValue = defaultRenderSelectedValue,
53
+ } = props;
54
+
55
+ const store = Ariakit.useSelectStore( {
56
+ setValue: ( nextValue ) => onChange?.( nextValue ),
57
+ defaultValue,
58
+ value,
59
+ } );
60
+
61
+ const { value: currentValue } = store.useState();
62
+
63
+ return (
64
+ <>
65
+ <Styled.CustomSelectLabel store={ store }>
66
+ { label }
67
+ </Styled.CustomSelectLabel>
68
+ <Styled.CustomSelectButton
69
+ size={ size }
70
+ hasCustomRenderProp={ !! renderSelectedValue }
71
+ store={ store }
72
+ >
73
+ { renderSelectedValue( currentValue ) }
74
+ <Ariakit.SelectArrow />
75
+ </Styled.CustomSelectButton>
76
+ <Styled.CustomSelectPopover gutter={ 12 } store={ store } sameWidth>
77
+ <CustomSelectContext.Provider value={ { store } }>
78
+ { children }
79
+ </CustomSelectContext.Provider>
80
+ </Styled.CustomSelectPopover>
81
+ </>
82
+ );
83
+ }
84
+
85
+ export function CustomSelectItem( {
86
+ children,
87
+ ...props
88
+ }: CustomSelectItemProps ) {
89
+ const customSelectContext = useContext( CustomSelectContext );
90
+ return (
91
+ <Styled.CustomSelectItem
92
+ store={ customSelectContext?.store }
93
+ { ...props }
94
+ >
95
+ { children ?? props.value }
96
+ <Ariakit.SelectItemCheck />
97
+ </Styled.CustomSelectItem>
98
+ );
99
+ }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { Meta, StoryFn } from '@storybook/react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { useState } from '@wordpress/element';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import { CustomSelect, CustomSelectItem } from '..';
15
+
16
+ const meta: Meta< typeof CustomSelect > = {
17
+ title: 'Components (Experimental)/CustomSelectControl v2',
18
+ component: CustomSelect,
19
+ subcomponents: {
20
+ // @ts-expect-error - See https://github.com/storybookjs/storybook/issues/23170
21
+ CustomSelectItem,
22
+ },
23
+ argTypes: {
24
+ children: { control: { type: null } },
25
+ renderSelectedValue: { control: { type: null } },
26
+ value: { control: { type: null } },
27
+ },
28
+ parameters: {
29
+ actions: { argTypesRegex: '^on.*' },
30
+ controls: { expanded: true },
31
+ docs: {
32
+ canvas: { sourceState: 'shown' },
33
+ source: { excludeDecorators: true },
34
+ },
35
+ },
36
+ decorators: [
37
+ ( Story ) => (
38
+ <div
39
+ style={ {
40
+ minHeight: '150px',
41
+ } }
42
+ >
43
+ <Story />
44
+ </div>
45
+ ),
46
+ ],
47
+ };
48
+ export default meta;
49
+
50
+ const Template: StoryFn< typeof CustomSelect > = ( props ) => {
51
+ return <CustomSelect { ...props } />;
52
+ };
53
+
54
+ const ControlledTemplate: StoryFn< typeof CustomSelect > = ( props ) => {
55
+ const [ value, setValue ] = useState< string | string[] >();
56
+ return (
57
+ <CustomSelect
58
+ { ...props }
59
+ onChange={ ( nextValue ) => {
60
+ setValue( nextValue );
61
+ props.onChange?.( nextValue );
62
+ } }
63
+ value={ value }
64
+ />
65
+ );
66
+ };
67
+
68
+ export const Default = Template.bind( {} );
69
+ Default.args = {
70
+ label: 'Label',
71
+ children: (
72
+ <>
73
+ <CustomSelectItem value="Small">
74
+ <span style={ { fontSize: '75%' } }>Small</span>
75
+ </CustomSelectItem>
76
+ <CustomSelectItem value="Something bigger">
77
+ <span style={ { fontSize: '200%' } }>Something bigger</span>
78
+ </CustomSelectItem>
79
+ </>
80
+ ),
81
+ };
82
+
83
+ /**
84
+ * Multiple selection can be enabled by using an array for the `value` and
85
+ * `defaultValue` props. The argument of the `onChange` function will also
86
+ * change accordingly.
87
+ */
88
+ export const MultiSelect = Template.bind( {} );
89
+ MultiSelect.args = {
90
+ defaultValue: [ 'lavender', 'tangerine' ],
91
+ label: 'Select Colors',
92
+ renderSelectedValue: ( currentValue: string | string[] ) => {
93
+ if ( ! Array.isArray( currentValue ) ) {
94
+ return currentValue;
95
+ }
96
+ if ( currentValue.length === 0 ) return 'No colors selected';
97
+ if ( currentValue.length === 1 ) return currentValue[ 0 ];
98
+ return `${ currentValue.length } colors selected`;
99
+ },
100
+ children: (
101
+ <>
102
+ { [
103
+ 'amber',
104
+ 'aquamarine',
105
+ 'flamingo pink',
106
+ 'lavender',
107
+ 'maroon',
108
+ 'tangerine',
109
+ ].map( ( item ) => (
110
+ <CustomSelectItem key={ item } value={ item }>
111
+ { item }
112
+ </CustomSelectItem>
113
+ ) ) }
114
+ </>
115
+ ),
116
+ };
117
+
118
+ const renderControlledValue = ( gravatar: string | string[] ) => {
119
+ const avatar = `https://gravatar.com/avatar?d=${ gravatar }`;
120
+ return (
121
+ <div style={ { display: 'flex', alignItems: 'center' } }>
122
+ <img
123
+ style={ { maxHeight: '75px', marginRight: '10px' } }
124
+ key={ avatar }
125
+ src={ avatar }
126
+ alt=""
127
+ aria-hidden="true"
128
+ />
129
+ <span>{ gravatar }</span>
130
+ </div>
131
+ );
132
+ };
133
+
134
+ export const Controlled = ControlledTemplate.bind( {} );
135
+ Controlled.args = {
136
+ label: 'Default Gravatars',
137
+ renderSelectedValue: renderControlledValue,
138
+ children: (
139
+ <>
140
+ { [ 'mystery-person', 'identicon', 'wavatar', 'retro' ].map(
141
+ ( option ) => (
142
+ <CustomSelectItem key={ option } value={ option }>
143
+ { renderControlledValue( option ) }
144
+ </CustomSelectItem>
145
+ )
146
+ ) }
147
+ </>
148
+ ),
149
+ };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import styled from '@emotion/styled';
5
+ // eslint-disable-next-line no-restricted-imports
6
+ import * as Ariakit from '@ariakit/react';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { COLORS } from '../utils';
12
+ import { space } from '../utils/space';
13
+ import type { CustomSelectProps } from './types';
14
+
15
+ export const CustomSelectLabel = styled( Ariakit.SelectLabel )`
16
+ font-size: 11px;
17
+ font-weight: 500;
18
+ line-height: 1.4;
19
+ text-transform: uppercase;
20
+ margin-bottom: ${ space( 2 ) };
21
+ `;
22
+
23
+ const inputHeights = {
24
+ default: 40,
25
+ small: 24,
26
+ };
27
+
28
+ export const CustomSelectButton = styled( Ariakit.Select, {
29
+ // Do not forward `hasCustomRenderProp` to the underlying Ariakit.Select component
30
+ shouldForwardProp: ( prop ) => prop !== 'hasCustomRenderProp',
31
+ } )( ( {
32
+ size,
33
+ hasCustomRenderProp,
34
+ }: {
35
+ size: NonNullable< CustomSelectProps[ 'size' ] >;
36
+ hasCustomRenderProp: boolean;
37
+ } ) => {
38
+ const isSmallSize = size === 'small' && ! hasCustomRenderProp;
39
+ const heightProperty = hasCustomRenderProp ? 'minHeight' : 'height';
40
+
41
+ return {
42
+ display: 'flex',
43
+ justifyContent: 'space-between',
44
+ alignItems: 'center',
45
+ backgroundColor: COLORS.white,
46
+ border: `1px solid ${ COLORS.gray[ 600 ] }`,
47
+ borderRadius: space( 0.5 ),
48
+ cursor: 'pointer',
49
+ width: '100%',
50
+ [ heightProperty ]: `${ inputHeights[ size ] }px`,
51
+ padding: isSmallSize ? space( 2 ) : space( 4 ),
52
+ fontSize: isSmallSize ? '11px' : '13px',
53
+ '&[data-focus-visible]': {
54
+ outlineStyle: 'solid',
55
+ },
56
+ '&[aria-expanded="true"]': {
57
+ outlineStyle: `1.5px solid ${ COLORS.theme.accent }`,
58
+ },
59
+ };
60
+ } );
61
+
62
+ export const CustomSelectPopover = styled( Ariakit.SelectPopover )`
63
+ border-radius: ${ space( 0.5 ) };
64
+ background: ${ COLORS.white };
65
+ border: 1px solid ${ COLORS.gray[ 900 ] };
66
+ `;
67
+
68
+ export const CustomSelectItem = styled( Ariakit.SelectItem )`
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: space-between;
72
+ padding: ${ space( 2 ) };
73
+ &[data-active-item] {
74
+ background-color: ${ COLORS.gray[ 300 ] };
75
+ }
76
+ `;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ // eslint-disable-next-line no-restricted-imports
5
+ import type * as Ariakit from '@ariakit/react';
6
+
7
+ export type CustomSelectContext =
8
+ | {
9
+ /**
10
+ * The store object returned by Ariakit's `useSelectStore` hook.
11
+ */
12
+ store: Ariakit.SelectStore;
13
+ }
14
+ | undefined;
15
+
16
+ export type CustomSelectProps = {
17
+ /**
18
+ * The child elements. This should be composed of CustomSelectItem components.
19
+ */
20
+ children: React.ReactNode;
21
+ /**
22
+ * An optional default value for the control. If left `undefined`, the first
23
+ * non-disabled item will be used.
24
+ */
25
+ defaultValue?: string | string[];
26
+ /**
27
+ * Label for the control.
28
+ */
29
+ label: string;
30
+ /**
31
+ * A function that receives the new value of the input.
32
+ */
33
+ onChange?: ( newValue: string | string[] ) => void;
34
+ /**
35
+ * Can be used to render select UI with custom styled values.
36
+ */
37
+ renderSelectedValue?: (
38
+ selectedValue: string | string[]
39
+ ) => React.ReactNode;
40
+ /**
41
+ * The size of the control.
42
+ *
43
+ * @default 'default'
44
+ */
45
+ size?: 'default' | 'small';
46
+ /**
47
+ * Can be used to externally control the value of the control.
48
+ */
49
+ value?: string | string[];
50
+ };
51
+
52
+ export type CustomSelectItemProps = {
53
+ /**
54
+ * The value of the select item. This will be used as the children if
55
+ * children are left `undefined`.
56
+ */
57
+ value: string;
58
+ /**
59
+ * The children to display for each select item. The `value` will be
60
+ * used if left `undefined`.
61
+ */
62
+ children?: React.ReactNode;
63
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ // eslint-disable-next-line no-restricted-imports
5
+ import * as Ariakit from '@ariakit/react';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import { forwardRef } from '@wordpress/element';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import type { DisclosureContentProps } from './types';
16
+ import type { WordPressComponentProps } from '../context';
17
+
18
+ /**
19
+ * Accessible Disclosure component that controls visibility of a section of
20
+ * content. It follows the WAI-ARIA Disclosure Pattern.
21
+ */
22
+ const UnforwardedDisclosureContent = (
23
+ {
24
+ visible,
25
+ children,
26
+ ...props
27
+ }: WordPressComponentProps< DisclosureContentProps, 'div', false >,
28
+ ref: React.ForwardedRef< any >
29
+ ) => {
30
+ const disclosure = Ariakit.useDisclosureStore( { open: visible } );
31
+
32
+ return (
33
+ <Ariakit.DisclosureContent
34
+ store={ disclosure }
35
+ ref={ ref }
36
+ { ...props }
37
+ >
38
+ { children }
39
+ </Ariakit.DisclosureContent>
40
+ );
41
+ };
42
+
43
+ export const DisclosureContent = forwardRef( UnforwardedDisclosureContent );
44
+ export default DisclosureContent;
@@ -0,0 +1,10 @@
1
+ export type DisclosureContentProps = {
2
+ /**
3
+ * If set to `true` the content will be shown, otherwise it's hidden.
4
+ */
5
+ visible?: boolean;
6
+ /**
7
+ * The content to display within the component.
8
+ */
9
+ children: React.ReactNode;
10
+ };
@@ -2,7 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  // eslint-disable-next-line no-restricted-imports
5
- import { Separator } from 'reakit';
5
+ import * as Ariakit from '@ariakit/react';
6
6
  import type { ForwardedRef } from 'react';
7
7
 
8
8
  /**
@@ -20,8 +20,8 @@ function UnconnectedDivider(
20
20
  const contextProps = useContextSystem( props, 'Divider' );
21
21
 
22
22
  return (
23
- <Separator
24
- as={ DividerView }
23
+ <Ariakit.Separator
24
+ render={ <DividerView /> }
25
25
  { ...contextProps }
26
26
  ref={ forwardedRef }
27
27
  />
@@ -23,6 +23,14 @@ const meta: Meta< typeof Divider > = {
23
23
  marginEnd: {
24
24
  control: { type: 'text' },
25
25
  },
26
+ wrapElement: {
27
+ control: { type: null },
28
+ },
29
+ ref: {
30
+ table: {
31
+ disable: true,
32
+ },
33
+ },
26
34
  },
27
35
  parameters: {
28
36
  controls: { expanded: true },
@@ -2,7 +2,7 @@
2
2
  * External dependencies
3
3
  */
4
4
  // eslint-disable-next-line no-restricted-imports
5
- import type { SeparatorProps } from 'reakit';
5
+ import type { SeparatorProps } from '@ariakit/react';
6
6
 
7
7
  /**
8
8
  * Internal dependencies
@@ -11,7 +11,7 @@ import type { SpaceInput } from '../utils/space';
11
11
 
12
12
  export type DividerProps = Omit<
13
13
  SeparatorProps,
14
- 'children' | 'unstable_system' | 'orientation'
14
+ 'children' | 'unstable_system' | 'orientation' | 'as' | 'render'
15
15
  > & {
16
16
  /**
17
17
  * Adjusts all margins on the inline dimension.
@@ -1,3 +1,7 @@
1
+ .components-dropdown-menu__toggle {
2
+ vertical-align: top;
3
+ }
4
+
1
5
  .components-dropdown-menu__menu {
2
6
  width: 100%;
3
7
  font-family: $default-font;
@@ -113,13 +113,6 @@ The skidding of the popover along the anchor element. Can be set to negative val
113
113
  - Required: no
114
114
  - Default: `0` for root-level menus, `-8` for nested menus
115
115
 
116
- ##### `hideOnEscape`: `boolean | ( ( event: KeyboardEvent | React.KeyboardEvent< Element > ) => boolean )`
117
-
118
- Determines whether the menu popover will be hidden when the user presses the Escape key.
119
-
120
- - Required: no
121
- - Default: `true`
122
-
123
116
  ### `DropdownMenuItem`
124
117
 
125
118
  Used to render a menu item.
@@ -291,9 +284,9 @@ Event handler called when the checked radio menu item changes.
291
284
 
292
285
  - Required: no
293
286
 
294
- ### `DropdownMenuGroup`
287
+ ### `DropdownMenuItemLabel`
295
288
 
296
- Used to group menu items.
289
+ Used to render the menu item's label.
297
290
 
298
291
  #### Props
299
292
 
@@ -301,13 +294,27 @@ The component accepts the following props:
301
294
 
302
295
  ##### `children`: `React.ReactNode`
303
296
 
304
- The contents of the group.
297
+ The label contents.
305
298
 
306
299
  - Required: yes
307
300
 
308
- ### `DropdownMenuGroupLabel`
301
+ ### `DropdownMenuItemHelpText`
302
+
303
+ Used to render the menu item's help text.
304
+
305
+ #### Props
309
306
 
310
- Used to render a group label.
307
+ The component accepts the following props:
308
+
309
+ ##### `children`: `React.ReactNode`
310
+
311
+ The help text contents.
312
+
313
+ - Required: yes
314
+
315
+ ### `DropdownMenuGroup`
316
+
317
+ Used to group menu items.
311
318
 
312
319
  #### Props
313
320