@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,13 @@
1
+ import {
2
+ afterEach,
3
+ beforeEach,
4
+ describe,
5
+ expect,
6
+ it,
7
+ vi,
8
+ type Mock,
9
+ } from 'vitest';
10
+ import { useState } from '@wordpress/element';
1
11
  import { render, screen, within } from '@testing-library/react';
2
12
  import userEvent from '@testing-library/user-event';
3
13
  import { ToolsPanel, ToolsPanelContext, ToolsPanelItem } from '../';
@@ -9,8 +19,10 @@ import type {
9
19
  ResetAllFilter,
10
20
  } from '../types';
11
21
 
22
+ globalThis.wpVitest.mockMatchMedia();
23
+
12
24
  const { Fill: ToolsPanelItems, Slot } = createSlotFill( 'ToolsPanelSlot' );
13
- const resetAll = jest.fn();
25
+ const resetAll = vi.fn();
14
26
  const noop = () => undefined;
15
27
  const gridContextValue = {
16
28
  Grid: {
@@ -30,51 +42,53 @@ const defaultProps = {
30
42
  // Default props for an enabled control to be rendered within panel.
31
43
  let controlValue: ControlValue = true;
32
44
  const controlProps = {
33
- hasValue: jest.fn().mockImplementation( () => {
45
+ hasValue: vi.fn().mockImplementation( () => {
34
46
  return !! controlValue;
35
47
  } ),
36
48
  label: 'Example',
37
- onDeselect: jest.fn().mockImplementation( () => {
49
+ onDeselect: vi.fn().mockImplementation( () => {
38
50
  controlValue = undefined;
39
51
  } ),
40
- onSelect: jest.fn(),
52
+ onSelect: vi.fn(),
53
+ onShownChange: vi.fn(),
41
54
  };
42
55
 
43
56
  // Default props without a value for an alternate control to be rendered within
44
57
  // the panel.
45
58
  let altControlValue: ControlValue = false;
46
59
  const altControlProps = {
47
- hasValue: jest.fn().mockImplementation( () => {
60
+ hasValue: vi.fn().mockImplementation( () => {
48
61
  return !! altControlValue;
49
62
  } ),
50
63
  label: 'Alt',
51
- onDeselect: jest.fn(),
52
- onSelect: jest.fn(),
64
+ onDeselect: vi.fn(),
65
+ onSelect: vi.fn(),
66
+ onShownChange: vi.fn(),
53
67
  };
54
68
 
55
69
  // Default props for wrapped or grouped panel items.
56
70
  let nestedControlValue: ControlValue = true;
57
71
  const nestedControlProps = {
58
- hasValue: jest.fn().mockImplementation( () => {
72
+ hasValue: vi.fn().mockImplementation( () => {
59
73
  return !! nestedControlValue;
60
74
  } ),
61
75
  label: 'Nested Control 1',
62
- onDeselect: jest.fn().mockImplementation( () => {
76
+ onDeselect: vi.fn().mockImplementation( () => {
63
77
  nestedControlValue = undefined;
64
78
  } ),
65
- onSelect: jest.fn(),
79
+ onSelect: vi.fn(),
66
80
  isShownByDefault: true,
67
81
  };
68
82
 
69
83
  // Alternative props for wrapped or grouped panel items.
70
84
  const altNestedControlValue: ControlValue = false;
71
85
  const altNestedControlProps = {
72
- hasValue: jest.fn().mockImplementation( () => {
86
+ hasValue: vi.fn().mockImplementation( () => {
73
87
  return !! altNestedControlValue;
74
88
  } ),
75
89
  label: 'Nested Control 2',
76
- onDeselect: jest.fn(),
77
- onSelect: jest.fn(),
90
+ onDeselect: vi.fn(),
91
+ onSelect: vi.fn(),
78
92
  };
79
93
 
80
94
  // Simple custom component grouping panel items. Used to test panel item
@@ -106,10 +120,10 @@ const panelContext: ToolsPanelContextType = {
106
120
  hasMenuItems: false,
107
121
  isResetting: false,
108
122
  shouldRenderPlaceholderItems: false,
109
- registerPanelItem: jest.fn(),
110
- deregisterPanelItem: jest.fn(),
111
- registerResetAllFilter: jest.fn(),
112
- deregisterResetAllFilter: jest.fn(),
123
+ registerPanelItem: vi.fn(),
124
+ deregisterPanelItem: vi.fn(),
125
+ registerResetAllFilter: vi.fn(),
126
+ deregisterResetAllFilter: vi.fn(),
113
127
  flagItemCustomization: noop,
114
128
  areAllOptionalControlsHidden: true,
115
129
  };
@@ -196,9 +210,27 @@ const selectMenuItem = async ( label: string ) => {
196
210
  };
197
211
 
198
212
  describe( 'ToolsPanel', () => {
213
+ beforeEach( () => {
214
+ controlProps.hasValue.mockImplementation( () => !! controlValue );
215
+ controlProps.onDeselect.mockImplementation( () => {
216
+ controlValue = undefined;
217
+ } );
218
+ altControlProps.hasValue.mockImplementation( () => !! altControlValue );
219
+ nestedControlProps.hasValue.mockImplementation(
220
+ () => !! nestedControlValue
221
+ );
222
+ nestedControlProps.onDeselect.mockImplementation( () => {
223
+ nestedControlValue = undefined;
224
+ } );
225
+ altNestedControlProps.hasValue.mockImplementation(
226
+ () => !! altNestedControlValue
227
+ );
228
+ } );
229
+
199
230
  afterEach( () => {
200
231
  controlValue = true;
201
232
  altControlValue = false;
233
+ nestedControlValue = true;
202
234
  } );
203
235
 
204
236
  describe( 'basic rendering', () => {
@@ -425,8 +457,8 @@ describe( 'ToolsPanel', () => {
425
457
  attributes: { value: toolsPanelItemValue },
426
458
  hasValue: () => !! toolsPanelItemValue,
427
459
  label: 'Alt',
428
- onDeselect: jest.fn(),
429
- onSelect: jest.fn(),
460
+ onDeselect: vi.fn(),
461
+ onSelect: vi.fn(),
430
462
  };
431
463
 
432
464
  return (
@@ -461,8 +493,8 @@ describe( 'ToolsPanel', () => {
461
493
  attributes: { value: toolsPanelItemValue },
462
494
  hasValue: () => !! toolsPanelItemValue,
463
495
  label: 'Alt',
464
- onDeselect: jest.fn(),
465
- onSelect: jest.fn(),
496
+ onDeselect: vi.fn(),
497
+ onSelect: vi.fn(),
466
498
  };
467
499
 
468
500
  // The null panelId below simulates the panel prop when there
@@ -488,6 +520,156 @@ describe( 'ToolsPanel', () => {
488
520
  expect( controlRerendered ).toBeInTheDocument();
489
521
  } );
490
522
 
523
+ it( 'should not render optional item without a value by default', () => {
524
+ render(
525
+ <ToolsPanel { ...defaultProps }>
526
+ <ToolsPanelItem { ...altControlProps }>
527
+ <div>Optional control</div>
528
+ </ToolsPanelItem>
529
+ </ToolsPanel>
530
+ );
531
+
532
+ expect(
533
+ screen.queryByText( 'Optional control' )
534
+ ).not.toBeInTheDocument();
535
+ } );
536
+
537
+ it( 'should render optional item on first render when defaultShown is true', () => {
538
+ render(
539
+ <ToolsPanel { ...defaultProps }>
540
+ <ToolsPanelItem { ...altControlProps } defaultShown>
541
+ <div>Optional control</div>
542
+ </ToolsPanelItem>
543
+ </ToolsPanel>
544
+ );
545
+
546
+ expect(
547
+ screen.getByText( 'Optional control' )
548
+ ).toBeInTheDocument();
549
+ } );
550
+
551
+ it( 'should render optional item with a value even when defaultShown is false', () => {
552
+ altControlValue = true;
553
+
554
+ render(
555
+ <ToolsPanel { ...defaultProps }>
556
+ <ToolsPanelItem
557
+ { ...altControlProps }
558
+ defaultShown={ false }
559
+ >
560
+ <div>Optional control</div>
561
+ </ToolsPanelItem>
562
+ </ToolsPanel>
563
+ );
564
+
565
+ expect(
566
+ screen.getByText( 'Optional control' )
567
+ ).toBeInTheDocument();
568
+ } );
569
+
570
+ // `defaultShown` only seeds the item's initial visibility. A change
571
+ // after mount must leave the item as it is, and must not be reported
572
+ // as though the user had used the menu.
573
+ describe( 'changing defaultShown after mount', () => {
574
+ const onDeselect = vi.fn();
575
+ const onSelect = vi.fn();
576
+ const onShownChange = vi.fn();
577
+
578
+ const ToolsPanelOptional = ( {
579
+ defaultShown,
580
+ }: {
581
+ defaultShown: boolean;
582
+ } ) => (
583
+ <ToolsPanel { ...defaultProps }>
584
+ <ToolsPanelItem
585
+ defaultShown={ defaultShown }
586
+ hasValue={ () => false }
587
+ label="Alt"
588
+ onDeselect={ onDeselect }
589
+ onSelect={ onSelect }
590
+ onShownChange={ onShownChange }
591
+ >
592
+ <div>Optional control</div>
593
+ </ToolsPanelItem>
594
+ </ToolsPanel>
595
+ );
596
+
597
+ beforeEach( () => {
598
+ vi.clearAllMocks();
599
+ } );
600
+
601
+ it( 'should keep a hidden item hidden when it changes to true', () => {
602
+ const { rerender } = render(
603
+ <ToolsPanelOptional defaultShown={ false } />
604
+ );
605
+
606
+ rerender( <ToolsPanelOptional defaultShown /> );
607
+
608
+ expect(
609
+ screen.queryByText( 'Optional control' )
610
+ ).not.toBeInTheDocument();
611
+ expect( onShownChange ).not.toHaveBeenCalled();
612
+ expect( onSelect ).not.toHaveBeenCalled();
613
+ expect( onDeselect ).not.toHaveBeenCalled();
614
+ } );
615
+
616
+ it( 'should keep a shown item visible when it changes to false', () => {
617
+ const { rerender } = render(
618
+ <ToolsPanelOptional defaultShown />
619
+ );
620
+
621
+ rerender( <ToolsPanelOptional defaultShown={ false } /> );
622
+
623
+ expect(
624
+ screen.getByText( 'Optional control' )
625
+ ).toBeInTheDocument();
626
+ expect( onShownChange ).not.toHaveBeenCalled();
627
+ expect( onSelect ).not.toHaveBeenCalled();
628
+ expect( onDeselect ).not.toHaveBeenCalled();
629
+ } );
630
+ } );
631
+
632
+ it( 'should keep an item the user hid hidden when another item registers', async () => {
633
+ // Registering an item regenerates the panel's menu state. An item
634
+ // the user hid is stored as `false`, which must be preserved
635
+ // rather than treated as unregistered and reseeded from
636
+ // `defaultShown`.
637
+ const TestPanel = ( { showExtra }: { showExtra: boolean } ) => (
638
+ <ToolsPanel { ...defaultProps }>
639
+ <ToolsPanelItem { ...altControlProps } defaultShown>
640
+ <div>Optional control</div>
641
+ </ToolsPanelItem>
642
+ { showExtra && (
643
+ <ToolsPanelItem
644
+ hasValue={ () => false }
645
+ label="Extra"
646
+ onDeselect={ noop }
647
+ onSelect={ noop }
648
+ >
649
+ <div>Extra control</div>
650
+ </ToolsPanelItem>
651
+ ) }
652
+ </ToolsPanel>
653
+ );
654
+
655
+ const { rerender } = render( <TestPanel showExtra={ false } /> );
656
+ expect(
657
+ screen.getByText( 'Optional control' )
658
+ ).toBeInTheDocument();
659
+
660
+ await openDropdownMenu();
661
+ await selectMenuItem( altControlProps.label );
662
+ expect(
663
+ screen.queryByText( 'Optional control' )
664
+ ).not.toBeInTheDocument();
665
+
666
+ rerender( <TestPanel showExtra /> );
667
+
668
+ expect(
669
+ screen.queryByText( 'Optional control' )
670
+ ).not.toBeInTheDocument();
671
+ } );
672
+
491
673
  it( 'should continue to render shown by default item after it is toggled off via menu item', async () => {
492
674
  render(
493
675
  <ToolsPanel { ...defaultProps }>
@@ -552,12 +734,12 @@ describe( 'ToolsPanel', () => {
552
734
  it( 'should render default controls with conditional isShownByDefault', async () => {
553
735
  const linkedControlValue = false;
554
736
  const linkedControlProps = {
555
- hasValue: jest.fn().mockImplementation( () => {
737
+ hasValue: vi.fn().mockImplementation( () => {
556
738
  return !! linkedControlValue;
557
739
  } ),
558
740
  label: 'Linked',
559
- onDeselect: jest.fn(),
560
- onSelect: jest.fn(),
741
+ onDeselect: vi.fn(),
742
+ onSelect: vi.fn(),
561
743
  };
562
744
 
563
745
  const TestPanel = () => (
@@ -624,12 +806,12 @@ describe( 'ToolsPanel', () => {
624
806
  it( 'should handle conditionally rendered default control', async () => {
625
807
  const conditionalControlValue = false;
626
808
  const conditionalControlProps = {
627
- hasValue: jest.fn().mockImplementation( () => {
809
+ hasValue: vi.fn().mockImplementation( () => {
628
810
  return !! conditionalControlValue;
629
811
  } ),
630
812
  label: 'Conditional',
631
- onDeselect: jest.fn(),
632
- onSelect: jest.fn(),
813
+ onDeselect: vi.fn(),
814
+ onSelect: vi.fn(),
633
815
  };
634
816
 
635
817
  const TestPanel = () => (
@@ -687,7 +869,7 @@ describe( 'ToolsPanel', () => {
687
869
 
688
870
  describe( 'registration of panel items', () => {
689
871
  beforeEach( () => {
690
- jest.clearAllMocks();
872
+ vi.clearAllMocks();
691
873
  } );
692
874
 
693
875
  it( 'should register and deregister items when panelId changes', () => {
@@ -734,7 +916,8 @@ describe( 'ToolsPanel', () => {
734
916
  expect( context.registerPanelItem ).toHaveBeenCalledTimes( 1 );
735
917
  // deregisterPanelItem is called, given that we have switched panels.
736
918
  expect( context.deregisterPanelItem ).toHaveBeenCalledWith(
737
- altControlProps.label
919
+ altControlProps.label,
920
+ expect.objectContaining( { label: altControlProps.label } )
738
921
  );
739
922
 
740
923
  // Simulate switching back to the original panelId, e.g. by selecting
@@ -757,6 +940,72 @@ describe( 'ToolsPanel', () => {
757
940
  expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 1 );
758
941
  } );
759
942
 
943
+ it( 'should register with the latest defaultShown when panelId changes', () => {
944
+ // A consumer that persists the user's choice feeds it back in
945
+ // through `defaultShown`. A change to that prop must not
946
+ // re-register the item on its own, but a re-registration caused by
947
+ // something else has to seed from the saved preference rather than
948
+ // the value the item mounted with.
949
+ const context: ToolsPanelContextType = {
950
+ ...panelContext,
951
+ registerPanelItem: vi.fn(),
952
+ deregisterPanelItem: vi.fn(),
953
+ };
954
+ const TestPanel = ( {
955
+ defaultShown,
956
+ }: {
957
+ defaultShown: boolean;
958
+ } ) => (
959
+ <ToolsPanelContext.Provider value={ context }>
960
+ <ToolsPanelItem
961
+ { ...altControlProps }
962
+ defaultShown={ defaultShown }
963
+ panelId="1234"
964
+ >
965
+ <div>Item</div>
966
+ </ToolsPanelItem>
967
+ </ToolsPanelContext.Provider>
968
+ );
969
+
970
+ const { rerender } = render( <TestPanel defaultShown={ false } /> );
971
+
972
+ expect( context.registerPanelItem ).toHaveBeenCalledWith(
973
+ expect.objectContaining( { defaultShown: false } )
974
+ );
975
+
976
+ // Let registration settle, so that any further calls can only
977
+ // have been caused by the changes made below.
978
+ rerender( <TestPanel defaultShown={ false } /> );
979
+ const settledCalls = ( context.registerPanelItem as Mock ).mock
980
+ .calls.length;
981
+
982
+ // The user shows the item and the consumer saves that preference.
983
+ // The updated prop alone must not re-register the item, which
984
+ // would discard the visibility the user chose.
985
+ rerender( <TestPanel defaultShown /> );
986
+
987
+ expect( context.registerPanelItem ).toHaveBeenCalledTimes(
988
+ settledCalls
989
+ );
990
+
991
+ // Simulate switching block selection away and back again, which
992
+ // deregisters and re-registers the item.
993
+ context.panelId = '4321';
994
+ rerender( <TestPanel defaultShown /> );
995
+ context.panelId = '1234';
996
+ rerender( <TestPanel defaultShown /> );
997
+
998
+ expect( context.deregisterPanelItem ).toHaveBeenCalledWith(
999
+ altControlProps.label,
1000
+ expect.objectContaining( { label: altControlProps.label } )
1001
+ );
1002
+ // The item registers again with the saved preference rather than
1003
+ // the value it mounted with.
1004
+ expect( context.registerPanelItem ).toHaveBeenLastCalledWith(
1005
+ expect.objectContaining( { defaultShown: true } )
1006
+ );
1007
+ } );
1008
+
760
1009
  it( 'should register items when ToolsPanel panelId is null', () => {
761
1010
  // This test simulates when a panel spans multiple block selections.
762
1011
  // Multi-selection means a panel can't have a single id to match
@@ -802,29 +1051,30 @@ describe( 'ToolsPanel', () => {
802
1051
  expect( context.deregisterPanelItem ).not.toHaveBeenCalled();
803
1052
 
804
1053
  // Simulate another multi-selection where the panelId is `null`.
805
- // Item should re-register itself after it deregistered as the
806
- // multi-selection occurred.
1054
+ // Still matches the panel, so the registration stands rather than
1055
+ // churning through a deregister/register pair.
807
1056
  context.panelId = null;
808
1057
  rerender( <TestPanel /> );
809
- expect( context.registerPanelItem ).toHaveBeenCalledTimes( 2 );
810
- expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 1 );
1058
+ expect( context.registerPanelItem ).toHaveBeenCalledTimes( 1 );
1059
+ expect( context.deregisterPanelItem ).not.toHaveBeenCalled();
811
1060
 
812
1061
  // Simulate a change in panel e.g. back to a single block selection
813
1062
  // Where the item's panelId is not a match.
814
1063
  context.panelId = '4321';
815
1064
  rerender( <TestPanel /> );
816
1065
 
817
- // As the item no longer matches the panelId it should not have
818
- // registered again but instead deregistered.
1066
+ // No longer matches, so it has already deregistered. Unmounting
1067
+ // must not deregister again.
1068
+ expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 1 );
819
1069
  unmount();
820
- expect( context.registerPanelItem ).toHaveBeenCalledTimes( 2 );
821
- expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 2 );
1070
+ expect( context.registerPanelItem ).toHaveBeenCalledTimes( 1 );
1071
+ expect( context.deregisterPanelItem ).toHaveBeenCalledTimes( 1 );
822
1072
  } );
823
1073
  } );
824
1074
 
825
1075
  describe( 'callbacks on menu item selection', () => {
826
1076
  beforeEach( () => {
827
- jest.clearAllMocks();
1077
+ vi.clearAllMocks();
828
1078
  } );
829
1079
 
830
1080
  it( 'should call onDeselect callback when menu item is toggled off', async () => {
@@ -878,6 +1128,126 @@ describe( 'ToolsPanel', () => {
878
1128
  } );
879
1129
  } );
880
1130
 
1131
+ describe( 'shown change callback', () => {
1132
+ beforeEach( () => {
1133
+ vi.clearAllMocks();
1134
+ } );
1135
+
1136
+ it( 'should call onShownChange with true when an optional item is shown via the menu', async () => {
1137
+ renderPanel();
1138
+
1139
+ await openDropdownMenu();
1140
+ await selectMenuItem( altControlProps.label );
1141
+
1142
+ expect( altControlProps.onShownChange ).toHaveBeenCalledTimes( 1 );
1143
+ expect( altControlProps.onShownChange ).toHaveBeenCalledWith(
1144
+ true
1145
+ );
1146
+ } );
1147
+
1148
+ it( 'should call onShownChange with false when an optional item without a value is hidden via the menu', async () => {
1149
+ renderPanel();
1150
+
1151
+ await openDropdownMenu();
1152
+ await selectMenuItem( altControlProps.label );
1153
+ await selectMenuItem( altControlProps.label );
1154
+
1155
+ expect( altControlProps.onShownChange ).toHaveBeenCalledTimes( 2 );
1156
+ expect( altControlProps.onShownChange ).toHaveBeenLastCalledWith(
1157
+ false
1158
+ );
1159
+ // The item never had a value, so there was nothing to reset.
1160
+ expect( altControlProps.onDeselect ).not.toHaveBeenCalled();
1161
+ } );
1162
+
1163
+ it( 'should call both onShownChange and onDeselect when an optional item with a value is hidden via the menu', async () => {
1164
+ renderPanel();
1165
+
1166
+ await openDropdownMenu();
1167
+ await selectMenuItem( controlProps.label );
1168
+
1169
+ expect( controlProps.onShownChange ).toHaveBeenCalledTimes( 1 );
1170
+ expect( controlProps.onShownChange ).toHaveBeenCalledWith( false );
1171
+ expect( controlProps.onDeselect ).toHaveBeenCalledTimes( 1 );
1172
+ } );
1173
+
1174
+ it( 'should not call onShownChange for default items', async () => {
1175
+ render(
1176
+ <ToolsPanel { ...defaultProps }>
1177
+ <ToolsPanelItem { ...controlProps } isShownByDefault>
1178
+ <div>Example control</div>
1179
+ </ToolsPanelItem>
1180
+ </ToolsPanel>
1181
+ );
1182
+
1183
+ await openDropdownMenu();
1184
+ await selectMenuItem( controlProps.label );
1185
+
1186
+ // Default items stay visible when toggled off; the action resets
1187
+ // them rather than hiding them.
1188
+ expect( controlProps.onDeselect ).toHaveBeenCalledTimes( 1 );
1189
+ expect( controlProps.onShownChange ).not.toHaveBeenCalled();
1190
+ } );
1191
+
1192
+ it( 'should not call onShownChange when items are hidden by Reset all', async () => {
1193
+ renderPanel();
1194
+
1195
+ await openDropdownMenu();
1196
+ await selectMenuItem( 'Reset all' );
1197
+
1198
+ expect( controlProps.onShownChange ).not.toHaveBeenCalled();
1199
+ expect( altControlProps.onShownChange ).not.toHaveBeenCalled();
1200
+ } );
1201
+
1202
+ it( 'should not call onShownChange when the value changes programmatically', () => {
1203
+ const onShownChange = vi.fn();
1204
+ const ToolsPanelOptional = ( { value }: { value?: number } ) => (
1205
+ <ToolsPanel { ...defaultProps } panelId="1234">
1206
+ <ToolsPanelItem
1207
+ hasValue={ () => !! value }
1208
+ label="Alt"
1209
+ onShownChange={ onShownChange }
1210
+ panelId="1234"
1211
+ >
1212
+ <div>Optional control</div>
1213
+ </ToolsPanelItem>
1214
+ </ToolsPanel>
1215
+ );
1216
+
1217
+ const { rerender } = render( <ToolsPanelOptional /> );
1218
+ expect(
1219
+ screen.queryByText( 'Optional control' )
1220
+ ).not.toBeInTheDocument();
1221
+
1222
+ // Gaining a value shows the item, but that is not a menu action.
1223
+ rerender( <ToolsPanelOptional value={ 100 } /> );
1224
+ expect(
1225
+ screen.getByText( 'Optional control' )
1226
+ ).toBeInTheDocument();
1227
+
1228
+ // Losing it again is not a menu action either.
1229
+ rerender( <ToolsPanelOptional /> );
1230
+
1231
+ expect( onShownChange ).not.toHaveBeenCalled();
1232
+ } );
1233
+
1234
+ it( 'should not call any callback when an item is mounted with defaultShown', () => {
1235
+ render(
1236
+ <ToolsPanel { ...defaultProps }>
1237
+ <ToolsPanelItem { ...altControlProps } defaultShown>
1238
+ <div>Alt control</div>
1239
+ </ToolsPanelItem>
1240
+ </ToolsPanel>
1241
+ );
1242
+
1243
+ // Registering an item as shown is not a menu action, so none of
1244
+ // the item's callbacks should fire.
1245
+ expect( screen.getByText( 'Alt control' ) ).toBeInTheDocument();
1246
+ expect( altControlProps.onShownChange ).not.toHaveBeenCalled();
1247
+ expect( altControlProps.onSelect ).not.toHaveBeenCalled();
1248
+ } );
1249
+ } );
1250
+
881
1251
  describe( 'grouped panel items within custom components', () => {
882
1252
  it( 'should render grouped items correctly', () => {
883
1253
  renderGroupedItemsInPanel();
@@ -952,7 +1322,7 @@ describe( 'ToolsPanel', () => {
952
1322
 
953
1323
  describe( 'rendering via SlotFills', () => {
954
1324
  beforeEach( () => {
955
- jest.clearAllMocks();
1325
+ vi.clearAllMocks();
956
1326
  } );
957
1327
 
958
1328
  it( 'should maintain visual order of controls when toggled on and off', async () => {
@@ -1153,6 +1523,103 @@ describe( 'ToolsPanel', () => {
1153
1523
  expect( altControlProps.onDeselect ).not.toHaveBeenCalled();
1154
1524
  } );
1155
1525
 
1526
+ it( 'should not contain menu items for an item belonging to another panel', async () => {
1527
+ // A fill can mount after the panel it is rendered into has already
1528
+ // settled. An item whose `panelId` doesn't match must stay out of
1529
+ // that panel's menu entirely, including out of the value flagging
1530
+ // that populates it.
1531
+ const Panel = ( { withForeign }: { withForeign: boolean } ) => (
1532
+ <ToolsPanel { ...defaultProps } panelId="1234">
1533
+ <ToolsPanelItem
1534
+ label="Mine"
1535
+ panelId="1234"
1536
+ isShownByDefault
1537
+ hasValue={ () => false }
1538
+ >
1539
+ <div>My control</div>
1540
+ </ToolsPanelItem>
1541
+ { withForeign && (
1542
+ <ToolsPanelItem
1543
+ label="Foreign"
1544
+ panelId="9999"
1545
+ hasValue={ () => true }
1546
+ >
1547
+ <div>Foreign control</div>
1548
+ </ToolsPanelItem>
1549
+ ) }
1550
+ </ToolsPanel>
1551
+ );
1552
+
1553
+ // Let the panel settle with only its own item registered, then
1554
+ // bring in an item that belongs to a different panel.
1555
+ const { rerender } = render( <Panel withForeign={ false } /> );
1556
+ rerender( <Panel withForeign /> );
1557
+
1558
+ await openDropdownMenu();
1559
+
1560
+ expect(
1561
+ screen.queryByRole( 'menuitemcheckbox', { name: /Foreign/i } )
1562
+ ).not.toBeInTheDocument();
1563
+ } );
1564
+
1565
+ it( "should not let a replacement item inherit the outgoing one's state", async () => {
1566
+ // Two blocks can each contribute a control of the same name. When
1567
+ // selection moves between them, the incoming item starts from its
1568
+ // own value rather than the visibility the user chose for the one
1569
+ // it replaced.
1570
+ const SameLabelInTwoPanels = ( {
1571
+ panelId,
1572
+ }: Pick<
1573
+ React.ComponentProps< typeof ToolsPanelItem >,
1574
+ 'panelId'
1575
+ > ) => (
1576
+ <SlotFillProvider>
1577
+ <ToolsPanelItems>
1578
+ <ToolsPanelItem
1579
+ label="Shared"
1580
+ panelId="1234"
1581
+ hasValue={ () => false }
1582
+ >
1583
+ <div>Item 1</div>
1584
+ </ToolsPanelItem>
1585
+ </ToolsPanelItems>
1586
+ <ToolsPanelItems>
1587
+ <ToolsPanelItem
1588
+ label="Shared"
1589
+ panelId="9999"
1590
+ hasValue={ () => false }
1591
+ >
1592
+ <div>Item 2</div>
1593
+ </ToolsPanelItem>
1594
+ </ToolsPanelItems>
1595
+ <ToolsPanel { ...defaultProps } panelId={ panelId }>
1596
+ <Slot />
1597
+ </ToolsPanel>
1598
+ </SlotFillProvider>
1599
+ );
1600
+
1601
+ const { rerender } = render(
1602
+ <SameLabelInTwoPanels panelId="1234" />
1603
+ );
1604
+
1605
+ // Show the first block's control.
1606
+ await openDropdownMenu();
1607
+ await selectMenuItem( 'Shared' );
1608
+ expect( screen.getByText( 'Item 1' ) ).toBeInTheDocument();
1609
+
1610
+ // Move to the other block. Its control has no value and was never
1611
+ // shown, so it stays hidden.
1612
+ // The menu stays open across the rerender.
1613
+ rerender( <SameLabelInTwoPanels panelId="9999" /> );
1614
+
1615
+ expect(
1616
+ await screen.findByRole( 'menuitemcheckbox', {
1617
+ name: 'Show Shared',
1618
+ } )
1619
+ ).toBeInTheDocument();
1620
+ expect( screen.queryByText( 'Item 2' ) ).not.toBeInTheDocument();
1621
+ } );
1622
+
1156
1623
  it( 'should not contain orphaned menu items when panelId changes', async () => {
1157
1624
  // As fills and the panel can update independently this aims to
1158
1625
  // test that no orphaned items appear registered in the panel menu.
@@ -1216,23 +1683,23 @@ describe( 'ToolsPanel', () => {
1216
1683
  describe( 'panel header icon toggle', () => {
1217
1684
  const defaultControlsValue = false;
1218
1685
  const defaultControls = {
1219
- hasValue: jest.fn().mockImplementation( () => {
1686
+ hasValue: vi.fn().mockImplementation( () => {
1220
1687
  return !! defaultControlsValue;
1221
1688
  } ),
1222
1689
  label: 'Default',
1223
- onDeselect: jest.fn(),
1224
- onSelect: jest.fn(),
1690
+ onDeselect: vi.fn(),
1691
+ onSelect: vi.fn(),
1225
1692
  isShownByDefault: true,
1226
1693
  };
1227
1694
 
1228
1695
  const optionalControlsValue = false;
1229
1696
  const optionalControls = {
1230
- hasValue: jest.fn().mockImplementation( () => {
1697
+ hasValue: vi.fn().mockImplementation( () => {
1231
1698
  return !! optionalControlsValue;
1232
1699
  } ),
1233
1700
  label: 'Optional',
1234
- onDeselect: jest.fn(),
1235
- onSelect: jest.fn(),
1701
+ onDeselect: vi.fn(),
1702
+ onSelect: vi.fn(),
1236
1703
  isShownByDefault: false,
1237
1704
  };
1238
1705
 
@@ -1291,9 +1758,48 @@ describe( 'ToolsPanel', () => {
1291
1758
  expect( optionsDisplayedIcon ).not.toHaveAccessibleDescription();
1292
1759
  } );
1293
1760
 
1761
+ it( 'should pass reset all filters that see the latest props', async () => {
1762
+ let received: unknown[] = [];
1763
+ const ChangingFilter = () => {
1764
+ const [ count, setCount ] = useState( 1 );
1765
+ return (
1766
+ <ToolsPanel
1767
+ label="Panel header"
1768
+ resetAll={ ( filters ) => {
1769
+ received = ( filters ?? [] ).map( ( filter ) =>
1770
+ filter()
1771
+ );
1772
+ } }
1773
+ >
1774
+ <ToolsPanelItem
1775
+ label="Filtered"
1776
+ isShownByDefault
1777
+ hasValue={ () => true }
1778
+ resetAllFilter={ () => count }
1779
+ >
1780
+ <button onClick={ () => setCount( 2 ) }>
1781
+ bump
1782
+ </button>
1783
+ </ToolsPanelItem>
1784
+ </ToolsPanel>
1785
+ );
1786
+ };
1787
+
1788
+ const user = userEvent.setup();
1789
+ render( <ChangingFilter /> );
1790
+
1791
+ // The panelId never changes, which is where a filter frozen at
1792
+ // registration goes stale.
1793
+ await user.click( screen.getByText( 'bump' ) );
1794
+ await openDropdownMenu();
1795
+ await selectMenuItem( 'Reset all' );
1796
+
1797
+ expect( received ).toEqual( [ 2 ] );
1798
+ } );
1799
+
1294
1800
  it( 'should not call reset all for different panelIds', async () => {
1295
- const resetItem = jest.fn();
1296
- const resetItemB = jest.fn();
1801
+ const resetItem = vi.fn();
1802
+ const resetItemB = vi.fn();
1297
1803
 
1298
1804
  const children = (
1299
1805
  <>
@@ -1383,6 +1889,48 @@ describe( 'ToolsPanel', () => {
1383
1889
  } );
1384
1890
  } );
1385
1891
 
1892
+ describe( 'reset all with values the reset leaves in place', () => {
1893
+ it( 'should keep a default control resettable when its value survives', async () => {
1894
+ // The value arrives after mount, like block library controls whose
1895
+ // `hasValue` closes over an attribute: false at mount, true once
1896
+ // edited. A value read back from registration time misses it.
1897
+ const GainsAValue = () => {
1898
+ const [ hasVal, setHasVal ] = useState( false );
1899
+ return (
1900
+ <ToolsPanel label="Panel header" resetAll={ () => {} }>
1901
+ <ToolsPanelItem
1902
+ label="Survivor"
1903
+ isShownByDefault
1904
+ hasValue={ () => hasVal }
1905
+ >
1906
+ <button onClick={ () => setHasVal( true ) }>
1907
+ set a value
1908
+ </button>
1909
+ </ToolsPanelItem>
1910
+ </ToolsPanel>
1911
+ );
1912
+ };
1913
+
1914
+ const user = userEvent.setup();
1915
+ render( <GainsAValue /> );
1916
+
1917
+ await user.click( screen.getByText( 'set a value' ) );
1918
+ await openDropdownMenu();
1919
+ await selectMenuItem( 'Reset all' );
1920
+
1921
+ // `resetAll` clears nothing here, so the value is still set and
1922
+ // must stay resettable from both menu entries.
1923
+ expect(
1924
+ await screen.findByRole( 'menuitem', { name: 'Reset all' } )
1925
+ ).toHaveAttribute( 'aria-disabled', 'false' );
1926
+ expect(
1927
+ await screen.findByRole( 'menuitem', {
1928
+ name: 'Reset Survivor',
1929
+ } )
1930
+ ).toBeInTheDocument();
1931
+ } );
1932
+ } );
1933
+
1386
1934
  describe( 'first and last panel items', () => {
1387
1935
  it( 'should apply first/last classes to appropriate items', () => {
1388
1936
  render(