@mortenbrudvik/waveui 0.7.0 → 0.8.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 (408) hide show
  1. package/README.md +395 -132
  2. package/dist/components/button/Button.cjs +1 -1
  3. package/dist/components/button/Button.cjs.map +1 -1
  4. package/dist/components/button/Button.mjs +36 -35
  5. package/dist/components/button/Button.mjs.map +1 -1
  6. package/dist/components/button/Button.slots.cjs +1 -1
  7. package/dist/components/button/Button.slots.cjs.map +1 -1
  8. package/dist/components/button/Button.slots.mjs +31 -21
  9. package/dist/components/button/Button.slots.mjs.map +1 -1
  10. package/dist/components/button/CompoundButton.cjs +1 -1
  11. package/dist/components/button/CompoundButton.cjs.map +1 -1
  12. package/dist/components/button/CompoundButton.mjs +31 -29
  13. package/dist/components/button/CompoundButton.mjs.map +1 -1
  14. package/dist/components/button/Link.cjs +1 -1
  15. package/dist/components/button/Link.cjs.map +1 -1
  16. package/dist/components/button/Link.mjs +24 -23
  17. package/dist/components/button/Link.mjs.map +1 -1
  18. package/dist/components/button/MenuButton.cjs +1 -1
  19. package/dist/components/button/MenuButton.cjs.map +1 -1
  20. package/dist/components/button/MenuButton.mjs +29 -28
  21. package/dist/components/button/MenuButton.mjs.map +1 -1
  22. package/dist/components/button/SplitButton.cjs +1 -1
  23. package/dist/components/button/SplitButton.cjs.map +1 -1
  24. package/dist/components/button/SplitButton.mjs +46 -45
  25. package/dist/components/button/SplitButton.mjs.map +1 -1
  26. package/dist/components/button/ToggleButton.cjs +1 -1
  27. package/dist/components/button/ToggleButton.cjs.map +1 -1
  28. package/dist/components/button/ToggleButton.mjs +38 -35
  29. package/dist/components/button/ToggleButton.mjs.map +1 -1
  30. package/dist/components/button/Toolbar.cjs +1 -1
  31. package/dist/components/button/Toolbar.cjs.map +1 -1
  32. package/dist/components/button/Toolbar.mjs +43 -42
  33. package/dist/components/button/Toolbar.mjs.map +1 -1
  34. package/dist/components/button/Toolbar.parts.cjs +1 -1
  35. package/dist/components/button/Toolbar.parts.cjs.map +1 -1
  36. package/dist/components/button/Toolbar.parts.mjs +76 -81
  37. package/dist/components/button/Toolbar.parts.mjs.map +1 -1
  38. package/dist/components/data-display/Avatar.cjs +1 -1
  39. package/dist/components/data-display/Avatar.cjs.map +1 -1
  40. package/dist/components/data-display/Avatar.mjs +72 -67
  41. package/dist/components/data-display/Avatar.mjs.map +1 -1
  42. package/dist/components/data-display/AvatarGroup.cjs +1 -1
  43. package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
  44. package/dist/components/data-display/AvatarGroup.mjs +89 -88
  45. package/dist/components/data-display/AvatarGroup.mjs.map +1 -1
  46. package/dist/components/data-display/Badge.cjs +1 -1
  47. package/dist/components/data-display/Badge.cjs.map +1 -1
  48. package/dist/components/data-display/Badge.mjs +17 -16
  49. package/dist/components/data-display/Badge.mjs.map +1 -1
  50. package/dist/components/data-display/CounterBadge.cjs +1 -1
  51. package/dist/components/data-display/CounterBadge.cjs.map +1 -1
  52. package/dist/components/data-display/CounterBadge.mjs +18 -17
  53. package/dist/components/data-display/CounterBadge.mjs.map +1 -1
  54. package/dist/components/data-display/Divider.cjs +1 -1
  55. package/dist/components/data-display/Divider.cjs.map +1 -1
  56. package/dist/components/data-display/Divider.mjs +31 -30
  57. package/dist/components/data-display/Divider.mjs.map +1 -1
  58. package/dist/components/data-display/Image.cjs +1 -1
  59. package/dist/components/data-display/Image.cjs.map +1 -1
  60. package/dist/components/data-display/Image.mjs +16 -15
  61. package/dist/components/data-display/Image.mjs.map +1 -1
  62. package/dist/components/data-display/InfoLabel.cjs +1 -1
  63. package/dist/components/data-display/InfoLabel.cjs.map +1 -1
  64. package/dist/components/data-display/InfoLabel.mjs +74 -73
  65. package/dist/components/data-display/InfoLabel.mjs.map +1 -1
  66. package/dist/components/data-display/List.cjs +1 -1
  67. package/dist/components/data-display/List.cjs.map +1 -1
  68. package/dist/components/data-display/List.mjs +175 -174
  69. package/dist/components/data-display/List.mjs.map +1 -1
  70. package/dist/components/data-display/Persona.cjs +1 -1
  71. package/dist/components/data-display/Persona.cjs.map +1 -1
  72. package/dist/components/data-display/Persona.mjs +31 -29
  73. package/dist/components/data-display/Persona.mjs.map +1 -1
  74. package/dist/components/data-display/PresenceBadge.cjs +1 -1
  75. package/dist/components/data-display/PresenceBadge.cjs.map +1 -1
  76. package/dist/components/data-display/PresenceBadge.mjs +25 -24
  77. package/dist/components/data-display/PresenceBadge.mjs.map +1 -1
  78. package/dist/components/data-display/Tag.cjs +1 -1
  79. package/dist/components/data-display/Tag.cjs.map +1 -1
  80. package/dist/components/data-display/Tag.mjs +87 -82
  81. package/dist/components/data-display/Tag.mjs.map +1 -1
  82. package/dist/components/feedback/MessageBar.cjs +1 -1
  83. package/dist/components/feedback/MessageBar.cjs.map +1 -1
  84. package/dist/components/feedback/MessageBar.mjs +129 -71
  85. package/dist/components/feedback/MessageBar.mjs.map +1 -1
  86. package/dist/components/feedback/MessageBar.parts.cjs +2 -0
  87. package/dist/components/feedback/MessageBar.parts.cjs.map +1 -0
  88. package/dist/components/feedback/MessageBar.parts.mjs +84 -0
  89. package/dist/components/feedback/MessageBar.parts.mjs.map +1 -0
  90. package/dist/components/feedback/MessageBar.reflow.cjs +2 -0
  91. package/dist/components/feedback/MessageBar.reflow.cjs.map +1 -0
  92. package/dist/components/feedback/MessageBar.reflow.mjs +74 -0
  93. package/dist/components/feedback/MessageBar.reflow.mjs.map +1 -0
  94. package/dist/components/feedback/MessageBar.status.cjs +1 -1
  95. package/dist/components/feedback/MessageBar.status.cjs.map +1 -1
  96. package/dist/components/feedback/MessageBar.status.mjs +2 -1
  97. package/dist/components/feedback/MessageBar.status.mjs.map +1 -1
  98. package/dist/components/feedback/ProgressBar.cjs +1 -1
  99. package/dist/components/feedback/ProgressBar.cjs.map +1 -1
  100. package/dist/components/feedback/ProgressBar.mjs +44 -43
  101. package/dist/components/feedback/ProgressBar.mjs.map +1 -1
  102. package/dist/components/feedback/Skeleton.cjs +1 -1
  103. package/dist/components/feedback/Skeleton.cjs.map +1 -1
  104. package/dist/components/feedback/Skeleton.mjs +26 -24
  105. package/dist/components/feedback/Skeleton.mjs.map +1 -1
  106. package/dist/components/feedback/Spinner.cjs +1 -1
  107. package/dist/components/feedback/Spinner.cjs.map +1 -1
  108. package/dist/components/feedback/Spinner.mjs +32 -31
  109. package/dist/components/feedback/Spinner.mjs.map +1 -1
  110. package/dist/components/feedback/Toast.cjs +1 -1
  111. package/dist/components/feedback/Toast.cjs.map +1 -1
  112. package/dist/components/feedback/Toast.context.cjs +2 -0
  113. package/dist/components/feedback/Toast.context.cjs.map +1 -0
  114. package/dist/components/feedback/Toast.context.mjs +23 -0
  115. package/dist/components/feedback/Toast.context.mjs.map +1 -0
  116. package/dist/components/feedback/Toast.mjs +10 -342
  117. package/dist/components/feedback/Toast.mjs.map +1 -1
  118. package/dist/components/feedback/Toast.parts.cjs +2 -0
  119. package/dist/components/feedback/Toast.parts.cjs.map +1 -0
  120. package/dist/components/feedback/Toast.parts.mjs +98 -0
  121. package/dist/components/feedback/Toast.parts.mjs.map +1 -0
  122. package/dist/components/feedback/Toast.root.cjs +2 -0
  123. package/dist/components/feedback/Toast.root.cjs.map +1 -0
  124. package/dist/components/feedback/Toast.root.mjs +109 -0
  125. package/dist/components/feedback/Toast.root.mjs.map +1 -0
  126. package/dist/components/feedback/Toaster.cjs +2 -0
  127. package/dist/components/feedback/Toaster.cjs.map +1 -0
  128. package/dist/components/feedback/Toaster.mjs +564 -0
  129. package/dist/components/feedback/Toaster.mjs.map +1 -0
  130. package/dist/components/input/AlphaSlider.cjs +2 -0
  131. package/dist/components/input/AlphaSlider.cjs.map +1 -0
  132. package/dist/components/input/AlphaSlider.mjs +115 -0
  133. package/dist/components/input/AlphaSlider.mjs.map +1 -0
  134. package/dist/components/input/Checkbox.cjs +1 -1
  135. package/dist/components/input/Checkbox.cjs.map +1 -1
  136. package/dist/components/input/Checkbox.mjs +47 -46
  137. package/dist/components/input/Checkbox.mjs.map +1 -1
  138. package/dist/components/input/ColorArea.cjs +2 -0
  139. package/dist/components/input/ColorArea.cjs.map +1 -0
  140. package/dist/components/input/ColorArea.mjs +204 -0
  141. package/dist/components/input/ColorArea.mjs.map +1 -0
  142. package/dist/components/input/ColorPicker.cjs +5 -5
  143. package/dist/components/input/ColorPicker.cjs.map +1 -1
  144. package/dist/components/input/ColorPicker.mjs +142 -165
  145. package/dist/components/input/ColorPicker.mjs.map +1 -1
  146. package/dist/components/input/ColorPicker.parts.cjs +2 -0
  147. package/dist/components/input/ColorPicker.parts.cjs.map +1 -0
  148. package/dist/components/input/ColorPicker.parts.mjs +192 -0
  149. package/dist/components/input/ColorPicker.parts.mjs.map +1 -0
  150. package/dist/components/input/ColorSlider.cjs +2 -0
  151. package/dist/components/input/ColorSlider.cjs.map +1 -0
  152. package/dist/components/input/ColorSlider.mjs +138 -0
  153. package/dist/components/input/ColorSlider.mjs.map +1 -0
  154. package/dist/components/input/Combobox.cjs +1 -1
  155. package/dist/components/input/Combobox.cjs.map +1 -1
  156. package/dist/components/input/Combobox.expand.cjs +1 -1
  157. package/dist/components/input/Combobox.expand.cjs.map +1 -1
  158. package/dist/components/input/Combobox.expand.mjs +9 -9
  159. package/dist/components/input/Combobox.expand.mjs.map +1 -1
  160. package/dist/components/input/Combobox.mjs +90 -85
  161. package/dist/components/input/Combobox.mjs.map +1 -1
  162. package/dist/components/input/DatePicker.cjs +1 -1
  163. package/dist/components/input/DatePicker.cjs.map +1 -1
  164. package/dist/components/input/DatePicker.mjs +186 -185
  165. package/dist/components/input/DatePicker.mjs.map +1 -1
  166. package/dist/components/input/Dropdown.cjs +1 -1
  167. package/dist/components/input/Dropdown.cjs.map +1 -1
  168. package/dist/components/input/Dropdown.mjs +71 -68
  169. package/dist/components/input/Dropdown.mjs.map +1 -1
  170. package/dist/components/input/Field.cjs +1 -1
  171. package/dist/components/input/Field.cjs.map +1 -1
  172. package/dist/components/input/Field.mjs +113 -112
  173. package/dist/components/input/Field.mjs.map +1 -1
  174. package/dist/components/input/Input.cjs +1 -1
  175. package/dist/components/input/Input.cjs.map +1 -1
  176. package/dist/components/input/Input.mjs +55 -54
  177. package/dist/components/input/Input.mjs.map +1 -1
  178. package/dist/components/input/Label.cjs +1 -1
  179. package/dist/components/input/Label.cjs.map +1 -1
  180. package/dist/components/input/Label.mjs +12 -11
  181. package/dist/components/input/Label.mjs.map +1 -1
  182. package/dist/components/input/Option.cjs +1 -1
  183. package/dist/components/input/Option.cjs.map +1 -1
  184. package/dist/components/input/Option.mjs +100 -98
  185. package/dist/components/input/Option.mjs.map +1 -1
  186. package/dist/components/input/RadioGroup.cjs +1 -1
  187. package/dist/components/input/RadioGroup.cjs.map +1 -1
  188. package/dist/components/input/RadioGroup.mjs +89 -88
  189. package/dist/components/input/RadioGroup.mjs.map +1 -1
  190. package/dist/components/input/Rating.cjs +1 -1
  191. package/dist/components/input/Rating.cjs.map +1 -1
  192. package/dist/components/input/Rating.mjs +110 -109
  193. package/dist/components/input/Rating.mjs.map +1 -1
  194. package/dist/components/input/SearchBox.cjs +1 -1
  195. package/dist/components/input/SearchBox.cjs.map +1 -1
  196. package/dist/components/input/SearchBox.mjs +118 -119
  197. package/dist/components/input/SearchBox.mjs.map +1 -1
  198. package/dist/components/input/Select.cjs +1 -1
  199. package/dist/components/input/Select.cjs.map +1 -1
  200. package/dist/components/input/Select.mjs +25 -24
  201. package/dist/components/input/Select.mjs.map +1 -1
  202. package/dist/components/input/Slider.cjs +1 -1
  203. package/dist/components/input/Slider.cjs.map +1 -1
  204. package/dist/components/input/Slider.mjs +47 -46
  205. package/dist/components/input/Slider.mjs.map +1 -1
  206. package/dist/components/input/SpinButton.cjs +1 -1
  207. package/dist/components/input/SpinButton.cjs.map +1 -1
  208. package/dist/components/input/SpinButton.mjs +76 -75
  209. package/dist/components/input/SpinButton.mjs.map +1 -1
  210. package/dist/components/input/SwatchPicker.cjs +1 -1
  211. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  212. package/dist/components/input/SwatchPicker.mjs +38 -37
  213. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  214. package/dist/components/input/Switch.cjs +1 -1
  215. package/dist/components/input/Switch.cjs.map +1 -1
  216. package/dist/components/input/Switch.mjs +65 -64
  217. package/dist/components/input/Switch.mjs.map +1 -1
  218. package/dist/components/input/TagPicker.cjs +1 -1
  219. package/dist/components/input/TagPicker.cjs.map +1 -1
  220. package/dist/components/input/TagPicker.mjs +161 -157
  221. package/dist/components/input/TagPicker.mjs.map +1 -1
  222. package/dist/components/input/Textarea.cjs +1 -1
  223. package/dist/components/input/Textarea.cjs.map +1 -1
  224. package/dist/components/input/Textarea.mjs +24 -23
  225. package/dist/components/input/Textarea.mjs.map +1 -1
  226. package/dist/components/input/TimePicker.cjs +1 -1
  227. package/dist/components/input/TimePicker.cjs.map +1 -1
  228. package/dist/components/input/TimePicker.mjs +202 -199
  229. package/dist/components/input/TimePicker.mjs.map +1 -1
  230. package/dist/components/input/colorName.cjs +2 -0
  231. package/dist/components/input/colorName.cjs.map +1 -0
  232. package/dist/components/input/colorName.mjs +30 -0
  233. package/dist/components/input/colorName.mjs.map +1 -0
  234. package/dist/components/input/colorUtils.cjs +1 -1
  235. package/dist/components/input/colorUtils.cjs.map +1 -1
  236. package/dist/components/input/colorUtils.mjs +154 -56
  237. package/dist/components/input/colorUtils.mjs.map +1 -1
  238. package/dist/components/layout/Accordion.cjs +1 -1
  239. package/dist/components/layout/Accordion.cjs.map +1 -1
  240. package/dist/components/layout/Accordion.mjs +130 -129
  241. package/dist/components/layout/Accordion.mjs.map +1 -1
  242. package/dist/components/layout/Card.cjs +1 -1
  243. package/dist/components/layout/Card.cjs.map +1 -1
  244. package/dist/components/layout/Card.mjs +78 -77
  245. package/dist/components/layout/Card.mjs.map +1 -1
  246. package/dist/components/layout/Carousel.cjs +1 -1
  247. package/dist/components/layout/Carousel.cjs.map +1 -1
  248. package/dist/components/layout/Carousel.mjs +111 -110
  249. package/dist/components/layout/Carousel.mjs.map +1 -1
  250. package/dist/components/layout/Flex.cjs +1 -1
  251. package/dist/components/layout/Flex.cjs.map +1 -1
  252. package/dist/components/layout/Flex.mjs +22 -21
  253. package/dist/components/layout/Flex.mjs.map +1 -1
  254. package/dist/components/layout/Grid.cjs +1 -1
  255. package/dist/components/layout/Grid.cjs.map +1 -1
  256. package/dist/components/layout/Grid.mjs +19 -18
  257. package/dist/components/layout/Grid.mjs.map +1 -1
  258. package/dist/components/layout/Overflow.cjs +1 -1
  259. package/dist/components/layout/Overflow.cjs.map +1 -1
  260. package/dist/components/layout/Overflow.mjs +92 -91
  261. package/dist/components/layout/Overflow.mjs.map +1 -1
  262. package/dist/components/layout/Stack.cjs +1 -1
  263. package/dist/components/layout/Stack.cjs.map +1 -1
  264. package/dist/components/layout/Stack.mjs +14 -13
  265. package/dist/components/layout/Stack.mjs.map +1 -1
  266. package/dist/components/layout/TabList.cjs +1 -1
  267. package/dist/components/layout/TabList.cjs.map +1 -1
  268. package/dist/components/layout/TabList.mjs +118 -117
  269. package/dist/components/layout/TabList.mjs.map +1 -1
  270. package/dist/components/layout/Tree.cjs +1 -1
  271. package/dist/components/layout/Tree.cjs.map +1 -1
  272. package/dist/components/layout/Tree.context.cjs +2 -0
  273. package/dist/components/layout/Tree.context.cjs.map +1 -0
  274. package/dist/components/layout/Tree.context.mjs +33 -0
  275. package/dist/components/layout/Tree.context.mjs.map +1 -0
  276. package/dist/components/layout/Tree.core.cjs +2 -0
  277. package/dist/components/layout/Tree.core.cjs.map +1 -0
  278. package/dist/components/layout/Tree.core.mjs +416 -0
  279. package/dist/components/layout/Tree.core.mjs.map +1 -0
  280. package/dist/components/layout/Tree.itemPersonaLayout.cjs +2 -0
  281. package/dist/components/layout/Tree.itemPersonaLayout.cjs.map +1 -0
  282. package/dist/components/layout/Tree.itemPersonaLayout.mjs +46 -0
  283. package/dist/components/layout/Tree.itemPersonaLayout.mjs.map +1 -0
  284. package/dist/components/layout/Tree.mjs +7 -215
  285. package/dist/components/layout/Tree.mjs.map +1 -1
  286. package/dist/components/layout/Tree.selection.cjs +2 -0
  287. package/dist/components/layout/Tree.selection.cjs.map +1 -0
  288. package/dist/components/layout/Tree.selection.mjs +73 -0
  289. package/dist/components/layout/Tree.selection.mjs.map +1 -0
  290. package/dist/components/navigation/Breadcrumb.cjs +1 -1
  291. package/dist/components/navigation/Breadcrumb.cjs.map +1 -1
  292. package/dist/components/navigation/Breadcrumb.mjs +76 -75
  293. package/dist/components/navigation/Breadcrumb.mjs.map +1 -1
  294. package/dist/components/navigation/Menu.group.cjs +1 -1
  295. package/dist/components/navigation/Menu.group.cjs.map +1 -1
  296. package/dist/components/navigation/Menu.group.mjs +39 -37
  297. package/dist/components/navigation/Menu.group.mjs.map +1 -1
  298. package/dist/components/navigation/Menu.items.cjs +1 -1
  299. package/dist/components/navigation/Menu.items.cjs.map +1 -1
  300. package/dist/components/navigation/Menu.items.mjs +67 -61
  301. package/dist/components/navigation/Menu.items.mjs.map +1 -1
  302. package/dist/components/navigation/Menu.link.cjs +1 -1
  303. package/dist/components/navigation/Menu.link.cjs.map +1 -1
  304. package/dist/components/navigation/Menu.link.mjs +34 -28
  305. package/dist/components/navigation/Menu.link.mjs.map +1 -1
  306. package/dist/components/navigation/Menu.popover.cjs +1 -1
  307. package/dist/components/navigation/Menu.popover.cjs.map +1 -1
  308. package/dist/components/navigation/Menu.popover.mjs +110 -109
  309. package/dist/components/navigation/Menu.popover.mjs.map +1 -1
  310. package/dist/components/navigation/Menu.root.cjs +1 -1
  311. package/dist/components/navigation/Menu.root.cjs.map +1 -1
  312. package/dist/components/navigation/Menu.root.mjs +171 -170
  313. package/dist/components/navigation/Menu.root.mjs.map +1 -1
  314. package/dist/components/navigation/Menu.selectable.cjs +1 -1
  315. package/dist/components/navigation/Menu.selectable.cjs.map +1 -1
  316. package/dist/components/navigation/Menu.selectable.mjs +85 -63
  317. package/dist/components/navigation/Menu.selectable.mjs.map +1 -1
  318. package/dist/components/navigation/Menu.splitGroup.cjs +1 -1
  319. package/dist/components/navigation/Menu.splitGroup.cjs.map +1 -1
  320. package/dist/components/navigation/Menu.splitGroup.mjs +27 -26
  321. package/dist/components/navigation/Menu.splitGroup.mjs.map +1 -1
  322. package/dist/components/navigation/Menu.trigger.cjs +1 -1
  323. package/dist/components/navigation/Menu.trigger.cjs.map +1 -1
  324. package/dist/components/navigation/Menu.trigger.mjs +6 -6
  325. package/dist/components/navigation/Nav.cjs +1 -1
  326. package/dist/components/navigation/Nav.cjs.map +1 -1
  327. package/dist/components/navigation/Nav.mjs +170 -155
  328. package/dist/components/navigation/Nav.mjs.map +1 -1
  329. package/dist/components/navigation/Pagination.cjs +1 -1
  330. package/dist/components/navigation/Pagination.cjs.map +1 -1
  331. package/dist/components/navigation/Pagination.mjs +73 -65
  332. package/dist/components/navigation/Pagination.mjs.map +1 -1
  333. package/dist/components/navigation/Stepper.cjs +1 -1
  334. package/dist/components/navigation/Stepper.cjs.map +1 -1
  335. package/dist/components/navigation/Stepper.mjs +110 -109
  336. package/dist/components/navigation/Stepper.mjs.map +1 -1
  337. package/dist/components/overlays/Dialog.cjs +1 -1
  338. package/dist/components/overlays/Dialog.cjs.map +1 -1
  339. package/dist/components/overlays/Dialog.mjs +109 -108
  340. package/dist/components/overlays/Dialog.mjs.map +1 -1
  341. package/dist/components/overlays/Drawer.cjs +1 -1
  342. package/dist/components/overlays/Drawer.cjs.map +1 -1
  343. package/dist/components/overlays/Drawer.mjs +110 -109
  344. package/dist/components/overlays/Drawer.mjs.map +1 -1
  345. package/dist/components/overlays/Popover.cjs +1 -1
  346. package/dist/components/overlays/Popover.cjs.map +1 -1
  347. package/dist/components/overlays/Popover.mjs +229 -227
  348. package/dist/components/overlays/Popover.mjs.map +1 -1
  349. package/dist/components/overlays/TeachingPopover.cjs +1 -1
  350. package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
  351. package/dist/components/overlays/TeachingPopover.mjs +41 -37
  352. package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
  353. package/dist/components/overlays/Tooltip.cjs +1 -1
  354. package/dist/components/overlays/Tooltip.cjs.map +1 -1
  355. package/dist/components/overlays/Tooltip.mjs +87 -86
  356. package/dist/components/overlays/Tooltip.mjs.map +1 -1
  357. package/dist/components/portal/Portal.cjs +1 -1
  358. package/dist/components/portal/Portal.cjs.map +1 -1
  359. package/dist/components/portal/Portal.mjs +33 -32
  360. package/dist/components/portal/Portal.mjs.map +1 -1
  361. package/dist/components/provider/WaveProvider.cjs +1 -1
  362. package/dist/components/provider/WaveProvider.cjs.map +1 -1
  363. package/dist/components/provider/WaveProvider.mjs +31 -30
  364. package/dist/components/provider/WaveProvider.mjs.map +1 -1
  365. package/dist/components/table/DataGrid.cjs +1 -1
  366. package/dist/components/table/DataGrid.cjs.map +1 -1
  367. package/dist/components/table/DataGrid.mjs +228 -227
  368. package/dist/components/table/DataGrid.mjs.map +1 -1
  369. package/dist/components/table/Table.cjs +1 -1
  370. package/dist/components/table/Table.cjs.map +1 -1
  371. package/dist/components/table/Table.mjs +60 -59
  372. package/dist/components/table/Table.mjs.map +1 -1
  373. package/dist/components/typography/Text.cjs +1 -1
  374. package/dist/components/typography/Text.cjs.map +1 -1
  375. package/dist/components/typography/Text.mjs +12 -11
  376. package/dist/components/typography/Text.mjs.map +1 -1
  377. package/dist/hooks/useMediaQuery.cjs +2 -0
  378. package/dist/hooks/useMediaQuery.cjs.map +1 -0
  379. package/dist/hooks/useMediaQuery.mjs +20 -0
  380. package/dist/hooks/useMediaQuery.mjs.map +1 -0
  381. package/dist/hooks/usePrefersReducedMotion.cjs +1 -1
  382. package/dist/hooks/usePrefersReducedMotion.cjs.map +1 -1
  383. package/dist/hooks/usePrefersReducedMotion.mjs +4 -18
  384. package/dist/hooks/usePrefersReducedMotion.mjs.map +1 -1
  385. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  386. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  387. package/dist/hooks/useRovingTabIndex.mjs +3 -3
  388. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  389. package/dist/index.cjs +1 -1
  390. package/dist/index.d.cts +2089 -102
  391. package/dist/index.d.ts +2089 -102
  392. package/dist/index.mjs +99 -87
  393. package/dist/lib/classNames.cjs +2 -0
  394. package/dist/lib/classNames.cjs.map +1 -0
  395. package/dist/lib/classNames.mjs +415 -0
  396. package/dist/lib/classNames.mjs.map +1 -0
  397. package/dist/lib/color.cjs +2 -0
  398. package/dist/lib/color.cjs.map +1 -0
  399. package/dist/lib/color.mjs +86 -0
  400. package/dist/lib/color.mjs.map +1 -0
  401. package/dist/lib/globalRegistry.cjs.map +1 -1
  402. package/dist/lib/globalRegistry.mjs.map +1 -1
  403. package/dist/lib/toaster.cjs +2 -0
  404. package/dist/lib/toaster.cjs.map +1 -0
  405. package/dist/lib/toaster.mjs +77 -0
  406. package/dist/lib/toaster.mjs.map +1 -0
  407. package/dist/styles.css +1 -1
  408. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.cjs","names":["React","inertModalTrigger","useRequiredContext","useModalOpenState","useIsClient","useModalTrigger","useModalTriggerPart","useModalClosePart","useId","useTitleRegistry","useMergedRefs","useBackdropPress","useModalDismiss","useModalLayer","slotRendersContent","Portal","cn","ModalSurfaceContext","Button","DismissIcon","useModalTitle","require_runtime","require_cn","require_dev","require_slot","require_useId","require_useMergedRefs","require_useIsClient","require_Portal","require_Button","require_icons","require_useModalLayer","require_Dialog_shared","react","react_jsx_runtime","DialogContext","inertDialogContext","useDialogContext","componentName","DialogRoot","openState","requestOpen","open","defaultOpen","onOpenChange","isClient","isOpen","trigger","contentId","setContentId","registerContentId","id","current","context","modalType","finalFocusRef","DialogTrigger","props","DialogClose","sizeClasses","DialogContent","rest","generatedId","propTitleId","titles","surface","setSurface","surfaceRef","attachSurface","node","registerId","mergedRef","ref","closesOnBackdropPress","backdropPress","onDismiss","layer","footerHeight","setFooterHeight","surfaceContext","hasTitle","title","size","className","closeLabel","event","DialogTitle","titleId","titleRef","stickyFooterClasses","footerRowClasses","DialogFooter","outsideContent","footer","setFooter","observer","entry","entries","Dialog"],"sources":["../../../src/components/overlays/Dialog.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnOnce } from '../../lib/dev';\nimport { DismissIcon } from '../../lib/icons';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { ModalOpenChangeReason, ModalType, OpenChangeDetails } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useModalLayer } from '../../hooks/useModalLayer';\nimport { Button } from '../button/Button';\nimport { Portal } from '../portal/Portal';\nimport {\n inertModalTrigger,\n ModalSurfaceContext,\n useBackdropPress,\n useModalClosePart,\n useModalDismiss,\n useModalOpenState,\n useModalTitle,\n useModalTrigger,\n useModalTriggerPart,\n useModalTriggerSession,\n useRequiredContext,\n useTitleRegistry,\n useUnnamedModalWarning,\n type ModalRequestOpen,\n type ModalSurfaceContextValue,\n type ModalTrigger,\n} from './Dialog.shared';\n\n/**\n * Why a {@link Dialog} asks to open or close: `trigger` (`Dialog.Trigger`), `close`\n * (`Dialog.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`.\n */\nexport type DialogOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a {@link Dialog}'s `onOpenChange`: the reason and the DOM event. */\nexport type DialogOpenChangeDetails = OpenChangeDetails<DialogOpenChangeReason>;\n\n/**\n * How a {@link Dialog} blocks the page (the shared `ModalType`; Drawer reuses it when it gains\n * `modalType`).\n */\nexport type DialogModalType = ModalType;\n\n/** Properties for the Dialog component. */\nexport interface DialogProps {\n /**\n * Controlled open state of the dialog. The surface renders only in the browser: an open dialog\n * is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Default open state for uncontrolled usage. The surface renders only in the browser: a dialog\n * open by default is closed in the server HTML and opens once it has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the new open state when it changes. `details.reason` tells how — `trigger`,\n * `close` (a `.Close` part), `close-button` (the built-in Close button), `escape` or\n * `outside-press` (the backdrop) — so a controlled dialog can refuse only some ways of closing\n * (for example keep a form with unsaved changes open on `outside-press`); `details.event` is the\n * DOM event behind the request. WaveUI always passes `details`; it is typed optional until 1.0\n * so that code which calls this prop itself keeps compiling.\n *\n * Fires only when the value changes; a controlled dialog stays as it is until the parent updates\n * `open`.\n */\n onOpenChange?: (open: boolean, details?: DialogOpenChangeDetails) => void;\n /**\n * `modal`: a backdrop press, Escape, the Close button and `Dialog.Close` close it. `alert`: a\n * confirmation that needs an answer — `role=\"alertdialog\"`, and a backdrop press does not close\n * it (Escape still does). Initial focus goes to the first focusable element, the built-in Close\n * button; give the least destructive action `autoFocus` to focus it instead. (`'non-modal'` is\n * planned.)\n * @default 'modal'\n */\n modalType?: DialogModalType;\n /**\n * Where focus goes when the dialog closes, if it can take focus. Otherwise focus returns to the\n * element that had focus when the dialog opened, then to the trigger, then to an element next to\n * where that opener was (the next row's action after a confirm dialog deleted the row). Use it to\n * send focus somewhere else.\n */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /** `Dialog.Trigger` and `Dialog.Content`. */\n children: React.ReactNode;\n}\n\n/** Properties for the DialogContent sub-component. */\nexport interface DialogContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /**\n * Title rendered as the dialog's heading; it names the dialog (`aria-labelledby`). Without it,\n * render a `Dialog.Title` or pass `aria-label`/`aria-labelledby`. A title that renders nothing\n * (`''`, `[]`, `true`) counts as none.\n */\n title?: React.ReactNode;\n /** Maximum width of the dialog: 400px (`small`) or 600px (`medium`); it never exceeds the viewport.\n * @default 'medium'\n */\n size?: 'small' | 'medium';\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /** Content rendered inside the dialog body (put `Dialog.Footer` here as well). */\n children: React.ReactNode;\n /** Ref to the dialog surface (`role=\"dialog\"`, or `alertdialog` with `modalType=\"alert\"`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogFooter sub-component. */\nexport interface DialogFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content, typically action buttons (wrap closing buttons in `Dialog.Close`). */\n children: React.ReactNode;\n /** Ref to the footer element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogTitle sub-component. */\nexport interface DialogTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /** The title; any content. */\n children: React.ReactNode;\n /** Ref to the heading element. */\n ref?: React.Ref<HTMLHeadingElement>;\n}\n\n/** Props a `Dialog.Trigger` puts on its element (and passes to a render-prop child). */\nexport interface DialogTriggerRenderProps extends React.HTMLAttributes<HTMLElement> {\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The dialog surface's id, while the dialog is open. */\n 'aria-controls'?: string;\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogTrigger sub-component. */\nexport interface DialogTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that opens the dialog. A single element receives the trigger props (merged with\n * its own: handlers composed, classes joined, its own `id` kept); a function receives them.\n */\n children: React.ReactNode | ((props: DialogTriggerRenderProps) => React.ReactNode);\n /**\n * `false` renders the 0.4 wrapper `<span>` around the children instead of merging the trigger\n * props onto the child. The span carries the click handler; `aria-haspopup`, `aria-expanded`\n * and `aria-controls` go to the first element in the tab order inside it.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Props a `Dialog.Close` puts on its element (and passes to a render-prop child). */\nexport interface DialogCloseRenderProps extends React.HTMLAttributes<HTMLElement> {\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogClose sub-component. */\nexport interface DialogCloseProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that closes the dialog, typically a footer button. A single element receives an\n * `onClick` composed with its own (its handler runs first; `preventDefault()` keeps the dialog\n * open); a function receives the props.\n */\n children: React.ReactNode | ((props: DialogCloseRenderProps) => React.ReactNode);\n /** `false` renders a wrapper `<span>` that closes the dialog on click. @default true */\n asChild?: boolean;\n /** Ref to the close element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\ninterface DialogContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The resolved `modalType`. */\n modalType: DialogModalType;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n finalFocusRef: React.RefObject<HTMLElement | null> | undefined;\n /** The id of the open dialog surface (for the trigger's `aria-controls`), or `undefined`. */\n contentId: string | undefined;\n /** Registers the surface's id while it is mounted; returns the unregister function. */\n registerContentId: (id: string) => () => void;\n}\n\nconst DialogContext = React.createContext<DialogContextValue | null>(null);\nDialogContext.displayName = 'DialogContext';\n\nconst inertDialogContext: DialogContextValue = {\n open: false,\n requestOpen: () => {},\n modalType: 'modal',\n trigger: inertModalTrigger,\n finalFocusRef: undefined,\n contentId: undefined,\n registerContentId: () => () => {},\n};\n\nfunction useDialogContext(componentName: string): DialogContextValue {\n return useRequiredContext(DialogContext, componentName, 'Dialog', () => inertDialogContext);\n}\n\n// The root of `Dialog` (documented on the export below). A const arrow (like DrawerRoot): its type\n// can be named in consumers' declaration files, e.g. a story's `satisfies Meta<typeof Dialog>` (a\n// function declaration's `typeof` cannot, TS4023).\nconst DialogRoot = ({\n open,\n defaultOpen,\n onOpenChange,\n modalType = 'modal',\n finalFocusRef,\n children,\n}: DialogProps) => {\n const [openState, requestOpen] = useModalOpenState(open, defaultOpen, onOpenChange);\n // The surface lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the dialog reports itself closed, so the trigger's aria-expanded never\n // describes a dialog that is not there.\n const isClient = useIsClient();\n const isOpen = openState && isClient;\n const trigger = useModalTrigger();\n // After Dialog.Content's focus restore (a child's layout effects run first), start the trigger\n // session, or end it and forget the trigger that opened it.\n useModalTriggerSession(trigger, isOpen);\n const [contentId, setContentId] = React.useState<string | undefined>(undefined);\n const registerContentId = React.useCallback((id: string) => {\n setContentId(id);\n return () => setContentId((current) => (current === id ? undefined : current));\n }, []);\n\n const context = React.useMemo<DialogContextValue>(\n () => ({\n open: isOpen,\n requestOpen,\n modalType,\n trigger,\n finalFocusRef,\n contentId,\n registerContentId,\n }),\n [isOpen, requestOpen, modalType, trigger, finalFocusRef, contentId, registerContentId],\n );\n\n return <DialogContext.Provider value={context}>{children}</DialogContext.Provider>;\n};\nDialogRoot.displayName = 'Dialog';\n\n/**\n * Opens the dialog. Puts `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), a\n * click handler and a ref on its single child (no wrapper element), or passes them to a\n * render-prop child. A custom child component must forward `ref` and spread its props; one that\n * does not is wrapped in a `<span>` automatically (with a development warning), the span that\n * `asChild={false}` renders. Focus returns to the trigger when the dialog closes (with several\n * triggers, to the one that opened it). On the span, the state ARIA goes to the first element in\n * the tab order inside it, and focus returns to that element (to the span when you made it the\n * trigger with a `role` such as `button` and `tabIndex={0}`, or when nothing inside it can take\n * focus).\n */\nexport const DialogTrigger = (props: DialogTriggerProps) => {\n const { open, requestOpen, trigger, contentId } = useDialogContext('Dialog.Trigger');\n return useModalTriggerPart<DialogTriggerRenderProps>(\n { open, requestOpen, trigger, controlsId: contentId },\n props,\n 'Dialog.Trigger',\n );\n};\nDialogTrigger.displayName = 'DialogTrigger';\n\n/**\n * Closes the dialog: composes a click handler onto its single child (its own `onClick` runs first;\n * calling `preventDefault()` there keeps the dialog open), or passes it to a render-prop child.\n *\n * @example\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n */\nexport const DialogClose = (props: DialogCloseProps) => {\n const { requestOpen } = useDialogContext('Dialog.Close');\n return useModalClosePart<DialogCloseRenderProps>(requestOpen, props, 'Dialog.Close');\n};\nDialogClose.displayName = 'DialogClose';\n\nconst sizeClasses: Record<'small' | 'medium', string> = {\n small: 'max-w-[400px]',\n medium: 'max-w-[600px]',\n};\n\n/**\n * The dialog surface, rendered in a portal (inheriting the WaveProvider theme) while the dialog is\n * open: backdrop, title, Close button and a scrolling body. It takes the full width up to its\n * `size` and never exceeds the viewport (the body scrolls). It is `role=\"dialog\"`, or\n * `role=\"alertdialog\"` when the Dialog has `modalType=\"alert\"` (a `role` you pass wins), and\n * carries `data-modal-type` with the resolved type.\n */\nexport const DialogContent = ({\n title,\n size = 'medium',\n closeLabel = 'Close',\n children,\n className,\n id,\n ref,\n ...rest\n}: DialogContentProps) => {\n const { open, requestOpen, modalType, trigger, finalFocusRef, registerContentId } =\n useDialogContext('Dialog.Content');\n const generatedId = useId('wave-dialog');\n const contentId = id ?? generatedId;\n const propTitleId = useId('wave-dialog-title');\n const titles = useTitleRegistry();\n\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const attachSurface = React.useCallback((node: HTMLDivElement | null) => {\n surfaceRef.current = node;\n setSurface(node);\n }, []);\n // Reports the surface's id to the root (the trigger's `aria-controls`) while it is mounted. A new\n // `id` makes a new callback, which useMergedRefs re-attaches after the commit (re-registering).\n const registerId = React.useCallback(\n (node: HTMLDivElement | null) => (node ? registerContentId(contentId) : undefined),\n [registerContentId, contentId],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, attachSurface, registerId);\n\n // An alert dialog needs an answer: a backdrop press does not close it (Escape still does).\n const closesOnBackdropPress = modalType !== 'alert';\n const backdropPress = useBackdropPress(surfaceRef, closesOnBackdropPress);\n const onDismiss = useModalDismiss(requestOpen, 'Dialog', backdropPress.afterOutsidePress);\n const layer = useModalLayer({\n open,\n onDismiss,\n refs: [surfaceRef],\n outsidePress: closesOnBackdropPress,\n container: surface,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n useUnnamedModalWarning(open ? surface : null, titles.hasTitle, 'Dialog.Content', 'Dialog.Title');\n\n // The height of the sticky Dialog.Footer, reserved as the body's scroll padding.\n const [footerHeight, setFooterHeight] = React.useState<number | null>(null);\n const surfaceContext = React.useMemo<ModalSurfaceContextValue>(\n () => ({ ...titles.context, setFooterHeight }),\n [titles.context],\n );\n\n if (!open) return null;\n\n const hasTitle = slotRendersContent(title);\n\n return (\n <Portal layerId={layer.layerId}>\n <div\n className=\"fixed inset-0 flex items-center justify-center bg-backdrop p-4\"\n onMouseDown={backdropPress.onMouseDown}\n >\n <div\n ref={mergedRef}\n role={modalType === 'alert' ? 'alertdialog' : 'dialog'}\n id={contentId}\n aria-labelledby={hasTitle ? propTitleId : titles.titleId}\n tabIndex={-1}\n data-modal-type={modalType}\n {...rest}\n className={cn(\n // The border marks the surface where the shadow cannot: in high contrast the page,\n // the backdrop and the surface are black, and forced colors drop shadows.\n 'relative flex max-h-[calc(100dvh-2rem)] w-full flex-col rounded-lg border border-border bg-background p-6 text-foreground shadow-64',\n sizeClasses[size],\n className,\n )}\n >\n <ModalSurfaceContext.Provider value={surfaceContext}>\n {hasTitle && (\n <h2 id={propTitleId} className=\"pe-8 text-subtitle-1 font-semibold\">\n {title}\n </h2>\n )}\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<DismissIcon />}\n aria-label={closeLabel}\n onClick={(event) =>\n requestOpen(false, { reason: 'close-button', event: event.nativeEvent })\n }\n className=\"absolute end-4 top-4 text-muted-foreground\"\n />\n <div\n // The scroll padding keeps a focused field above the sticky footer (WCAG 2.4.11).\n className=\"-mx-1 mt-1 min-h-0 flex-1 overflow-y-auto scroll-pb-(--wave-dialog-footer-height) p-1 text-body-1 text-muted-foreground\"\n style={\n footerHeight === null\n ? undefined\n : ({ '--wave-dialog-footer-height': `${footerHeight}px` } as React.CSSProperties)\n }\n >\n {children}\n </div>\n </ModalSurfaceContext.Provider>\n </div>\n </div>\n </Portal>\n );\n};\nDialogContent.displayName = 'DialogContent';\n\n/**\n * A heading that names the dialog (`aria-labelledby`), for rich titles or custom layouts. Render it\n * inside `Dialog.Content` (instead of the `title` prop). Like the `title` heading it reserves end\n * padding (`pe-8`) so a long first line stays clear of the Close button; a `className` padding wins.\n */\nexport const DialogTitle = ({ id, className, children, ref, ...rest }: DialogTitleProps) => {\n const { id: titleId, ref: titleRef } = useModalTitle('Dialog.Title', 'Dialog.Content', id, ref);\n return (\n <h2\n {...rest}\n id={titleId}\n ref={titleRef}\n className={cn('pe-8 text-subtitle-1 font-semibold text-foreground', className)}\n >\n {children}\n </h2>\n );\n};\nDialogTitle.displayName = 'DialogTitle';\n\n/**\n * `Dialog.Footer` inside `Dialog.Content`. The body is `p-1`, and sticky positioning stops at its\n * padding edge: `-bottom-1` with `-mb-1 pb-2` covers the body's bottom padding, `-mx-1 px-1` its\n * focus-ring inset, and `pt-3` separates the actions from the content scrolling under them.\n */\nconst stickyFooterClasses =\n 'sticky -bottom-1 z-10 -mx-1 -mb-1 mt-6 flex justify-end gap-2 bg-background px-1 pb-2 pt-3';\n\n/**\n * `Dialog.Footer` where no body reserves its height as scroll padding (a Drawer's body): a plain\n * action row, which never covers a focused field.\n */\nconst footerRowClasses = 'mt-6 flex justify-end gap-2';\n\n/**\n * Action row at the end of the dialog body. It stays where you render it in the DOM and sticks to\n * the bottom of the body while long content scrolls under it (with an opaque background); the body\n * reserves its height as scroll padding, so a focused field is never hidden behind it. Inside a\n * `<form>` that wraps the fields and the footer it sticks too: make it the form's last child.\n * Render it inside `Dialog.Content`: outside it, it would stay on the page while the dialog is\n * closed (a development warning says so). Inside a `Drawer`, whose body reserves no footer height,\n * it does not stick: it is an action row at the end of the content. Render one `Dialog.Footer` per\n * `Dialog.Content`: with two at once, the body reserves the height of the one measured last, and\n * unmounting either clears it until the other resizes (swapping one footer for another is fine).\n */\nexport const DialogFooter = ({ children, className, ref, ...rest }: DialogFooterProps) => {\n const surfaceContext = React.useContext(ModalSurfaceContext);\n const outsideContent = surfaceContext === null;\n const setFooterHeight = surfaceContext?.setFooterHeight;\n const [footer, setFooter] = React.useState<HTMLDivElement | null>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, setFooter);\n\n React.useEffect(() => {\n if (!outsideContent) return;\n warnOnce(\n 'Dialog.Footer:outside-content',\n 'Dialog.Footer must be rendered inside Dialog.Content. Outside it, the footer stays on the page while the dialog is closed.',\n );\n }, [outsideContent]);\n\n // Reports the footer's border-box height to Dialog.Content. The observer's first callback,\n // delivered before the next paint, supplies the first value; without ResizeObserver the body\n // keeps its default scroll padding.\n React.useLayoutEffect(() => {\n if (!footer || !setFooterHeight || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[entries.length - 1];\n if (!entry) return;\n setFooterHeight(entry.borderBoxSize?.[0]?.blockSize ?? footer.offsetHeight);\n });\n observer.observe(footer, { box: 'border-box' });\n return () => {\n observer.disconnect();\n setFooterHeight(null);\n };\n }, [footer, setFooterHeight]);\n\n return (\n <div\n ref={mergedRef}\n {...rest}\n // Sticky only where the surface reserves the footer's height (Dialog.Content).\n className={cn(setFooterHeight ? stickyFooterClasses : footerRowClasses, className)}\n >\n {children}\n </div>\n );\n};\nDialogFooter.displayName = 'DialogFooter';\n\n/**\n * A modal dialog (Fluent UI v2 style): `Dialog` holds the open state; `Dialog.Trigger` opens it and\n * `Dialog.Content` renders the surface in a portal while open.\n *\n * - **Modal**: focus moves into the dialog and Tab stays inside it (toasts included), the rest of\n * the page is `inert` (instead of `aria-modal`, so toasts and live regions stay announced), and\n * the page does not scroll.\n * - **Closing**: Escape (only the topmost layer: a popup opened inside closes first), a click on\n * the backdrop (a drag that starts inside does not close it), the Close button and `Dialog.Close`.\n * `onOpenChange` gets the reason as its second argument (`details.reason`), so a controlled\n * dialog can refuse some of them. A backdrop press blurs the focused field before the dialog\n * closes, so a typed value is committed as with the Close button; when a controlled dialog\n * refuses the press, the field gets focus back (an alert dialog's press leaves focus where it\n * was). Focus returns to the first of these that can take focus: `finalFocusRef`, the element\n * that had focus when the dialog opened, the trigger, an element next to where that opener was.\n * - **Alert dialogs**: `modalType=\"alert\"` renders `role=\"alertdialog\"` for a confirmation that\n * needs an answer; a backdrop press does not close it.\n * - **Footer**: `Dialog.Footer` sticks to the bottom of the scrolling body, and the body keeps a\n * focused field above it.\n * - **Naming**: give `Dialog.Content` a `title`, a `Dialog.Title`, or `aria-label`.\n *\n * The sub-components are also exported under flat names (`DialogTrigger`, `DialogContent`,\n * `DialogFooter`, `DialogTitle`, `DialogClose`) for React Server Components, which cannot use the\n * dotted form; dotted access (`Dialog.Content`) needs a client file.\n *\n * @example\n * <Dialog>\n * <Dialog.Trigger><Button>Delete</Button></Dialog.Trigger>\n * <Dialog.Content title=\"Delete file?\">\n * This cannot be undone.\n * <Dialog.Footer>\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n * <Button appearance=\"primary\" onClick={remove}>Delete</Button>\n * </Dialog.Footer>\n * </Dialog.Content>\n * </Dialog>\n */\nexport const Dialog = /* @__PURE__ */ Object.assign(DialogRoot, {\n Trigger: DialogTrigger,\n Content: DialogContent,\n Footer: DialogFooter,\n Title: DialogTitle,\n Close: DialogClose,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Dialog.cjs","names":["React","inertModalTrigger","useRequiredContext","useModalOpenState","useIsClient","useModalTrigger","useModalTriggerPart","useModalClosePart","useId","useTitleRegistry","useMergedRefs","useBackdropPress","useModalDismiss","useModalLayer","slotRendersContent","Portal","cn","dialogContentClassNames","ModalSurfaceContext","dialogTitleClassNames","Button","DismissIcon","useModalTitle","dialogFooterClassNames","require_runtime","require_cn","require_dev","require_slot","require_classNames","require_useId","require_useMergedRefs","require_useIsClient","require_Portal","require_Button","require_icons","require_useModalLayer","require_Dialog_shared","react","react_jsx_runtime","DialogContext","inertDialogContext","useDialogContext","componentName","DialogRoot","openState","requestOpen","open","defaultOpen","onOpenChange","isClient","isOpen","trigger","contentId","setContentId","registerContentId","id","current","context","modalType","finalFocusRef","DialogTrigger","props","DialogClose","sizeClasses","DialogContent","rest","generatedId","propTitleId","titles","surface","setSurface","surfaceRef","attachSurface","node","registerId","mergedRef","ref","closesOnBackdropPress","backdropPress","onDismiss","layer","footerHeight","setFooterHeight","surfaceContext","hasTitle","title","size","className","closeLabel","event","DialogTitle","titleId","titleRef","stickyFooterClasses","footerRowClasses","DialogFooter","outsideContent","footer","setFooter","observer","entry","entries","Dialog"],"sources":["../../../src/components/overlays/Dialog.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport {\n dialogContentClassNames,\n dialogFooterClassNames,\n dialogTitleClassNames,\n} from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { DismissIcon } from '../../lib/icons';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { ModalOpenChangeReason, ModalType, OpenChangeDetails } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useModalLayer } from '../../hooks/useModalLayer';\nimport { Button } from '../button/Button';\nimport { Portal } from '../portal/Portal';\nimport {\n inertModalTrigger,\n ModalSurfaceContext,\n useBackdropPress,\n useModalClosePart,\n useModalDismiss,\n useModalOpenState,\n useModalTitle,\n useModalTrigger,\n useModalTriggerPart,\n useModalTriggerSession,\n useRequiredContext,\n useTitleRegistry,\n useUnnamedModalWarning,\n type ModalRequestOpen,\n type ModalSurfaceContextValue,\n type ModalTrigger,\n} from './Dialog.shared';\n\n/**\n * Why a {@link Dialog} asks to open or close: `trigger` (`Dialog.Trigger`), `close`\n * (`Dialog.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`.\n */\nexport type DialogOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a {@link Dialog}'s `onOpenChange`: the reason and the DOM event. */\nexport type DialogOpenChangeDetails = OpenChangeDetails<DialogOpenChangeReason>;\n\n/**\n * How a {@link Dialog} blocks the page (the shared `ModalType`; Drawer reuses it when it gains\n * `modalType`).\n */\nexport type DialogModalType = ModalType;\n\n/** Properties for the Dialog component. */\nexport interface DialogProps {\n /**\n * Controlled open state of the dialog. The surface renders only in the browser: an open dialog\n * is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Default open state for uncontrolled usage. The surface renders only in the browser: a dialog\n * open by default is closed in the server HTML and opens once it has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the new open state when it changes. `details.reason` tells how — `trigger`,\n * `close` (a `.Close` part), `close-button` (the built-in Close button), `escape` or\n * `outside-press` (the backdrop) — so a controlled dialog can refuse only some ways of closing\n * (for example keep a form with unsaved changes open on `outside-press`); `details.event` is the\n * DOM event behind the request. WaveUI always passes `details`; it is typed optional until 1.0\n * so that code which calls this prop itself keeps compiling.\n *\n * Fires only when the value changes; a controlled dialog stays as it is until the parent updates\n * `open`.\n */\n onOpenChange?: (open: boolean, details?: DialogOpenChangeDetails) => void;\n /**\n * `modal`: a backdrop press, Escape, the Close button and `Dialog.Close` close it. `alert`: a\n * confirmation that needs an answer — `role=\"alertdialog\"`, and a backdrop press does not close\n * it (Escape still does). Initial focus goes to the first focusable element, the built-in Close\n * button; give the least destructive action `autoFocus` to focus it instead. (`'non-modal'` is\n * planned.)\n * @default 'modal'\n */\n modalType?: DialogModalType;\n /**\n * Where focus goes when the dialog closes, if it can take focus. Otherwise focus returns to the\n * element that had focus when the dialog opened, then to the trigger, then to an element next to\n * where that opener was (the next row's action after a confirm dialog deleted the row). Use it to\n * send focus somewhere else.\n */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /** `Dialog.Trigger` and `Dialog.Content`. */\n children: React.ReactNode;\n}\n\n/** Properties for the DialogContent sub-component. */\nexport interface DialogContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /**\n * Title rendered as the dialog's heading; it names the dialog (`aria-labelledby`). Without it,\n * render a `Dialog.Title` or pass `aria-label`/`aria-labelledby`. A title that renders nothing\n * (`''`, `[]`, `true`) counts as none.\n */\n title?: React.ReactNode;\n /** Maximum width of the dialog: 400px (`small`) or 600px (`medium`); it never exceeds the viewport.\n * @default 'medium'\n */\n size?: 'small' | 'medium';\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /** Content rendered inside the dialog body (put `Dialog.Footer` here as well). */\n children: React.ReactNode;\n /** Ref to the dialog surface (`role=\"dialog\"`, or `alertdialog` with `modalType=\"alert\"`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogFooter sub-component. */\nexport interface DialogFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content, typically action buttons (wrap closing buttons in `Dialog.Close`). */\n children: React.ReactNode;\n /** Ref to the footer element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogTitle sub-component. */\nexport interface DialogTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /** The title; any content. */\n children: React.ReactNode;\n /** Ref to the heading element. */\n ref?: React.Ref<HTMLHeadingElement>;\n}\n\n/** Props a `Dialog.Trigger` puts on its element (and passes to a render-prop child). */\nexport interface DialogTriggerRenderProps extends React.HTMLAttributes<HTMLElement> {\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The dialog surface's id, while the dialog is open. */\n 'aria-controls'?: string;\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogTrigger sub-component. */\nexport interface DialogTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that opens the dialog. A single element receives the trigger props (merged with\n * its own: handlers composed, classes joined, its own `id` kept); a function receives them.\n */\n children: React.ReactNode | ((props: DialogTriggerRenderProps) => React.ReactNode);\n /**\n * `false` renders the 0.4 wrapper `<span>` around the children instead of merging the trigger\n * props onto the child. The span carries the click handler; `aria-haspopup`, `aria-expanded`\n * and `aria-controls` go to the first element in the tab order inside it.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Props a `Dialog.Close` puts on its element (and passes to a render-prop child). */\nexport interface DialogCloseRenderProps extends React.HTMLAttributes<HTMLElement> {\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogClose sub-component. */\nexport interface DialogCloseProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that closes the dialog, typically a footer button. A single element receives an\n * `onClick` composed with its own (its handler runs first; `preventDefault()` keeps the dialog\n * open); a function receives the props.\n */\n children: React.ReactNode | ((props: DialogCloseRenderProps) => React.ReactNode);\n /** `false` renders a wrapper `<span>` that closes the dialog on click. @default true */\n asChild?: boolean;\n /** Ref to the close element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\ninterface DialogContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The resolved `modalType`. */\n modalType: DialogModalType;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n finalFocusRef: React.RefObject<HTMLElement | null> | undefined;\n /** The id of the open dialog surface (for the trigger's `aria-controls`), or `undefined`. */\n contentId: string | undefined;\n /** Registers the surface's id while it is mounted; returns the unregister function. */\n registerContentId: (id: string) => () => void;\n}\n\nconst DialogContext = React.createContext<DialogContextValue | null>(null);\nDialogContext.displayName = 'DialogContext';\n\nconst inertDialogContext: DialogContextValue = {\n open: false,\n requestOpen: () => {},\n modalType: 'modal',\n trigger: inertModalTrigger,\n finalFocusRef: undefined,\n contentId: undefined,\n registerContentId: () => () => {},\n};\n\nfunction useDialogContext(componentName: string): DialogContextValue {\n return useRequiredContext(DialogContext, componentName, 'Dialog', () => inertDialogContext);\n}\n\n// The root of `Dialog` (documented on the export below). A const arrow (like DrawerRoot): its type\n// can be named in consumers' declaration files, e.g. a story's `satisfies Meta<typeof Dialog>` (a\n// function declaration's `typeof` cannot, TS4023).\nconst DialogRoot = ({\n open,\n defaultOpen,\n onOpenChange,\n modalType = 'modal',\n finalFocusRef,\n children,\n}: DialogProps) => {\n const [openState, requestOpen] = useModalOpenState(open, defaultOpen, onOpenChange);\n // The surface lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the dialog reports itself closed, so the trigger's aria-expanded never\n // describes a dialog that is not there.\n const isClient = useIsClient();\n const isOpen = openState && isClient;\n const trigger = useModalTrigger();\n // After Dialog.Content's focus restore (a child's layout effects run first), start the trigger\n // session, or end it and forget the trigger that opened it.\n useModalTriggerSession(trigger, isOpen);\n const [contentId, setContentId] = React.useState<string | undefined>(undefined);\n const registerContentId = React.useCallback((id: string) => {\n setContentId(id);\n return () => setContentId((current) => (current === id ? undefined : current));\n }, []);\n\n const context = React.useMemo<DialogContextValue>(\n () => ({\n open: isOpen,\n requestOpen,\n modalType,\n trigger,\n finalFocusRef,\n contentId,\n registerContentId,\n }),\n [isOpen, requestOpen, modalType, trigger, finalFocusRef, contentId, registerContentId],\n );\n\n return <DialogContext.Provider value={context}>{children}</DialogContext.Provider>;\n};\nDialogRoot.displayName = 'Dialog';\n\n/**\n * Opens the dialog. Puts `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), a\n * click handler and a ref on its single child (no wrapper element), or passes them to a\n * render-prop child. A custom child component must forward `ref` and spread its props; one that\n * does not is wrapped in a `<span>` automatically (with a development warning), the span that\n * `asChild={false}` renders. Focus returns to the trigger when the dialog closes (with several\n * triggers, to the one that opened it). On the span, the state ARIA goes to the first element in\n * the tab order inside it, and focus returns to that element (to the span when you made it the\n * trigger with a `role` such as `button` and `tabIndex={0}`, or when nothing inside it can take\n * focus).\n */\nexport const DialogTrigger = (props: DialogTriggerProps) => {\n const { open, requestOpen, trigger, contentId } = useDialogContext('Dialog.Trigger');\n return useModalTriggerPart<DialogTriggerRenderProps>(\n { open, requestOpen, trigger, controlsId: contentId },\n props,\n 'Dialog.Trigger',\n );\n};\nDialogTrigger.displayName = 'DialogTrigger';\n\n/**\n * Closes the dialog: composes a click handler onto its single child (its own `onClick` runs first;\n * calling `preventDefault()` there keeps the dialog open), or passes it to a render-prop child.\n *\n * @example\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n */\nexport const DialogClose = (props: DialogCloseProps) => {\n const { requestOpen } = useDialogContext('Dialog.Close');\n return useModalClosePart<DialogCloseRenderProps>(requestOpen, props, 'Dialog.Close');\n};\nDialogClose.displayName = 'DialogClose';\n\nconst sizeClasses: Record<'small' | 'medium', string> = {\n small: 'max-w-[400px]',\n medium: 'max-w-[600px]',\n};\n\n/**\n * The dialog surface, rendered in a portal (inheriting the WaveProvider theme) while the dialog is\n * open: backdrop, title, Close button and a scrolling body. It takes the full width up to its\n * `size` and never exceeds the viewport (the body scrolls, also sideways for content wider than\n * the dialog). Its 1rem gap to the viewport edges is its own margin, so a margin in `className`\n * replaces the gap: with the width and height caps lifted as well and its height set to the\n * viewport's, it fills the viewport (a full-screen dialog). It is `role=\"dialog\"`, or\n * `role=\"alertdialog\"` when the Dialog has `modalType=\"alert\"` (a `role` you pass wins), and\n * carries `data-modal-type` with the resolved type.\n */\nexport const DialogContent = ({\n title,\n size = 'medium',\n closeLabel = 'Close',\n children,\n className,\n id,\n ref,\n ...rest\n}: DialogContentProps) => {\n const { open, requestOpen, modalType, trigger, finalFocusRef, registerContentId } =\n useDialogContext('Dialog.Content');\n const generatedId = useId('wave-dialog');\n const contentId = id ?? generatedId;\n const propTitleId = useId('wave-dialog-title');\n const titles = useTitleRegistry();\n\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const attachSurface = React.useCallback((node: HTMLDivElement | null) => {\n surfaceRef.current = node;\n setSurface(node);\n }, []);\n // Reports the surface's id to the root (the trigger's `aria-controls`) while it is mounted. A new\n // `id` makes a new callback, which useMergedRefs re-attaches after the commit (re-registering).\n const registerId = React.useCallback(\n (node: HTMLDivElement | null) => (node ? registerContentId(contentId) : undefined),\n [registerContentId, contentId],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, attachSurface, registerId);\n\n // An alert dialog needs an answer: a backdrop press does not close it (Escape still does).\n const closesOnBackdropPress = modalType !== 'alert';\n const backdropPress = useBackdropPress(surfaceRef, closesOnBackdropPress);\n const onDismiss = useModalDismiss(requestOpen, 'Dialog', backdropPress.afterOutsidePress);\n const layer = useModalLayer({\n open,\n onDismiss,\n refs: [surfaceRef],\n outsidePress: closesOnBackdropPress,\n container: surface,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n useUnnamedModalWarning(open ? surface : null, titles.hasTitle, 'Dialog.Content', 'Dialog.Title');\n\n // The height of the sticky Dialog.Footer, reserved as the body's scroll padding.\n const [footerHeight, setFooterHeight] = React.useState<number | null>(null);\n const surfaceContext = React.useMemo<ModalSurfaceContextValue>(\n () => ({ ...titles.context, setFooterHeight }),\n [titles.context],\n );\n\n if (!open) return null;\n\n const hasTitle = slotRendersContent(title);\n\n return (\n <Portal layerId={layer.layerId}>\n <div\n className={cn(\n dialogContentClassNames.backdrop,\n 'fixed inset-0 flex items-center justify-center bg-backdrop',\n )}\n onMouseDown={backdropPress.onMouseDown}\n >\n <div\n ref={mergedRef}\n role={modalType === 'alert' ? 'alertdialog' : 'dialog'}\n id={contentId}\n aria-labelledby={hasTitle ? propTitleId : titles.titleId}\n tabIndex={-1}\n data-modal-type={modalType}\n {...rest}\n className={cn(\n dialogContentClassNames.root,\n // The border marks the surface where the shadow cannot: in high contrast the page,\n // the backdrop and the surface are black, and forced colors drop shadows. The 1rem gap\n // to the viewport edges is the surface's own margin, not the backdrop's padding, so a\n // margin in `className` replaces it and a full-screen dialog can reach the edges. Its\n // minimum width is zero, so content wider than the room inside the gap scrolls in the\n // body instead of pushing the surface over the gap.\n 'relative m-4 flex min-w-0 max-h-[calc(100dvh-2rem)] w-full flex-col rounded-lg border border-border bg-background p-6 text-foreground shadow-64',\n sizeClasses[size],\n className,\n )}\n >\n <ModalSurfaceContext.Provider value={surfaceContext}>\n {hasTitle && (\n <h2\n id={propTitleId}\n className={cn(dialogTitleClassNames.root, 'pe-8 text-subtitle-1 font-semibold')}\n >\n {title}\n </h2>\n )}\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<DismissIcon />}\n aria-label={closeLabel}\n onClick={(event) =>\n requestOpen(false, { reason: 'close-button', event: event.nativeEvent })\n }\n className={cn(\n dialogContentClassNames.closeButton,\n 'absolute end-4 top-4 text-muted-foreground',\n )}\n />\n <div\n // The scroll padding keeps a focused field above the sticky footer (WCAG 2.4.11).\n className={cn(\n dialogContentClassNames.body,\n '-mx-1 mt-1 min-h-0 flex-1 overflow-y-auto scroll-pb-(--wave-dialog-footer-height) p-1 text-body-1',\n )}\n style={\n footerHeight === null\n ? undefined\n : ({ '--wave-dialog-footer-height': `${footerHeight}px` } as React.CSSProperties)\n }\n >\n {children}\n </div>\n </ModalSurfaceContext.Provider>\n </div>\n </div>\n </Portal>\n );\n};\nDialogContent.displayName = 'DialogContent';\n\n/**\n * A heading that names the dialog (`aria-labelledby`), for rich titles or custom layouts. Render it\n * inside `Dialog.Content` (instead of the `title` prop). Like the `title` heading it reserves end\n * padding (`pe-8`) so a long first line stays clear of the Close button; a `className` padding wins.\n */\nexport const DialogTitle = ({ id, className, children, ref, ...rest }: DialogTitleProps) => {\n const { id: titleId, ref: titleRef } = useModalTitle('Dialog.Title', 'Dialog.Content', id, ref);\n return (\n <h2\n {...rest}\n id={titleId}\n ref={titleRef}\n className={cn(\n dialogTitleClassNames.root,\n 'pe-8 text-subtitle-1 font-semibold text-foreground',\n className,\n )}\n >\n {children}\n </h2>\n );\n};\nDialogTitle.displayName = 'DialogTitle';\n\n/**\n * `Dialog.Footer` inside `Dialog.Content`. The body is `p-1`, and sticky positioning stops at its\n * padding edge: `-bottom-1` with `-mb-1 pb-2` covers the body's bottom padding, `-mx-1 px-1` its\n * focus-ring inset, and `pt-3` separates the actions from the content scrolling under them.\n */\nconst stickyFooterClasses =\n 'sticky -bottom-1 z-10 -mx-1 -mb-1 mt-6 flex justify-end gap-2 bg-background px-1 pb-2 pt-3';\n\n/**\n * `Dialog.Footer` where no body reserves its height as scroll padding (a Drawer's body): a plain\n * action row, which never covers a focused field.\n */\nconst footerRowClasses = 'mt-6 flex justify-end gap-2';\n\n/**\n * Action row at the end of the dialog body. It stays where you render it in the DOM and sticks to\n * the bottom of the body while long content scrolls under it (with an opaque background); the body\n * reserves its height as scroll padding, so a focused field is never hidden behind it. Inside a\n * `<form>` that wraps the fields and the footer it sticks too: make it the form's last child.\n * Render it inside `Dialog.Content`: outside it, it would stay on the page while the dialog is\n * closed (a development warning says so). Inside a `Drawer`, whose body reserves no footer height,\n * it does not stick: it is an action row at the end of the content. Render one `Dialog.Footer` per\n * `Dialog.Content`: with two at once, the body reserves the height of the one measured last, and\n * unmounting either clears it until the other resizes (swapping one footer for another is fine).\n */\nexport const DialogFooter = ({ children, className, ref, ...rest }: DialogFooterProps) => {\n const surfaceContext = React.useContext(ModalSurfaceContext);\n const outsideContent = surfaceContext === null;\n const setFooterHeight = surfaceContext?.setFooterHeight;\n const [footer, setFooter] = React.useState<HTMLDivElement | null>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, setFooter);\n\n React.useEffect(() => {\n if (!outsideContent) return;\n warnOnce(\n 'Dialog.Footer:outside-content',\n 'Dialog.Footer must be rendered inside Dialog.Content. Outside it, the footer stays on the page while the dialog is closed.',\n );\n }, [outsideContent]);\n\n // Reports the footer's border-box height to Dialog.Content. The observer's first callback,\n // delivered before the next paint, supplies the first value; without ResizeObserver the body\n // keeps its default scroll padding.\n React.useLayoutEffect(() => {\n if (!footer || !setFooterHeight || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[entries.length - 1];\n if (!entry) return;\n setFooterHeight(entry.borderBoxSize?.[0]?.blockSize ?? footer.offsetHeight);\n });\n observer.observe(footer, { box: 'border-box' });\n return () => {\n observer.disconnect();\n setFooterHeight(null);\n };\n }, [footer, setFooterHeight]);\n\n return (\n <div\n ref={mergedRef}\n {...rest}\n // Sticky only where the surface reserves the footer's height (Dialog.Content).\n className={cn(\n dialogFooterClassNames.root,\n setFooterHeight ? stickyFooterClasses : footerRowClasses,\n className,\n )}\n >\n {children}\n </div>\n );\n};\nDialogFooter.displayName = 'DialogFooter';\n\n/**\n * A modal dialog (Fluent UI v2 style): `Dialog` holds the open state; `Dialog.Trigger` opens it and\n * `Dialog.Content` renders the surface in a portal while open.\n *\n * - **Modal**: focus moves into the dialog and Tab stays inside it (toasts included), the rest of\n * the page is `inert` (instead of `aria-modal`, so toasts and live regions stay announced), and\n * the page does not scroll.\n * - **Closing**: Escape (only the topmost layer: a popup opened inside closes first), a click on\n * the backdrop (a drag that starts inside does not close it), the Close button and `Dialog.Close`.\n * `onOpenChange` gets the reason as its second argument (`details.reason`), so a controlled\n * dialog can refuse some of them. A backdrop press blurs the focused field before the dialog\n * closes, so a typed value is committed as with the Close button; when a controlled dialog\n * refuses the press, the field gets focus back (an alert dialog's press leaves focus where it\n * was). Focus returns to the first of these that can take focus: `finalFocusRef`, the element\n * that had focus when the dialog opened, the trigger, an element next to where that opener was.\n * - **Alert dialogs**: `modalType=\"alert\"` renders `role=\"alertdialog\"` for a confirmation that\n * needs an answer; a backdrop press does not close it.\n * - **Footer**: `Dialog.Footer` sticks to the bottom of the scrolling body, and the body keeps a\n * focused field above it.\n * - **Naming**: give `Dialog.Content` a `title`, a `Dialog.Title`, or `aria-label`.\n *\n * The sub-components are also exported under flat names (`DialogTrigger`, `DialogContent`,\n * `DialogFooter`, `DialogTitle`, `DialogClose`) for React Server Components, which cannot use the\n * dotted form; dotted access (`Dialog.Content`) needs a client file.\n *\n * @example\n * <Dialog>\n * <Dialog.Trigger><Button>Delete</Button></Dialog.Trigger>\n * <Dialog.Content title=\"Delete file?\">\n * This cannot be undone.\n * <Dialog.Footer>\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n * <Button appearance=\"primary\" onClick={remove}>Delete</Button>\n * </Dialog.Footer>\n * </Dialog.Content>\n * </Dialog>\n */\nexport const Dialog = /* @__PURE__ */ Object.assign(DialogRoot, {\n Trigger: DialogTrigger,\n Content: DialogContent,\n Footer: DialogFooter,\n Title: DialogTitle,\n Close: DialogClose,\n});\n"],"mappings":"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"}
@@ -2,37 +2,38 @@
2
2
  import { cn as e } from "../../lib/cn.mjs";
3
3
  import { warnOnce as t } from "../../lib/dev.mjs";
4
4
  import { slotRendersContent as n } from "../../lib/slot.mjs";
5
- import { useId as r } from "../../hooks/useId.mjs";
6
- import { useMergedRefs as i } from "../../hooks/useMergedRefs.mjs";
7
- import { useIsClient as a } from "../../hooks/useIsClient.mjs";
8
- import { Portal as o } from "../portal/Portal.mjs";
9
- import { Button as s } from "../button/Button.mjs";
10
- import { DismissIcon as c } from "../../lib/icons.mjs";
11
- import { useModalLayer as l } from "../../hooks/useModalLayer.mjs";
12
- import { ModalSurfaceContext as u, inertModalTrigger as d, useBackdropPress as f, useModalClosePart as p, useModalDismiss as m, useModalOpenState as h, useModalTitle as g, useModalTrigger as _, useModalTriggerPart as v, useModalTriggerSession as y, useRequiredContext as b, useTitleRegistry as x, useUnnamedModalWarning as S } from "./Dialog.shared.mjs";
13
- import * as C from "react";
14
- import { jsx as w, jsxs as T } from "react/jsx-runtime";
5
+ import { dialogContentClassNames as r, dialogFooterClassNames as i, dialogTitleClassNames as a } from "../../lib/classNames.mjs";
6
+ import { useId as o } from "../../hooks/useId.mjs";
7
+ import { useMergedRefs as s } from "../../hooks/useMergedRefs.mjs";
8
+ import { useIsClient as c } from "../../hooks/useIsClient.mjs";
9
+ import { Portal as l } from "../portal/Portal.mjs";
10
+ import { Button as u } from "../button/Button.mjs";
11
+ import { DismissIcon as d } from "../../lib/icons.mjs";
12
+ import { useModalLayer as f } from "../../hooks/useModalLayer.mjs";
13
+ import { ModalSurfaceContext as p, inertModalTrigger as m, useBackdropPress as h, useModalClosePart as g, useModalDismiss as _, useModalOpenState as v, useModalTitle as y, useModalTrigger as b, useModalTriggerPart as x, useModalTriggerSession as S, useRequiredContext as C, useTitleRegistry as w, useUnnamedModalWarning as T } from "./Dialog.shared.mjs";
14
+ import * as E from "react";
15
+ import { jsx as D, jsxs as O } from "react/jsx-runtime";
15
16
  //#region src/components/overlays/Dialog.tsx
16
- var E = C.createContext(null);
17
- E.displayName = "DialogContext";
18
- var D = {
17
+ var k = E.createContext(null);
18
+ k.displayName = "DialogContext";
19
+ var A = {
19
20
  open: !1,
20
21
  requestOpen: () => {},
21
22
  modalType: "modal",
22
- trigger: d,
23
+ trigger: m,
23
24
  finalFocusRef: void 0,
24
25
  contentId: void 0,
25
26
  registerContentId: () => () => {}
26
27
  };
27
- function O(e) {
28
- return b(E, e, "Dialog", () => D);
28
+ function j(e) {
29
+ return C(k, e, "Dialog", () => A);
29
30
  }
30
- var k = ({ open: e, defaultOpen: t, onOpenChange: n, modalType: r = "modal", finalFocusRef: i, children: o }) => {
31
- let [s, c] = h(e, t, n), l = a(), u = s && l, d = _();
32
- y(d, u);
33
- let [f, p] = C.useState(void 0), m = C.useCallback((e) => (p(e), () => p((t) => t === e ? void 0 : t)), []), g = C.useMemo(() => ({
31
+ var M = ({ open: e, defaultOpen: t, onOpenChange: n, modalType: r = "modal", finalFocusRef: i, children: a }) => {
32
+ let [o, s] = v(e, t, n), l = c(), u = o && l, d = b();
33
+ S(d, u);
34
+ let [f, p] = E.useState(void 0), m = E.useCallback((e) => (p(e), () => p((t) => t === e ? void 0 : t)), []), h = E.useMemo(() => ({
34
35
  open: u,
35
- requestOpen: c,
36
+ requestOpen: s,
36
37
  modalType: r,
37
38
  trigger: d,
38
39
  finalFocusRef: i,
@@ -40,93 +41,93 @@ var k = ({ open: e, defaultOpen: t, onOpenChange: n, modalType: r = "modal", fin
40
41
  registerContentId: m
41
42
  }), [
42
43
  u,
43
- c,
44
+ s,
44
45
  r,
45
46
  d,
46
47
  i,
47
48
  f,
48
49
  m
49
50
  ]);
50
- return /* @__PURE__ */ w(E.Provider, {
51
- value: g,
52
- children: o
51
+ return /* @__PURE__ */ D(k.Provider, {
52
+ value: h,
53
+ children: a
53
54
  });
54
55
  };
55
- k.displayName = "Dialog";
56
- var A = (e) => {
57
- let { open: t, requestOpen: n, trigger: r, contentId: i } = O("Dialog.Trigger");
58
- return v({
56
+ M.displayName = "Dialog";
57
+ var N = (e) => {
58
+ let { open: t, requestOpen: n, trigger: r, contentId: i } = j("Dialog.Trigger");
59
+ return x({
59
60
  open: t,
60
61
  requestOpen: n,
61
62
  trigger: r,
62
63
  controlsId: i
63
64
  }, e, "Dialog.Trigger");
64
65
  };
65
- A.displayName = "DialogTrigger";
66
- var j = (e) => {
67
- let { requestOpen: t } = O("Dialog.Close");
68
- return p(t, e, "Dialog.Close");
66
+ N.displayName = "DialogTrigger";
67
+ var P = (e) => {
68
+ let { requestOpen: t } = j("Dialog.Close");
69
+ return g(t, e, "Dialog.Close");
69
70
  };
70
- j.displayName = "DialogClose";
71
- var M = {
71
+ P.displayName = "DialogClose";
72
+ var F = {
72
73
  small: "max-w-[400px]",
73
74
  medium: "max-w-[600px]"
74
- }, N = ({ title: t, size: a = "medium", closeLabel: d = "Close", children: p, className: h, id: g, ref: _, ...v }) => {
75
- let { open: y, requestOpen: b, modalType: E, trigger: D, finalFocusRef: k, registerContentId: A } = O("Dialog.Content"), j = r("wave-dialog"), N = g ?? j, P = r("wave-dialog-title"), F = x(), [I, L] = C.useState(null), R = C.useRef(null), z = C.useCallback((e) => {
76
- R.current = e, L(e);
77
- }, []), B = C.useCallback((e) => e ? A(N) : void 0, [A, N]), V = i(_, z, B), H = E !== "alert", U = f(R, H), W = m(b, "Dialog", U.afterOutsidePress), G = l({
78
- open: y,
79
- onDismiss: W,
80
- refs: [R],
81
- outsidePress: H,
82
- container: I,
83
- triggerRef: D.focusRef,
84
- finalFocusRef: k
75
+ }, I = ({ title: t, size: i = "medium", closeLabel: c = "Close", children: m, className: g, id: v, ref: y, ...b }) => {
76
+ let { open: x, requestOpen: S, modalType: C, trigger: k, finalFocusRef: A, registerContentId: M } = j("Dialog.Content"), N = o("wave-dialog"), P = v ?? N, I = o("wave-dialog-title"), L = w(), [R, z] = E.useState(null), B = E.useRef(null), V = E.useCallback((e) => {
77
+ B.current = e, z(e);
78
+ }, []), H = E.useCallback((e) => e ? M(P) : void 0, [M, P]), U = s(y, V, H), W = C !== "alert", G = h(B, W), K = _(S, "Dialog", G.afterOutsidePress), q = f({
79
+ open: x,
80
+ onDismiss: K,
81
+ refs: [B],
82
+ outsidePress: W,
83
+ container: R,
84
+ triggerRef: k.focusRef,
85
+ finalFocusRef: A
85
86
  });
86
- S(y ? I : null, F.hasTitle, "Dialog.Content", "Dialog.Title");
87
- let [K, q] = C.useState(null), J = C.useMemo(() => ({
88
- ...F.context,
89
- setFooterHeight: q
90
- }), [F.context]);
91
- if (!y) return null;
92
- let Y = n(t);
93
- return /* @__PURE__ */ w(o, {
94
- layerId: G.layerId,
95
- children: /* @__PURE__ */ w("div", {
96
- className: "fixed inset-0 flex items-center justify-center bg-backdrop p-4",
97
- onMouseDown: U.onMouseDown,
98
- children: /* @__PURE__ */ w("div", {
99
- ref: V,
100
- role: E === "alert" ? "alertdialog" : "dialog",
101
- id: N,
102
- "aria-labelledby": Y ? P : F.titleId,
87
+ T(x ? R : null, L.hasTitle, "Dialog.Content", "Dialog.Title");
88
+ let [J, Y] = E.useState(null), X = E.useMemo(() => ({
89
+ ...L.context,
90
+ setFooterHeight: Y
91
+ }), [L.context]);
92
+ if (!x) return null;
93
+ let Z = n(t);
94
+ return /* @__PURE__ */ D(l, {
95
+ layerId: q.layerId,
96
+ children: /* @__PURE__ */ D("div", {
97
+ className: e(r.backdrop, "fixed inset-0 flex items-center justify-center bg-backdrop"),
98
+ onMouseDown: G.onMouseDown,
99
+ children: /* @__PURE__ */ D("div", {
100
+ ref: U,
101
+ role: C === "alert" ? "alertdialog" : "dialog",
102
+ id: P,
103
+ "aria-labelledby": Z ? I : L.titleId,
103
104
  tabIndex: -1,
104
- "data-modal-type": E,
105
- ...v,
106
- className: e("relative flex max-h-[calc(100dvh-2rem)] w-full flex-col rounded-lg border border-border bg-background p-6 text-foreground shadow-64", M[a], h),
107
- children: /* @__PURE__ */ T(u.Provider, {
108
- value: J,
105
+ "data-modal-type": C,
106
+ ...b,
107
+ className: e(r.root, "relative m-4 flex min-w-0 max-h-[calc(100dvh-2rem)] w-full flex-col rounded-lg border border-border bg-background p-6 text-foreground shadow-64", F[i], g),
108
+ children: /* @__PURE__ */ O(p.Provider, {
109
+ value: X,
109
110
  children: [
110
- Y && /* @__PURE__ */ w("h2", {
111
- id: P,
112
- className: "pe-8 text-subtitle-1 font-semibold",
111
+ Z && /* @__PURE__ */ D("h2", {
112
+ id: I,
113
+ className: e(a.root, "pe-8 text-subtitle-1 font-semibold"),
113
114
  children: t
114
115
  }),
115
- /* @__PURE__ */ w(s, {
116
+ /* @__PURE__ */ D(u, {
116
117
  appearance: "subtle",
117
118
  size: "small",
118
- icon: /* @__PURE__ */ w(c, {}),
119
- "aria-label": d,
120
- onClick: (e) => b(!1, {
119
+ icon: /* @__PURE__ */ D(d, {}),
120
+ "aria-label": c,
121
+ onClick: (e) => S(!1, {
121
122
  reason: "close-button",
122
123
  event: e.nativeEvent
123
124
  }),
124
- className: "absolute end-4 top-4 text-muted-foreground"
125
+ className: e(r.closeButton, "absolute end-4 top-4 text-muted-foreground")
125
126
  }),
126
- /* @__PURE__ */ w("div", {
127
- className: "-mx-1 mt-1 min-h-0 flex-1 overflow-y-auto scroll-pb-(--wave-dialog-footer-height) p-1 text-body-1 text-muted-foreground",
128
- style: K === null ? void 0 : { "--wave-dialog-footer-height": `${K}px` },
129
- children: p
127
+ /* @__PURE__ */ D("div", {
128
+ className: e(r.body, "-mx-1 mt-1 min-h-0 flex-1 overflow-y-auto scroll-pb-(--wave-dialog-footer-height) p-1 text-body-1"),
129
+ style: J === null ? void 0 : { "--wave-dialog-footer-height": `${J}px` },
130
+ children: m
130
131
  })
131
132
  ]
132
133
  })
@@ -134,47 +135,47 @@ var M = {
134
135
  })
135
136
  });
136
137
  };
137
- N.displayName = "DialogContent";
138
- var P = ({ id: t, className: n, children: r, ref: i, ...a }) => {
139
- let { id: o, ref: s } = g("Dialog.Title", "Dialog.Content", t, i);
140
- return /* @__PURE__ */ w("h2", {
141
- ...a,
142
- id: o,
143
- ref: s,
144
- className: e("pe-8 text-subtitle-1 font-semibold text-foreground", n),
138
+ I.displayName = "DialogContent";
139
+ var L = ({ id: t, className: n, children: r, ref: i, ...o }) => {
140
+ let { id: s, ref: c } = y("Dialog.Title", "Dialog.Content", t, i);
141
+ return /* @__PURE__ */ D("h2", {
142
+ ...o,
143
+ id: s,
144
+ ref: c,
145
+ className: e(a.root, "pe-8 text-subtitle-1 font-semibold text-foreground", n),
145
146
  children: r
146
147
  });
147
148
  };
148
- P.displayName = "DialogTitle";
149
- var F = "sticky -bottom-1 z-10 -mx-1 -mb-1 mt-6 flex justify-end gap-2 bg-background px-1 pb-2 pt-3", I = "mt-6 flex justify-end gap-2", L = ({ children: n, className: r, ref: a, ...o }) => {
150
- let s = C.useContext(u), c = s === null, l = s?.setFooterHeight, [d, f] = C.useState(null), p = i(a, f);
151
- return C.useEffect(() => {
152
- c && t("Dialog.Footer:outside-content", "Dialog.Footer must be rendered inside Dialog.Content. Outside it, the footer stays on the page while the dialog is closed.");
153
- }, [c]), C.useLayoutEffect(() => {
154
- if (!d || !l || typeof ResizeObserver > "u") return;
149
+ L.displayName = "DialogTitle";
150
+ var R = "sticky -bottom-1 z-10 -mx-1 -mb-1 mt-6 flex justify-end gap-2 bg-background px-1 pb-2 pt-3", z = "mt-6 flex justify-end gap-2", B = ({ children: n, className: r, ref: a, ...o }) => {
151
+ let c = E.useContext(p), l = c === null, u = c?.setFooterHeight, [d, f] = E.useState(null), m = s(a, f);
152
+ return E.useEffect(() => {
153
+ l && t("Dialog.Footer:outside-content", "Dialog.Footer must be rendered inside Dialog.Content. Outside it, the footer stays on the page while the dialog is closed.");
154
+ }, [l]), E.useLayoutEffect(() => {
155
+ if (!d || !u || typeof ResizeObserver > "u") return;
155
156
  let e = new ResizeObserver((e) => {
156
157
  let t = e[e.length - 1];
157
- t && l(t.borderBoxSize?.[0]?.blockSize ?? d.offsetHeight);
158
+ t && u(t.borderBoxSize?.[0]?.blockSize ?? d.offsetHeight);
158
159
  });
159
160
  return e.observe(d, { box: "border-box" }), () => {
160
- e.disconnect(), l(null);
161
+ e.disconnect(), u(null);
161
162
  };
162
- }, [d, l]), /* @__PURE__ */ w("div", {
163
- ref: p,
163
+ }, [d, u]), /* @__PURE__ */ D("div", {
164
+ ref: m,
164
165
  ...o,
165
- className: e(l ? F : I, r),
166
+ className: e(i.root, u ? R : z, r),
166
167
  children: n
167
168
  });
168
169
  };
169
- L.displayName = "DialogFooter";
170
- var R = /* @__PURE__ */ Object.assign(k, {
171
- Trigger: A,
172
- Content: N,
173
- Footer: L,
174
- Title: P,
175
- Close: j
170
+ B.displayName = "DialogFooter";
171
+ var V = /* @__PURE__ */ Object.assign(M, {
172
+ Trigger: N,
173
+ Content: I,
174
+ Footer: B,
175
+ Title: L,
176
+ Close: P
176
177
  });
177
178
  //#endregion
178
- export { R as Dialog, j as DialogClose, N as DialogContent, L as DialogFooter, P as DialogTitle, A as DialogTrigger };
179
+ export { V as Dialog, P as DialogClose, I as DialogContent, B as DialogFooter, L as DialogTitle, N as DialogTrigger };
179
180
 
180
181
  //# sourceMappingURL=Dialog.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.mjs","names":["useId","useId$1","React","DialogContext","inertDialogContext","inertModalTrigger","useDialogContext","useRequiredContext","componentName","DialogRoot","openState","requestOpen","useModalOpenState","open","defaultOpen","onOpenChange","isClient","useIsClient","isOpen","trigger","useModalTrigger","contentId","setContentId","registerContentId","id","current","context","modalType","finalFocusRef","DialogTrigger","useModalTriggerPart","props","DialogClose","useModalClosePart","sizeClasses","DialogContent","rest","generatedId","propTitleId","titles","useTitleRegistry","surface","setSurface","surfaceRef","attachSurface","node","registerId","mergedRef","useMergedRefs","ref","closesOnBackdropPress","backdropPress","useBackdropPress","onDismiss","useModalDismiss","layer","useModalLayer","footerHeight","setFooterHeight","surfaceContext","hasTitle","slotRendersContent","title","Portal","cn","size","className","ModalSurfaceContext","Button","DismissIcon","closeLabel","event","DialogTitle","titleId","titleRef","useModalTitle","stickyFooterClasses","footerRowClasses","DialogFooter","outsideContent","footer","setFooter","warnOnce","observer","entry","entries","Dialog"],"sources":["../../../src/components/overlays/Dialog.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport { warnOnce } from '../../lib/dev';\nimport { DismissIcon } from '../../lib/icons';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { ModalOpenChangeReason, ModalType, OpenChangeDetails } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useModalLayer } from '../../hooks/useModalLayer';\nimport { Button } from '../button/Button';\nimport { Portal } from '../portal/Portal';\nimport {\n inertModalTrigger,\n ModalSurfaceContext,\n useBackdropPress,\n useModalClosePart,\n useModalDismiss,\n useModalOpenState,\n useModalTitle,\n useModalTrigger,\n useModalTriggerPart,\n useModalTriggerSession,\n useRequiredContext,\n useTitleRegistry,\n useUnnamedModalWarning,\n type ModalRequestOpen,\n type ModalSurfaceContextValue,\n type ModalTrigger,\n} from './Dialog.shared';\n\n/**\n * Why a {@link Dialog} asks to open or close: `trigger` (`Dialog.Trigger`), `close`\n * (`Dialog.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`.\n */\nexport type DialogOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a {@link Dialog}'s `onOpenChange`: the reason and the DOM event. */\nexport type DialogOpenChangeDetails = OpenChangeDetails<DialogOpenChangeReason>;\n\n/**\n * How a {@link Dialog} blocks the page (the shared `ModalType`; Drawer reuses it when it gains\n * `modalType`).\n */\nexport type DialogModalType = ModalType;\n\n/** Properties for the Dialog component. */\nexport interface DialogProps {\n /**\n * Controlled open state of the dialog. The surface renders only in the browser: an open dialog\n * is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Default open state for uncontrolled usage. The surface renders only in the browser: a dialog\n * open by default is closed in the server HTML and opens once it has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the new open state when it changes. `details.reason` tells how — `trigger`,\n * `close` (a `.Close` part), `close-button` (the built-in Close button), `escape` or\n * `outside-press` (the backdrop) — so a controlled dialog can refuse only some ways of closing\n * (for example keep a form with unsaved changes open on `outside-press`); `details.event` is the\n * DOM event behind the request. WaveUI always passes `details`; it is typed optional until 1.0\n * so that code which calls this prop itself keeps compiling.\n *\n * Fires only when the value changes; a controlled dialog stays as it is until the parent updates\n * `open`.\n */\n onOpenChange?: (open: boolean, details?: DialogOpenChangeDetails) => void;\n /**\n * `modal`: a backdrop press, Escape, the Close button and `Dialog.Close` close it. `alert`: a\n * confirmation that needs an answer — `role=\"alertdialog\"`, and a backdrop press does not close\n * it (Escape still does). Initial focus goes to the first focusable element, the built-in Close\n * button; give the least destructive action `autoFocus` to focus it instead. (`'non-modal'` is\n * planned.)\n * @default 'modal'\n */\n modalType?: DialogModalType;\n /**\n * Where focus goes when the dialog closes, if it can take focus. Otherwise focus returns to the\n * element that had focus when the dialog opened, then to the trigger, then to an element next to\n * where that opener was (the next row's action after a confirm dialog deleted the row). Use it to\n * send focus somewhere else.\n */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /** `Dialog.Trigger` and `Dialog.Content`. */\n children: React.ReactNode;\n}\n\n/** Properties for the DialogContent sub-component. */\nexport interface DialogContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /**\n * Title rendered as the dialog's heading; it names the dialog (`aria-labelledby`). Without it,\n * render a `Dialog.Title` or pass `aria-label`/`aria-labelledby`. A title that renders nothing\n * (`''`, `[]`, `true`) counts as none.\n */\n title?: React.ReactNode;\n /** Maximum width of the dialog: 400px (`small`) or 600px (`medium`); it never exceeds the viewport.\n * @default 'medium'\n */\n size?: 'small' | 'medium';\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /** Content rendered inside the dialog body (put `Dialog.Footer` here as well). */\n children: React.ReactNode;\n /** Ref to the dialog surface (`role=\"dialog\"`, or `alertdialog` with `modalType=\"alert\"`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogFooter sub-component. */\nexport interface DialogFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content, typically action buttons (wrap closing buttons in `Dialog.Close`). */\n children: React.ReactNode;\n /** Ref to the footer element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogTitle sub-component. */\nexport interface DialogTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /** The title; any content. */\n children: React.ReactNode;\n /** Ref to the heading element. */\n ref?: React.Ref<HTMLHeadingElement>;\n}\n\n/** Props a `Dialog.Trigger` puts on its element (and passes to a render-prop child). */\nexport interface DialogTriggerRenderProps extends React.HTMLAttributes<HTMLElement> {\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The dialog surface's id, while the dialog is open. */\n 'aria-controls'?: string;\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogTrigger sub-component. */\nexport interface DialogTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that opens the dialog. A single element receives the trigger props (merged with\n * its own: handlers composed, classes joined, its own `id` kept); a function receives them.\n */\n children: React.ReactNode | ((props: DialogTriggerRenderProps) => React.ReactNode);\n /**\n * `false` renders the 0.4 wrapper `<span>` around the children instead of merging the trigger\n * props onto the child. The span carries the click handler; `aria-haspopup`, `aria-expanded`\n * and `aria-controls` go to the first element in the tab order inside it.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Props a `Dialog.Close` puts on its element (and passes to a render-prop child). */\nexport interface DialogCloseRenderProps extends React.HTMLAttributes<HTMLElement> {\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogClose sub-component. */\nexport interface DialogCloseProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that closes the dialog, typically a footer button. A single element receives an\n * `onClick` composed with its own (its handler runs first; `preventDefault()` keeps the dialog\n * open); a function receives the props.\n */\n children: React.ReactNode | ((props: DialogCloseRenderProps) => React.ReactNode);\n /** `false` renders a wrapper `<span>` that closes the dialog on click. @default true */\n asChild?: boolean;\n /** Ref to the close element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\ninterface DialogContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The resolved `modalType`. */\n modalType: DialogModalType;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n finalFocusRef: React.RefObject<HTMLElement | null> | undefined;\n /** The id of the open dialog surface (for the trigger's `aria-controls`), or `undefined`. */\n contentId: string | undefined;\n /** Registers the surface's id while it is mounted; returns the unregister function. */\n registerContentId: (id: string) => () => void;\n}\n\nconst DialogContext = React.createContext<DialogContextValue | null>(null);\nDialogContext.displayName = 'DialogContext';\n\nconst inertDialogContext: DialogContextValue = {\n open: false,\n requestOpen: () => {},\n modalType: 'modal',\n trigger: inertModalTrigger,\n finalFocusRef: undefined,\n contentId: undefined,\n registerContentId: () => () => {},\n};\n\nfunction useDialogContext(componentName: string): DialogContextValue {\n return useRequiredContext(DialogContext, componentName, 'Dialog', () => inertDialogContext);\n}\n\n// The root of `Dialog` (documented on the export below). A const arrow (like DrawerRoot): its type\n// can be named in consumers' declaration files, e.g. a story's `satisfies Meta<typeof Dialog>` (a\n// function declaration's `typeof` cannot, TS4023).\nconst DialogRoot = ({\n open,\n defaultOpen,\n onOpenChange,\n modalType = 'modal',\n finalFocusRef,\n children,\n}: DialogProps) => {\n const [openState, requestOpen] = useModalOpenState(open, defaultOpen, onOpenChange);\n // The surface lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the dialog reports itself closed, so the trigger's aria-expanded never\n // describes a dialog that is not there.\n const isClient = useIsClient();\n const isOpen = openState && isClient;\n const trigger = useModalTrigger();\n // After Dialog.Content's focus restore (a child's layout effects run first), start the trigger\n // session, or end it and forget the trigger that opened it.\n useModalTriggerSession(trigger, isOpen);\n const [contentId, setContentId] = React.useState<string | undefined>(undefined);\n const registerContentId = React.useCallback((id: string) => {\n setContentId(id);\n return () => setContentId((current) => (current === id ? undefined : current));\n }, []);\n\n const context = React.useMemo<DialogContextValue>(\n () => ({\n open: isOpen,\n requestOpen,\n modalType,\n trigger,\n finalFocusRef,\n contentId,\n registerContentId,\n }),\n [isOpen, requestOpen, modalType, trigger, finalFocusRef, contentId, registerContentId],\n );\n\n return <DialogContext.Provider value={context}>{children}</DialogContext.Provider>;\n};\nDialogRoot.displayName = 'Dialog';\n\n/**\n * Opens the dialog. Puts `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), a\n * click handler and a ref on its single child (no wrapper element), or passes them to a\n * render-prop child. A custom child component must forward `ref` and spread its props; one that\n * does not is wrapped in a `<span>` automatically (with a development warning), the span that\n * `asChild={false}` renders. Focus returns to the trigger when the dialog closes (with several\n * triggers, to the one that opened it). On the span, the state ARIA goes to the first element in\n * the tab order inside it, and focus returns to that element (to the span when you made it the\n * trigger with a `role` such as `button` and `tabIndex={0}`, or when nothing inside it can take\n * focus).\n */\nexport const DialogTrigger = (props: DialogTriggerProps) => {\n const { open, requestOpen, trigger, contentId } = useDialogContext('Dialog.Trigger');\n return useModalTriggerPart<DialogTriggerRenderProps>(\n { open, requestOpen, trigger, controlsId: contentId },\n props,\n 'Dialog.Trigger',\n );\n};\nDialogTrigger.displayName = 'DialogTrigger';\n\n/**\n * Closes the dialog: composes a click handler onto its single child (its own `onClick` runs first;\n * calling `preventDefault()` there keeps the dialog open), or passes it to a render-prop child.\n *\n * @example\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n */\nexport const DialogClose = (props: DialogCloseProps) => {\n const { requestOpen } = useDialogContext('Dialog.Close');\n return useModalClosePart<DialogCloseRenderProps>(requestOpen, props, 'Dialog.Close');\n};\nDialogClose.displayName = 'DialogClose';\n\nconst sizeClasses: Record<'small' | 'medium', string> = {\n small: 'max-w-[400px]',\n medium: 'max-w-[600px]',\n};\n\n/**\n * The dialog surface, rendered in a portal (inheriting the WaveProvider theme) while the dialog is\n * open: backdrop, title, Close button and a scrolling body. It takes the full width up to its\n * `size` and never exceeds the viewport (the body scrolls). It is `role=\"dialog\"`, or\n * `role=\"alertdialog\"` when the Dialog has `modalType=\"alert\"` (a `role` you pass wins), and\n * carries `data-modal-type` with the resolved type.\n */\nexport const DialogContent = ({\n title,\n size = 'medium',\n closeLabel = 'Close',\n children,\n className,\n id,\n ref,\n ...rest\n}: DialogContentProps) => {\n const { open, requestOpen, modalType, trigger, finalFocusRef, registerContentId } =\n useDialogContext('Dialog.Content');\n const generatedId = useId('wave-dialog');\n const contentId = id ?? generatedId;\n const propTitleId = useId('wave-dialog-title');\n const titles = useTitleRegistry();\n\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const attachSurface = React.useCallback((node: HTMLDivElement | null) => {\n surfaceRef.current = node;\n setSurface(node);\n }, []);\n // Reports the surface's id to the root (the trigger's `aria-controls`) while it is mounted. A new\n // `id` makes a new callback, which useMergedRefs re-attaches after the commit (re-registering).\n const registerId = React.useCallback(\n (node: HTMLDivElement | null) => (node ? registerContentId(contentId) : undefined),\n [registerContentId, contentId],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, attachSurface, registerId);\n\n // An alert dialog needs an answer: a backdrop press does not close it (Escape still does).\n const closesOnBackdropPress = modalType !== 'alert';\n const backdropPress = useBackdropPress(surfaceRef, closesOnBackdropPress);\n const onDismiss = useModalDismiss(requestOpen, 'Dialog', backdropPress.afterOutsidePress);\n const layer = useModalLayer({\n open,\n onDismiss,\n refs: [surfaceRef],\n outsidePress: closesOnBackdropPress,\n container: surface,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n useUnnamedModalWarning(open ? surface : null, titles.hasTitle, 'Dialog.Content', 'Dialog.Title');\n\n // The height of the sticky Dialog.Footer, reserved as the body's scroll padding.\n const [footerHeight, setFooterHeight] = React.useState<number | null>(null);\n const surfaceContext = React.useMemo<ModalSurfaceContextValue>(\n () => ({ ...titles.context, setFooterHeight }),\n [titles.context],\n );\n\n if (!open) return null;\n\n const hasTitle = slotRendersContent(title);\n\n return (\n <Portal layerId={layer.layerId}>\n <div\n className=\"fixed inset-0 flex items-center justify-center bg-backdrop p-4\"\n onMouseDown={backdropPress.onMouseDown}\n >\n <div\n ref={mergedRef}\n role={modalType === 'alert' ? 'alertdialog' : 'dialog'}\n id={contentId}\n aria-labelledby={hasTitle ? propTitleId : titles.titleId}\n tabIndex={-1}\n data-modal-type={modalType}\n {...rest}\n className={cn(\n // The border marks the surface where the shadow cannot: in high contrast the page,\n // the backdrop and the surface are black, and forced colors drop shadows.\n 'relative flex max-h-[calc(100dvh-2rem)] w-full flex-col rounded-lg border border-border bg-background p-6 text-foreground shadow-64',\n sizeClasses[size],\n className,\n )}\n >\n <ModalSurfaceContext.Provider value={surfaceContext}>\n {hasTitle && (\n <h2 id={propTitleId} className=\"pe-8 text-subtitle-1 font-semibold\">\n {title}\n </h2>\n )}\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<DismissIcon />}\n aria-label={closeLabel}\n onClick={(event) =>\n requestOpen(false, { reason: 'close-button', event: event.nativeEvent })\n }\n className=\"absolute end-4 top-4 text-muted-foreground\"\n />\n <div\n // The scroll padding keeps a focused field above the sticky footer (WCAG 2.4.11).\n className=\"-mx-1 mt-1 min-h-0 flex-1 overflow-y-auto scroll-pb-(--wave-dialog-footer-height) p-1 text-body-1 text-muted-foreground\"\n style={\n footerHeight === null\n ? undefined\n : ({ '--wave-dialog-footer-height': `${footerHeight}px` } as React.CSSProperties)\n }\n >\n {children}\n </div>\n </ModalSurfaceContext.Provider>\n </div>\n </div>\n </Portal>\n );\n};\nDialogContent.displayName = 'DialogContent';\n\n/**\n * A heading that names the dialog (`aria-labelledby`), for rich titles or custom layouts. Render it\n * inside `Dialog.Content` (instead of the `title` prop). Like the `title` heading it reserves end\n * padding (`pe-8`) so a long first line stays clear of the Close button; a `className` padding wins.\n */\nexport const DialogTitle = ({ id, className, children, ref, ...rest }: DialogTitleProps) => {\n const { id: titleId, ref: titleRef } = useModalTitle('Dialog.Title', 'Dialog.Content', id, ref);\n return (\n <h2\n {...rest}\n id={titleId}\n ref={titleRef}\n className={cn('pe-8 text-subtitle-1 font-semibold text-foreground', className)}\n >\n {children}\n </h2>\n );\n};\nDialogTitle.displayName = 'DialogTitle';\n\n/**\n * `Dialog.Footer` inside `Dialog.Content`. The body is `p-1`, and sticky positioning stops at its\n * padding edge: `-bottom-1` with `-mb-1 pb-2` covers the body's bottom padding, `-mx-1 px-1` its\n * focus-ring inset, and `pt-3` separates the actions from the content scrolling under them.\n */\nconst stickyFooterClasses =\n 'sticky -bottom-1 z-10 -mx-1 -mb-1 mt-6 flex justify-end gap-2 bg-background px-1 pb-2 pt-3';\n\n/**\n * `Dialog.Footer` where no body reserves its height as scroll padding (a Drawer's body): a plain\n * action row, which never covers a focused field.\n */\nconst footerRowClasses = 'mt-6 flex justify-end gap-2';\n\n/**\n * Action row at the end of the dialog body. It stays where you render it in the DOM and sticks to\n * the bottom of the body while long content scrolls under it (with an opaque background); the body\n * reserves its height as scroll padding, so a focused field is never hidden behind it. Inside a\n * `<form>` that wraps the fields and the footer it sticks too: make it the form's last child.\n * Render it inside `Dialog.Content`: outside it, it would stay on the page while the dialog is\n * closed (a development warning says so). Inside a `Drawer`, whose body reserves no footer height,\n * it does not stick: it is an action row at the end of the content. Render one `Dialog.Footer` per\n * `Dialog.Content`: with two at once, the body reserves the height of the one measured last, and\n * unmounting either clears it until the other resizes (swapping one footer for another is fine).\n */\nexport const DialogFooter = ({ children, className, ref, ...rest }: DialogFooterProps) => {\n const surfaceContext = React.useContext(ModalSurfaceContext);\n const outsideContent = surfaceContext === null;\n const setFooterHeight = surfaceContext?.setFooterHeight;\n const [footer, setFooter] = React.useState<HTMLDivElement | null>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, setFooter);\n\n React.useEffect(() => {\n if (!outsideContent) return;\n warnOnce(\n 'Dialog.Footer:outside-content',\n 'Dialog.Footer must be rendered inside Dialog.Content. Outside it, the footer stays on the page while the dialog is closed.',\n );\n }, [outsideContent]);\n\n // Reports the footer's border-box height to Dialog.Content. The observer's first callback,\n // delivered before the next paint, supplies the first value; without ResizeObserver the body\n // keeps its default scroll padding.\n React.useLayoutEffect(() => {\n if (!footer || !setFooterHeight || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[entries.length - 1];\n if (!entry) return;\n setFooterHeight(entry.borderBoxSize?.[0]?.blockSize ?? footer.offsetHeight);\n });\n observer.observe(footer, { box: 'border-box' });\n return () => {\n observer.disconnect();\n setFooterHeight(null);\n };\n }, [footer, setFooterHeight]);\n\n return (\n <div\n ref={mergedRef}\n {...rest}\n // Sticky only where the surface reserves the footer's height (Dialog.Content).\n className={cn(setFooterHeight ? stickyFooterClasses : footerRowClasses, className)}\n >\n {children}\n </div>\n );\n};\nDialogFooter.displayName = 'DialogFooter';\n\n/**\n * A modal dialog (Fluent UI v2 style): `Dialog` holds the open state; `Dialog.Trigger` opens it and\n * `Dialog.Content` renders the surface in a portal while open.\n *\n * - **Modal**: focus moves into the dialog and Tab stays inside it (toasts included), the rest of\n * the page is `inert` (instead of `aria-modal`, so toasts and live regions stay announced), and\n * the page does not scroll.\n * - **Closing**: Escape (only the topmost layer: a popup opened inside closes first), a click on\n * the backdrop (a drag that starts inside does not close it), the Close button and `Dialog.Close`.\n * `onOpenChange` gets the reason as its second argument (`details.reason`), so a controlled\n * dialog can refuse some of them. A backdrop press blurs the focused field before the dialog\n * closes, so a typed value is committed as with the Close button; when a controlled dialog\n * refuses the press, the field gets focus back (an alert dialog's press leaves focus where it\n * was). Focus returns to the first of these that can take focus: `finalFocusRef`, the element\n * that had focus when the dialog opened, the trigger, an element next to where that opener was.\n * - **Alert dialogs**: `modalType=\"alert\"` renders `role=\"alertdialog\"` for a confirmation that\n * needs an answer; a backdrop press does not close it.\n * - **Footer**: `Dialog.Footer` sticks to the bottom of the scrolling body, and the body keeps a\n * focused field above it.\n * - **Naming**: give `Dialog.Content` a `title`, a `Dialog.Title`, or `aria-label`.\n *\n * The sub-components are also exported under flat names (`DialogTrigger`, `DialogContent`,\n * `DialogFooter`, `DialogTitle`, `DialogClose`) for React Server Components, which cannot use the\n * dotted form; dotted access (`Dialog.Content`) needs a client file.\n *\n * @example\n * <Dialog>\n * <Dialog.Trigger><Button>Delete</Button></Dialog.Trigger>\n * <Dialog.Content title=\"Delete file?\">\n * This cannot be undone.\n * <Dialog.Footer>\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n * <Button appearance=\"primary\" onClick={remove}>Delete</Button>\n * </Dialog.Footer>\n * </Dialog.Content>\n * </Dialog>\n */\nexport const Dialog = /* @__PURE__ */ Object.assign(DialogRoot, {\n Trigger: DialogTrigger,\n Content: DialogContent,\n Footer: DialogFooter,\n Title: DialogTitle,\n Close: DialogClose,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Dialog.mjs","names":["useId","useId$1","React","DialogContext","inertDialogContext","inertModalTrigger","useDialogContext","useRequiredContext","componentName","DialogRoot","openState","requestOpen","useModalOpenState","open","defaultOpen","onOpenChange","isClient","useIsClient","isOpen","trigger","useModalTrigger","contentId","setContentId","registerContentId","id","current","context","modalType","finalFocusRef","DialogTrigger","useModalTriggerPart","props","DialogClose","useModalClosePart","sizeClasses","DialogContent","rest","generatedId","propTitleId","titles","useTitleRegistry","surface","setSurface","surfaceRef","attachSurface","node","registerId","mergedRef","useMergedRefs","ref","closesOnBackdropPress","backdropPress","useBackdropPress","onDismiss","useModalDismiss","layer","useModalLayer","footerHeight","setFooterHeight","surfaceContext","hasTitle","slotRendersContent","title","Portal","cn","dialogContentClassNames","size","className","ModalSurfaceContext","dialogTitleClassNames","Button","DismissIcon","closeLabel","event","DialogTitle","titleId","titleRef","useModalTitle","stickyFooterClasses","footerRowClasses","DialogFooter","outsideContent","footer","setFooter","warnOnce","observer","entry","entries","dialogFooterClassNames","Dialog"],"sources":["../../../src/components/overlays/Dialog.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../lib/cn';\nimport {\n dialogContentClassNames,\n dialogFooterClassNames,\n dialogTitleClassNames,\n} from '../../lib/classNames';\nimport { warnOnce } from '../../lib/dev';\nimport { DismissIcon } from '../../lib/icons';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { ModalOpenChangeReason, ModalType, OpenChangeDetails } from '../../lib/types';\nimport { useId } from '../../hooks/useId';\nimport { useIsClient } from '../../hooks/useIsClient';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { useModalLayer } from '../../hooks/useModalLayer';\nimport { Button } from '../button/Button';\nimport { Portal } from '../portal/Portal';\nimport {\n inertModalTrigger,\n ModalSurfaceContext,\n useBackdropPress,\n useModalClosePart,\n useModalDismiss,\n useModalOpenState,\n useModalTitle,\n useModalTrigger,\n useModalTriggerPart,\n useModalTriggerSession,\n useRequiredContext,\n useTitleRegistry,\n useUnnamedModalWarning,\n type ModalRequestOpen,\n type ModalSurfaceContextValue,\n type ModalTrigger,\n} from './Dialog.shared';\n\n/**\n * Why a {@link Dialog} asks to open or close: `trigger` (`Dialog.Trigger`), `close`\n * (`Dialog.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`.\n */\nexport type DialogOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a {@link Dialog}'s `onOpenChange`: the reason and the DOM event. */\nexport type DialogOpenChangeDetails = OpenChangeDetails<DialogOpenChangeReason>;\n\n/**\n * How a {@link Dialog} blocks the page (the shared `ModalType`; Drawer reuses it when it gains\n * `modalType`).\n */\nexport type DialogModalType = ModalType;\n\n/** Properties for the Dialog component. */\nexport interface DialogProps {\n /**\n * Controlled open state of the dialog. The surface renders only in the browser: an open dialog\n * is closed in the server HTML and opens once it has hydrated.\n */\n open?: boolean;\n /**\n * Default open state for uncontrolled usage. The surface renders only in the browser: a dialog\n * open by default is closed in the server HTML and opens once it has hydrated.\n * @default false\n */\n defaultOpen?: boolean;\n /**\n * Called with the new open state when it changes. `details.reason` tells how — `trigger`,\n * `close` (a `.Close` part), `close-button` (the built-in Close button), `escape` or\n * `outside-press` (the backdrop) — so a controlled dialog can refuse only some ways of closing\n * (for example keep a form with unsaved changes open on `outside-press`); `details.event` is the\n * DOM event behind the request. WaveUI always passes `details`; it is typed optional until 1.0\n * so that code which calls this prop itself keeps compiling.\n *\n * Fires only when the value changes; a controlled dialog stays as it is until the parent updates\n * `open`.\n */\n onOpenChange?: (open: boolean, details?: DialogOpenChangeDetails) => void;\n /**\n * `modal`: a backdrop press, Escape, the Close button and `Dialog.Close` close it. `alert`: a\n * confirmation that needs an answer — `role=\"alertdialog\"`, and a backdrop press does not close\n * it (Escape still does). Initial focus goes to the first focusable element, the built-in Close\n * button; give the least destructive action `autoFocus` to focus it instead. (`'non-modal'` is\n * planned.)\n * @default 'modal'\n */\n modalType?: DialogModalType;\n /**\n * Where focus goes when the dialog closes, if it can take focus. Otherwise focus returns to the\n * element that had focus when the dialog opened, then to the trigger, then to an element next to\n * where that opener was (the next row's action after a confirm dialog deleted the row). Use it to\n * send focus somewhere else.\n */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /** `Dialog.Trigger` and `Dialog.Content`. */\n children: React.ReactNode;\n}\n\n/** Properties for the DialogContent sub-component. */\nexport interface DialogContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /**\n * Title rendered as the dialog's heading; it names the dialog (`aria-labelledby`). Without it,\n * render a `Dialog.Title` or pass `aria-label`/`aria-labelledby`. A title that renders nothing\n * (`''`, `[]`, `true`) counts as none.\n */\n title?: React.ReactNode;\n /** Maximum width of the dialog: 400px (`small`) or 600px (`medium`); it never exceeds the viewport.\n * @default 'medium'\n */\n size?: 'small' | 'medium';\n /**\n * Accessible name of the built-in Close button (an icon-only button). Localize it with the\n * page's language.\n * @default 'Close'\n */\n closeLabel?: string;\n /** Content rendered inside the dialog body (put `Dialog.Footer` here as well). */\n children: React.ReactNode;\n /** Ref to the dialog surface (`role=\"dialog\"`, or `alertdialog` with `modalType=\"alert\"`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogFooter sub-component. */\nexport interface DialogFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Footer content, typically action buttons (wrap closing buttons in `Dialog.Close`). */\n children: React.ReactNode;\n /** Ref to the footer element. */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Properties for the DialogTitle sub-component. */\nexport interface DialogTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /** The title; any content. */\n children: React.ReactNode;\n /** Ref to the heading element. */\n ref?: React.Ref<HTMLHeadingElement>;\n}\n\n/** Props a `Dialog.Trigger` puts on its element (and passes to a render-prop child). */\nexport interface DialogTriggerRenderProps extends React.HTMLAttributes<HTMLElement> {\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The dialog surface's id, while the dialog is open. */\n 'aria-controls'?: string;\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogTrigger sub-component. */\nexport interface DialogTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that opens the dialog. A single element receives the trigger props (merged with\n * its own: handlers composed, classes joined, its own `id` kept); a function receives them.\n */\n children: React.ReactNode | ((props: DialogTriggerRenderProps) => React.ReactNode);\n /**\n * `false` renders the 0.4 wrapper `<span>` around the children instead of merging the trigger\n * props onto the child. The span carries the click handler; `aria-haspopup`, `aria-expanded`\n * and `aria-controls` go to the first element in the tab order inside it.\n * @default true\n */\n asChild?: boolean;\n /** Ref to the trigger element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\n/** Props a `Dialog.Close` puts on its element (and passes to a render-prop child). */\nexport interface DialogCloseRenderProps extends React.HTMLAttributes<HTMLElement> {\n onClick: React.MouseEventHandler<HTMLElement>;\n /** A callback ref, so the props spread onto any element type. */\n ref: React.RefCallback<HTMLElement>;\n}\n\n/** Properties for the DialogClose sub-component. */\nexport interface DialogCloseProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that closes the dialog, typically a footer button. A single element receives an\n * `onClick` composed with its own (its handler runs first; `preventDefault()` keeps the dialog\n * open); a function receives the props.\n */\n children: React.ReactNode | ((props: DialogCloseRenderProps) => React.ReactNode);\n /** `false` renders a wrapper `<span>` that closes the dialog on click. @default true */\n asChild?: boolean;\n /** Ref to the close element (the child, or the wrapper span). */\n ref?: React.Ref<HTMLElement>;\n}\n\ninterface DialogContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The resolved `modalType`. */\n modalType: DialogModalType;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n finalFocusRef: React.RefObject<HTMLElement | null> | undefined;\n /** The id of the open dialog surface (for the trigger's `aria-controls`), or `undefined`. */\n contentId: string | undefined;\n /** Registers the surface's id while it is mounted; returns the unregister function. */\n registerContentId: (id: string) => () => void;\n}\n\nconst DialogContext = React.createContext<DialogContextValue | null>(null);\nDialogContext.displayName = 'DialogContext';\n\nconst inertDialogContext: DialogContextValue = {\n open: false,\n requestOpen: () => {},\n modalType: 'modal',\n trigger: inertModalTrigger,\n finalFocusRef: undefined,\n contentId: undefined,\n registerContentId: () => () => {},\n};\n\nfunction useDialogContext(componentName: string): DialogContextValue {\n return useRequiredContext(DialogContext, componentName, 'Dialog', () => inertDialogContext);\n}\n\n// The root of `Dialog` (documented on the export below). A const arrow (like DrawerRoot): its type\n// can be named in consumers' declaration files, e.g. a story's `satisfies Meta<typeof Dialog>` (a\n// function declaration's `typeof` cannot, TS4023).\nconst DialogRoot = ({\n open,\n defaultOpen,\n onOpenChange,\n modalType = 'modal',\n finalFocusRef,\n children,\n}: DialogProps) => {\n const [openState, requestOpen] = useModalOpenState(open, defaultOpen, onOpenChange);\n // The surface lives in a portal, which renders only in the browser: until then (the server\n // HTML, hydration) the dialog reports itself closed, so the trigger's aria-expanded never\n // describes a dialog that is not there.\n const isClient = useIsClient();\n const isOpen = openState && isClient;\n const trigger = useModalTrigger();\n // After Dialog.Content's focus restore (a child's layout effects run first), start the trigger\n // session, or end it and forget the trigger that opened it.\n useModalTriggerSession(trigger, isOpen);\n const [contentId, setContentId] = React.useState<string | undefined>(undefined);\n const registerContentId = React.useCallback((id: string) => {\n setContentId(id);\n return () => setContentId((current) => (current === id ? undefined : current));\n }, []);\n\n const context = React.useMemo<DialogContextValue>(\n () => ({\n open: isOpen,\n requestOpen,\n modalType,\n trigger,\n finalFocusRef,\n contentId,\n registerContentId,\n }),\n [isOpen, requestOpen, modalType, trigger, finalFocusRef, contentId, registerContentId],\n );\n\n return <DialogContext.Provider value={context}>{children}</DialogContext.Provider>;\n};\nDialogRoot.displayName = 'Dialog';\n\n/**\n * Opens the dialog. Puts `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), a\n * click handler and a ref on its single child (no wrapper element), or passes them to a\n * render-prop child. A custom child component must forward `ref` and spread its props; one that\n * does not is wrapped in a `<span>` automatically (with a development warning), the span that\n * `asChild={false}` renders. Focus returns to the trigger when the dialog closes (with several\n * triggers, to the one that opened it). On the span, the state ARIA goes to the first element in\n * the tab order inside it, and focus returns to that element (to the span when you made it the\n * trigger with a `role` such as `button` and `tabIndex={0}`, or when nothing inside it can take\n * focus).\n */\nexport const DialogTrigger = (props: DialogTriggerProps) => {\n const { open, requestOpen, trigger, contentId } = useDialogContext('Dialog.Trigger');\n return useModalTriggerPart<DialogTriggerRenderProps>(\n { open, requestOpen, trigger, controlsId: contentId },\n props,\n 'Dialog.Trigger',\n );\n};\nDialogTrigger.displayName = 'DialogTrigger';\n\n/**\n * Closes the dialog: composes a click handler onto its single child (its own `onClick` runs first;\n * calling `preventDefault()` there keeps the dialog open), or passes it to a render-prop child.\n *\n * @example\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n */\nexport const DialogClose = (props: DialogCloseProps) => {\n const { requestOpen } = useDialogContext('Dialog.Close');\n return useModalClosePart<DialogCloseRenderProps>(requestOpen, props, 'Dialog.Close');\n};\nDialogClose.displayName = 'DialogClose';\n\nconst sizeClasses: Record<'small' | 'medium', string> = {\n small: 'max-w-[400px]',\n medium: 'max-w-[600px]',\n};\n\n/**\n * The dialog surface, rendered in a portal (inheriting the WaveProvider theme) while the dialog is\n * open: backdrop, title, Close button and a scrolling body. It takes the full width up to its\n * `size` and never exceeds the viewport (the body scrolls, also sideways for content wider than\n * the dialog). Its 1rem gap to the viewport edges is its own margin, so a margin in `className`\n * replaces the gap: with the width and height caps lifted as well and its height set to the\n * viewport's, it fills the viewport (a full-screen dialog). It is `role=\"dialog\"`, or\n * `role=\"alertdialog\"` when the Dialog has `modalType=\"alert\"` (a `role` you pass wins), and\n * carries `data-modal-type` with the resolved type.\n */\nexport const DialogContent = ({\n title,\n size = 'medium',\n closeLabel = 'Close',\n children,\n className,\n id,\n ref,\n ...rest\n}: DialogContentProps) => {\n const { open, requestOpen, modalType, trigger, finalFocusRef, registerContentId } =\n useDialogContext('Dialog.Content');\n const generatedId = useId('wave-dialog');\n const contentId = id ?? generatedId;\n const propTitleId = useId('wave-dialog-title');\n const titles = useTitleRegistry();\n\n const [surface, setSurface] = React.useState<HTMLDivElement | null>(null);\n const surfaceRef = React.useRef<HTMLDivElement | null>(null);\n const attachSurface = React.useCallback((node: HTMLDivElement | null) => {\n surfaceRef.current = node;\n setSurface(node);\n }, []);\n // Reports the surface's id to the root (the trigger's `aria-controls`) while it is mounted. A new\n // `id` makes a new callback, which useMergedRefs re-attaches after the commit (re-registering).\n const registerId = React.useCallback(\n (node: HTMLDivElement | null) => (node ? registerContentId(contentId) : undefined),\n [registerContentId, contentId],\n );\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, attachSurface, registerId);\n\n // An alert dialog needs an answer: a backdrop press does not close it (Escape still does).\n const closesOnBackdropPress = modalType !== 'alert';\n const backdropPress = useBackdropPress(surfaceRef, closesOnBackdropPress);\n const onDismiss = useModalDismiss(requestOpen, 'Dialog', backdropPress.afterOutsidePress);\n const layer = useModalLayer({\n open,\n onDismiss,\n refs: [surfaceRef],\n outsidePress: closesOnBackdropPress,\n container: surface,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n useUnnamedModalWarning(open ? surface : null, titles.hasTitle, 'Dialog.Content', 'Dialog.Title');\n\n // The height of the sticky Dialog.Footer, reserved as the body's scroll padding.\n const [footerHeight, setFooterHeight] = React.useState<number | null>(null);\n const surfaceContext = React.useMemo<ModalSurfaceContextValue>(\n () => ({ ...titles.context, setFooterHeight }),\n [titles.context],\n );\n\n if (!open) return null;\n\n const hasTitle = slotRendersContent(title);\n\n return (\n <Portal layerId={layer.layerId}>\n <div\n className={cn(\n dialogContentClassNames.backdrop,\n 'fixed inset-0 flex items-center justify-center bg-backdrop',\n )}\n onMouseDown={backdropPress.onMouseDown}\n >\n <div\n ref={mergedRef}\n role={modalType === 'alert' ? 'alertdialog' : 'dialog'}\n id={contentId}\n aria-labelledby={hasTitle ? propTitleId : titles.titleId}\n tabIndex={-1}\n data-modal-type={modalType}\n {...rest}\n className={cn(\n dialogContentClassNames.root,\n // The border marks the surface where the shadow cannot: in high contrast the page,\n // the backdrop and the surface are black, and forced colors drop shadows. The 1rem gap\n // to the viewport edges is the surface's own margin, not the backdrop's padding, so a\n // margin in `className` replaces it and a full-screen dialog can reach the edges. Its\n // minimum width is zero, so content wider than the room inside the gap scrolls in the\n // body instead of pushing the surface over the gap.\n 'relative m-4 flex min-w-0 max-h-[calc(100dvh-2rem)] w-full flex-col rounded-lg border border-border bg-background p-6 text-foreground shadow-64',\n sizeClasses[size],\n className,\n )}\n >\n <ModalSurfaceContext.Provider value={surfaceContext}>\n {hasTitle && (\n <h2\n id={propTitleId}\n className={cn(dialogTitleClassNames.root, 'pe-8 text-subtitle-1 font-semibold')}\n >\n {title}\n </h2>\n )}\n <Button\n appearance=\"subtle\"\n size=\"small\"\n icon={<DismissIcon />}\n aria-label={closeLabel}\n onClick={(event) =>\n requestOpen(false, { reason: 'close-button', event: event.nativeEvent })\n }\n className={cn(\n dialogContentClassNames.closeButton,\n 'absolute end-4 top-4 text-muted-foreground',\n )}\n />\n <div\n // The scroll padding keeps a focused field above the sticky footer (WCAG 2.4.11).\n className={cn(\n dialogContentClassNames.body,\n '-mx-1 mt-1 min-h-0 flex-1 overflow-y-auto scroll-pb-(--wave-dialog-footer-height) p-1 text-body-1',\n )}\n style={\n footerHeight === null\n ? undefined\n : ({ '--wave-dialog-footer-height': `${footerHeight}px` } as React.CSSProperties)\n }\n >\n {children}\n </div>\n </ModalSurfaceContext.Provider>\n </div>\n </div>\n </Portal>\n );\n};\nDialogContent.displayName = 'DialogContent';\n\n/**\n * A heading that names the dialog (`aria-labelledby`), for rich titles or custom layouts. Render it\n * inside `Dialog.Content` (instead of the `title` prop). Like the `title` heading it reserves end\n * padding (`pe-8`) so a long first line stays clear of the Close button; a `className` padding wins.\n */\nexport const DialogTitle = ({ id, className, children, ref, ...rest }: DialogTitleProps) => {\n const { id: titleId, ref: titleRef } = useModalTitle('Dialog.Title', 'Dialog.Content', id, ref);\n return (\n <h2\n {...rest}\n id={titleId}\n ref={titleRef}\n className={cn(\n dialogTitleClassNames.root,\n 'pe-8 text-subtitle-1 font-semibold text-foreground',\n className,\n )}\n >\n {children}\n </h2>\n );\n};\nDialogTitle.displayName = 'DialogTitle';\n\n/**\n * `Dialog.Footer` inside `Dialog.Content`. The body is `p-1`, and sticky positioning stops at its\n * padding edge: `-bottom-1` with `-mb-1 pb-2` covers the body's bottom padding, `-mx-1 px-1` its\n * focus-ring inset, and `pt-3` separates the actions from the content scrolling under them.\n */\nconst stickyFooterClasses =\n 'sticky -bottom-1 z-10 -mx-1 -mb-1 mt-6 flex justify-end gap-2 bg-background px-1 pb-2 pt-3';\n\n/**\n * `Dialog.Footer` where no body reserves its height as scroll padding (a Drawer's body): a plain\n * action row, which never covers a focused field.\n */\nconst footerRowClasses = 'mt-6 flex justify-end gap-2';\n\n/**\n * Action row at the end of the dialog body. It stays where you render it in the DOM and sticks to\n * the bottom of the body while long content scrolls under it (with an opaque background); the body\n * reserves its height as scroll padding, so a focused field is never hidden behind it. Inside a\n * `<form>` that wraps the fields and the footer it sticks too: make it the form's last child.\n * Render it inside `Dialog.Content`: outside it, it would stay on the page while the dialog is\n * closed (a development warning says so). Inside a `Drawer`, whose body reserves no footer height,\n * it does not stick: it is an action row at the end of the content. Render one `Dialog.Footer` per\n * `Dialog.Content`: with two at once, the body reserves the height of the one measured last, and\n * unmounting either clears it until the other resizes (swapping one footer for another is fine).\n */\nexport const DialogFooter = ({ children, className, ref, ...rest }: DialogFooterProps) => {\n const surfaceContext = React.useContext(ModalSurfaceContext);\n const outsideContent = surfaceContext === null;\n const setFooterHeight = surfaceContext?.setFooterHeight;\n const [footer, setFooter] = React.useState<HTMLDivElement | null>(null);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, setFooter);\n\n React.useEffect(() => {\n if (!outsideContent) return;\n warnOnce(\n 'Dialog.Footer:outside-content',\n 'Dialog.Footer must be rendered inside Dialog.Content. Outside it, the footer stays on the page while the dialog is closed.',\n );\n }, [outsideContent]);\n\n // Reports the footer's border-box height to Dialog.Content. The observer's first callback,\n // delivered before the next paint, supplies the first value; without ResizeObserver the body\n // keeps its default scroll padding.\n React.useLayoutEffect(() => {\n if (!footer || !setFooterHeight || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[entries.length - 1];\n if (!entry) return;\n setFooterHeight(entry.borderBoxSize?.[0]?.blockSize ?? footer.offsetHeight);\n });\n observer.observe(footer, { box: 'border-box' });\n return () => {\n observer.disconnect();\n setFooterHeight(null);\n };\n }, [footer, setFooterHeight]);\n\n return (\n <div\n ref={mergedRef}\n {...rest}\n // Sticky only where the surface reserves the footer's height (Dialog.Content).\n className={cn(\n dialogFooterClassNames.root,\n setFooterHeight ? stickyFooterClasses : footerRowClasses,\n className,\n )}\n >\n {children}\n </div>\n );\n};\nDialogFooter.displayName = 'DialogFooter';\n\n/**\n * A modal dialog (Fluent UI v2 style): `Dialog` holds the open state; `Dialog.Trigger` opens it and\n * `Dialog.Content` renders the surface in a portal while open.\n *\n * - **Modal**: focus moves into the dialog and Tab stays inside it (toasts included), the rest of\n * the page is `inert` (instead of `aria-modal`, so toasts and live regions stay announced), and\n * the page does not scroll.\n * - **Closing**: Escape (only the topmost layer: a popup opened inside closes first), a click on\n * the backdrop (a drag that starts inside does not close it), the Close button and `Dialog.Close`.\n * `onOpenChange` gets the reason as its second argument (`details.reason`), so a controlled\n * dialog can refuse some of them. A backdrop press blurs the focused field before the dialog\n * closes, so a typed value is committed as with the Close button; when a controlled dialog\n * refuses the press, the field gets focus back (an alert dialog's press leaves focus where it\n * was). Focus returns to the first of these that can take focus: `finalFocusRef`, the element\n * that had focus when the dialog opened, the trigger, an element next to where that opener was.\n * - **Alert dialogs**: `modalType=\"alert\"` renders `role=\"alertdialog\"` for a confirmation that\n * needs an answer; a backdrop press does not close it.\n * - **Footer**: `Dialog.Footer` sticks to the bottom of the scrolling body, and the body keeps a\n * focused field above it.\n * - **Naming**: give `Dialog.Content` a `title`, a `Dialog.Title`, or `aria-label`.\n *\n * The sub-components are also exported under flat names (`DialogTrigger`, `DialogContent`,\n * `DialogFooter`, `DialogTitle`, `DialogClose`) for React Server Components, which cannot use the\n * dotted form; dotted access (`Dialog.Content`) needs a client file.\n *\n * @example\n * <Dialog>\n * <Dialog.Trigger><Button>Delete</Button></Dialog.Trigger>\n * <Dialog.Content title=\"Delete file?\">\n * This cannot be undone.\n * <Dialog.Footer>\n * <Dialog.Close><Button appearance=\"subtle\">Cancel</Button></Dialog.Close>\n * <Button appearance=\"primary\" onClick={remove}>Delete</Button>\n * </Dialog.Footer>\n * </Dialog.Content>\n * </Dialog>\n */\nexport const Dialog = /* @__PURE__ */ Object.assign(DialogRoot, {\n Trigger: DialogTrigger,\n Content: DialogContent,\n Footer: DialogFooter,\n Title: DialogTitle,\n Close: DialogClose,\n});\n"],"mappings":"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"}