@wordpress/components 21.1.2-next.4d3b314fd5.0 → 21.3.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 (401) hide show
  1. package/CHANGELOG.md +48 -3
  2. package/CONTRIBUTING.md +20 -0
  3. package/build/border-box-control/border-box-control/component.js +2 -0
  4. package/build/border-box-control/border-box-control/component.js.map +1 -1
  5. package/build/border-box-control/border-box-control/hook.js +4 -1
  6. package/build/border-box-control/border-box-control/hook.js.map +1 -1
  7. package/build/border-box-control/utils.js +42 -2
  8. package/build/border-box-control/utils.js.map +1 -1
  9. package/build/border-control/border-control/component.js +2 -0
  10. package/build/border-control/border-control/component.js.map +1 -1
  11. package/build/combobox-control/index.js +0 -1
  12. package/build/combobox-control/index.js.map +1 -1
  13. package/build/custom-select-control/index.js +4 -2
  14. package/build/custom-select-control/index.js.map +1 -1
  15. package/build/disabled/index.js +6 -26
  16. package/build/disabled/index.js.map +1 -1
  17. package/build/font-size-picker/index.js +47 -56
  18. package/build/font-size-picker/index.js.map +1 -1
  19. package/build/font-size-picker/styles.js +65 -0
  20. package/build/font-size-picker/styles.js.map +1 -0
  21. package/build/font-size-picker/types.js +6 -0
  22. package/build/font-size-picker/types.js.map +1 -0
  23. package/build/font-size-picker/utils.js +18 -16
  24. package/build/font-size-picker/utils.js.map +1 -1
  25. package/build/form-token-field/suggestions-list.js +5 -5
  26. package/build/form-token-field/suggestions-list.js.map +1 -1
  27. package/build/form-token-field/token-input.js +20 -1
  28. package/build/form-token-field/token-input.js.map +1 -1
  29. package/build/higher-order/with-fallback-styles/index.js +1 -1
  30. package/build/higher-order/with-fallback-styles/index.js.map +1 -1
  31. package/build/index.js +14 -6
  32. package/build/index.js.map +1 -1
  33. package/build/modal/aria-helper.js +2 -3
  34. package/build/modal/aria-helper.js.map +1 -1
  35. package/build/modal/index.js +42 -11
  36. package/build/modal/index.js.map +1 -1
  37. package/build/modal/types.js +6 -0
  38. package/build/modal/types.js.map +1 -0
  39. package/build/navigator/index.js +8 -8
  40. package/build/navigator/index.js.map +1 -1
  41. package/build/navigator/navigator-back-button/component.js +5 -4
  42. package/build/navigator/navigator-back-button/component.js.map +1 -1
  43. package/build/navigator/navigator-back-button/index.js +1 -1
  44. package/build/navigator/navigator-back-button/index.js.map +1 -1
  45. package/build/navigator/navigator-button/component.js +5 -4
  46. package/build/navigator/navigator-button/component.js.map +1 -1
  47. package/build/navigator/navigator-button/index.js +1 -1
  48. package/build/navigator/navigator-button/index.js.map +1 -1
  49. package/build/navigator/navigator-provider/component.js +10 -7
  50. package/build/navigator/navigator-provider/component.js.map +1 -1
  51. package/build/navigator/navigator-provider/index.js +1 -1
  52. package/build/navigator/navigator-provider/index.js.map +1 -1
  53. package/build/navigator/navigator-screen/component.js +30 -26
  54. package/build/navigator/navigator-screen/component.js.map +1 -1
  55. package/build/navigator/navigator-screen/index.js +1 -1
  56. package/build/navigator/navigator-screen/index.js.map +1 -1
  57. package/build/resizable-box/resize-tooltip/utils.js +12 -14
  58. package/build/resizable-box/resize-tooltip/utils.js.map +1 -1
  59. package/build/sandbox/index.js +68 -67
  60. package/build/sandbox/index.js.map +1 -1
  61. package/build/sandbox/index.native.js +66 -63
  62. package/build/sandbox/index.native.js.map +1 -1
  63. package/build/search-control/index.native.js +6 -2
  64. package/build/search-control/index.native.js.map +1 -1
  65. package/build/slot-fill/bubbles-virtually/slot-fill-context.js +8 -2
  66. package/build/slot-fill/bubbles-virtually/slot-fill-context.js.map +1 -1
  67. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js +31 -41
  68. package/build/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  69. package/build/slot-fill/bubbles-virtually/use-slot-fills.js +39 -0
  70. package/build/slot-fill/bubbles-virtually/use-slot-fills.js.map +1 -0
  71. package/build/slot-fill/bubbles-virtually/use-slot.js +13 -4
  72. package/build/slot-fill/bubbles-virtually/use-slot.js.map +1 -1
  73. package/build/slot-fill/index.js +8 -0
  74. package/build/slot-fill/index.js.map +1 -1
  75. package/build/tab-panel/index.js +4 -4
  76. package/build/tab-panel/index.js.map +1 -1
  77. package/build/theme/index.js +62 -0
  78. package/build/theme/index.js.map +1 -0
  79. package/build/theme/styles.js +33 -0
  80. package/build/theme/styles.js.map +1 -0
  81. package/build/theme/types.js +6 -0
  82. package/build/theme/types.js.map +1 -0
  83. package/build/toggle-group-control/toggle-group-control-option-base/styles.js +8 -8
  84. package/build/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
  85. package/build/tools-panel/tools-panel/hook.js +3 -3
  86. package/build/tools-panel/tools-panel/hook.js.map +1 -1
  87. package/build/tools-panel/tools-panel-item/hook.js +6 -6
  88. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  89. package/build/tooltip/index.js +4 -1
  90. package/build/tooltip/index.js.map +1 -1
  91. package/build/tooltip/index.native.js +17 -4
  92. package/build/tooltip/index.native.js.map +1 -1
  93. package/build-module/border-box-control/border-box-control/component.js +2 -0
  94. package/build-module/border-box-control/border-box-control/component.js.map +1 -1
  95. package/build-module/border-box-control/border-box-control/hook.js +4 -1
  96. package/build-module/border-box-control/border-box-control/hook.js.map +1 -1
  97. package/build-module/border-box-control/utils.js +36 -1
  98. package/build-module/border-box-control/utils.js.map +1 -1
  99. package/build-module/border-control/border-control/component.js +2 -0
  100. package/build-module/border-control/border-control/component.js.map +1 -1
  101. package/build-module/combobox-control/index.js +0 -1
  102. package/build-module/combobox-control/index.js.map +1 -1
  103. package/build-module/custom-select-control/index.js +2 -1
  104. package/build-module/custom-select-control/index.js.map +1 -1
  105. package/build-module/disabled/index.js +7 -26
  106. package/build-module/disabled/index.js.map +1 -1
  107. package/build-module/font-size-picker/index.js +46 -54
  108. package/build-module/font-size-picker/index.js.map +1 -1
  109. package/build-module/font-size-picker/styles.js +54 -0
  110. package/build-module/font-size-picker/styles.js.map +1 -0
  111. package/build-module/font-size-picker/types.js +2 -0
  112. package/build-module/font-size-picker/types.js.map +1 -0
  113. package/build-module/font-size-picker/utils.js +22 -16
  114. package/build-module/font-size-picker/utils.js.map +1 -1
  115. package/build-module/form-token-field/suggestions-list.js +5 -5
  116. package/build-module/form-token-field/suggestions-list.js.map +1 -1
  117. package/build-module/form-token-field/token-input.js +21 -2
  118. package/build-module/form-token-field/token-input.js.map +1 -1
  119. package/build-module/higher-order/with-fallback-styles/index.js +2 -2
  120. package/build-module/higher-order/with-fallback-styles/index.js.map +1 -1
  121. package/build-module/index.js +3 -2
  122. package/build-module/index.js.map +1 -1
  123. package/build-module/modal/aria-helper.js +2 -3
  124. package/build-module/modal/aria-helper.js.map +1 -1
  125. package/build-module/modal/index.js +44 -12
  126. package/build-module/modal/index.js.map +1 -1
  127. package/build-module/modal/types.js +2 -0
  128. package/build-module/modal/types.js.map +1 -0
  129. package/build-module/navigator/index.js +4 -4
  130. package/build-module/navigator/index.js.map +1 -1
  131. package/build-module/navigator/navigator-back-button/component.js +3 -3
  132. package/build-module/navigator/navigator-back-button/component.js.map +1 -1
  133. package/build-module/navigator/navigator-back-button/index.js +1 -1
  134. package/build-module/navigator/navigator-back-button/index.js.map +1 -1
  135. package/build-module/navigator/navigator-button/component.js +3 -3
  136. package/build-module/navigator/navigator-button/component.js.map +1 -1
  137. package/build-module/navigator/navigator-button/index.js +1 -1
  138. package/build-module/navigator/navigator-button/index.js.map +1 -1
  139. package/build-module/navigator/navigator-provider/component.js +8 -6
  140. package/build-module/navigator/navigator-provider/component.js.map +1 -1
  141. package/build-module/navigator/navigator-provider/index.js +1 -1
  142. package/build-module/navigator/navigator-provider/index.js.map +1 -1
  143. package/build-module/navigator/navigator-screen/component.js +18 -25
  144. package/build-module/navigator/navigator-screen/component.js.map +1 -1
  145. package/build-module/navigator/navigator-screen/index.js +1 -1
  146. package/build-module/navigator/navigator-screen/index.js.map +1 -1
  147. package/build-module/resizable-box/resize-tooltip/utils.js +13 -15
  148. package/build-module/resizable-box/resize-tooltip/utils.js.map +1 -1
  149. package/build-module/sandbox/index.js +69 -67
  150. package/build-module/sandbox/index.js.map +1 -1
  151. package/build-module/sandbox/index.native.js +57 -53
  152. package/build-module/sandbox/index.native.js.map +1 -1
  153. package/build-module/search-control/index.native.js +6 -2
  154. package/build-module/search-control/index.native.js.map +1 -1
  155. package/build-module/slot-fill/bubbles-virtually/slot-fill-context.js +7 -2
  156. package/build-module/slot-fill/bubbles-virtually/slot-fill-context.js.map +1 -1
  157. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js +30 -42
  158. package/build-module/slot-fill/bubbles-virtually/slot-fill-provider.js.map +1 -1
  159. package/build-module/slot-fill/bubbles-virtually/use-slot-fills.js +27 -0
  160. package/build-module/slot-fill/bubbles-virtually/use-slot-fills.js.map +1 -0
  161. package/build-module/slot-fill/bubbles-virtually/use-slot.js +13 -5
  162. package/build-module/slot-fill/bubbles-virtually/use-slot.js.map +1 -1
  163. package/build-module/slot-fill/index.js +1 -0
  164. package/build-module/slot-fill/index.js.map +1 -1
  165. package/build-module/tab-panel/index.js +4 -4
  166. package/build-module/tab-panel/index.js.map +1 -1
  167. package/build-module/theme/index.js +52 -0
  168. package/build-module/theme/index.js.map +1 -0
  169. package/build-module/theme/styles.js +25 -0
  170. package/build-module/theme/styles.js.map +1 -0
  171. package/build-module/theme/types.js +2 -0
  172. package/build-module/theme/types.js.map +1 -0
  173. package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js +7 -7
  174. package/build-module/toggle-group-control/toggle-group-control-option-base/styles.js.map +1 -1
  175. package/build-module/tools-panel/tools-panel/hook.js +3 -3
  176. package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
  177. package/build-module/tools-panel/tools-panel-item/hook.js +6 -6
  178. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  179. package/build-module/tooltip/index.js +4 -1
  180. package/build-module/tooltip/index.js.map +1 -1
  181. package/build-module/tooltip/index.native.js +17 -4
  182. package/build-module/tooltip/index.native.js.map +1 -1
  183. package/build-style/style-rtl.css +27 -120
  184. package/build-style/style.css +27 -120
  185. package/build-types/border-box-control/border-box-control/component.d.ts.map +1 -1
  186. package/build-types/border-box-control/border-box-control/hook.d.ts +1 -0
  187. package/build-types/border-box-control/border-box-control/hook.d.ts.map +1 -1
  188. package/build-types/border-box-control/utils.d.ts +1 -3
  189. package/build-types/border-box-control/utils.d.ts.map +1 -1
  190. package/build-types/border-control/border-control/component.d.ts +1 -0
  191. package/build-types/border-control/border-control/component.d.ts.map +1 -1
  192. package/build-types/border-control/border-control/hook.d.ts +1 -0
  193. package/build-types/border-control/border-control/hook.d.ts.map +1 -1
  194. package/build-types/border-control/stories/index.d.ts +6 -0
  195. package/build-types/border-control/stories/index.d.ts.map +1 -1
  196. package/build-types/border-control/types.d.ts +4 -0
  197. package/build-types/border-control/types.d.ts.map +1 -1
  198. package/build-types/confirm-dialog/types.d.ts +5 -1
  199. package/build-types/confirm-dialog/types.d.ts.map +1 -1
  200. package/build-types/custom-select-control/index.d.ts +13 -0
  201. package/build-types/custom-select-control/index.d.ts.map +1 -0
  202. package/build-types/custom-select-control/styles.d.ts +9 -0
  203. package/build-types/custom-select-control/styles.d.ts.map +1 -0
  204. package/build-types/disabled/index.d.ts.map +1 -1
  205. package/build-types/font-size-picker/index.d.ts +5 -0
  206. package/build-types/font-size-picker/index.d.ts.map +1 -0
  207. package/build-types/font-size-picker/stories/e2e/index.d.ts +16 -0
  208. package/build-types/font-size-picker/stories/e2e/index.d.ts.map +1 -0
  209. package/build-types/font-size-picker/stories/index.d.ts +31 -0
  210. package/build-types/font-size-picker/stories/index.d.ts.map +1 -0
  211. package/build-types/font-size-picker/styles.d.ts +27 -0
  212. package/build-types/font-size-picker/styles.d.ts.map +1 -0
  213. package/build-types/font-size-picker/test/index.d.ts +2 -0
  214. package/build-types/font-size-picker/test/index.d.ts.map +1 -0
  215. package/build-types/font-size-picker/test/utils.d.ts +2 -0
  216. package/build-types/font-size-picker/test/utils.d.ts.map +1 -0
  217. package/build-types/font-size-picker/types.d.ts +93 -0
  218. package/build-types/font-size-picker/types.d.ts.map +1 -0
  219. package/build-types/font-size-picker/utils.d.ts +41 -0
  220. package/build-types/font-size-picker/utils.d.ts.map +1 -0
  221. package/build-types/form-token-field/token-input.d.ts.map +1 -1
  222. package/build-types/modal/aria-helper.d.ts +4 -4
  223. package/build-types/modal/aria-helper.d.ts.map +1 -1
  224. package/build-types/modal/index.d.ts +35 -2
  225. package/build-types/modal/index.d.ts.map +1 -1
  226. package/build-types/modal/stories/index.d.ts +9 -0
  227. package/build-types/modal/stories/index.d.ts.map +1 -0
  228. package/build-types/modal/test/aria-helper.d.ts +2 -0
  229. package/build-types/modal/test/aria-helper.d.ts.map +1 -0
  230. package/build-types/modal/test/index.d.ts +2 -0
  231. package/build-types/modal/test/index.d.ts.map +1 -0
  232. package/build-types/modal/types.d.ts +134 -0
  233. package/build-types/modal/types.d.ts.map +1 -0
  234. package/build-types/navigator/index.d.ts +4 -4
  235. package/build-types/navigator/index.d.ts.map +1 -1
  236. package/build-types/navigator/navigator-back-button/component.d.ts +4 -2
  237. package/build-types/navigator/navigator-back-button/component.d.ts.map +1 -1
  238. package/build-types/navigator/navigator-back-button/hook.d.ts +1 -0
  239. package/build-types/navigator/navigator-back-button/hook.d.ts.map +1 -1
  240. package/build-types/navigator/navigator-back-button/index.d.ts +1 -1
  241. package/build-types/navigator/navigator-back-button/index.d.ts.map +1 -1
  242. package/build-types/navigator/navigator-button/component.d.ts +4 -2
  243. package/build-types/navigator/navigator-button/component.d.ts.map +1 -1
  244. package/build-types/navigator/navigator-button/hook.d.ts +1 -0
  245. package/build-types/navigator/navigator-button/hook.d.ts.map +1 -1
  246. package/build-types/navigator/navigator-button/index.d.ts +1 -1
  247. package/build-types/navigator/navigator-button/index.d.ts.map +1 -1
  248. package/build-types/navigator/navigator-provider/component.d.ts +2 -2
  249. package/build-types/navigator/navigator-provider/component.d.ts.map +1 -1
  250. package/build-types/navigator/navigator-provider/index.d.ts +1 -1
  251. package/build-types/navigator/navigator-provider/index.d.ts.map +1 -1
  252. package/build-types/navigator/navigator-screen/component.d.ts +2 -2
  253. package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
  254. package/build-types/navigator/navigator-screen/index.d.ts +1 -1
  255. package/build-types/navigator/navigator-screen/index.d.ts.map +1 -1
  256. package/build-types/navigator/stories/index.d.ts +9 -0
  257. package/build-types/navigator/stories/index.d.ts.map +1 -0
  258. package/build-types/navigator/test/index.d.ts +2 -0
  259. package/build-types/navigator/test/index.d.ts.map +1 -0
  260. package/build-types/navigator/types.d.ts +4 -1
  261. package/build-types/navigator/types.d.ts.map +1 -1
  262. package/build-types/slot-fill/bubbles-virtually/slot-fill-context.d.ts +2 -2
  263. package/build-types/slot-fill/bubbles-virtually/slot-fill-context.d.ts.map +1 -1
  264. package/build-types/slot-fill/bubbles-virtually/slot-fill-provider.d.ts.map +1 -1
  265. package/build-types/slot-fill/bubbles-virtually/use-slot-fills.d.ts +2 -0
  266. package/build-types/slot-fill/bubbles-virtually/use-slot-fills.d.ts.map +1 -0
  267. package/build-types/slot-fill/bubbles-virtually/use-slot.d.ts.map +1 -1
  268. package/build-types/slot-fill/index.d.ts +1 -0
  269. package/build-types/slot-fill/index.d.ts.map +1 -1
  270. package/build-types/tab-panel/index.d.ts.map +1 -1
  271. package/build-types/theme/index.d.ts +31 -0
  272. package/build-types/theme/index.d.ts.map +1 -0
  273. package/build-types/theme/stories/index.d.ts +13 -0
  274. package/build-types/theme/stories/index.d.ts.map +1 -0
  275. package/build-types/theme/styles.d.ts +10 -0
  276. package/build-types/theme/styles.d.ts.map +1 -0
  277. package/build-types/theme/test/index.d.ts +2 -0
  278. package/build-types/theme/test/index.d.ts.map +1 -0
  279. package/build-types/theme/types.d.ts +21 -0
  280. package/build-types/theme/types.d.ts.map +1 -0
  281. package/build-types/toggle-group-control/toggle-group-control-option-base/styles.d.ts +1 -1
  282. package/build-types/toggle-group-control/toggle-group-control-option-base/styles.d.ts.map +1 -1
  283. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  284. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  285. package/build-types/tooltip/index.d.ts.map +1 -1
  286. package/package.json +19 -18
  287. package/src/alignment-matrix-control/test/index.js +17 -62
  288. package/src/base-field/test/index.js +4 -6
  289. package/src/border-box-control/border-box-control/component.tsx +2 -0
  290. package/src/border-box-control/border-box-control/hook.ts +4 -0
  291. package/src/border-box-control/test/index.js +7 -2
  292. package/src/border-box-control/test/utils.js +48 -0
  293. package/src/border-box-control/utils.ts +44 -1
  294. package/src/border-control/border-control/README.md +6 -0
  295. package/src/border-control/border-control/component.tsx +2 -0
  296. package/src/border-control/types.ts +4 -0
  297. package/src/button/style.scss +25 -25
  298. package/src/button/test/index.js +3 -5
  299. package/src/combobox-control/index.js +0 -5
  300. package/src/combobox-control/test/index.js +1 -1
  301. package/src/confirm-dialog/types.ts +6 -0
  302. package/src/custom-select-control/index.js +2 -1
  303. package/src/date-time/time/test/index.tsx +2 -6
  304. package/src/disabled/index.tsx +11 -33
  305. package/src/disabled/test/index.tsx +14 -82
  306. package/src/dropdown/test/index.js +4 -3
  307. package/src/font-size-picker/{index.js → index.tsx} +114 -80
  308. package/src/font-size-picker/stories/e2e/{index.js → index.tsx} +13 -4
  309. package/src/font-size-picker/stories/{index.js → index.tsx} +42 -36
  310. package/src/font-size-picker/styles.ts +46 -0
  311. package/src/font-size-picker/test/{index.js → index.tsx} +3 -3
  312. package/src/font-size-picker/test/{utils.js → utils.ts} +11 -7
  313. package/src/font-size-picker/types.ts +98 -0
  314. package/src/font-size-picker/{utils.js → utils.ts} +52 -28
  315. package/src/form-file-upload/test/index.tsx +1 -1
  316. package/src/form-token-field/suggestions-list.tsx +5 -5
  317. package/src/form-token-field/test/index.tsx +22 -1
  318. package/src/form-token-field/token-input.tsx +25 -3
  319. package/src/higher-order/with-fallback-styles/index.js +6 -2
  320. package/src/higher-order/with-focus-outside/test/index.js +44 -45
  321. package/src/higher-order/with-focus-return/test/index.js +34 -30
  322. package/src/higher-order/with-notices/test/index.js +1 -1
  323. package/src/index.js +3 -1
  324. package/src/input-control/test/index.js +2 -2
  325. package/src/item-group/test/index.js +2 -2
  326. package/src/menu-item/test/index.js +0 -3
  327. package/src/mobile/bottom-sheet/test/range-cell.native.js +16 -14
  328. package/src/modal/README.md +53 -54
  329. package/src/modal/{aria-helper.js → aria-helper.ts} +5 -7
  330. package/src/modal/{index.js → index.tsx} +48 -12
  331. package/src/modal/stories/{index.js → index.tsx} +47 -42
  332. package/src/modal/test/{aria-helper.js → aria-helper.ts} +0 -0
  333. package/src/modal/test/{index.js → index.tsx} +13 -3
  334. package/src/modal/types.ts +144 -0
  335. package/src/navigation/test/index.js +1 -1
  336. package/src/navigator/index.ts +4 -4
  337. package/src/navigator/navigator-back-button/component.tsx +4 -4
  338. package/src/navigator/navigator-back-button/index.ts +1 -1
  339. package/src/navigator/navigator-button/component.tsx +4 -4
  340. package/src/navigator/navigator-button/index.ts +1 -1
  341. package/src/navigator/navigator-provider/component.tsx +6 -4
  342. package/src/navigator/navigator-provider/index.ts +1 -1
  343. package/src/navigator/navigator-screen/component.tsx +27 -26
  344. package/src/navigator/navigator-screen/index.ts +1 -1
  345. package/src/navigator/stories/index.tsx +210 -0
  346. package/src/navigator/test/index.tsx +509 -0
  347. package/src/navigator/types.ts +2 -0
  348. package/src/notice/test/__snapshots__/index.js.snap +39 -38
  349. package/src/notice/test/index.js +15 -36
  350. package/src/notice/test/list.js +6 -14
  351. package/src/number-control/test/index.js +3 -2
  352. package/src/panel/test/body.js +2 -2
  353. package/src/placeholder/style.scss +7 -2
  354. package/src/resizable-box/resize-tooltip/utils.ts +13 -13
  355. package/src/sandbox/index.js +75 -54
  356. package/src/sandbox/index.native.js +75 -52
  357. package/src/sandbox/test/index.js +7 -10
  358. package/src/search-control/index.native.js +6 -0
  359. package/src/shortcut/test/index.tsx +1 -1
  360. package/src/slot-fill/bubbles-virtually/slot-fill-context.js +6 -2
  361. package/src/slot-fill/bubbles-virtually/slot-fill-provider.js +53 -58
  362. package/src/slot-fill/bubbles-virtually/use-slot-fills.js +24 -0
  363. package/src/slot-fill/bubbles-virtually/use-slot.js +11 -6
  364. package/src/slot-fill/index.js +1 -0
  365. package/src/style.scss +4 -1
  366. package/src/tab-panel/index.tsx +4 -7
  367. package/src/text-highlight/test/index.tsx +1 -3
  368. package/src/theme/README.md +34 -0
  369. package/src/theme/index.tsx +51 -0
  370. package/src/theme/stories/index.tsx +47 -0
  371. package/src/theme/styles.ts +28 -0
  372. package/src/theme/test/index.tsx +101 -0
  373. package/src/theme/types.ts +21 -0
  374. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +1 -0
  375. package/src/toggle-group-control/toggle-group-control-option-base/styles.ts +9 -7
  376. package/src/toolbar/test/index.js +2 -2
  377. package/src/toolbar-group/test/index.js +6 -10
  378. package/src/tools-panel/test/index.js +4 -6
  379. package/src/tools-panel/tools-panel/hook.ts +2 -9
  380. package/src/tools-panel/tools-panel-item/hook.ts +17 -3
  381. package/src/tooltip/index.js +3 -0
  382. package/src/tooltip/index.native.js +15 -0
  383. package/src/tooltip/test/index.native.js +1 -2
  384. package/src/tree-grid/test/__snapshots__/cell.js.snap +1 -3
  385. package/src/tree-grid/test/__snapshots__/roving-tab-index-item.js.snap +17 -15
  386. package/src/tree-grid/test/__snapshots__/row.js.snap +25 -21
  387. package/src/tree-grid/test/cell.js +4 -4
  388. package/src/tree-grid/test/roving-tab-index-item.js +8 -8
  389. package/src/tree-grid/test/roving-tab-index.js +3 -3
  390. package/src/tree-grid/test/row.js +20 -16
  391. package/src/truncate/test/index.tsx +4 -4
  392. package/src/ui/shortcut/test/index.js +2 -1
  393. package/src/ui/spinner/test/index.js +14 -13
  394. package/src/ui/tooltip/test/index.js +16 -14
  395. package/src/utils/theme-variables.scss +8 -0
  396. package/src/visually-hidden/README.md +4 -0
  397. package/tsconfig.json +0 -2
  398. package/tsconfig.tsbuildinfo +1 -1
  399. package/src/font-size-picker/style.scss +0 -78
  400. package/src/navigator/stories/index.js +0 -194
  401. package/src/navigator/test/index.js +0 -407
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentMeta, ComponentStory } from '@storybook/react';
5
+
1
6
  /**
2
7
  * WordPress dependencies
3
8
  */
@@ -8,53 +13,48 @@ import { useState } from '@wordpress/element';
8
13
  */
9
14
  import FontSizePicker from '../';
10
15
 
11
- export default {
16
+ const meta: ComponentMeta< typeof FontSizePicker > = {
12
17
  title: 'Components/FontSizePicker',
13
18
  component: FontSizePicker,
14
19
  argTypes: {
15
- initialValue: { table: { disable: true } }, // hide prop because it's not actually part of FontSizePicker
16
- fallbackFontSize: {
17
- description:
18
- 'If no value exists, this prop defines the starting position for the font size picker slider. Only relevant if `withSlider` is `true`.',
19
- },
20
- size: {
21
- control: { type: 'radio' },
22
- options: [ 'default', '__unstable-large' ],
23
- },
24
- withReset: {
25
- description:
26
- 'If `true`, a reset button will be displayed alongside the input field when a custom font size is active. Has no effect when `disableCustomFontSizes` or `withSlider` is `true`.',
27
- control: { type: 'boolean' },
28
- table: {
29
- type: 'boolean',
30
- defaultValue: { summary: true },
31
- },
32
- },
20
+ value: { control: { type: null } },
33
21
  },
34
22
  parameters: {
23
+ actions: { argTypesRegex: '^on.*' },
35
24
  controls: { expanded: true },
36
25
  docs: { source: { state: 'open' } },
37
26
  },
38
27
  };
28
+ export default meta;
39
29
 
40
- const FontSizePickerWithState = ( { initialValue, ...props } ) => {
41
- const [ fontSize, setFontSize ] = useState( initialValue );
30
+ const FontSizePickerWithState: ComponentStory< typeof FontSizePicker > = ( {
31
+ value,
32
+ onChange,
33
+ ...props
34
+ } ) => {
35
+ const [ fontSize, setFontSize ] = useState( value );
42
36
  return (
43
37
  <FontSizePicker
44
38
  { ...props }
45
39
  value={ fontSize }
46
- onChange={ setFontSize }
40
+ onChange={ ( nextValue ) => {
41
+ setFontSize( nextValue );
42
+ onChange?.( nextValue );
43
+ } }
47
44
  />
48
45
  );
49
46
  };
50
47
 
51
- const TwoFontSizePickersWithState = ( { fontSizes, ...props } ) => {
48
+ const TwoFontSizePickersWithState: ComponentStory< typeof FontSizePicker > = ( {
49
+ fontSizes,
50
+ ...props
51
+ } ) => {
52
52
  return (
53
53
  <>
54
54
  <h2>Fewer font sizes</h2>
55
55
  <FontSizePickerWithState
56
56
  { ...props }
57
- fontSizes={ fontSizes.slice( 0, 4 ) }
57
+ fontSizes={ fontSizes?.slice( 0, 4 ) }
58
58
  />
59
59
 
60
60
  <h2>More font sizes</h2>
@@ -63,7 +63,8 @@ const TwoFontSizePickersWithState = ( { fontSizes, ...props } ) => {
63
63
  );
64
64
  };
65
65
 
66
- export const Default = FontSizePickerWithState.bind( {} );
66
+ export const Default: ComponentStory< typeof FontSizePicker > =
67
+ FontSizePickerWithState.bind( {} );
67
68
  Default.args = {
68
69
  __nextHasNoMarginBottom: true,
69
70
  disableCustomFontSizes: false,
@@ -84,15 +85,16 @@ Default.args = {
84
85
  size: 26,
85
86
  },
86
87
  ],
87
- initialValue: 16,
88
+ value: 16,
88
89
  withSlider: false,
89
90
  };
90
91
 
91
- export const WithSlider = FontSizePickerWithState.bind( {} );
92
+ export const WithSlider: ComponentStory< typeof FontSizePicker > =
93
+ FontSizePickerWithState.bind( {} );
92
94
  WithSlider.args = {
93
95
  ...Default.args,
94
96
  fallbackFontSize: 16,
95
- initialValue: undefined,
97
+ value: undefined,
96
98
  withSlider: true,
97
99
  };
98
100
 
@@ -100,7 +102,8 @@ WithSlider.args = {
100
102
  * With custom font sizes disabled via the `disableCustomFontSizes` prop, the user will
101
103
  * only be able to pick one of the predefined sizes passed in `fontSizes`.
102
104
  */
103
- export const WithCustomSizesDisabled = FontSizePickerWithState.bind( {} );
105
+ export const WithCustomSizesDisabled: ComponentStory< typeof FontSizePicker > =
106
+ FontSizePickerWithState.bind( {} );
104
107
  WithCustomSizesDisabled.args = {
105
108
  ...Default.args,
106
109
  disableCustomFontSizes: true,
@@ -109,7 +112,8 @@ WithCustomSizesDisabled.args = {
109
112
  /**
110
113
  * When there are more than 5 font size options, the UI is no longer a toggle group.
111
114
  */
112
- export const WithMoreFontSizes = FontSizePickerWithState.bind( {} );
115
+ export const WithMoreFontSizes: ComponentStory< typeof FontSizePicker > =
116
+ FontSizePickerWithState.bind( {} );
113
117
  WithMoreFontSizes.args = {
114
118
  ...Default.args,
115
119
  fontSizes: [
@@ -144,27 +148,29 @@ WithMoreFontSizes.args = {
144
148
  size: 36,
145
149
  },
146
150
  ],
147
- initialValue: 8,
151
+ value: 8,
148
152
  };
149
153
 
150
154
  /**
151
155
  * When units like `px` are specified explicitly, it will be shown as a label hint.
152
156
  */
153
- export const WithUnits = TwoFontSizePickersWithState.bind( {} );
157
+ export const WithUnits: ComponentStory< typeof FontSizePicker > =
158
+ TwoFontSizePickersWithState.bind( {} );
154
159
  WithUnits.args = {
155
160
  ...WithMoreFontSizes.args,
156
- fontSizes: WithMoreFontSizes.args.fontSizes.map( ( option ) => ( {
161
+ fontSizes: WithMoreFontSizes.args.fontSizes?.map( ( option ) => ( {
157
162
  ...option,
158
163
  size: `${ option.size }px`,
159
164
  } ) ),
160
- initialValue: '8px',
165
+ value: '8px',
161
166
  };
162
167
 
163
168
  /**
164
169
  * The label hint will not be shown if it is a complex CSS value. Some examples of complex CSS values
165
170
  * in this context are CSS functions like `calc()`, `clamp()`, and `var()`.
166
171
  */
167
- export const WithComplexCSSValues = TwoFontSizePickersWithState.bind( {} );
172
+ export const WithComplexCSSValues: ComponentStory< typeof FontSizePicker > =
173
+ TwoFontSizePickersWithState.bind( {} );
168
174
  WithComplexCSSValues.args = {
169
175
  ...Default.args,
170
176
  fontSizes: [
@@ -200,5 +206,5 @@ WithComplexCSSValues.args = {
200
206
  size: '2.8rem',
201
207
  },
202
208
  ],
203
- initialValue: '1.125rem',
209
+ value: '1.125rem',
204
210
  };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import styled from '@emotion/styled';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import BaseControl from '../base-control';
10
+ import Button from '../button';
11
+ import { space } from '../ui/utils/space';
12
+ import { COLORS } from '../utils';
13
+ import type { FontSizePickerProps } from './types';
14
+
15
+ export const Container = styled.fieldset`
16
+ border: 0;
17
+ margin: 0;
18
+ padding: 0;
19
+ `;
20
+
21
+ export const HeaderLabel = styled( BaseControl.VisualLabel )`
22
+ display: flex;
23
+ gap: ${ space( 1 ) };
24
+ justify-content: flex-start;
25
+ margin-bottom: 0;
26
+ `;
27
+
28
+ export const HeaderHint = styled.span`
29
+ color: ${ COLORS.gray[ 700 ] };
30
+ `;
31
+
32
+ export const Controls = styled.div< {
33
+ __nextHasNoMarginBottom: boolean;
34
+ } >`
35
+ ${ ( props ) =>
36
+ ! props.__nextHasNoMarginBottom && `margin-bottom: ${ space( 6 ) };` }
37
+ `;
38
+
39
+ export const ResetButton = styled( Button )< {
40
+ size: FontSizePickerProps[ 'size' ];
41
+ } >`
42
+ &&& {
43
+ height: ${ ( props ) =>
44
+ props.size === '__unstable-large' ? '40px' : '30px' };
45
+ }
46
+ `;
@@ -13,7 +13,7 @@ const getUnitSelect = () =>
13
13
  const getUnitLabel = () =>
14
14
  document.body.querySelector( '.components-unit-control__unit-label' );
15
15
 
16
- const toggleCustomInput = ( showCustomInput ) => {
16
+ const toggleCustomInput = ( showCustomInput: boolean ) => {
17
17
  const label = showCustomInput ? 'Set custom size' : 'Use size preset';
18
18
  const toggleCustom = screen.getByLabelText( label, { selector: 'button' } );
19
19
  fireEvent.click( toggleCustom );
@@ -215,7 +215,7 @@ describe( 'FontSizePicker', () => {
215
215
  );
216
216
  const element = screen.getByLabelText( 'Large' );
217
217
  expect( element ).toBeInTheDocument();
218
- expect( element.children[ 0 ].textContent ).toBe( 'L' );
218
+ expect( element.children[ 0 ] ).toHaveTextContent( 'L' );
219
219
  } );
220
220
  it( 'should use incremental sequence of t-shirt sizes as labels if we have complex css', () => {
221
221
  const fontSizes = [
@@ -240,7 +240,7 @@ describe( 'FontSizePicker', () => {
240
240
  const extraLargeElement =
241
241
  screen.getByLabelText( 'Extra Large' );
242
242
  expect( extraLargeElement ).toBeInTheDocument();
243
- expect( extraLargeElement.children[ 0 ].textContent ).toBe(
243
+ expect( extraLargeElement.children[ 0 ] ).toHaveTextContent(
244
244
  'XL'
245
245
  );
246
246
  } );
@@ -7,7 +7,7 @@ import {
7
7
  getToggleGroupOptions,
8
8
  } from '../utils';
9
9
 
10
- const simpleCSSCases = [
10
+ const simpleCSSCases: [ number | string, boolean ][] = [
11
11
  // Test integers and non-integers.
12
12
  [ 1, true ],
13
13
  [ 1.25, true ],
@@ -41,7 +41,11 @@ describe( 'isSimpleCssValue', () => {
41
41
  );
42
42
  } );
43
43
 
44
- const splitValuesCases = [
44
+ const splitValuesCases: [
45
+ number | string,
46
+ string | undefined,
47
+ string | undefined
48
+ ][] = [
45
49
  // Test integers and non-integers.
46
50
  [ 1, '1', undefined ],
47
51
  [ 1.25, '1.25', undefined ],
@@ -116,33 +120,33 @@ describe( 'getToggleGroupOptions', () => {
116
120
  ).toEqual( [
117
121
  {
118
122
  key: '1',
119
- value: '1',
120
123
  label: 'S',
121
124
  name: '1',
125
+ value: '1',
122
126
  },
123
127
  {
124
128
  key: '2',
125
- value: '2',
126
129
  label: 'M',
127
130
  name: '2',
131
+ value: '2',
128
132
  },
129
133
  {
130
134
  key: '3',
131
- value: '3',
132
135
  label: 'L',
133
136
  name: '3',
137
+ value: '3',
134
138
  },
135
139
  {
136
140
  key: '4',
137
- value: '4',
138
141
  label: 'XL',
139
142
  name: '4',
143
+ value: '4',
140
144
  },
141
145
  {
142
146
  key: '5',
143
- value: '5',
144
147
  label: 'XXL',
145
148
  name: 'XXL',
149
+ value: '5',
146
150
  },
147
151
  ] );
148
152
  } );
@@ -0,0 +1,98 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ReactNode } from 'react';
5
+
6
+ export type FontSizePickerProps = {
7
+ /**
8
+ * If `true`, it will not be possible to choose a custom fontSize. The user
9
+ * will be forced to pick one of the pre-defined sizes passed in fontSizes.
10
+ *
11
+ * @default false
12
+ */
13
+ disableCustomFontSizes?: boolean;
14
+ /**
15
+ * If no value exists, this prop defines the starting position for the font
16
+ * size picker slider. Only relevant if `withSlider` is `true`.
17
+ */
18
+ fallbackFontSize?: number;
19
+ /**
20
+ * An array of font size objects. The object should contain properties size,
21
+ * name, and slug.
22
+ */
23
+ fontSizes?: FontSize[];
24
+ /**
25
+ * A function that receives the new font size value.
26
+ * If onChange is called without any parameter, it should reset the value,
27
+ * attending to what reset means in that context, e.g., set the font size to
28
+ * undefined or set the font size a starting value.
29
+ */
30
+ onChange?: ( value: number | string | undefined ) => void;
31
+ /**
32
+ * The current font size value.
33
+ */
34
+ value?: number | string;
35
+ /**
36
+ * If `true`, the UI will contain a slider, instead of a numeric text input
37
+ * field. If `false`, no slider will be present.
38
+ *
39
+ * @default false
40
+ */
41
+ withSlider?: boolean;
42
+ /**
43
+ * If `true`, a reset button will be displayed alongside the input field
44
+ * when a custom font size is active. Has no effect when
45
+ * `disableCustomFontSizes` or `withSlider` is `true`.
46
+ *
47
+ * @default true
48
+ */
49
+ withReset?: boolean;
50
+ /**
51
+ * Start opting into the new margin-free styles that will become the default
52
+ * in a future version, currently scheduled to be WordPress 6.4. (The prop
53
+ * can be safely removed once this happens.)
54
+ *
55
+ * @default false
56
+ */
57
+ __nextHasNoMarginBottom?: boolean;
58
+ /**
59
+ * Size of the control.
60
+ *
61
+ * @default default
62
+ */
63
+ size?: 'default' | '__unstable-large';
64
+ };
65
+
66
+ export type FontSize = {
67
+ /**
68
+ * The property `size` contains a number with the font size value, in `px` or
69
+ * a string specifying the font size CSS property that should be used eg:
70
+ * "13px", "1em", or "clamp(12px, 5vw, 100px)".
71
+ */
72
+ size: number | string;
73
+ /**
74
+ * The `name` property includes a label for that font size e.g.: `Small`.
75
+ */
76
+ name?: string;
77
+ /**
78
+ * The `slug` property is a string with a unique identifier for the font
79
+ * size. Used for the class generation process.
80
+ */
81
+ slug: string;
82
+ };
83
+
84
+ export type FontSizeOption = Omit< FontSize, 'size' > &
85
+ Partial< Pick< FontSize, 'size' > >;
86
+
87
+ export type FontSizeSelectOption = Pick< FontSizeOption, 'size' > & {
88
+ key: string;
89
+ name?: string;
90
+ __experimentalHint: ReactNode;
91
+ };
92
+
93
+ export type FontSizeToggleGroupOption = {
94
+ key: string;
95
+ value: number | string;
96
+ label: string;
97
+ name: string;
98
+ };
@@ -3,6 +3,17 @@
3
3
  */
4
4
  import { __ } from '@wordpress/i18n';
5
5
 
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import type {
10
+ FontSize,
11
+ FontSizeOption,
12
+ FontSizeSelectOption,
13
+ FontSizeToggleGroupOption,
14
+ FontSizePickerProps,
15
+ } from './types';
16
+
6
17
  const DEFAULT_FONT_SIZE = 'default';
7
18
  const DEFAULT_FONT_SIZE_OPTION = {
8
19
  slug: DEFAULT_FONT_SIZE,
@@ -36,13 +47,18 @@ const FONT_SIZES_ALIASES = [
36
47
  * Helper util to split a font size to its numeric value
37
48
  * and its `unit`, if exists.
38
49
  *
39
- * @param {string|number} size Font size.
40
- * @return {[number, string]} An array with the numeric value and the unit if exists.
50
+ * @param size Font size.
51
+ * @return An array with the numeric value and the unit if exists.
41
52
  */
42
- export function splitValueAndUnitFromSize( size ) {
43
- const [ numericValue, unit ] = `${ size }`.match( /[\d\.]+|\D+/g );
53
+ export function splitValueAndUnitFromSize(
54
+ size: NonNullable< FontSizePickerProps[ 'value' ] >
55
+ ) {
56
+ const [ numericValue, unit ] = `${ size }`.match( /[\d\.]+|\D+/g ) ?? [];
44
57
 
45
- if ( ! isNaN( parseFloat( numericValue ) ) && isFinite( numericValue ) ) {
58
+ if (
59
+ ! isNaN( parseFloat( numericValue ) ) &&
60
+ isFinite( Number( numericValue ) )
61
+ ) {
46
62
  return [ numericValue, unit ];
47
63
  }
48
64
 
@@ -53,28 +69,30 @@ export function splitValueAndUnitFromSize( size ) {
53
69
  * Some themes use css vars for their font sizes, so until we
54
70
  * have the way of calculating them don't display them.
55
71
  *
56
- * @param {string|number} value The value that is checked.
57
- * @return {boolean} Whether the value is a simple css value.
72
+ * @param value The value that is checked.
73
+ * @return Whether the value is a simple css value.
58
74
  */
59
- export function isSimpleCssValue( value ) {
75
+ export function isSimpleCssValue(
76
+ value: NonNullable< FontSizePickerProps[ 'value' ] >
77
+ ) {
60
78
  const sizeRegex = /^[\d\.]+(px|em|rem|vw|vh|%)?$/i;
61
- return sizeRegex.test( value );
79
+ return sizeRegex.test( String( value ) );
62
80
  }
63
81
 
64
82
  /**
65
83
  * Return font size options in the proper format depending
66
84
  * on the currently used control (select, toggle group).
67
85
  *
68
- * @param {boolean} useSelectControl Whether to use a select control.
69
- * @param {Object[]} optionsArray Array of available font sizes objects.
70
- * @param {boolean} disableCustomFontSizes Flag that indicates if custom font sizes are disabled.
71
- * @return {Object[]|null} Array of font sizes in proper format for the used control.
86
+ * @param useSelectControl Whether to use a select control.
87
+ * @param optionsArray Array of available font sizes objects.
88
+ * @param disableCustomFontSizes Flag that indicates if custom font sizes are disabled.
89
+ * @return Array of font sizes in proper format for the used control.
72
90
  */
73
91
  export function getFontSizeOptions(
74
- useSelectControl,
75
- optionsArray,
76
- disableCustomFontSizes
77
- ) {
92
+ useSelectControl: boolean,
93
+ optionsArray: FontSize[],
94
+ disableCustomFontSizes: boolean
95
+ ): FontSizeSelectOption[] | FontSizeToggleGroupOption[] | null {
78
96
  if ( disableCustomFontSizes && ! optionsArray.length ) {
79
97
  return null;
80
98
  }
@@ -83,32 +101,35 @@ export function getFontSizeOptions(
83
101
  : getToggleGroupOptions( optionsArray );
84
102
  }
85
103
 
86
- function getSelectOptions( optionsArray, disableCustomFontSizes ) {
87
- const options = [
104
+ function getSelectOptions(
105
+ optionsArray: FontSize[],
106
+ disableCustomFontSizes: boolean
107
+ ): FontSizeSelectOption[] {
108
+ const options: FontSizeOption[] = [
88
109
  DEFAULT_FONT_SIZE_OPTION,
89
110
  ...optionsArray,
90
111
  ...( disableCustomFontSizes ? [] : [ CUSTOM_FONT_SIZE_OPTION ] ),
91
112
  ];
92
113
  return options.map( ( { slug, name, size } ) => ( {
93
114
  key: slug,
94
- name,
115
+ name: name || slug,
95
116
  size,
96
117
  __experimentalHint:
97
- size && isSimpleCssValue( size ) && parseFloat( size ),
118
+ size && isSimpleCssValue( size ) && parseFloat( String( size ) ),
98
119
  } ) );
99
120
  }
100
121
 
101
122
  /**
102
123
  * Build options for the toggle group options.
103
124
  *
104
- * @param {Array} optionsArray An array of font size options.
105
- * @param {string[]} labelAliases An array of alternative labels.
106
- * @return {Array} Remapped optionsArray.
125
+ * @param optionsArray An array of font size options.
126
+ * @param labelAliases An array of alternative labels.
127
+ * @return Remapped optionsArray.
107
128
  */
108
129
  export function getToggleGroupOptions(
109
- optionsArray,
110
- labelAliases = FONT_SIZES_ALIASES
111
- ) {
130
+ optionsArray: FontSize[],
131
+ labelAliases: string[] = FONT_SIZES_ALIASES
132
+ ): FontSizeToggleGroupOption[] {
112
133
  return optionsArray.map( ( { slug, size, name }, index ) => {
113
134
  return {
114
135
  key: slug,
@@ -119,7 +140,10 @@ export function getToggleGroupOptions(
119
140
  } );
120
141
  }
121
142
 
122
- export function getSelectedOption( fontSizes, value ) {
143
+ export function getSelectedOption(
144
+ fontSizes: FontSize[],
145
+ value: FontSizePickerProps[ 'value' ]
146
+ ): FontSizeOption {
123
147
  if ( ! value ) {
124
148
  return DEFAULT_FONT_SIZE_OPTION;
125
149
  }
@@ -41,7 +41,7 @@ describe( 'FormFileUpload', () => {
41
41
  const button = screen.getByText( 'My Upload Button' );
42
42
  const input = screen.getByTestId( 'form-file-upload-input' );
43
43
  expect( button ).toBeInTheDocument();
44
- expect( input.style.display ).toBe( 'none' );
44
+ expect( input ).toHaveStyle( 'display: none' );
45
45
  } );
46
46
 
47
47
  it( 'should not fire a change event after selecting the same file', async () => {
@@ -38,7 +38,7 @@ export function SuggestionsList< T extends string | { value: string } >( {
38
38
  ( listNode ) => {
39
39
  // only have to worry about scrolling selected suggestion into view
40
40
  // when already expanded.
41
- let id: number;
41
+ let rafId: number | undefined;
42
42
  if (
43
43
  selectedIndex > -1 &&
44
44
  scrollIntoView &&
@@ -52,14 +52,14 @@ export function SuggestionsList< T extends string | { value: string } >( {
52
52
  onlyScrollIfNeeded: true,
53
53
  }
54
54
  );
55
- id = window.setTimeout( () => {
55
+ rafId = requestAnimationFrame( () => {
56
56
  setScrollingIntoView( false );
57
- }, 100 );
57
+ } );
58
58
  }
59
59
 
60
60
  return () => {
61
- if ( id !== undefined ) {
62
- window.clearTimeout( id );
61
+ if ( rafId !== undefined ) {
62
+ cancelAnimationFrame( rafId );
63
63
  }
64
64
  };
65
65
  },
@@ -2057,7 +2057,12 @@ describe( 'FormTokenField', () => {
2057
2057
 
2058
2058
  const suggestions = [ 'Pine', 'Pistachio', 'Sage' ];
2059
2059
 
2060
- render( <FormTokenFieldWithState suggestions={ suggestions } /> );
2060
+ render(
2061
+ <>
2062
+ <FormTokenFieldWithState suggestions={ suggestions } />
2063
+ <button>Click me</button>
2064
+ </>
2065
+ );
2061
2066
 
2062
2067
  // No suggestions visible
2063
2068
  const input = screen.getByRole( 'combobox' );
@@ -2093,6 +2098,22 @@ describe( 'FormTokenField', () => {
2093
2098
  pineSuggestion.id
2094
2099
  );
2095
2100
 
2101
+ // Blur the input and make sure that the `aria-activedescendant`
2102
+ // is removed
2103
+ const button = screen.getByRole( 'button', { name: 'Click me' } );
2104
+
2105
+ await user.click( button );
2106
+
2107
+ expect( input ).not.toHaveAttribute( 'aria-activedescendant' );
2108
+
2109
+ // Focus the input again, `aria-activedescendant` should be added back.
2110
+ await user.click( input );
2111
+
2112
+ expect( input ).toHaveAttribute(
2113
+ 'aria-activedescendant',
2114
+ pineSuggestion.id
2115
+ );
2116
+
2096
2117
  // Add the suggestion, which hides the list
2097
2118
  await user.keyboard( '[Enter]' );
2098
2119
 
@@ -2,12 +2,12 @@
2
2
  * External dependencies
3
3
  */
4
4
  import classnames from 'classnames';
5
- import type { ChangeEvent, ForwardedRef } from 'react';
5
+ import type { ChangeEvent, ForwardedRef, FocusEventHandler } from 'react';
6
6
 
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
- import { forwardRef } from '@wordpress/element';
10
+ import { forwardRef, useState } from '@wordpress/element';
11
11
 
12
12
  /**
13
13
  * Internal dependencies
@@ -26,9 +26,13 @@ export function UnForwardedTokenInput(
26
26
  selectedSuggestionIndex,
27
27
  className,
28
28
  onChange,
29
+ onFocus,
30
+ onBlur,
29
31
  ...restProps
30
32
  } = props;
31
33
 
34
+ const [ hasFocus, setHasFocus ] = useState( false );
35
+
32
36
  const size = value ? value.length + 1 : 0;
33
37
 
34
38
  const onChangeHandler = ( event: ChangeEvent< HTMLInputElement > ) => {
@@ -39,6 +43,18 @@ export function UnForwardedTokenInput(
39
43
  }
40
44
  };
41
45
 
46
+ const onFocusHandler: FocusEventHandler< HTMLInputElement > = ( e ) => {
47
+ setHasFocus( true );
48
+ onFocus?.( e );
49
+ };
50
+
51
+ const onBlurHandler: React.FocusEventHandler< HTMLInputElement > = (
52
+ e
53
+ ) => {
54
+ setHasFocus( false );
55
+ onBlur?.( e );
56
+ };
57
+
42
58
  return (
43
59
  <input
44
60
  ref={ ref }
@@ -47,6 +63,8 @@ export function UnForwardedTokenInput(
47
63
  { ...restProps }
48
64
  value={ value || '' }
49
65
  onChange={ onChangeHandler }
66
+ onFocus={ onFocusHandler }
67
+ onBlur={ onBlurHandler }
50
68
  size={ size }
51
69
  className={ classnames(
52
70
  className,
@@ -62,7 +80,11 @@ export function UnForwardedTokenInput(
62
80
  : undefined
63
81
  }
64
82
  aria-activedescendant={
65
- selectedSuggestionIndex !== -1
83
+ // Only add the `aria-activedescendant` attribute when:
84
+ // - the user is actively interacting with the input (`hasFocus`)
85
+ // - there is a selected suggestion (`selectedSuggestionIndex !== -1`)
86
+ // - the list of suggestions are rendered in the DOM (`isExpanded`)
87
+ hasFocus && selectedSuggestionIndex !== -1 && isExpanded
66
88
  ? `components-form-token-suggestions-${ instanceId }-${ selectedSuggestionIndex }`
67
89
  : undefined
68
90
  }