@wordpress/components 23.9.0 → 25.0.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 (423) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/CONTRIBUTING.md +75 -1
  3. package/README.md +1 -3
  4. package/build/autocomplete/autocompleter-ui.js +0 -2
  5. package/build/autocomplete/autocompleter-ui.js.map +1 -1
  6. package/build/autocomplete/index.js +2 -0
  7. package/build/autocomplete/index.js.map +1 -1
  8. package/build/button/index.js +2 -0
  9. package/build/button/index.js.map +1 -1
  10. package/build/card/card-media/component.js +2 -1
  11. package/build/card/card-media/component.js.map +1 -1
  12. package/build/color-picker/styles.js +8 -8
  13. package/build/color-picker/styles.js.map +1 -1
  14. package/build/combobox-control/index.js +7 -5
  15. package/build/combobox-control/index.js.map +1 -1
  16. package/build/combobox-control/styles.js +3 -3
  17. package/build/combobox-control/styles.js.map +1 -1
  18. package/build/date-time/date-time/index.js +3 -84
  19. package/build/date-time/date-time/index.js.map +1 -1
  20. package/build/date-time/date-time/styles.js +4 -19
  21. package/build/date-time/date-time/styles.js.map +1 -1
  22. package/build/dimension-control/index.js +1 -1
  23. package/build/dimension-control/index.js.map +1 -1
  24. package/build/draggable/index.js +2 -7
  25. package/build/draggable/index.js.map +1 -1
  26. package/build/dropdown-menu/index.js +87 -11
  27. package/build/dropdown-menu/index.js.map +1 -1
  28. package/build/dropdown-menu/types.js +6 -0
  29. package/build/dropdown-menu/types.js.map +1 -0
  30. package/build/dropdown-menu-v2/index.js +195 -0
  31. package/build/dropdown-menu-v2/index.js.map +1 -0
  32. package/build/dropdown-menu-v2/styles.js +176 -0
  33. package/build/dropdown-menu-v2/styles.js.map +1 -0
  34. package/build/dropdown-menu-v2/types.js +6 -0
  35. package/build/dropdown-menu-v2/types.js.map +1 -0
  36. package/build/form-token-field/index.js +5 -3
  37. package/build/form-token-field/index.js.map +1 -1
  38. package/build/form-token-field/styles.js +3 -3
  39. package/build/form-token-field/styles.js.map +1 -1
  40. package/build/index.native.js +0 -9
  41. package/build/index.native.js.map +1 -1
  42. package/build/input-control/styles/input-control-styles.js +30 -23
  43. package/build/input-control/styles/input-control-styles.js.map +1 -1
  44. package/build/mobile/bottom-sheet/cell.native.js +16 -8
  45. package/build/mobile/bottom-sheet/cell.native.js.map +1 -1
  46. package/build/mobile/bottom-sheet/range-cell.native.js +3 -2
  47. package/build/mobile/bottom-sheet/range-cell.native.js.map +1 -1
  48. package/build/mobile/bottom-sheet/stepper-cell/index.native.js +4 -2
  49. package/build/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
  50. package/build/mobile/bottom-sheet/switch-cell.native.js +8 -2
  51. package/build/mobile/bottom-sheet/switch-cell.native.js.map +1 -1
  52. package/build/mobile/bottom-sheet-select-control/index.native.js +4 -2
  53. package/build/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
  54. package/build/mobile/bottom-sheet-text-control/index.native.js +4 -2
  55. package/build/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
  56. package/build/mobile/global-styles-context/index.native.js +13 -1
  57. package/build/mobile/global-styles-context/index.native.js.map +1 -1
  58. package/build/mobile/link-picker/link-picker-results.native.js +3 -1
  59. package/build/mobile/link-picker/link-picker-results.native.js.map +1 -1
  60. package/build/navigable-container/container.js +39 -19
  61. package/build/navigable-container/container.js.map +1 -1
  62. package/build/navigable-container/index.js.map +1 -1
  63. package/build/navigable-container/menu.js +37 -5
  64. package/build/navigable-container/menu.js.map +1 -1
  65. package/build/navigable-container/tabbable.js +45 -4
  66. package/build/navigable-container/tabbable.js.map +1 -1
  67. package/build/navigable-container/types.js +6 -0
  68. package/build/navigable-container/types.js.map +1 -0
  69. package/build/palette-edit/index.js +34 -12
  70. package/build/palette-edit/index.js.map +1 -1
  71. package/build/private-apis.js +13 -1
  72. package/build/private-apis.js.map +1 -1
  73. package/build/range-control/index.native.js +5 -2
  74. package/build/range-control/index.native.js.map +1 -1
  75. package/build/sandbox/index.native.js +6 -2
  76. package/build/sandbox/index.native.js.map +1 -1
  77. package/build/slot-fill/bubbles-virtually/fill.js +2 -1
  78. package/build/slot-fill/bubbles-virtually/fill.js.map +1 -1
  79. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +45 -35
  80. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  81. package/build/slot-fill/bubbles-virtually/use-slot.js +11 -26
  82. package/build/slot-fill/bubbles-virtually/use-slot.js.map +1 -1
  83. package/build/slot-fill/fill.js +7 -31
  84. package/build/slot-fill/fill.js.map +1 -1
  85. package/build/slot-fill/index.js.map +1 -1
  86. package/build/slot-fill/provider.js +0 -6
  87. package/build/slot-fill/provider.js.map +1 -1
  88. package/build/slot-fill/slot.js +0 -5
  89. package/build/slot-fill/slot.js.map +1 -1
  90. package/build/snackbar/list.js +0 -2
  91. package/build/snackbar/list.js.map +1 -1
  92. package/build/tab-panel/index.js.map +1 -1
  93. package/build/theme/color-algorithms.js +1 -1
  94. package/build/theme/color-algorithms.js.map +1 -1
  95. package/build/toggle-group-control/toggle-group-control/styles.js +7 -7
  96. package/build/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  97. package/build/toolbar/toolbar-button/index.js +1 -2
  98. package/build/toolbar/toolbar-button/index.js.map +1 -1
  99. package/build/toolbar/toolbar-item/index.js +4 -2
  100. package/build/toolbar/toolbar-item/index.js.map +1 -1
  101. package/build/utils/colors-values.js +3 -3
  102. package/build/utils/colors-values.js.map +1 -1
  103. package/build/utils/use-deprecated-props.js +35 -0
  104. package/build/utils/use-deprecated-props.js.map +1 -0
  105. package/build-module/autocomplete/autocompleter-ui.js +1 -3
  106. package/build-module/autocomplete/autocompleter-ui.js.map +1 -1
  107. package/build-module/autocomplete/index.js +3 -3
  108. package/build-module/autocomplete/index.js.map +1 -1
  109. package/build-module/button/index.js +2 -0
  110. package/build-module/button/index.js.map +1 -1
  111. package/build-module/card/card-media/component.js +2 -1
  112. package/build-module/card/card-media/component.js.map +1 -1
  113. package/build-module/color-picker/styles.js +8 -8
  114. package/build-module/color-picker/styles.js.map +1 -1
  115. package/build-module/combobox-control/index.js +6 -5
  116. package/build-module/combobox-control/index.js.map +1 -1
  117. package/build-module/combobox-control/styles.js +3 -3
  118. package/build-module/combobox-control/styles.js.map +1 -1
  119. package/build-module/date-time/date-time/index.js +6 -81
  120. package/build-module/date-time/date-time/index.js.map +1 -1
  121. package/build-module/date-time/date-time/styles.js +3 -17
  122. package/build-module/date-time/date-time/styles.js.map +1 -1
  123. package/build-module/dimension-control/index.js +1 -1
  124. package/build-module/dimension-control/index.js.map +1 -1
  125. package/build-module/draggable/index.js +2 -7
  126. package/build-module/draggable/index.js.map +1 -1
  127. package/build-module/dropdown-menu/index.js +87 -10
  128. package/build-module/dropdown-menu/index.js.map +1 -1
  129. package/build-module/dropdown-menu/types.js +2 -0
  130. package/build-module/dropdown-menu/types.js.map +1 -0
  131. package/build-module/dropdown-menu-v2/index.js +149 -0
  132. package/build-module/dropdown-menu-v2/index.js.map +1 -0
  133. package/build-module/dropdown-menu-v2/styles.js +153 -0
  134. package/build-module/dropdown-menu-v2/styles.js.map +1 -0
  135. package/build-module/dropdown-menu-v2/types.js +2 -0
  136. package/build-module/dropdown-menu-v2/types.js.map +1 -0
  137. package/build-module/form-token-field/index.js +4 -3
  138. package/build-module/form-token-field/index.js.map +1 -1
  139. package/build-module/form-token-field/styles.js +3 -3
  140. package/build-module/form-token-field/styles.js.map +1 -1
  141. package/build-module/index.native.js +0 -1
  142. package/build-module/index.native.js.map +1 -1
  143. package/build-module/input-control/styles/input-control-styles.js +30 -23
  144. package/build-module/input-control/styles/input-control-styles.js.map +1 -1
  145. package/build-module/mobile/bottom-sheet/cell.native.js +16 -8
  146. package/build-module/mobile/bottom-sheet/cell.native.js.map +1 -1
  147. package/build-module/mobile/bottom-sheet/range-cell.native.js +3 -2
  148. package/build-module/mobile/bottom-sheet/range-cell.native.js.map +1 -1
  149. package/build-module/mobile/bottom-sheet/stepper-cell/index.native.js +4 -2
  150. package/build-module/mobile/bottom-sheet/stepper-cell/index.native.js.map +1 -1
  151. package/build-module/mobile/bottom-sheet/switch-cell.native.js +7 -2
  152. package/build-module/mobile/bottom-sheet/switch-cell.native.js.map +1 -1
  153. package/build-module/mobile/bottom-sheet-select-control/index.native.js +4 -2
  154. package/build-module/mobile/bottom-sheet-select-control/index.native.js.map +1 -1
  155. package/build-module/mobile/bottom-sheet-text-control/index.native.js +4 -2
  156. package/build-module/mobile/bottom-sheet-text-control/index.native.js.map +1 -1
  157. package/build-module/mobile/global-styles-context/index.native.js +13 -1
  158. package/build-module/mobile/global-styles-context/index.native.js.map +1 -1
  159. package/build-module/mobile/link-picker/link-picker-results.native.js +3 -1
  160. package/build-module/mobile/link-picker/link-picker-results.native.js.map +1 -1
  161. package/build-module/navigable-container/container.js +43 -19
  162. package/build-module/navigable-container/container.js.map +1 -1
  163. package/build-module/navigable-container/index.js +0 -2
  164. package/build-module/navigable-container/index.js.map +1 -1
  165. package/build-module/navigable-container/menu.js +36 -4
  166. package/build-module/navigable-container/menu.js.map +1 -1
  167. package/build-module/navigable-container/tabbable.js +44 -3
  168. package/build-module/navigable-container/tabbable.js.map +1 -1
  169. package/build-module/navigable-container/types.js +2 -0
  170. package/build-module/navigable-container/types.js.map +1 -0
  171. package/build-module/palette-edit/index.js +34 -13
  172. package/build-module/palette-edit/index.js.map +1 -1
  173. package/build-module/private-apis.js +12 -1
  174. package/build-module/private-apis.js.map +1 -1
  175. package/build-module/range-control/index.native.js +5 -2
  176. package/build-module/range-control/index.native.js.map +1 -1
  177. package/build-module/sandbox/index.native.js +6 -2
  178. package/build-module/sandbox/index.native.js.map +1 -1
  179. package/build-module/slot-fill/bubbles-virtually/fill.js +2 -1
  180. package/build-module/slot-fill/bubbles-virtually/fill.js.map +1 -1
  181. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +46 -36
  182. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  183. package/build-module/slot-fill/bubbles-virtually/use-slot.js +12 -27
  184. package/build-module/slot-fill/bubbles-virtually/use-slot.js.map +1 -1
  185. package/build-module/slot-fill/fill.js +7 -31
  186. package/build-module/slot-fill/fill.js.map +1 -1
  187. package/build-module/slot-fill/index.js +1 -2
  188. package/build-module/slot-fill/index.js.map +1 -1
  189. package/build-module/slot-fill/provider.js +0 -6
  190. package/build-module/slot-fill/provider.js.map +1 -1
  191. package/build-module/slot-fill/slot.js +0 -5
  192. package/build-module/slot-fill/slot.js.map +1 -1
  193. package/build-module/snackbar/list.js +0 -2
  194. package/build-module/snackbar/list.js.map +1 -1
  195. package/build-module/tab-panel/index.js.map +1 -1
  196. package/build-module/theme/color-algorithms.js +1 -1
  197. package/build-module/theme/color-algorithms.js.map +1 -1
  198. package/build-module/toggle-group-control/toggle-group-control/styles.js +7 -7
  199. package/build-module/toggle-group-control/toggle-group-control/styles.js.map +1 -1
  200. package/build-module/toolbar/toolbar-button/index.js +1 -2
  201. package/build-module/toolbar/toolbar-button/index.js.map +1 -1
  202. package/build-module/toolbar/toolbar-item/index.js +5 -2
  203. package/build-module/toolbar/toolbar-item/index.js.map +1 -1
  204. package/build-module/utils/colors-values.js +3 -3
  205. package/build-module/utils/colors-values.js.map +1 -1
  206. package/build-module/utils/use-deprecated-props.js +25 -0
  207. package/build-module/utils/use-deprecated-props.js.map +1 -0
  208. package/build-style/style-rtl.css +67 -67
  209. package/build-style/style.css +67 -67
  210. package/build-types/autocomplete/autocompleter-ui.d.ts.map +1 -1
  211. package/build-types/autocomplete/index.d.ts.map +1 -1
  212. package/build-types/autocomplete/types.d.ts +2 -18
  213. package/build-types/autocomplete/types.d.ts.map +1 -1
  214. package/build-types/button/deprecated.d.ts +6 -0
  215. package/build-types/button/deprecated.d.ts.map +1 -1
  216. package/build-types/button/index.d.ts.map +1 -1
  217. package/build-types/button/types.d.ts +7 -0
  218. package/build-types/button/types.d.ts.map +1 -1
  219. package/build-types/card/card-media/component.d.ts +2 -1
  220. package/build-types/card/card-media/component.d.ts.map +1 -1
  221. package/build-types/card/stories/index.d.ts +21 -1
  222. package/build-types/card/stories/index.d.ts.map +1 -1
  223. package/build-types/color-picker/styles.d.ts.map +1 -1
  224. package/build-types/combobox-control/index.d.ts +1 -1
  225. package/build-types/combobox-control/index.d.ts.map +1 -1
  226. package/build-types/combobox-control/stories/index.d.ts.map +1 -1
  227. package/build-types/combobox-control/styles.d.ts +1 -1
  228. package/build-types/combobox-control/types.d.ts +8 -1
  229. package/build-types/combobox-control/types.d.ts.map +1 -1
  230. package/build-types/date-time/date-time/index.d.ts +3 -4
  231. package/build-types/date-time/date-time/index.d.ts.map +1 -1
  232. package/build-types/date-time/date-time/styles.d.ts +0 -4
  233. package/build-types/date-time/date-time/styles.d.ts.map +1 -1
  234. package/build-types/date-time/stories/date-time.d.ts.map +1 -1
  235. package/build-types/date-time/types.d.ts +0 -14
  236. package/build-types/date-time/types.d.ts.map +1 -1
  237. package/build-types/dimension-control/index.d.ts +1 -1
  238. package/build-types/draggable/index.d.ts.map +1 -1
  239. package/build-types/dropdown-menu/index.d.ts +83 -1
  240. package/build-types/dropdown-menu/index.d.ts.map +1 -1
  241. package/build-types/dropdown-menu/stories/index.d.ts +13 -0
  242. package/build-types/dropdown-menu/stories/index.d.ts.map +1 -0
  243. package/build-types/dropdown-menu/test/index.d.ts +2 -0
  244. package/build-types/dropdown-menu/test/index.d.ts.map +1 -0
  245. package/build-types/dropdown-menu/types.d.ts +134 -0
  246. package/build-types/dropdown-menu/types.d.ts.map +1 -0
  247. package/build-types/dropdown-menu-v2/index.d.ts +17 -0
  248. package/build-types/dropdown-menu-v2/index.d.ts.map +1 -0
  249. package/build-types/dropdown-menu-v2/stories/index.d.ts +13 -0
  250. package/build-types/dropdown-menu-v2/stories/index.d.ts.map +1 -0
  251. package/build-types/dropdown-menu-v2/styles.d.ts +41 -0
  252. package/build-types/dropdown-menu-v2/styles.d.ts.map +1 -0
  253. package/build-types/dropdown-menu-v2/test/index.d.ts +2 -0
  254. package/build-types/dropdown-menu-v2/test/index.d.ts.map +1 -0
  255. package/build-types/dropdown-menu-v2/types.d.ts +242 -0
  256. package/build-types/dropdown-menu-v2/types.d.ts.map +1 -0
  257. package/build-types/form-token-field/index.d.ts.map +1 -1
  258. package/build-types/form-token-field/styles.d.ts +1 -1
  259. package/build-types/form-token-field/types.d.ts +8 -1
  260. package/build-types/form-token-field/types.d.ts.map +1 -1
  261. package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
  262. package/build-types/navigable-container/container.d.ts +20 -1
  263. package/build-types/navigable-container/container.d.ts.map +1 -1
  264. package/build-types/navigable-container/index.d.ts +5 -2
  265. package/build-types/navigable-container/index.d.ts.map +1 -1
  266. package/build-types/navigable-container/menu.d.ts +45 -11
  267. package/build-types/navigable-container/menu.d.ts.map +1 -1
  268. package/build-types/navigable-container/stories/navigable-menu.d.ts +12 -0
  269. package/build-types/navigable-container/stories/navigable-menu.d.ts.map +1 -0
  270. package/build-types/navigable-container/stories/tabbable-container.d.ts +12 -0
  271. package/build-types/navigable-container/stories/tabbable-container.d.ts.map +1 -0
  272. package/build-types/navigable-container/tabbable.d.ts +52 -9
  273. package/build-types/navigable-container/tabbable.d.ts.map +1 -1
  274. package/build-types/navigable-container/test/navigable-menu.d.ts +2 -0
  275. package/build-types/navigable-container/test/navigable-menu.d.ts.map +1 -0
  276. package/build-types/navigable-container/test/tababble-container.d.ts +2 -0
  277. package/build-types/navigable-container/test/tababble-container.d.ts.map +1 -0
  278. package/build-types/navigable-container/types.d.ts +61 -0
  279. package/build-types/navigable-container/types.d.ts.map +1 -0
  280. package/build-types/navigator/navigator-back-button/component.d.ts +1 -0
  281. package/build-types/navigator/navigator-back-button/component.d.ts.map +1 -1
  282. package/build-types/navigator/navigator-back-button/hook.d.ts +1 -0
  283. package/build-types/navigator/navigator-back-button/hook.d.ts.map +1 -1
  284. package/build-types/navigator/navigator-button/component.d.ts +1 -0
  285. package/build-types/navigator/navigator-button/component.d.ts.map +1 -1
  286. package/build-types/navigator/navigator-button/hook.d.ts +1 -0
  287. package/build-types/navigator/navigator-button/hook.d.ts.map +1 -1
  288. package/build-types/navigator/navigator-to-parent-button/component.d.ts +1 -0
  289. package/build-types/navigator/navigator-to-parent-button/component.d.ts.map +1 -1
  290. package/build-types/palette-edit/index.d.ts +1 -1
  291. package/build-types/palette-edit/index.d.ts.map +1 -1
  292. package/build-types/palette-edit/stories/index.d.ts.map +1 -1
  293. package/build-types/palette-edit/types.d.ts +8 -0
  294. package/build-types/palette-edit/types.d.ts.map +1 -1
  295. package/build-types/private-apis.d.ts.map +1 -1
  296. package/build-types/slot-fill/bubbles-virtually/fill.d.ts.map +1 -1
  297. package/build-types/slot-fill/bubbles-virtually/slot-fill-provider.d.ts.map +1 -1
  298. package/build-types/slot-fill/bubbles-virtually/use-slot.d.ts.map +1 -1
  299. package/build-types/slot-fill/fill.d.ts +4 -2
  300. package/build-types/slot-fill/fill.d.ts.map +1 -1
  301. package/build-types/slot-fill/index.d.ts +1 -2
  302. package/build-types/slot-fill/index.d.ts.map +1 -1
  303. package/build-types/slot-fill/provider.d.ts +0 -2
  304. package/build-types/slot-fill/provider.d.ts.map +1 -1
  305. package/build-types/slot-fill/slot.d.ts.map +1 -1
  306. package/build-types/snackbar/list.d.ts.map +1 -1
  307. package/build-types/toggle-group-control/toggle-group-control/styles.d.ts.map +1 -1
  308. package/build-types/toolbar/stories/index.d.ts.map +1 -1
  309. package/build-types/toolbar/toolbar-button/index.d.ts +6 -0
  310. package/build-types/toolbar/toolbar-button/index.d.ts.map +1 -1
  311. package/build-types/toolbar/toolbar-item/index.d.ts +6 -4
  312. package/build-types/toolbar/toolbar-item/index.d.ts.map +1 -1
  313. package/build-types/tree-grid/types.d.ts +7 -0
  314. package/build-types/tree-grid/types.d.ts.map +1 -1
  315. package/build-types/ui/context/get-styled-class-name-from-key.d.ts +1 -10
  316. package/build-types/ui/context/get-styled-class-name-from-key.d.ts.map +1 -1
  317. package/build-types/utils/use-deprecated-props.d.ts +9 -0
  318. package/build-types/utils/use-deprecated-props.d.ts.map +1 -0
  319. package/package.json +21 -20
  320. package/src/autocomplete/README.md +78 -52
  321. package/src/autocomplete/autocompleter-ui.tsx +0 -2
  322. package/src/autocomplete/index.tsx +1 -2
  323. package/src/autocomplete/types.ts +3 -19
  324. package/src/button/index.tsx +2 -0
  325. package/src/button/style.scss +18 -18
  326. package/src/button/types.ts +7 -0
  327. package/src/card/card-media/README.md +1 -1
  328. package/src/card/card-media/component.tsx +2 -1
  329. package/src/card/stories/index.tsx +47 -26
  330. package/src/checkbox-control/style.scss +1 -4
  331. package/src/color-picker/styles.ts +7 -2
  332. package/src/combobox-control/index.tsx +24 -18
  333. package/src/combobox-control/stories/index.tsx +0 -1
  334. package/src/combobox-control/styles.ts +4 -4
  335. package/src/combobox-control/types.ts +8 -1
  336. package/src/custom-gradient-picker/style.scss +2 -2
  337. package/src/date-time/README.md +0 -16
  338. package/src/date-time/date-time/index.tsx +17 -155
  339. package/src/date-time/date-time/styles.ts +0 -4
  340. package/src/date-time/stories/date-time.tsx +0 -4
  341. package/src/date-time/types.ts +0 -16
  342. package/src/dimension-control/index.tsx +1 -1
  343. package/src/draggable/index.tsx +1 -9
  344. package/src/dropdown-menu/README.md +12 -22
  345. package/src/dropdown-menu/{index.js → index.tsx} +111 -25
  346. package/src/dropdown-menu/stories/{index.js → index.tsx} +14 -22
  347. package/src/dropdown-menu/test/{index.js → index.tsx} +6 -5
  348. package/src/dropdown-menu/types.ts +143 -0
  349. package/src/dropdown-menu-v2/README.md +392 -0
  350. package/src/dropdown-menu-v2/index.tsx +241 -0
  351. package/src/dropdown-menu-v2/stories/index.tsx +193 -0
  352. package/src/dropdown-menu-v2/styles.ts +263 -0
  353. package/src/dropdown-menu-v2/test/index.tsx +816 -0
  354. package/src/dropdown-menu-v2/types.ts +250 -0
  355. package/src/form-toggle/style.scss +1 -5
  356. package/src/form-token-field/index.tsx +7 -3
  357. package/src/form-token-field/styles.ts +4 -4
  358. package/src/form-token-field/types.ts +8 -1
  359. package/src/index.native.js +0 -1
  360. package/src/input-control/styles/input-control-styles.tsx +7 -0
  361. package/src/mobile/bottom-sheet/cell.native.js +26 -5
  362. package/src/mobile/bottom-sheet/range-cell.native.js +2 -1
  363. package/src/mobile/bottom-sheet/stepper-cell/index.native.js +2 -0
  364. package/src/mobile/bottom-sheet/styles.native.scss +13 -1
  365. package/src/mobile/bottom-sheet/switch-cell.native.js +10 -2
  366. package/src/mobile/bottom-sheet-select-control/index.native.js +2 -0
  367. package/src/mobile/bottom-sheet-text-control/index.native.js +2 -0
  368. package/src/mobile/global-styles-context/index.native.js +12 -1
  369. package/src/mobile/link-picker/link-picker-results.native.js +3 -0
  370. package/src/modal/style.scss +1 -1
  371. package/src/navigable-container/README.md +24 -13
  372. package/src/navigable-container/{container.js → container.tsx} +57 -27
  373. package/src/navigable-container/{index.js → index.tsx} +0 -1
  374. package/src/navigable-container/menu.tsx +100 -0
  375. package/src/navigable-container/stories/{navigable-menu.js → navigable-menu.tsx} +15 -10
  376. package/src/navigable-container/stories/{tabbable-container.js → tabbable-container.tsx} +15 -6
  377. package/src/navigable-container/tabbable.tsx +92 -0
  378. package/src/navigable-container/test/{navigable-menu.js → navigable-menu.tsx} +3 -1
  379. package/src/navigable-container/test/{tababble-container.js → tababble-container.tsx} +53 -24
  380. package/src/navigable-container/types.ts +76 -0
  381. package/src/palette-edit/index.tsx +45 -7
  382. package/src/palette-edit/stories/index.tsx +4 -0
  383. package/src/palette-edit/types.ts +11 -0
  384. package/src/private-apis.ts +22 -0
  385. package/src/range-control/index.native.js +3 -0
  386. package/src/sandbox/index.native.js +4 -0
  387. package/src/search-control/style.scss +2 -0
  388. package/src/slot-fill/bubbles-virtually/fill.js +2 -1
  389. package/src/slot-fill/bubbles-virtually/slot-fill-provider.js +46 -60
  390. package/src/slot-fill/bubbles-virtually/use-slot.js +14 -41
  391. package/src/slot-fill/fill.js +4 -26
  392. package/src/slot-fill/index.js +1 -3
  393. package/src/slot-fill/provider.js +0 -6
  394. package/src/slot-fill/slot.js +0 -5
  395. package/src/snackbar/list.tsx +0 -1
  396. package/src/style.scss +6 -0
  397. package/src/tab-panel/index.tsx +1 -1
  398. package/src/theme/color-algorithms.ts +1 -1
  399. package/src/theme/stories/index.tsx +1 -1
  400. package/src/theme/test/color-algorithms.ts +2 -2
  401. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +10 -6
  402. package/src/toggle-group-control/toggle-group-control/styles.ts +6 -1
  403. package/src/toolbar/stories/index.tsx +25 -26
  404. package/src/toolbar/toolbar-button/index.tsx +10 -13
  405. package/src/toolbar/toolbar-item/{index.js → index.tsx} +12 -3
  406. package/src/tooltip/style.scss +2 -2
  407. package/src/tree-grid/README.md +18 -0
  408. package/src/tree-grid/types.ts +7 -0
  409. package/src/utils/colors-values.js +3 -3
  410. package/src/utils/theme-variables.scss +4 -4
  411. package/src/utils/use-deprecated-props.ts +29 -0
  412. package/tsconfig.json +1 -0
  413. package/tsconfig.tsbuildinfo +1 -1
  414. package/build/mobile/readable-content-view/index.native.js +0 -97
  415. package/build/mobile/readable-content-view/index.native.js.map +0 -1
  416. package/build-module/mobile/readable-content-view/index.native.js +0 -81
  417. package/build-module/mobile/readable-content-view/index.native.js.map +0 -1
  418. package/src/CONTRIBUTING.md +0 -78
  419. package/src/README.md +0 -20
  420. package/src/mobile/readable-content-view/index.native.js +0 -85
  421. package/src/mobile/readable-content-view/style.native.scss +0 -30
  422. package/src/navigable-container/menu.js +0 -62
  423. package/src/navigable-container/tabbable.js +0 -46
@@ -1,14 +1,23 @@
1
- // @ts-nocheck
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ForwardedRef } from 'react';
5
+
2
6
  /**
3
7
  * WordPress dependencies
4
8
  */
5
9
  import { Component, forwardRef } from '@wordpress/element';
6
10
  import { focus } from '@wordpress/dom';
7
11
 
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import type { NavigableContainerProps } from './types';
16
+
8
17
  const noop = () => {};
9
18
  const MENU_ITEM_ROLES = [ 'menuitem', 'menuitemradio', 'menuitemcheckbox' ];
10
19
 
11
- function cycleValue( value, total, offset ) {
20
+ function cycleValue( value: number, total: number, offset: number ) {
12
21
  const nextValue = value + offset;
13
22
  if ( nextValue < 0 ) {
14
23
  return total + nextValue;
@@ -19,9 +28,11 @@ function cycleValue( value, total, offset ) {
19
28
  return nextValue;
20
29
  }
21
30
 
22
- class NavigableContainer extends Component {
23
- constructor() {
24
- super( ...arguments );
31
+ class NavigableContainer extends Component< NavigableContainerProps > {
32
+ container?: HTMLDivElement;
33
+
34
+ constructor( args: NavigableContainerProps ) {
35
+ super( args );
25
36
  this.onKeyDown = this.onKeyDown.bind( this );
26
37
  this.bindContainer = this.bindContainer.bind( this );
27
38
 
@@ -30,21 +41,27 @@ class NavigableContainer extends Component {
30
41
  }
31
42
 
32
43
  componentDidMount() {
44
+ if ( ! this.container ) {
45
+ return;
46
+ }
47
+
33
48
  // We use DOM event listeners instead of React event listeners
34
49
  // because we want to catch events from the underlying DOM tree
35
50
  // The React Tree can be different from the DOM tree when using
36
51
  // portals. Block Toolbars for instance are rendered in a separate
37
52
  // React Trees.
38
53
  this.container.addEventListener( 'keydown', this.onKeyDown );
39
- this.container.addEventListener( 'focus', this.onFocus );
40
54
  }
41
55
 
42
56
  componentWillUnmount() {
57
+ if ( ! this.container ) {
58
+ return;
59
+ }
60
+
43
61
  this.container.removeEventListener( 'keydown', this.onKeyDown );
44
- this.container.removeEventListener( 'focus', this.onFocus );
45
62
  }
46
63
 
47
- bindContainer( ref ) {
64
+ bindContainer( ref: HTMLDivElement ) {
48
65
  const { forwardedRef } = this.props;
49
66
  this.container = ref;
50
67
 
@@ -55,10 +72,14 @@ class NavigableContainer extends Component {
55
72
  }
56
73
  }
57
74
 
58
- getFocusableContext( target ) {
75
+ getFocusableContext( target: Element ) {
76
+ if ( ! this.container ) {
77
+ return null;
78
+ }
79
+
59
80
  const { onlyBrowserTabstops } = this.props;
60
81
  const finder = onlyBrowserTabstops ? focus.tabbable : focus.focusable;
61
- const focusables = finder.find( this.container );
82
+ const focusables = finder.find( this.container ) as HTMLElement[];
62
83
 
63
84
  const index = this.getFocusableIndex( focusables, target );
64
85
  if ( index > -1 && target ) {
@@ -67,14 +88,11 @@ class NavigableContainer extends Component {
67
88
  return null;
68
89
  }
69
90
 
70
- getFocusableIndex( focusables, target ) {
71
- const directIndex = focusables.indexOf( target );
72
- if ( directIndex !== -1 ) {
73
- return directIndex;
74
- }
91
+ getFocusableIndex( focusables: Element[], target: Element ) {
92
+ return focusables.indexOf( target );
75
93
  }
76
94
 
77
- onKeyDown( event ) {
95
+ onKeyDown( event: KeyboardEvent ) {
78
96
  if ( this.props.onKeyDown ) {
79
97
  this.props.onKeyDown( event );
80
98
  }
@@ -98,15 +116,13 @@ class NavigableContainer extends Component {
98
116
  // from scrolling. The preventDefault also prevents Voiceover from
99
117
  // 'handling' the event, as voiceover will try to use arrow keys
100
118
  // for highlighting text.
101
- const targetRole = event.target.getAttribute( 'role' );
119
+ const targetRole = (
120
+ event.target as HTMLDivElement | null
121
+ )?.getAttribute( 'role' );
102
122
  const targetHasMenuItemRole =
103
- MENU_ITEM_ROLES.includes( targetRole );
104
-
105
- // `preventDefault()` on tab to avoid having the browser move the focus
106
- // after this component has already moved it.
107
- const isTab = event.code === 'Tab';
123
+ !! targetRole && MENU_ITEM_ROLES.includes( targetRole );
108
124
 
109
- if ( targetHasMenuItemRole || isTab ) {
125
+ if ( targetHasMenuItemRole ) {
110
126
  event.preventDefault();
111
127
  }
112
128
  }
@@ -115,9 +131,13 @@ class NavigableContainer extends Component {
115
131
  return;
116
132
  }
117
133
 
118
- const context = getFocusableContext(
119
- event.target.ownerDocument.activeElement
120
- );
134
+ const activeElement = ( event.target as HTMLElement | null )
135
+ ?.ownerDocument?.activeElement;
136
+ if ( ! activeElement ) {
137
+ return;
138
+ }
139
+
140
+ const context = getFocusableContext( activeElement );
121
141
  if ( ! context ) {
122
142
  return;
123
143
  }
@@ -126,9 +146,16 @@ class NavigableContainer extends Component {
126
146
  const nextIndex = cycle
127
147
  ? cycleValue( index, focusables.length, offset )
128
148
  : index + offset;
149
+
129
150
  if ( nextIndex >= 0 && nextIndex < focusables.length ) {
130
151
  focusables[ nextIndex ].focus();
131
152
  onNavigate( nextIndex, focusables[ nextIndex ] );
153
+
154
+ // `preventDefault()` on tab to avoid having the browser move the focus
155
+ // after this component has already moved it.
156
+ if ( event.code === 'Tab' ) {
157
+ event.preventDefault();
158
+ }
132
159
  }
133
160
  }
134
161
 
@@ -152,7 +179,10 @@ class NavigableContainer extends Component {
152
179
  }
153
180
  }
154
181
 
155
- const forwardedNavigableContainer = ( props, ref ) => {
182
+ const forwardedNavigableContainer = (
183
+ props: NavigableContainerProps,
184
+ ref: ForwardedRef< HTMLDivElement >
185
+ ) => {
156
186
  return <NavigableContainer { ...props } forwardedRef={ ref } />;
157
187
  };
158
188
  forwardedNavigableContainer.displayName = 'NavigableContainer';
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * Internal Dependencies
4
3
  */
@@ -0,0 +1,100 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ForwardedRef } from 'react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { forwardRef } from '@wordpress/element';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import NavigableContainer from './container';
15
+ import type { NavigableMenuProps } from './types';
16
+
17
+ export function UnforwardedNavigableMenu(
18
+ { role = 'menu', orientation = 'vertical', ...rest }: NavigableMenuProps,
19
+ ref: ForwardedRef< any >
20
+ ) {
21
+ const eventToOffset = ( evt: KeyboardEvent ) => {
22
+ const { code } = evt;
23
+
24
+ let next = [ 'ArrowDown' ];
25
+ let previous = [ 'ArrowUp' ];
26
+
27
+ if ( orientation === 'horizontal' ) {
28
+ next = [ 'ArrowRight' ];
29
+ previous = [ 'ArrowLeft' ];
30
+ }
31
+
32
+ if ( orientation === 'both' ) {
33
+ next = [ 'ArrowRight', 'ArrowDown' ];
34
+ previous = [ 'ArrowLeft', 'ArrowUp' ];
35
+ }
36
+
37
+ if ( next.includes( code ) ) {
38
+ return 1;
39
+ } else if ( previous.includes( code ) ) {
40
+ return -1;
41
+ } else if (
42
+ [ 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight' ].includes(
43
+ code
44
+ )
45
+ ) {
46
+ // Key press should be handled, e.g. have event propagation and
47
+ // default behavior handled by NavigableContainer but not result
48
+ // in an offset.
49
+ return 0;
50
+ }
51
+
52
+ return undefined;
53
+ };
54
+
55
+ return (
56
+ <NavigableContainer
57
+ ref={ ref }
58
+ stopNavigationEvents
59
+ onlyBrowserTabstops={ false }
60
+ role={ role }
61
+ aria-orientation={
62
+ role !== 'presentation' &&
63
+ ( orientation === 'vertical' || orientation === 'horizontal' )
64
+ ? orientation
65
+ : undefined
66
+ }
67
+ eventToOffset={ eventToOffset }
68
+ { ...rest }
69
+ />
70
+ );
71
+ }
72
+
73
+ /**
74
+ * A container for a navigable menu.
75
+ *
76
+ * ```jsx
77
+ * import {
78
+ * NavigableMenu,
79
+ * Button,
80
+ * } from '@wordpress/components';
81
+ *
82
+ * function onNavigate( index, target ) {
83
+ * console.log( `Navigates to ${ index }`, target );
84
+ * }
85
+ *
86
+ * const MyNavigableContainer = () => (
87
+ * <div>
88
+ * <span>Navigable Menu:</span>
89
+ * <NavigableMenu onNavigate={ onNavigate } orientation="horizontal">
90
+ * <Button variant="secondary">Item 1</Button>
91
+ * <Button variant="secondary">Item 2</Button>
92
+ * <Button variant="secondary">Item 3</Button>
93
+ * </NavigableMenu>
94
+ * </div>
95
+ * );
96
+ * ```
97
+ */
98
+ export const NavigableMenu = forwardRef( UnforwardedNavigableMenu );
99
+
100
+ export default NavigableMenu;
@@ -1,25 +1,30 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentMeta, ComponentStory } from '@storybook/react';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import { NavigableMenu } from '..';
5
10
 
6
- export default {
11
+ const meta: ComponentMeta< typeof NavigableMenu > = {
7
12
  title: 'Components/NavigableMenu',
8
13
  component: NavigableMenu,
9
14
  argTypes: {
10
- children: { type: null },
11
- cycle: {
12
- type: 'boolean',
13
- },
14
- onNavigate: { action: 'onNavigate' },
15
- orientation: {
16
- options: [ 'horizontal', 'vertical' ],
17
- control: { type: 'radio' },
15
+ children: { control: { type: null } },
16
+ },
17
+ parameters: {
18
+ actions: { argTypesRegex: '^on.*' },
19
+ controls: {
20
+ expanded: true,
18
21
  },
22
+ docs: { source: { state: 'open' } },
19
23
  },
20
24
  };
25
+ export default meta;
21
26
 
22
- export const Default = ( args ) => {
27
+ export const Default: ComponentStory< typeof NavigableMenu > = ( args ) => {
23
28
  return (
24
29
  <>
25
30
  <button>Before navigable menu</button>
@@ -1,21 +1,30 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentMeta, ComponentStory } from '@storybook/react';
5
+
1
6
  /**
2
7
  * Internal dependencies
3
8
  */
4
9
  import { TabbableContainer } from '..';
5
10
 
6
- export default {
11
+ const meta: ComponentMeta< typeof TabbableContainer > = {
7
12
  title: 'Components/TabbableContainer',
8
13
  component: TabbableContainer,
9
14
  argTypes: {
10
- children: { type: null },
11
- cycle: {
12
- type: 'boolean',
15
+ children: { control: { type: null } },
16
+ },
17
+ parameters: {
18
+ actions: { argTypesRegex: '^on.*' },
19
+ controls: {
20
+ expanded: true,
13
21
  },
14
- onNavigate: { action: 'onNavigate' },
22
+ docs: { source: { state: 'open' } },
15
23
  },
16
24
  };
25
+ export default meta;
17
26
 
18
- export const Default = ( args ) => {
27
+ export const Default: ComponentStory< typeof TabbableContainer > = ( args ) => {
19
28
  return (
20
29
  <>
21
30
  <button>Before tabbable container</button>
@@ -0,0 +1,92 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ForwardedRef } from 'react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { forwardRef } from '@wordpress/element';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import NavigableContainer from './container';
15
+ import type { TabbableContainerProps } from './types';
16
+
17
+ export function UnforwardedTabbableContainer(
18
+ { eventToOffset, ...props }: TabbableContainerProps,
19
+ ref: ForwardedRef< any >
20
+ ) {
21
+ const innerEventToOffset = ( evt: KeyboardEvent ) => {
22
+ const { code, shiftKey } = evt;
23
+ if ( 'Tab' === code ) {
24
+ return shiftKey ? -1 : 1;
25
+ }
26
+
27
+ // Allow custom handling of keys besides Tab.
28
+ //
29
+ // By default, TabbableContainer will move focus forward on Tab and
30
+ // backward on Shift+Tab. The handler below will be used for all other
31
+ // events. The semantics for `eventToOffset`'s return
32
+ // values are the following:
33
+ //
34
+ // - +1: move focus forward
35
+ // - -1: move focus backward
36
+ // - 0: don't move focus, but acknowledge event and thus stop it
37
+ // - undefined: do nothing, let the event propagate.
38
+ if ( eventToOffset ) {
39
+ return eventToOffset( evt );
40
+ }
41
+
42
+ return undefined;
43
+ };
44
+
45
+ return (
46
+ <NavigableContainer
47
+ ref={ ref }
48
+ stopNavigationEvents
49
+ onlyBrowserTabstops
50
+ eventToOffset={ innerEventToOffset }
51
+ { ...props }
52
+ />
53
+ );
54
+ }
55
+
56
+ /**
57
+ * A container for tabbable elements.
58
+ *
59
+ * ```jsx
60
+ * import {
61
+ * TabbableContainer,
62
+ * Button,
63
+ * } from '@wordpress/components';
64
+ *
65
+ * function onNavigate( index, target ) {
66
+ * console.log( `Navigates to ${ index }`, target );
67
+ * }
68
+ *
69
+ * const MyTabbableContainer = () => (
70
+ * <div>
71
+ * <span>Tabbable Container:</span>
72
+ * <TabbableContainer onNavigate={ onNavigate }>
73
+ * <Button variant="secondary" tabIndex="0">
74
+ * Section 1
75
+ * </Button>
76
+ * <Button variant="secondary" tabIndex="0">
77
+ * Section 2
78
+ * </Button>
79
+ * <Button variant="secondary" tabIndex="0">
80
+ * Section 3
81
+ * </Button>
82
+ * <Button variant="secondary" tabIndex="0">
83
+ * Section 4
84
+ * </Button>
85
+ * </TabbableContainer>
86
+ * </div>
87
+ * );
88
+ * ```
89
+ */
90
+ export const TabbableContainer = forwardRef( UnforwardedTabbableContainer );
91
+
92
+ export default TabbableContainer;
@@ -8,8 +8,9 @@ import userEvent from '@testing-library/user-event';
8
8
  * Internal dependencies
9
9
  */
10
10
  import { NavigableMenu } from '../menu';
11
+ import type { NavigableMenuProps } from '../types';
11
12
 
12
- const NavigableMenuTestCase = ( props ) => (
13
+ const NavigableMenuTestCase = ( props: NavigableMenuProps ) => (
13
14
  <NavigableMenu { ...props }>
14
15
  <button>Item 1</button>
15
16
  <span>
@@ -34,6 +35,7 @@ describe( 'NavigableMenu', () => {
34
35
  // Mocking `getClientRects()` is necessary to pass a check performed by
35
36
  // the `focus.tabbable.find()` and by the `focus.focusable.find()` functions
36
37
  // from the `@wordpress/dom` package.
38
+ // @ts-expect-error We're not trying to comply to the DOM spec, only mocking
37
39
  window.HTMLElement.prototype.getClientRects = function () {
38
40
  return [ 'trick-jsdom-into-having-size-for-element-rect' ];
39
41
  };
@@ -8,20 +8,25 @@ import userEvent from '@testing-library/user-event';
8
8
  * Internal dependencies
9
9
  */
10
10
  import { TabbableContainer } from '../tabbable';
11
-
12
- const TabbableContainerTestCase = ( props ) => (
13
- <TabbableContainer { ...props }>
14
- <button>Item 1</button>
15
- <span>
16
- <span tabIndex={ -1 }>Item 2 (not tabbable)</span>
17
- </span>
18
- <span>
19
- <span tabIndex={ 0 }>Item 3</span>
20
- </span>
21
- <p>I can not be tabbed</p>
22
- <input type="text" disabled name="disabled-input" />
23
- <a href="https://example.com">Item 4</a>
24
- </TabbableContainer>
11
+ import type { TabbableContainerProps } from '../types';
12
+
13
+ const TabbableContainerTestCase = ( props: TabbableContainerProps ) => (
14
+ <>
15
+ <button>Before container</button>
16
+ <TabbableContainer { ...props }>
17
+ <button>Item 1</button>
18
+ <span>
19
+ <span tabIndex={ -1 }>Item 2 (not tabbable)</span>
20
+ </span>
21
+ <span>
22
+ <span tabIndex={ 0 }>Item 3</span>
23
+ </span>
24
+ <p>I can not be tabbed</p>
25
+ <input type="text" disabled name="disabled-input" />
26
+ <a href="https://example.com">Item 4</a>
27
+ </TabbableContainer>
28
+ <button>After container</button>
29
+ </>
25
30
  );
26
31
 
27
32
  const getTabbableContainerTabbables = () => [
@@ -37,6 +42,7 @@ describe( 'TabbableContainer', () => {
37
42
  // Mocking `getClientRects()` is necessary to pass a check performed by
38
43
  // the `focus.tabbable.find()` and by the `focus.focusable.find()` functions
39
44
  // from the `@wordpress/dom` package.
45
+ // @ts-expect-error We're not trying to comply to the DOM spec, only mocking
40
46
  window.HTMLElement.prototype.getClientRects = function () {
41
47
  return [ 'trick-jsdom-into-having-size-for-element-rect' ];
42
48
  };
@@ -55,7 +61,11 @@ describe( 'TabbableContainer', () => {
55
61
 
56
62
  const tabbables = getTabbableContainerTabbables();
57
63
 
58
- // Move focus to first item.
64
+ await user.tab();
65
+ expect(
66
+ screen.getByRole( 'button', { name: 'Before container' } )
67
+ ).toHaveFocus();
68
+
59
69
  await user.tab();
60
70
  expect( tabbables[ 0 ] ).toHaveFocus();
61
71
 
@@ -89,7 +99,11 @@ describe( 'TabbableContainer', () => {
89
99
  const lastTabbableIndex = tabbables.length - 1;
90
100
  const lastTabbable = tabbables[ lastTabbableIndex ];
91
101
 
92
- // Move focus to first item.
102
+ await user.tab();
103
+ expect(
104
+ screen.getByRole( 'button', { name: 'Before container' } )
105
+ ).toHaveFocus();
106
+
93
107
  await user.tab();
94
108
  expect( firstTabbable ).toHaveFocus();
95
109
 
@@ -114,12 +128,17 @@ describe( 'TabbableContainer', () => {
114
128
  />
115
129
  );
116
130
 
117
- // With the `cycle` prop set to `false`, cycling is not allowed.
118
131
  // By default, cycling from first to last and from last to first is allowed.
132
+ // With the `cycle` prop set to `false`, cycling is not allowed.
133
+ // Therefore, focus will escape the `TabbableContainer` and continue its
134
+ // natural path in the page.
119
135
  await user.tab( { shift: true } );
120
- expect( firstTabbable ).toHaveFocus();
136
+ expect(
137
+ screen.getByRole( 'button', { name: 'Before container' } )
138
+ ).toHaveFocus();
121
139
  expect( onNavigateSpy ).toHaveBeenCalledTimes( 2 );
122
140
 
141
+ await user.tab();
123
142
  await user.tab();
124
143
  await user.tab();
125
144
  expect( lastTabbable ).toHaveFocus();
@@ -129,8 +148,12 @@ describe( 'TabbableContainer', () => {
129
148
  lastTabbable
130
149
  );
131
150
 
151
+ // Focus will move to the next natively focusable elements after
152
+ // `TabbableContainer`
132
153
  await user.tab();
133
- expect( lastTabbable ).toHaveFocus();
154
+ expect(
155
+ screen.getByRole( 'button', { name: 'After container' } )
156
+ ).toHaveFocus();
134
157
  expect( onNavigateSpy ).toHaveBeenCalledTimes( 4 );
135
158
  } );
136
159
 
@@ -149,21 +172,27 @@ describe( 'TabbableContainer', () => {
149
172
 
150
173
  const tabbables = getTabbableContainerTabbables();
151
174
 
152
- // Move focus to first item
175
+ await user.tab();
176
+ expect(
177
+ screen.getByRole( 'button', { name: 'Before container' } )
178
+ ).toHaveFocus();
179
+ expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 0 );
180
+
153
181
  await user.tab();
154
182
  expect( tabbables[ 0 ] ).toHaveFocus();
183
+ expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 1 );
155
184
 
156
185
  await user.keyboard( '[Space]' );
157
- expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 1 );
186
+ expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 2 );
158
187
 
159
188
  await user.tab();
160
- expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 1 );
189
+ expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 2 );
161
190
  await user.tab( { shift: true } );
162
191
  // This extra call is caused by the "shift" key being pressed
163
192
  // on its own before "tab"
164
- expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 2 );
193
+ expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 3 );
165
194
 
166
195
  await user.keyboard( '[Escape]' );
167
- expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 3 );
196
+ expect( externalWrapperOnKeyDownSpy ).toHaveBeenCalledTimes( 4 );
168
197
  } );
169
198
  } );
@@ -0,0 +1,76 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ForwardedRef, ReactNode } from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import type { WordPressComponentProps } from '../ui/context';
10
+
11
+ type BaseProps = {
12
+ /**
13
+ * The component children.
14
+ */
15
+ children?: ReactNode;
16
+ /**
17
+ * A boolean which tells the component whether or not to cycle from the end back to the beginning and vice versa.
18
+ *
19
+ * @default true
20
+ */
21
+ cycle?: boolean;
22
+ /**
23
+ * A callback invoked on the keydown event.
24
+ */
25
+ onKeyDown?: ( event: KeyboardEvent ) => void;
26
+ /**
27
+ * A callback invoked when the menu navigates to one of its children passing the index and child as an argument
28
+ */
29
+ onNavigate?: ( index: number, focusable: HTMLElement ) => void;
30
+ };
31
+
32
+ export type NavigableContainerProps = WordPressComponentProps<
33
+ BaseProps & {
34
+ /**
35
+ * Gets an offset, given an event.
36
+ */
37
+ eventToOffset: ( event: KeyboardEvent ) => -1 | 0 | 1 | undefined;
38
+ /**
39
+ * The forwarded ref.
40
+ */
41
+ forwardedRef?: ForwardedRef< any >;
42
+ /**
43
+ * Whether to only consider browser tab stops.
44
+ *
45
+ * @default false
46
+ */
47
+ onlyBrowserTabstops: boolean;
48
+ /**
49
+ * Whether to stop navigation events.
50
+ *
51
+ * @default false
52
+ */
53
+ stopNavigationEvents: boolean;
54
+ },
55
+ 'div',
56
+ false
57
+ >;
58
+
59
+ export type NavigableMenuProps = WordPressComponentProps<
60
+ BaseProps & {
61
+ /**
62
+ * The orientation of the menu.
63
+ *
64
+ * @default 'vertical'
65
+ */
66
+ orientation?: 'vertical' | 'horizontal' | 'both';
67
+ },
68
+ 'div',
69
+ false
70
+ >;
71
+
72
+ export type TabbableContainerProps = WordPressComponentProps<
73
+ BaseProps & Partial< Pick< NavigableContainerProps, 'eventToOffset' > >,
74
+ 'div',
75
+ false
76
+ >;