@wordpress/ui 0.11.0 → 0.12.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 (660) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +4 -4
  3. package/build/alert-dialog/index.cjs +3 -0
  4. package/build/alert-dialog/index.cjs.map +2 -2
  5. package/build/alert-dialog/popup.cjs +120 -55
  6. package/build/alert-dialog/popup.cjs.map +3 -3
  7. package/build/alert-dialog/portal.cjs +38 -0
  8. package/build/alert-dialog/portal.cjs.map +7 -0
  9. package/build/alert-dialog/types.cjs.map +1 -1
  10. package/build/collapsible-card/content.cjs +9 -5
  11. package/build/collapsible-card/content.cjs.map +2 -2
  12. package/build/collapsible-card/header.cjs +14 -4
  13. package/build/collapsible-card/header.cjs.map +3 -3
  14. package/build/dialog/content.cjs +85 -0
  15. package/build/dialog/content.cjs.map +7 -0
  16. package/build/dialog/context.cjs +12 -44
  17. package/build/dialog/context.cjs.map +2 -2
  18. package/build/dialog/description.cjs +59 -0
  19. package/build/dialog/description.cjs.map +7 -0
  20. package/build/dialog/footer.cjs +5 -4
  21. package/build/dialog/footer.cjs.map +2 -2
  22. package/build/dialog/header.cjs +5 -4
  23. package/build/dialog/header.cjs.map +2 -2
  24. package/build/dialog/index.cjs +9 -0
  25. package/build/dialog/index.cjs.map +2 -2
  26. package/build/dialog/popup.cjs +21 -9
  27. package/build/dialog/popup.cjs.map +2 -2
  28. package/build/dialog/portal.cjs +38 -0
  29. package/build/dialog/portal.cjs.map +7 -0
  30. package/build/dialog/root.cjs +3 -2
  31. package/build/dialog/root.cjs.map +2 -2
  32. package/build/dialog/title.cjs +9 -6
  33. package/build/dialog/title.cjs.map +2 -2
  34. package/build/dialog/types.cjs.map +1 -1
  35. package/build/drawer/action.cjs +48 -0
  36. package/build/drawer/action.cjs.map +7 -0
  37. package/build/drawer/close-icon.cjs +58 -0
  38. package/build/drawer/close-icon.cjs.map +7 -0
  39. package/build/drawer/content.cjs +86 -0
  40. package/build/drawer/content.cjs.map +7 -0
  41. package/build/drawer/context.cjs +44 -0
  42. package/build/drawer/context.cjs.map +7 -0
  43. package/build/drawer/description.cjs +47 -0
  44. package/build/drawer/description.cjs.map +7 -0
  45. package/build/drawer/footer.cjs +65 -0
  46. package/build/drawer/footer.cjs.map +7 -0
  47. package/build/drawer/header.cjs +65 -0
  48. package/build/drawer/header.cjs.map +7 -0
  49. package/build/drawer/index.cjs +61 -0
  50. package/build/drawer/index.cjs.map +7 -0
  51. package/build/drawer/popup.cjs +103 -0
  52. package/build/drawer/popup.cjs.map +7 -0
  53. package/build/drawer/portal.cjs +38 -0
  54. package/build/drawer/portal.cjs.map +7 -0
  55. package/build/drawer/root.cjs +49 -0
  56. package/build/drawer/root.cjs.map +7 -0
  57. package/build/drawer/title.cjs +70 -0
  58. package/build/drawer/title.cjs.map +7 -0
  59. package/build/drawer/trigger.cjs +38 -0
  60. package/build/drawer/trigger.cjs.map +7 -0
  61. package/build/drawer/types.cjs +19 -0
  62. package/build/drawer/types.cjs.map +7 -0
  63. package/build/form/primitives/autocomplete/clear.cjs +62 -0
  64. package/build/form/primitives/autocomplete/clear.cjs.map +7 -0
  65. package/build/form/primitives/autocomplete/collection.cjs +38 -0
  66. package/build/form/primitives/autocomplete/collection.cjs.map +7 -0
  67. package/build/form/primitives/autocomplete/empty.cjs +67 -0
  68. package/build/form/primitives/autocomplete/empty.cjs.map +7 -0
  69. package/build/form/primitives/autocomplete/index.cjs +64 -0
  70. package/build/form/primitives/autocomplete/index.cjs.map +7 -0
  71. package/build/form/primitives/autocomplete/input-group.cjs +36 -0
  72. package/build/form/primitives/autocomplete/input-group.cjs.map +7 -0
  73. package/build/form/primitives/autocomplete/input.cjs +47 -0
  74. package/build/form/primitives/autocomplete/input.cjs.map +7 -0
  75. package/build/form/primitives/autocomplete/item.cjs +81 -0
  76. package/build/form/primitives/autocomplete/item.cjs.map +7 -0
  77. package/build/form/primitives/autocomplete/list-body.cjs +57 -0
  78. package/build/form/primitives/autocomplete/list-body.cjs.map +7 -0
  79. package/build/form/primitives/autocomplete/list.cjs +67 -0
  80. package/build/form/primitives/autocomplete/list.cjs.map +7 -0
  81. package/build/form/primitives/autocomplete/popup.cjs +102 -0
  82. package/build/form/primitives/autocomplete/popup.cjs.map +7 -0
  83. package/build/form/primitives/autocomplete/portal.cjs +38 -0
  84. package/build/form/primitives/autocomplete/portal.cjs.map +7 -0
  85. package/build/form/primitives/autocomplete/root.cjs +35 -0
  86. package/build/form/primitives/autocomplete/root.cjs.map +7 -0
  87. package/build/form/primitives/autocomplete/types.cjs +19 -0
  88. package/build/form/primitives/autocomplete/types.cjs.map +7 -0
  89. package/build/form/primitives/autocomplete/value.cjs +35 -0
  90. package/build/form/primitives/autocomplete/value.cjs.map +7 -0
  91. package/build/form/primitives/index.cjs +3 -0
  92. package/build/form/primitives/index.cjs.map +2 -2
  93. package/build/form/primitives/select/index.cjs +3 -0
  94. package/build/form/primitives/select/index.cjs.map +2 -2
  95. package/build/form/primitives/select/item.cjs +4 -5
  96. package/build/form/primitives/select/item.cjs.map +2 -2
  97. package/build/form/primitives/select/popup.cjs +12 -11
  98. package/build/form/primitives/select/popup.cjs.map +2 -2
  99. package/build/form/primitives/select/portal.cjs +38 -0
  100. package/build/form/primitives/select/portal.cjs.map +7 -0
  101. package/build/form/primitives/select/types.cjs.map +1 -1
  102. package/build/index.cjs +3 -0
  103. package/build/index.cjs.map +2 -2
  104. package/build/link/link.cjs +8 -18
  105. package/build/link/link.cjs.map +2 -2
  106. package/build/link/types.cjs.map +1 -1
  107. package/build/notice/action-button.cjs +3 -3
  108. package/build/notice/action-button.cjs.map +2 -2
  109. package/build/notice/action-link.cjs +8 -7
  110. package/build/notice/action-link.cjs.map +2 -2
  111. package/build/notice/actions.cjs +3 -3
  112. package/build/notice/actions.cjs.map +2 -2
  113. package/build/notice/close-icon.cjs +3 -3
  114. package/build/notice/close-icon.cjs.map +2 -2
  115. package/build/notice/description.cjs +3 -3
  116. package/build/notice/description.cjs.map +2 -2
  117. package/build/notice/root.cjs +3 -3
  118. package/build/notice/root.cjs.map +2 -2
  119. package/build/notice/title.cjs +3 -3
  120. package/build/notice/title.cjs.map +2 -2
  121. package/build/popover/arrow.cjs +4 -4
  122. package/build/popover/arrow.cjs.map +2 -2
  123. package/build/popover/context.cjs +4 -44
  124. package/build/popover/context.cjs.map +2 -2
  125. package/build/popover/description.cjs +1 -24
  126. package/build/popover/description.cjs.map +4 -4
  127. package/build/popover/index.cjs +3 -0
  128. package/build/popover/index.cjs.map +2 -2
  129. package/build/popover/popup.cjs +15 -15
  130. package/build/popover/popup.cjs.map +2 -2
  131. package/build/popover/portal.cjs +38 -0
  132. package/build/popover/portal.cjs.map +7 -0
  133. package/build/popover/root.cjs.map +1 -1
  134. package/build/popover/title.cjs +18 -4
  135. package/build/popover/title.cjs.map +3 -3
  136. package/build/popover/types.cjs.map +1 -1
  137. package/build/tabs/context.cjs +9 -22
  138. package/build/tabs/context.cjs.map +2 -2
  139. package/build/tabs/list.cjs +4 -4
  140. package/build/tabs/list.cjs.map +2 -2
  141. package/build/tabs/panel.cjs +19 -6
  142. package/build/tabs/panel.cjs.map +3 -3
  143. package/build/tabs/tab.cjs +4 -4
  144. package/build/tabs/tab.cjs.map +2 -2
  145. package/build/text/text.cjs +2 -2
  146. package/build/text/text.cjs.map +2 -2
  147. package/build/tooltip/index.cjs +3 -0
  148. package/build/tooltip/index.cjs.map +2 -2
  149. package/build/tooltip/popup.cjs +11 -14
  150. package/build/tooltip/popup.cjs.map +3 -3
  151. package/build/tooltip/portal.cjs +38 -0
  152. package/build/tooltip/portal.cjs.map +7 -0
  153. package/build/tooltip/provider.cjs +2 -2
  154. package/build/tooltip/provider.cjs.map +3 -3
  155. package/build/tooltip/root.cjs.map +3 -3
  156. package/build/tooltip/trigger.cjs +2 -2
  157. package/build/tooltip/trigger.cjs.map +3 -3
  158. package/build/tooltip/types.cjs.map +1 -1
  159. package/build/utils/create-overlay-modal-context.cjs +48 -0
  160. package/build/utils/create-overlay-modal-context.cjs.map +7 -0
  161. package/build/utils/create-overlay-title-validation.cjs +93 -0
  162. package/build/utils/create-overlay-title-validation.cjs.map +7 -0
  163. package/build/utils/render-portal-with-children.cjs +37 -0
  164. package/build/utils/render-portal-with-children.cjs.map +7 -0
  165. package/build/utils/use-deprioritized-initial-focus.cjs +8 -8
  166. package/build/utils/use-deprioritized-initial-focus.cjs.map +2 -2
  167. package/build/utils/use-overlay-scroll-state-attributes.cjs +140 -0
  168. package/build/utils/use-overlay-scroll-state-attributes.cjs.map +7 -0
  169. package/build/utils/use-schedule-validation.cjs +59 -0
  170. package/build/utils/use-schedule-validation.cjs.map +7 -0
  171. package/build/visually-hidden/visually-hidden.cjs +5 -1
  172. package/build/visually-hidden/visually-hidden.cjs.map +2 -2
  173. package/build-module/alert-dialog/index.mjs +2 -0
  174. package/build-module/alert-dialog/index.mjs.map +2 -2
  175. package/build-module/alert-dialog/popup.mjs +124 -56
  176. package/build-module/alert-dialog/popup.mjs.map +3 -3
  177. package/build-module/alert-dialog/portal.mjs +13 -0
  178. package/build-module/alert-dialog/portal.mjs.map +7 -0
  179. package/build-module/collapsible-card/content.mjs +9 -5
  180. package/build-module/collapsible-card/content.mjs.map +2 -2
  181. package/build-module/collapsible-card/header.mjs +14 -4
  182. package/build-module/collapsible-card/header.mjs.map +3 -3
  183. package/build-module/dialog/content.mjs +50 -0
  184. package/build-module/dialog/content.mjs.map +7 -0
  185. package/build-module/dialog/context.mjs +10 -51
  186. package/build-module/dialog/context.mjs.map +2 -2
  187. package/build-module/dialog/description.mjs +34 -0
  188. package/build-module/dialog/description.mjs.map +7 -0
  189. package/build-module/dialog/footer.mjs +5 -4
  190. package/build-module/dialog/footer.mjs.map +2 -2
  191. package/build-module/dialog/header.mjs +5 -4
  192. package/build-module/dialog/header.mjs.map +2 -2
  193. package/build-module/dialog/index.mjs +6 -0
  194. package/build-module/dialog/index.mjs.map +2 -2
  195. package/build-module/dialog/popup.mjs +23 -11
  196. package/build-module/dialog/popup.mjs.map +2 -2
  197. package/build-module/dialog/portal.mjs +13 -0
  198. package/build-module/dialog/portal.mjs.map +7 -0
  199. package/build-module/dialog/root.mjs +3 -2
  200. package/build-module/dialog/root.mjs.map +2 -2
  201. package/build-module/dialog/title.mjs +10 -7
  202. package/build-module/dialog/title.mjs.map +2 -2
  203. package/build-module/drawer/action.mjs +23 -0
  204. package/build-module/drawer/action.mjs.map +7 -0
  205. package/build-module/drawer/close-icon.mjs +33 -0
  206. package/build-module/drawer/close-icon.mjs.map +7 -0
  207. package/build-module/drawer/content.mjs +51 -0
  208. package/build-module/drawer/content.mjs.map +7 -0
  209. package/build-module/drawer/context.mjs +16 -0
  210. package/build-module/drawer/context.mjs.map +7 -0
  211. package/build-module/drawer/description.mjs +22 -0
  212. package/build-module/drawer/description.mjs.map +7 -0
  213. package/build-module/drawer/footer.mjs +30 -0
  214. package/build-module/drawer/footer.mjs.map +7 -0
  215. package/build-module/drawer/header.mjs +30 -0
  216. package/build-module/drawer/header.mjs.map +7 -0
  217. package/build-module/drawer/index.mjs +26 -0
  218. package/build-module/drawer/index.mjs.map +7 -0
  219. package/build-module/drawer/popup.mjs +70 -0
  220. package/build-module/drawer/popup.mjs.map +7 -0
  221. package/build-module/drawer/portal.mjs +13 -0
  222. package/build-module/drawer/portal.mjs.map +7 -0
  223. package/build-module/drawer/root.mjs +24 -0
  224. package/build-module/drawer/root.mjs.map +7 -0
  225. package/build-module/drawer/title.mjs +45 -0
  226. package/build-module/drawer/title.mjs.map +7 -0
  227. package/build-module/drawer/trigger.mjs +13 -0
  228. package/build-module/drawer/trigger.mjs.map +7 -0
  229. package/build-module/drawer/types.mjs +1 -0
  230. package/build-module/form/primitives/autocomplete/clear.mjs +37 -0
  231. package/build-module/form/primitives/autocomplete/clear.mjs.map +7 -0
  232. package/build-module/form/primitives/autocomplete/collection.mjs +13 -0
  233. package/build-module/form/primitives/autocomplete/collection.mjs.map +7 -0
  234. package/build-module/form/primitives/autocomplete/empty.mjs +32 -0
  235. package/build-module/form/primitives/autocomplete/empty.mjs.map +7 -0
  236. package/build-module/form/primitives/autocomplete/index.mjs +28 -0
  237. package/build-module/form/primitives/autocomplete/index.mjs.map +7 -0
  238. package/build-module/form/primitives/autocomplete/input-group.mjs +11 -0
  239. package/build-module/form/primitives/autocomplete/input-group.mjs.map +7 -0
  240. package/build-module/form/primitives/autocomplete/input.mjs +22 -0
  241. package/build-module/form/primitives/autocomplete/input.mjs.map +7 -0
  242. package/build-module/form/primitives/autocomplete/item.mjs +46 -0
  243. package/build-module/form/primitives/autocomplete/item.mjs.map +7 -0
  244. package/build-module/form/primitives/autocomplete/list-body.mjs +32 -0
  245. package/build-module/form/primitives/autocomplete/list-body.mjs.map +7 -0
  246. package/build-module/form/primitives/autocomplete/list.mjs +32 -0
  247. package/build-module/form/primitives/autocomplete/list.mjs.map +7 -0
  248. package/build-module/form/primitives/autocomplete/popup.mjs +69 -0
  249. package/build-module/form/primitives/autocomplete/popup.mjs.map +7 -0
  250. package/build-module/form/primitives/autocomplete/portal.mjs +13 -0
  251. package/build-module/form/primitives/autocomplete/portal.mjs.map +7 -0
  252. package/build-module/form/primitives/autocomplete/root.mjs +10 -0
  253. package/build-module/form/primitives/autocomplete/root.mjs.map +7 -0
  254. package/build-module/form/primitives/autocomplete/types.mjs +1 -0
  255. package/build-module/form/primitives/autocomplete/value.mjs +10 -0
  256. package/build-module/form/primitives/autocomplete/value.mjs.map +7 -0
  257. package/build-module/form/primitives/index.mjs +2 -0
  258. package/build-module/form/primitives/index.mjs.map +2 -2
  259. package/build-module/form/primitives/select/index.mjs +2 -0
  260. package/build-module/form/primitives/select/index.mjs.map +2 -2
  261. package/build-module/form/primitives/select/item.mjs +4 -5
  262. package/build-module/form/primitives/select/item.mjs.map +2 -2
  263. package/build-module/form/primitives/select/popup.mjs +12 -11
  264. package/build-module/form/primitives/select/popup.mjs.map +2 -2
  265. package/build-module/form/primitives/select/portal.mjs +13 -0
  266. package/build-module/form/primitives/select/portal.mjs.map +7 -0
  267. package/build-module/index.mjs +2 -0
  268. package/build-module/index.mjs.map +2 -2
  269. package/build-module/link/link.mjs +8 -18
  270. package/build-module/link/link.mjs.map +2 -2
  271. package/build-module/notice/action-button.mjs +3 -3
  272. package/build-module/notice/action-button.mjs.map +2 -2
  273. package/build-module/notice/action-link.mjs +8 -7
  274. package/build-module/notice/action-link.mjs.map +2 -2
  275. package/build-module/notice/actions.mjs +3 -3
  276. package/build-module/notice/actions.mjs.map +2 -2
  277. package/build-module/notice/close-icon.mjs +3 -3
  278. package/build-module/notice/close-icon.mjs.map +2 -2
  279. package/build-module/notice/description.mjs +3 -3
  280. package/build-module/notice/description.mjs.map +2 -2
  281. package/build-module/notice/root.mjs +3 -3
  282. package/build-module/notice/root.mjs.map +2 -2
  283. package/build-module/notice/title.mjs +3 -3
  284. package/build-module/notice/title.mjs.map +2 -2
  285. package/build-module/popover/arrow.mjs +4 -4
  286. package/build-module/popover/arrow.mjs.map +2 -2
  287. package/build-module/popover/context.mjs +4 -51
  288. package/build-module/popover/context.mjs.map +2 -2
  289. package/build-module/popover/description.mjs +1 -14
  290. package/build-module/popover/description.mjs.map +3 -3
  291. package/build-module/popover/index.mjs +2 -0
  292. package/build-module/popover/index.mjs.map +2 -2
  293. package/build-module/popover/popup.mjs +16 -16
  294. package/build-module/popover/popup.mjs.map +2 -2
  295. package/build-module/popover/portal.mjs +13 -0
  296. package/build-module/popover/portal.mjs.map +7 -0
  297. package/build-module/popover/root.mjs.map +1 -1
  298. package/build-module/popover/title.mjs +19 -5
  299. package/build-module/popover/title.mjs.map +3 -3
  300. package/build-module/tabs/context.mjs +11 -24
  301. package/build-module/tabs/context.mjs.map +2 -2
  302. package/build-module/tabs/list.mjs +4 -4
  303. package/build-module/tabs/list.mjs.map +2 -2
  304. package/build-module/tabs/panel.mjs +19 -6
  305. package/build-module/tabs/panel.mjs.map +3 -3
  306. package/build-module/tabs/tab.mjs +4 -4
  307. package/build-module/tabs/tab.mjs.map +2 -2
  308. package/build-module/text/text.mjs +2 -2
  309. package/build-module/text/text.mjs.map +2 -2
  310. package/build-module/tooltip/index.mjs +2 -0
  311. package/build-module/tooltip/index.mjs.map +2 -2
  312. package/build-module/tooltip/popup.mjs +14 -17
  313. package/build-module/tooltip/popup.mjs.map +2 -2
  314. package/build-module/tooltip/portal.mjs +13 -0
  315. package/build-module/tooltip/portal.mjs.map +7 -0
  316. package/build-module/tooltip/provider.mjs +3 -3
  317. package/build-module/tooltip/provider.mjs.map +2 -2
  318. package/build-module/tooltip/root.mjs +2 -2
  319. package/build-module/tooltip/root.mjs.map +2 -2
  320. package/build-module/tooltip/trigger.mjs +3 -3
  321. package/build-module/tooltip/trigger.mjs.map +2 -2
  322. package/build-module/utils/create-overlay-modal-context.mjs +23 -0
  323. package/build-module/utils/create-overlay-modal-context.mjs.map +7 -0
  324. package/build-module/utils/create-overlay-title-validation.mjs +75 -0
  325. package/build-module/utils/create-overlay-title-validation.mjs.map +7 -0
  326. package/build-module/utils/render-portal-with-children.mjs +12 -0
  327. package/build-module/utils/render-portal-with-children.mjs.map +7 -0
  328. package/build-module/utils/use-deprioritized-initial-focus.mjs +9 -9
  329. package/build-module/utils/use-deprioritized-initial-focus.mjs.map +2 -2
  330. package/build-module/utils/use-overlay-scroll-state-attributes.mjs +114 -0
  331. package/build-module/utils/use-overlay-scroll-state-attributes.mjs.map +7 -0
  332. package/build-module/utils/use-schedule-validation.mjs +34 -0
  333. package/build-module/utils/use-schedule-validation.mjs.map +7 -0
  334. package/build-module/visually-hidden/visually-hidden.mjs +5 -1
  335. package/build-module/visually-hidden/visually-hidden.mjs.map +2 -2
  336. package/build-types/alert-dialog/index.d.ts +1 -0
  337. package/build-types/alert-dialog/index.d.ts.map +1 -1
  338. package/build-types/alert-dialog/popup.d.ts.map +1 -1
  339. package/build-types/alert-dialog/portal.d.ts +9 -0
  340. package/build-types/alert-dialog/portal.d.ts.map +1 -0
  341. package/build-types/alert-dialog/stories/index.story.d.ts +29 -1
  342. package/build-types/alert-dialog/stories/index.story.d.ts.map +1 -1
  343. package/build-types/alert-dialog/types.d.ts +25 -3
  344. package/build-types/alert-dialog/types.d.ts.map +1 -1
  345. package/build-types/badge/stories/index.story.d.ts.map +1 -1
  346. package/build-types/card/stories/index.story.d.ts.map +1 -1
  347. package/build-types/collapsible/stories/index.story.d.ts.map +1 -1
  348. package/build-types/collapsible-card/content.d.ts.map +1 -1
  349. package/build-types/collapsible-card/header.d.ts.map +1 -1
  350. package/build-types/collapsible-card/stories/index.story.d.ts.map +1 -1
  351. package/build-types/dialog/content.d.ts +17 -0
  352. package/build-types/dialog/content.d.ts.map +1 -0
  353. package/build-types/dialog/context.d.ts +11 -16
  354. package/build-types/dialog/context.d.ts.map +1 -1
  355. package/build-types/dialog/description.d.ts +9 -0
  356. package/build-types/dialog/description.d.ts.map +1 -0
  357. package/build-types/dialog/footer.d.ts +8 -1
  358. package/build-types/dialog/footer.d.ts.map +1 -1
  359. package/build-types/dialog/header.d.ts +8 -1
  360. package/build-types/dialog/header.d.ts.map +1 -1
  361. package/build-types/dialog/index.d.ts +4 -1
  362. package/build-types/dialog/index.d.ts.map +1 -1
  363. package/build-types/dialog/popup.d.ts +3 -0
  364. package/build-types/dialog/popup.d.ts.map +1 -1
  365. package/build-types/dialog/portal.d.ts +10 -0
  366. package/build-types/dialog/portal.d.ts.map +1 -0
  367. package/build-types/dialog/root.d.ts +14 -4
  368. package/build-types/dialog/root.d.ts.map +1 -1
  369. package/build-types/dialog/stories/index.story.d.ts +29 -6
  370. package/build-types/dialog/stories/index.story.d.ts.map +1 -1
  371. package/build-types/dialog/title.d.ts.map +1 -1
  372. package/build-types/dialog/types.d.ts +60 -7
  373. package/build-types/dialog/types.d.ts.map +1 -1
  374. package/build-types/drawer/action.d.ts +8 -0
  375. package/build-types/drawer/action.d.ts.map +1 -0
  376. package/build-types/drawer/close-icon.d.ts +8 -0
  377. package/build-types/drawer/close-icon.d.ts.map +1 -0
  378. package/build-types/drawer/content.d.ts +21 -0
  379. package/build-types/drawer/content.d.ts.map +1 -0
  380. package/build-types/drawer/context.d.ts +20 -0
  381. package/build-types/drawer/context.d.ts.map +1 -0
  382. package/build-types/drawer/description.d.ts +9 -0
  383. package/build-types/drawer/description.d.ts.map +1 -0
  384. package/build-types/drawer/footer.d.ts +15 -0
  385. package/build-types/drawer/footer.d.ts.map +1 -0
  386. package/build-types/drawer/header.d.ts +15 -0
  387. package/build-types/drawer/header.d.ts.map +1 -0
  388. package/build-types/drawer/index.d.ts +13 -0
  389. package/build-types/drawer/index.d.ts.map +1 -0
  390. package/build-types/drawer/popup.d.ts +16 -0
  391. package/build-types/drawer/popup.d.ts.map +1 -0
  392. package/build-types/drawer/portal.d.ts +10 -0
  393. package/build-types/drawer/portal.d.ts.map +1 -0
  394. package/build-types/drawer/root.d.ts +21 -0
  395. package/build-types/drawer/root.d.ts.map +1 -0
  396. package/build-types/drawer/stories/index.story.d.ts +63 -0
  397. package/build-types/drawer/stories/index.story.d.ts.map +1 -0
  398. package/build-types/drawer/test/index.test.d.ts +2 -0
  399. package/build-types/drawer/test/index.test.d.ts.map +1 -0
  400. package/build-types/drawer/title.d.ts +22 -0
  401. package/build-types/drawer/title.d.ts.map +1 -0
  402. package/build-types/drawer/trigger.d.ts +7 -0
  403. package/build-types/drawer/trigger.d.ts.map +1 -0
  404. package/build-types/drawer/types.d.ts +146 -0
  405. package/build-types/drawer/types.d.ts.map +1 -0
  406. package/build-types/empty-state/stories/index.story.d.ts +1 -1
  407. package/build-types/empty-state/stories/index.story.d.ts.map +1 -1
  408. package/build-types/form/input-control/stories/index.story.d.ts +1 -1
  409. package/build-types/form/input-control/stories/index.story.d.ts.map +1 -1
  410. package/build-types/form/primitives/autocomplete/clear.d.ts +13 -0
  411. package/build-types/form/primitives/autocomplete/clear.d.ts.map +1 -0
  412. package/build-types/form/primitives/autocomplete/collection.d.ts +3 -0
  413. package/build-types/form/primitives/autocomplete/collection.d.ts.map +1 -0
  414. package/build-types/form/primitives/autocomplete/empty.d.ts +10 -0
  415. package/build-types/form/primitives/autocomplete/empty.d.ts.map +1 -0
  416. package/build-types/form/primitives/autocomplete/index.d.ts +13 -0
  417. package/build-types/form/primitives/autocomplete/index.d.ts.map +1 -0
  418. package/build-types/form/primitives/autocomplete/input-group.d.ts +16 -0
  419. package/build-types/form/primitives/autocomplete/input-group.d.ts.map +1 -0
  420. package/build-types/form/primitives/autocomplete/input.d.ts +3 -0
  421. package/build-types/form/primitives/autocomplete/input.d.ts.map +1 -0
  422. package/build-types/form/primitives/autocomplete/item.d.ts +10 -0
  423. package/build-types/form/primitives/autocomplete/item.d.ts.map +1 -0
  424. package/build-types/form/primitives/autocomplete/list-body.d.ts +13 -0
  425. package/build-types/form/primitives/autocomplete/list-body.d.ts.map +1 -0
  426. package/build-types/form/primitives/autocomplete/list.d.ts +11 -0
  427. package/build-types/form/primitives/autocomplete/list.d.ts.map +1 -0
  428. package/build-types/form/primitives/autocomplete/popup.d.ts +11 -0
  429. package/build-types/form/primitives/autocomplete/popup.d.ts.map +1 -0
  430. package/build-types/form/primitives/autocomplete/portal.d.ts +8 -0
  431. package/build-types/form/primitives/autocomplete/portal.d.ts.map +1 -0
  432. package/build-types/form/primitives/autocomplete/root.d.ts +8 -0
  433. package/build-types/form/primitives/autocomplete/root.d.ts.map +1 -0
  434. package/build-types/form/primitives/autocomplete/stories/fixtures.d.ts +8 -0
  435. package/build-types/form/primitives/autocomplete/stories/fixtures.d.ts.map +1 -0
  436. package/build-types/form/primitives/autocomplete/stories/index.story.d.ts +41 -0
  437. package/build-types/form/primitives/autocomplete/stories/index.story.d.ts.map +1 -0
  438. package/build-types/form/primitives/autocomplete/test/index.test.d.ts +2 -0
  439. package/build-types/form/primitives/autocomplete/test/index.test.d.ts.map +1 -0
  440. package/build-types/form/primitives/autocomplete/types.d.ts +44 -0
  441. package/build-types/form/primitives/autocomplete/types.d.ts.map +1 -0
  442. package/build-types/form/primitives/autocomplete/value.d.ts +3 -0
  443. package/build-types/form/primitives/autocomplete/value.d.ts.map +1 -0
  444. package/build-types/form/primitives/field/stories/index.story.d.ts +1 -1
  445. package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
  446. package/build-types/form/primitives/fieldset/stories/index.story.d.ts +1 -1
  447. package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
  448. package/build-types/form/primitives/index.d.ts +1 -0
  449. package/build-types/form/primitives/index.d.ts.map +1 -1
  450. package/build-types/form/primitives/input/stories/index.story.d.ts +1 -1
  451. package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -1
  452. package/build-types/form/primitives/input-layout/stories/index.story.d.ts +1 -1
  453. package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -1
  454. package/build-types/form/primitives/select/index.d.ts +1 -0
  455. package/build-types/form/primitives/select/index.d.ts.map +1 -1
  456. package/build-types/form/primitives/select/item.d.ts.map +1 -1
  457. package/build-types/form/primitives/select/popup.d.ts +1 -2
  458. package/build-types/form/primitives/select/popup.d.ts.map +1 -1
  459. package/build-types/form/primitives/select/portal.d.ts +8 -0
  460. package/build-types/form/primitives/select/portal.d.ts.map +1 -0
  461. package/build-types/form/primitives/select/stories/index.story.d.ts +14 -6
  462. package/build-types/form/primitives/select/stories/index.story.d.ts.map +1 -1
  463. package/build-types/form/primitives/select/types.d.ts +7 -2
  464. package/build-types/form/primitives/select/types.d.ts.map +1 -1
  465. package/build-types/index.d.ts +1 -0
  466. package/build-types/index.d.ts.map +1 -1
  467. package/build-types/link/link.d.ts.map +1 -1
  468. package/build-types/link/stories/index.story.d.ts +2 -3
  469. package/build-types/link/stories/index.story.d.ts.map +1 -1
  470. package/build-types/link/types.d.ts +1 -2
  471. package/build-types/link/types.d.ts.map +1 -1
  472. package/build-types/notice/action-link.d.ts.map +1 -1
  473. package/build-types/popover/context.d.ts +6 -13
  474. package/build-types/popover/context.d.ts.map +1 -1
  475. package/build-types/popover/description.d.ts +0 -1
  476. package/build-types/popover/description.d.ts.map +1 -1
  477. package/build-types/popover/index.d.ts +2 -1
  478. package/build-types/popover/index.d.ts.map +1 -1
  479. package/build-types/popover/popup.d.ts +3 -2
  480. package/build-types/popover/popup.d.ts.map +1 -1
  481. package/build-types/popover/portal.d.ts +9 -0
  482. package/build-types/popover/portal.d.ts.map +1 -0
  483. package/build-types/popover/root.d.ts +2 -2
  484. package/build-types/popover/stories/index.story.d.ts +23 -15
  485. package/build-types/popover/stories/index.story.d.ts.map +1 -1
  486. package/build-types/popover/title.d.ts.map +1 -1
  487. package/build-types/popover/types.d.ts +8 -15
  488. package/build-types/popover/types.d.ts.map +1 -1
  489. package/build-types/stack/stories/index.story.d.ts.map +1 -1
  490. package/build-types/tabs/context.d.ts.map +1 -1
  491. package/build-types/tabs/panel.d.ts.map +1 -1
  492. package/build-types/tabs/stories/index.story.d.ts +1 -1
  493. package/build-types/tabs/stories/index.story.d.ts.map +1 -1
  494. package/build-types/text/stories/index.story.d.ts.map +1 -1
  495. package/build-types/tooltip/index.d.ts +2 -1
  496. package/build-types/tooltip/index.d.ts.map +1 -1
  497. package/build-types/tooltip/popup.d.ts.map +1 -1
  498. package/build-types/tooltip/portal.d.ts +8 -0
  499. package/build-types/tooltip/portal.d.ts.map +1 -0
  500. package/build-types/tooltip/provider.d.ts +1 -1
  501. package/build-types/tooltip/provider.d.ts.map +1 -1
  502. package/build-types/tooltip/stories/index.story.d.ts +18 -1
  503. package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
  504. package/build-types/tooltip/stories/usage-guidelines.story.d.ts.map +1 -1
  505. package/build-types/tooltip/trigger.d.ts.map +1 -1
  506. package/build-types/tooltip/types.d.ts +11 -7
  507. package/build-types/tooltip/types.d.ts.map +1 -1
  508. package/build-types/utils/create-overlay-modal-context.d.ts +14 -0
  509. package/build-types/utils/create-overlay-modal-context.d.ts.map +1 -0
  510. package/build-types/utils/create-overlay-title-validation.d.ts +15 -0
  511. package/build-types/utils/create-overlay-title-validation.d.ts.map +1 -0
  512. package/build-types/utils/render-portal-with-children.d.ts +16 -0
  513. package/build-types/utils/render-portal-with-children.d.ts.map +1 -0
  514. package/build-types/utils/use-deprioritized-initial-focus.d.ts +9 -8
  515. package/build-types/utils/use-deprioritized-initial-focus.d.ts.map +1 -1
  516. package/build-types/utils/use-overlay-scroll-state-attributes.d.ts +85 -0
  517. package/build-types/utils/use-overlay-scroll-state-attributes.d.ts.map +1 -0
  518. package/build-types/utils/use-schedule-validation.d.ts +13 -0
  519. package/build-types/utils/use-schedule-validation.d.ts.map +1 -0
  520. package/build-types/visually-hidden/stories/index.story.d.ts.map +1 -1
  521. package/build-types/visually-hidden/visually-hidden.d.ts +4 -20
  522. package/build-types/visually-hidden/visually-hidden.d.ts.map +1 -1
  523. package/package.json +12 -12
  524. package/src/alert-dialog/index.ts +1 -0
  525. package/src/alert-dialog/popup.tsx +114 -45
  526. package/src/alert-dialog/portal.tsx +17 -0
  527. package/src/alert-dialog/stories/index.story.tsx +123 -3
  528. package/src/alert-dialog/style.module.css +13 -4
  529. package/src/alert-dialog/test/index.test.tsx +329 -3
  530. package/src/alert-dialog/types.ts +30 -3
  531. package/src/badge/stories/choosing-intent.story.tsx +1 -1
  532. package/src/badge/stories/index.story.tsx +1 -0
  533. package/src/card/stories/index.story.tsx +1 -0
  534. package/src/collapsible/stories/index.story.tsx +1 -0
  535. package/src/collapsible-card/content.tsx +12 -1
  536. package/src/collapsible-card/header.tsx +2 -0
  537. package/src/collapsible-card/stories/index.story.tsx +1 -0
  538. package/src/collapsible-card/style.module.css +16 -4
  539. package/src/dialog/content.tsx +47 -0
  540. package/src/dialog/context.tsx +14 -98
  541. package/src/dialog/description.tsx +27 -0
  542. package/src/dialog/footer.tsx +10 -2
  543. package/src/dialog/header.tsx +10 -2
  544. package/src/dialog/index.ts +16 -1
  545. package/src/dialog/popup.tsx +28 -8
  546. package/src/dialog/portal.tsx +18 -0
  547. package/src/dialog/root.tsx +22 -5
  548. package/src/dialog/stories/index.story.tsx +195 -51
  549. package/src/dialog/style.module.css +73 -23
  550. package/src/dialog/test/index.test.tsx +849 -149
  551. package/src/dialog/title.tsx +6 -4
  552. package/src/dialog/types.ts +64 -6
  553. package/src/drawer/action.tsx +28 -0
  554. package/src/drawer/close-icon.tsx +33 -0
  555. package/src/drawer/content.tsx +50 -0
  556. package/src/drawer/context.tsx +29 -0
  557. package/src/drawer/description.tsx +25 -0
  558. package/src/drawer/footer.tsx +34 -0
  559. package/src/drawer/header.tsx +34 -0
  560. package/src/drawer/index.ts +25 -0
  561. package/src/drawer/popup.tsx +100 -0
  562. package/src/drawer/portal.tsx +18 -0
  563. package/src/drawer/root.tsx +41 -0
  564. package/src/drawer/stories/index.story.tsx +543 -0
  565. package/src/drawer/style.module.css +324 -0
  566. package/src/drawer/test/index.test.tsx +1097 -0
  567. package/src/drawer/title.tsx +53 -0
  568. package/src/drawer/trigger.tsx +14 -0
  569. package/src/drawer/types.ts +174 -0
  570. package/src/empty-state/stories/index.story.tsx +2 -1
  571. package/src/form/input-control/stories/index.story.tsx +4 -1
  572. package/src/form/primitives/autocomplete/clear.tsx +35 -0
  573. package/src/form/primitives/autocomplete/collection.tsx +13 -0
  574. package/src/form/primitives/autocomplete/empty.tsx +17 -0
  575. package/src/form/primitives/autocomplete/index.ts +12 -0
  576. package/src/form/primitives/autocomplete/input-group.tsx +16 -0
  577. package/src/form/primitives/autocomplete/input.tsx +20 -0
  578. package/src/form/primitives/autocomplete/item.tsx +24 -0
  579. package/src/form/primitives/autocomplete/list-body.tsx +23 -0
  580. package/src/form/primitives/autocomplete/list.tsx +17 -0
  581. package/src/form/primitives/autocomplete/popup.tsx +42 -0
  582. package/src/form/primitives/autocomplete/portal.tsx +16 -0
  583. package/src/form/primitives/autocomplete/root.tsx +11 -0
  584. package/src/form/primitives/autocomplete/stories/fixtures.ts +35 -0
  585. package/src/form/primitives/autocomplete/stories/index.story.tsx +437 -0
  586. package/src/form/primitives/autocomplete/style.module.css +7 -0
  587. package/src/form/primitives/autocomplete/test/index.test.tsx +162 -0
  588. package/src/form/primitives/autocomplete/types.ts +74 -0
  589. package/src/form/primitives/autocomplete/value.tsx +6 -0
  590. package/src/form/primitives/field/stories/index.story.tsx +1 -1
  591. package/src/form/primitives/fieldset/stories/index.story.tsx +1 -1
  592. package/src/form/primitives/index.ts +1 -0
  593. package/src/form/primitives/input/stories/index.story.tsx +2 -1
  594. package/src/form/primitives/input-layout/stories/index.story.tsx +2 -1
  595. package/src/form/primitives/select/index.ts +1 -0
  596. package/src/form/primitives/select/item.tsx +0 -1
  597. package/src/form/primitives/select/popup.tsx +34 -37
  598. package/src/form/primitives/select/portal.tsx +16 -0
  599. package/src/form/primitives/select/stories/index.story.tsx +21 -7
  600. package/src/form/primitives/select/test/index.test.tsx +7 -3
  601. package/src/form/primitives/select/types.ts +9 -2
  602. package/src/index.ts +1 -0
  603. package/src/link/link.tsx +12 -26
  604. package/src/link/stories/index.story.tsx +6 -11
  605. package/src/link/style.module.css +5 -17
  606. package/src/link/test/index.test.tsx +31 -27
  607. package/src/link/types.ts +1 -2
  608. package/src/notice/action-link.tsx +7 -4
  609. package/src/notice/style.module.css +5 -5
  610. package/src/popover/context.tsx +6 -89
  611. package/src/popover/description.tsx +1 -5
  612. package/src/popover/index.ts +2 -1
  613. package/src/popover/popup.tsx +17 -15
  614. package/src/popover/portal.tsx +17 -0
  615. package/src/popover/root.tsx +2 -2
  616. package/src/popover/stories/index.story.tsx +56 -25
  617. package/src/popover/style.module.css +33 -4
  618. package/src/popover/test/index.test.tsx +189 -74
  619. package/src/popover/title.tsx +9 -5
  620. package/src/popover/types.ts +10 -15
  621. package/src/stack/stories/index.story.tsx +1 -0
  622. package/src/tabs/context.tsx +14 -34
  623. package/src/tabs/panel.tsx +7 -2
  624. package/src/tabs/stories/index.story.tsx +2 -1
  625. package/src/tabs/style.module.css +0 -17
  626. package/src/tabs/test/index.test.tsx +7 -3
  627. package/src/text/stories/index.story.tsx +1 -0
  628. package/src/text/text.tsx +2 -2
  629. package/src/tooltip/index.ts +2 -1
  630. package/src/tooltip/popup.tsx +24 -28
  631. package/src/tooltip/portal.tsx +16 -0
  632. package/src/tooltip/provider.tsx +3 -3
  633. package/src/tooltip/root.tsx +2 -2
  634. package/src/tooltip/stories/index.story.tsx +39 -1
  635. package/src/tooltip/stories/usage-guidelines.story.tsx +5 -1
  636. package/src/tooltip/style.module.css +12 -0
  637. package/src/tooltip/test/index.test.tsx +9 -3
  638. package/src/tooltip/trigger.tsx +3 -7
  639. package/src/tooltip/types.ts +13 -7
  640. package/src/utils/create-overlay-modal-context.tsx +34 -0
  641. package/src/utils/create-overlay-title-validation.tsx +116 -0
  642. package/src/utils/css/item-popup.module.css +9 -11
  643. package/src/utils/css/overlay-chrome.module.css +222 -0
  644. package/src/utils/render-portal-with-children.ts +27 -0
  645. package/src/utils/test/use-deprioritized-initial-focus.test.tsx +3 -3
  646. package/src/utils/use-deprioritized-initial-focus.ts +23 -17
  647. package/src/utils/use-overlay-scroll-state-attributes.ts +272 -0
  648. package/src/utils/use-schedule-validation.ts +45 -0
  649. package/src/visually-hidden/stories/index.story.tsx +1 -0
  650. package/src/visually-hidden/visually-hidden.tsx +9 -21
  651. package/build/types/css-modules.d.cjs +0 -2
  652. package/build/types/react.d.cjs +0 -5
  653. package/build/types/react.d.cjs.map +0 -7
  654. package/build-module/types/css-modules.d.mjs +0 -1
  655. package/build-module/types/react.d.mjs +0 -3
  656. package/build-module/types/react.d.mjs.map +0 -7
  657. package/src/types/css-modules.d.ts +0 -4
  658. package/src/types/react.d.ts +0 -7
  659. /package/build-module/{types/css-modules.d.mjs.map → drawer/types.mjs.map} +0 -0
  660. /package/{build/types/css-modules.d.cjs.map → build-module/form/primitives/autocomplete/types.mjs.map} +0 -0
@@ -1,8 +1,21 @@
1
- import { render, screen, waitFor } from '@testing-library/react';
1
+ import { act, render, screen, waitFor } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
- import { Component, createRef, useState } from '@wordpress/element';
3
+ import { createRef, useState } from '@wordpress/element';
4
4
  import * as Popover from '../index';
5
5
 
6
+ function collectUncaughtErrors() {
7
+ const errors: Error[] = [];
8
+ const handler = ( event: ErrorEvent ) => {
9
+ event.preventDefault();
10
+ errors.push( event.error );
11
+ };
12
+ window.addEventListener( 'error', handler );
13
+ return {
14
+ errors,
15
+ cleanup: () => window.removeEventListener( 'error', handler ),
16
+ };
17
+ }
18
+
6
19
  describe( 'Popover', () => {
7
20
  describe( 'forwards ref', () => {
8
21
  it( 'should forward ref on Trigger', () => {
@@ -376,6 +389,35 @@ describe( 'Popover', () => {
376
389
  );
377
390
  } );
378
391
  } );
392
+
393
+ it( 'merges user `className` on Popover.Title with the internal one', async () => {
394
+ // Regression test for the shared `useRender` class-name merge
395
+ // that also covers Popover.Description and its Dialog/Drawer
396
+ // counterparts.
397
+ const user = userEvent.setup();
398
+
399
+ render(
400
+ <Popover.Root>
401
+ <Popover.Trigger>Open</Popover.Trigger>
402
+ <Popover.Popup>
403
+ <Popover.Title className="custom-title">
404
+ Title
405
+ </Popover.Title>
406
+ </Popover.Popup>
407
+ </Popover.Root>
408
+ );
409
+
410
+ await user.click( screen.getByRole( 'button', { name: 'Open' } ) );
411
+
412
+ const heading = await screen.findByRole( 'heading', {
413
+ name: 'Title',
414
+ } );
415
+ // The regression this guards against: `useRender` must still
416
+ // forward the user-supplied className to the underlying DOM node.
417
+ // CSS module classes are stubbed in the Jest environment, so we
418
+ // can only assert the user class end-to-end.
419
+ expect( heading ).toHaveClass( 'custom-title' );
420
+ } );
379
421
  } );
380
422
 
381
423
  describe( 'variant', () => {
@@ -421,7 +463,7 @@ describe( 'Popover', () => {
421
463
  } );
422
464
  } );
423
465
 
424
- describe( 'inline (via container)', () => {
466
+ describe( 'inline via portal (custom container)', () => {
425
467
  function InlinePopover() {
426
468
  const containerRef = createRef< HTMLSpanElement >();
427
469
  return (
@@ -432,7 +474,11 @@ describe( 'Popover', () => {
432
474
  ref={ containerRef }
433
475
  style={ { display: 'contents' } }
434
476
  />
435
- <Popover.Popup container={ containerRef }>
477
+ <Popover.Popup
478
+ portal={
479
+ <Popover.Portal container={ containerRef } />
480
+ }
481
+ >
436
482
  <Popover.Title>Title</Popover.Title>
437
483
  Inline content
438
484
  </Popover.Popup>
@@ -441,7 +487,7 @@ describe( 'Popover', () => {
441
487
  );
442
488
  }
443
489
 
444
- it( 'should render inside the container when a local ref is used', async () => {
490
+ it( 'should render inside the portal container when a local ref is used', async () => {
445
491
  const user = userEvent.setup();
446
492
 
447
493
  render( <InlinePopover /> );
@@ -613,84 +659,87 @@ describe( 'Popover', () => {
613
659
  } );
614
660
 
615
661
  describe( 'title validation', () => {
662
+ // Suppress console.error from React act() warnings and jsdom
663
+ // unhandled-error logging. Validation errors are caught via
664
+ // collectUncaughtErrors (window 'error' event) instead.
665
+ let originalConsoleError: typeof console.error;
666
+
667
+ beforeEach( () => {
668
+ // eslint-disable-next-line no-console
669
+ originalConsoleError = console.error;
670
+ // eslint-disable-next-line no-console
671
+ console.error = jest.fn();
672
+ } );
673
+
674
+ afterEach( () => {
675
+ // eslint-disable-next-line no-console
676
+ console.error = originalConsoleError;
677
+ } );
678
+
616
679
  it( 'should throw when Popover.Title is missing', async () => {
617
680
  const user = userEvent.setup();
618
- const onError = jest.fn();
619
-
620
- // Suppress console.error from React error boundary
621
- const spy = jest
622
- .spyOn( console, 'error' )
623
- .mockImplementation( () => {} );
681
+ const { errors, cleanup } = collectUncaughtErrors();
624
682
 
625
683
  render(
626
- <ErrorBoundary onError={ onError }>
627
- <Popover.Root>
628
- <Popover.Trigger>Open</Popover.Trigger>
629
- <Popover.Popup>No title here</Popover.Popup>
630
- </Popover.Root>
631
- </ErrorBoundary>
684
+ <Popover.Root>
685
+ <Popover.Trigger>Open</Popover.Trigger>
686
+ <Popover.Popup>No title here</Popover.Popup>
687
+ </Popover.Root>
632
688
  );
633
689
 
634
690
  await user.click( screen.getByRole( 'button', { name: 'Open' } ) );
635
691
 
636
692
  await waitFor( () => {
637
- expect( onError ).toHaveBeenCalledWith(
638
- expect.objectContaining( {
639
- message: expect.stringContaining(
640
- 'Missing <Popover.Title>'
641
- ),
642
- } )
643
- );
693
+ expect( errors.length ).toBeGreaterThan( 0 );
644
694
  } );
645
695
 
646
- spy.mockRestore();
696
+ expect( errors[ 0 ].message ).toBe(
697
+ 'Popover: Missing <Popover.Title>. ' +
698
+ 'For accessibility, every popover requires a title. ' +
699
+ 'If needed, the title can be visually hidden but must not be omitted.'
700
+ );
701
+
702
+ cleanup();
647
703
  } );
648
704
 
649
705
  it( 'should throw when Popover.Title is empty', async () => {
650
706
  const user = userEvent.setup();
651
- const onError = jest.fn();
652
-
653
- const spy = jest
654
- .spyOn( console, 'error' )
655
- .mockImplementation( () => {} );
707
+ const { errors, cleanup } = collectUncaughtErrors();
656
708
 
657
709
  render(
658
- <ErrorBoundary onError={ onError }>
659
- <Popover.Root>
660
- <Popover.Trigger>Open</Popover.Trigger>
661
- <Popover.Popup>
662
- <Popover.Title />
663
- </Popover.Popup>
664
- </Popover.Root>
665
- </ErrorBoundary>
710
+ <Popover.Root>
711
+ <Popover.Trigger>Open</Popover.Trigger>
712
+ <Popover.Popup>
713
+ <Popover.Title />
714
+ </Popover.Popup>
715
+ </Popover.Root>
666
716
  );
667
717
 
668
718
  await user.click( screen.getByRole( 'button', { name: 'Open' } ) );
669
719
 
670
720
  await waitFor( () => {
671
- expect( onError ).toHaveBeenCalledWith(
672
- expect.objectContaining( {
673
- message: expect.stringContaining( 'cannot be empty' ),
674
- } )
675
- );
721
+ expect( errors.length ).toBeGreaterThan( 0 );
676
722
  } );
677
723
 
678
- spy.mockRestore();
724
+ expect( errors[ 0 ].message ).toBe(
725
+ 'Popover: <Popover.Title> cannot be empty. ' +
726
+ 'Provide meaningful text content for the popover title.'
727
+ );
728
+
729
+ cleanup();
679
730
  } );
680
731
 
681
732
  it( 'should not throw when Popover.Title is present', async () => {
682
733
  const user = userEvent.setup();
683
- const onError = jest.fn();
734
+ const { errors, cleanup } = collectUncaughtErrors();
684
735
 
685
736
  render(
686
- <ErrorBoundary onError={ onError }>
687
- <Popover.Root>
688
- <Popover.Trigger>Open</Popover.Trigger>
689
- <Popover.Popup>
690
- <Popover.Title>Valid Title</Popover.Title>
691
- </Popover.Popup>
692
- </Popover.Root>
693
- </ErrorBoundary>
737
+ <Popover.Root>
738
+ <Popover.Trigger>Open</Popover.Trigger>
739
+ <Popover.Popup>
740
+ <Popover.Title>Valid Title</Popover.Title>
741
+ </Popover.Popup>
742
+ </Popover.Root>
694
743
  );
695
744
 
696
745
  await user.click( screen.getByRole( 'button', { name: 'Open' } ) );
@@ -699,29 +748,95 @@ describe( 'Popover', () => {
699
748
  expect( screen.getByText( 'Valid Title' ) ).toBeVisible();
700
749
  } );
701
750
 
702
- expect( onError ).not.toHaveBeenCalled();
751
+ await act(
752
+ () => new Promise( ( resolve ) => setTimeout( resolve, 50 ) )
753
+ );
754
+ expect( errors ).toHaveLength( 0 );
755
+
756
+ cleanup();
703
757
  } );
704
- } );
705
- } );
706
758
 
707
- class ErrorBoundary extends Component<
708
- { children: React.ReactNode; onError: ( error: Error ) => void },
709
- { hasError: boolean }
710
- > {
711
- state = { hasError: false };
759
+ it( 'should throw when title is removed after mount', async () => {
760
+ const { errors, cleanup } = collectUncaughtErrors();
761
+
762
+ const ui = ( showTitle: boolean ) => (
763
+ <Popover.Root defaultOpen>
764
+ <Popover.Trigger>Open</Popover.Trigger>
765
+ <Popover.Popup>
766
+ { showTitle && <Popover.Title>My Title</Popover.Title> }
767
+ <p>Content</p>
768
+ </Popover.Popup>
769
+ </Popover.Root>
770
+ );
771
+
772
+ const { rerender } = render( ui( true ) );
712
773
 
713
- static getDerivedStateFromError() {
714
- return { hasError: true };
715
- }
774
+ // Wait for the popover to render.
775
+ await waitFor( () => {
776
+ expect( screen.getByText( 'Content' ) ).toBeInTheDocument();
777
+ } );
716
778
 
717
- componentDidCatch( error: Error ) {
718
- this.props.onError( error );
719
- }
779
+ // Let initial validation settle — no errors expected.
780
+ await act(
781
+ () => new Promise( ( resolve ) => setTimeout( resolve, 50 ) )
782
+ );
783
+ expect( errors ).toHaveLength( 0 );
720
784
 
721
- render() {
722
- if ( this.state.hasError ) {
723
- return null;
724
- }
725
- return this.props.children;
726
- }
727
- }
785
+ // Remove the title via rerender.
786
+ rerender( ui( false ) );
787
+
788
+ await waitFor( () => {
789
+ expect( errors.length ).toBeGreaterThan( 0 );
790
+ } );
791
+
792
+ expect( errors[ 0 ].message ).toBe(
793
+ 'Popover: Missing <Popover.Title>. ' +
794
+ 'For accessibility, every popover requires a title. ' +
795
+ 'If needed, the title can be visually hidden but must not be omitted.'
796
+ );
797
+
798
+ cleanup();
799
+ } );
800
+
801
+ it( 'should recover when title is added back', async () => {
802
+ const { errors, cleanup } = collectUncaughtErrors();
803
+
804
+ const ui = ( showTitle: boolean ) => (
805
+ <Popover.Root defaultOpen>
806
+ <Popover.Trigger>Open</Popover.Trigger>
807
+ <Popover.Popup>
808
+ { showTitle && <Popover.Title>My Title</Popover.Title> }
809
+ <p>Content</p>
810
+ </Popover.Popup>
811
+ </Popover.Root>
812
+ );
813
+
814
+ const { rerender } = render( ui( false ) );
815
+
816
+ // Wait for the popover to render.
817
+ await waitFor( () => {
818
+ expect( screen.getByText( 'Content' ) ).toBeInTheDocument();
819
+ } );
820
+
821
+ // Initially no title — should error.
822
+ await waitFor( () => {
823
+ expect( errors.length ).toBeGreaterThan( 0 );
824
+ } );
825
+
826
+ const errorCountAfterInitial = errors.length;
827
+
828
+ // Add the title back via rerender.
829
+ rerender( ui( true ) );
830
+
831
+ // Wait for deferred validation to settle.
832
+ await act(
833
+ () => new Promise( ( resolve ) => setTimeout( resolve, 50 ) )
834
+ );
835
+
836
+ // No new errors should have been thrown.
837
+ expect( errors ).toHaveLength( errorCountAfterInitial );
838
+
839
+ cleanup();
840
+ } );
841
+ } );
842
+ } );
@@ -1,8 +1,9 @@
1
1
  import { Popover as _Popover } from '@base-ui/react/popover';
2
2
  import { useMergeRefs } from '@wordpress/compose';
3
- import { forwardRef, useLayoutEffect, useRef } from '@wordpress/element';
3
+ import { forwardRef, useEffect, useRef } from '@wordpress/element';
4
4
  import { Text } from '../text';
5
5
  import { usePopoverValidationContext } from './context';
6
+ import styles from './style.module.css';
6
7
  import type { TitleProps } from './types';
7
8
 
8
9
  /**
@@ -22,13 +23,16 @@ import type { TitleProps } from './types';
22
23
  * ```
23
24
  */
24
25
  const Title = forwardRef< HTMLHeadingElement, TitleProps >(
25
- function PopoverTitle( { className, children, ...props }, forwardedRef ) {
26
+ function PopoverTitle( { children, ...props }, forwardedRef ) {
26
27
  const validationContext = usePopoverValidationContext();
27
28
  const internalRef = useRef< HTMLHeadingElement >( null );
28
29
  const mergedRef = useMergeRefs( [ internalRef, forwardedRef ] );
29
30
 
30
- useLayoutEffect( () => {
31
- validationContext?.registerTitle( internalRef.current );
31
+ useEffect( () => {
32
+ if ( validationContext ) {
33
+ return validationContext.registerTitle( internalRef.current );
34
+ }
35
+ return undefined;
32
36
  }, [ validationContext ] );
33
37
 
34
38
  return (
@@ -36,7 +40,7 @@ const Title = forwardRef< HTMLHeadingElement, TitleProps >(
36
40
  ref={ mergedRef }
37
41
  variant="heading-xl"
38
42
  render={ <_Popover.Title { ...props } /> }
39
- className={ className }
43
+ className={ styles.title }
40
44
  >
41
45
  { children }
42
46
  </Text>
@@ -1,7 +1,10 @@
1
- import type { ReactNode } from 'react';
1
+ import type { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';
2
2
  import type { Popover as _Popover } from '@base-ui/react/popover';
3
+
3
4
  import type { ComponentProps } from '../utils/types';
4
5
 
6
+ export type PortalProps = ComponentPropsWithoutRef< typeof _Popover.Portal >;
7
+
5
8
  export interface RootProps
6
9
  extends Pick<
7
10
  _Popover.Root.Props,
@@ -22,16 +25,6 @@ export interface TriggerProps
22
25
  children?: ReactNode;
23
26
  }
24
27
 
25
- /**
26
- * `Popover.Popup` maps to two Base UI elements internally: the
27
- * **Positioner** (outer, handles fixed positioning and z-index) and the
28
- * **Popup** (inner, holds content and visual styles).
29
- *
30
- * `style` and `className` are forwarded to the **Positioner** so that
31
- * z-index overrides (`--wp-ui-popover-z-index`) and Base UI CSS variables
32
- * (`--available-height`, `--available-width`) work correctly. All other
33
- * HTML attributes are forwarded to the inner **Popup** element.
34
- */
35
28
  export interface PopupProps
36
29
  extends ComponentProps< 'div' >,
37
30
  Pick<
@@ -64,12 +57,14 @@ export interface PopupProps
64
57
  children?: ReactNode;
65
58
 
66
59
  /**
67
- * A parent element to render the portal into.
60
+ * Optional portal element, typically `<Popover.Portal />` with custom
61
+ * `container` for cross-document rendering. Floating content is rendered
62
+ * as this portal's children (do not pass `children` on the portal element;
63
+ * they would be ignored).
68
64
  *
69
- * Useful for cross-document rendering, such as rendering a popover
70
- * in a parent document when the trigger is inside an iframe.
65
+ * When omitted, `Popover.Popup` uses `Popover.Portal` with default props.
71
66
  */
72
- container?: _Popover.Portal.Props[ 'container' ];
67
+ portal?: ReactElement< Omit< PortalProps, 'children' > >;
73
68
 
74
69
  /**
75
70
  * The visual style variant of the popup.
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { Stack } from '../index';
3
3
 
4
4
  const meta: Meta< typeof Stack > = {
5
+ tags: [ 'manifest' ],
5
6
  title: 'Design System/Components/Stack',
6
7
  component: Stack,
7
8
  };
@@ -2,10 +2,11 @@ import {
2
2
  createContext,
3
3
  useContext,
4
4
  useCallback,
5
+ useEffect,
5
6
  useMemo,
6
7
  useRef,
7
- useEffect,
8
8
  } from '@wordpress/element';
9
+ import { useScheduleValidation } from '../utils/use-schedule-validation';
9
10
 
10
11
  type TabsValidationContextType = {
11
12
  registerTab: () => () => void;
@@ -77,33 +78,20 @@ function TabsValidationProviderDev( {
77
78
  } ) {
78
79
  const tabCountRef = useRef( 0 );
79
80
  const panelCountRef = useRef( 0 );
80
- const validationScheduledRef = useRef< ReturnType<
81
- typeof setTimeout
82
- > | null >( null );
83
81
 
84
- const scheduleValidation = useCallback( () => {
85
- if ( validationScheduledRef.current ) {
86
- clearTimeout( validationScheduledRef.current );
82
+ const scheduleValidation = useScheduleValidation( () => {
83
+ const tabCount = tabCountRef.current;
84
+ const panelCount = panelCountRef.current;
85
+
86
+ if ( tabCount !== panelCount ) {
87
+ throw new Error(
88
+ `Tabs: Tab/Panel count mismatch (${ tabCount } Tabs, ${ panelCount } Panels). ` +
89
+ `Each Tab must be associated with exactly one Panel. ` +
90
+ `Mismatched or missing associations can break screen reader navigation ` +
91
+ `and violate WAI-ARIA Tabs pattern requirements.`
92
+ );
87
93
  }
88
-
89
- // Schedule validation for the next tick to allow all
90
- // registrations/unregistrations to complete.
91
- validationScheduledRef.current = setTimeout( () => {
92
- const tabCount = tabCountRef.current;
93
- const panelCount = panelCountRef.current;
94
-
95
- if ( tabCount !== panelCount ) {
96
- throw new Error(
97
- `Tabs: Tab/Panel count mismatch (${ tabCount } Tabs, ${ panelCount } Panels). ` +
98
- `Each Tab must be associated with exactly one Panel. ` +
99
- `Mismatched or missing associations can break screen reader navigation ` +
100
- `and violate WAI-ARIA Tabs pattern requirements.`
101
- );
102
- }
103
-
104
- validationScheduledRef.current = null;
105
- }, 0 );
106
- }, [] );
94
+ } );
107
95
 
108
96
  const registerTab = useCallback( () => {
109
97
  tabCountRef.current += 1;
@@ -125,14 +113,6 @@ function TabsValidationProviderDev( {
125
113
  };
126
114
  }, [ scheduleValidation ] );
127
115
 
128
- useEffect( () => {
129
- return () => {
130
- if ( validationScheduledRef.current ) {
131
- clearTimeout( validationScheduledRef.current );
132
- }
133
- };
134
- }, [] );
135
-
136
116
  const contextValue = useMemo(
137
117
  () => ( {
138
118
  registerTab,
@@ -2,7 +2,8 @@ import { forwardRef } from '@wordpress/element';
2
2
  import clsx from 'clsx';
3
3
  import { Tabs as _Tabs } from '@base-ui/react/tabs';
4
4
  import { useRegisterPanel } from './context';
5
- import styles from './style.module.css';
5
+ import defenseStyles from '../utils/css/global-css-defense.module.css';
6
+ import focusStyles from '../utils/css/focus.module.css';
6
7
  import type { TabPanelProps } from './types';
7
8
 
8
9
  /**
@@ -18,7 +19,11 @@ export const Panel = forwardRef< HTMLDivElement, TabPanelProps >(
18
19
  return (
19
20
  <_Tabs.Panel
20
21
  ref={ forwardedRef }
21
- className={ clsx( styles.tabpanel, className ) }
22
+ className={ clsx(
23
+ defenseStyles.div,
24
+ focusStyles[ 'outset-ring--focus-visible' ],
25
+ className
26
+ ) }
22
27
  { ...otherProps }
23
28
  />
24
29
  );
@@ -1,7 +1,8 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { useState, cloneElement } from '@wordpress/element';
3
3
  import { link, more, wordpress } from '@wordpress/icons';
4
- import { Tabs, Tooltip } from '../..';
4
+ import * as Tabs from '../';
5
+ import * as Tooltip from '../../tooltip';
5
6
 
6
7
  const meta: Meta< typeof Tabs.Root > = {
7
8
  title: 'Design System/Components/Tabs',
@@ -249,21 +249,4 @@
249
249
  rotate: 180deg;
250
250
  }
251
251
  }
252
-
253
- .tabpanel {
254
- &:focus {
255
- box-shadow: none;
256
- outline: none;
257
- }
258
-
259
- &:focus-visible {
260
- box-shadow:
261
- 0 0 0 var(--wpds-border-width-focus)
262
- var(--wpds-color-stroke-focus-brand);
263
-
264
- /* Windows high contrast mode. */
265
- outline: 2px solid transparent;
266
- outline-offset: 0;
267
- }
268
- }
269
252
  }
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable jest/no-conditional-expect */
2
- import { render, screen, waitFor } from '@testing-library/react';
2
+ import { act, render, screen, waitFor } from '@testing-library/react';
3
3
  import userEvent from '@testing-library/user-event';
4
4
  import { DirectionProvider } from '@base-ui/react/direction-provider';
5
5
  import { useEffect, useState, createRef } from '@wordpress/element';
@@ -2344,7 +2344,9 @@ describe( 'Tabs', () => {
2344
2344
  await waitForComponentToBeInitializedWithSelectedTab( 'One' );
2345
2345
 
2346
2346
  // Wait a bit to ensure validation has run
2347
- await new Promise( ( resolve ) => setTimeout( resolve, 50 ) );
2347
+ await act(
2348
+ () => new Promise( ( resolve ) => setTimeout( resolve, 50 ) )
2349
+ );
2348
2350
 
2349
2351
  expect( errors ).toHaveLength( 0 );
2350
2352
 
@@ -2391,7 +2393,9 @@ describe( 'Tabs', () => {
2391
2393
  await waitForComponentToBeInitializedWithSelectedTab( 'One' );
2392
2394
 
2393
2395
  // Wait for validation
2394
- await new Promise( ( resolve ) => setTimeout( resolve, 50 ) );
2396
+ await act(
2397
+ () => new Promise( ( resolve ) => setTimeout( resolve, 50 ) )
2398
+ );
2395
2399
 
2396
2400
  // No errors since counts match
2397
2401
  expect( errors ).toHaveLength( 0 );
@@ -3,6 +3,7 @@ import { Text } from '../index';
3
3
  import { Stack } from '../../stack';
4
4
 
5
5
  const meta: Meta< typeof Text > = {
6
+ tags: [ 'manifest' ],
6
7
  title: 'Design System/Components/Text',
7
8
  component: Text,
8
9
  };
package/src/text/text.tsx CHANGED
@@ -20,8 +20,8 @@ export const Text = forwardRef< HTMLSpanElement, TextProps >( function Text(
20
20
  props: mergeProps< 'span' >( props, {
21
21
  className: clsx(
22
22
  styles.text,
23
- variant.startsWith( 'heading-' ) && defenseStyles.heading,
24
- variant.startsWith( 'body-' ) && defenseStyles.p,
23
+ defenseStyles.heading,
24
+ defenseStyles.p,
25
25
  styles[ variant ],
26
26
  className
27
27
  ),
@@ -1,6 +1,7 @@
1
1
  import { Popup } from './popup';
2
+ import { Portal } from './portal';
2
3
  import { Trigger } from './trigger';
3
4
  import { Root } from './root';
4
5
  import { Provider } from './provider';
5
6
 
6
- export { Provider, Root, Trigger, Popup };
7
+ export { Provider, Root, Trigger, Popup, Portal };