@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
@@ -0,0 +1,537 @@
1
+ import { render, screen, waitFor } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { createRef, useState } from '@wordpress/element';
4
+
5
+ import * as AlertDialog from '..';
6
+
7
+ describe( 'AlertDialog', () => {
8
+ it( 'forwards ref', () => {
9
+ const triggerRef = createRef< HTMLButtonElement >();
10
+ const popupRef = createRef< HTMLDivElement >();
11
+
12
+ render(
13
+ <AlertDialog.Root defaultOpen>
14
+ <AlertDialog.Trigger ref={ triggerRef }>
15
+ Open
16
+ </AlertDialog.Trigger>
17
+ <AlertDialog.Popup
18
+ ref={ popupRef }
19
+ title="Test Title"
20
+ onConfirm={ jest.fn() }
21
+ >
22
+ Test message content
23
+ </AlertDialog.Popup>
24
+ </AlertDialog.Root>
25
+ );
26
+
27
+ expect( triggerRef.current ).toBeInstanceOf( HTMLButtonElement );
28
+ expect( popupRef.current ).toBeInstanceOf( HTMLDivElement );
29
+ } );
30
+
31
+ it( 'renders with title, message, and default buttons', async () => {
32
+ render(
33
+ <AlertDialog.Root open onOpenChange={ jest.fn() }>
34
+ <AlertDialog.Popup title="Test Title" onConfirm={ jest.fn() }>
35
+ Test message content
36
+ </AlertDialog.Popup>
37
+ </AlertDialog.Root>
38
+ );
39
+
40
+ await waitFor( () => {
41
+ expect( screen.getByText( 'Test Title' ) ).toBeVisible();
42
+ } );
43
+
44
+ expect( screen.getByText( 'Test message content' ) ).toBeVisible();
45
+ expect(
46
+ screen.queryByRole( 'button', { name: 'Close' } )
47
+ ).not.toBeInTheDocument();
48
+ expect( screen.getByRole( 'button', { name: 'OK' } ) ).toBeVisible();
49
+ expect(
50
+ screen.getByRole( 'button', { name: 'Cancel' } )
51
+ ).toBeVisible();
52
+ } );
53
+
54
+ it( 'renders with role="alertdialog" for default intent', async () => {
55
+ render(
56
+ <AlertDialog.Root open onOpenChange={ jest.fn() }>
57
+ <AlertDialog.Popup
58
+ title="Default Dialog"
59
+ onConfirm={ jest.fn() }
60
+ >
61
+ Content
62
+ </AlertDialog.Popup>
63
+ </AlertDialog.Root>
64
+ );
65
+
66
+ await waitFor( () => {
67
+ expect( screen.getByRole( 'alertdialog' ) ).toBeVisible();
68
+ } );
69
+ } );
70
+
71
+ it( 'renders with role="alertdialog" for irreversible intent', async () => {
72
+ render(
73
+ <AlertDialog.Root
74
+ intent="irreversible"
75
+ open
76
+ onOpenChange={ jest.fn() }
77
+ >
78
+ <AlertDialog.Popup
79
+ title="Irreversible Dialog"
80
+ onConfirm={ jest.fn() }
81
+ >
82
+ Content
83
+ </AlertDialog.Popup>
84
+ </AlertDialog.Root>
85
+ );
86
+
87
+ await waitFor( () => {
88
+ expect( screen.getByRole( 'alertdialog' ) ).toBeVisible();
89
+ } );
90
+ } );
91
+
92
+ it( 'calls onConfirm and onOpenChange when confirm button is clicked', async () => {
93
+ const onConfirm = jest.fn();
94
+ const onOpenChange = jest.fn();
95
+
96
+ render(
97
+ <AlertDialog.Root open onOpenChange={ onOpenChange }>
98
+ <AlertDialog.Popup
99
+ title="Confirm Action"
100
+ onConfirm={ onConfirm }
101
+ >
102
+ Are you sure?
103
+ </AlertDialog.Popup>
104
+ </AlertDialog.Root>
105
+ );
106
+
107
+ await waitFor( () => {
108
+ expect(
109
+ screen.getByRole( 'button', { name: 'OK' } )
110
+ ).toBeVisible();
111
+ } );
112
+
113
+ await userEvent.click( screen.getByRole( 'button', { name: 'OK' } ) );
114
+
115
+ expect( onConfirm ).toHaveBeenCalledTimes( 1 );
116
+ expect( onOpenChange ).toHaveBeenCalledWith(
117
+ false,
118
+ expect.objectContaining( { reason: 'close-press' } )
119
+ );
120
+ } );
121
+
122
+ it( 'calls onOpenChange when cancel button is clicked', async () => {
123
+ const onConfirm = jest.fn();
124
+ const onOpenChange = jest.fn();
125
+
126
+ render(
127
+ <AlertDialog.Root open onOpenChange={ onOpenChange }>
128
+ <AlertDialog.Popup
129
+ title="Confirm Action"
130
+ onConfirm={ onConfirm }
131
+ >
132
+ Are you sure?
133
+ </AlertDialog.Popup>
134
+ </AlertDialog.Root>
135
+ );
136
+
137
+ await waitFor( () => {
138
+ expect(
139
+ screen.getByRole( 'button', { name: 'Cancel' } )
140
+ ).toBeVisible();
141
+ } );
142
+
143
+ await userEvent.click(
144
+ screen.getByRole( 'button', { name: 'Cancel' } )
145
+ );
146
+
147
+ expect( onOpenChange ).toHaveBeenCalledWith(
148
+ false,
149
+ expect.objectContaining( { reason: 'close-press' } )
150
+ );
151
+ expect( onConfirm ).not.toHaveBeenCalled();
152
+ } );
153
+
154
+ it( 'calls onOpenChange on escape key for default intent', async () => {
155
+ const onOpenChange = jest.fn();
156
+
157
+ render(
158
+ <AlertDialog.Root open onOpenChange={ onOpenChange }>
159
+ <AlertDialog.Popup
160
+ title="Default Dialog"
161
+ onConfirm={ jest.fn() }
162
+ >
163
+ Content
164
+ </AlertDialog.Popup>
165
+ </AlertDialog.Root>
166
+ );
167
+
168
+ await waitFor( () => {
169
+ expect( screen.getByText( 'Default Dialog' ) ).toBeVisible();
170
+ } );
171
+
172
+ await userEvent.keyboard( '{Escape}' );
173
+
174
+ expect( onOpenChange ).toHaveBeenCalledWith(
175
+ false,
176
+ expect.objectContaining( { reason: 'escape-key' } )
177
+ );
178
+ } );
179
+
180
+ it( 'does not call onOpenChange on backdrop click for default intent', async () => {
181
+ const onOpenChange = jest.fn();
182
+
183
+ render(
184
+ <AlertDialog.Root open onOpenChange={ onOpenChange }>
185
+ <AlertDialog.Popup
186
+ title="Default Dialog"
187
+ onConfirm={ jest.fn() }
188
+ >
189
+ Content
190
+ </AlertDialog.Popup>
191
+ </AlertDialog.Root>
192
+ );
193
+
194
+ await waitFor( () => {
195
+ expect( screen.getByText( 'Default Dialog' ) ).toBeVisible();
196
+ } );
197
+
198
+ await userEvent.click( document.body );
199
+
200
+ expect( onOpenChange ).not.toHaveBeenCalled();
201
+ } );
202
+
203
+ it( 'renders with title, message, and default buttons for irreversible intent', async () => {
204
+ render(
205
+ <AlertDialog.Root
206
+ intent="irreversible"
207
+ open
208
+ onOpenChange={ jest.fn() }
209
+ >
210
+ <AlertDialog.Popup
211
+ title="Irreversible Dialog"
212
+ onConfirm={ jest.fn() }
213
+ >
214
+ Irreversible message content
215
+ </AlertDialog.Popup>
216
+ </AlertDialog.Root>
217
+ );
218
+
219
+ await waitFor( () => {
220
+ expect( screen.getByText( 'Irreversible Dialog' ) ).toBeVisible();
221
+ } );
222
+
223
+ expect(
224
+ screen.getByText( 'Irreversible message content' )
225
+ ).toBeVisible();
226
+ expect(
227
+ screen.queryByRole( 'button', { name: 'Close' } )
228
+ ).not.toBeInTheDocument();
229
+ expect( screen.getByRole( 'button', { name: 'OK' } ) ).toBeVisible();
230
+ expect(
231
+ screen.getByRole( 'button', { name: 'Cancel' } )
232
+ ).toBeVisible();
233
+ } );
234
+
235
+ it( 'calls onOpenChange on escape key for irreversible intent', async () => {
236
+ const onOpenChange = jest.fn();
237
+
238
+ render(
239
+ <AlertDialog.Root
240
+ intent="irreversible"
241
+ open
242
+ onOpenChange={ onOpenChange }
243
+ >
244
+ <AlertDialog.Popup
245
+ title="Irreversible Dialog"
246
+ onConfirm={ jest.fn() }
247
+ >
248
+ Content
249
+ </AlertDialog.Popup>
250
+ </AlertDialog.Root>
251
+ );
252
+
253
+ await waitFor( () => {
254
+ expect( screen.getByText( 'Irreversible Dialog' ) ).toBeVisible();
255
+ } );
256
+
257
+ await userEvent.keyboard( '{Escape}' );
258
+
259
+ expect( onOpenChange ).toHaveBeenCalledWith(
260
+ false,
261
+ expect.objectContaining( { reason: 'escape-key' } )
262
+ );
263
+ } );
264
+
265
+ it( 'does not call onOpenChange on backdrop click for irreversible intent', async () => {
266
+ const onOpenChange = jest.fn();
267
+
268
+ render(
269
+ <AlertDialog.Root
270
+ intent="irreversible"
271
+ open
272
+ onOpenChange={ onOpenChange }
273
+ >
274
+ <AlertDialog.Popup
275
+ title="Irreversible Dialog"
276
+ onConfirm={ jest.fn() }
277
+ >
278
+ Content
279
+ </AlertDialog.Popup>
280
+ </AlertDialog.Root>
281
+ );
282
+
283
+ await waitFor( () => {
284
+ expect( screen.getByText( 'Irreversible Dialog' ) ).toBeVisible();
285
+ } );
286
+
287
+ await userEvent.click( document.body );
288
+
289
+ expect( onOpenChange ).not.toHaveBeenCalled();
290
+ } );
291
+
292
+ it( 'calls onOpenChange on cancel button click for irreversible intent', async () => {
293
+ const onOpenChange = jest.fn();
294
+ const onConfirm = jest.fn();
295
+
296
+ render(
297
+ <AlertDialog.Root
298
+ intent="irreversible"
299
+ open
300
+ onOpenChange={ onOpenChange }
301
+ >
302
+ <AlertDialog.Popup
303
+ title="Irreversible Dialog"
304
+ onConfirm={ onConfirm }
305
+ >
306
+ Content
307
+ </AlertDialog.Popup>
308
+ </AlertDialog.Root>
309
+ );
310
+
311
+ await waitFor( () => {
312
+ expect(
313
+ screen.getByRole( 'button', { name: 'Cancel' } )
314
+ ).toBeVisible();
315
+ } );
316
+
317
+ await userEvent.click(
318
+ screen.getByRole( 'button', { name: 'Cancel' } )
319
+ );
320
+
321
+ expect( onOpenChange ).toHaveBeenCalledWith(
322
+ false,
323
+ expect.objectContaining( { reason: 'close-press' } )
324
+ );
325
+ expect( onConfirm ).not.toHaveBeenCalled();
326
+ } );
327
+
328
+ it( 'calls onConfirm and onOpenChange on confirm button click for irreversible intent', async () => {
329
+ const onOpenChange = jest.fn();
330
+ const onConfirm = jest.fn();
331
+
332
+ render(
333
+ <AlertDialog.Root
334
+ intent="irreversible"
335
+ open
336
+ onOpenChange={ onOpenChange }
337
+ >
338
+ <AlertDialog.Popup
339
+ title="Irreversible Dialog"
340
+ onConfirm={ onConfirm }
341
+ >
342
+ Content
343
+ </AlertDialog.Popup>
344
+ </AlertDialog.Root>
345
+ );
346
+
347
+ await waitFor( () => {
348
+ expect(
349
+ screen.getByRole( 'button', { name: 'OK' } )
350
+ ).toBeVisible();
351
+ } );
352
+
353
+ await userEvent.click( screen.getByRole( 'button', { name: 'OK' } ) );
354
+
355
+ expect( onConfirm ).toHaveBeenCalledTimes( 1 );
356
+ expect( onOpenChange ).toHaveBeenCalledWith(
357
+ false,
358
+ expect.objectContaining( { reason: 'close-press' } )
359
+ );
360
+ } );
361
+
362
+ it( 'disables both buttons when loading', async () => {
363
+ render(
364
+ <AlertDialog.Root open onOpenChange={ jest.fn() }>
365
+ <AlertDialog.Popup
366
+ title="Loading Test"
367
+ onConfirm={ jest.fn() }
368
+ loading
369
+ >
370
+ Content
371
+ </AlertDialog.Popup>
372
+ </AlertDialog.Root>
373
+ );
374
+
375
+ await waitFor( () => {
376
+ expect(
377
+ screen.getByRole( 'button', { name: 'OK' } )
378
+ ).toBeVisible();
379
+ } );
380
+
381
+ expect( screen.getByRole( 'button', { name: 'OK' } ) ).toHaveAttribute(
382
+ 'aria-disabled',
383
+ 'true'
384
+ );
385
+
386
+ expect(
387
+ screen.getByRole( 'button', { name: 'Cancel' } )
388
+ ).toHaveAttribute( 'aria-disabled', 'true' );
389
+ } );
390
+
391
+ it( 'does not disable buttons when loading is false', async () => {
392
+ render(
393
+ <AlertDialog.Root open onOpenChange={ jest.fn() }>
394
+ <AlertDialog.Popup
395
+ title="No Loading"
396
+ onConfirm={ jest.fn() }
397
+ loading={ false }
398
+ >
399
+ Content
400
+ </AlertDialog.Popup>
401
+ </AlertDialog.Root>
402
+ );
403
+
404
+ await waitFor( () => {
405
+ expect(
406
+ screen.getByRole( 'button', { name: 'OK' } )
407
+ ).toBeVisible();
408
+ } );
409
+
410
+ expect(
411
+ screen.getByRole( 'button', { name: 'OK' } )
412
+ ).not.toHaveAttribute( 'aria-disabled', 'true' );
413
+
414
+ expect(
415
+ screen.getByRole( 'button', { name: 'Cancel' } )
416
+ ).not.toHaveAttribute( 'aria-disabled', 'true' );
417
+ } );
418
+
419
+ it( 'uses custom button text when provided', async () => {
420
+ render(
421
+ <AlertDialog.Root open onOpenChange={ jest.fn() }>
422
+ <AlertDialog.Popup
423
+ title="Custom Text"
424
+ onConfirm={ jest.fn() }
425
+ confirmButtonText="Yes, do it"
426
+ cancelButtonText="No, go back"
427
+ >
428
+ Custom message
429
+ </AlertDialog.Popup>
430
+ </AlertDialog.Root>
431
+ );
432
+
433
+ await waitFor( () => {
434
+ expect(
435
+ screen.getByRole( 'button', { name: 'Yes, do it' } )
436
+ ).toBeVisible();
437
+ } );
438
+
439
+ expect(
440
+ screen.getByRole( 'button', { name: 'No, go back' } )
441
+ ).toBeVisible();
442
+ } );
443
+
444
+ it( 'keeps dialog open when confirm is clicked with loading prop (async flow)', async () => {
445
+ function AsyncDialog() {
446
+ const [ isOpen, setIsOpen ] = useState( true );
447
+ const [ isLoading, setIsLoading ] = useState( false );
448
+
449
+ return (
450
+ <AlertDialog.Root
451
+ open={ isOpen }
452
+ onOpenChange={ ( open ) => {
453
+ if ( ! isLoading ) {
454
+ setIsOpen( open );
455
+ }
456
+ } }
457
+ >
458
+ <AlertDialog.Popup
459
+ title="Async Test"
460
+ loading={ isLoading }
461
+ onConfirm={ () => setIsLoading( true ) }
462
+ >
463
+ Content
464
+ </AlertDialog.Popup>
465
+ </AlertDialog.Root>
466
+ );
467
+ }
468
+
469
+ render( <AsyncDialog /> );
470
+
471
+ await waitFor( () => {
472
+ expect( screen.getByText( 'Async Test' ) ).toBeVisible();
473
+ } );
474
+
475
+ await userEvent.click( screen.getByRole( 'button', { name: 'OK' } ) );
476
+
477
+ expect( screen.getByText( 'Async Test' ) ).toBeVisible();
478
+ expect( screen.getByRole( 'button', { name: 'OK' } ) ).toHaveAttribute(
479
+ 'aria-disabled',
480
+ 'true'
481
+ );
482
+ } );
483
+
484
+ it( 'does not auto-close on confirm click when loading is false (manual-close mode)', async () => {
485
+ function ManualCloseDialog() {
486
+ const [ isOpen, setIsOpen ] = useState( true );
487
+
488
+ return (
489
+ <AlertDialog.Root
490
+ open={ isOpen }
491
+ onOpenChange={ ( open ) => setIsOpen( open ) }
492
+ >
493
+ <AlertDialog.Popup
494
+ title="Manual Close"
495
+ loading={ false }
496
+ onConfirm={ jest.fn() }
497
+ >
498
+ Content
499
+ </AlertDialog.Popup>
500
+ </AlertDialog.Root>
501
+ );
502
+ }
503
+
504
+ render( <ManualCloseDialog /> );
505
+
506
+ await waitFor( () => {
507
+ expect( screen.getByText( 'Manual Close' ) ).toBeVisible();
508
+ } );
509
+
510
+ await userEvent.click( screen.getByRole( 'button', { name: 'OK' } ) );
511
+
512
+ expect( screen.getByText( 'Manual Close' ) ).toBeVisible();
513
+ } );
514
+
515
+ it( 'opens dialog when Trigger is clicked', async () => {
516
+ render(
517
+ <AlertDialog.Root>
518
+ <AlertDialog.Trigger>Open</AlertDialog.Trigger>
519
+ <AlertDialog.Popup title="Trigger Test" onConfirm={ jest.fn() }>
520
+ Dialog content
521
+ </AlertDialog.Popup>
522
+ </AlertDialog.Root>
523
+ );
524
+
525
+ expect(
526
+ screen.queryByText( 'Dialog content' )
527
+ ).not.toBeInTheDocument();
528
+
529
+ await userEvent.click( screen.getByRole( 'button', { name: 'Open' } ) );
530
+
531
+ await waitFor( () => {
532
+ expect( screen.getByText( 'Trigger Test' ) ).toBeVisible();
533
+ } );
534
+
535
+ expect( screen.getByText( 'Dialog content' ) ).toBeVisible();
536
+ } );
537
+ } );
@@ -0,0 +1,15 @@
1
+ import { forwardRef } from '@wordpress/element';
2
+
3
+ import * as Dialog from '../dialog';
4
+ import type { TriggerProps } from './types';
5
+
6
+ /**
7
+ * Renders a button that opens the alert dialog when clicked.
8
+ */
9
+ const Trigger = forwardRef< HTMLButtonElement, TriggerProps >(
10
+ function AlertDialogTrigger( props, ref ) {
11
+ return <Dialog.Trigger ref={ ref } { ...props } />;
12
+ }
13
+ );
14
+
15
+ export { Trigger };
@@ -0,0 +1,83 @@
1
+ import type { AlertDialog as _AlertDialog } from '@base-ui/react/alert-dialog';
2
+ import type { ReactNode } from 'react';
3
+
4
+ import type { TriggerProps as DialogTriggerProps } from '../dialog/types';
5
+
6
+ export interface RootProps
7
+ extends Pick<
8
+ _AlertDialog.Root.Props,
9
+ 'open' | 'onOpenChange' | 'defaultOpen'
10
+ > {
11
+ /**
12
+ * The content to be rendered inside the component. Typically includes
13
+ * `AlertDialog.Trigger` and `AlertDialog.Popup`.
14
+ */
15
+ children: ReactNode;
16
+
17
+ /**
18
+ * The semantic intent of the dialog, which determines its styling.
19
+ *
20
+ * All intents use `role="alertdialog"`, are always modal, and block
21
+ * backdrop click dismissal. Escape key and the cancel/confirm buttons
22
+ * still dismiss the dialog.
23
+ *
24
+ * - `'default'`: Standard confirmation dialog for reversible actions.
25
+ * - `'irreversible'`: Confirmation dialog for irreversible actions that
26
+ * cannot be undone. The confirm button uses error/danger coloring.
27
+ *
28
+ * @default 'default'
29
+ */
30
+ intent?: 'default' | 'irreversible';
31
+ }
32
+
33
+ export type TriggerProps = DialogTriggerProps;
34
+
35
+ export interface PopupProps {
36
+ /**
37
+ * The title displayed in the dialog header. This serves as both the
38
+ * visible heading and the accessible label for the dialog.
39
+ */
40
+ title: string;
41
+
42
+ /**
43
+ * The message content displayed in the dialog body.
44
+ */
45
+ children: ReactNode;
46
+
47
+ /**
48
+ * Callback fired when the user confirms the action.
49
+ */
50
+ onConfirm: () => void;
51
+
52
+ /**
53
+ * Custom text for the confirm button.
54
+ *
55
+ * @default 'OK'
56
+ */
57
+ confirmButtonText?: string;
58
+
59
+ /**
60
+ * Custom text for the cancel button.
61
+ *
62
+ * @default 'Cancel'
63
+ */
64
+ cancelButtonText?: string;
65
+
66
+ /**
67
+ * Whether the confirm action is in a loading state (e.g. an async
68
+ * operation is in progress). When `true`, the confirm button shows a
69
+ * spinner and the cancel button is disabled.
70
+ *
71
+ * **Important:** Passing this prop — even as `false` — opts into
72
+ * manual-close mode: the confirm button will no longer auto-close the
73
+ * dialog. The consumer is responsible for setting `open={false}` when
74
+ * the operation completes. Omit the prop entirely for the default
75
+ * auto-close-on-confirm behavior.
76
+ *
77
+ * To implement an async confirm flow, use controlled mode
78
+ * (`open` / `onOpenChange`) and manage the loading state externally:
79
+ * prevent closing in `onOpenChange` while loading, and set
80
+ * `open={false}` once the operation completes.
81
+ */
82
+ loading?: boolean;
83
+ }
@@ -42,7 +42,10 @@
42
42
  }
43
43
 
44
44
  .is-none-intent {
45
- background-color: var(--wpds-color-bg-surface-neutral);
46
- color: var(--wpds-color-fg-content-neutral-weak);
45
+ background-color: var(--wpds-color-bg-surface-neutral-strong);
46
+ color: var(--wpds-color-fg-content-neutral);
47
+ border: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral);
48
+ padding-block: calc(var(--wpds-dimension-padding-xs) - var(--wpds-border-width-xs));
49
+ padding-inline: calc(var(--wpds-dimension-padding-sm) - var(--wpds-border-width-xs));
47
50
  }
48
51
  }
@@ -50,6 +50,7 @@
50
50
  line-height: var(--wpds-font-line-height-sm);
51
51
  text-decoration: none;
52
52
  color: var(--wp-ui-button-foreground-color);
53
+ cursor: var(--wpds-cursor-control);
53
54
 
54
55
  @media not ( prefers-reduced-motion ) {
55
56
  transition: color 0.1s ease-out;
@@ -61,6 +62,7 @@
61
62
 
62
63
  /* Use pointer cursor for buttons that are links */
63
64
  &[href] {
65
+ /* stylelint-disable-next-line declaration-property-value-disallowed-list -- Links should always use pointer. */
64
66
  cursor: pointer;
65
67
  }
66
68
 
@@ -10,7 +10,7 @@ function Text( { children }: { children: React.ReactNode } ) {
10
10
  <p
11
11
  style={ {
12
12
  margin: 0,
13
- fontFamily: [ 'var(--wp', 'ds-font-family-body)' ].join( '' ),
13
+ fontFamily: 'var(--wpds-font-family-body)',
14
14
  fontSize: 'var(--wpds-font-size-md)',
15
15
  fontWeight: 'var(--wpds-font-weight-regular)',
16
16
  lineHeight: 'var(--wpds-font-line-height-sm)',
@@ -2,13 +2,15 @@
2
2
 
3
3
  @layer wp-ui-components {
4
4
  .root {
5
- --wp-ui-card-padding: var(--wpds-dimension-padding-xl);
6
- --wp-ui-card-header-content-gap: var(--wpds-dimension-gap-lg);
5
+ --wp-ui-card-padding: var(--wpds-dimension-padding-2xl);
6
+ --wp-ui-card-header-content-gap: var(--wpds-dimension-gap-xl);
7
+ --wp-ui-card-header-content-margin: calc(var(--wp-ui-card-header-content-gap) - var(--wp-ui-card-padding));
7
8
 
8
9
  display: flex;
9
10
  flex-direction: column;
10
11
  border: 1px solid var(--wpds-color-stroke-surface-neutral-weak);
11
12
  border-radius: var(--wpds-border-radius-lg);
13
+ overflow: clip;
12
14
  background-color: var(--wpds-color-bg-surface-neutral-strong);
13
15
  }
14
16
 
@@ -28,7 +30,7 @@
28
30
  /* Custom vertical gap between header and content */
29
31
  .header + .content {
30
32
  padding-block-start: 0;
31
- margin-block-start: calc(var(--wp-ui-card-header-content-gap) - var(--wp-ui-card-padding));
33
+ margin-block-start: var(--wp-ui-card-header-content-margin);
32
34
  }
33
35
 
34
36
  .fullbleed {
@@ -38,10 +40,6 @@
38
40
 
39
41
  .title {
40
42
  margin: 0;
41
- font-family: var(--wpds-font-family-heading);
42
- font-size: var(--wpds-font-size-lg);
43
- font-weight: var(--wpds-font-weight-medium);
44
- line-height: var(--wpds-font-line-height-sm);
45
43
  color: var(--wpds-color-fg-content-neutral);
46
44
  }
47
45
  }