@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,5 @@
1
+ @use "@wordpress/base-styles/variables" as *;
2
+
1
3
  .linked-border-control {
2
4
  /* Preserve the original `&&` specificity so this beats BorderControl's margin reset. */
3
5
  &#{&} {
@@ -6,14 +8,43 @@
6
8
  }
7
9
  }
8
10
 
11
+ /* No inline-end gutter is needed when the toggle sits in the header row. */
12
+ .linked-border-control-full-width {
13
+ &#{&} {
14
+ margin-inline-end: 0;
15
+ }
16
+ }
17
+
18
+ /* The label row the linked/unlinked toggle joins when a visible label is
19
+ rendered. Laid out as a content-driven grid like `BoxControl`'s label row, so
20
+ a label that wraps grows the row rather than overflowing a fixed height. */
21
+ .header {
22
+ /* The row is as tall as the toggle (24px, `Button` `size="small"`), so 4px
23
+ here leaves the same 28px between label and inputs as the sibling
24
+ controls, which instead pair a fixed 16px row with a 12px margin. */
25
+ margin-bottom: $grid-unit-05;
26
+
27
+ /* The label (a `BaseControl.VisualLabel`, so a `span`) supplies its own
28
+ bottom margin as the gap to the input below. In the header row that gap
29
+ comes from the row itself, and the margin would both pull the vertically
30
+ centred label off centre and pad the row out once the label wraps. */
31
+ > span {
32
+ margin-bottom: 0;
33
+ }
34
+ }
35
+
9
36
  .wrapper {
10
37
  position: relative;
38
+
39
+ /* Without a header row the toggle is positioned against the input instead. */
40
+ .linked-button {
41
+ position: absolute;
42
+ top: 8px;
43
+ inset-inline-end: 0;
44
+ }
11
45
  }
12
46
 
13
47
  .linked-button {
14
- position: absolute;
15
- top: 8px;
16
- inset-inline-end: 0;
17
48
  line-height: 0;
18
49
  }
19
50
 
@@ -1,8 +1,12 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
1
2
  import type { ComponentProps } from 'react';
2
3
  import { render, screen, waitFor } from '@testing-library/react';
3
4
  import userEvent from '@testing-library/user-event';
5
+ import { useId } from '@wordpress/element';
4
6
  import { BorderBoxControl } from '..';
5
7
 
8
+ globalThis.wpVitest.mockMatchMedia();
9
+
6
10
  const colors = [
7
11
  { name: 'Gray', color: '#f6f7f7' },
8
12
  { name: 'Blue', color: '#72aee6' },
@@ -34,7 +38,7 @@ const mixedBorders = {
34
38
  const props = {
35
39
  colors,
36
40
  label: 'Border Box',
37
- onChange: jest.fn().mockImplementation( ( newValue ) => {
41
+ onChange: vi.fn().mockImplementation( ( newValue ) => {
38
42
  props.value = newValue;
39
43
  } ),
40
44
  value: undefined,
@@ -50,6 +54,102 @@ function TestBorderBoxControl(
50
54
  }
51
55
 
52
56
  describe( 'BorderBoxControl', () => {
57
+ describe( 'Labelling', () => {
58
+ it( 'should give the group of controls an accessible name from the label', () => {
59
+ render( <TestBorderBoxControl { ...props } /> );
60
+
61
+ expect(
62
+ screen.getByRole( 'group', { name: props.label } )
63
+ ).toBeInTheDocument();
64
+ } );
65
+
66
+ it( 'should name the group of controls even when the label is hidden', () => {
67
+ render( <TestBorderBoxControl { ...props } hideLabelFromVision /> );
68
+
69
+ expect(
70
+ screen.getByRole( 'group', { name: props.label } )
71
+ ).toBeInTheDocument();
72
+ } );
73
+
74
+ it( 'should let a consumer-provided `aria-label` take precedence over the label', () => {
75
+ render(
76
+ <TestBorderBoxControl { ...props } aria-label="Outer borders" />
77
+ );
78
+
79
+ expect(
80
+ screen.getByRole( 'group', { name: 'Outer borders' } )
81
+ ).toBeInTheDocument();
82
+ } );
83
+
84
+ it( 'should let a consumer-provided `aria-labelledby` take precedence over the label', () => {
85
+ const ExternallyLabelledControl = () => {
86
+ const id = useId();
87
+ return (
88
+ <>
89
+ <span id={ id }>Outer borders</span>
90
+ <TestBorderBoxControl
91
+ { ...props }
92
+ aria-labelledby={ id }
93
+ />
94
+ </>
95
+ );
96
+ };
97
+
98
+ render( <ExternallyLabelledControl /> );
99
+
100
+ expect(
101
+ screen.getByRole( 'group', { name: 'Outer borders' } )
102
+ ).toBeInTheDocument();
103
+
104
+ // With an external name in play, the internal label is no longer
105
+ // referenced, so it shouldn't carry a generated ID either.
106
+ expect( screen.getByText( props.label ) ).not.toHaveAttribute(
107
+ 'id'
108
+ );
109
+ } );
110
+
111
+ it( 'should form a group when named only by `aria-label`', () => {
112
+ render(
113
+ <TestBorderBoxControl
114
+ { ...props }
115
+ label={ undefined }
116
+ aria-label="Outer borders"
117
+ />
118
+ );
119
+
120
+ expect(
121
+ screen.getByRole( 'group', { name: 'Outer borders' } )
122
+ ).toBeInTheDocument();
123
+ } );
124
+
125
+ it( 'should fall back to the label when an ARIA naming prop is empty', () => {
126
+ // An empty `aria-label` is skipped by the accessible name
127
+ // computation, so it shouldn't suppress the label association and
128
+ // leave the group unnamed.
129
+ render( <TestBorderBoxControl { ...props } aria-label="" /> );
130
+
131
+ expect(
132
+ screen.getByRole( 'group', { name: props.label } )
133
+ ).toBeInTheDocument();
134
+ } );
135
+
136
+ it( 'should give each instance its own label association', () => {
137
+ render(
138
+ <>
139
+ <TestBorderBoxControl { ...props } label="First" />
140
+ <TestBorderBoxControl { ...props } label="Second" />
141
+ </>
142
+ );
143
+
144
+ expect(
145
+ screen.getByRole( 'group', { name: 'First' } )
146
+ ).toBeInTheDocument();
147
+ expect(
148
+ screen.getByRole( 'group', { name: 'Second' } )
149
+ ).toBeInTheDocument();
150
+ } );
151
+ } );
152
+
53
153
  describe( 'Linked view rendering', () => {
54
154
  it( 'should render correctly when no value provided', () => {
55
155
  render( <TestBorderBoxControl { ...props } /> );
@@ -76,6 +176,42 @@ describe( 'BorderBoxControl', () => {
76
176
  expect( linkedButton ).toBeInTheDocument();
77
177
  } );
78
178
 
179
+ // `getAllByRole` returns document order, so the sign of this offset is
180
+ // which side of the border inputs the linked button sits on. The color
181
+ // button is the first of those inputs.
182
+ const getLinkedButtonOffsetFromColorButton = () => {
183
+ const buttons = screen.getAllByRole( 'button' );
184
+ const linkedButtonIndex = buttons.indexOf(
185
+ screen.getByLabelText( 'Unlink sides' )
186
+ );
187
+ const colorButtonIndex = buttons.indexOf(
188
+ screen.getByLabelText( toggleLabelRegex )
189
+ );
190
+
191
+ // Both queries throw when absent, and `indexOf` gives -1 for a
192
+ // button outside the list, which would read as "earlier than".
193
+ expect( linkedButtonIndex ).toBeGreaterThanOrEqual( 0 );
194
+ expect( colorButtonIndex ).toBeGreaterThanOrEqual( 0 );
195
+
196
+ return linkedButtonIndex - colorButtonIndex;
197
+ };
198
+
199
+ it( 'should place the linked button before the border inputs when the label is visible', () => {
200
+ render( <TestBorderBoxControl { ...props } /> );
201
+
202
+ // Sharing the label's row is what lines it up with the equivalent
203
+ // button on sibling controls such as border radius.
204
+ expect( getLinkedButtonOffsetFromColorButton() ).toBeLessThan( 0 );
205
+ } );
206
+
207
+ it( 'should place the linked button after the border inputs when the label is hidden', () => {
208
+ render( <TestBorderBoxControl { ...props } hideLabelFromVision /> );
209
+
210
+ expect( getLinkedButtonOffsetFromColorButton() ).toBeGreaterThan(
211
+ 0
212
+ );
213
+ } );
214
+
79
215
  it( 'should hide label', () => {
80
216
  render( <TestBorderBoxControl { ...props } hideLabelFromVision /> );
81
217
 
@@ -318,7 +454,7 @@ describe( 'BorderBoxControl', () => {
318
454
 
319
455
  describe( 'onChange handling', () => {
320
456
  beforeEach( () => {
321
- jest.clearAllMocks();
457
+ vi.clearAllMocks();
322
458
  props.value = undefined;
323
459
  } );
324
460
 
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it } from 'vitest';
1
2
  import {
2
3
  getBorderDiff,
3
4
  getCommonBorder,
@@ -44,12 +45,14 @@ describe( 'BorderBoxControl Utils', () => {
44
45
  describe( 'isEmptyBorder', () => {
45
46
  it( 'should determine a undefined, null, and {} to be empty', () => {
46
47
  expect( isEmptyBorder( undefined ) ).toBe( true );
48
+ // Checking for extra resilience, even if not a valid type.
47
49
  // @ts-expect-error `null` is outside the declared `Border | undefined` input; resilience is tested.
48
50
  expect( isEmptyBorder( null ) ).toBe( true );
49
51
  expect( isEmptyBorder( {} ) ).toBe( true );
50
52
  } );
51
53
 
52
54
  it( 'should determine object missing all border props to be empty', () => {
55
+ // Checking for extra resilience, even if not a valid type.
53
56
  // @ts-expect-error `nonBorder` has no properties in common with `Border`; resilience is tested.
54
57
  expect( isEmptyBorder( nonBorder ) ).toBe( true );
55
58
  } );
@@ -109,12 +112,14 @@ describe( 'BorderBoxControl Utils', () => {
109
112
  describe( 'isCompleteBorder', () => {
110
113
  it( 'should determine a undefined, null, and {} to be incomplete', () => {
111
114
  expect( isCompleteBorder( undefined ) ).toBe( false );
115
+ // Checking for extra resilience, even if not a valid type.
112
116
  // @ts-expect-error `null` is outside the declared `Border | undefined` input; resilience is tested.
113
117
  expect( isCompleteBorder( null ) ).toBe( false );
114
118
  expect( isCompleteBorder( {} ) ).toBe( false );
115
119
  } );
116
120
 
117
121
  it( 'should determine objects missing border props to be incomplete', () => {
122
+ // Checking for extra resilience, even if not a valid type.
118
123
  // @ts-expect-error `nonBorder` has no properties in common with `Border`; resilience is tested.
119
124
  expect( isCompleteBorder( nonBorder ) ).toBe( false );
120
125
  expect( isCompleteBorder( partialBorder ) ).toBe( false );
@@ -150,6 +155,7 @@ describe( 'BorderBoxControl Utils', () => {
150
155
  it( 'should determine undefined, non-border or empty object as not being mixed', () => {
151
156
  expect( hasMixedBorders( undefined ) ).toBe( false );
152
157
  expect( hasMixedBorders( {} ) ).toBe( false );
158
+ // Checking for extra resilience, even if not a valid type.
153
159
  // @ts-expect-error `nonBorder` is not assignable to `AnyBorder`; resilience is tested.
154
160
  expect( hasMixedBorders( nonBorder ) ).toBe( false );
155
161
  } );
@@ -170,12 +176,14 @@ describe( 'BorderBoxControl Utils', () => {
170
176
  describe( 'getSplitBorders', () => {
171
177
  it( 'should return undefined when no border provided', () => {
172
178
  expect( getSplitBorders( undefined ) ).toEqual( undefined );
179
+ // Checking for extra resilience, even if not a valid type.
173
180
  // @ts-expect-error `null` is outside the declared `Border | undefined` input; resilience is tested.
174
181
  expect( getSplitBorders( null ) ).toEqual( undefined );
175
182
  } );
176
183
 
177
184
  it( 'should return undefined when supplied border is empty', () => {
178
185
  expect( getSplitBorders( {} ) ).toEqual( undefined );
186
+ // Checking for extra resilience, even if not a valid type.
179
187
  // @ts-expect-error `nonBorder` has no properties in common with `Border`; resilience is tested.
180
188
  expect( getSplitBorders( nonBorder ) ).toEqual( undefined );
181
189
  } );
@@ -197,6 +205,7 @@ describe( 'BorderBoxControl Utils', () => {
197
205
  } );
198
206
 
199
207
  it( 'should only return differences for border related properties', () => {
208
+ // Checking for extra resilience, even if not a valid type.
200
209
  // @ts-expect-error `nonBorder` has no properties in common with `Border`; resilience is tested.
201
210
  const diff = getBorderDiff( nonBorder, { caffeine: 'coffee' } );
202
211
  expect( diff ).toEqual( {} );
@@ -206,6 +215,7 @@ describe( 'BorderBoxControl Utils', () => {
206
215
  const diff = getBorderDiff( completeBorder, {
207
216
  ...completeBorder,
208
217
  color: '#21759b',
218
+ // Checking for extra resilience, even if not a valid type.
209
219
  // @ts-expect-error `caffeine` is not a declared `Border` property; the test checks it is ignored.
210
220
  caffeine: 'cola',
211
221
  } );
@@ -304,6 +314,7 @@ describe( 'BorderBoxControl Utils', () => {
304
314
  it( 'should return undefined when no border provided', () => {
305
315
  expect( getShorthandBorderStyle( undefined ) ).toEqual( undefined );
306
316
  expect( getShorthandBorderStyle( {} ) ).toEqual( undefined );
317
+ // Checking for extra resilience, even if not a valid type.
307
318
  // @ts-expect-error `nonBorder` has no properties in common with `Border`; resilience is tested.
308
319
  expect( getShorthandBorderStyle( nonBorder ) ).toEqual( undefined );
309
320
  } );
@@ -34,7 +34,9 @@ export type BorderBoxControlProps = ColorProps &
34
34
  */
35
35
  popoverPlacement?: PopoverProps[ 'placement' ];
36
36
  /**
37
- * The space between the popover and the control wrapper.
37
+ * The space between the popover and the control wrapper. A number
38
+ * displaces the popover along its main axis; pass an object to also
39
+ * displace it along its cross axis.
38
40
  */
39
41
  popoverOffset?: PopoverProps[ 'offset' ];
40
42
  /**
@@ -83,7 +85,9 @@ export type SplitControlsProps = ColorProps &
83
85
  */
84
86
  popoverPlacement?: PopoverProps[ 'placement' ];
85
87
  /**
86
- * The space between the popover and the control wrapper.
88
+ * The space between the popover and the control wrapper. A number
89
+ * displaces the popover along its main axis; pass an object to also
90
+ * displace it along its cross axis.
87
91
  */
88
92
  popoverOffset?: PopoverProps[ 'offset' ];
89
93
  /**
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it, vi } from 'vitest';
1
2
  import {
2
3
  fireEvent,
3
4
  render,
@@ -7,8 +8,13 @@ import {
7
8
  } from '@testing-library/react';
8
9
  import userEvent from '@testing-library/user-event';
9
10
  import { BorderControl } from '../';
11
+ import type { Border, BorderControlProps } from '../types';
10
12
  import { COLORS } from '../../utils';
11
13
 
14
+ globalThis.wpVitest.mockMatchMedia();
15
+
16
+ globalThis.wpVitest.mockResizeObserver();
17
+
12
18
  const colors = [
13
19
  { name: 'Gray', color: '#f6f7f7' },
14
20
  { name: 'Blue', color: '#72aee6' },
@@ -23,11 +29,13 @@ const defaultBorder = {
23
29
  width: '1px',
24
30
  };
25
31
 
26
- function createProps( customProps ) {
27
- const props = {
32
+ function createProps(
33
+ customProps: Partial< BorderControlProps > = {}
34
+ ): BorderControlProps {
35
+ const props: BorderControlProps = {
28
36
  colors,
29
37
  label: 'Border',
30
- onChange: jest.fn().mockImplementation( ( newValue ) => {
38
+ onChange: vi.fn().mockImplementation( ( newValue?: Border ) => {
31
39
  props.value = newValue;
32
40
  } ),
33
41
  value: defaultBorder,
@@ -38,7 +46,7 @@ function createProps( customProps ) {
38
46
 
39
47
  const toggleLabelRegex = /Border color( and style)* picker/;
40
48
 
41
- const openPopover = async ( user ) => {
49
+ const openPopover = async ( user: ReturnType< typeof userEvent.setup > ) => {
42
50
  const toggleButton = screen.getByLabelText( toggleLabelRegex );
43
51
  await user.click( toggleButton );
44
52
 
@@ -50,27 +58,31 @@ const openPopover = async ( user ) => {
50
58
  await waitFor( () => expect( pickerButton ).toBePositionedPopover() );
51
59
  };
52
60
 
53
- const getButton = ( name ) => {
61
+ const getButton = ( name: string | RegExp ) => {
54
62
  return screen.getByRole( 'button', { name } );
55
63
  };
56
64
 
57
- const getColorOption = ( color ) => {
65
+ const getColorOption = ( color: string ) => {
58
66
  return screen.getByRole( 'option', { name: `${ color }` } );
59
67
  };
60
68
 
61
- const queryButton = ( name ) => {
69
+ const queryButton = ( name: string | RegExp ) => {
62
70
  return screen.queryByRole( 'button', { name } );
63
71
  };
64
72
 
65
73
  const getSliderInput = () => {
66
- return screen.getByRole( 'slider', { name: 'Border width' } );
74
+ return screen.getByRole< HTMLInputElement >( 'slider', {
75
+ name: 'Border width',
76
+ } );
67
77
  };
68
78
 
69
79
  const getWidthInput = () => {
70
- return screen.getByRole( 'spinbutton', { name: 'Border width' } );
80
+ return screen.getByRole< HTMLInputElement >( 'spinbutton', {
81
+ name: 'Border width',
82
+ } );
71
83
  };
72
84
 
73
- function TestBorderControl( restProps ) {
85
+ function TestBorderControl( restProps: BorderControlProps ) {
74
86
  return <BorderControl { ...restProps } />;
75
87
  }
76
88
 
@@ -80,7 +92,7 @@ describe( 'BorderControl', () => {
80
92
  const props = createProps();
81
93
  render( <TestBorderControl { ...props } /> );
82
94
 
83
- const label = screen.getByText( props.label );
95
+ const label = screen.getByText( props.label! );
84
96
  const colorButton = screen.getByLabelText( toggleLabelRegex );
85
97
  const widthInput = getWidthInput();
86
98
  const unitSelect = screen.getByRole( 'combobox', {
@@ -100,7 +112,7 @@ describe( 'BorderControl', () => {
100
112
  it( 'should hide label', () => {
101
113
  const props = createProps( { hideLabelFromVision: true } );
102
114
  render( <TestBorderControl { ...props } /> );
103
- const label = screen.getByText( props.label );
115
+ const label = screen.getByText( props.label! );
104
116
 
105
117
  // As visually hidden labels are still included in the document
106
118
  // and do not have `display: none` styling, we can't rely on
@@ -128,7 +140,7 @@ describe( 'BorderControl', () => {
128
140
  } );
129
141
 
130
142
  describe( 'color indicator inline styles', () => {
131
- const getIndicatorWrapper = ( border ) => {
143
+ const getIndicatorWrapper = ( border: Border ) => {
132
144
  render(
133
145
  <TestBorderControl
134
146
  { ...createProps( { value: border } ) }
@@ -142,16 +154,21 @@ describe( 'BorderControl', () => {
142
154
  return toggleButton.firstElementChild;
143
155
  };
144
156
 
157
+ /* eslint-disable jest-dom/prefer-to-have-style -- These jsdom tests check normalized inline style values without browser layout. */
145
158
  it( 'should fall back to gray-300 when a style is set without a color', () => {
146
159
  const indicatorWrapper = getIndicatorWrapper( {
147
160
  style: 'solid',
148
161
  color: '',
149
162
  } );
163
+ const expectedStyle = document.createElement( 'div' ).style;
164
+ expectedStyle.borderColor = COLORS.gray[ 300 ];
150
165
 
151
- expect( indicatorWrapper ).toHaveStyle( {
152
- borderStyle: 'solid',
153
- borderColor: COLORS.gray[ 300 ],
154
- } );
166
+ expect(
167
+ ( indicatorWrapper as HTMLElement ).style.borderStyle
168
+ ).toBe( 'solid' );
169
+ expect(
170
+ ( indicatorWrapper as HTMLElement ).style.borderColor
171
+ ).toBe( expectedStyle.borderColor );
155
172
  } );
156
173
 
157
174
  it( 'should pass CSS-wide values through to border-style and border-color', () => {
@@ -160,10 +177,12 @@ describe( 'BorderControl', () => {
160
177
  color: 'inherit',
161
178
  } );
162
179
 
163
- expect( indicatorWrapper ).toHaveStyle( {
164
- borderStyle: 'inherit',
165
- borderColor: 'inherit',
166
- } );
180
+ expect(
181
+ ( indicatorWrapper as HTMLElement ).style.borderStyle
182
+ ).toBe( 'inherit' );
183
+ expect(
184
+ ( indicatorWrapper as HTMLElement ).style.borderColor
185
+ ).toBe( 'inherit' );
167
186
  } );
168
187
 
169
188
  it( 'should preview a `none` style as solid without applying a color', () => {
@@ -171,14 +190,15 @@ describe( 'BorderControl', () => {
171
190
  style: 'none',
172
191
  } );
173
192
 
174
- expect( indicatorWrapper ).toHaveStyle( {
175
- borderStyle: 'solid',
176
- } );
193
+ expect(
194
+ ( indicatorWrapper as HTMLElement ).style.borderStyle
195
+ ).toBe( 'solid' );
177
196
  expect( indicatorWrapper ).not.toHaveAttribute(
178
197
  'style',
179
198
  expect.stringContaining( 'border-color' )
180
199
  );
181
200
  } );
201
+ /* eslint-enable jest-dom/prefer-to-have-style */
182
202
 
183
203
  it( 'should not apply inline styles when no style is set', () => {
184
204
  const indicatorWrapper = getIndicatorWrapper( {
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it, vi } from 'vitest';
1
2
  import { fireEvent, render, screen } from '@testing-library/react';
2
3
  import userEvent from '@testing-library/user-event';
3
4
  import { useState } from '@wordpress/element';
@@ -5,6 +6,8 @@ import BoxControl from '..';
5
6
  import type { BoxControlProps, BoxControlValue } from '../types';
6
7
  import styles from '../style.module.scss';
7
8
 
9
+ globalThis.wpVitest.mockMatchMedia();
10
+
8
11
  // Since `BoxControlProps` is a the result of type unions, we need to use
9
12
  // a distributive version of the standard `Omit` utility.
10
13
  // See https://stackoverflow.com/a/57103940
@@ -198,7 +201,7 @@ describe( 'BoxControl', () => {
198
201
 
199
202
  it( 'should persist cleared value when focus changes', async () => {
200
203
  const user = userEvent.setup();
201
- const spyChange = jest.fn();
204
+ const spyChange = vi.fn();
202
205
 
203
206
  render(
204
207
  <UncontrolledBoxControl onChange={ ( v ) => spyChange( v ) } />
@@ -473,7 +476,7 @@ describe( 'BoxControl', () => {
473
476
  describe( 'onChange updates', () => {
474
477
  it( 'should call onChange when values contain more than just CSS units', async () => {
475
478
  const user = userEvent.setup();
476
- const onChangeSpy = jest.fn();
479
+ const onChangeSpy = vi.fn();
477
480
 
478
481
  render( <UncontrolledBoxControl onChange={ onChangeSpy } /> );
479
482
 
@@ -502,7 +505,7 @@ describe( 'BoxControl', () => {
502
505
 
503
506
  it( 'should not pass invalid CSS unit only values to onChange', async () => {
504
507
  const user = userEvent.setup();
505
- const setState = jest.fn();
508
+ const setState = vi.fn();
506
509
 
507
510
  render( <UncontrolledBoxControl onChange={ setState } /> );
508
511
 
@@ -368,12 +368,6 @@
368
368
  fill: currentColor;
369
369
  outline: none;
370
370
  flex-shrink: 0;
371
-
372
- // Optimize for high contrast modes.
373
- // See also https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/.
374
- @media (forced-colors: active) {
375
- fill: CanvasText;
376
- }
377
371
  }
378
372
  }
379
373
 
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it, vi } from 'vitest';
1
2
  import { render, screen } from '@testing-library/react';
2
3
  import { press } from '@ariakit/test';
3
4
  import { createRef, forwardRef } from '@wordpress/element';
@@ -6,7 +7,10 @@ import _Button from '..';
6
7
  import Tooltip from '../../tooltip';
7
8
  import cleanupTooltip from '../../tooltip/test/utils';
8
9
 
9
- jest.mock( '../../icon', () => () => <div data-testid="test-icon" /> );
10
+ vi.mock( import( '../../icon' ), async ( importOriginal ) => ( {
11
+ ...( await importOriginal() ),
12
+ default: () => <div data-testid="test-icon" />,
13
+ } ) );
10
14
 
11
15
  const Button = forwardRef(
12
16
  (
@@ -664,7 +668,7 @@ describe( 'Button', () => {
664
668
  } );
665
669
  } );
666
670
 
667
- describe( 'static typing', () => {
671
+ it( 'supports the expected static types', () => {
668
672
  <>
669
673
  <Button href="foo" />
670
674
  { /* @ts-expect-error - `target` requires `href` */ }
@@ -29,7 +29,7 @@ const meta: Meta< typeof CheckboxControl > = {
29
29
  componentStatus: {
30
30
  status: 'recommended',
31
31
  whereUsed: 'global',
32
- notes: 'Will be superseded by [`CheckboxControl`](?path=/docs/design-system-components-form-primitives-checkbox--docs) in `@wordpress/ui`, but continue using for now.',
32
+ notes: 'Will be superseded by [`CheckboxControl`](?path=/docs/design-system-components-form-checkboxcontrol--docs) in `@wordpress/ui`, but continue using for now.',
33
33
  },
34
34
  },
35
35
  };
@@ -77,7 +77,7 @@ svg.components-checkbox-control__checked,
77
77
  svg.components-checkbox-control__indeterminate {
78
78
  --checkmark-size: var(--checkbox-input-size);
79
79
 
80
- fill: $white;
80
+ color: $white;
81
81
  cursor: var(--wpds-cursor-control);
82
82
  position: absolute;
83
83
  left: 50%;
@@ -96,7 +96,7 @@ svg.components-checkbox-control__indeterminate {
96
96
  .components-checkbox-control:has(:disabled) {
97
97
  svg.components-checkbox-control__checked,
98
98
  svg.components-checkbox-control__indeterminate {
99
- fill: $components-color-gray-400;
99
+ color: $components-color-gray-400;
100
100
  }
101
101
  }
102
102
 
@@ -1,11 +1,11 @@
1
- // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`CheckboxControl Basic rendering should render the indeterminate icon when in the indeterminate state 1`] = `
3
+ exports[`CheckboxControl > Basic rendering > should render the indeterminate icon when in the indeterminate state 1`] = `
4
4
  Snapshot Diff:
5
5
  - First value
6
6
  + Second value
7
7
 
8
- @@ -14,14 +14,29 @@
8
+ @@ -14,14 +14,32 @@
9
9
  <span
10
10
  class="components-checkbox-control__input-container"
11
11
  >
@@ -15,21 +15,24 @@ Snapshot Diff:
15
15
  + id="inspector-checkbox-control-7"
16
16
  type="checkbox"
17
17
  value="1"
18
- />
18
+ + />
19
19
  + <svg
20
20
  + aria-hidden="true"
21
21
  + class="components-checkbox-control__indeterminate"
22
- + fill="currentColor"
23
22
  + focusable="false"
24
23
  + height="24"
25
24
  + role="presentation"
25
+ + stroke="currentColor"
26
+ + stroke-width="1.5"
27
+ + style="fill: none;"
26
28
  + viewBox="0 0 24 24"
27
29
  + width="24"
28
30
  + xmlns="http://www.w3.org/2000/svg"
29
31
  + >
30
32
  + <path
31
- + d="M7 11.5h10V13H7z"
32
- + />
33
+ + d="M7 12H17"
34
+ + vector-effect="non-scaling-stroke"
35
+ />
33
36
  + </svg>
34
37
  </span>
35
38
  </div>
@@ -1,9 +1,12 @@
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';
3
4
  import { useState } from '@wordpress/element';
4
5
  import BaseCheckboxControl from '..';
5
6
  import type { CheckboxControlProps } from '../types';
6
7
 
8
+ globalThis.wpVitest.mockMatchMedia();
9
+
7
10
  const noop = () => {};
8
11
 
9
12
  const getInput = () => screen.getByRole( 'checkbox' ) as HTMLInputElement;
@@ -87,7 +90,7 @@ describe( 'CheckboxControl', () => {
87
90
  const user = userEvent.setup();
88
91
 
89
92
  let state = false;
90
- const setState = jest.fn(
93
+ const setState = vi.fn(
91
94
  ( nextState: boolean ) => ( state = nextState )
92
95
  );
93
96
 
@@ -1,3 +1,4 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
1
2
  import { render, screen } from '@testing-library/react';
2
3
  import { press } from '@ariakit/test';
3
4
  import { logged } from '@wordpress/deprecated';