@wordpress/components 25.14.0 → 25.15.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 (479) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/CONTRIBUTING.md +57 -115
  3. package/LICENSE.md +1 -1
  4. package/build/base-control/index.js +17 -13
  5. package/build/base-control/index.js.map +1 -1
  6. package/build/border-box-control/border-box-control-linked-button/component.js +1 -1
  7. package/build/border-box-control/border-box-control-linked-button/component.js.map +1 -1
  8. package/build/border-control/border-control-style-picker/component.js +1 -1
  9. package/build/border-control/border-control-style-picker/component.js.map +1 -1
  10. package/build/box-control/index.js +1 -1
  11. package/build/box-control/index.js.map +1 -1
  12. package/build/box-control/linked-button.js +1 -1
  13. package/build/box-control/linked-button.js.map +1 -1
  14. package/build/button/index.js +1 -1
  15. package/build/button/index.js.map +1 -1
  16. package/build/color-picker/color-copy-button.js +1 -1
  17. package/build/color-picker/color-copy-button.js.map +1 -1
  18. package/build/context/wordpress-component.js.map +1 -1
  19. package/build/custom-select-control-v2/index.js +11 -10
  20. package/build/custom-select-control-v2/index.js.map +1 -1
  21. package/build/date-time/date/styles.js +8 -8
  22. package/build/date-time/date/styles.js.map +1 -1
  23. package/build/dropdown-menu-v2/index.js +205 -159
  24. package/build/dropdown-menu-v2/index.js.map +1 -1
  25. package/build/dropdown-menu-v2/styles.js +86 -77
  26. package/build/dropdown-menu-v2/styles.js.map +1 -1
  27. package/build/dropdown-menu-v2/types.js.map +1 -1
  28. package/build/duotone-picker/duotone-picker.js +4 -3
  29. package/build/duotone-picker/duotone-picker.js.map +1 -1
  30. package/build/font-size-picker/index.js +4 -2
  31. package/build/font-size-picker/index.js.map +1 -1
  32. package/build/font-size-picker/index.native.js +6 -3
  33. package/build/font-size-picker/index.native.js.map +1 -1
  34. package/build/form-token-field/index.js +10 -5
  35. package/build/form-token-field/index.js.map +1 -1
  36. package/build/form-token-field/token.js +1 -0
  37. package/build/form-token-field/token.js.map +1 -1
  38. package/build/gradient-picker/index.js +3 -2
  39. package/build/gradient-picker/index.js.map +1 -1
  40. package/build/index.native.js +20 -3
  41. package/build/index.native.js.map +1 -1
  42. package/build/input-control/styles/input-control-styles.js +32 -29
  43. package/build/input-control/styles/input-control-styles.js.map +1 -1
  44. package/build/input-control/types.js.map +1 -1
  45. package/build/lock-unlock.js +18 -0
  46. package/build/lock-unlock.js.map +1 -0
  47. package/build/mobile/bottom-sheet/index.native.js +8 -0
  48. package/build/mobile/bottom-sheet/index.native.js.map +1 -1
  49. package/build/mobile/global-styles-context/utils.native.js +26 -13
  50. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  51. package/build/mobile/image/constants.js +12 -0
  52. package/build/mobile/image/constants.js.map +1 -0
  53. package/build/mobile/image/index.native.js +26 -18
  54. package/build/mobile/image/index.native.js.map +1 -1
  55. package/build/mobile/keyboard-aware-flat-list/index.android.js +40 -8
  56. package/build/mobile/keyboard-aware-flat-list/index.android.js.map +1 -1
  57. package/build/mobile/keyboard-aware-flat-list/index.ios.js +44 -68
  58. package/build/mobile/keyboard-aware-flat-list/index.ios.js.map +1 -1
  59. package/build/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js +39 -0
  60. package/build/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js.map +1 -0
  61. package/build/mobile/keyboard-aware-flat-list/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +22 -29
  62. package/build/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js.map +1 -0
  63. package/build/mobile/keyboard-aware-flat-list/use-scroll.native.js +93 -0
  64. package/build/mobile/keyboard-aware-flat-list/use-scroll.native.js.map +1 -0
  65. package/build/mobile/utils/get-px-from-css-unit.native.js +302 -0
  66. package/build/mobile/utils/get-px-from-css-unit.native.js.map +1 -0
  67. package/build/modal/index.js +18 -13
  68. package/build/modal/index.js.map +1 -1
  69. package/build/navigation/menu/menu-title.js +1 -1
  70. package/build/navigation/menu/menu-title.js.map +1 -1
  71. package/build/navigator/navigator-provider/component.js +13 -15
  72. package/build/navigator/navigator-provider/component.js.map +1 -1
  73. package/build/navigator/navigator-screen/component.js +23 -63
  74. package/build/navigator/navigator-screen/component.js.map +1 -1
  75. package/build/navigator/styles.js +52 -0
  76. package/build/navigator/styles.js.map +1 -0
  77. package/build/number-control/index.js +4 -8
  78. package/build/number-control/index.js.map +1 -1
  79. package/build/number-control/types.js.map +1 -1
  80. package/build/palette-edit/index.js +15 -54
  81. package/build/palette-edit/index.js.map +1 -1
  82. package/build/private-apis.js +11 -26
  83. package/build/private-apis.js.map +1 -1
  84. package/build/private-apis.native.js +21 -0
  85. package/build/private-apis.native.js.map +1 -0
  86. package/build/radio-control/index.js +1 -0
  87. package/build/radio-control/index.js.map +1 -1
  88. package/build/range-control/index.js +1 -1
  89. package/build/range-control/index.js.map +1 -1
  90. package/build/select-control/styles/select-control-styles.js +15 -25
  91. package/build/select-control/styles/select-control-styles.js.map +1 -1
  92. package/build/slot-fill/index.js +3 -2
  93. package/build/slot-fill/index.js.map +1 -1
  94. package/build/slot-fill/types.js.map +1 -1
  95. package/build/snackbar/types.js.map +1 -1
  96. package/build/tabs/styles.js +3 -3
  97. package/build/tabs/styles.js.map +1 -1
  98. package/build/tabs/tabpanel.js +9 -7
  99. package/build/tabs/tabpanel.js.map +1 -1
  100. package/build/toggle-group-control/toggle-group-control/component.js +4 -4
  101. package/build/toggle-group-control/toggle-group-control/component.js.map +1 -1
  102. package/build/toggle-group-control/toggle-group-control/styles.js +29 -15
  103. package/build/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  104. package/build/toggle-group-control/toggle-group-control-option-base/styles.js +9 -9
  105. package/build/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
  106. package/build/tools-panel/tools-panel/component.js +3 -1
  107. package/build/tools-panel/tools-panel/component.js.map +1 -1
  108. package/build/tools-panel/tools-panel-header/component.js +9 -8
  109. package/build/tools-panel/tools-panel-header/component.js.map +1 -1
  110. package/build/tools-panel/types.js.map +1 -1
  111. package/build/tooltip/index.js +1 -1
  112. package/build/tooltip/index.js.map +1 -1
  113. package/build/truncate/hook.js +10 -4
  114. package/build/truncate/hook.js.map +1 -1
  115. package/build/truncate/types.js.map +1 -1
  116. package/build/unit-control/index.js +1 -1
  117. package/build/unit-control/index.js.map +1 -1
  118. package/build/utils/strings.js +34 -3
  119. package/build/utils/strings.js.map +1 -1
  120. package/build-module/base-control/index.js +16 -12
  121. package/build-module/base-control/index.js.map +1 -1
  122. package/build-module/border-box-control/border-box-control-linked-button/component.js +1 -1
  123. package/build-module/border-box-control/border-box-control-linked-button/component.js.map +1 -1
  124. package/build-module/border-control/border-control-style-picker/component.js +1 -1
  125. package/build-module/border-control/border-control-style-picker/component.js.map +1 -1
  126. package/build-module/box-control/index.js +1 -1
  127. package/build-module/box-control/index.js.map +1 -1
  128. package/build-module/box-control/linked-button.js +1 -1
  129. package/build-module/box-control/linked-button.js.map +1 -1
  130. package/build-module/button/index.js +1 -1
  131. package/build-module/button/index.js.map +1 -1
  132. package/build-module/color-picker/color-copy-button.js +1 -1
  133. package/build-module/color-picker/color-copy-button.js.map +1 -1
  134. package/build-module/context/wordpress-component.js.map +1 -1
  135. package/build-module/custom-select-control-v2/index.js +11 -10
  136. package/build-module/custom-select-control-v2/index.js.map +1 -1
  137. package/build-module/date-time/date/styles.js +8 -8
  138. package/build-module/date-time/date/styles.js.map +1 -1
  139. package/build-module/dropdown-menu-v2/index.js +201 -154
  140. package/build-module/dropdown-menu-v2/index.js.map +1 -1
  141. package/build-module/dropdown-menu-v2/styles.js +68 -61
  142. package/build-module/dropdown-menu-v2/styles.js.map +1 -1
  143. package/build-module/dropdown-menu-v2/types.js.map +1 -1
  144. package/build-module/duotone-picker/duotone-picker.js +4 -3
  145. package/build-module/duotone-picker/duotone-picker.js.map +1 -1
  146. package/build-module/font-size-picker/index.js +4 -2
  147. package/build-module/font-size-picker/index.js.map +1 -1
  148. package/build-module/font-size-picker/index.native.js +5 -2
  149. package/build-module/font-size-picker/index.native.js.map +1 -1
  150. package/build-module/form-token-field/index.js +10 -5
  151. package/build-module/form-token-field/index.js.map +1 -1
  152. package/build-module/form-token-field/token.js +1 -0
  153. package/build-module/form-token-field/token.js.map +1 -1
  154. package/build-module/gradient-picker/index.js +3 -2
  155. package/build-module/gradient-picker/index.js.map +1 -1
  156. package/build-module/index.native.js +6 -1
  157. package/build-module/index.native.js.map +1 -1
  158. package/build-module/input-control/styles/input-control-styles.js +31 -29
  159. package/build-module/input-control/styles/input-control-styles.js.map +1 -1
  160. package/build-module/input-control/types.js.map +1 -1
  161. package/build-module/lock-unlock.js +9 -0
  162. package/build-module/lock-unlock.js.map +1 -0
  163. package/build-module/mobile/bottom-sheet/index.native.js +9 -1
  164. package/build-module/mobile/bottom-sheet/index.native.js.map +1 -1
  165. package/build-module/mobile/global-styles-context/utils.native.js +25 -13
  166. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  167. package/build-module/mobile/image/constants.js +5 -0
  168. package/build-module/mobile/image/constants.js.map +1 -0
  169. package/build-module/mobile/image/index.native.js +25 -16
  170. package/build-module/mobile/image/index.native.js.map +1 -1
  171. package/build-module/mobile/keyboard-aware-flat-list/index.android.js +40 -6
  172. package/build-module/mobile/keyboard-aware-flat-list/index.android.js.map +1 -1
  173. package/build-module/mobile/keyboard-aware-flat-list/index.ios.js +46 -68
  174. package/build-module/mobile/keyboard-aware-flat-list/index.ios.js.map +1 -1
  175. package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js +33 -0
  176. package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js.map +1 -0
  177. package/build-module/mobile/keyboard-aware-flat-list/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +21 -27
  178. package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-section.native.js.map +1 -0
  179. package/build-module/mobile/keyboard-aware-flat-list/use-scroll.native.js +86 -0
  180. package/build-module/mobile/keyboard-aware-flat-list/use-scroll.native.js.map +1 -0
  181. package/build-module/mobile/utils/get-px-from-css-unit.native.js +294 -0
  182. package/build-module/mobile/utils/get-px-from-css-unit.native.js.map +1 -0
  183. package/build-module/modal/index.js +18 -13
  184. package/build-module/modal/index.js.map +1 -1
  185. package/build-module/navigation/menu/menu-title.js +1 -1
  186. package/build-module/navigation/menu/menu-title.js.map +1 -1
  187. package/build-module/navigator/navigator-provider/component.js +3 -16
  188. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  189. package/build-module/navigator/navigator-screen/component.js +16 -70
  190. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  191. package/build-module/navigator/styles.js +47 -0
  192. package/build-module/navigator/styles.js.map +1 -0
  193. package/build-module/number-control/index.js +4 -8
  194. package/build-module/number-control/index.js.map +1 -1
  195. package/build-module/number-control/types.js.map +1 -1
  196. package/build-module/palette-edit/index.js +15 -51
  197. package/build-module/palette-edit/index.js.map +1 -1
  198. package/build-module/private-apis.js +10 -23
  199. package/build-module/private-apis.js.map +1 -1
  200. package/build-module/private-apis.native.js +14 -0
  201. package/build-module/private-apis.native.js.map +1 -0
  202. package/build-module/radio-control/index.js +1 -0
  203. package/build-module/radio-control/index.js.map +1 -1
  204. package/build-module/range-control/index.js +1 -1
  205. package/build-module/range-control/index.js.map +1 -1
  206. package/build-module/select-control/styles/select-control-styles.js +15 -25
  207. package/build-module/select-control/styles/select-control-styles.js.map +1 -1
  208. package/build-module/slot-fill/index.js +3 -2
  209. package/build-module/slot-fill/index.js.map +1 -1
  210. package/build-module/slot-fill/types.js.map +1 -1
  211. package/build-module/snackbar/types.js.map +1 -1
  212. package/build-module/tabs/styles.js +3 -3
  213. package/build-module/tabs/styles.js.map +1 -1
  214. package/build-module/tabs/tabpanel.js +9 -7
  215. package/build-module/tabs/tabpanel.js.map +1 -1
  216. package/build-module/toggle-group-control/toggle-group-control/component.js +4 -4
  217. package/build-module/toggle-group-control/toggle-group-control/component.js.map +1 -1
  218. package/build-module/toggle-group-control/toggle-group-control/styles.js +29 -15
  219. package/build-module/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  220. package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js +9 -9
  221. package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
  222. package/build-module/tools-panel/tools-panel/component.js +3 -1
  223. package/build-module/tools-panel/tools-panel/component.js.map +1 -1
  224. package/build-module/tools-panel/tools-panel-header/component.js +9 -8
  225. package/build-module/tools-panel/tools-panel-header/component.js.map +1 -1
  226. package/build-module/tools-panel/types.js.map +1 -1
  227. package/build-module/tooltip/index.js +1 -1
  228. package/build-module/tooltip/index.js.map +1 -1
  229. package/build-module/truncate/hook.js +10 -4
  230. package/build-module/truncate/hook.js.map +1 -1
  231. package/build-module/truncate/types.js.map +1 -1
  232. package/build-module/unit-control/index.js +1 -1
  233. package/build-module/unit-control/index.js.map +1 -1
  234. package/build-module/utils/strings.js +32 -2
  235. package/build-module/utils/strings.js.map +1 -1
  236. package/build-style/style-rtl.css +29 -5
  237. package/build-style/style.css +29 -5
  238. package/build-types/base-control/index.d.ts +3 -27
  239. package/build-types/base-control/index.d.ts.map +1 -1
  240. package/build-types/base-control/stories/index.story.d.ts +4 -1
  241. package/build-types/base-control/stories/index.story.d.ts.map +1 -1
  242. package/build-types/color-picker/component.d.ts +1 -1
  243. package/build-types/color-picker/stories/index.story.d.ts +1 -1
  244. package/build-types/color-picker/stories/index.story.d.ts.map +1 -1
  245. package/build-types/composite/test/index.d.ts.map +1 -0
  246. package/build-types/context/wordpress-component.d.ts +3 -3
  247. package/build-types/context/wordpress-component.d.ts.map +1 -1
  248. package/build-types/custom-select-control-v2/index.d.ts +3 -2
  249. package/build-types/custom-select-control-v2/index.d.ts.map +1 -1
  250. package/build-types/custom-select-control-v2/stories/index.story.d.ts +4 -3
  251. package/build-types/custom-select-control-v2/stories/index.story.d.ts.map +1 -1
  252. package/build-types/dropdown/index.d.ts +1 -1
  253. package/build-types/dropdown/index.d.ts.map +1 -1
  254. package/build-types/dropdown/stories/index.story.d.ts +3 -3
  255. package/build-types/dropdown/stories/index.story.d.ts.map +1 -1
  256. package/build-types/dropdown-menu/index.d.ts +1 -1
  257. package/build-types/dropdown-menu/index.d.ts.map +1 -1
  258. package/build-types/dropdown-menu/stories/index.story.d.ts +2 -2
  259. package/build-types/dropdown-menu/stories/index.story.d.ts.map +1 -1
  260. package/build-types/dropdown-menu-v2/index.d.ts +18 -15
  261. package/build-types/dropdown-menu-v2/index.d.ts.map +1 -1
  262. package/build-types/dropdown-menu-v2/stories/index.story.d.ts +7 -2
  263. package/build-types/dropdown-menu-v2/stories/index.story.d.ts.map +1 -1
  264. package/build-types/dropdown-menu-v2/styles.d.ts +77 -23
  265. package/build-types/dropdown-menu-v2/styles.d.ts.map +1 -1
  266. package/build-types/dropdown-menu-v2/types.d.ts +89 -173
  267. package/build-types/dropdown-menu-v2/types.d.ts.map +1 -1
  268. package/build-types/duotone-picker/duotone-picker.d.ts.map +1 -1
  269. package/build-types/font-size-picker/index.d.ts.map +1 -1
  270. package/build-types/form-token-field/index.d.ts.map +1 -1
  271. package/build-types/form-token-field/token.d.ts.map +1 -1
  272. package/build-types/input-control/styles/input-control-styles.d.ts +11 -0
  273. package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
  274. package/build-types/input-control/types.d.ts +1 -1
  275. package/build-types/input-control/types.d.ts.map +1 -1
  276. package/build-types/lock-unlock.d.ts +3 -0
  277. package/build-types/lock-unlock.d.ts.map +1 -0
  278. package/build-types/mobile/image/constants.d.ts +5 -0
  279. package/build-types/mobile/image/constants.d.ts.map +1 -0
  280. package/build-types/modal/index.d.ts.map +1 -1
  281. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  282. package/build-types/navigator/navigator-screen/component.d.ts +1 -7
  283. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  284. package/build-types/navigator/styles.d.ts +9 -0
  285. package/build-types/navigator/styles.d.ts.map +1 -0
  286. package/build-types/number-control/index.d.ts.map +1 -1
  287. package/build-types/number-control/types.d.ts +1 -1
  288. package/build-types/palette-edit/index.d.ts +3 -8
  289. package/build-types/palette-edit/index.d.ts.map +1 -1
  290. package/build-types/popover/index.d.ts +1 -1
  291. package/build-types/popover/index.d.ts.map +1 -1
  292. package/build-types/popover/stories/e2e/index.story.d.ts +1 -1
  293. package/build-types/private-apis.d.ts +0 -1
  294. package/build-types/private-apis.d.ts.map +1 -1
  295. package/build-types/radio-control/index.d.ts.map +1 -1
  296. package/build-types/select-control/styles/select-control-styles.d.ts.map +1 -1
  297. package/build-types/slot-fill/index.d.ts +1 -1
  298. package/build-types/slot-fill/index.d.ts.map +1 -1
  299. package/build-types/slot-fill/types.d.ts +4 -0
  300. package/build-types/slot-fill/types.d.ts.map +1 -1
  301. package/build-types/snackbar/index.d.ts +2 -2
  302. package/build-types/snackbar/stories/index.story.d.ts +0 -3
  303. package/build-types/snackbar/stories/index.story.d.ts.map +1 -1
  304. package/build-types/snackbar/types.d.ts +1 -1
  305. package/build-types/snackbar/types.d.ts.map +1 -1
  306. package/build-types/tabs/styles.d.ts.map +1 -1
  307. package/build-types/tabs/tabpanel.d.ts +1 -1
  308. package/build-types/tabs/tabpanel.d.ts.map +1 -1
  309. package/build-types/toggle-group-control/toggle-group-control/component.d.ts.map +1 -1
  310. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts +2 -2
  311. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts.map +1 -1
  312. package/build-types/toggle-group-control/toggle-group-control-option-base/component.d.ts +1 -1
  313. package/build-types/toggle-group-control/toggle-group-control-option-base/component.d.ts.map +1 -1
  314. package/build-types/toggle-group-control/toggle-group-control-option-base/styles.d.ts.map +1 -1
  315. package/build-types/tools-panel/tools-panel/component.d.ts.map +1 -1
  316. package/build-types/tools-panel/tools-panel/hook.d.ts +1 -0
  317. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  318. package/build-types/tools-panel/tools-panel-header/component.d.ts.map +1 -1
  319. package/build-types/tools-panel/tools-panel-header/hook.d.ts +1 -0
  320. package/build-types/tools-panel/tools-panel-header/hook.d.ts.map +1 -1
  321. package/build-types/tools-panel/types.d.ts +9 -0
  322. package/build-types/tools-panel/types.d.ts.map +1 -1
  323. package/build-types/truncate/hook.d.ts +1 -1
  324. package/build-types/truncate/hook.d.ts.map +1 -1
  325. package/build-types/truncate/types.d.ts +4 -0
  326. package/build-types/truncate/types.d.ts.map +1 -1
  327. package/build-types/utils/strings.d.ts +14 -2
  328. package/build-types/utils/strings.d.ts.map +1 -1
  329. package/package.json +20 -21
  330. package/src/alignment-matrix-control/test/index.tsx +10 -16
  331. package/src/base-control/index.tsx +21 -16
  332. package/src/border-box-control/border-box-control-linked-button/component.tsx +1 -1
  333. package/src/border-control/border-control-style-picker/component.tsx +1 -1
  334. package/src/box-control/index.tsx +1 -1
  335. package/src/box-control/linked-button.tsx +1 -1
  336. package/src/button/README.md +32 -6
  337. package/src/button/index.tsx +1 -1
  338. package/src/button-group/README.md +0 -6
  339. package/src/card/card/README.md +1 -1
  340. package/src/checkbox-control/README.md +1 -9
  341. package/src/color-picker/color-copy-button.tsx +1 -1
  342. package/src/combobox-control/README.md +0 -6
  343. package/src/composite/test/index.tsx +576 -0
  344. package/src/context/wordpress-component.ts +11 -6
  345. package/src/custom-select-control/README.md +0 -6
  346. package/src/custom-select-control-v2/index.tsx +13 -12
  347. package/src/date-time/date/styles.ts +3 -3
  348. package/src/dropdown-menu/README.md +0 -5
  349. package/src/dropdown-menu-v2/README.md +75 -136
  350. package/src/dropdown-menu-v2/index.tsx +321 -231
  351. package/src/dropdown-menu-v2/stories/index.story.tsx +522 -126
  352. package/src/dropdown-menu-v2/styles.ts +226 -151
  353. package/src/dropdown-menu-v2/test/index.tsx +480 -188
  354. package/src/dropdown-menu-v2/types.ts +98 -184
  355. package/src/duotone-picker/duotone-picker.tsx +7 -3
  356. package/src/font-size-picker/index.native.js +8 -2
  357. package/src/font-size-picker/index.tsx +4 -2
  358. package/src/form-toggle/README.md +0 -6
  359. package/src/form-token-field/index.tsx +11 -7
  360. package/src/form-token-field/test/index.tsx +97 -0
  361. package/src/form-token-field/token.tsx +1 -0
  362. package/src/gradient-picker/index.tsx +2 -2
  363. package/src/index.native.js +6 -1
  364. package/src/input-control/styles/input-control-styles.tsx +10 -8
  365. package/src/input-control/types.ts +1 -1
  366. package/src/lock-unlock.js +10 -0
  367. package/src/menu-group/README.md +0 -8
  368. package/src/menu-items-choice/README.md +0 -7
  369. package/src/mobile/bottom-sheet/index.native.js +15 -1
  370. package/src/mobile/global-styles-context/test/fixtures/theme.native.js +0 -20
  371. package/src/mobile/global-styles-context/utils.native.js +28 -19
  372. package/src/mobile/image/constants.js +1 -0
  373. package/src/mobile/image/index.native.js +55 -18
  374. package/src/mobile/image/style.native.scss +35 -9
  375. package/src/mobile/keyboard-aware-flat-list/index.android.js +50 -5
  376. package/src/mobile/keyboard-aware-flat-list/index.ios.js +65 -91
  377. package/src/mobile/keyboard-aware-flat-list/test/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +27 -25
  378. package/src/mobile/keyboard-aware-flat-list/test/use-scroll.native.js +71 -0
  379. package/src/mobile/keyboard-aware-flat-list/use-scroll-to-element.native.js +41 -0
  380. package/src/mobile/keyboard-aware-flat-list/{use-scroll-to-text-input.native.js → use-scroll-to-section.native.js} +22 -27
  381. package/src/mobile/keyboard-aware-flat-list/use-scroll.native.js +100 -0
  382. package/src/mobile/utils/get-px-from-css-unit.native.js +329 -0
  383. package/src/mobile/utils/test/get-px-from-css-unit.native.js +172 -0
  384. package/src/modal/README.md +0 -6
  385. package/src/modal/index.tsx +18 -16
  386. package/src/modal/test/index.tsx +90 -1
  387. package/src/navigation/menu/menu-title.tsx +1 -1
  388. package/src/navigator/navigator-provider/component.tsx +3 -4
  389. package/src/navigator/navigator-screen/component.tsx +15 -93
  390. package/src/navigator/styles.ts +71 -0
  391. package/src/navigator/test/index.tsx +0 -64
  392. package/src/notice/README.md +0 -6
  393. package/src/number-control/README.md +2 -2
  394. package/src/number-control/index.tsx +4 -8
  395. package/src/number-control/types.ts +1 -1
  396. package/src/palette-edit/index.tsx +15 -58
  397. package/src/palette-edit/test/index.tsx +1 -75
  398. package/src/panel/README.md +0 -6
  399. package/src/private-apis.native.js +13 -0
  400. package/src/private-apis.ts +12 -37
  401. package/src/radio-control/README.md +0 -6
  402. package/src/radio-control/index.tsx +4 -1
  403. package/src/radio-control/style.scss +29 -2
  404. package/src/radio-group/README.md +0 -6
  405. package/src/range-control/README.md +1 -9
  406. package/src/range-control/index.tsx +1 -1
  407. package/src/search-control/README.md +0 -6
  408. package/src/select-control/README.md +0 -6
  409. package/src/select-control/styles/select-control-styles.ts +10 -28
  410. package/src/slot-fill/index.tsx +5 -2
  411. package/src/slot-fill/types.ts +5 -0
  412. package/src/snackbar/README.md +0 -6
  413. package/src/snackbar/stories/index.story.tsx +7 -5
  414. package/src/snackbar/style.scss +4 -3
  415. package/src/snackbar/types.ts +2 -1
  416. package/src/spacer/README.md +0 -2
  417. package/src/tab-panel/README.md +0 -5
  418. package/src/tab-panel/test/index.tsx +39 -56
  419. package/src/tabs/styles.ts +7 -1
  420. package/src/tabs/tabpanel.tsx +7 -6
  421. package/src/tabs/test/index.tsx +56 -0
  422. package/src/text-control/README.md +0 -6
  423. package/src/textarea-control/README.md +0 -6
  424. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +12 -16
  425. package/src/toggle-group-control/test/index.tsx +58 -45
  426. package/src/toggle-group-control/toggle-group-control/component.tsx +5 -4
  427. package/src/toggle-group-control/toggle-group-control/styles.ts +13 -19
  428. package/src/toggle-group-control/toggle-group-control-option/README.md +1 -1
  429. package/src/toggle-group-control/toggle-group-control-option-base/README.md +1 -1
  430. package/src/toggle-group-control/toggle-group-control-option-base/styles.ts +3 -2
  431. package/src/toggle-group-control/toggle-group-control-option-icon/README.md +1 -1
  432. package/src/toolbar/toolbar/README.md +0 -6
  433. package/src/tools-panel/test/index.tsx +12 -20
  434. package/src/tools-panel/tools-panel/README.md +7 -0
  435. package/src/tools-panel/tools-panel/component.tsx +2 -0
  436. package/src/tools-panel/tools-panel-header/README.md +7 -0
  437. package/src/tools-panel/tools-panel-header/component.tsx +20 -13
  438. package/src/tools-panel/types.ts +9 -0
  439. package/src/tooltip/index.tsx +1 -1
  440. package/src/tooltip/test/index.tsx +360 -256
  441. package/src/tree-grid/README.md +0 -4
  442. package/src/truncate/README.md +8 -0
  443. package/src/truncate/hook.ts +17 -10
  444. package/src/truncate/test/index.tsx +54 -27
  445. package/src/truncate/types.ts +4 -0
  446. package/src/unit-control/index.tsx +1 -1
  447. package/src/utils/strings.ts +30 -2
  448. package/src/utils/test/strings.js +96 -1
  449. package/tsconfig.tsbuildinfo +1 -1
  450. package/build/dropdown-menu-v2-ariakit/index.js +0 -256
  451. package/build/dropdown-menu-v2-ariakit/index.js.map +0 -1
  452. package/build/dropdown-menu-v2-ariakit/styles.js +0 -180
  453. package/build/dropdown-menu-v2-ariakit/styles.js.map +0 -1
  454. package/build/dropdown-menu-v2-ariakit/types.js +0 -6
  455. package/build/dropdown-menu-v2-ariakit/types.js.map +0 -1
  456. package/build/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js.map +0 -1
  457. package/build-module/dropdown-menu-v2-ariakit/index.js +0 -237
  458. package/build-module/dropdown-menu-v2-ariakit/index.js.map +0 -1
  459. package/build-module/dropdown-menu-v2-ariakit/styles.js +0 -165
  460. package/build-module/dropdown-menu-v2-ariakit/styles.js.map +0 -1
  461. package/build-module/dropdown-menu-v2-ariakit/types.js +0 -2
  462. package/build-module/dropdown-menu-v2-ariakit/types.js.map +0 -1
  463. package/build-module/mobile/keyboard-aware-flat-list/use-scroll-to-text-input.native.js.map +0 -1
  464. package/build-types/dropdown-menu-v2-ariakit/index.d.ts +0 -20
  465. package/build-types/dropdown-menu-v2-ariakit/index.d.ts.map +0 -1
  466. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts +0 -16
  467. package/build-types/dropdown-menu-v2-ariakit/stories/index.story.d.ts.map +0 -1
  468. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts +0 -96
  469. package/build-types/dropdown-menu-v2-ariakit/styles.d.ts.map +0 -1
  470. package/build-types/dropdown-menu-v2-ariakit/test/index.d.ts.map +0 -1
  471. package/build-types/dropdown-menu-v2-ariakit/types.d.ts +0 -168
  472. package/build-types/dropdown-menu-v2-ariakit/types.d.ts.map +0 -1
  473. package/src/dropdown-menu-v2-ariakit/README.md +0 -331
  474. package/src/dropdown-menu-v2-ariakit/index.tsx +0 -383
  475. package/src/dropdown-menu-v2-ariakit/stories/index.story.tsx +0 -617
  476. package/src/dropdown-menu-v2-ariakit/styles.ts +0 -345
  477. package/src/dropdown-menu-v2-ariakit/test/index.tsx +0 -1108
  478. package/src/dropdown-menu-v2-ariakit/types.ts +0 -179
  479. /package/build-types/{dropdown-menu-v2-ariakit → composite}/test/index.d.ts +0 -0
@@ -0,0 +1,576 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import {
11
+ Composite as ReakitComposite,
12
+ CompositeGroup as ReakitCompositeGroup,
13
+ CompositeItem as ReakitCompositeItem,
14
+ useCompositeState as ReakitUseCompositeState,
15
+ } from '..';
16
+
17
+ const COMPOSITE_SUITES = {
18
+ reakit: {
19
+ Composite: ReakitComposite,
20
+ CompositeGroup: ReakitCompositeGroup,
21
+ CompositeItem: ReakitCompositeItem,
22
+ useCompositeState: ReakitUseCompositeState,
23
+ },
24
+ };
25
+
26
+ type InitialState = Parameters< typeof ReakitUseCompositeState >[ 0 ];
27
+
28
+ // It was decided not to test the full API, instead opting
29
+ // to cover basic usage, with a view to adding broader support
30
+ // for the original API should the need arise. As such we are
31
+ // only testing here for standard usage.
32
+ // See https://github.com/WordPress/gutenberg/pull/56645
33
+
34
+ describe.each( Object.entries( COMPOSITE_SUITES ) )(
35
+ 'Validate %s implementation',
36
+ ( _, { Composite, CompositeGroup, CompositeItem, useCompositeState } ) => {
37
+ function useSpreadProps( initialState?: InitialState ) {
38
+ return useCompositeState( initialState );
39
+ }
40
+
41
+ function useStateProps( initialState?: InitialState ) {
42
+ return {
43
+ state: useCompositeState( initialState ),
44
+ };
45
+ }
46
+
47
+ function OneDimensionalTest( { ...props } ) {
48
+ return (
49
+ <Composite
50
+ { ...props }
51
+ aria-label={ expect.getState().currentTestName }
52
+ >
53
+ <CompositeItem { ...props }>Item 1</CompositeItem>
54
+ <CompositeItem { ...props }>Item 2</CompositeItem>
55
+ <CompositeItem { ...props }>Item 3</CompositeItem>
56
+ </Composite>
57
+ );
58
+ }
59
+
60
+ function getOneDimensionalItems() {
61
+ return {
62
+ item1: screen.getByText( 'Item 1' ),
63
+ item2: screen.getByText( 'Item 2' ),
64
+ item3: screen.getByText( 'Item 3' ),
65
+ };
66
+ }
67
+
68
+ function TwoDimensionalTest( { ...props } ) {
69
+ return (
70
+ <Composite
71
+ { ...props }
72
+ aria-label={ expect.getState().currentTestName }
73
+ >
74
+ <CompositeGroup role="row" { ...props }>
75
+ <CompositeItem { ...props }>Item A1</CompositeItem>
76
+ <CompositeItem { ...props }>Item A2</CompositeItem>
77
+ <CompositeItem { ...props }>Item A3</CompositeItem>
78
+ </CompositeGroup>
79
+ <CompositeGroup role="row" { ...props }>
80
+ <CompositeItem { ...props }>Item B1</CompositeItem>
81
+ <CompositeItem { ...props }>Item B2</CompositeItem>
82
+ <CompositeItem { ...props }>Item B3</CompositeItem>
83
+ </CompositeGroup>
84
+ <CompositeGroup role="row" { ...props }>
85
+ <CompositeItem { ...props }>Item C1</CompositeItem>
86
+ <CompositeItem { ...props }>Item C2</CompositeItem>
87
+ <CompositeItem { ...props }>Item C3</CompositeItem>
88
+ </CompositeGroup>
89
+ </Composite>
90
+ );
91
+ }
92
+
93
+ function getTwoDimensionalItems() {
94
+ return {
95
+ itemA1: screen.getByText( 'Item A1' ),
96
+ itemA2: screen.getByText( 'Item A2' ),
97
+ itemA3: screen.getByText( 'Item A3' ),
98
+ itemB1: screen.getByText( 'Item B1' ),
99
+ itemB2: screen.getByText( 'Item B2' ),
100
+ itemB3: screen.getByText( 'Item B3' ),
101
+ itemC1: screen.getByText( 'Item C1' ),
102
+ itemC2: screen.getByText( 'Item C2' ),
103
+ itemC3: screen.getByText( 'Item C3' ),
104
+ };
105
+ }
106
+
107
+ function ShiftTest( { ...props } ) {
108
+ return (
109
+ <Composite
110
+ { ...props }
111
+ aria-label={ expect.getState().currentTestName }
112
+ >
113
+ <CompositeGroup role="row" { ...props }>
114
+ <CompositeItem { ...props }>Item A1</CompositeItem>
115
+ </CompositeGroup>
116
+ <CompositeGroup role="row" { ...props }>
117
+ <CompositeItem { ...props }>Item B1</CompositeItem>
118
+ <CompositeItem { ...props }>Item B2</CompositeItem>
119
+ </CompositeGroup>
120
+ <CompositeGroup role="row" { ...props }>
121
+ <CompositeItem { ...props }>Item C1</CompositeItem>
122
+ <CompositeItem { ...props } disabled>
123
+ Item C2
124
+ </CompositeItem>
125
+ </CompositeGroup>
126
+ </Composite>
127
+ );
128
+ }
129
+
130
+ function getShiftTestItems() {
131
+ return {
132
+ itemA1: screen.getByText( 'Item A1' ),
133
+ itemB1: screen.getByText( 'Item B1' ),
134
+ itemB2: screen.getByText( 'Item B2' ),
135
+ itemC1: screen.getByText( 'Item C1' ),
136
+ itemC2: screen.getByText( 'Item C2' ),
137
+ };
138
+ }
139
+
140
+ describe.each( [
141
+ [ 'With spread state', useSpreadProps ],
142
+ [ 'With `state` prop', useStateProps ],
143
+ ] )( '%s', ( __, useProps ) => {
144
+ function useOneDimensionalTest( initialState?: InitialState ) {
145
+ const Test = () => (
146
+ <OneDimensionalTest { ...useProps( initialState ) } />
147
+ );
148
+ render( <Test /> );
149
+ return getOneDimensionalItems();
150
+ }
151
+
152
+ test( 'Renders as a single tab stop', async () => {
153
+ const user = userEvent.setup();
154
+ const Test = () => (
155
+ <>
156
+ <button>Before</button>
157
+ <OneDimensionalTest { ...useProps() } />
158
+ <button>After</button>
159
+ </>
160
+ );
161
+ render( <Test /> );
162
+
163
+ await user.tab();
164
+ expect( screen.getByText( 'Before' ) ).toHaveFocus();
165
+ await user.tab();
166
+ expect( screen.getByText( 'Item 1' ) ).toHaveFocus();
167
+ await user.tab();
168
+ expect( screen.getByText( 'After' ) ).toHaveFocus();
169
+ await user.tab( { shift: true } );
170
+ expect( screen.getByText( 'Item 1' ) ).toHaveFocus();
171
+ } );
172
+
173
+ test( 'Excludes disabled items', async () => {
174
+ const user = userEvent.setup();
175
+ const Test = () => {
176
+ const props = useProps();
177
+ return (
178
+ <Composite
179
+ { ...props }
180
+ aria-label={ expect.getState().currentTestName }
181
+ >
182
+ <CompositeItem { ...props }>Item 1</CompositeItem>
183
+ <CompositeItem { ...props } disabled>
184
+ Item 2
185
+ </CompositeItem>
186
+ <CompositeItem { ...props }>Item 3</CompositeItem>
187
+ </Composite>
188
+ );
189
+ };
190
+ render( <Test /> );
191
+
192
+ const { item1, item2, item3 } = getOneDimensionalItems();
193
+
194
+ expect( item2 ).toBeDisabled();
195
+
196
+ await user.tab();
197
+ expect( item1 ).toHaveFocus();
198
+ await user.keyboard( '[ArrowDown]' );
199
+ expect( item2 ).not.toHaveFocus();
200
+ expect( item3 ).toHaveFocus();
201
+ } );
202
+
203
+ test( 'Includes focusable disabled items', async () => {
204
+ const user = userEvent.setup();
205
+ const Test = () => {
206
+ const props = useProps();
207
+ return (
208
+ <Composite
209
+ { ...props }
210
+ aria-label={ expect.getState().currentTestName }
211
+ >
212
+ <CompositeItem { ...props }>Item 1</CompositeItem>
213
+ <CompositeItem { ...props } disabled focusable>
214
+ Item 2
215
+ </CompositeItem>
216
+ <CompositeItem { ...props }>Item 3</CompositeItem>
217
+ </Composite>
218
+ );
219
+ };
220
+ render( <Test /> );
221
+ const { item1, item2, item3 } = getOneDimensionalItems();
222
+
223
+ expect( item2 ).toBeEnabled();
224
+ expect( item2 ).toHaveAttribute( 'aria-disabled', 'true' );
225
+
226
+ await user.tab();
227
+ expect( item1 ).toHaveFocus();
228
+ await user.keyboard( '[ArrowDown]' );
229
+ expect( item2 ).toHaveFocus();
230
+ expect( item3 ).not.toHaveFocus();
231
+ } );
232
+
233
+ test( 'Supports `baseId`', async () => {
234
+ const { item1, item2, item3 } = useOneDimensionalTest( {
235
+ baseId: 'test-id',
236
+ } );
237
+
238
+ expect( item1.id ).toMatch( 'test-id-1' );
239
+ expect( item2.id ).toMatch( 'test-id-2' );
240
+ expect( item3.id ).toMatch( 'test-id-3' );
241
+ } );
242
+
243
+ test( 'Supports `currentId`', async () => {
244
+ const user = userEvent.setup();
245
+ const { item2 } = useOneDimensionalTest( {
246
+ baseId: 'test-id',
247
+ currentId: 'test-id-2',
248
+ } );
249
+
250
+ await user.tab();
251
+ expect( item2 ).toHaveFocus();
252
+ } );
253
+ } );
254
+
255
+ describe.each( [
256
+ [
257
+ 'When LTR',
258
+ false,
259
+ { previous: 'ArrowLeft', next: 'ArrowRight' },
260
+ ],
261
+ [ 'When RTL', true, { previous: 'ArrowRight', next: 'ArrowLeft' } ],
262
+ ] )( '%s', ( _when, rtl, { previous, next } ) => {
263
+ function useOneDimensionalTest( initialState?: InitialState ) {
264
+ const Test = () => (
265
+ <OneDimensionalTest { ...useStateProps( initialState ) } />
266
+ );
267
+ render( <Test /> );
268
+ return getOneDimensionalItems();
269
+ }
270
+
271
+ function useTwoDimensionalTest( initialState?: InitialState ) {
272
+ const Test = () => (
273
+ <TwoDimensionalTest { ...useStateProps( initialState ) } />
274
+ );
275
+ render( <Test /> );
276
+ return getTwoDimensionalItems();
277
+ }
278
+
279
+ function useShiftTest( shift: boolean ) {
280
+ const Test = () => (
281
+ <ShiftTest { ...useStateProps( { rtl, shift } ) } />
282
+ );
283
+ render( <Test /> );
284
+ return getShiftTestItems();
285
+ }
286
+
287
+ describe( 'In one dimension', () => {
288
+ test( 'All directions work with no orientation', async () => {
289
+ const user = userEvent.setup();
290
+ const { item1, item2, item3 } = useOneDimensionalTest( {
291
+ rtl,
292
+ } );
293
+
294
+ await user.tab();
295
+ expect( item1 ).toHaveFocus();
296
+ await user.keyboard( '[ArrowDown]' );
297
+ expect( item2 ).toHaveFocus();
298
+ await user.keyboard( '[ArrowDown]' );
299
+ expect( item3 ).toHaveFocus();
300
+ await user.keyboard( '[ArrowDown]' );
301
+ expect( item3 ).toHaveFocus();
302
+ await user.keyboard( '[ArrowUp]' );
303
+ expect( item2 ).toHaveFocus();
304
+ await user.keyboard( '[ArrowUp]' );
305
+ expect( item1 ).toHaveFocus();
306
+ await user.keyboard( '[ArrowUp]' );
307
+ expect( item1 ).toHaveFocus();
308
+ await user.keyboard( `[${ next }]` );
309
+ expect( item2 ).toHaveFocus();
310
+ await user.keyboard( `[${ next }]` );
311
+ expect( item3 ).toHaveFocus();
312
+ await user.keyboard( `[${ previous }]` );
313
+ expect( item2 ).toHaveFocus();
314
+ await user.keyboard( `[${ previous }]` );
315
+ expect( item1 ).toHaveFocus();
316
+ await user.keyboard( '[End]' );
317
+ expect( item3 ).toHaveFocus();
318
+ await user.keyboard( '[Home]' );
319
+ expect( item1 ).toHaveFocus();
320
+ await user.keyboard( '[PageDown]' );
321
+ expect( item3 ).toHaveFocus();
322
+ await user.keyboard( '[PageUp]' );
323
+ expect( item1 ).toHaveFocus();
324
+ } );
325
+
326
+ test( 'Only left/right work with horizontal orientation', async () => {
327
+ const user = userEvent.setup();
328
+ const { item1, item2, item3 } = useOneDimensionalTest( {
329
+ rtl,
330
+ orientation: 'horizontal',
331
+ } );
332
+
333
+ await user.tab();
334
+ expect( item1 ).toHaveFocus();
335
+ await user.keyboard( '[ArrowDown]' );
336
+ expect( item1 ).toHaveFocus();
337
+ await user.keyboard( `[${ next }]` );
338
+ expect( item2 ).toHaveFocus();
339
+ await user.keyboard( `[${ next }]` );
340
+ expect( item3 ).toHaveFocus();
341
+ await user.keyboard( '[ArrowUp]' );
342
+ expect( item3 ).toHaveFocus();
343
+ await user.keyboard( `[${ previous }]` );
344
+ expect( item2 ).toHaveFocus();
345
+ await user.keyboard( `[${ previous }]` );
346
+ expect( item1 ).toHaveFocus();
347
+ await user.keyboard( '[End]' );
348
+ expect( item3 ).toHaveFocus();
349
+ await user.keyboard( '[Home]' );
350
+ expect( item1 ).toHaveFocus();
351
+ await user.keyboard( '[PageDown]' );
352
+ expect( item3 ).toHaveFocus();
353
+ await user.keyboard( '[PageUp]' );
354
+ expect( item1 ).toHaveFocus();
355
+ } );
356
+
357
+ test( 'Only up/down work with vertical orientation', async () => {
358
+ const user = userEvent.setup();
359
+ const { item1, item2, item3 } = useOneDimensionalTest( {
360
+ rtl,
361
+ orientation: 'vertical',
362
+ } );
363
+
364
+ await user.tab();
365
+ expect( item1 ).toHaveFocus();
366
+ await user.keyboard( `[${ next }]` );
367
+ expect( item1 ).toHaveFocus();
368
+ await user.keyboard( '[ArrowDown]' );
369
+ expect( item2 ).toHaveFocus();
370
+ await user.keyboard( '[ArrowDown]' );
371
+ expect( item3 ).toHaveFocus();
372
+ await user.keyboard( `[${ previous }]` );
373
+ expect( item3 ).toHaveFocus();
374
+ await user.keyboard( '[ArrowUp]' );
375
+ expect( item2 ).toHaveFocus();
376
+ await user.keyboard( '[ArrowUp]' );
377
+ expect( item1 ).toHaveFocus();
378
+ await user.keyboard( '[End]' );
379
+ expect( item3 ).toHaveFocus();
380
+ await user.keyboard( '[Home]' );
381
+ expect( item1 ).toHaveFocus();
382
+ await user.keyboard( '[PageDown]' );
383
+ expect( item3 ).toHaveFocus();
384
+ await user.keyboard( '[PageUp]' );
385
+ expect( item1 ).toHaveFocus();
386
+ } );
387
+
388
+ test( 'Focus wraps with loop enabled', async () => {
389
+ const user = userEvent.setup();
390
+ const { item1, item2, item3 } = useOneDimensionalTest( {
391
+ rtl,
392
+ loop: true,
393
+ } );
394
+
395
+ await user.tab();
396
+ expect( item1 ).toHaveFocus();
397
+ await user.keyboard( '[ArrowDown]' );
398
+ expect( item2 ).toHaveFocus();
399
+ await user.keyboard( '[ArrowDown]' );
400
+ expect( item3 ).toHaveFocus();
401
+ await user.keyboard( '[ArrowDown]' );
402
+ expect( item1 ).toHaveFocus();
403
+ await user.keyboard( '[ArrowUp]' );
404
+ expect( item3 ).toHaveFocus();
405
+ await user.keyboard( `[${ next }]` );
406
+ expect( item1 ).toHaveFocus();
407
+ await user.keyboard( `[${ previous }]` );
408
+ expect( item3 ).toHaveFocus();
409
+ } );
410
+ } );
411
+
412
+ describe( 'In two dimensions', () => {
413
+ test( 'All directions work as standard', async () => {
414
+ const user = userEvent.setup();
415
+ const {
416
+ itemA1,
417
+ itemA2,
418
+ itemA3,
419
+ itemB1,
420
+ itemB2,
421
+ itemC1,
422
+ itemC3,
423
+ } = useTwoDimensionalTest( { rtl } );
424
+
425
+ await user.tab();
426
+ expect( itemA1 ).toHaveFocus();
427
+ await user.keyboard( '[ArrowUp]' );
428
+ expect( itemA1 ).toHaveFocus();
429
+ await user.keyboard( `[${ previous }]` );
430
+ expect( itemA1 ).toHaveFocus();
431
+ await user.keyboard( '[ArrowDown]' );
432
+ expect( itemB1 ).toHaveFocus();
433
+ await user.keyboard( `[${ next }]` );
434
+ expect( itemB2 ).toHaveFocus();
435
+ await user.keyboard( '[ArrowUp]' );
436
+ expect( itemA2 ).toHaveFocus();
437
+ await user.keyboard( `[${ previous }]` );
438
+ expect( itemA1 ).toHaveFocus();
439
+ await user.keyboard( '[End]' );
440
+ expect( itemA3 ).toHaveFocus();
441
+ await user.keyboard( '[PageDown]' );
442
+ expect( itemC3 ).toHaveFocus();
443
+ await user.keyboard( `[${ next }]` );
444
+ expect( itemC3 ).toHaveFocus();
445
+ await user.keyboard( '[ArrowDown]' );
446
+ expect( itemC3 ).toHaveFocus();
447
+ await user.keyboard( '[Home]' );
448
+ expect( itemC1 ).toHaveFocus();
449
+ await user.keyboard( '[PageUp]' );
450
+ expect( itemA1 ).toHaveFocus();
451
+ await user.keyboard( '{Control>}[End]{/Control}' );
452
+ expect( itemC3 ).toHaveFocus();
453
+ await user.keyboard( '{Control>}[Home]{/Control}' );
454
+ expect( itemA1 ).toHaveFocus();
455
+ } );
456
+
457
+ test( 'Focus wraps around rows/columns with loop enabled', async () => {
458
+ const user = userEvent.setup();
459
+ const { itemA1, itemA2, itemA3, itemB1, itemC1, itemC3 } =
460
+ useTwoDimensionalTest( { rtl, loop: true } );
461
+
462
+ await user.tab();
463
+ expect( itemA1 ).toHaveFocus();
464
+ await user.keyboard( `[${ next }]` );
465
+ expect( itemA2 ).toHaveFocus();
466
+ await user.keyboard( `[${ next }]` );
467
+ expect( itemA3 ).toHaveFocus();
468
+ await user.keyboard( `[${ next }]` );
469
+ expect( itemA1 ).toHaveFocus();
470
+ await user.keyboard( '[ArrowDown]' );
471
+ expect( itemB1 ).toHaveFocus();
472
+ await user.keyboard( '[ArrowDown]' );
473
+ expect( itemC1 ).toHaveFocus();
474
+ await user.keyboard( '[ArrowDown]' );
475
+ expect( itemA1 ).toHaveFocus();
476
+ await user.keyboard( `[${ previous }]` );
477
+ expect( itemA3 ).toHaveFocus();
478
+ await user.keyboard( '[ArrowUp]' );
479
+ expect( itemC3 ).toHaveFocus();
480
+ } );
481
+
482
+ test( 'Focus moves between rows/columns with wrap enabled', async () => {
483
+ const user = userEvent.setup();
484
+ const { itemA1, itemA2, itemA3, itemB1, itemC1, itemC3 } =
485
+ useTwoDimensionalTest( { rtl, wrap: true } );
486
+
487
+ await user.tab();
488
+ expect( itemA1 ).toHaveFocus();
489
+ await user.keyboard( `[${ next }]` );
490
+ expect( itemA2 ).toHaveFocus();
491
+ await user.keyboard( `[${ next }]` );
492
+ expect( itemA3 ).toHaveFocus();
493
+ await user.keyboard( `[${ next }]` );
494
+ expect( itemB1 ).toHaveFocus();
495
+ await user.keyboard( '[ArrowDown]' );
496
+ expect( itemC1 ).toHaveFocus();
497
+ await user.keyboard( '[ArrowDown]' );
498
+ expect( itemA2 ).toHaveFocus();
499
+ await user.keyboard( `[${ previous }]` );
500
+ expect( itemA1 ).toHaveFocus();
501
+ await user.keyboard( `[${ previous }]` );
502
+ expect( itemA1 ).toHaveFocus();
503
+ await user.keyboard( '[ArrowUp]' );
504
+ expect( itemA1 ).toHaveFocus();
505
+ await user.keyboard( '{Control>}[End]{/Control}' );
506
+ expect( itemC3 ).toHaveFocus();
507
+ await user.keyboard( `[${ next }]` );
508
+ expect( itemC3 ).toHaveFocus();
509
+ await user.keyboard( '[ArrowDown]' );
510
+ expect( itemC3 ).toHaveFocus();
511
+ } );
512
+
513
+ test( 'Focus wraps around start/end with loop and wrap enabled', async () => {
514
+ const user = userEvent.setup();
515
+ const { itemA1, itemC3 } = useTwoDimensionalTest( {
516
+ rtl,
517
+ loop: true,
518
+ wrap: true,
519
+ } );
520
+
521
+ await user.tab();
522
+ expect( itemA1 ).toHaveFocus();
523
+ await user.keyboard( `[${ previous }]` );
524
+ expect( itemC3 ).toHaveFocus();
525
+ await user.keyboard( '[ArrowDown]' );
526
+ expect( itemA1 ).toHaveFocus();
527
+ await user.keyboard( '[ArrowUp]' );
528
+ expect( itemC3 ).toHaveFocus();
529
+ await user.keyboard( `[${ next }]` );
530
+ expect( itemA1 ).toHaveFocus();
531
+ } );
532
+
533
+ test( 'Focus shifts if vertical neighbour unavailable when shift enabled', async () => {
534
+ const user = userEvent.setup();
535
+ const { itemA1, itemB1, itemB2, itemC1 } =
536
+ useShiftTest( true );
537
+
538
+ await user.tab();
539
+ expect( itemA1 ).toHaveFocus();
540
+ await user.keyboard( '[ArrowDown]' );
541
+ expect( itemB1 ).toHaveFocus();
542
+ await user.keyboard( `[${ next }]` );
543
+ expect( itemB2 ).toHaveFocus();
544
+ await user.keyboard( '[ArrowUp]' );
545
+ // A2 doesn't exist
546
+ expect( itemA1 ).toHaveFocus();
547
+ await user.keyboard( '[ArrowDown]' );
548
+ expect( itemB1 ).toHaveFocus();
549
+ await user.keyboard( `[${ next }]` );
550
+ expect( itemB2 ).toHaveFocus();
551
+ await user.keyboard( '[ArrowDown]' );
552
+ // C2 is disabled
553
+ expect( itemC1 ).toHaveFocus();
554
+ } );
555
+
556
+ test( 'Focus does not shift if vertical neighbour unavailable when shift not enabled', async () => {
557
+ const user = userEvent.setup();
558
+ const { itemA1, itemB1, itemB2 } = useShiftTest( false );
559
+
560
+ await user.tab();
561
+ expect( itemA1 ).toHaveFocus();
562
+ await user.keyboard( '[ArrowDown]' );
563
+ expect( itemB1 ).toHaveFocus();
564
+ await user.keyboard( `[${ next }]` );
565
+ expect( itemB2 ).toHaveFocus();
566
+ await user.keyboard( '[ArrowUp]' );
567
+ // A2 doesn't exist
568
+ expect( itemB2 ).toHaveFocus();
569
+ await user.keyboard( '[ArrowDown]' );
570
+ // C2 is disabled
571
+ expect( itemB2 ).toHaveFocus();
572
+ } );
573
+ } );
574
+ } );
575
+ }
576
+ );
@@ -8,14 +8,19 @@ export type WordPressComponentProps<
8
8
  /** Prop types. */
9
9
  P,
10
10
  /** The HTML element to inherit props from. */
11
- T extends React.ElementType,
11
+ T extends React.ElementType | null,
12
12
  /** Supports polymorphism through the `as` prop. */
13
13
  IsPolymorphic extends boolean = true,
14
14
  > = P &
15
- // The `children` prop is being explicitly omitted since it is otherwise implicitly added
16
- // by `ComponentPropsWithRef`. The context is that components should require the `children`
17
- // prop explicitly when needed (see https://github.com/WordPress/gutenberg/pull/31817).
18
- Omit< React.ComponentPropsWithoutRef< T >, 'as' | keyof P | 'children' > &
15
+ ( T extends React.ElementType
16
+ ? // The `children` prop is being explicitly omitted since it is otherwise implicitly added
17
+ // by `ComponentPropsWithRef`. The context is that components should require the `children`
18
+ // prop explicitly when needed (see https://github.com/WordPress/gutenberg/pull/31817).
19
+ Omit<
20
+ React.ComponentPropsWithoutRef< T >,
21
+ 'as' | keyof P | 'children'
22
+ >
23
+ : {} ) &
19
24
  ( IsPolymorphic extends true
20
25
  ? {
21
26
  /** The HTML element or React component to render the component as. */
@@ -24,7 +29,7 @@ export type WordPressComponentProps<
24
29
  : {} );
25
30
 
26
31
  export type WordPressComponent<
27
- T extends React.ElementType,
32
+ T extends React.ElementType | null,
28
33
  O,
29
34
  IsPolymorphic extends boolean,
30
35
  > = {
@@ -2,12 +2,6 @@
2
2
 
3
3
  `CustomSelectControl` allows users to select an item from a single-option menu just like [`SelectControl`](/packages/components/src/select-control/readme.md), with the addition of being able to provide custom styles for each item in the menu. This means it does not use a native `<select>`, so should only be used if the custom styling is necessary.
4
4
 
5
- ## Table of contents
6
-
7
- 1. [Design guidelines](#design-guidelines)
8
- 2. [Development guidelines](#development-guidelines)
9
- 3. [Related components](#related-components)
10
-
11
5
  ## Design guidelines
12
6
 
13
7
  These are the same as [the ones for `SelectControl`s](/packages/components/src/select-control/readme.md#design-guidelines).
@@ -18,6 +18,7 @@ import type {
18
18
  CustomSelectItemProps,
19
19
  CustomSelectContext as CustomSelectContextType,
20
20
  } from './types';
21
+ import type { WordPressComponentProps } from '../context';
21
22
 
22
23
  export const CustomSelectContext =
23
24
  createContext< CustomSelectContextType >( undefined );
@@ -41,17 +42,16 @@ function defaultRenderSelectedValue( value: CustomSelectProps[ 'value' ] ) {
41
42
  return value;
42
43
  }
43
44
 
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
-
45
+ export function CustomSelect( {
46
+ children,
47
+ defaultValue,
48
+ label,
49
+ onChange,
50
+ size = 'default',
51
+ value,
52
+ renderSelectedValue = defaultRenderSelectedValue,
53
+ ...props
54
+ }: WordPressComponentProps< CustomSelectProps, 'button', false > ) {
55
55
  const store = Ariakit.useSelectStore( {
56
56
  setValue: ( nextValue ) => onChange?.( nextValue ),
57
57
  defaultValue,
@@ -66,6 +66,7 @@ export function CustomSelect( props: CustomSelectProps ) {
66
66
  { label }
67
67
  </Styled.CustomSelectLabel>
68
68
  <Styled.CustomSelectButton
69
+ { ...props }
69
70
  size={ size }
70
71
  hasCustomRenderProp={ !! renderSelectedValue }
71
72
  store={ store }
@@ -85,7 +86,7 @@ export function CustomSelect( props: CustomSelectProps ) {
85
86
  export function CustomSelectItem( {
86
87
  children,
87
88
  ...props
88
- }: CustomSelectItemProps ) {
89
+ }: WordPressComponentProps< CustomSelectItemProps, 'div', false > ) {
89
90
  const customSelectContext = useContext( CustomSelectContext );
90
91
  return (
91
92
  <Styled.CustomSelectItem
@@ -84,8 +84,8 @@ export const DayButton = styled( Button, {
84
84
 
85
85
  &&& {
86
86
  border-radius: 100%;
87
- height: ${ space( 7 ) };
88
- width: ${ space( 7 ) };
87
+ height: ${ space( 8 ) };
88
+ width: ${ space( 8 ) };
89
89
 
90
90
  ${ ( props ) =>
91
91
  props.isSelected &&
@@ -108,7 +108,7 @@ export const DayButton = styled( Button, {
108
108
  ::before {
109
109
  background: ${ props.isSelected ? COLORS.white : COLORS.theme.accent };
110
110
  border-radius: 2px;
111
- bottom: 0;
111
+ bottom: 2px;
112
112
  content: " ";
113
113
  height: 4px;
114
114
  left: 50%;