@wordpress/ui 0.9.1-next.v.202603102151.0 → 0.10.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 (529) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/CONTRIBUTING.md +31 -0
  3. package/README.md +106 -0
  4. package/build/alert-dialog/context.cjs +34 -0
  5. package/build/alert-dialog/context.cjs.map +7 -0
  6. package/build/alert-dialog/index.cjs +37 -0
  7. package/build/alert-dialog/index.cjs.map +7 -0
  8. package/build/alert-dialog/popup.cjs +93 -0
  9. package/build/alert-dialog/popup.cjs.map +7 -0
  10. package/build/alert-dialog/root.cjs +52 -0
  11. package/build/alert-dialog/root.cjs.map +7 -0
  12. package/build/alert-dialog/trigger.cjs +48 -0
  13. package/build/alert-dialog/trigger.cjs.map +7 -0
  14. package/build/alert-dialog/types.cjs +19 -0
  15. package/build/alert-dialog/types.cjs.map +7 -0
  16. package/build/badge/badge.cjs +3 -3
  17. package/build/badge/badge.cjs.map +2 -2
  18. package/build/button/button.cjs +9 -9
  19. package/build/button/button.cjs.map +2 -2
  20. package/build/card/content.cjs +3 -3
  21. package/build/card/content.cjs.map +2 -2
  22. package/build/card/full-bleed.cjs +3 -3
  23. package/build/card/full-bleed.cjs.map +2 -2
  24. package/build/card/header.cjs +3 -3
  25. package/build/card/header.cjs.map +2 -2
  26. package/build/card/root.cjs +5 -5
  27. package/build/card/root.cjs.map +2 -2
  28. package/build/card/title.cjs +26 -13
  29. package/build/card/title.cjs.map +3 -3
  30. package/build/collapsible/index.cjs +37 -0
  31. package/build/collapsible/index.cjs.map +7 -0
  32. package/build/collapsible/panel.cjs +38 -0
  33. package/build/collapsible/panel.cjs.map +7 -0
  34. package/build/collapsible/root.cjs +38 -0
  35. package/build/collapsible/root.cjs.map +7 -0
  36. package/build/collapsible/trigger.cjs +38 -0
  37. package/build/collapsible/trigger.cjs.map +7 -0
  38. package/build/collapsible/types.cjs +19 -0
  39. package/build/collapsible/types.cjs.map +7 -0
  40. package/build/collapsible-card/content.cjs +26 -5
  41. package/build/collapsible-card/content.cjs.map +4 -4
  42. package/build/collapsible-card/context.cjs +35 -0
  43. package/build/collapsible-card/context.cjs.map +7 -0
  44. package/build/collapsible-card/header-description.cjs +52 -0
  45. package/build/collapsible-card/header-description.cjs.map +7 -0
  46. package/build/collapsible-card/header.cjs +57 -38
  47. package/build/collapsible-card/header.cjs.map +3 -3
  48. package/build/collapsible-card/index.cjs +3 -0
  49. package/build/collapsible-card/index.cjs.map +2 -2
  50. package/build/collapsible-card/root.cjs +4 -4
  51. package/build/collapsible-card/root.cjs.map +2 -2
  52. package/build/collapsible-card/types.cjs.map +1 -1
  53. package/build/dialog/action.cjs +4 -2
  54. package/build/dialog/action.cjs.map +2 -2
  55. package/build/dialog/close-icon.cjs +2 -1
  56. package/build/dialog/close-icon.cjs.map +2 -2
  57. package/build/dialog/footer.cjs +3 -3
  58. package/build/dialog/footer.cjs.map +2 -2
  59. package/build/dialog/header.cjs +3 -3
  60. package/build/dialog/header.cjs.map +2 -2
  61. package/build/dialog/popup.cjs +22 -5
  62. package/build/dialog/popup.cjs.map +2 -2
  63. package/build/dialog/title.cjs +3 -3
  64. package/build/dialog/title.cjs.map +2 -2
  65. package/build/dialog/types.cjs.map +1 -1
  66. package/build/empty-state/actions.cjs +66 -0
  67. package/build/empty-state/actions.cjs.map +7 -0
  68. package/build/empty-state/description.cjs +66 -0
  69. package/build/empty-state/description.cjs.map +7 -0
  70. package/build/empty-state/icon.cjs +69 -0
  71. package/build/empty-state/icon.cjs.map +7 -0
  72. package/build/empty-state/index.cjs +46 -0
  73. package/build/empty-state/index.cjs.map +7 -0
  74. package/build/empty-state/root.cjs +66 -0
  75. package/build/empty-state/root.cjs.map +7 -0
  76. package/build/empty-state/title.cjs +68 -0
  77. package/build/empty-state/title.cjs.map +7 -0
  78. package/build/empty-state/types.cjs +19 -0
  79. package/build/empty-state/types.cjs.map +7 -0
  80. package/build/empty-state/visual.cjs +66 -0
  81. package/build/empty-state/visual.cjs.map +7 -0
  82. package/build/form/index.cjs +27 -0
  83. package/build/form/index.cjs.map +7 -0
  84. package/build/form/input-control/index.cjs +31 -0
  85. package/build/form/input-control/index.cjs.map +7 -0
  86. package/build/form/input-control/input-control.cjs +50 -0
  87. package/build/form/input-control/input-control.cjs.map +7 -0
  88. package/build/form/input-control/types.cjs +19 -0
  89. package/build/form/input-control/types.cjs.map +7 -0
  90. package/build/form/primitives/field/description.cjs +2 -2
  91. package/build/form/primitives/field/description.cjs.map +1 -1
  92. package/build/form/primitives/field/details.cjs +2 -2
  93. package/build/form/primitives/field/details.cjs.map +1 -1
  94. package/build/form/primitives/field/label.cjs +2 -2
  95. package/build/form/primitives/field/label.cjs.map +1 -1
  96. package/build/form/primitives/field/root.cjs +4 -4
  97. package/build/form/primitives/field/root.cjs.map +2 -2
  98. package/build/form/primitives/fieldset/description.cjs +2 -2
  99. package/build/form/primitives/fieldset/description.cjs.map +1 -1
  100. package/build/form/primitives/fieldset/details.cjs +2 -2
  101. package/build/form/primitives/fieldset/details.cjs.map +1 -1
  102. package/build/form/primitives/fieldset/legend.cjs +2 -2
  103. package/build/form/primitives/fieldset/legend.cjs.map +1 -1
  104. package/build/form/primitives/fieldset/root.cjs +2 -2
  105. package/build/form/primitives/fieldset/root.cjs.map +1 -1
  106. package/build/form/primitives/input/input.cjs +6 -6
  107. package/build/form/primitives/input/input.cjs.map +2 -2
  108. package/build/form/primitives/input-layout/input-layout.cjs +4 -4
  109. package/build/form/primitives/input-layout/input-layout.cjs.map +1 -1
  110. package/build/form/primitives/input-layout/slot.cjs +5 -4
  111. package/build/form/primitives/input-layout/slot.cjs.map +2 -2
  112. package/build/form/primitives/select/item.cjs +5 -5
  113. package/build/form/primitives/select/item.cjs.map +2 -2
  114. package/build/form/primitives/select/popup.cjs +7 -7
  115. package/build/form/primitives/select/popup.cjs.map +2 -2
  116. package/build/form/primitives/select/trigger.cjs +7 -7
  117. package/build/form/primitives/select/trigger.cjs.map +2 -2
  118. package/build/form/primitives/textarea/textarea.cjs +3 -3
  119. package/build/form/primitives/textarea/textarea.cjs.map +2 -2
  120. package/build/form/types.cjs +19 -0
  121. package/build/form/types.cjs.map +7 -0
  122. package/build/icon-button/icon-button.cjs +2 -2
  123. package/build/icon-button/icon-button.cjs.map +1 -1
  124. package/build/index.cjs +11 -2
  125. package/build/index.cjs.map +2 -2
  126. package/build/link/link.cjs +8 -8
  127. package/build/link/link.cjs.map +2 -2
  128. package/build/notice/action-button.cjs +2 -2
  129. package/build/notice/action-button.cjs.map +1 -1
  130. package/build/notice/action-link.cjs +2 -2
  131. package/build/notice/action-link.cjs.map +1 -1
  132. package/build/notice/actions.cjs +2 -2
  133. package/build/notice/actions.cjs.map +1 -1
  134. package/build/notice/close-icon.cjs +2 -2
  135. package/build/notice/close-icon.cjs.map +1 -1
  136. package/build/notice/description.cjs +2 -2
  137. package/build/notice/description.cjs.map +1 -1
  138. package/build/notice/index.cjs.map +1 -1
  139. package/build/notice/root.cjs +4 -4
  140. package/build/notice/root.cjs.map +1 -1
  141. package/build/notice/title.cjs +2 -2
  142. package/build/notice/title.cjs.map +1 -1
  143. package/build/stack/stack.cjs +2 -2
  144. package/build/stack/stack.cjs.map +1 -1
  145. package/build/tabs/context.cjs +121 -0
  146. package/build/tabs/context.cjs.map +7 -0
  147. package/build/tabs/list.cjs +3 -3
  148. package/build/tabs/list.cjs.map +2 -2
  149. package/build/tabs/panel.cjs +5 -3
  150. package/build/tabs/panel.cjs.map +2 -2
  151. package/build/tabs/root.cjs +2 -1
  152. package/build/tabs/root.cjs.map +2 -2
  153. package/build/tabs/tab.cjs +5 -3
  154. package/build/tabs/tab.cjs.map +2 -2
  155. package/build/text/text.cjs +2 -2
  156. package/build/text/text.cjs.map +1 -1
  157. package/build/tooltip/popup.cjs +4 -4
  158. package/build/tooltip/popup.cjs.map +1 -1
  159. package/build/tooltip/root.cjs.map +2 -2
  160. package/build/utils/use-deprioritized-initial-focus.cjs +64 -0
  161. package/build/utils/use-deprioritized-initial-focus.cjs.map +7 -0
  162. package/build/visually-hidden/visually-hidden.cjs +2 -2
  163. package/build/visually-hidden/visually-hidden.cjs.map +1 -1
  164. package/build-module/alert-dialog/context.mjs +9 -0
  165. package/build-module/alert-dialog/context.mjs.map +7 -0
  166. package/build-module/alert-dialog/index.mjs +10 -0
  167. package/build-module/alert-dialog/index.mjs.map +7 -0
  168. package/build-module/alert-dialog/popup.mjs +58 -0
  169. package/build-module/alert-dialog/popup.mjs.map +7 -0
  170. package/build-module/alert-dialog/root.mjs +27 -0
  171. package/build-module/alert-dialog/root.mjs.map +7 -0
  172. package/build-module/alert-dialog/trigger.mjs +13 -0
  173. package/build-module/alert-dialog/trigger.mjs.map +7 -0
  174. package/build-module/alert-dialog/types.mjs +1 -0
  175. package/build-module/alert-dialog/types.mjs.map +7 -0
  176. package/build-module/badge/badge.mjs +3 -3
  177. package/build-module/badge/badge.mjs.map +2 -2
  178. package/build-module/button/button.mjs +9 -9
  179. package/build-module/button/button.mjs.map +2 -2
  180. package/build-module/card/content.mjs +3 -3
  181. package/build-module/card/content.mjs.map +2 -2
  182. package/build-module/card/full-bleed.mjs +3 -3
  183. package/build-module/card/full-bleed.mjs.map +2 -2
  184. package/build-module/card/header.mjs +3 -3
  185. package/build-module/card/header.mjs.map +2 -2
  186. package/build-module/card/root.mjs +5 -5
  187. package/build-module/card/root.mjs.map +2 -2
  188. package/build-module/card/title.mjs +16 -13
  189. package/build-module/card/title.mjs.map +2 -2
  190. package/build-module/collapsible/index.mjs +10 -0
  191. package/build-module/collapsible/index.mjs.map +7 -0
  192. package/build-module/collapsible/panel.mjs +13 -0
  193. package/build-module/collapsible/panel.mjs.map +7 -0
  194. package/build-module/collapsible/root.mjs +13 -0
  195. package/build-module/collapsible/root.mjs.map +7 -0
  196. package/build-module/collapsible/trigger.mjs +13 -0
  197. package/build-module/collapsible/trigger.mjs.map +7 -0
  198. package/build-module/collapsible/types.mjs +1 -0
  199. package/build-module/collapsible/types.mjs.map +7 -0
  200. package/build-module/collapsible-card/content.mjs +25 -4
  201. package/build-module/collapsible-card/content.mjs.map +3 -3
  202. package/build-module/collapsible-card/context.mjs +10 -0
  203. package/build-module/collapsible-card/context.mjs.map +7 -0
  204. package/build-module/collapsible-card/header-description.mjs +27 -0
  205. package/build-module/collapsible-card/header-description.mjs.map +7 -0
  206. package/build-module/collapsible-card/header.mjs +59 -40
  207. package/build-module/collapsible-card/header.mjs.map +3 -3
  208. package/build-module/collapsible-card/index.mjs +2 -0
  209. package/build-module/collapsible-card/index.mjs.map +2 -2
  210. package/build-module/collapsible-card/root.mjs +3 -3
  211. package/build-module/collapsible-card/root.mjs.map +2 -2
  212. package/build-module/dialog/action.mjs +4 -2
  213. package/build-module/dialog/action.mjs.map +2 -2
  214. package/build-module/dialog/close-icon.mjs +2 -1
  215. package/build-module/dialog/close-icon.mjs.map +2 -2
  216. package/build-module/dialog/footer.mjs +3 -3
  217. package/build-module/dialog/footer.mjs.map +2 -2
  218. package/build-module/dialog/header.mjs +3 -3
  219. package/build-module/dialog/header.mjs.map +2 -2
  220. package/build-module/dialog/popup.mjs +22 -5
  221. package/build-module/dialog/popup.mjs.map +2 -2
  222. package/build-module/dialog/title.mjs +3 -3
  223. package/build-module/dialog/title.mjs.map +2 -2
  224. package/build-module/empty-state/actions.mjs +31 -0
  225. package/build-module/empty-state/actions.mjs.map +7 -0
  226. package/build-module/empty-state/description.mjs +31 -0
  227. package/build-module/empty-state/description.mjs.map +7 -0
  228. package/build-module/empty-state/icon.mjs +34 -0
  229. package/build-module/empty-state/icon.mjs.map +7 -0
  230. package/build-module/empty-state/index.mjs +16 -0
  231. package/build-module/empty-state/index.mjs.map +7 -0
  232. package/build-module/empty-state/root.mjs +31 -0
  233. package/build-module/empty-state/root.mjs.map +7 -0
  234. package/build-module/empty-state/title.mjs +33 -0
  235. package/build-module/empty-state/title.mjs.map +7 -0
  236. package/build-module/empty-state/types.mjs +1 -0
  237. package/build-module/empty-state/types.mjs.map +7 -0
  238. package/build-module/empty-state/visual.mjs +31 -0
  239. package/build-module/empty-state/visual.mjs.map +7 -0
  240. package/build-module/form/index.mjs +4 -0
  241. package/build-module/form/index.mjs.map +7 -0
  242. package/build-module/form/input-control/index.mjs +6 -0
  243. package/build-module/form/input-control/index.mjs.map +7 -0
  244. package/build-module/form/input-control/input-control.mjs +25 -0
  245. package/build-module/form/input-control/input-control.mjs.map +7 -0
  246. package/build-module/form/input-control/types.mjs +1 -0
  247. package/build-module/form/input-control/types.mjs.map +7 -0
  248. package/build-module/form/primitives/field/description.mjs +2 -2
  249. package/build-module/form/primitives/field/description.mjs.map +1 -1
  250. package/build-module/form/primitives/field/details.mjs +2 -2
  251. package/build-module/form/primitives/field/details.mjs.map +1 -1
  252. package/build-module/form/primitives/field/label.mjs +2 -2
  253. package/build-module/form/primitives/field/label.mjs.map +1 -1
  254. package/build-module/form/primitives/field/root.mjs +4 -4
  255. package/build-module/form/primitives/field/root.mjs.map +2 -2
  256. package/build-module/form/primitives/fieldset/description.mjs +2 -2
  257. package/build-module/form/primitives/fieldset/description.mjs.map +1 -1
  258. package/build-module/form/primitives/fieldset/details.mjs +2 -2
  259. package/build-module/form/primitives/fieldset/details.mjs.map +1 -1
  260. package/build-module/form/primitives/fieldset/legend.mjs +2 -2
  261. package/build-module/form/primitives/fieldset/legend.mjs.map +1 -1
  262. package/build-module/form/primitives/fieldset/root.mjs +2 -2
  263. package/build-module/form/primitives/fieldset/root.mjs.map +1 -1
  264. package/build-module/form/primitives/input/input.mjs +6 -6
  265. package/build-module/form/primitives/input/input.mjs.map +2 -2
  266. package/build-module/form/primitives/input-layout/input-layout.mjs +4 -4
  267. package/build-module/form/primitives/input-layout/input-layout.mjs.map +1 -1
  268. package/build-module/form/primitives/input-layout/slot.mjs +5 -4
  269. package/build-module/form/primitives/input-layout/slot.mjs.map +2 -2
  270. package/build-module/form/primitives/select/item.mjs +5 -5
  271. package/build-module/form/primitives/select/item.mjs.map +2 -2
  272. package/build-module/form/primitives/select/popup.mjs +7 -7
  273. package/build-module/form/primitives/select/popup.mjs.map +2 -2
  274. package/build-module/form/primitives/select/trigger.mjs +7 -7
  275. package/build-module/form/primitives/select/trigger.mjs.map +2 -2
  276. package/build-module/form/primitives/textarea/textarea.mjs +3 -3
  277. package/build-module/form/primitives/textarea/textarea.mjs.map +2 -2
  278. package/build-module/form/types.mjs +1 -0
  279. package/build-module/form/types.mjs.map +7 -0
  280. package/build-module/icon-button/icon-button.mjs +2 -2
  281. package/build-module/icon-button/icon-button.mjs.map +1 -1
  282. package/build-module/index.mjs +7 -1
  283. package/build-module/index.mjs.map +2 -2
  284. package/build-module/link/link.mjs +8 -8
  285. package/build-module/link/link.mjs.map +2 -2
  286. package/build-module/notice/action-button.mjs +2 -2
  287. package/build-module/notice/action-button.mjs.map +1 -1
  288. package/build-module/notice/action-link.mjs +2 -2
  289. package/build-module/notice/action-link.mjs.map +1 -1
  290. package/build-module/notice/actions.mjs +2 -2
  291. package/build-module/notice/actions.mjs.map +1 -1
  292. package/build-module/notice/close-icon.mjs +2 -2
  293. package/build-module/notice/close-icon.mjs.map +1 -1
  294. package/build-module/notice/description.mjs +2 -2
  295. package/build-module/notice/description.mjs.map +1 -1
  296. package/build-module/notice/index.mjs.map +1 -1
  297. package/build-module/notice/root.mjs +4 -4
  298. package/build-module/notice/root.mjs.map +1 -1
  299. package/build-module/notice/title.mjs +2 -2
  300. package/build-module/notice/title.mjs.map +1 -1
  301. package/build-module/stack/stack.mjs +2 -2
  302. package/build-module/stack/stack.mjs.map +1 -1
  303. package/build-module/tabs/context.mjs +101 -0
  304. package/build-module/tabs/context.mjs.map +7 -0
  305. package/build-module/tabs/list.mjs +3 -3
  306. package/build-module/tabs/list.mjs.map +2 -2
  307. package/build-module/tabs/panel.mjs +5 -3
  308. package/build-module/tabs/panel.mjs.map +2 -2
  309. package/build-module/tabs/root.mjs +2 -1
  310. package/build-module/tabs/root.mjs.map +2 -2
  311. package/build-module/tabs/tab.mjs +5 -3
  312. package/build-module/tabs/tab.mjs.map +2 -2
  313. package/build-module/text/text.mjs +2 -2
  314. package/build-module/text/text.mjs.map +1 -1
  315. package/build-module/tooltip/popup.mjs +4 -4
  316. package/build-module/tooltip/popup.mjs.map +1 -1
  317. package/build-module/tooltip/root.mjs.map +2 -2
  318. package/build-module/utils/use-deprioritized-initial-focus.mjs +39 -0
  319. package/build-module/utils/use-deprioritized-initial-focus.mjs.map +7 -0
  320. package/build-module/visually-hidden/visually-hidden.mjs +2 -2
  321. package/build-module/visually-hidden/visually-hidden.mjs.map +1 -1
  322. package/build-types/alert-dialog/context.d.ts +8 -0
  323. package/build-types/alert-dialog/context.d.ts.map +1 -0
  324. package/build-types/alert-dialog/index.d.ts +4 -0
  325. package/build-types/alert-dialog/index.d.ts.map +1 -0
  326. package/build-types/alert-dialog/popup.d.ts +4 -0
  327. package/build-types/alert-dialog/popup.d.ts.map +1 -0
  328. package/build-types/alert-dialog/root.d.ts +24 -0
  329. package/build-types/alert-dialog/root.d.ts.map +1 -0
  330. package/build-types/alert-dialog/stories/index.story.d.ts +44 -0
  331. package/build-types/alert-dialog/stories/index.story.d.ts.map +1 -0
  332. package/build-types/alert-dialog/test/index.test.d.ts +2 -0
  333. package/build-types/alert-dialog/test/index.test.d.ts.map +1 -0
  334. package/build-types/alert-dialog/trigger.d.ts +6 -0
  335. package/build-types/alert-dialog/trigger.d.ts.map +1 -0
  336. package/build-types/alert-dialog/types.d.ts +70 -0
  337. package/build-types/alert-dialog/types.d.ts.map +1 -0
  338. package/build-types/card/title.d.ts.map +1 -1
  339. package/build-types/collapsible/index.d.ts +5 -0
  340. package/build-types/collapsible/index.d.ts.map +1 -0
  341. package/build-types/collapsible/panel.d.ts +16 -0
  342. package/build-types/collapsible/panel.d.ts.map +1 -0
  343. package/build-types/collapsible/root.d.ts +15 -0
  344. package/build-types/collapsible/root.d.ts.map +1 -0
  345. package/build-types/collapsible/stories/index.story.d.ts +18 -0
  346. package/build-types/collapsible/stories/index.story.d.ts.map +1 -0
  347. package/build-types/collapsible/test/index.test.d.ts +2 -0
  348. package/build-types/collapsible/test/index.test.d.ts.map +1 -0
  349. package/build-types/collapsible/trigger.d.ts +15 -0
  350. package/build-types/collapsible/trigger.d.ts.map +1 -0
  351. package/build-types/collapsible/types.d.ts +22 -0
  352. package/build-types/collapsible/types.d.ts.map +1 -0
  353. package/build-types/collapsible-card/content.d.ts.map +1 -1
  354. package/build-types/collapsible-card/context.d.ts +4 -0
  355. package/build-types/collapsible-card/context.d.ts.map +1 -0
  356. package/build-types/collapsible-card/header-description.d.ts +15 -0
  357. package/build-types/collapsible-card/header-description.d.ts.map +1 -0
  358. package/build-types/collapsible-card/header.d.ts.map +1 -1
  359. package/build-types/collapsible-card/index.d.ts +2 -1
  360. package/build-types/collapsible-card/index.d.ts.map +1 -1
  361. package/build-types/collapsible-card/stories/index.story.d.ts +10 -0
  362. package/build-types/collapsible-card/stories/index.story.d.ts.map +1 -1
  363. package/build-types/collapsible-card/types.d.ts +21 -0
  364. package/build-types/collapsible-card/types.d.ts.map +1 -1
  365. package/build-types/dialog/action.d.ts.map +1 -1
  366. package/build-types/dialog/close-icon.d.ts.map +1 -1
  367. package/build-types/dialog/popup.d.ts.map +1 -1
  368. package/build-types/dialog/stories/index.story.d.ts +0 -6
  369. package/build-types/dialog/stories/index.story.d.ts.map +1 -1
  370. package/build-types/dialog/types.d.ts +5 -5
  371. package/build-types/dialog/types.d.ts.map +1 -1
  372. package/build-types/empty-state/actions.d.ts +7 -0
  373. package/build-types/empty-state/actions.d.ts.map +1 -0
  374. package/build-types/empty-state/description.d.ts +7 -0
  375. package/build-types/empty-state/description.d.ts.map +1 -0
  376. package/build-types/empty-state/icon.d.ts +7 -0
  377. package/build-types/empty-state/icon.d.ts.map +1 -0
  378. package/build-types/empty-state/index.d.ts +8 -0
  379. package/build-types/empty-state/index.d.ts.map +1 -0
  380. package/build-types/empty-state/root.d.ts +6 -0
  381. package/build-types/empty-state/root.d.ts.map +1 -0
  382. package/build-types/empty-state/stories/index.story.d.ts +8 -0
  383. package/build-types/empty-state/stories/index.story.d.ts.map +1 -0
  384. package/build-types/empty-state/test/actions.test.d.ts +2 -0
  385. package/build-types/empty-state/test/actions.test.d.ts.map +1 -0
  386. package/build-types/empty-state/test/description.test.d.ts +2 -0
  387. package/build-types/empty-state/test/description.test.d.ts.map +1 -0
  388. package/build-types/empty-state/test/icon.test.d.ts +2 -0
  389. package/build-types/empty-state/test/icon.test.d.ts.map +1 -0
  390. package/build-types/empty-state/test/root.test.d.ts +2 -0
  391. package/build-types/empty-state/test/root.test.d.ts.map +1 -0
  392. package/build-types/empty-state/test/title.test.d.ts +2 -0
  393. package/build-types/empty-state/test/title.test.d.ts.map +1 -0
  394. package/build-types/empty-state/test/visual.test.d.ts +2 -0
  395. package/build-types/empty-state/test/visual.test.d.ts.map +1 -0
  396. package/build-types/empty-state/title.d.ts +6 -0
  397. package/build-types/empty-state/title.d.ts.map +1 -0
  398. package/build-types/empty-state/types.d.ts +40 -0
  399. package/build-types/empty-state/types.d.ts.map +1 -0
  400. package/build-types/empty-state/visual.d.ts +7 -0
  401. package/build-types/empty-state/visual.d.ts.map +1 -0
  402. package/build-types/form/index.d.ts +3 -0
  403. package/build-types/form/index.d.ts.map +1 -0
  404. package/build-types/form/input-control/index.d.ts +2 -0
  405. package/build-types/form/input-control/index.d.ts.map +1 -0
  406. package/build-types/form/input-control/input-control.d.ts +6 -0
  407. package/build-types/form/input-control/input-control.d.ts.map +1 -0
  408. package/build-types/form/input-control/stories/index.story.d.ts +16 -0
  409. package/build-types/form/input-control/stories/index.story.d.ts.map +1 -0
  410. package/build-types/form/input-control/test/index.test.d.ts +2 -0
  411. package/build-types/form/input-control/test/index.test.d.ts.map +1 -0
  412. package/build-types/form/input-control/types.d.ts +4 -0
  413. package/build-types/form/input-control/types.d.ts.map +1 -0
  414. package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
  415. package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
  416. package/build-types/form/primitives/input/stories/index.story.d.ts +2 -0
  417. package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -1
  418. package/build-types/form/primitives/input-layout/slot.d.ts.map +1 -1
  419. package/build-types/form/primitives/input-layout/stories/index.story.d.ts +5 -0
  420. package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -1
  421. package/build-types/form/stories/shared.d.ts +3 -0
  422. package/build-types/form/stories/shared.d.ts.map +1 -0
  423. package/build-types/form/types.d.ts +30 -0
  424. package/build-types/form/types.d.ts.map +1 -0
  425. package/build-types/index.d.ts +4 -1
  426. package/build-types/index.d.ts.map +1 -1
  427. package/build-types/notice/index.d.ts +0 -1
  428. package/build-types/notice/index.d.ts.map +1 -1
  429. package/build-types/tabs/context.d.ts +26 -0
  430. package/build-types/tabs/context.d.ts.map +1 -0
  431. package/build-types/tabs/panel.d.ts.map +1 -1
  432. package/build-types/tabs/root.d.ts.map +1 -1
  433. package/build-types/tabs/tab.d.ts.map +1 -1
  434. package/build-types/tooltip/root.d.ts +12 -0
  435. package/build-types/tooltip/root.d.ts.map +1 -1
  436. package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
  437. package/build-types/utils/test/use-deprioritized-initial-focus.test.d.ts +2 -0
  438. package/build-types/utils/test/use-deprioritized-initial-focus.test.d.ts.map +1 -0
  439. package/build-types/utils/use-deprioritized-initial-focus.d.ts +35 -0
  440. package/build-types/utils/use-deprioritized-initial-focus.d.ts.map +1 -0
  441. package/package.json +17 -16
  442. package/src/alert-dialog/context.tsx +14 -0
  443. package/src/alert-dialog/index.ts +3 -0
  444. package/src/alert-dialog/popup.tsx +58 -0
  445. package/src/alert-dialog/root.tsx +48 -0
  446. package/src/alert-dialog/stories/index.story.tsx +254 -0
  447. package/src/alert-dialog/style.module.css +10 -0
  448. package/src/alert-dialog/test/index.test.tsx +537 -0
  449. package/src/alert-dialog/trigger.tsx +15 -0
  450. package/src/alert-dialog/types.ts +83 -0
  451. package/src/badge/style.module.css +5 -2
  452. package/src/button/style.module.css +2 -0
  453. package/src/card/stories/index.story.tsx +1 -1
  454. package/src/card/style.module.css +5 -7
  455. package/src/card/title.tsx +12 -11
  456. package/src/collapsible/index.ts +5 -0
  457. package/src/collapsible/panel.tsx +16 -0
  458. package/src/collapsible/root.tsx +15 -0
  459. package/src/collapsible/stories/index.story.tsx +108 -0
  460. package/src/collapsible/test/index.test.tsx +228 -0
  461. package/src/collapsible/trigger.tsx +15 -0
  462. package/src/collapsible/types.ts +24 -0
  463. package/src/collapsible-card/content.tsx +17 -4
  464. package/src/collapsible-card/context.ts +7 -0
  465. package/src/collapsible-card/header-description.tsx +43 -0
  466. package/src/collapsible-card/header.tsx +50 -45
  467. package/src/collapsible-card/index.ts +2 -1
  468. package/src/collapsible-card/root.tsx +1 -1
  469. package/src/collapsible-card/stories/index.story.tsx +99 -1
  470. package/src/collapsible-card/style.module.css +49 -4
  471. package/src/collapsible-card/test/index.test.tsx +107 -40
  472. package/src/collapsible-card/types.ts +22 -0
  473. package/src/dialog/action.tsx +8 -2
  474. package/src/dialog/close-icon.tsx +1 -0
  475. package/src/dialog/popup.tsx +21 -2
  476. package/src/dialog/stories/index.story.tsx +0 -28
  477. package/src/dialog/style.module.css +5 -5
  478. package/src/dialog/test/index.test.tsx +117 -0
  479. package/src/dialog/types.ts +11 -5
  480. package/src/empty-state/actions.tsx +24 -0
  481. package/src/empty-state/description.tsx +27 -0
  482. package/src/empty-state/icon.tsx +24 -0
  483. package/src/empty-state/index.ts +8 -0
  484. package/src/empty-state/root.tsx +23 -0
  485. package/src/empty-state/stories/index.story.tsx +64 -0
  486. package/src/empty-state/style.module.css +53 -0
  487. package/src/empty-state/test/actions.test.tsx +18 -0
  488. package/src/empty-state/test/description.test.tsx +13 -0
  489. package/src/empty-state/test/icon.test.tsx +13 -0
  490. package/src/empty-state/test/root.test.tsx +13 -0
  491. package/src/empty-state/test/title.test.tsx +13 -0
  492. package/src/empty-state/test/visual.test.tsx +17 -0
  493. package/src/empty-state/title.tsx +23 -0
  494. package/src/empty-state/types.ts +45 -0
  495. package/src/empty-state/visual.tsx +24 -0
  496. package/src/form/index.ts +3 -0
  497. package/src/form/input-control/index.ts +1 -0
  498. package/src/form/input-control/input-control.tsx +33 -0
  499. package/src/form/input-control/stories/index.story.tsx +163 -0
  500. package/src/form/input-control/test/index.test.tsx +53 -0
  501. package/src/form/input-control/types.ts +5 -0
  502. package/src/form/primitives/field/root.tsx +2 -2
  503. package/src/form/primitives/field/stories/index.story.tsx +2 -7
  504. package/src/form/primitives/fieldset/stories/index.story.tsx +2 -7
  505. package/src/form/primitives/input/stories/index.story.tsx +7 -0
  506. package/src/form/primitives/input-layout/slot.tsx +6 -2
  507. package/src/form/primitives/input-layout/stories/index.story.tsx +22 -1
  508. package/src/form/primitives/stories/overview.mdx +15 -0
  509. package/src/form/primitives/textarea/textarea.tsx +1 -1
  510. package/src/form/stories/shared.tsx +19 -0
  511. package/src/form/types.ts +34 -0
  512. package/src/index.ts +4 -1
  513. package/src/notice/index.ts +0 -2
  514. package/src/notice/style.module.css +1 -1
  515. package/src/tabs/context.tsx +170 -0
  516. package/src/tabs/panel.tsx +3 -0
  517. package/src/tabs/root.tsx +6 -1
  518. package/src/tabs/style.module.css +1 -1
  519. package/src/tabs/tab.tsx +3 -0
  520. package/src/tabs/test/index.test.tsx +162 -0
  521. package/src/tooltip/root.tsx +12 -0
  522. package/src/tooltip/stories/index.story.tsx +20 -15
  523. package/src/utils/css/focus.module.css +4 -2
  524. package/src/utils/css/item-popup.module.css +1 -0
  525. package/src/utils/css/select-trigger.module.css +1 -0
  526. package/src/utils/test/use-deprioritized-initial-focus.test.tsx +230 -0
  527. package/src/utils/use-deprioritized-initial-focus.ts +83 -0
  528. package/AGENTS.md +0 -9
  529. package/CLAUDE.md +0 -1
@@ -1,5 +1,6 @@
1
- import { mergeProps, useRender } from '@base-ui/react';
2
1
  import { forwardRef } from '@wordpress/element';
2
+ import clsx from 'clsx';
3
+ import { Text } from '../text';
3
4
  import styles from './style.module.css';
4
5
  import type { TitleProps } from './types';
5
6
 
@@ -8,15 +9,15 @@ import type { TitleProps } from './types';
8
9
  * prop to swap in a semantic heading element when appropriate.
9
10
  */
10
11
  export const Title = forwardRef< HTMLDivElement, TitleProps >(
11
- function CardTitle( { render, ...props }, ref ) {
12
- const element = useRender( {
13
- defaultTagName: 'div',
14
- render,
15
- ref,
16
- // TODO: use `Text` component instead, when ready
17
- props: mergeProps< 'div' >( { className: styles.title }, props ),
18
- } );
19
-
20
- return element;
12
+ function CardTitle( { className, render, children, ...props }, ref ) {
13
+ return (
14
+ <Text
15
+ variant="heading-lg"
16
+ render={ render ?? <div ref={ ref } { ...props } /> }
17
+ className={ clsx( styles.title, className ) }
18
+ >
19
+ { children }
20
+ </Text>
21
+ );
21
22
  }
22
23
  );
@@ -0,0 +1,5 @@
1
+ import { Panel } from './panel';
2
+ import { Root } from './root';
3
+ import { Trigger } from './trigger';
4
+
5
+ export { Root, Trigger, Panel };
@@ -0,0 +1,16 @@
1
+ import { Collapsible as _Collapsible } from '@base-ui/react/collapsible';
2
+ import { forwardRef } from '@wordpress/element';
3
+ import type { PanelProps } from './types';
4
+
5
+ /**
6
+ * A panel with the collapsible contents. Hidden when collapsed, visible
7
+ * when expanded.
8
+ *
9
+ * `Collapsible` is a collection of React components that combine to render
10
+ * a collapsible panel controlled by a button.
11
+ */
12
+ export const Panel = forwardRef< HTMLDivElement, PanelProps >(
13
+ function CollapsiblePanel( props, forwardedRef ) {
14
+ return <_Collapsible.Panel ref={ forwardedRef } { ...props } />;
15
+ }
16
+ );
@@ -0,0 +1,15 @@
1
+ import { Collapsible as _Collapsible } from '@base-ui/react/collapsible';
2
+ import { forwardRef } from '@wordpress/element';
3
+ import type { RootProps } from './types';
4
+
5
+ /**
6
+ * Groups all parts of the collapsible.
7
+ *
8
+ * `Collapsible` is a collection of React components that combine to render
9
+ * a collapsible panel controlled by a button.
10
+ */
11
+ export const Root = forwardRef< HTMLDivElement, RootProps >(
12
+ function CollapsibleRoot( props, forwardedRef ) {
13
+ return <_Collapsible.Root ref={ forwardedRef } { ...props } />;
14
+ }
15
+ );
@@ -0,0 +1,108 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { useState } from '@wordpress/element';
3
+ import * as Collapsible from '../index';
4
+
5
+ const meta: Meta< typeof Collapsible.Root > = {
6
+ title: 'Design System/Components/Collapsible',
7
+ component: Collapsible.Root,
8
+ subcomponents: {
9
+ 'Collapsible.Trigger': Collapsible.Trigger,
10
+ 'Collapsible.Panel': Collapsible.Panel,
11
+ },
12
+ };
13
+ export default meta;
14
+
15
+ type Story = StoryObj< typeof Collapsible.Root >;
16
+
17
+ export const Default: Story = {
18
+ args: {
19
+ children: (
20
+ <>
21
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
22
+ <Collapsible.Panel>
23
+ <p>Collapsible content here.</p>
24
+ </Collapsible.Panel>
25
+ </>
26
+ ),
27
+ },
28
+ };
29
+
30
+ export const DefaultOpen: Story = {
31
+ argTypes: { open: { control: false } },
32
+ args: {
33
+ defaultOpen: true,
34
+ children: (
35
+ <>
36
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
37
+ <Collapsible.Panel>
38
+ <p>This panel is open by default.</p>
39
+ </Collapsible.Panel>
40
+ </>
41
+ ),
42
+ },
43
+ };
44
+
45
+ export const Disabled: Story = {
46
+ args: {
47
+ disabled: true,
48
+ children: (
49
+ <>
50
+ <Collapsible.Trigger>Toggle (disabled)</Collapsible.Trigger>
51
+ <Collapsible.Panel>
52
+ <p>This content cannot be toggled.</p>
53
+ </Collapsible.Panel>
54
+ </>
55
+ ),
56
+ },
57
+ };
58
+
59
+ /**
60
+ * When `hiddenUntilFound` is set on `Collapsible.Panel`, the collapsed content
61
+ * remains in the DOM using the `hidden="until-found"` HTML attribute instead of
62
+ * being removed entirely. This lets the browser's native page search (Ctrl/Cmd+F)
63
+ * find text inside collapsed panels and automatically expand them to reveal the
64
+ * match — improving discoverability without sacrificing the collapsed layout.
65
+ */
66
+ export const HiddenUntilFound: Story = {
67
+ render: function HiddenUntilFound() {
68
+ return (
69
+ <div>
70
+ <p>
71
+ Use the browser&apos;s find-in-page (Ctrl/Cmd+F) to search
72
+ for &quot;hidden treasure&quot;. The collapsed panel will
73
+ automatically expand to reveal the match.
74
+ </p>
75
+ <Collapsible.Root>
76
+ <Collapsible.Trigger>Expand to reveal</Collapsible.Trigger>
77
+ <Collapsible.Panel hiddenUntilFound>
78
+ <p>
79
+ This is the hidden treasure that can be found via
80
+ the browser&apos;s built-in page search even while
81
+ the panel is collapsed.
82
+ </p>
83
+ </Collapsible.Panel>
84
+ </Collapsible.Root>
85
+ </div>
86
+ );
87
+ },
88
+ };
89
+
90
+ export const Controlled: Story = {
91
+ argTypes: {
92
+ open: { control: false },
93
+ defaultOpen: { control: false },
94
+ },
95
+ render: function Controlled() {
96
+ const [ open, setOpen ] = useState( false );
97
+ return (
98
+ <Collapsible.Root open={ open } onOpenChange={ setOpen }>
99
+ <Collapsible.Trigger>
100
+ { open ? 'Close' : 'Open' }
101
+ </Collapsible.Trigger>
102
+ <Collapsible.Panel>
103
+ <p>Controlled collapsible panel.</p>
104
+ </Collapsible.Panel>
105
+ </Collapsible.Root>
106
+ );
107
+ },
108
+ };
@@ -0,0 +1,228 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import { userEvent } from '@testing-library/user-event';
3
+ import { createRef, useState } from '@wordpress/element';
4
+ import * as Collapsible from '../index';
5
+
6
+ function UncontrolledCollapsible( {
7
+ defaultOpen,
8
+ disabled,
9
+ }: {
10
+ defaultOpen?: boolean;
11
+ disabled?: boolean;
12
+ } ) {
13
+ return (
14
+ <Collapsible.Root defaultOpen={ defaultOpen } disabled={ disabled }>
15
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
16
+ <Collapsible.Panel>Panel content</Collapsible.Panel>
17
+ </Collapsible.Root>
18
+ );
19
+ }
20
+
21
+ function ControlledCollapsible( {
22
+ onOpenChange,
23
+ }: {
24
+ onOpenChange?: ( open: boolean ) => void;
25
+ } ) {
26
+ const [ open, setOpen ] = useState( false );
27
+ return (
28
+ <Collapsible.Root
29
+ open={ open }
30
+ onOpenChange={ ( nextOpen ) => {
31
+ setOpen( nextOpen );
32
+ onOpenChange?.( nextOpen );
33
+ } }
34
+ >
35
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
36
+ <Collapsible.Panel>Controlled panel</Collapsible.Panel>
37
+ </Collapsible.Root>
38
+ );
39
+ }
40
+
41
+ describe( 'Collapsible', () => {
42
+ describe( 'ref forwarding', () => {
43
+ it( 'forwards ref on Root', () => {
44
+ const ref = createRef< HTMLDivElement >();
45
+ render(
46
+ <Collapsible.Root ref={ ref }>
47
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
48
+ <Collapsible.Panel>Content</Collapsible.Panel>
49
+ </Collapsible.Root>
50
+ );
51
+ expect( ref.current ).toBeInstanceOf( HTMLDivElement );
52
+ } );
53
+
54
+ it( 'forwards ref on Trigger', () => {
55
+ const ref = createRef< HTMLButtonElement >();
56
+ render(
57
+ <Collapsible.Root>
58
+ <Collapsible.Trigger ref={ ref }>
59
+ Toggle
60
+ </Collapsible.Trigger>
61
+ <Collapsible.Panel>Content</Collapsible.Panel>
62
+ </Collapsible.Root>
63
+ );
64
+ expect( ref.current ).toBeInstanceOf( HTMLButtonElement );
65
+ } );
66
+
67
+ it( 'forwards ref on Panel', () => {
68
+ const ref = createRef< HTMLDivElement >();
69
+ render(
70
+ <Collapsible.Root defaultOpen>
71
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
72
+ <Collapsible.Panel ref={ ref }>Content</Collapsible.Panel>
73
+ </Collapsible.Root>
74
+ );
75
+ expect( ref.current ).toBeInstanceOf( HTMLDivElement );
76
+ } );
77
+ } );
78
+
79
+ describe( 'uncontrolled', () => {
80
+ it( 'is collapsed by default', () => {
81
+ render( <UncontrolledCollapsible /> );
82
+ expect(
83
+ screen.queryByText( 'Panel content' )
84
+ ).not.toBeInTheDocument();
85
+ } );
86
+
87
+ it( 'shows panel when defaultOpen is true', () => {
88
+ render( <UncontrolledCollapsible defaultOpen /> );
89
+ expect( screen.getByText( 'Panel content' ) ).toBeVisible();
90
+ } );
91
+
92
+ it( 'toggles panel on trigger click', async () => {
93
+ const user = userEvent.setup();
94
+ render( <UncontrolledCollapsible /> );
95
+
96
+ expect(
97
+ screen.queryByText( 'Panel content' )
98
+ ).not.toBeInTheDocument();
99
+
100
+ await user.click(
101
+ screen.getByRole( 'button', { name: 'Toggle' } )
102
+ );
103
+ expect( screen.getByText( 'Panel content' ) ).toBeVisible();
104
+
105
+ await user.click(
106
+ screen.getByRole( 'button', { name: 'Toggle' } )
107
+ );
108
+ expect(
109
+ screen.queryByText( 'Panel content' )
110
+ ).not.toBeInTheDocument();
111
+ } );
112
+ } );
113
+
114
+ describe( 'controlled', () => {
115
+ it( 'calls onOpenChange when toggled', async () => {
116
+ const onOpenChange = jest.fn();
117
+ const user = userEvent.setup();
118
+
119
+ render( <ControlledCollapsible onOpenChange={ onOpenChange } /> );
120
+
121
+ await user.click(
122
+ screen.getByRole( 'button', { name: 'Toggle' } )
123
+ );
124
+ expect( onOpenChange ).toHaveBeenCalledWith( true );
125
+
126
+ await user.click(
127
+ screen.getByRole( 'button', { name: 'Toggle' } )
128
+ );
129
+ expect( onOpenChange ).toHaveBeenCalledWith( false );
130
+ } );
131
+ } );
132
+
133
+ describe( 'disabled', () => {
134
+ it( 'does not toggle when disabled', async () => {
135
+ const user = userEvent.setup();
136
+ render( <UncontrolledCollapsible defaultOpen disabled /> );
137
+
138
+ expect( screen.getByText( 'Panel content' ) ).toBeVisible();
139
+
140
+ await user.click(
141
+ screen.getByRole( 'button', { name: 'Toggle' } )
142
+ );
143
+ expect( screen.getByText( 'Panel content' ) ).toBeVisible();
144
+ } );
145
+ } );
146
+
147
+ describe( 'render prop', () => {
148
+ it( 'supports render prop on Root', () => {
149
+ const ref = createRef< HTMLDivElement >();
150
+ render(
151
+ <Collapsible.Root ref={ ref } render={ <section /> }>
152
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
153
+ <Collapsible.Panel>Content</Collapsible.Panel>
154
+ </Collapsible.Root>
155
+ );
156
+ expect( ref.current?.tagName ).toBe( 'SECTION' );
157
+ } );
158
+
159
+ it( 'supports render prop on Trigger', () => {
160
+ render(
161
+ <Collapsible.Root>
162
+ <Collapsible.Trigger
163
+ nativeButton={ false }
164
+ render={ <div /> }
165
+ >
166
+ Toggle
167
+ </Collapsible.Trigger>
168
+ <Collapsible.Panel>Content</Collapsible.Panel>
169
+ </Collapsible.Root>
170
+ );
171
+ const trigger = screen.getByRole( 'button', { name: 'Toggle' } );
172
+ expect( trigger.tagName ).toBe( 'DIV' );
173
+ } );
174
+
175
+ it( 'supports render prop on Panel', () => {
176
+ const ref = createRef< HTMLDivElement >();
177
+ render(
178
+ <Collapsible.Root defaultOpen>
179
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
180
+ <Collapsible.Panel ref={ ref } render={ <section /> }>
181
+ Content
182
+ </Collapsible.Panel>
183
+ </Collapsible.Root>
184
+ );
185
+ expect( ref.current?.tagName ).toBe( 'SECTION' );
186
+ } );
187
+ } );
188
+
189
+ describe( 'custom className', () => {
190
+ it( 'applies className to Root', () => {
191
+ const ref = createRef< HTMLDivElement >();
192
+ render(
193
+ <Collapsible.Root ref={ ref } className="custom-root">
194
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
195
+ <Collapsible.Panel>Content</Collapsible.Panel>
196
+ </Collapsible.Root>
197
+ );
198
+ expect( ref.current ).toHaveClass( 'custom-root' );
199
+ } );
200
+
201
+ it( 'applies className to Trigger', () => {
202
+ render(
203
+ <Collapsible.Root>
204
+ <Collapsible.Trigger className="custom-trigger">
205
+ Toggle
206
+ </Collapsible.Trigger>
207
+ <Collapsible.Panel>Content</Collapsible.Panel>
208
+ </Collapsible.Root>
209
+ );
210
+ expect(
211
+ screen.getByRole( 'button', { name: 'Toggle' } )
212
+ ).toHaveClass( 'custom-trigger' );
213
+ } );
214
+
215
+ it( 'applies className to Panel', () => {
216
+ const ref = createRef< HTMLDivElement >();
217
+ render(
218
+ <Collapsible.Root defaultOpen>
219
+ <Collapsible.Trigger>Toggle</Collapsible.Trigger>
220
+ <Collapsible.Panel ref={ ref } className="custom-panel">
221
+ Content
222
+ </Collapsible.Panel>
223
+ </Collapsible.Root>
224
+ );
225
+ expect( ref.current ).toHaveClass( 'custom-panel' );
226
+ } );
227
+ } );
228
+ } );
@@ -0,0 +1,15 @@
1
+ import { Collapsible as _Collapsible } from '@base-ui/react/collapsible';
2
+ import { forwardRef } from '@wordpress/element';
3
+ import type { TriggerProps } from './types';
4
+
5
+ /**
6
+ * A button that opens and closes the collapsible panel.
7
+ *
8
+ * `Collapsible` is a collection of React components that combine to render
9
+ * a collapsible panel controlled by a button.
10
+ */
11
+ export const Trigger = forwardRef< HTMLButtonElement, TriggerProps >(
12
+ function CollapsibleTrigger( props, forwardedRef ) {
13
+ return <_Collapsible.Trigger ref={ forwardedRef } { ...props } />;
14
+ }
15
+ );
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { Collapsible as _Collapsible } from '@base-ui/react/collapsible';
3
+ import type { ComponentProps } from '../utils/types';
4
+
5
+ export type RootProps = ComponentProps< typeof _Collapsible.Root > & {
6
+ /**
7
+ * The content to be rendered inside the component.
8
+ */
9
+ children?: ReactNode;
10
+ };
11
+
12
+ export type TriggerProps = ComponentProps< typeof _Collapsible.Trigger > & {
13
+ /**
14
+ * The content to be rendered inside the component.
15
+ */
16
+ children?: ReactNode;
17
+ };
18
+
19
+ export type PanelProps = ComponentProps< typeof _Collapsible.Panel > & {
20
+ /**
21
+ * The content to be rendered inside the component.
22
+ */
23
+ children?: ReactNode;
24
+ };
@@ -1,6 +1,8 @@
1
- import { Collapsible } from '@base-ui/react/collapsible';
2
1
  import { forwardRef } from '@wordpress/element';
2
+ import clsx from 'clsx';
3
3
  import * as Card from '../card';
4
+ import * as Collapsible from '../collapsible';
5
+ import styles from './style.module.css';
4
6
  import type { ContentProps } from './types';
5
7
 
6
8
  /**
@@ -8,13 +10,24 @@ import type { ContentProps } from './types';
8
10
  * visible when expanded.
9
11
  */
10
12
  export const Content = forwardRef< HTMLDivElement, ContentProps >(
11
- function CollapsibleCardContent( { render, ...restProps }, ref ) {
13
+ function CollapsibleCardContent(
14
+ { className, render, children, hiddenUntilFound = true, ...restProps },
15
+ ref
16
+ ) {
12
17
  return (
13
18
  <Collapsible.Panel
14
19
  ref={ ref }
15
- render={ <Card.Content render={ render } /> }
20
+ className={ clsx( styles.content, className ) }
21
+ hiddenUntilFound={ hiddenUntilFound }
16
22
  { ...restProps }
17
- />
23
+ >
24
+ <Card.Content
25
+ className={ styles[ 'content-inner' ] }
26
+ render={ render }
27
+ >
28
+ { children }
29
+ </Card.Content>
30
+ </Collapsible.Panel>
18
31
  );
19
32
  }
20
33
  );
@@ -0,0 +1,7 @@
1
+ import { createContext } from '@wordpress/element';
2
+
3
+ export const HeaderDescriptionIdContext = createContext< {
4
+ setDescriptionId: ( id: string | undefined ) => void;
5
+ } >( {
6
+ setDescriptionId: () => {},
7
+ } );
@@ -0,0 +1,43 @@
1
+ import { forwardRef, useContext, useEffect, useId } from '@wordpress/element';
2
+ import { HeaderDescriptionIdContext } from './context';
3
+ import type { HeaderDescriptionProps } from './types';
4
+
5
+ /**
6
+ * Secondary content placed in the collapsible card header that describes
7
+ * the trigger button via `aria-describedby`. Use it for supplementary
8
+ * information such as status badges or summary values.
9
+ *
10
+ * The content is visually rendered but marked `aria-hidden` so that
11
+ * assistive technologies consume it only through the `aria-describedby`
12
+ * relationship on the trigger, avoiding double announcements.
13
+ *
14
+ * Avoid interactive elements (buttons, links, inputs) inside this
15
+ * component — the entire header is the toggle trigger.
16
+ */
17
+ export const HeaderDescription = forwardRef<
18
+ HTMLDivElement,
19
+ HeaderDescriptionProps
20
+ >( function CollapsibleCardHeaderDescription(
21
+ { children, className, ...restProps },
22
+ ref
23
+ ) {
24
+ const descriptionId = useId();
25
+ const { setDescriptionId } = useContext( HeaderDescriptionIdContext );
26
+
27
+ useEffect( () => {
28
+ setDescriptionId( descriptionId );
29
+ return () => setDescriptionId( undefined );
30
+ }, [ descriptionId, setDescriptionId ] );
31
+
32
+ return (
33
+ <div
34
+ ref={ ref }
35
+ id={ descriptionId }
36
+ aria-hidden="true"
37
+ className={ className }
38
+ { ...restProps }
39
+ >
40
+ { children }
41
+ </div>
42
+ );
43
+ } );
@@ -1,12 +1,12 @@
1
- import { Collapsible } from '@base-ui/react/collapsible';
2
1
  import clsx from 'clsx';
3
- import type { MouseEvent } from 'react';
4
- import { forwardRef, useCallback, useRef } from '@wordpress/element';
5
- import { __ } from '@wordpress/i18n';
6
- import { chevronDown, chevronUp } from '@wordpress/icons';
2
+ import { forwardRef, useMemo, useState } from '@wordpress/element';
3
+ import { chevronDown } from '@wordpress/icons';
7
4
  import * as Card from '../card';
8
- import { IconButton } from '../icon-button';
5
+ import * as Collapsible from '../collapsible';
6
+ import { Icon } from '../icon';
9
7
  import styles from './style.module.css';
8
+ import focusStyles from '../utils/css/focus.module.css';
9
+ import { HeaderDescriptionIdContext } from './context';
10
10
  import type { HeaderProps } from './types';
11
11
 
12
12
  /**
@@ -20,52 +20,57 @@ import type { HeaderProps } from './types';
20
20
  */
21
21
  export const Header = forwardRef< HTMLDivElement, HeaderProps >(
22
22
  function CollapsibleCardHeader(
23
- { children, className, onClick, ...restProps },
23
+ { children, className, render, ...restProps },
24
24
  ref
25
25
  ) {
26
- const triggerRef = useRef< HTMLButtonElement >( null );
26
+ const [ descriptionId, setDescriptionId ] = useState< string >();
27
27
 
28
- const handleHeaderClick = useCallback(
29
- ( event: MouseEvent< HTMLDivElement > ) => {
30
- const trigger = triggerRef.current;
31
- if (
32
- trigger &&
33
- event.target instanceof Node &&
34
- ! trigger.contains( event.target )
35
- ) {
36
- trigger.click();
37
- }
38
-
39
- onClick?.( event );
40
- },
41
- [ onClick ]
28
+ const contextValue = useMemo(
29
+ () => ( { setDescriptionId } ),
30
+ [ setDescriptionId ]
42
31
  );
43
32
 
44
33
  return (
45
- <Card.Header
46
- ref={ ref }
47
- className={ clsx( styles.header, className ) }
48
- onClick={ handleHeaderClick }
49
- { ...restProps }
50
- >
51
- <div className={ styles[ 'header-content' ] }>{ children }</div>
52
- <div className={ styles[ 'header-trigger-wrapper' ] }>
53
- <Collapsible.Trigger
54
- ref={ triggerRef }
55
- render={ ( props, state ) => (
56
- <IconButton
57
- { ...props }
58
- label={ __( 'Expand or collapse card' ) }
59
- icon={ state.open ? chevronUp : chevronDown }
60
- variant="minimal"
61
- tone="neutral"
62
- size="compact"
63
- />
34
+ <HeaderDescriptionIdContext.Provider value={ contextValue }>
35
+ <Collapsible.Trigger
36
+ className={ clsx( styles.header, className ) }
37
+ render={
38
+ <Card.Header
39
+ ref={ ref }
40
+ render={ render }
41
+ { ...restProps }
42
+ />
43
+ }
44
+ nativeButton={ false }
45
+ aria-describedby={ descriptionId }
46
+ >
47
+ <div className={ styles[ 'header-content' ] }>
48
+ { children }
49
+ </div>
50
+ <div
51
+ className={ clsx(
52
+ styles[ 'header-trigger-positioner' ]
64
53
  ) }
65
- className={ styles[ 'header-trigger' ] }
66
- />
67
- </div>
68
- </Card.Header>
54
+ >
55
+ <div
56
+ className={ clsx(
57
+ styles[ 'header-trigger-wrapper' ],
58
+ // While the interactive trigger element is the whole header,
59
+ // the focus ring will be displayed only on the icon to visually
60
+ // emulate it being the button.
61
+ focusStyles[
62
+ 'outset-ring--focus-parent-visible'
63
+ ]
64
+ ) }
65
+ >
66
+ <Icon
67
+ icon={ chevronDown }
68
+ className={ styles[ 'header-trigger' ] }
69
+ />
70
+ </div>
71
+ </div>
72
+ </Collapsible.Trigger>
73
+ </HeaderDescriptionIdContext.Provider>
69
74
  );
70
75
  }
71
76
  );
@@ -1,5 +1,6 @@
1
1
  import { Root } from './root';
2
2
  import { Header } from './header';
3
+ import { HeaderDescription } from './header-description';
3
4
  import { Content } from './content';
4
5
 
5
- export { Root, Header, Content };
6
+ export { Root, Header, HeaderDescription, Content };
@@ -1,6 +1,6 @@
1
- import { Collapsible } from '@base-ui/react/collapsible';
2
1
  import { forwardRef } from '@wordpress/element';
3
2
  import * as Card from '../card';
3
+ import * as Collapsible from '../collapsible';
4
4
  import type { RootProps } from './types';
5
5
 
6
6
  /**