@wordpress/components 40.0.0 → 40.1.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 (472) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/CONTRIBUTING.md +2 -0
  3. package/build/border-box-control/border-box-control/component.cjs +37 -5
  4. package/build/border-box-control/border-box-control/component.cjs.map +3 -3
  5. package/build/border-box-control/border-box-control/hook.cjs +24 -3
  6. package/build/border-box-control/border-box-control/hook.cjs.map +3 -3
  7. package/build/border-box-control/border-box-control-linked-button/hook.cjs +2 -2
  8. package/build/border-box-control/border-box-control-linked-button/hook.cjs.map +2 -2
  9. package/build/border-box-control/border-box-control-split-controls/hook.cjs +2 -2
  10. package/build/border-box-control/border-box-control-split-controls/hook.cjs.map +2 -2
  11. package/build/border-box-control/border-box-control-visualizer/hook.cjs +2 -2
  12. package/build/border-box-control/border-box-control-visualizer/hook.cjs.map +2 -2
  13. package/build/color-palette/index.cjs +1 -1
  14. package/build/color-palette/index.cjs.map +2 -2
  15. package/build/composite/context.cjs +9 -2
  16. package/build/composite/context.cjs.map +2 -2
  17. package/build/composite/group-label.cjs +4 -0
  18. package/build/composite/group-label.cjs.map +2 -2
  19. package/build/composite/group.cjs +10 -2
  20. package/build/composite/group.cjs.map +2 -2
  21. package/build/composite/item.cjs +4 -0
  22. package/build/composite/item.cjs.map +3 -3
  23. package/build/context/context-system-provider.cjs +2 -5
  24. package/build/context/context-system-provider.cjs.map +3 -3
  25. package/build/context/use-context-system.cjs +7 -2
  26. package/build/context/use-context-system.cjs.map +2 -2
  27. package/build/disabled/index.cjs +1 -1
  28. package/build/disabled/index.cjs.map +2 -2
  29. package/build/draggable/index.cjs.map +1 -1
  30. package/build/form-token-field/index.cjs +1 -1
  31. package/build/form-token-field/index.cjs.map +2 -2
  32. package/build/icon/index.cjs +30 -12
  33. package/build/icon/index.cjs.map +2 -2
  34. package/build/input-control/styles/input-control-styles.cjs +42 -27
  35. package/build/input-control/styles/input-control-styles.cjs.map +2 -2
  36. package/build/item-group/context.cjs +1 -0
  37. package/build/item-group/context.cjs.map +2 -2
  38. package/build/item-group/item/component.cjs +12 -0
  39. package/build/item-group/item/component.cjs.map +3 -3
  40. package/build/item-group/item/hook.cjs +7 -6
  41. package/build/item-group/item/hook.cjs.map +2 -2
  42. package/build/item-group/item-group/component.cjs +1 -0
  43. package/build/item-group/item-group/component.cjs.map +2 -2
  44. package/build/item-group/item-group/hook.cjs +1 -1
  45. package/build/item-group/item-group/hook.cjs.map +2 -2
  46. package/build/progress-bar/index.cjs +1 -1
  47. package/build/progress-bar/index.cjs.map +2 -2
  48. package/build/resizable-box/index.cjs.map +1 -1
  49. package/build/snackbar/index.cjs +8 -5
  50. package/build/snackbar/index.cjs.map +2 -2
  51. package/build/textarea-control/index.cjs +1 -1
  52. package/build/textarea-control/index.cjs.map +2 -2
  53. package/build/toggle-group-control/context.cjs +8 -2
  54. package/build/toggle-group-control/context.cjs.map +2 -2
  55. package/build/toggle-group-control/toggle-group-control/as-button-group.cjs +5 -2
  56. package/build/toggle-group-control/toggle-group-control/as-button-group.cjs.map +2 -2
  57. package/build/toggle-group-control/toggle-group-control/as-radio-group.cjs +5 -2
  58. package/build/toggle-group-control/toggle-group-control/as-radio-group.cjs.map +2 -2
  59. package/build/toggle-group-control/toggle-group-control/component.cjs +3 -1
  60. package/build/toggle-group-control/toggle-group-control/component.cjs.map +2 -2
  61. package/build/toggle-group-control/toggle-group-control-option/component.cjs +2 -0
  62. package/build/toggle-group-control/toggle-group-control-option/component.cjs.map +2 -2
  63. package/build/toggle-group-control/toggle-group-control-option-base/component.cjs +2 -1
  64. package/build/toggle-group-control/toggle-group-control-option-base/component.cjs.map +2 -2
  65. package/build/toggle-group-control/toggle-group-control-option-icon/component.cjs +2 -0
  66. package/build/toggle-group-control/toggle-group-control-option-icon/component.cjs.map +2 -2
  67. package/build/tools-panel/tools-panel/hook.cjs +102 -106
  68. package/build/tools-panel/tools-panel/hook.cjs.map +2 -2
  69. package/build/tools-panel/tools-panel-item/hook.cjs +33 -33
  70. package/build/tools-panel/tools-panel-item/hook.cjs.map +2 -2
  71. package/build/tree-grid/cell.cjs +4 -0
  72. package/build/tree-grid/cell.cjs.map +2 -2
  73. package/build/tree-grid/roving-tab-index-item.cjs +5 -1
  74. package/build/tree-grid/roving-tab-index-item.cjs.map +2 -2
  75. package/build/tree-grid/row.cjs +6 -1
  76. package/build/tree-grid/row.cjs.map +2 -2
  77. package/build/tree-grid/use-validate-tree-grid-structure.cjs +81 -0
  78. package/build/tree-grid/use-validate-tree-grid-structure.cjs.map +7 -0
  79. package/build/utils/colors-values.cjs +3 -2
  80. package/build/utils/colors-values.cjs.map +2 -2
  81. package/build-module/border-box-control/border-box-control/component.mjs +38 -6
  82. package/build-module/border-box-control/border-box-control/component.mjs.map +2 -2
  83. package/build-module/border-box-control/border-box-control/hook.mjs +14 -3
  84. package/build-module/border-box-control/border-box-control/hook.mjs.map +2 -2
  85. package/build-module/border-box-control/border-box-control-linked-button/hook.mjs +2 -2
  86. package/build-module/border-box-control/border-box-control-linked-button/hook.mjs.map +2 -2
  87. package/build-module/border-box-control/border-box-control-split-controls/hook.mjs +2 -2
  88. package/build-module/border-box-control/border-box-control-split-controls/hook.mjs.map +2 -2
  89. package/build-module/border-box-control/border-box-control-visualizer/hook.mjs +2 -2
  90. package/build-module/border-box-control/border-box-control-visualizer/hook.mjs.map +2 -2
  91. package/build-module/color-palette/index.mjs +1 -1
  92. package/build-module/color-palette/index.mjs.map +2 -2
  93. package/build-module/composite/context.mjs +6 -1
  94. package/build-module/composite/context.mjs.map +2 -2
  95. package/build-module/composite/group-label.mjs +5 -1
  96. package/build-module/composite/group-label.mjs.map +2 -2
  97. package/build-module/composite/group.mjs +11 -3
  98. package/build-module/composite/group.mjs.map +2 -2
  99. package/build-module/composite/item.mjs +4 -0
  100. package/build-module/composite/item.mjs.map +2 -2
  101. package/build-module/context/context-system-provider.mjs +2 -5
  102. package/build-module/context/context-system-provider.mjs.map +3 -3
  103. package/build-module/context/use-context-system.mjs +7 -2
  104. package/build-module/context/use-context-system.mjs.map +2 -2
  105. package/build-module/disabled/index.mjs +1 -1
  106. package/build-module/disabled/index.mjs.map +2 -2
  107. package/build-module/draggable/index.mjs.map +1 -1
  108. package/build-module/form-token-field/index.mjs +1 -1
  109. package/build-module/form-token-field/index.mjs.map +2 -2
  110. package/build-module/icon/index.mjs +30 -12
  111. package/build-module/icon/index.mjs.map +2 -2
  112. package/build-module/input-control/styles/input-control-styles.mjs +42 -27
  113. package/build-module/input-control/styles/input-control-styles.mjs.map +2 -2
  114. package/build-module/item-group/context.mjs +1 -0
  115. package/build-module/item-group/context.mjs.map +2 -2
  116. package/build-module/item-group/item/component.mjs +12 -0
  117. package/build-module/item-group/item/component.mjs.map +2 -2
  118. package/build-module/item-group/item/hook.mjs +7 -6
  119. package/build-module/item-group/item/hook.mjs.map +2 -2
  120. package/build-module/item-group/item-group/component.mjs +1 -0
  121. package/build-module/item-group/item-group/component.mjs.map +2 -2
  122. package/build-module/item-group/item-group/hook.mjs +1 -1
  123. package/build-module/item-group/item-group/hook.mjs.map +2 -2
  124. package/build-module/progress-bar/index.mjs +1 -1
  125. package/build-module/progress-bar/index.mjs.map +2 -2
  126. package/build-module/resizable-box/index.mjs.map +1 -1
  127. package/build-module/snackbar/index.mjs +8 -5
  128. package/build-module/snackbar/index.mjs.map +2 -2
  129. package/build-module/textarea-control/index.mjs +1 -1
  130. package/build-module/textarea-control/index.mjs.map +2 -2
  131. package/build-module/toggle-group-control/context.mjs +8 -2
  132. package/build-module/toggle-group-control/context.mjs.map +2 -2
  133. package/build-module/toggle-group-control/toggle-group-control/as-button-group.mjs +5 -2
  134. package/build-module/toggle-group-control/toggle-group-control/as-button-group.mjs.map +2 -2
  135. package/build-module/toggle-group-control/toggle-group-control/as-radio-group.mjs +5 -2
  136. package/build-module/toggle-group-control/toggle-group-control/as-radio-group.mjs.map +2 -2
  137. package/build-module/toggle-group-control/toggle-group-control/component.mjs +3 -1
  138. package/build-module/toggle-group-control/toggle-group-control/component.mjs.map +2 -2
  139. package/build-module/toggle-group-control/toggle-group-control-option/component.mjs +2 -0
  140. package/build-module/toggle-group-control/toggle-group-control-option/component.mjs.map +2 -2
  141. package/build-module/toggle-group-control/toggle-group-control-option-base/component.mjs +2 -1
  142. package/build-module/toggle-group-control/toggle-group-control-option-base/component.mjs.map +2 -2
  143. package/build-module/toggle-group-control/toggle-group-control-option-icon/component.mjs +2 -0
  144. package/build-module/toggle-group-control/toggle-group-control-option-icon/component.mjs.map +2 -2
  145. package/build-module/tools-panel/tools-panel/hook.mjs +103 -107
  146. package/build-module/tools-panel/tools-panel/hook.mjs.map +2 -2
  147. package/build-module/tools-panel/tools-panel-item/hook.mjs +35 -35
  148. package/build-module/tools-panel/tools-panel-item/hook.mjs.map +2 -2
  149. package/build-module/tree-grid/cell.mjs +5 -1
  150. package/build-module/tree-grid/cell.mjs.map +2 -2
  151. package/build-module/tree-grid/roving-tab-index-item.mjs +5 -1
  152. package/build-module/tree-grid/roving-tab-index-item.mjs.map +2 -2
  153. package/build-module/tree-grid/row.mjs +7 -2
  154. package/build-module/tree-grid/row.mjs.map +2 -2
  155. package/build-module/tree-grid/use-validate-tree-grid-structure.mjs +56 -0
  156. package/build-module/tree-grid/use-validate-tree-grid-structure.mjs.map +7 -0
  157. package/build-module/utils/colors-values.mjs +3 -2
  158. package/build-module/utils/colors-values.mjs.map +2 -2
  159. package/build-style/style-rtl.css +27 -85
  160. package/build-style/style.css +27 -85
  161. package/build-types/border-box-control/border-box-control/component.d.ts +4 -0
  162. package/build-types/border-box-control/border-box-control/component.d.ts.map +1 -1
  163. package/build-types/border-box-control/border-box-control/hook.d.ts +4 -2
  164. package/build-types/border-box-control/border-box-control/hook.d.ts.map +1 -1
  165. package/build-types/border-box-control/types.d.ts +6 -2
  166. package/build-types/border-box-control/types.d.ts.map +1 -1
  167. package/build-types/composite/context.d.ts +2 -0
  168. package/build-types/composite/context.d.ts.map +1 -1
  169. package/build-types/composite/group-label.d.ts.map +1 -1
  170. package/build-types/composite/group.d.ts.map +1 -1
  171. package/build-types/composite/item.d.ts.map +1 -1
  172. package/build-types/composite/types.d.ts +1 -1
  173. package/build-types/context/context-system-provider.d.ts +8 -6
  174. package/build-types/context/context-system-provider.d.ts.map +1 -1
  175. package/build-types/context/use-context-system.d.ts.map +1 -1
  176. package/build-types/icon/index.d.ts.map +1 -1
  177. package/build-types/input-control/styles/input-control-styles.d.ts.map +1 -1
  178. package/build-types/item-group/context.d.ts.map +1 -1
  179. package/build-types/item-group/item/component.d.ts.map +1 -1
  180. package/build-types/item-group/item/hook.d.ts +1 -1
  181. package/build-types/item-group/item/hook.d.ts.map +1 -1
  182. package/build-types/item-group/item-group/component.d.ts.map +1 -1
  183. package/build-types/item-group/types.d.ts +4 -0
  184. package/build-types/item-group/types.d.ts.map +1 -1
  185. package/build-types/popover/types.d.ts +6 -2
  186. package/build-types/popover/types.d.ts.map +1 -1
  187. package/build-types/snackbar/index.d.ts.map +1 -1
  188. package/build-types/toggle-group-control/context.d.ts +2 -2
  189. package/build-types/toggle-group-control/context.d.ts.map +1 -1
  190. package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts +1 -1
  191. package/build-types/toggle-group-control/toggle-group-control/as-button-group.d.ts.map +1 -1
  192. package/build-types/toggle-group-control/toggle-group-control/as-radio-group.d.ts +1 -1
  193. package/build-types/toggle-group-control/toggle-group-control/as-radio-group.d.ts.map +1 -1
  194. package/build-types/toggle-group-control/toggle-group-control/component.d.ts.map +1 -1
  195. package/build-types/toggle-group-control/toggle-group-control-option/component.d.ts +2 -2
  196. package/build-types/toggle-group-control/toggle-group-control-option/component.d.ts.map +1 -1
  197. package/build-types/toggle-group-control/toggle-group-control-option-base/component.d.ts.map +1 -1
  198. package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts +2 -2
  199. package/build-types/toggle-group-control/toggle-group-control-option-icon/component.d.ts.map +1 -1
  200. package/build-types/toggle-group-control/types.d.ts +12 -3
  201. package/build-types/toggle-group-control/types.d.ts.map +1 -1
  202. package/build-types/tools-panel/tools-panel/hook.d.ts +4 -4
  203. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  204. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  205. package/build-types/tools-panel/types.d.ts +52 -9
  206. package/build-types/tools-panel/types.d.ts.map +1 -1
  207. package/build-types/tree-grid/cell.d.ts.map +1 -1
  208. package/build-types/tree-grid/roving-tab-index-item.d.ts.map +1 -1
  209. package/build-types/tree-grid/row.d.ts.map +1 -1
  210. package/build-types/tree-grid/use-validate-tree-grid-structure.d.ts +2 -0
  211. package/build-types/tree-grid/use-validate-tree-grid-structure.d.ts.map +1 -0
  212. package/build-types/utils/colors-values.d.ts.map +1 -1
  213. package/emotion-to-scss-modules.md +149 -0
  214. package/package.json +28 -27
  215. package/src/alignment-matrix-control/test/{index.tsx → index.jsdom.test.tsx} +5 -4
  216. package/src/angle-picker-control/style.module.scss +1 -1
  217. package/src/autocomplete/test/get-autocomplete-match.ts +2 -1
  218. package/src/autocomplete/test/{index.tsx → index.jsdom.test.tsx} +2 -1
  219. package/src/badge/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  220. package/src/base-control/stories/index.story.tsx +2 -2
  221. package/src/base-control/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  222. package/src/border-box-control/border-box-control/README.md +5 -3
  223. package/src/border-box-control/border-box-control/component.tsx +83 -15
  224. package/src/border-box-control/border-box-control/hook.ts +19 -1
  225. package/src/border-box-control/stories/index.story.tsx +10 -0
  226. package/src/border-box-control/style.module.scss +34 -3
  227. package/src/border-box-control/test/{index.tsx → index.jsdom.test.tsx} +138 -2
  228. package/src/border-box-control/test/utils.ts +11 -0
  229. package/src/border-box-control/types.ts +6 -2
  230. package/src/border-control/test/{index.js → index.jsdom.test.tsx} +44 -24
  231. package/src/box-control/test/{index.tsx → index.jsdom.test.tsx} +6 -3
  232. package/src/button/style.scss +0 -6
  233. package/src/button/test/{index.tsx → index.jsdom.test.tsx} +6 -2
  234. package/src/checkbox-control/stories/index.story.tsx +1 -1
  235. package/src/checkbox-control/style.scss +2 -2
  236. package/src/checkbox-control/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +10 -7
  237. package/src/checkbox-control/test/{index.tsx → index.jsdom.test.tsx} +4 -1
  238. package/src/circular-option-picker/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  239. package/src/color-indicator/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +2 -2
  240. package/src/color-indicator/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  241. package/src/color-palette/index.tsx +1 -1
  242. package/src/color-palette/test/{index.tsx → index.jsdom.test.tsx} +25 -22
  243. package/src/color-palette/test/{utils.ts → utils.jsdom.test.ts} +1 -0
  244. package/src/combobox-control/test/{index.tsx → index.jsdom.test.tsx} +12 -7
  245. package/src/composite/README.md +1 -1
  246. package/src/composite/context.tsx +6 -0
  247. package/src/composite/group-label.tsx +8 -1
  248. package/src/composite/group.tsx +9 -2
  249. package/src/composite/item.tsx +6 -0
  250. package/src/composite/legacy/test/{index.tsx → index.jsdom.test.tsx} +6 -13
  251. package/src/composite/test/{index.tsx → index.jsdom.test.tsx} +60 -17
  252. package/src/composite/types.ts +1 -1
  253. package/src/confirm-dialog/test/{index.tsx → index.jsdom.test.tsx} +16 -14
  254. package/src/content-editable-control/test/{index.tsx → index.jsdom.test.tsx} +4 -3
  255. package/src/context/{context-system-provider.js → context-system-provider.tsx} +19 -5
  256. package/src/context/stories/{ComponentsProvider.stories.jsx → ComponentsProvider.stories.tsx} +2 -2
  257. package/src/context/test/context-connect.tsx +1 -2
  258. package/src/context/test/{context-system-provider.js → context-system-provider.jsdom.test.tsx} +93 -51
  259. package/src/context/test/wordpress-component.tsx +1 -2
  260. package/src/context/use-context-system.js +13 -4
  261. package/src/custom-gradient-picker/gradient-bar/test/{utils.ts → utils.jsdom.test.ts} +6 -5
  262. package/src/custom-gradient-picker/test/serializer.ts +1 -0
  263. package/src/custom-select-control-v2/test/{index.tsx → index.jsdom.test.tsx} +4 -1
  264. package/src/date-time/date-picker/test/{index.tsx → index.jsdom.test.tsx} +6 -3
  265. package/src/date-time/date-picker/test/{use-lilius.ts → use-lilius.jsdom.test.ts} +1 -0
  266. package/src/date-time/date-time/test/{index.tsx → index.jsdom.test.tsx} +20 -11
  267. package/src/date-time/test/utils.test.ts +9 -0
  268. package/src/date-time/time-picker/test/{index.tsx → index.jsdom.test.tsx} +37 -27
  269. package/src/date-time/time-picker/time-input/test/{index.tsx → index.jsdom.test.tsx} +8 -3
  270. package/src/disabled/index.tsx +7 -7
  271. package/src/disabled/test/{index.tsx → index.jsdom.test.tsx} +26 -0
  272. package/src/draggable/index.tsx +1 -1
  273. package/src/draggable/style.module.scss +1 -1
  274. package/src/dropdown/style.module.scss +2 -2
  275. package/src/dropdown/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  276. package/src/dropdown-menu/test/{index.tsx → index.jsdom.test.tsx} +5 -4
  277. package/src/duotone-picker/test/{custom-duotone-bar.tsx → custom-duotone-bar.jsdom.test.tsx} +11 -8
  278. package/src/duotone-picker/test/{index.tsx → index.jsdom.test.tsx} +11 -10
  279. package/src/external-link/test/{index.tsx → index.jsdom.test.tsx} +5 -4
  280. package/src/focal-point-picker/test/{index.tsx → index.jsdom.test.tsx} +12 -9
  281. package/src/focal-point-picker/test/{media.tsx → media.jsdom.test.tsx} +1 -0
  282. package/src/font-size-picker/test/{font-size-picker-select.tsx → font-size-picker-select.jsdom.test.tsx} +19 -16
  283. package/src/font-size-picker/test/{font-size-picker-toggle-group.tsx → font-size-picker-toggle-group.jsdom.test.tsx} +13 -11
  284. package/src/font-size-picker/test/{index.tsx → index.jsdom.test.tsx} +19 -14
  285. package/src/font-size-picker/test/utils.ts +1 -0
  286. package/src/form-toggle/style.scss +1 -1
  287. package/src/form-toggle/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +4 -4
  288. package/src/form-toggle/test/{index.tsx → index.jsdom.test.tsx} +2 -1
  289. package/src/form-token-field/index.tsx +1 -1
  290. package/src/form-token-field/test/{index.tsx → index.jsdom.test.tsx} +86 -44
  291. package/src/gradient-picker/test/{index.tsx → index.jsdom.test.tsx} +12 -9
  292. package/src/guide/test/{index.tsx → index.jsdom.test.tsx} +4 -2
  293. package/src/h-stack/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +4 -4
  294. package/src/h-stack/test/{index.tsx → index.jsdom.test.tsx} +3 -0
  295. package/src/higher-order/with-fallback-styles/test/{index.tsx → index.jsdom.test.tsx} +3 -2
  296. package/src/higher-order/with-filters/test/__snapshots__/index.jsdom.test.tsx.snap +87 -0
  297. package/src/higher-order/with-filters/test/{index.tsx → index.jsdom.test.tsx} +6 -5
  298. package/src/higher-order/with-focus-outside/test/{index.tsx → index.jsdom.test.tsx} +2 -1
  299. package/src/higher-order/with-focus-return/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  300. package/src/higher-order/with-notices/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  301. package/src/higher-order/with-spoken-messages/test/{index.tsx → index.jsdom.test.tsx} +3 -2
  302. package/src/icon/index.tsx +28 -12
  303. package/src/icon/test/{index.tsx → index.jsdom.test.tsx} +66 -0
  304. package/src/input-control/styles/input-control-styles.tsx +38 -7
  305. package/src/input-control/test/{index.js → index.jsdom.test.tsx} +16 -10
  306. package/src/isolated-event-container/test/{index.tsx → index.jsdom.test.tsx} +4 -3
  307. package/src/item-group/context.ts +1 -0
  308. package/src/item-group/item/component.tsx +19 -1
  309. package/src/item-group/item/hook.ts +2 -3
  310. package/src/item-group/item-group/component.tsx +1 -0
  311. package/src/item-group/style.module.scss +1 -2
  312. package/src/item-group/test/__snapshots__/{index.js.snap → index.jsdom.test.tsx.snap} +9 -9
  313. package/src/item-group/test/{index.js → index.jsdom.test.tsx} +99 -2
  314. package/src/item-group/types.ts +4 -0
  315. package/src/keyboard-shortcuts/test/{index.tsx → index.jsdom.test.tsx} +5 -4
  316. package/src/menu/test/{index.tsx → index.jsdom.test.tsx} +67 -23
  317. package/src/menu-group/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  318. package/src/menu-item/test/__snapshots__/{index.js.snap → index.jsdom.test.tsx.snap} +5 -5
  319. package/src/menu-item/test/{index.js → index.jsdom.test.tsx} +1 -0
  320. package/src/modal/test/{aria-helper.ts → aria-helper.jsdom.test.ts} +1 -0
  321. package/src/modal/test/{index.tsx → index.jsdom.test.tsx} +9 -5
  322. package/src/navigable-container/test/{navigable-menu.tsx → navigable-menu.jsdom.test.tsx} +7 -5
  323. package/src/navigable-container/test/{tababble-container.tsx → tababble-container.jsdom.test.tsx} +5 -3
  324. package/src/navigator/test/{index.tsx → index.jsdom.test.tsx} +5 -2
  325. package/src/navigator/test/router.ts +1 -0
  326. package/src/notice/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +7 -4
  327. package/src/notice/test/{index.tsx → index.jsdom.test.tsx} +8 -4
  328. package/src/notice/test/{list.tsx → list.jsdom.test.tsx} +1 -0
  329. package/src/number-control/test/{index.tsx → index.jsdom.test.tsx} +9 -6
  330. package/src/palette-edit/test/{index.tsx → index.jsdom.test.tsx} +16 -13
  331. package/src/panel/test/__snapshots__/body.jsdom.test.tsx.snap +9 -0
  332. package/src/panel/test/__snapshots__/header.jsdom.test.tsx.snap +9 -0
  333. package/src/panel/test/__snapshots__/index.jsdom.test.tsx.snap +17 -0
  334. package/src/panel/test/__snapshots__/row.jsdom.test.tsx.snap +17 -0
  335. package/src/panel/test/{body.tsx → body.jsdom.test.tsx} +2 -1
  336. package/src/panel/test/{header.tsx → header.jsdom.test.tsx} +1 -0
  337. package/src/panel/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  338. package/src/panel/test/{row.tsx → row.jsdom.test.tsx} +1 -0
  339. package/src/placeholder/style.scss +0 -5
  340. package/src/placeholder/test/{index.tsx → index.jsdom.test.tsx} +19 -14
  341. package/src/popover/README.md +2 -2
  342. package/src/popover/test/{index.tsx → index.jsdom.test.tsx} +23 -0
  343. package/src/popover/types.ts +9 -3
  344. package/src/progress-bar/style.module.scss +9 -1
  345. package/src/query-controls/test/terms.ts +1 -0
  346. package/src/radio-control/test/{index.tsx → index.jsdom.test.tsx} +14 -11
  347. package/src/range-control/test/{index.tsx → index.jsdom.test.tsx} +10 -7
  348. package/src/resizable-box/index.tsx +1 -1
  349. package/src/sandbox/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  350. package/src/scroll-lock/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  351. package/src/shortcut/test/__snapshots__/index.jsdom.test.tsx.snap +15 -0
  352. package/src/shortcut/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  353. package/src/slot-fill/test/{index.js → index.jsdom.test.tsx} +4 -3
  354. package/src/slot-fill/test/{slot.js → slot.jsdom.test.tsx} +17 -9
  355. package/src/snackbar/index.tsx +10 -6
  356. package/src/snackbar/test/{index.tsx → index.jsdom.test.tsx} +41 -11
  357. package/src/snackbar/test/list.jsdom.test.tsx +100 -0
  358. package/src/style-provider/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  359. package/src/surface/style.module.scss +2 -2
  360. package/src/surface/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  361. package/src/tab-panel/style.scss +4 -23
  362. package/src/tab-panel/test/{index.tsx → index.jsdom.test.tsx} +22 -21
  363. package/src/tabs/test/{index.tsx → index.jsdom.test.tsx} +21 -19
  364. package/src/text-control/test/{text-control.tsx → text-control.jsdom.test.tsx} +1 -0
  365. package/src/text-highlight/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  366. package/src/textarea-control/style.module.scss +9 -4
  367. package/src/tip/style.scss +1 -1
  368. package/src/toggle-control/test/{index.tsx → index.jsdom.test.tsx} +4 -1
  369. package/src/toggle-group-control/context.ts +14 -5
  370. package/src/toggle-group-control/stories/index.story.tsx +15 -2
  371. package/src/toggle-group-control/test/{index.tsx → index.jsdom.test.tsx} +283 -9
  372. package/src/toggle-group-control/toggle-group-control/README.md +8 -5
  373. package/src/toggle-group-control/toggle-group-control/as-button-group.tsx +4 -0
  374. package/src/toggle-group-control/toggle-group-control/as-radio-group.tsx +4 -0
  375. package/src/toggle-group-control/toggle-group-control/component.tsx +2 -0
  376. package/src/toggle-group-control/toggle-group-control/style.module.scss +8 -2
  377. package/src/toggle-group-control/toggle-group-control-option/README.md +8 -5
  378. package/src/toggle-group-control/toggle-group-control-option/component.tsx +2 -0
  379. package/src/toggle-group-control/toggle-group-control-option-base/component.tsx +4 -1
  380. package/src/toggle-group-control/toggle-group-control-option-icon/README.md +7 -0
  381. package/src/toggle-group-control/toggle-group-control-option-icon/component.tsx +2 -0
  382. package/src/toggle-group-control/types.ts +12 -3
  383. package/src/toolbar/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  384. package/src/toolbar/test/{toolbar-group.tsx → toolbar-group.jsdom.test.tsx} +2 -1
  385. package/src/tools-panel/test/{index.tsx → index.jsdom.test.tsx} +595 -47
  386. package/src/tools-panel/tools-panel/hook.ts +195 -180
  387. package/src/tools-panel/tools-panel-item/README.md +42 -1
  388. package/src/tools-panel/tools-panel-item/hook.ts +97 -69
  389. package/src/tools-panel/types.ts +54 -9
  390. package/src/tooltip/test/{index.tsx → index.jsdom.test.tsx} +5 -3
  391. package/src/tree-grid/cell.tsx +6 -2
  392. package/src/tree-grid/roving-tab-index-item.tsx +7 -3
  393. package/src/tree-grid/row.tsx +8 -2
  394. package/src/tree-grid/test/__snapshots__/{cell.tsx.snap → cell.jsdom.test.tsx.snap} +2 -2
  395. package/src/tree-grid/test/__snapshots__/index.jsdom.test.tsx.snap +3 -0
  396. package/src/tree-grid/test/__snapshots__/roving-tab-index-item.jsdom.test.tsx.snap +27 -0
  397. package/src/tree-grid/test/__snapshots__/roving-tab-index.jsdom.test.tsx.snap +9 -0
  398. package/src/tree-grid/test/__snapshots__/{row.tsx.snap → row.jsdom.test.tsx.snap} +9 -5
  399. package/src/tree-grid/test/cell.jsdom.test.tsx +149 -0
  400. package/src/tree-grid/test/{index.tsx → index.jsdom.test.tsx} +9 -7
  401. package/src/tree-grid/test/{roving-tab-index-item.tsx → roving-tab-index-item.jsdom.test.tsx} +4 -1
  402. package/src/tree-grid/test/{roving-tab-index.tsx → roving-tab-index.jsdom.test.tsx} +1 -0
  403. package/src/tree-grid/test/row.jsdom.test.tsx +132 -0
  404. package/src/tree-grid/use-validate-tree-grid-structure.ts +104 -0
  405. package/src/truncate/style.module.scss +0 -1
  406. package/src/truncate/test/{index.tsx → index.jsdom.test.tsx} +1 -0
  407. package/src/unit-control/test/{index.tsx → index.jsdom.test.tsx} +22 -19
  408. package/src/unit-control/test/utils.ts +1 -0
  409. package/src/utils/colors-values.js +5 -4
  410. package/src/utils/hooks/test/{use-controlled-state.js → use-controlled-state.jsdom.test.tsx} +22 -7
  411. package/src/utils/hooks/test/{use-controlled-value.js → use-controlled-value.jsdom.test.tsx} +6 -3
  412. package/src/utils/hooks/test/{use-cx.js → use-cx.jsdom.test.tsx} +8 -5
  413. package/src/utils/test/colors.js +1 -0
  414. package/src/utils/test/{get-node-text.js → get-node-text.tsx} +1 -0
  415. package/src/utils/test/math.js +1 -0
  416. package/src/utils/test/rtl.js +1 -0
  417. package/src/utils/test/space.js +1 -0
  418. package/src/utils/test/strings.js +1 -0
  419. package/src/utils/test/unit-values.js +1 -0
  420. package/src/v-stack/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +4 -4
  421. package/src/v-stack/test/{index.tsx → index.jsdom.test.tsx} +3 -0
  422. package/src/validated-form-controls/style.scss +11 -15
  423. package/src/validated-form-controls/test/{content-editable-control.tsx → content-editable-control.jsdom.test.tsx} +1 -1
  424. package/src/validated-form-controls/test/{custom-select-control.tsx → custom-select-control.jsdom.test.tsx} +3 -0
  425. package/src/validated-form-controls/test/{input-control.tsx → input-control.jsdom.test.tsx} +3 -0
  426. package/src/validated-form-controls/test/{range-control.tsx → range-control.jsdom.test.tsx} +3 -0
  427. package/src/validated-form-controls/test/{textarea-control.tsx → textarea-control.jsdom.test.tsx} +1 -0
  428. package/src/view/test/__snapshots__/{index.js.snap → index.jsdom.test.tsx.snap} +7 -7
  429. package/src/view/test/{index.js → index.jsdom.test.tsx} +7 -2
  430. package/src/context/test/__snapshots__/context-system-provider.js.snap +0 -35
  431. package/src/higher-order/with-filters/test/__snapshots__/index.tsx.snap +0 -87
  432. package/src/panel/test/__snapshots__/body.tsx.snap +0 -9
  433. package/src/panel/test/__snapshots__/header.tsx.snap +0 -9
  434. package/src/panel/test/__snapshots__/index.tsx.snap +0 -17
  435. package/src/panel/test/__snapshots__/row.tsx.snap +0 -17
  436. package/src/shortcut/test/__snapshots__/index.tsx.snap +0 -15
  437. package/src/snackbar/test/list.tsx +0 -39
  438. package/src/toggle-group-control/test/__snapshots__/index.tsx.snap +0 -359
  439. package/src/tree-grid/test/__snapshots__/index.tsx.snap +0 -3
  440. package/src/tree-grid/test/__snapshots__/roving-tab-index-item.tsx.snap +0 -27
  441. package/src/tree-grid/test/__snapshots__/roving-tab-index.tsx.snap +0 -9
  442. package/src/tree-grid/test/cell.tsx +0 -46
  443. package/src/tree-grid/test/row.tsx +0 -37
  444. /package/src/card/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  445. /package/src/card/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  446. /package/src/color-picker/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  447. /package/src/custom-gradient-picker/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  448. /package/src/custom-select-control/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  449. /package/src/custom-select-control/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  450. /package/src/divider/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  451. /package/src/elevation/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  452. /package/src/elevation/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  453. /package/src/flex/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  454. /package/src/flex/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  455. /package/src/form-file-upload/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  456. /package/src/grid/test/{grid.tsx → grid.jsdom.test.tsx} +0 -0
  457. /package/src/heading/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  458. /package/src/heading/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  459. /package/src/input-control/test/__snapshots__/{index.js.snap → index.jsdom.test.tsx.snap} +0 -0
  460. /package/src/progress-bar/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  461. /package/src/resizable-box/resize-tooltip/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  462. /package/src/resizable-box/resize-tooltip/test/{label.tsx → label.jsdom.test.tsx} +0 -0
  463. /package/src/scrollable/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  464. /package/src/search-control/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  465. /package/src/select-control/test/__snapshots__/{select-control.tsx.snap → select-control.jsdom.test.tsx.snap} +0 -0
  466. /package/src/select-control/test/{select-control.tsx → select-control.jsdom.test.tsx} +0 -0
  467. /package/src/slot-fill/test/__snapshots__/{slot.js.snap → slot.jsdom.test.tsx.snap} +0 -0
  468. /package/src/spacer/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  469. /package/src/spacer/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  470. /package/src/text/test/__snapshots__/{index.tsx.snap → index.jsdom.test.tsx.snap} +0 -0
  471. /package/src/text/test/{index.tsx → index.jsdom.test.tsx} +0 -0
  472. /package/src/utils/test/{polymorphic-element.tsx → polymorphic-element.jsdom.test.tsx} +0 -0
@@ -1,3 +1,4 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
1
2
  import { render, waitFor } from '@testing-library/react';
2
3
  import { addFilter, removeAllFilters, removeFilter } from '@wordpress/hooks';
3
4
  import withFilters from '..';
@@ -56,7 +57,7 @@ describe( 'withFilters', () => {
56
57
  } );
57
58
 
58
59
  it( 'should not re-render component when new filter added before component was mounted', async () => {
59
- const SpiedComponent = jest.fn( () => <div>Spied component</div> );
60
+ const SpiedComponent = vi.fn( () => <div>Spied component</div> );
60
61
  addFilter(
61
62
  hookName,
62
63
  'test/enhanced-component-spy-1',
@@ -77,7 +78,7 @@ describe( 'withFilters', () => {
77
78
  } );
78
79
 
79
80
  it( 'should re-render component once when new filter added after component was mounted', async () => {
80
- const SpiedComponent = jest.fn( () => <div>Spied component</div> );
81
+ const SpiedComponent = vi.fn( () => <div>Spied component</div> );
81
82
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
82
83
 
83
84
  const { container } = render( <EnhancedComponent /> );
@@ -101,7 +102,7 @@ describe( 'withFilters', () => {
101
102
  } );
102
103
 
103
104
  it( 'should re-render component once when two filters added in the same animation frame', async () => {
104
- const SpiedComponent = jest.fn( () => <div>Spied component</div> );
105
+ const SpiedComponent = vi.fn( () => <div>Spied component</div> );
105
106
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
106
107
 
107
108
  const { container } = render( <EnhancedComponent /> );
@@ -134,7 +135,7 @@ describe( 'withFilters', () => {
134
135
  } );
135
136
 
136
137
  it( 'should re-render component twice when new filter added and removed in two different animation frames', async () => {
137
- const SpiedComponent = jest.fn( () => <div>Spied component</div> );
138
+ const SpiedComponent = vi.fn( () => <div>Spied component</div> );
138
139
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
139
140
  const { container } = render( <EnhancedComponent /> );
140
141
 
@@ -163,7 +164,7 @@ describe( 'withFilters', () => {
163
164
  } );
164
165
 
165
166
  it( 'should re-render both components once each when one filter added', async () => {
166
- const SpiedComponent = jest.fn( () => <div>Spied component</div> );
167
+ const SpiedComponent = vi.fn( () => <div>Spied component</div> );
167
168
  const EnhancedComponent = withFilters( hookName )( SpiedComponent );
168
169
 
169
170
  const CombinedComponents = () => (
@@ -1,3 +1,4 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
1
2
  import { render, screen, waitFor } from '@testing-library/react';
2
3
  import userEvent from '@testing-library/user-event';
3
4
  import { Component } from '@wordpress/element';
@@ -39,7 +40,7 @@ describe( 'withFocusOutside', () => {
39
40
  origHasFocus = document.hasFocus;
40
41
  document.hasFocus = () => true;
41
42
 
42
- onFocusOutside = jest.fn();
43
+ onFocusOutside = vi.fn();
43
44
  } );
44
45
 
45
46
  afterEach( () => {
@@ -1,3 +1,4 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
1
2
  import { render, screen } from '@testing-library/react';
2
3
  import userEvent from '@testing-library/user-event';
3
4
  import { Component } from '@wordpress/element';
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it } from 'vitest';
1
2
  import {
2
3
  act,
3
4
  render,
@@ -1,10 +1,11 @@
1
+ import { describe, expect, it, vi } from 'vitest';
1
2
  import { render } from '@testing-library/react';
2
3
  import withSpokenMessages from '../';
3
4
 
4
5
  describe( 'withSpokenMessages', () => {
5
6
  it( 'should generate speak and debouncedSpeak props', () => {
6
- const testSpeak = jest.fn();
7
- const testDebouncedSpeak = jest.fn();
7
+ const testSpeak = vi.fn();
8
+ const testDebouncedSpeak = vi.fn();
8
9
  const isFunction = ( maybeFunc: any ) =>
9
10
  typeof maybeFunc === 'function';
10
11
  const DumpComponent = withSpokenMessages(
@@ -1,4 +1,4 @@
1
- import type { ComponentType, HTMLProps, SVGProps } from 'react';
1
+ import type { ComponentType, CSSProperties, HTMLProps, SVGProps } from 'react';
2
2
  import {
3
3
  cloneElement,
4
4
  createElement,
@@ -19,6 +19,7 @@ type SizeProps = {
19
19
  size?: number;
20
20
  width?: number | string;
21
21
  height?: number | string;
22
+ style?: CSSProperties;
22
23
  };
23
24
 
24
25
  type AdditionalProps< T > = T extends ComponentType< infer U >
@@ -88,23 +89,38 @@ function Icon( {
88
89
  } );
89
90
  }
90
91
 
91
- if ( icon && ( icon.type === 'svg' || icon.type === SVG ) ) {
92
- const appliedProps = {
93
- ...icon.props,
94
- width: size,
95
- height: size,
96
- ...additionalProps,
97
- };
92
+ if ( isValidElement< SizeProps >( icon ) ) {
93
+ const { style: consumerStyle, ...restProps } =
94
+ additionalProps as SVGProps< SVGSVGElement >;
95
+ const mergedStyle =
96
+ icon.props.style || consumerStyle
97
+ ? { ...icon.props.style, ...consumerStyle }
98
+ : undefined;
99
+ const styleProps = mergedStyle ? { style: mergedStyle } : {};
98
100
 
99
- return <SVG { ...appliedProps } />;
100
- }
101
+ if ( icon.type === 'svg' || icon.type === SVG ) {
102
+ const appliedProps = {
103
+ ...icon.props,
104
+ width: size,
105
+ height: size,
106
+ ...restProps,
107
+ // Merge styles so the icon's intrinsic style (e.g. `fill: none` on
108
+ // stroke-based icons) is preserved unless the consumer overrides
109
+ // the same property explicitly.
110
+ ...styleProps,
111
+ };
112
+
113
+ return <SVG { ...appliedProps } />;
114
+ }
101
115
 
102
- if ( isValidElement< SizeProps >( icon ) ) {
103
116
  return cloneElement( icon, {
104
117
  size,
105
118
  width: size,
106
119
  height: size,
107
- ...additionalProps,
120
+ ...restProps,
121
+ // Merge styles so the icon's intrinsic style is preserved unless
122
+ // the consumer overrides the same property explicitly.
123
+ ...styleProps,
108
124
  } );
109
125
  }
110
126
 
@@ -95,4 +95,70 @@ describe( 'Icon', () => {
95
95
 
96
96
  expect( screen.getByTestId( testId ) ).toHaveClass( className );
97
97
  } );
98
+
99
+ it( "merges a consumer 'style' prop with the icon's intrinsic style", () => {
100
+ const strokeIcon = (
101
+ <SVG style={ { fill: 'none' } }>
102
+ <Path d="M5 4v3h5.5v12h3V7H19V4z" />
103
+ </SVG>
104
+ );
105
+ render(
106
+ <Icon
107
+ data-testid={ testId }
108
+ icon={ strokeIcon }
109
+ style={ { marginInlineStart: 4 } }
110
+ />
111
+ );
112
+ const icon = screen.getByTestId( testId );
113
+
114
+ // The icon's intrinsic `fill: none` survives…
115
+ expect( icon ).toHaveStyle( 'fill: none' );
116
+ // …alongside the consumer-supplied style.
117
+ expect( icon ).toHaveStyle( 'margin-inline-start: 4px' );
118
+ } );
119
+
120
+ it( "lets a consumer 'style' override the icon's intrinsic style", () => {
121
+ const strokeIcon = (
122
+ <SVG style={ { fill: 'none' } }>
123
+ <Path d="M5 4v3h5.5v12h3V7H19V4z" />
124
+ </SVG>
125
+ );
126
+ render(
127
+ <Icon
128
+ data-testid={ testId }
129
+ icon={ strokeIcon }
130
+ style={ { fill: 'red' } }
131
+ />
132
+ );
133
+
134
+ expect( screen.getByTestId( testId ) ).toHaveStyle( 'fill: red' );
135
+ } );
136
+
137
+ it( "merges a consumer 'style' with a non-svg element's intrinsic style", () => {
138
+ render(
139
+ <Icon
140
+ icon={
141
+ <span data-testid={ testId } style={ { fill: 'none' } } />
142
+ }
143
+ style={ { marginInlineStart: 4 } }
144
+ />
145
+ );
146
+ const icon = screen.getByTestId( testId );
147
+
148
+ expect( icon ).toHaveStyle( 'fill: none' );
149
+ expect( icon ).toHaveStyle( 'margin-inline-start: 4px' );
150
+ } );
151
+
152
+ it( "does not add a 'style' prop to a non-svg element without styles", () => {
153
+ let hasStyleProp = true;
154
+ const CustomIcon = ( props: Record< string, unknown > ) => {
155
+ hasStyleProp = 'style' in props;
156
+ return <span data-testid={ testId } />;
157
+ };
158
+
159
+ render( <Icon icon={ <CustomIcon /> } /> );
160
+
161
+ expect( screen.getByTestId( testId ) ).toBeVisible();
162
+ expect( hasStyleProp ).toBe( false );
163
+ } );
98
164
  } );
@@ -47,6 +47,21 @@ const backdropBorderColor = ( {
47
47
  return COLORS.ui.border;
48
48
  };
49
49
 
50
+ const backdropDisabledStyles = ( {
51
+ disabled,
52
+ isBorderless,
53
+ }: BackdropProps ) => {
54
+ if ( ! disabled || isBorderless ) {
55
+ return undefined;
56
+ }
57
+
58
+ return css`
59
+ @media ( forced-colors: active ) {
60
+ border-color: GrayText;
61
+ }
62
+ `;
63
+ };
64
+
50
65
  export const BackdropUI = styled.div< BackdropProps >`
51
66
  &&& {
52
67
  box-sizing: border-box;
@@ -64,6 +79,7 @@ export const BackdropUI = styled.div< BackdropProps >`
64
79
  top: 0;
65
80
 
66
81
  ${ rtl( { paddingLeft: 2 } ) }
82
+ ${ backdropDisabledStyles }
67
83
  }
68
84
  `;
69
85
 
@@ -75,11 +91,17 @@ export const Root = styled( Flex )`
75
91
  `;
76
92
 
77
93
  const containerDisabledStyles = ( { disabled }: ContainerProps ) => {
78
- const backgroundColor = disabled
79
- ? COLORS.ui.backgroundDisabled
80
- : COLORS.ui.background;
94
+ if ( ! disabled ) {
95
+ return undefined;
96
+ }
81
97
 
82
- return css( { backgroundColor } );
98
+ return css`
99
+ color: ${ COLORS.ui.textDisabled };
100
+
101
+ @media ( forced-colors: active ) {
102
+ color: GrayText;
103
+ }
104
+ `;
83
105
  };
84
106
 
85
107
  const containerWidthStyles = ( {
@@ -110,6 +132,7 @@ export const Container = styled.div< ContainerProps >`
110
132
  display: flex;
111
133
  flex: 1;
112
134
  position: relative;
135
+ background-color: ${ COLORS.ui.background };
113
136
 
114
137
  ${ containerDisabledStyles }
115
138
  ${ containerWidthStyles }
@@ -129,9 +152,17 @@ const disabledStyles = ( { disabled }: InputProps ) => {
129
152
  return '';
130
153
  }
131
154
 
132
- return css( {
133
- color: COLORS.ui.textDisabled,
134
- } );
155
+ return css`
156
+ color: ${ COLORS.ui.textDisabled };
157
+
158
+ @media ( forced-colors: active ) {
159
+ color: GrayText;
160
+ }
161
+
162
+ &:disabled::placeholder {
163
+ color: ${ COLORS.ui.textDisabled };
164
+ }
165
+ `;
135
166
  };
136
167
 
137
168
  export const fontSizeStyles = ( { inputSize: size }: InputProps ) => {
@@ -1,16 +1,17 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
+ import type { KeyboardEvent } from 'react';
3
4
  import { useState } from '@wordpress/element';
4
5
  import BaseInputControl from '../';
5
6
  import InputControlPrefixWrapper from '../input-prefix-wrapper';
7
+ import type { InputControlProps } from '../types';
6
8
 
7
- const getInput = () => screen.getByTestId( 'input' );
9
+ const getInput = () => screen.getByTestId< HTMLInputElement >( 'input' );
8
10
 
9
11
  describe( 'InputControl', () => {
10
- const InputControl = ( props ) => {
12
+ const InputControl = ( props: InputControlProps ) => {
11
13
  return <BaseInputControl { ...props } data-testid="input" />;
12
14
  };
13
-
14
15
  describe( 'Basic rendering', () => {
15
16
  it( 'should render', () => {
16
17
  render( <InputControl /> );
@@ -85,14 +86,16 @@ describe( 'InputControl', () => {
85
86
  it( 'should work as a controlled component given normal, falsy or nullish values', async () => {
86
87
  const user = await userEvent.setup();
87
88
  const spy = jest.fn();
88
- const heldKeySet = new Set();
89
+ const heldKeySet = new Set< string >();
89
90
  const Example = () => {
90
- const [ state, setState ] = useState( 'one' );
91
- const onChange = ( value ) => {
91
+ const [ state, setState ] = useState< string | undefined >(
92
+ 'one'
93
+ );
94
+ const onChange = ( value: string | undefined ) => {
92
95
  setState( value );
93
96
  spy( value );
94
97
  };
95
- const onKeyDown = ( { key } ) => {
98
+ const onKeyDown = ( { key }: KeyboardEvent ) => {
96
99
  heldKeySet.add( key );
97
100
  if ( key === 'Escape' ) {
98
101
  if ( heldKeySet.has( 'Meta' ) ) {
@@ -104,7 +107,8 @@ describe( 'InputControl', () => {
104
107
  }
105
108
  }
106
109
  };
107
- const onKeyUp = ( { key } ) => heldKeySet.delete( key );
110
+ const onKeyUp = ( { key }: KeyboardEvent ) =>
111
+ heldKeySet.delete( key );
108
112
  return (
109
113
  <InputControl
110
114
  value={ state }
@@ -189,7 +193,8 @@ describe( 'InputControl', () => {
189
193
  let { value } = state;
190
194
  if (
191
195
  action.type === 'COMMIT' &&
192
- action.payload.event.type === 'blur'
196
+ action.payload.event?.type === 'blur' &&
197
+ value !== undefined
193
198
  ) {
194
199
  value = value.replace( /\bnow\b/, 'meow' );
195
200
  }
@@ -219,7 +224,8 @@ describe( 'InputControl', () => {
219
224
  <InputControl
220
225
  label="Test"
221
226
  prefix={ prefix }
222
- { ...{ size: '__unstable-large' } }
227
+ // @ts-expect-error Verify the legacy value that is omitted from the public type.
228
+ size="__unstable-large"
223
229
  />
224
230
  );
225
231
 
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it, vi } from 'vitest';
1
2
  import { render, screen, within } from '@testing-library/react';
2
3
  import userEvent from '@testing-library/user-event';
3
4
  import IsolatedEventContainer from '..';
@@ -5,7 +6,7 @@ import IsolatedEventContainer from '..';
5
6
  describe( 'IsolatedEventContainer', () => {
6
7
  it( 'should pass props to container', async () => {
7
8
  const user = userEvent.setup();
8
- const clickHandler = jest.fn();
9
+ const clickHandler = vi.fn();
9
10
  render(
10
11
  <IsolatedEventContainer
11
12
  title="Container"
@@ -38,8 +39,8 @@ describe( 'IsolatedEventContainer', () => {
38
39
  it( 'should stop event propagation only for mousedown, but not for keydown', async () => {
39
40
  const user = userEvent.setup();
40
41
 
41
- const mousedownHandler = jest.fn();
42
- const keydownHandler = jest.fn();
42
+ const mousedownHandler = vi.fn();
43
+ const keydownHandler = vi.fn();
43
44
  render(
44
45
  <button
45
46
  onMouseDown={ mousedownHandler }
@@ -2,6 +2,7 @@ import { createContext, useContext } from '@wordpress/element';
2
2
  import type { ItemGroupContext as Context } from './types';
3
3
 
4
4
  export const ItemGroupContext = createContext( {
5
+ isList: false,
5
6
  size: 'medium',
6
7
  } as Context );
7
8
  ItemGroupContext.displayName = 'ItemGroupContext';
@@ -1,18 +1,36 @@
1
1
  import type { ForwardedRef } from 'react';
2
+ import { useEffect, useRef } from '@wordpress/element';
2
3
  import type { ItemProps } from '../types';
3
4
  import { useItem } from './hook';
4
5
  import type { WordPressComponentProps } from '../../context';
5
6
  import { contextConnect } from '../../context';
6
7
  import { View } from '../../view';
8
+ import { useItemGroupContext } from '../context';
7
9
 
8
10
  function UnconnectedItem(
9
11
  props: WordPressComponentProps< ItemProps, 'div' >,
10
12
  forwardedRef: ForwardedRef< any >
11
13
  ) {
12
14
  const { role, wrapperClassName, ...otherProps } = useItem( props );
15
+ const itemRef = useRef< HTMLDivElement >( null );
16
+ const { isList } = useItemGroupContext();
17
+
18
+ useEffect( () => {
19
+ if (
20
+ isList &&
21
+ role === 'listitem' &&
22
+ ! itemRef.current?.closest(
23
+ 'ol, ul, menu, [role="list"], [role="directory"]'
24
+ )
25
+ ) {
26
+ throw new Error(
27
+ 'Item with list semantics must be rendered inside an element with role="list".'
28
+ );
29
+ }
30
+ }, [ isList, role ] );
13
31
 
14
32
  return (
15
- <div role={ role } className={ wrapperClassName }>
33
+ <div ref={ itemRef } role={ role } className={ wrapperClassName }>
16
34
  <View { ...otherProps } ref={ forwardedRef } />
17
35
  </div>
18
36
  );
@@ -12,17 +12,16 @@ const sizeClassName = {
12
12
  };
13
13
 
14
14
  export function useItem( props: WordPressComponentProps< ItemProps, 'div' > ) {
15
+ const { isList, spacedAround, size: contextSize } = useItemGroupContext();
15
16
  const {
16
17
  as: asProp,
17
18
  className,
18
19
  onClick,
19
- role = 'listitem',
20
+ role = isList ? 'listitem' : undefined,
20
21
  size: sizeProp,
21
22
  ...otherProps
22
23
  } = useContextSystem( props, 'Item' );
23
24
 
24
- const { spacedAround, size: contextSize } = useItemGroupContext();
25
-
26
25
  const size = sizeProp || contextSize;
27
26
 
28
27
  const as = asProp || ( typeof onClick !== 'undefined' ? 'button' : 'div' );
@@ -23,6 +23,7 @@ function UnconnectedItemGroup(
23
23
  const size = sizeProp || contextSize;
24
24
 
25
25
  const contextValue = {
26
+ isList: otherProps.role === 'list' || otherProps.role === 'directory',
26
27
  spacedAround,
27
28
  size,
28
29
  };
@@ -70,8 +70,7 @@ $padding-y-large: calc((calc(#{$control-height} * 1.2) - #{$base-font-height} -
70
70
  background: none;
71
71
  text-align: start;
72
72
 
73
- svg,
74
- path {
73
+ svg {
75
74
  fill: currentColor;
76
75
  }
77
76
 
@@ -1,6 +1,6 @@
1
- // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`ItemGroup Item should read the value of the size prop from context when the prop is not defined 1`] = `
3
+ exports[`ItemGroup > Item > should read the value of the size prop from context when the prop is not defined 1`] = `
4
4
  Snapshot Diff:
5
5
  - First value
6
6
  + Second value
@@ -33,15 +33,15 @@ Snapshot Diff:
33
33
  </div>
34
34
  `;
35
35
 
36
- exports[`ItemGroup Item should use different amounts of padding depending on the value of the size prop 1`] = `
36
+ exports[`ItemGroup > Item > should use different amounts of padding depending on the value of the size prop 1`] = `
37
37
  Snapshot Diff:
38
38
  - First value
39
39
  + Second value
40
40
 
41
- @@ -2,11 +2,11 @@
41
+ @@ -1,11 +1,11 @@
42
+ <div>
42
43
  <div
43
44
  class="style-item-wrapper"
44
- role="listitem"
45
45
  >
46
46
  <div
47
47
  - class="style-item style-is-size-medium components-item"
@@ -53,7 +53,7 @@ Snapshot Diff:
53
53
  </div>
54
54
  `;
55
55
 
56
- exports[`ItemGroup ItemGroup component should render correctly 1`] = `
56
+ exports[`ItemGroup > ItemGroup component > should render correctly 1`] = `
57
57
  <div>
58
58
  <div
59
59
  class="style-item-group style-is-rounded components-item-group"
@@ -77,7 +77,7 @@ exports[`ItemGroup ItemGroup component should render correctly 1`] = `
77
77
  </div>
78
78
  `;
79
79
 
80
- exports[`ItemGroup ItemGroup component should render items individually when the isSeparated prop is true 1`] = `
80
+ exports[`ItemGroup > ItemGroup component > should render items individually when the isSeparated prop is true 1`] = `
81
81
  Snapshot Diff:
82
82
  - First value
83
83
  + Second value
@@ -105,7 +105,7 @@ Snapshot Diff:
105
105
  </div>
106
106
  `;
107
107
 
108
- exports[`ItemGroup ItemGroup component should show borders when the isBordered prop is true 1`] = `
108
+ exports[`ItemGroup > ItemGroup component > should show borders when the isBordered prop is true 1`] = `
109
109
  Snapshot Diff:
110
110
  - First value
111
111
  + Second value
@@ -133,7 +133,7 @@ Snapshot Diff:
133
133
  </div>
134
134
  `;
135
135
 
136
- exports[`ItemGroup ItemGroup component should show rounded corners when the isRounded prop is true 1`] = `
136
+ exports[`ItemGroup > ItemGroup component > should show rounded corners when the isRounded prop is true 1`] = `
137
137
  Snapshot Diff:
138
138
  - First value
139
139
  + Second value
@@ -1,9 +1,70 @@
1
+ import { describe, expect, it, vi } from 'vitest';
1
2
  import { render, screen } from '@testing-library/react';
2
3
  import userEvent from '@testing-library/user-event';
4
+ import { createPortal } from '@wordpress/element';
3
5
  import { Item, ItemGroup } from '..';
4
6
 
5
7
  describe( 'ItemGroup', () => {
6
8
  describe( 'ItemGroup component', () => {
9
+ it( 'accepts an Item nested within a semantic list', () => {
10
+ render(
11
+ <ItemGroup>
12
+ <div>
13
+ <Item>Nested item</Item>
14
+ </div>
15
+ </ItemGroup>
16
+ );
17
+
18
+ expect( screen.getByRole( 'listitem' ) ).toHaveTextContent(
19
+ 'Nested item'
20
+ );
21
+ } );
22
+
23
+ it( 'throws when an Item with list semantics is outside a semantic list', () => {
24
+ const portalContainer = document.createElement( 'div' );
25
+ document.body.append( portalContainer );
26
+
27
+ try {
28
+ expect( () =>
29
+ render(
30
+ <ItemGroup>
31
+ { createPortal(
32
+ <Item>Portaled item</Item>,
33
+ portalContainer
34
+ ) }
35
+ </ItemGroup>
36
+ )
37
+ ).toThrow(
38
+ 'Item with list semantics must be rendered inside an element with role="list".'
39
+ );
40
+ expect( console ).toHaveErrored();
41
+ } finally {
42
+ portalContainer.remove();
43
+ }
44
+ } );
45
+
46
+ it( 'accepts custom children', () => {
47
+ render(
48
+ <ItemGroup>
49
+ <div>Custom item</div>
50
+ </ItemGroup>
51
+ );
52
+
53
+ expect( screen.getByText( 'Custom item' ) ).toBeVisible();
54
+ } );
55
+
56
+ it( 'preserves custom roles', () => {
57
+ render(
58
+ <ItemGroup role="group">
59
+ <div>
60
+ <Item role="presentation">Custom item</Item>
61
+ </div>
62
+ </ItemGroup>
63
+ );
64
+
65
+ expect( screen.getByRole( 'group' ) ).toBeVisible();
66
+ } );
67
+
7
68
  it( 'should render correctly', () => {
8
69
  const { container } = render(
9
70
  <ItemGroup>
@@ -66,9 +127,45 @@ describe( 'ItemGroup', () => {
66
127
  } );
67
128
 
68
129
  describe( 'Item', () => {
130
+ it( 'uses list semantics only within a list-semantic ItemGroup', () => {
131
+ const { rerender } = render( <Item>Standalone item</Item> );
132
+
133
+ expect( screen.queryByRole( 'listitem' ) ).not.toBeInTheDocument();
134
+
135
+ rerender(
136
+ <ItemGroup role="group">
137
+ <Item>Non-list item</Item>
138
+ </ItemGroup>
139
+ );
140
+
141
+ expect( screen.queryByRole( 'listitem' ) ).not.toBeInTheDocument();
142
+
143
+ rerender(
144
+ <ItemGroup>
145
+ <Item>Grouped item</Item>
146
+ </ItemGroup>
147
+ );
148
+
149
+ expect( screen.getByRole( 'listitem' ) ).toHaveTextContent(
150
+ 'Grouped item'
151
+ );
152
+ } );
153
+
154
+ it( 'uses list semantics within an ItemGroup with the directory role', () => {
155
+ render(
156
+ <ItemGroup role="directory">
157
+ <Item>Directory item</Item>
158
+ </ItemGroup>
159
+ );
160
+
161
+ expect( screen.getByRole( 'listitem' ) ).toHaveTextContent(
162
+ 'Directory item'
163
+ );
164
+ } );
165
+
69
166
  it( 'should render as a `button` if the `onClick` handler is specified', async () => {
70
167
  const user = userEvent.setup();
71
- const spy = jest.fn();
168
+ const spy = vi.fn();
72
169
  render( <Item onClick={ spy }>Code is poetry</Item> );
73
170
 
74
171
  const button = screen.getByRole( 'button' );
@@ -81,7 +178,7 @@ describe( 'ItemGroup', () => {
81
178
  } );
82
179
 
83
180
  it( 'should give priority to the `as` prop even if the `onClick` handler is specified', () => {
84
- const spy = jest.fn();
181
+ const spy = vi.fn();
85
182
  const { rerender } = render(
86
183
  <Item onClick={ spy }>Code is poetry</Item>
87
184
  );