@mortenbrudvik/waveui 0.9.0 → 0.11.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 (264) hide show
  1. package/README.md +758 -152
  2. package/dist/components/button/Toolbar.cjs +1 -1
  3. package/dist/components/button/Toolbar.cjs.map +1 -1
  4. package/dist/components/button/Toolbar.mjs +25 -30
  5. package/dist/components/button/Toolbar.mjs.map +1 -1
  6. package/dist/components/button/Toolbar.navigation.cjs +2 -0
  7. package/dist/components/button/Toolbar.navigation.cjs.map +1 -0
  8. package/dist/components/button/Toolbar.navigation.mjs +17 -0
  9. package/dist/components/button/Toolbar.navigation.mjs.map +1 -0
  10. package/dist/components/data-display/Avatar.cjs +1 -1
  11. package/dist/components/data-display/Avatar.cjs.map +1 -1
  12. package/dist/components/data-display/Avatar.context.cjs +2 -0
  13. package/dist/components/data-display/Avatar.context.cjs.map +1 -0
  14. package/dist/components/data-display/Avatar.context.mjs +9 -0
  15. package/dist/components/data-display/Avatar.context.mjs.map +1 -0
  16. package/dist/components/data-display/Avatar.mjs +66 -61
  17. package/dist/components/data-display/Avatar.mjs.map +1 -1
  18. package/dist/components/data-display/InteractionTag.cjs +2 -0
  19. package/dist/components/data-display/InteractionTag.cjs.map +1 -0
  20. package/dist/components/data-display/InteractionTag.mjs +234 -0
  21. package/dist/components/data-display/InteractionTag.mjs.map +1 -0
  22. package/dist/components/data-display/Tag.cjs +1 -1
  23. package/dist/components/data-display/Tag.cjs.map +1 -1
  24. package/dist/components/data-display/Tag.mjs +222 -90
  25. package/dist/components/data-display/Tag.mjs.map +1 -1
  26. package/dist/components/data-display/TagGroup.cjs +2 -0
  27. package/dist/components/data-display/TagGroup.cjs.map +1 -0
  28. package/dist/components/data-display/TagGroup.context.cjs +2 -0
  29. package/dist/components/data-display/TagGroup.context.cjs.map +1 -0
  30. package/dist/components/data-display/TagGroup.context.mjs +113 -0
  31. package/dist/components/data-display/TagGroup.context.mjs.map +1 -0
  32. package/dist/components/data-display/TagGroup.mjs +149 -0
  33. package/dist/components/data-display/TagGroup.mjs.map +1 -0
  34. package/dist/components/data-display/tagStyles.cjs +2 -0
  35. package/dist/components/data-display/tagStyles.cjs.map +1 -0
  36. package/dist/components/data-display/tagStyles.mjs +108 -0
  37. package/dist/components/data-display/tagStyles.mjs.map +1 -0
  38. package/dist/components/feedback/Toaster.cjs +1 -1
  39. package/dist/components/feedback/Toaster.cjs.map +1 -1
  40. package/dist/components/feedback/Toaster.mjs +213 -181
  41. package/dist/components/feedback/Toaster.mjs.map +1 -1
  42. package/dist/components/input/Calendar.cjs +2 -0
  43. package/dist/components/input/Calendar.cjs.map +1 -0
  44. package/dist/components/input/Calendar.mjs +352 -0
  45. package/dist/components/input/Calendar.mjs.map +1 -0
  46. package/dist/components/input/Calendar.views.cjs +2 -0
  47. package/dist/components/input/Calendar.views.cjs.map +1 -0
  48. package/dist/components/input/Calendar.views.mjs +194 -0
  49. package/dist/components/input/Calendar.views.mjs.map +1 -0
  50. package/dist/components/input/ColorArea.cjs +1 -1
  51. package/dist/components/input/ColorArea.cjs.map +1 -1
  52. package/dist/components/input/ColorArea.mjs +18 -18
  53. package/dist/components/input/ColorArea.mjs.map +1 -1
  54. package/dist/components/input/Combobox.cjs +1 -1
  55. package/dist/components/input/Combobox.cjs.map +1 -1
  56. package/dist/components/input/Combobox.expand.cjs +1 -1
  57. package/dist/components/input/Combobox.expand.cjs.map +1 -1
  58. package/dist/components/input/Combobox.expand.mjs +7 -7
  59. package/dist/components/input/Combobox.expand.mjs.map +1 -1
  60. package/dist/components/input/Combobox.mjs +232 -156
  61. package/dist/components/input/Combobox.mjs.map +1 -1
  62. package/dist/components/input/Combobox.text.cjs +2 -0
  63. package/dist/components/input/Combobox.text.cjs.map +1 -0
  64. package/dist/components/input/Combobox.text.mjs +24 -0
  65. package/dist/components/input/Combobox.text.mjs.map +1 -0
  66. package/dist/components/input/DatePicker.cjs +1 -1
  67. package/dist/components/input/DatePicker.cjs.map +1 -1
  68. package/dist/components/input/DatePicker.mjs +203 -288
  69. package/dist/components/input/DatePicker.mjs.map +1 -1
  70. package/dist/components/input/Dropdown.cjs +1 -1
  71. package/dist/components/input/Dropdown.cjs.map +1 -1
  72. package/dist/components/input/Dropdown.mjs +135 -109
  73. package/dist/components/input/Dropdown.mjs.map +1 -1
  74. package/dist/components/input/Listbox.cjs +2 -0
  75. package/dist/components/input/Listbox.cjs.map +1 -0
  76. package/dist/components/input/Listbox.mjs +134 -0
  77. package/dist/components/input/Listbox.mjs.map +1 -0
  78. package/dist/components/input/Option.cjs +1 -1
  79. package/dist/components/input/Option.cjs.map +1 -1
  80. package/dist/components/input/Option.mjs +163 -97
  81. package/dist/components/input/Option.mjs.map +1 -1
  82. package/dist/components/input/SwatchPicker.cjs +1 -1
  83. package/dist/components/input/SwatchPicker.cjs.map +1 -1
  84. package/dist/components/input/SwatchPicker.context.cjs +2 -0
  85. package/dist/components/input/SwatchPicker.context.cjs.map +1 -0
  86. package/dist/components/input/SwatchPicker.context.mjs +35 -0
  87. package/dist/components/input/SwatchPicker.context.mjs.map +1 -0
  88. package/dist/components/input/SwatchPicker.mjs +131 -103
  89. package/dist/components/input/SwatchPicker.mjs.map +1 -1
  90. package/dist/components/input/SwatchPicker.swatches.cjs +2 -0
  91. package/dist/components/input/SwatchPicker.swatches.cjs.map +1 -0
  92. package/dist/components/input/SwatchPicker.swatches.mjs +207 -0
  93. package/dist/components/input/SwatchPicker.swatches.mjs.map +1 -0
  94. package/dist/components/input/TagPicker.cjs +1 -1
  95. package/dist/components/input/TagPicker.cjs.map +1 -1
  96. package/dist/components/input/TagPicker.context.cjs +2 -0
  97. package/dist/components/input/TagPicker.context.cjs.map +1 -0
  98. package/dist/components/input/TagPicker.context.mjs +20 -0
  99. package/dist/components/input/TagPicker.context.mjs.map +1 -0
  100. package/dist/components/input/TagPicker.create.cjs +2 -0
  101. package/dist/components/input/TagPicker.create.cjs.map +1 -0
  102. package/dist/components/input/TagPicker.create.mjs +24 -0
  103. package/dist/components/input/TagPicker.create.mjs.map +1 -0
  104. package/dist/components/input/TagPicker.mjs +13 -274
  105. package/dist/components/input/TagPicker.mjs.map +1 -1
  106. package/dist/components/input/TagPicker.option.cjs +2 -0
  107. package/dist/components/input/TagPicker.option.cjs.map +1 -0
  108. package/dist/components/input/TagPicker.option.mjs +45 -0
  109. package/dist/components/input/TagPicker.option.mjs.map +1 -0
  110. package/dist/components/input/TagPicker.overflow.cjs +2 -0
  111. package/dist/components/input/TagPicker.overflow.cjs.map +1 -0
  112. package/dist/components/input/TagPicker.overflow.mjs +153 -0
  113. package/dist/components/input/TagPicker.overflow.mjs.map +1 -0
  114. package/dist/components/input/TagPicker.parts.cjs +2 -0
  115. package/dist/components/input/TagPicker.parts.cjs.map +1 -0
  116. package/dist/components/input/TagPicker.parts.mjs +425 -0
  117. package/dist/components/input/TagPicker.parts.mjs.map +1 -0
  118. package/dist/components/input/TagPicker.root.cjs +2 -0
  119. package/dist/components/input/TagPicker.root.cjs.map +1 -0
  120. package/dist/components/input/TagPicker.root.mjs +416 -0
  121. package/dist/components/input/TagPicker.root.mjs.map +1 -0
  122. package/dist/components/input/TimePicker.cjs +1 -1
  123. package/dist/components/input/TimePicker.cjs.map +1 -1
  124. package/dist/components/input/TimePicker.mjs +77 -77
  125. package/dist/components/input/TimePicker.mjs.map +1 -1
  126. package/dist/components/input/dateUtils.cjs +1 -1
  127. package/dist/components/input/dateUtils.cjs.map +1 -1
  128. package/dist/components/input/dateUtils.mjs +114 -96
  129. package/dist/components/input/dateUtils.mjs.map +1 -1
  130. package/dist/components/input/pickerLabels.cjs +2 -0
  131. package/dist/components/input/pickerLabels.cjs.map +1 -0
  132. package/dist/components/input/pickerLabels.mjs +16 -0
  133. package/dist/components/input/pickerLabels.mjs.map +1 -0
  134. package/dist/components/input/pickerValues.cjs +2 -0
  135. package/dist/components/input/pickerValues.cjs.map +1 -0
  136. package/dist/components/input/pickerValues.mjs +24 -0
  137. package/dist/components/input/pickerValues.mjs.map +1 -0
  138. package/dist/components/layout/Accordion.cjs.map +1 -1
  139. package/dist/components/layout/Accordion.mjs.map +1 -1
  140. package/dist/components/navigation/Hamburger.cjs +2 -0
  141. package/dist/components/navigation/Hamburger.cjs.map +1 -0
  142. package/dist/components/navigation/Hamburger.mjs +54 -0
  143. package/dist/components/navigation/Hamburger.mjs.map +1 -0
  144. package/dist/components/navigation/Nav.cjs +1 -1
  145. package/dist/components/navigation/Nav.cjs.map +1 -1
  146. package/dist/components/navigation/Nav.context.cjs +2 -0
  147. package/dist/components/navigation/Nav.context.cjs.map +1 -0
  148. package/dist/components/navigation/Nav.context.mjs +137 -0
  149. package/dist/components/navigation/Nav.context.mjs.map +1 -0
  150. package/dist/components/navigation/Nav.mjs +151 -258
  151. package/dist/components/navigation/Nav.mjs.map +1 -1
  152. package/dist/components/navigation/Nav.parts.cjs +2 -0
  153. package/dist/components/navigation/Nav.parts.cjs.map +1 -0
  154. package/dist/components/navigation/Nav.parts.mjs +77 -0
  155. package/dist/components/navigation/Nav.parts.mjs.map +1 -0
  156. package/dist/components/navigation/Nav.root.cjs +2 -0
  157. package/dist/components/navigation/Nav.root.cjs.map +1 -0
  158. package/dist/components/navigation/Nav.root.mjs +78 -0
  159. package/dist/components/navigation/Nav.root.mjs.map +1 -0
  160. package/dist/components/navigation/NavDrawer.cjs +2 -0
  161. package/dist/components/navigation/NavDrawer.cjs.map +1 -0
  162. package/dist/components/navigation/NavDrawer.context.cjs +2 -0
  163. package/dist/components/navigation/NavDrawer.context.cjs.map +1 -0
  164. package/dist/components/navigation/NavDrawer.context.mjs +11 -0
  165. package/dist/components/navigation/NavDrawer.context.mjs.map +1 -0
  166. package/dist/components/navigation/NavDrawer.mjs +179 -0
  167. package/dist/components/navigation/NavDrawer.mjs.map +1 -0
  168. package/dist/components/overlays/Dialog.cjs +1 -1
  169. package/dist/components/overlays/Dialog.cjs.map +1 -1
  170. package/dist/components/overlays/Dialog.mjs +190 -125
  171. package/dist/components/overlays/Dialog.mjs.map +1 -1
  172. package/dist/components/overlays/Dialog.shared.cjs +1 -1
  173. package/dist/components/overlays/Dialog.shared.cjs.map +1 -1
  174. package/dist/components/overlays/Dialog.shared.mjs +157 -81
  175. package/dist/components/overlays/Dialog.shared.mjs.map +1 -1
  176. package/dist/components/overlays/Dialog.slots.cjs +2 -0
  177. package/dist/components/overlays/Dialog.slots.cjs.map +1 -0
  178. package/dist/components/overlays/Dialog.slots.mjs +129 -0
  179. package/dist/components/overlays/Dialog.slots.mjs.map +1 -0
  180. package/dist/components/overlays/Drawer.cjs +1 -1
  181. package/dist/components/overlays/Drawer.cjs.map +1 -1
  182. package/dist/components/overlays/Drawer.context.cjs +2 -0
  183. package/dist/components/overlays/Drawer.context.cjs.map +1 -0
  184. package/dist/components/overlays/Drawer.context.mjs +29 -0
  185. package/dist/components/overlays/Drawer.context.mjs.map +1 -0
  186. package/dist/components/overlays/Drawer.mjs +12 -187
  187. package/dist/components/overlays/Drawer.mjs.map +1 -1
  188. package/dist/components/overlays/Drawer.panel.cjs +2 -0
  189. package/dist/components/overlays/Drawer.panel.cjs.map +1 -0
  190. package/dist/components/overlays/Drawer.panel.mjs +159 -0
  191. package/dist/components/overlays/Drawer.panel.mjs.map +1 -0
  192. package/dist/components/overlays/Drawer.parts.cjs +2 -0
  193. package/dist/components/overlays/Drawer.parts.cjs.map +1 -0
  194. package/dist/components/overlays/Drawer.parts.mjs +152 -0
  195. package/dist/components/overlays/Drawer.parts.mjs.map +1 -0
  196. package/dist/components/overlays/Drawer.root.cjs +2 -0
  197. package/dist/components/overlays/Drawer.root.cjs.map +1 -0
  198. package/dist/components/overlays/Drawer.root.mjs +207 -0
  199. package/dist/components/overlays/Drawer.root.mjs.map +1 -0
  200. package/dist/components/overlays/Drawer.scroll.cjs +2 -0
  201. package/dist/components/overlays/Drawer.scroll.cjs.map +1 -0
  202. package/dist/components/overlays/Drawer.scroll.mjs +42 -0
  203. package/dist/components/overlays/Drawer.scroll.mjs.map +1 -0
  204. package/dist/components/table/useGridNavigation.cjs +1 -1
  205. package/dist/components/table/useGridNavigation.cjs.map +1 -1
  206. package/dist/components/table/useGridNavigation.mjs +67 -70
  207. package/dist/components/table/useGridNavigation.mjs.map +1 -1
  208. package/dist/hooks/useActiveDescendant.cjs +2 -0
  209. package/dist/hooks/useActiveDescendant.cjs.map +1 -0
  210. package/dist/hooks/useActiveDescendant.mjs +56 -0
  211. package/dist/hooks/useActiveDescendant.mjs.map +1 -0
  212. package/dist/hooks/useDismiss.cjs.map +1 -1
  213. package/dist/hooks/useDismiss.mjs.map +1 -1
  214. package/dist/hooks/useFocusTrap.cjs +1 -1
  215. package/dist/hooks/useFocusTrap.cjs.map +1 -1
  216. package/dist/hooks/useFocusTrap.mjs +115 -98
  217. package/dist/hooks/useFocusTrap.mjs.map +1 -1
  218. package/dist/hooks/useListbox.cjs +1 -1
  219. package/dist/hooks/useListbox.cjs.map +1 -1
  220. package/dist/hooks/useListbox.mjs +250 -210
  221. package/dist/hooks/useListbox.mjs.map +1 -1
  222. package/dist/hooks/useModalLayer.cjs +1 -1
  223. package/dist/hooks/useModalLayer.cjs.map +1 -1
  224. package/dist/hooks/useModalLayer.mjs +35 -22
  225. package/dist/hooks/useModalLayer.mjs.map +1 -1
  226. package/dist/hooks/useRestoreFocus.cjs +1 -1
  227. package/dist/hooks/useRestoreFocus.cjs.map +1 -1
  228. package/dist/hooks/useRestoreFocus.mjs +91 -78
  229. package/dist/hooks/useRestoreFocus.mjs.map +1 -1
  230. package/dist/hooks/useRovingGrid.cjs +2 -0
  231. package/dist/hooks/useRovingGrid.cjs.map +1 -0
  232. package/dist/hooks/useRovingGrid.mjs +69 -0
  233. package/dist/hooks/useRovingGrid.mjs.map +1 -0
  234. package/dist/hooks/useRovingTabIndex.cjs +1 -1
  235. package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
  236. package/dist/hooks/useRovingTabIndex.mjs +102 -78
  237. package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
  238. package/dist/index.cjs +1 -1
  239. package/dist/index.d.cts +4391 -394
  240. package/dist/index.d.ts +4391 -394
  241. package/dist/index.mjs +115 -101
  242. package/dist/lib/classNames.cjs +1 -1
  243. package/dist/lib/classNames.cjs.map +1 -1
  244. package/dist/lib/classNames.mjs +170 -74
  245. package/dist/lib/classNames.mjs.map +1 -1
  246. package/dist/lib/date.cjs +2 -0
  247. package/dist/lib/date.cjs.map +1 -0
  248. package/dist/lib/date.mjs +44 -0
  249. package/dist/lib/date.mjs.map +1 -0
  250. package/dist/lib/focus.cjs +1 -1
  251. package/dist/lib/focus.cjs.map +1 -1
  252. package/dist/lib/focus.mjs +5 -2
  253. package/dist/lib/focus.mjs.map +1 -1
  254. package/dist/lib/icons.cjs +1 -1
  255. package/dist/lib/icons.cjs.map +1 -1
  256. package/dist/lib/icons.mjs +13 -6
  257. package/dist/lib/icons.mjs.map +1 -1
  258. package/dist/lib/layers.cjs +1 -1
  259. package/dist/lib/layers.cjs.map +1 -1
  260. package/dist/lib/layers.mjs +53 -47
  261. package/dist/lib/layers.mjs.map +1 -1
  262. package/dist/styles.css +1 -1
  263. package/package.json +1 -1
  264. package/src/styles/tokens.css +25 -0
@@ -0,0 +1,129 @@
1
+ "use client";
2
+ import { cn as e } from "../../lib/cn.mjs";
3
+ import { isElementOfType as t } from "../../lib/children.mjs";
4
+ import { warnOnce as n } from "../../lib/dev.mjs";
5
+ import { materialiseSlotContent as r, resolveSlot as i, slotRendersContent as a, slotWrapsDefaultContent as o } from "../../lib/slot.mjs";
6
+ import { composeEventHandlers as s } from "../../lib/composeEventHandlers.mjs";
7
+ import { useMergedRefs as c } from "../../hooks/useMergedRefs.mjs";
8
+ import { hasIsolatingModalBelow as l, subscribeLayers as u } from "../../lib/layers.mjs";
9
+ import { Button as d } from "../button/Button.mjs";
10
+ import { BUTTON_OWN_PROP_KEYS as f } from "../button/Button.slots.mjs";
11
+ import { DismissIcon as p } from "../../lib/icons.mjs";
12
+ import { hasRenderedTextLabel as m, hasTextLabel as h, observeTextLabel as g } from "../../lib/labelInName.mjs";
13
+ import * as _ from "react";
14
+ import { jsx as v } from "react/jsx-runtime";
15
+ //#region src/components/overlays/Dialog.slots.tsx
16
+ var y = /* @__PURE__ */ new Set([
17
+ "aria-label",
18
+ "aria-labelledby",
19
+ "title"
20
+ ]), b = /^on[A-Z]/, x = () => {}, S = () => /* @__PURE__ */ v(p, {});
21
+ function C() {
22
+ return {
23
+ buttonProps: {},
24
+ icon: S(),
25
+ iconPosition: void 0,
26
+ children: void 0,
27
+ contentMayName: !1,
28
+ literalTextLabel: !1,
29
+ disabledFocusable: !1,
30
+ merged: null
31
+ };
32
+ }
33
+ function w(e) {
34
+ return e === "button" || e === d;
35
+ }
36
+ function T(e, t, n, i) {
37
+ let o = {};
38
+ for (let [t, n] of Object.entries(e)) t === "children" || t === "dangerouslySetInnerHTML" || f.has(t) || (o[t] = n);
39
+ let s = e.dangerouslySetInnerHTML, c = s == null ? r(t) : /* @__PURE__ */ v("span", {
40
+ className: "inline-flex items-center",
41
+ dangerouslySetInnerHTML: s
42
+ }), l = n && a(e.icon) ? e.icon : null, u = l !== null || a(c);
43
+ return {
44
+ buttonProps: o,
45
+ icon: u ? l ?? void 0 : S(),
46
+ iconPosition: n ? e.iconPosition : void 0,
47
+ children: u ? c : void 0,
48
+ contentMayName: !0,
49
+ literalTextLabel: h(c),
50
+ disabledFocusable: n && !!e.disabledFocusable,
51
+ merged: i
52
+ };
53
+ }
54
+ function E(e) {
55
+ if (e === null) return null;
56
+ if (e === void 0 || typeof e == "boolean") return C();
57
+ let n = e;
58
+ if (t(n, "button", d)) return T(n.props, n.props.children, t(n, d), "a button element");
59
+ let r = i(e, "span");
60
+ if (!r) return C();
61
+ let { Component: s, props: c, children: l } = r;
62
+ if (w(s)) return T(c, l, s === d, "a slot object that renders a button");
63
+ let u = {}, f = {};
64
+ for (let [e, t] of Object.entries(c)) y.has(e) || b.test(e) ? u[e] = t : f[e] = t;
65
+ let p;
66
+ return a(l) ? p = l : o(s, {
67
+ ...f,
68
+ children: l
69
+ }) && (p = S()), {
70
+ buttonProps: u,
71
+ icon: {
72
+ ...f,
73
+ as: s,
74
+ children: p
75
+ },
76
+ iconPosition: void 0,
77
+ children: void 0,
78
+ contentMayName: !1,
79
+ literalTextLabel: !1,
80
+ disabledFocusable: !1,
81
+ merged: null
82
+ };
83
+ }
84
+ function D({ componentName: t, closeButton: r, closeLabel: i, onClose: a, className: o }) {
85
+ let l = E(r), u = l?.merged ?? null;
86
+ _.useEffect(() => {
87
+ u !== null && n(`${t}:closeButton-button-element`, `${t}: \`closeButton\` received ${u}; its props were merged into the built-in Close button (buttons cannot be nested). Pass icon content instead, e.g. \`closeButton={<CloseIcon />}\`.`);
88
+ }, [u, t]);
89
+ let { ref: f, onClick: p, className: h, ...b } = l?.buttonProps ?? {}, S = Object.keys(b).some((e) => y.has(e) && b[e] != null), C = l !== null && l.contentMayName && !S, w = l?.literalTextLabel ?? !1, [T, D] = _.useState(null), O = _.useCallback((e) => T ? g(T, e) : x, [T]), k = _.useSyncExternalStore(O, () => T ? m(T) : w, () => w), A = C && k, j = c(f, C ? D : void 0);
90
+ return l === null ? null : /* @__PURE__ */ v(d, {
91
+ appearance: "subtle",
92
+ size: "small",
93
+ "aria-label": S || A ? void 0 : i,
94
+ ...b,
95
+ ref: j,
96
+ icon: l.icon,
97
+ iconPosition: l.iconPosition,
98
+ disabledFocusable: l.disabledFocusable,
99
+ onClick: s(p, (e) => a(e.nativeEvent)),
100
+ className: e(o, h),
101
+ children: l.children
102
+ });
103
+ }
104
+ D.displayName = "ModalCloseButton";
105
+ var O = () => "dimmed";
106
+ function k(e, t) {
107
+ let n = _.useCallback(() => t && l(e) ? "transparent" : "dimmed", [e, t]);
108
+ return _.useSyncExternalStore(u, n, O);
109
+ }
110
+ function A({ backdrop: t, className: n, layerId: r, open: a, onMouseDown: o, presenceProps: l }) {
111
+ let u = k(r, a), d = t === null || typeof t == "boolean" ? void 0 : t, f = d === void 0 ? null : i(d, "div"), { appearance: p, className: m, onMouseDown: h, ref: g, ..._ } = f?.props ?? {}, y = c(g);
112
+ if (t === null) return null;
113
+ let b = p === "dimmed" || p === "transparent" ? p : u, x = f?.Component ?? "div";
114
+ return /* @__PURE__ */ v(x, {
115
+ "data-appearance": b,
116
+ ..._,
117
+ ...l,
118
+ ref: y,
119
+ "aria-hidden": "true",
120
+ onMouseDown: s(h, o),
121
+ className: e(n, "fixed inset-0", b === "transparent" ? "bg-transparent" : "bg-backdrop", m),
122
+ children: f?.children
123
+ });
124
+ }
125
+ A.displayName = "ModalBackdrop";
126
+ //#endregion
127
+ export { A as ModalBackdrop, D as ModalCloseButton, k as useBackdropAppearance };
128
+
129
+ //# sourceMappingURL=Dialog.slots.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dialog.slots.mjs","names":["React","NAMING_KEYS","HANDLER_KEY","noop","defaultGlyph","DismissIcon","defaultParts","isButtonType","type","Button","mergedParts","buttonProps","key","value","props","BUTTON_OWN_PROP_KEYS","markup","content","materialiseSlotContent","children","icon","isWaveButton","slotRendersContent","hasContent","hasTextLabel","resolveCloseButton","closeButton","element","isElementOfType","resolved","resolveSlot","Component","contentProps","inner","slotWrapsDefaultContent","ModalCloseButton","parts","merged","warnOnce","componentName","slotRef","slotOnClick","slotClassName","slotButtonProps","hasOwnName","checksContent","literalTextLabel","labelTarget","setLabelTarget","subscribeToContent","observeTextLabel","onChange","contentHasTextLabel","hasRenderedTextLabel","namedByContent","ref","useMergedRefs","closeLabel","composeEventHandlers","onClose","event","cn","className","getServerAppearance","useBackdropAppearance","getSnapshot","open","hasIsolatingModalBelow","layerId","subscribeLayers","ModalBackdrop","automatic","slot","backdrop","ownAppearance","slotOnMouseDown","slotProps","appearance","presenceProps","onMouseDown"],"sources":["../../../src/components/overlays/Dialog.slots.tsx"],"sourcesContent":["import * as React from 'react';\nimport { isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { composeEventHandlers } from '../../lib/composeEventHandlers';\nimport { warnOnce } from '../../lib/dev';\nimport { DismissIcon } from '../../lib/icons';\nimport { hasRenderedTextLabel, hasTextLabel, observeTextLabel } from '../../lib/labelInName';\nimport { hasIsolatingModalBelow, subscribeLayers } from '../../lib/layers';\nimport {\n materialiseSlotContent,\n resolveSlot,\n slotRendersContent,\n slotWrapsDefaultContent,\n type Slot,\n type SlotObject,\n} from '../../lib/slot';\nimport type { BackdropAppearance, IconPosition } from '../../lib/types';\nimport type { PresenceAttributes } from '../../hooks/usePresence';\nimport { useMergedRefs } from '../../hooks/useMergedRefs';\nimport { Button } from '../button/Button';\nimport { BUTTON_OWN_PROP_KEYS, type UnwrappedButton } from '../button/Button.slots';\n\n/*\n * The Close button and backdrop slots of Dialog and Drawer (P6-06 D93–D95). Internal (not\n * exported from the package). Imports Button, never the reverse.\n */\n\ntype UnknownProps = Record<string, unknown>;\n\n/** The `backdrop` slot of `Dialog.Content`, `Drawer` and the drawer panel shell. */\nexport type ModalBackdropSlot =\n Slot<'div'> | (SlotObject<'div'> & { appearance?: BackdropAppearance });\n\n/** Attributes of a `closeButton` slot that name the Close button instead of `closeLabel`. */\nconst NAMING_KEYS: ReadonlySet<string> = new Set(['aria-label', 'aria-labelledby', 'title']);\n\nconst HANDLER_KEY = /^on[A-Z]/;\n\nconst noop = () => {};\n\n/** How the `closeButton` slot splits between the built-in Button and the content inside it. */\ninterface CloseButtonParts {\n /**\n * Props for the built-in Button: every prop of a merged button (except Wave Button's own), or a\n * slot object's naming attributes and handlers.\n */\n buttonProps: UnknownProps;\n /** The Button's decorative `icon`: the slot's content, a merged Button's icon, or the glyph. */\n icon: Slot<'span'> | undefined;\n /** A merged Wave Button's `iconPosition`. */\n iconPosition: IconPosition | undefined;\n /** The Button's children: the content of a merged button (it may name the button). */\n children: React.ReactNode;\n /** `true` for a merged button: a text label in its content names the Close button. */\n contentMayName: boolean;\n /** Whether a merged button's literal content holds a text label (the server and first render). */\n literalTextLabel: boolean;\n /** A merged Wave Button's `disabledFocusable`. */\n disabledFocusable: boolean;\n /** What was merged, for the development warning (`null`: nothing). */\n merged: UnwrappedButton | null;\n}\n\n/** The decorative default glyph of the Close button. */\nconst defaultGlyph = () => <DismissIcon />;\n\nfunction defaultParts(): CloseButtonParts {\n return {\n buttonProps: {},\n icon: defaultGlyph(),\n iconPosition: undefined,\n children: undefined,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n merged: null,\n };\n}\n\nfunction isButtonType(type: unknown): boolean {\n return type === 'button' || type === Button;\n}\n\n/**\n * The parts of a `<button>` or Wave `Button` merged into the built-in Close button: its props go\n * to the Button (Wave Button's own props are applied or dropped), its content becomes the Button's\n * children, and a Wave Button's `icon` stays its icon. Without content of either kind the\n * default glyph stays.\n */\nfunction mergedParts(\n props: UnknownProps,\n children: unknown,\n isWaveButton: boolean,\n merged: UnwrappedButton,\n): CloseButtonParts {\n const buttonProps: UnknownProps = {};\n for (const [key, value] of Object.entries(props)) {\n if (key === 'children' || key === 'dangerouslySetInnerHTML' || BUTTON_OWN_PROP_KEYS.has(key)) {\n continue;\n }\n buttonProps[key] = value;\n }\n // Markup of the merged button is its content too, in a span inside the Button.\n const markup = props.dangerouslySetInnerHTML as\n React.HTMLAttributes<HTMLElement>['dangerouslySetInnerHTML'] | undefined;\n const content =\n markup != null ? (\n <span className=\"inline-flex items-center\" dangerouslySetInnerHTML={markup} />\n ) : (\n materialiseSlotContent(children)\n );\n const icon = isWaveButton && slotRendersContent(props.icon) ? (props.icon as Slot<'span'>) : null;\n const hasContent = icon !== null || slotRendersContent(content);\n return {\n buttonProps,\n icon: hasContent ? (icon ?? undefined) : defaultGlyph(),\n iconPosition: isWaveButton ? (props.iconPosition as IconPosition | undefined) : undefined,\n children: hasContent ? content : undefined,\n contentMayName: true,\n literalTextLabel: hasTextLabel(content),\n disabledFocusable: isWaveButton && Boolean(props.disabledFocusable),\n merged,\n };\n}\n\n/**\n * Splits the `closeButton` slot (D95): `null` means no Close button; `undefined` and booleans keep\n * the default; a `<button>`/`Button` element, or a slot object whose `as` is one, is merged; other\n * content is the Button's decorative icon, whose element takes a slot object's other attributes\n * while its naming attributes and handlers go to the Button. Content that renders nothing keeps\n * the default glyph, as does a slot object whose element wraps the default content.\n */\nfunction resolveCloseButton(closeButton: Slot<'span'> | undefined): CloseButtonParts | null {\n if (closeButton === null) return null;\n if (closeButton === undefined || typeof closeButton === 'boolean') return defaultParts();\n\n // A Button written in a Server Component (a lazy client reference) is merged too.\n const element = closeButton as React.ReactNode;\n if (isElementOfType<UnknownProps>(element, 'button', Button)) {\n return mergedParts(\n element.props,\n element.props.children,\n isElementOfType(element, Button),\n 'a button element',\n );\n }\n\n const resolved = resolveSlot(closeButton, 'span');\n if (!resolved) return defaultParts();\n const { Component, props, children } = resolved;\n if (isButtonType(Component)) {\n return mergedParts(\n props,\n children,\n Component === Button,\n 'a slot object that renders a button',\n );\n }\n\n const buttonProps: UnknownProps = {};\n const contentProps: UnknownProps = {};\n for (const [key, value] of Object.entries(props)) {\n if (NAMING_KEYS.has(key) || HANDLER_KEY.test(key)) buttonProps[key] = value;\n else contentProps[key] = value;\n }\n let inner: React.ReactNode;\n if (slotRendersContent(children)) inner = children;\n else if (slotWrapsDefaultContent(Component, { ...contentProps, children }))\n inner = defaultGlyph();\n return {\n buttonProps,\n // The content element, as a slot object of the Button's icon: Button adds its icon classes\n // and `aria-hidden`.\n icon: { ...contentProps, as: Component, children: inner } as SlotObject<'span'>,\n iconPosition: undefined,\n children: undefined,\n contentMayName: false,\n literalTextLabel: false,\n disabledFocusable: false,\n merged: null,\n };\n}\n\n/** Properties of {@link ModalCloseButton}. */\nexport interface ModalCloseButtonProps {\n /** `'Dialog.Content'` or `'Drawer'`: the warning key and text. */\n componentName: string;\n /** The `closeButton` slot. */\n closeButton: Slot<'span'> | undefined;\n /** The Button's name unless the slot names it (`closeLabel`). */\n closeLabel: string;\n /** Asks to close with `'close-button'`. */\n onClose: (event: Event) => void;\n /** The part class and layout classes, after Button's own (`drawerClassNames.closeButton`, …). */\n className: string;\n}\n\n/**\n * The built-in Close button with the `closeButton` slot rules (D95), shared by `Dialog.Content`,\n * the built-in Drawer header and every `Drawer.HeaderTitle`: a subtle, small Wave `Button` named\n * by `closeLabel`, holding the dismiss glyph or the slot's decorative content; a merged button's\n * text label (two letters or digits, `labelInName.ts`) names it instead, from the literal content\n * on the server and the first render and from the rendered text after mount. `null` when hidden.\n * Warns once, from an effect, when a button was merged.\n */\nexport function ModalCloseButton({\n componentName,\n closeButton,\n closeLabel,\n onClose,\n className,\n}: ModalCloseButtonProps): React.ReactNode {\n const parts = resolveCloseButton(closeButton);\n const merged = parts?.merged ?? null;\n React.useEffect(() => {\n if (merged === null) return;\n warnOnce(\n `${componentName}:closeButton-button-element`,\n `${componentName}: \\`closeButton\\` received ${merged}; its props were merged into the built-in Close button (buttons cannot be nested). Pass icon content instead, e.g. \\`closeButton={<CloseIcon />}\\`.`,\n );\n }, [merged, componentName]);\n\n const {\n ref: slotRef,\n onClick: slotOnClick,\n className: slotClassName,\n ...slotButtonProps\n } = parts?.buttonProps ?? {};\n const hasOwnName = Object.keys(slotButtonProps).some(\n (key) => NAMING_KEYS.has(key) && slotButtonProps[key] != null,\n );\n\n // WCAG 2.5.3 (Label in Name): a merged button's text label names the Close button, which then\n // drops `closeLabel`. The literal content decides on the server and the first render; after\n // mount the rendered text does (text from components, e.g. translations, and later changes).\n const checksContent = parts !== null && parts.contentMayName && !hasOwnName;\n const literalTextLabel = parts?.literalTextLabel ?? false;\n const [labelTarget, setLabelTarget] = React.useState<HTMLButtonElement | null>(null);\n const subscribeToContent = React.useCallback(\n (onChange: () => void) => (labelTarget ? observeTextLabel(labelTarget, onChange) : noop),\n [labelTarget],\n );\n const contentHasTextLabel = React.useSyncExternalStore(\n subscribeToContent,\n () => (labelTarget ? hasRenderedTextLabel(labelTarget) : literalTextLabel),\n () => literalTextLabel,\n );\n const namedByContent = checksContent && contentHasTextLabel;\n const ref = useMergedRefs<HTMLButtonElement>(\n slotRef as React.Ref<HTMLButtonElement> | undefined,\n checksContent ? setLabelTarget : undefined,\n );\n\n if (parts === null) return null;\n return (\n <Button\n appearance=\"subtle\"\n size=\"small\"\n aria-label={hasOwnName || namedByContent ? undefined : closeLabel}\n {...slotButtonProps}\n ref={ref}\n icon={parts.icon}\n iconPosition={parts.iconPosition}\n disabledFocusable={parts.disabledFocusable}\n onClick={composeEventHandlers(\n slotOnClick as React.MouseEventHandler<HTMLButtonElement> | undefined,\n (event: React.MouseEvent<HTMLButtonElement>) => onClose(event.nativeEvent),\n )}\n className={cn(className, slotClassName as string | undefined)}\n >\n {parts.children}\n </Button>\n );\n}\nModalCloseButton.displayName = 'ModalCloseButton';\n\n/** The server snapshot of {@link useBackdropAppearance}: nothing is stacked on the server. */\nconst getServerAppearance = (): BackdropAppearance => 'dimmed';\n\n/**\n * The automatic look of a modal surface's backdrop (D94): `'transparent'` while the surface is\n * open and another open modal surface whose isolation is active is stacked below it (nested in its\n * content or opened beside it), so the page is dimmed once; `'dimmed'` otherwise. Derived during\n * render from the layer stack (`hasIsolatingModalBelow`), re-read whenever a layer or an isolation\n * changes, so the upper surface dims when the lower one closes. A modal layer without isolation\n * (the DatePicker calendar) never counts.\n */\nexport function useBackdropAppearance(layerId: string, open: boolean): BackdropAppearance {\n const getSnapshot = React.useCallback(\n (): BackdropAppearance => (open && hasIsolatingModalBelow(layerId) ? 'transparent' : 'dimmed'),\n [layerId, open],\n );\n return React.useSyncExternalStore(subscribeLayers, getSnapshot, getServerAppearance);\n}\n\n/** Properties of {@link ModalBackdrop}. */\nexport interface ModalBackdropProps {\n /** The `backdrop` slot. */\n backdrop: ModalBackdropSlot | undefined;\n /**\n * The stable class (`dialogContentClassNames.backdrop`, `drawerClassNames.backdrop`, plus a\n * variant's), first in the backdrop's classes.\n */\n className: string;\n /** The surface's dismiss layer (for the automatic appearance). */\n layerId: string;\n /** Whether the surface is open. */\n open: boolean;\n /** The surface's backdrop press handling (`useBackdropPress`), after the slot's own handler. */\n onMouseDown: (event: React.MouseEvent<HTMLElement>) => void;\n /** The presence attributes of the surface's top-level elements (P6-07). */\n presenceProps: PresenceAttributes;\n}\n\n/**\n * The backdrop element of a modal or alert surface with the `backdrop` slot rules (D93) and the\n * automatic appearance (D94): `aria-hidden`, `fixed inset-0`, rendered as `data-appearance` and\n * filled with the backdrop token, or transparent. `null` renders none; `undefined` and booleans\n * the default; shorthand content renders inside it; a slot object's attributes, `className`\n * (merged last), `style`, `ref` and handlers (composed, the slot's first) go to it, its children\n * render inside it, and its `appearance` overrides the automatic one. `aria-hidden=\"true\"` always\n * wins.\n */\nexport function ModalBackdrop({\n backdrop,\n className,\n layerId,\n open,\n onMouseDown,\n presenceProps,\n}: ModalBackdropProps): React.ReactNode {\n const automatic = useBackdropAppearance(layerId, open);\n const slot = backdrop === null || typeof backdrop === 'boolean' ? undefined : backdrop;\n const resolved = slot === undefined ? null : resolveSlot<'div'>(slot as Slot<'div'>, 'div');\n const {\n appearance: ownAppearance,\n className: slotClassName,\n onMouseDown: slotOnMouseDown,\n ref: slotRef,\n ...slotProps\n } = resolved?.props ?? {};\n const ref = useMergedRefs<HTMLElement>(slotRef as React.Ref<HTMLElement> | undefined);\n if (backdrop === null) return null;\n\n const appearance: BackdropAppearance =\n ownAppearance === 'dimmed' || ownAppearance === 'transparent' ? ownAppearance : automatic;\n const Component: React.ElementType = resolved?.Component ?? 'div';\n return (\n <Component\n data-appearance={appearance}\n {...slotProps}\n {...presenceProps}\n ref={ref}\n aria-hidden=\"true\"\n onMouseDown={composeEventHandlers(\n slotOnMouseDown as React.MouseEventHandler<HTMLElement> | undefined,\n onMouseDown,\n )}\n className={cn(\n className,\n 'fixed inset-0',\n appearance === 'transparent' ? 'bg-transparent' : 'bg-backdrop',\n slotClassName as string | undefined,\n )}\n >\n {resolved?.children}\n </Component>\n );\n}\nModalBackdrop.displayName = 'ModalBackdrop';\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/cn.cjs"),n=require("../../lib/children.cjs"),r=require("../../lib/dev.cjs"),i=require("../../lib/slot.cjs"),a=require("../../lib/classNames.cjs"),o=require("../../hooks/useId.cjs"),s=require("../../hooks/useMergedRefs.cjs"),c=require("../../hooks/useIsClient.cjs"),ee=require("../portal/Portal.cjs"),te=require("../button/Button.cjs"),l=require("../../lib/icons.cjs"),ne=require("../../hooks/useModalLayer.cjs"),u=require("./Dialog.shared.cjs");let d=require("react");d=e.__toESM(d,1);let f=require("react/jsx-runtime");var p=d.createContext(null);p.displayName=`DrawerContext`;var m={open:!1,requestOpen:()=>{},trigger:u.inertModalTrigger,panelId:``,inPanel:!1};function h(e){return u.useRequiredContext(p,e,`Drawer`,()=>m)}var g={start:`start-0 border-e`,end:`end-0 border-s`,left:`left-0 border-r`,right:`right-0 border-l`},_=`Drawer.Trigger:nested`,v="Drawer.Trigger must be a direct child of Drawer (a Fragment is fine). Inside another element or a component it is rendered as panel content, which exists only while the drawer is open, so it cannot open the drawer. Make it a direct child, put wrappers such as a Tooltip inside the trigger, or control the Drawer with `open`/`onOpenChange` and open it from your own button.",y=`Drawer:unreachable`,b="Drawer has no way to open: a second after mounting it is still uncontrolled (no `open` prop), closed, and has no Drawer.Trigger as a direct child (or in a Fragment there). A Drawer.Trigger rendered by a component or nested in an element is panel content, which exists only while the drawer is open. Make the trigger a direct child of Drawer, or control the Drawer with `open`/`onOpenChange`.",x=1e3,S=e=>{let{open:t,requestOpen:n,trigger:i,panelId:a,inPanel:o}=h(`Drawer.Trigger`);return d.useEffect(()=>{o&&r.warnOnce(_,v)},[o]),u.useModalTriggerPart({open:t,requestOpen:n,trigger:i,controlsId:a},e,`Drawer.Trigger`)};S.displayName=`DrawerTrigger`;var C=e=>{let{requestOpen:t}=h(`Drawer.Close`);return u.useModalClosePart(t,e,`Drawer.Close`)};C.displayName=`DrawerClose`;var w=({id:e,className:n,children:r,ref:i,...o})=>{let{id:s,ref:c}=u.useModalTitle(`Drawer.Title`,`Drawer`,e,i);return(0,f.jsx)(`h2`,{...o,id:s,ref:c,className:t.cn(a.drawerTitleClassNames.root,`text-subtitle-1 font-semibold text-foreground`,n),children:r})};w.displayName=`DrawerTitle`;var T=32;function E(e){let t=(e,r,i)=>{if(i>T||typeof e!=`object`||!e)return!1;if(Array.isArray(e))return e.some(e=>t(e,r,i));if(!d.isValidElement(e))return!1;let a=n.getElementType(e,{suspend:!1});if(a===S)return r>0;let o=a===d.Fragment;if(typeof a!=`string`&&!o)return!1;let{children:s}=e.props;return t(s,o?r:r+1,i+1)};return t(e,0,0)}function re(e){let t=[],r=[];for(let{key:i,node:a}of n.flattenChildren(e)){let e=d.isValidElement(a)?d.cloneElement(a,{key:i}):a;n.isElementOfType(a,S)?t.push(e):r.push(e)}return{triggers:t,content:r}}var D=({open:e,defaultOpen:n,onOpenChange:m,position:h=`end`,title:S,closeLabel:C=`Close`,finalFocusRef:w,children:T,className:D,id:O,ref:k,...A})=>{let[j,M]=u.useModalOpenState(e,n,m),ie=c.useIsClient(),N=j&&ie,P=u.useModalTrigger(),F=o.useId(`wave-drawer`),I=O??F,L=o.useId(`wave-drawer-title`),R=u.useTitleRegistry(),[z,B]=d.useState(null),V=d.useRef(null),H=d.useCallback(e=>{V.current=e,B(e)},[]),U=s.useMergedRefs(k,H),W=u.useBackdropPress(V,!0),G=u.useModalDismiss(M,`Drawer`,W.afterOutsidePress),K=ne.useModalLayer({open:N,onDismiss:G,refs:[V],container:z,triggerRef:P.focusRef,finalFocusRef:w});u.useModalTriggerSession(P,N),u.useUnnamedModalWarning(N?z:null,R.hasTitle,`Drawer`,`Drawer.Title`);let{triggers:q,content:J}=re(T),Y=d.useRef(!1);d.useEffect(()=>{r.isDev&&!Y.current&&E(T)&&(Y.current=!0,r.warnOnce(_,v))},[T]);let X=e===void 0&&!n&&q.length===0,Z=d.useRef({unreachable:X,children:T});d.useLayoutEffect(()=>{Z.current={unreachable:X,children:T}}),d.useEffect(()=>{if(!r.isDev||!Z.current.unreachable)return;let e=setTimeout(()=>{let e=Z.current;e.unreachable&&!E(e.children)&&r.warnOnce(y,b)},x);return()=>clearTimeout(e)},[]);let Q=d.useMemo(()=>({open:N,requestOpen:M,trigger:P,panelId:I,inPanel:!1}),[N,M,P,I]),ae=d.useMemo(()=>({...Q,inPanel:!0}),[Q]),$=i.slotRendersContent(S);return(0,f.jsxs)(p.Provider,{value:Q,children:[q,N&&(0,f.jsx)(ee.Portal,{layerId:K.layerId,children:(0,f.jsx)(`div`,{className:t.cn(a.drawerClassNames.backdrop,`fixed inset-0 bg-backdrop`),onMouseDown:W.onMouseDown,children:(0,f.jsx)(`div`,{ref:U,role:`dialog`,id:I,"aria-labelledby":$?L:R.titleId,tabIndex:-1,...A,className:t.cn(a.drawerClassNames.root,`fixed top-0 flex h-full w-80 max-w-full flex-col border-border bg-background text-foreground shadow-64`,g[h],D),children:(0,f.jsx)(p.Provider,{value:ae,children:(0,f.jsxs)(u.ModalSurfaceContext.Provider,{value:R.context,children:[(0,f.jsxs)(`div`,{className:t.cn(a.drawerClassNames.header,`flex items-center justify-between gap-2 border-b border-border p-4`),children:[$&&(0,f.jsx)(`h2`,{id:L,className:t.cn(a.drawerTitleClassNames.root,`text-subtitle-1 font-semibold`),children:S}),(0,f.jsx)(te.Button,{appearance:`subtle`,size:`small`,icon:(0,f.jsx)(l.DismissIcon,{}),"aria-label":C,onClick:e=>M(!1,{reason:`close-button`,event:e.nativeEvent}),className:t.cn(a.drawerClassNames.closeButton,`ms-auto text-muted-foreground`)})]}),(0,f.jsx)(`div`,{className:t.cn(a.drawerClassNames.body,`min-h-0 flex-1 overflow-y-auto p-4`),children:J})]})})})})})]})};D.displayName=`Drawer`;var O=Object.assign(D,{Trigger:S,Close:C,Title:w});exports.Drawer=O,exports.DrawerClose=C,exports.DrawerTitle=w,exports.DrawerTrigger=S;
1
+ "use client";const e=require("./Drawer.parts.cjs"),t=require("./Drawer.root.cjs");var n=Object.assign(t.DrawerRoot,{Trigger:e.DrawerTrigger,Close:e.DrawerClose,Title:e.DrawerTitle,Header:e.DrawerHeader,HeaderTitle:e.DrawerHeaderTitle,HeaderNavigation:e.DrawerHeaderNavigation,Body:e.DrawerBody,Footer:e.DrawerFooter});exports.Drawer=n,exports.DrawerBody=e.DrawerBody,exports.DrawerClose=e.DrawerClose,exports.DrawerFooter=e.DrawerFooter,exports.DrawerHeader=e.DrawerHeader,exports.DrawerHeaderNavigation=e.DrawerHeaderNavigation,exports.DrawerHeaderTitle=e.DrawerHeaderTitle,exports.DrawerTitle=e.DrawerTitle,exports.DrawerTrigger=e.DrawerTrigger;
2
2
  //# sourceMappingURL=Drawer.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.cjs","names":["React","inertModalTrigger","useRequiredContext","useModalTriggerPart","useModalClosePart","useModalTitle","cn","drawerTitleClassNames","getElementType","flattenChildren","isElementOfType","useModalOpenState","useIsClient","useModalTrigger","useId","useTitleRegistry","useMergedRefs","useBackdropPress","useModalDismiss","useModalLayer","isDev","slotRendersContent","Portal","drawerClassNames","ModalSurfaceContext","Button","DismissIcon","require_runtime","require_cn","require_children","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","DrawerContext","inertDrawerContext","useDrawerContext","componentName","positionClasses","NESTED_TRIGGER_WARNING_KEY","NESTED_TRIGGER_WARNING","UNREACHABLE_WARNING_KEY","UNREACHABLE_WARNING","REACHABILITY_CHECK_DELAY","DrawerTrigger","inPanel","panelId","props","DrawerClose","requestOpen","DrawerTitle","rest","titleId","titleRef","id","ref","className","NESTED_TRIGGER_MAX_DEPTH","hasNestedTrigger","visit","level","node","item","depth","type","isFragment","nested","children","splitChildren","triggers","content","keyed","DrawerRoot","openProp","openState","defaultOpen","onOpenChange","isClient","open","trigger","generatedId","propTitleId","titles","panel","setPanel","panelRef","attachPanel","mergedRef","backdropPress","onDismiss","layer","nestedWarnedRef","unreachable","latestRef","timer","latest","context","panelContext","hasTitle","title","position","closeLabel","event","Drawer"],"sources":["../../../src/components/overlays/Drawer.tsx"],"sourcesContent":["import * as React from 'react';\nimport { flattenChildren, getElementType, isElementOfType } from '../../lib/children';\nimport { cn } from '../../lib/cn';\nimport { drawerClassNames, drawerTitleClassNames } from '../../lib/classNames';\nimport { isDev, warnOnce } from '../../lib/dev';\nimport { DismissIcon } from '../../lib/icons';\nimport { slotRendersContent } from '../../lib/slot';\nimport type { ModalOpenChangeReason, 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 ModalTrigger,\n} from './Dialog.shared';\n\n/**\n * Side of the screen the drawer is attached to. `start`/`end` follow the text direction (in a\n * right-to-left layout `end` is the left edge); `left`/`right` are physical sides.\n */\nexport type DrawerPosition = 'start' | 'end' | 'left' | 'right';\n\n/**\n * Why a {@link Drawer} asks to open or close: `trigger` (`Drawer.Trigger`), `close`\n * (`Drawer.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`, as for Dialog.\n */\nexport type DrawerOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a {@link Drawer}'s `onOpenChange`: the reason and the DOM event. */\nexport type DrawerOpenChangeDetails = OpenChangeDetails<DrawerOpenChangeReason>;\n\n/** Properties for the Drawer component. */\nexport interface DrawerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n /**\n * Controlled open state of the drawer. The panel renders only in the browser: an open drawer\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 panel renders only in the browser: a drawer\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 drawer 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 drawer stays as it is until the parent updates\n * `open`.\n */\n onOpenChange?: (open: boolean, details?: DrawerOpenChangeDetails) => void;\n /**\n * Side of the screen the drawer is attached to. `start`/`end` follow the text direction;\n * `left`/`right` are physical sides.\n * @default 'end'\n */\n position?: DrawerPosition;\n /**\n * Title displayed in the drawer header; it names the drawer (`aria-labelledby`). Without it,\n * render a `Drawer.Title` or pass `aria-label`/`aria-labelledby`. A title that renders nothing\n * (`''`, `[]`, `true`) counts as none.\n */\n title?: React.ReactNode;\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 /**\n * Where focus goes when the drawer closes, if it can take focus. Otherwise focus returns to the\n * element that had focus when the drawer opened, then to the trigger, then to an element next to\n * where that opener was.\n */\n finalFocusRef?: React.RefObject<HTMLElement | null>;\n /**\n * The drawer body. `Drawer.Trigger` children placed directly inside the Drawer, or in a Fragment\n * there (`{isMobile && <>…</>}`), render in place (outside the panel); everything else renders in\n * the panel's scrolling body. A `Drawer.Trigger` nested in another element, or rendered by a\n * component, is panel content, so it only exists while the drawer is open (development warnings\n * say so, also when an uncontrolled drawer still has no direct trigger a second after it mounts\n * and therefore cannot open; a controlled drawer whose trigger a component such as a Tooltip\n * wraps warns only once it opens).\n * Put wrappers inside the trigger instead: see `Drawer.Trigger`.\n */\n children: React.ReactNode;\n /** Ref to the drawer panel (`role=\"dialog\"`). */\n ref?: React.Ref<HTMLDivElement>;\n}\n\n/** Props a `Drawer.Trigger` puts on its element (and passes to a render-prop child). */\nexport interface DrawerTriggerRenderProps extends React.HTMLAttributes<HTMLElement> {\n 'aria-haspopup': 'dialog';\n 'aria-expanded': boolean;\n /** The panel's id, while the drawer 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 DrawerTrigger sub-component. */\nexport interface DrawerTriggerProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that opens the drawer. A single element receives the trigger props (merged with its\n * own); a function receives them.\n */\n children: React.ReactNode | ((props: DrawerTriggerRenderProps) => React.ReactNode);\n /**\n * `false` renders a wrapper `<span>` around the children instead of merging the trigger props\n * onto the child. The span carries the click handler; `aria-haspopup`, `aria-expanded` and\n * `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 `Drawer.Close` puts on its element (and passes to a render-prop child). */\nexport interface DrawerCloseRenderProps 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 DrawerClose sub-component. */\nexport interface DrawerCloseProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {\n /**\n * The element that closes the drawer. A single element receives an `onClick` composed with its own\n * (its handler runs first; `preventDefault()` keeps the drawer open); a function receives the\n * props.\n */\n children: React.ReactNode | ((props: DrawerCloseRenderProps) => React.ReactNode);\n /** `false` renders a wrapper `<span>` that closes the drawer 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\n/** Properties for the DrawerTitle sub-component. */\nexport interface DrawerTitleProps 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\ninterface DrawerContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n /** The panel's id (for the trigger's `aria-controls`). */\n panelId: string;\n /** `true` for sub-components rendered inside the panel (a `Drawer.Trigger` there is misplaced). */\n inPanel: boolean;\n}\n\nconst DrawerContext = React.createContext<DrawerContextValue | null>(null);\nDrawerContext.displayName = 'DrawerContext';\n\nconst inertDrawerContext: DrawerContextValue = {\n open: false,\n requestOpen: () => {},\n trigger: inertModalTrigger,\n panelId: '',\n inPanel: false,\n};\n\nfunction useDrawerContext(componentName: string): DrawerContextValue {\n return useRequiredContext(DrawerContext, componentName, 'Drawer', () => inertDrawerContext);\n}\n\n/**\n * The side the panel is pinned to, and a border on its inner edge (the one facing the page): it\n * marks the panel where the shadow cannot, in high contrast (page, backdrop and panel are black)\n * and in forced colors (which drop shadows).\n */\nconst positionClasses: Record<DrawerPosition, string> = {\n start: 'start-0 border-e',\n end: 'end-0 border-s',\n left: 'left-0 border-r', // wave-allow-physical: the consumer asked for the physical left edge\n right: 'right-0 border-l', // wave-allow-physical: the consumer asked for the physical right edge\n};\n\nconst NESTED_TRIGGER_WARNING_KEY = 'Drawer.Trigger:nested';\nconst NESTED_TRIGGER_WARNING =\n 'Drawer.Trigger must be a direct child of Drawer (a Fragment is fine). Inside another element or a component it is rendered as panel content, which exists only while the drawer is open, so it cannot open the drawer. Make it a direct child, put wrappers such as a Tooltip inside the trigger, or control the Drawer with `open`/`onOpenChange` and open it from your own button.';\n\nconst UNREACHABLE_WARNING_KEY = 'Drawer:unreachable';\nconst UNREACHABLE_WARNING =\n 'Drawer has no way to open: a second after mounting it is still uncontrolled (no `open` prop), closed, and has no Drawer.Trigger as a direct child (or in a Fragment there). A Drawer.Trigger rendered by a component or nested in an element is panel content, which exists only while the drawer is open. Make the trigger a direct child of Drawer, or control the Drawer with `open`/`onOpenChange`.';\n\n/**\n * How long after mount (ms) the development check for a drawer without a trigger waits: long\n * enough for a trigger that a conditional Fragment renders once the page knows its layout.\n */\nconst REACHABILITY_CHECK_DELAY = 1000;\n\n/**\n * Opens the drawer. Place it directly inside `Drawer`, or in a Fragment there (not inside a wrapper\n * element or a component of your own): it renders in place, not in the panel; a misplaced one warns\n * in development. A Drawer may have several triggers: focus returns to the one that opened it. Puts\n * `aria-haspopup=\"dialog\"`, `aria-expanded`, `aria-controls` (while open), a click handler and a\n * ref on its single child, or passes them to a render-prop child. A custom child component must\n * forward `ref` and spread its props; one that does not is wrapped in a `<span>` automatically\n * (with a development warning), the span that `asChild={false}` renders. Focus returns to the\n * trigger when the drawer closes. On the span, the state ARIA goes to the first element in the tab\n * order inside it, and focus returns to that element (to the span when you made it the trigger\n * with a `role` such as `button` and `tabIndex={0}`, or when nothing inside it can take focus).\n *\n * A Tooltip (or any other wrapper) goes inside the trigger, not around it. Use a render-prop child\n * so the trigger props land on the button and the Tooltip describes that same button:\n *\n * @example\n * <Drawer title=\"Filters\">\n * <Drawer.Trigger>\n * {(triggerProps) => (\n * <Tooltip content=\"Narrow the list\">\n * <Button {...triggerProps}>Filters</Button>\n * </Tooltip>\n * )}\n * </Drawer.Trigger>\n * <FilterForm />\n * </Drawer>\n */\nexport const DrawerTrigger = (props: DrawerTriggerProps) => {\n const { open, requestOpen, trigger, panelId, inPanel } = useDrawerContext('Drawer.Trigger');\n\n // Rendered inside its own drawer's panel (e.g. by a component): it only exists while open.\n React.useEffect(() => {\n if (inPanel) warnOnce(NESTED_TRIGGER_WARNING_KEY, NESTED_TRIGGER_WARNING);\n }, [inPanel]);\n\n return useModalTriggerPart<DrawerTriggerRenderProps>(\n { open, requestOpen, trigger, controlsId: panelId },\n props,\n 'Drawer.Trigger',\n );\n};\nDrawerTrigger.displayName = 'DrawerTrigger';\n\n/**\n * Closes the drawer: composes a click handler onto its single child (its own `onClick` runs first;\n * calling `preventDefault()` there keeps the drawer open), or passes it to a render-prop child.\n */\nexport const DrawerClose = (props: DrawerCloseProps) => {\n const { requestOpen } = useDrawerContext('Drawer.Close');\n return useModalClosePart<DrawerCloseRenderProps>(requestOpen, props, 'Drawer.Close');\n};\nDrawerClose.displayName = 'DrawerClose';\n\n/**\n * A heading that names the drawer (`aria-labelledby`), for rich titles or custom layouts. Render it\n * inside the Drawer's content (instead of the `title` prop).\n */\nexport const DrawerTitle = ({ id, className, children, ref, ...rest }: DrawerTitleProps) => {\n const { id: titleId, ref: titleRef } = useModalTitle('Drawer.Title', 'Drawer', id, ref);\n return (\n <h2\n {...rest}\n id={titleId}\n ref={titleRef}\n className={cn(\n drawerTitleClassNames.root,\n 'text-subtitle-1 font-semibold text-foreground',\n className,\n )}\n >\n {children}\n </h2>\n );\n};\nDrawerTitle.displayName = 'DrawerTitle';\n\n/** Deepest element level the development check for nested triggers looks at. */\nconst NESTED_TRIGGER_MAX_DEPTH = 32;\n\n/**\n * Development check: whether the Drawer's children hold a `Drawer.Trigger` inside a host element\n * (at any depth, also through Fragments), which would become panel content; a trigger inside\n * Fragments only is direct (see `splitChildren`). Walks the element tree the consumer wrote, not\n * rendered output, so it descends only into host elements (`<div>`, `<span>`, …) and Fragments,\n * which render their `children` as written. A component's\n * output is unknown here — a wrapper that renders its own Drawer around its children, for one —\n * so components are not walked; a trigger rendered by a component is caught when it renders in the\n * open panel, or, while the drawer cannot open, by the unreachable-drawer check.\n */\nfunction hasNestedTrigger(children: React.ReactNode): boolean {\n // `depth` counts host elements only: a Fragment adds no level, as `splitChildren` flattens it.\n const visit = (node: unknown, depth: number, level: number): boolean => {\n if (level > NESTED_TRIGGER_MAX_DEPTH || typeof node !== 'object' || node === null) return false;\n if (Array.isArray(node)) return node.some((item) => visit(item, depth, level));\n if (!React.isValidElement(node)) return false;\n // A part written in a Server Component has a lazy type. The walk runs in effects, outside\n // render: a lazy part that is still loading must not throw its thenable there, so it counts\n // as no trigger (`suspend: false` returns the lazy itself, which matches nothing).\n const type = getElementType(node, { suspend: false });\n if (type === DrawerTrigger) return depth > 0;\n const isFragment = type === React.Fragment;\n if (typeof type !== 'string' && !isFragment) return false;\n const { children: nested } = node.props as { children?: unknown };\n return visit(nested, isFragment ? depth : depth + 1, level + 1);\n };\n return visit(children, 0, 0);\n}\n\n/**\n * Splits the Drawer's children into its direct `Drawer.Trigger` elements and the panel content.\n * Fragments are flattened (recursively), so a `Drawer.Trigger` in a Fragment —\n * `{isMobile && <><Drawer.Trigger>…</Drawer.Trigger><Filters /></>}` — counts as a direct child.\n * Every element keeps the key `flattenChildren` gives it: unique across Fragments and stable when a\n * sibling Fragment toggles, so panel content keeps its state. A trigger is recognised also when it\n * was written in a Server Component (a lazy type).\n */\nfunction splitChildren(children: React.ReactNode): {\n triggers: React.ReactNode[];\n content: React.ReactNode[];\n} {\n const triggers: React.ReactNode[] = [];\n const content: React.ReactNode[] = [];\n for (const { key, node } of flattenChildren(children)) {\n const keyed = React.isValidElement(node) ? React.cloneElement(node, { key }) : node;\n if (isElementOfType(node, DrawerTrigger)) triggers.push(keyed);\n else content.push(keyed);\n }\n return { triggers, content };\n}\n\n// The root of `Drawer` (documented on the export below).\nconst DrawerRoot = ({\n open: openProp,\n defaultOpen,\n onOpenChange,\n position = 'end',\n title,\n closeLabel = 'Close',\n finalFocusRef,\n children,\n className,\n id,\n ref,\n ...rest\n}: DrawerProps) => {\n const [openState, requestOpen] = useModalOpenState(openProp, defaultOpen, onOpenChange);\n // The panel lives in a portal, which renders only in the browser: until then (the server HTML,\n // hydration) the drawer reports itself closed, so the trigger's aria-expanded and aria-controls\n // never describe a panel that is not there.\n const isClient = useIsClient();\n const open = openState && isClient;\n const trigger = useModalTrigger();\n const generatedId = useId('wave-drawer');\n const panelId = id ?? generatedId;\n const propTitleId = useId('wave-drawer-title');\n const titles = useTitleRegistry();\n\n const [panel, setPanel] = React.useState<HTMLDivElement | null>(null);\n const panelRef = React.useRef<HTMLDivElement | null>(null);\n const attachPanel = React.useCallback((node: HTMLDivElement | null) => {\n panelRef.current = node;\n setPanel(node);\n }, []);\n const mergedRef = useMergedRefs<HTMLDivElement>(ref, attachPanel);\n\n // Every backdrop press asks the drawer to close.\n const backdropPress = useBackdropPress(panelRef, true);\n const onDismiss = useModalDismiss(requestOpen, 'Drawer', backdropPress.afterOutsidePress);\n const layer = useModalLayer({\n open,\n onDismiss,\n refs: [panelRef],\n container: panel,\n triggerRef: trigger.focusRef,\n finalFocusRef,\n });\n // After useModalLayer's focus restore (effects run in order), start the trigger session, or end\n // it and forget the trigger that opened it.\n useModalTriggerSession(trigger, open);\n useUnnamedModalWarning(open ? panel : null, titles.hasTitle, 'Drawer', 'Drawer.Title');\n\n const { triggers, content } = splitChildren(children);\n\n // A trigger nested in the children is panel content: never rendered while the drawer is closed.\n // The children change on every parent render; once this drawer has warned, it stops walking.\n const nestedWarnedRef = React.useRef(false);\n React.useEffect(() => {\n if (!isDev || nestedWarnedRef.current || !hasNestedTrigger(children)) return;\n nestedWarnedRef.current = true;\n warnOnce(NESTED_TRIGGER_WARNING_KEY, NESTED_TRIGGER_WARNING);\n }, [children]);\n\n // An uncontrolled closed drawer without a direct trigger cannot open (e.g.\n // `<Drawer><FilterTrigger /></Drawer>`, whose trigger is panel content). Checked once, a moment\n // after mount, against the latest render: a trigger that a conditional Fragment adds right after\n // mount (`{isMobile && <>…</>}` with an SSR-safe media query) counts. A trigger nested in an\n // element already has the more specific warning above.\n const unreachable = openProp === undefined && !defaultOpen && triggers.length === 0;\n const latestRef = React.useRef({ unreachable, children });\n React.useLayoutEffect(() => {\n latestRef.current = { unreachable, children };\n });\n React.useEffect(() => {\n if (!isDev || !latestRef.current.unreachable) return;\n const timer = setTimeout(() => {\n const latest = latestRef.current;\n if (latest.unreachable && !hasNestedTrigger(latest.children)) {\n warnOnce(UNREACHABLE_WARNING_KEY, UNREACHABLE_WARNING);\n }\n }, REACHABILITY_CHECK_DELAY);\n return () => clearTimeout(timer);\n }, []);\n\n const context = React.useMemo<DrawerContextValue>(\n () => ({ open, requestOpen, trigger, panelId, inPanel: false }),\n [open, requestOpen, trigger, panelId],\n );\n const panelContext = React.useMemo<DrawerContextValue>(\n () => ({ ...context, inPanel: true }),\n [context],\n );\n\n const hasTitle = slotRendersContent(title);\n\n return (\n <DrawerContext.Provider value={context}>\n {triggers}\n {open && (\n <Portal layerId={layer.layerId}>\n <div\n className={cn(drawerClassNames.backdrop, 'fixed inset-0 bg-backdrop')}\n onMouseDown={backdropPress.onMouseDown}\n >\n <div\n ref={mergedRef}\n role=\"dialog\"\n id={panelId}\n aria-labelledby={hasTitle ? propTitleId : titles.titleId}\n tabIndex={-1}\n {...rest}\n className={cn(\n drawerClassNames.root,\n 'fixed top-0 flex h-full w-80 max-w-full flex-col border-border bg-background text-foreground shadow-64',\n positionClasses[position],\n className,\n )}\n >\n <DrawerContext.Provider value={panelContext}>\n <ModalSurfaceContext.Provider value={titles.context}>\n <div\n className={cn(\n drawerClassNames.header,\n 'flex items-center justify-between gap-2 border-b border-border p-4',\n )}\n >\n {hasTitle && (\n <h2\n id={propTitleId}\n className={cn(drawerTitleClassNames.root, '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(drawerClassNames.closeButton, 'ms-auto text-muted-foreground')}\n />\n </div>\n <div className={cn(drawerClassNames.body, 'min-h-0 flex-1 overflow-y-auto p-4')}>\n {content}\n </div>\n </ModalSurfaceContext.Provider>\n </DrawerContext.Provider>\n </div>\n </div>\n </Portal>\n )}\n </DrawerContext.Provider>\n );\n};\nDrawerRoot.displayName = 'Drawer';\n\n/**\n * A modal panel attached to a side of the screen (Fluent UI v2 style), rendered in a portal\n * (inheriting the WaveProvider theme) while open.\n *\n * - **Opening**: controlled (`open`), or uncontrolled with a `Drawer.Trigger` placed directly inside\n * the Drawer or in a Fragment there (it renders in place, outside the panel).\n * - **Modal**: focus moves into the panel and Tab stays inside it (toasts included), the rest of the\n * page is `inert` (instead of `aria-modal`), and the page does not scroll.\n * - **Closing**: Escape (only the topmost layer: a popup opened inside closes first), a click on the\n * backdrop (a drag that starts inside does not close it), the Close button and `Drawer.Close`.\n * `onOpenChange` gets the reason as its second argument (`details.reason`), so a controlled\n * drawer can refuse some of them. A backdrop press blurs the focused field before the drawer\n * closes, so a typed value is committed as with the Close button; when a controlled drawer\n * refuses the press, the field gets focus back. Focus returns to the first of these that can\n * take focus: `finalFocusRef`, the element that had focus when the drawer opened, the trigger,\n * an element next to where that opener was.\n * - **Position**: `end` (default) and `start` follow the text direction.\n *\n * The sub-components are also exported under flat names (`DrawerTrigger`, `DrawerClose`,\n * `DrawerTitle`) for React Server Components, which cannot use the dotted form; dotted access\n * (`Drawer.Trigger`) needs a client file.\n *\n * @example\n * <Drawer title=\"Filters\">\n * <Drawer.Trigger><Button>Filters</Button></Drawer.Trigger>\n * <FilterForm />\n * <Drawer.Close><Button appearance=\"primary\">Apply</Button></Drawer.Close>\n * </Drawer>\n */\nexport const Drawer = /* @__PURE__ */ Object.assign(DrawerRoot, {\n Trigger: DrawerTrigger,\n Close: DrawerClose,\n Title: DrawerTitle,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Drawer.cjs","names":["DrawerRoot","DrawerTrigger","DrawerClose","DrawerTitle","DrawerHeader","DrawerHeaderTitle","DrawerHeaderNavigation","DrawerBody","DrawerFooter","require_Drawer_parts","require_Drawer_root","Drawer"],"sources":["../../../src/components/overlays/Drawer.tsx"],"sourcesContent":["import {\n DrawerBody,\n DrawerClose,\n DrawerFooter,\n DrawerHeader,\n DrawerHeaderNavigation,\n DrawerHeaderTitle,\n DrawerTitle,\n DrawerTrigger,\n} from './Drawer.parts';\nimport { DrawerRoot } from './Drawer.root';\n\nexport type {\n DrawerPosition,\n DrawerSize,\n DrawerType,\n DrawerModalType,\n DrawerOpenChangeReason,\n DrawerOpenChangeDetails,\n} from './Drawer.context';\nexport type { DrawerProps } from './Drawer.root';\nexport type {\n DrawerTriggerProps,\n DrawerTriggerRenderProps,\n DrawerCloseProps,\n DrawerCloseRenderProps,\n DrawerTitleProps,\n DrawerHeaderProps,\n DrawerHeaderTitleProps,\n DrawerHeaderNavigationProps,\n DrawerBodyProps,\n DrawerFooterProps,\n} from './Drawer.parts';\n\n/**\n * A side or bottom panel (Fluent UI v2 style): by default an overlay, modal unless it is\n * non-modal, rendered in a portal (inheriting the WaveProvider theme) while open; with\n * `type=\"inline\"` a panel in the page layout, rendered in place. With `unmountOnClose={false}`\n * either kind stays mounted while closed, `hidden` and `inert`.\n *\n * - **Opening**: controlled (`open`), or uncontrolled with a `Drawer.Trigger` placed directly inside\n * the Drawer or in a Fragment there (it renders in place, outside the panel); the trigger opens\n * and closes it.\n * - **Modal**: focus moves into the panel and Tab stays inside it (toasts included), the rest of the\n * page is `inert` (instead of `aria-modal`), and the page does not scroll. `modalType=\"alert\"`\n * renders `role=\"alertdialog\"`, and a backdrop press does not close it.\n * - **Non-modal**: `modalType=\"non-modal\"` leaves the page usable (no backdrop, no focus trap,\n * nothing inert, the page scrolls). Focus moves in on open; Tab and Shift+Tab leave the panel in\n * the page's order right after the element that opened it; Escape closes it only while focus is\n * inside it; presses on the page never close it; focus returns to the opener only from inside.\n * Reserve the panel's room in the page layout while it is open, so it hides no page control.\n * - **Inline**: `type=\"inline\"` renders the panel where the Drawer is, after its direct triggers,\n * as an `<aside>` (a complementary landmark named by its title), also in the server HTML. It is\n * page content: no portal, backdrop, focus trap, inert page or scroll lock, and toasts keep\n * their corner next to it. Its trigger toggles it (with `aria-expanded` and `aria-controls`, no\n * `aria-haspopup`); opening it moves no focus; Escape and presses outside never close it;\n * closing it returns focus only when focus was inside. `position` picks its inner edge and\n * `size` its width (its height at the bottom); `separator` draws the inner edge. Place it in\n * your layout, for example a flex row of the panel and the page content. Changing `type`\n * remounts the panel and its content.\n * - **Closing**: Escape (only the topmost layer: a popup opened inside closes first), a click on the\n * backdrop (a drag that starts inside does not close it), the Close button and `Drawer.Close`\n * (an inline drawer: the trigger, the Close button and `Drawer.Close`).\n * `onOpenChange` gets the reason as its second argument (`details.reason`), so a controlled\n * drawer can refuse some of them. A backdrop press blurs the focused field before the drawer\n * closes, so a typed value is committed as with the Close button; when a controlled drawer\n * refuses the press, the field gets focus back. Focus returns to the first of these that can\n * take focus: `finalFocusRef`, the element that had focus when the drawer opened, the trigger,\n * an element next to where that opener was.\n * - **Size and position**: `position` is `end` (default) or `start`, which follow the text\n * direction, `left` or `right`, or `bottom` (along the bottom edge, the window wide). `size` sets\n * the width at a side and the height at the bottom: `small` (default, 320px), `medium` (592px),\n * `large` (940px) or `full`; the panel never grows past the window (an inline one past its\n * container). A width class in `className` (a height class for `bottom`) replaces the size. An\n * overlay panel pads the safe-area insets of the screen edges it touches (the iOS home\n * indicator, once the page sets `viewport-fit=cover`). Both render as `data-position` and\n * `data-size`, next to `data-type`.\n * - **Layout**: the `title` prop and the built-in Close button make the header row; a\n * `Drawer.Header` replaces it, with a `Drawer.HeaderNavigation` row (a Back button, commands)\n * and a `Drawer.HeaderTitle` (the heading, an `action` area and the Close button). The rest of\n * the content scrolls in the body (`Drawer.Body` gives it your props); a `Drawer.Footer` is an\n * action row below the body that never scrolls. Make the parts direct children of the Drawer (a\n * Fragment there is fine). The header draws a line under itself once the body is scrolled, the\n * footer one above itself while content continues below: the body, the header and the footer\n * render the body's scroll state as `data-scroll-state` (`none`, `top`, `middle`, `bottom`).\n * - **Backdrop, Close button and title actions**: the backdrop is the panel's sibling and a slot\n * (`backdrop`: `null` removes it, `appearance` picks `dimmed` or `transparent`); a modal opened\n * over another modal dims the page once. `closeButton` sets the content of every built-in Close\n * button, or hides them (`null`); a button passed there is merged into it. `titleAction` places\n * header buttons between the `title` heading and the Close button.\n * - **Kept mounted**: `unmountOnClose={false}` keeps the panel and its content mounted while the\n * drawer is closed, so a form keeps what was typed and the components inside keep their state;\n * each open of an overlay focuses the first focusable element again (an `autoFocus` inside never\n * applies), and a kept overlay opened while another overlay is open stacks above it. A kept\n * inline drawer is in the server HTML, hidden.\n * - **Presence**: the panel and the backdrop mount through the presence core and render\n * `data-presence` (`entered` while open, `exited` while kept closed); the backdrop and the\n * panel (an inline drawer's `<aside>`) are `inert` while exiting and `hidden` and `inert` while\n * kept closed. No motion ships:\n * `data-[presence=…]:` classes in `className` animate the panel, whose motion a closed drawer\n * waits for before it unmounts or hides (focus, the trap and the isolation follow the open\n * state at once).\n *\n * The sub-components are also exported under flat names (`DrawerTrigger`, `DrawerClose`,\n * `DrawerTitle`, `DrawerHeader`, `DrawerHeaderTitle`, `DrawerHeaderNavigation`, `DrawerBody`,\n * `DrawerFooter`) for React Server Components, which cannot use the dotted form; dotted access\n * (`Drawer.Trigger`) needs a client file.\n *\n * @example\n * <Drawer>\n * <Drawer.Trigger><Button>Filters</Button></Drawer.Trigger>\n * <Drawer.Header>\n * <Drawer.HeaderTitle>Filters</Drawer.HeaderTitle>\n * </Drawer.Header>\n * <FilterForm id=\"filters\" />\n * <Drawer.Footer>\n * <Button appearance=\"primary\" type=\"submit\" form=\"filters\">Apply</Button>\n * <Drawer.Close><Button>Cancel</Button></Drawer.Close>\n * </Drawer.Footer>\n * </Drawer>\n */\nexport const Drawer = /* @__PURE__ */ Object.assign(DrawerRoot, {\n Trigger: DrawerTrigger,\n Close: DrawerClose,\n Title: DrawerTitle,\n Header: DrawerHeader,\n HeaderTitle: DrawerHeaderTitle,\n HeaderNavigation: DrawerHeaderNavigation,\n Body: DrawerBody,\n Footer: DrawerFooter,\n});\n\nexport {\n DrawerTrigger,\n DrawerClose,\n DrawerTitle,\n DrawerHeader,\n DrawerHeaderTitle,\n DrawerHeaderNavigation,\n DrawerBody,\n DrawerFooter,\n};\n"],"mappings":"kFAyHA,IAAaW,EAAyB,OAAO,OAAOX,EAAAA,WAAY,CAC9D,QAASC,EAAAA,cACT,MAAOC,EAAAA,YACP,MAAOC,EAAAA,YACP,OAAQC,EAAAA,aACR,YAAaC,EAAAA,kBACb,iBAAkBC,EAAAA,uBAClB,KAAMC,EAAAA,WACN,OAAQC,EAAAA,YACV,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use client";const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("./Dialog.shared.cjs");let n=require("react");n=e.__toESM(n,1);var r=n.createContext(null);r.displayName=`DrawerContext`;var i={open:!1,requestOpen:()=>{},trigger:t.inertModalTrigger,panelId:``,type:`overlay`,inPanel:!1,closeLabel:`Close`,closeButton:void 0};function a(e){return t.useRequiredContext(r,e,`Drawer`,()=>i)}var o=n.createContext(null);o.displayName=`DrawerPartContext`;var s=n.createContext(!1);s.displayName=`DrawerHeaderContext`;var c=n.createContext(null);c.displayName=`DrawerScrollStateContext`,exports.DrawerContext=r,exports.DrawerHeaderContext=s,exports.DrawerPartContext=o,exports.DrawerScrollStateContext=c,exports.useDrawerContext=a;
2
+ //# sourceMappingURL=Drawer.context.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.context.cjs","names":["React","inertModalTrigger","useRequiredContext","require_runtime","require_Dialog_shared","react","DrawerContext","inertDrawerContext","useDrawerContext","componentName","DrawerPartContext","DrawerHeaderContext","DrawerScrollStateContext"],"sources":["../../../src/components/overlays/Drawer.context.ts"],"sourcesContent":["import * as React from 'react';\nimport type { Slot } from '../../lib/slot';\nimport type {\n ModalOpenChangeReason,\n ModalType,\n OpenChangeDetails,\n SurfaceSize,\n} from '../../lib/types';\nimport {\n inertModalTrigger,\n useRequiredContext,\n type ModalRequestOpen,\n type ModalTrigger,\n} from './Dialog.shared';\nimport type { DrawerScrollState } from './Drawer.scroll';\n\n/*\n * The Drawer's public types and its contexts. Imports no component: the root, the parts and the\n * panel modules read it, never the reverse.\n */\n\n/**\n * Side of the screen the drawer is attached to. `start`/`end` follow the text direction (in a\n * right-to-left layout `end` is the left edge); `left`/`right` are physical sides; `bottom` runs\n * along the bottom edge, as wide as the viewport. An inline drawer sits where the page layout puts\n * it: the position picks its inner edge (the one facing the page content) and its size's axis.\n */\nexport type DrawerPosition = 'start' | 'end' | 'left' | 'right' | 'bottom';\n\n/**\n * How much room a Drawer takes: its width at a side, its height at the bottom. `small` 320px,\n * `medium` 592px, `large` 940px; `full` the viewport (an inline drawer: its container). The shared\n * `SurfaceSize`.\n */\nexport type DrawerSize = SurfaceSize;\n\n/**\n * How a Drawer sits on the page: `overlay`, a panel over the page (in a portal), or `inline`, a\n * panel in the page layout, rendered where the Drawer is. Fluent's `type`.\n */\nexport type DrawerType = 'overlay' | 'inline';\n\n/**\n * How a `Drawer` relates to the page: `modal`, `alert` or `non-modal` (the shared `ModalType`;\n * `DialogModalType` is the same type).\n */\nexport type DrawerModalType = ModalType;\n\n/**\n * Why a `Drawer` asks to open or close: `trigger` (`Drawer.Trigger`), `close`\n * (`Drawer.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`, as for Dialog.\n */\nexport type DrawerOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a `Drawer`'s `onOpenChange`: the reason and the DOM event. */\nexport type DrawerOpenChangeDetails = OpenChangeDetails<DrawerOpenChangeReason>;\n\n/** What the Drawer root provides to its parts. */\nexport interface DrawerContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n /** The panel's id (for the trigger's `aria-controls`). */\n panelId: string;\n /** The drawer's `type`: the trigger of an inline drawer renders no `aria-haspopup`. */\n type: DrawerType;\n /** `true` for sub-components rendered inside the panel (a `Drawer.Trigger` there is misplaced). */\n inPanel: boolean;\n /** The accessible name of the built-in Close button (the Drawer's `closeLabel`). */\n closeLabel: string;\n /** The content of every built-in Close button (the Drawer's `closeButton`; `null` hides them). */\n closeButton: Slot<'span'> | undefined;\n}\n\n/** Provided by the Drawer root (`inPanel: false`) and again inside its panel (`inPanel: true`). */\nexport const DrawerContext = React.createContext<DrawerContextValue | null>(null);\nDrawerContext.displayName = 'DrawerContext';\n\n/** What a part reads outside a Drawer in production (C-CONTEXT): closed, requests ignored. */\nconst inertDrawerContext: DrawerContextValue = {\n open: false,\n requestOpen: () => {},\n trigger: inertModalTrigger,\n panelId: '',\n type: 'overlay',\n inPanel: false,\n closeLabel: 'Close',\n closeButton: undefined,\n};\n\n/**\n * C-CONTEXT: the enclosing Drawer's context. Outside a Drawer it throws\n * `[WaveUI] <componentName> must be used within Drawer` in development; in production it logs once\n * and returns an inert value.\n */\nexport function useDrawerContext(componentName: string): DrawerContextValue {\n return useRequiredContext(DrawerContext, componentName, 'Drawer', () => inertDrawerContext);\n}\n\n/**\n * Where the Drawer put a layout part (`Drawer.Header`, `Drawer.Body`, `Drawer.Footer`): `'placed'`\n * around the parts its scan of its direct children placed in the header area or after the body,\n * `'content'` around the body content. Every part provides `'content'` to its own children, so a\n * part nested in another part, in an element or in a component of yours reads `'content'`: it\n * renders where it is and warns. `null` outside a Drawer's panel (read as `'content'`).\n */\nexport type DrawerPartPlacement = 'placed' | 'content';\n\n/** See {@link DrawerPartPlacement}. */\nexport const DrawerPartContext = React.createContext<DrawerPartPlacement | null>(null);\nDrawerPartContext.displayName = 'DrawerPartContext';\n\n/**\n * `true` inside a `Drawer.Header` (which provides it to its children), so a `Drawer.HeaderTitle`\n * there ends with the built-in Close button. The panel provides `false`, so a Drawer opened from a\n * header does not inherit it.\n */\nexport const DrawerHeaderContext = React.createContext(false);\nDrawerHeaderContext.displayName = 'DrawerHeaderContext';\n\n/**\n * The scroll state of the panel's scrolling body, which the built-in header, `Drawer.Header` and\n * `Drawer.Footer` render as `data-scroll-state` to draw their separators. `null` outside a\n * Drawer's panel (read as `'none'`).\n */\nexport const DrawerScrollStateContext = React.createContext<DrawerScrollState | null>(null);\nDrawerScrollStateContext.displayName = 'DrawerScrollStateContext';\n"],"mappings":"8IA8EA,IAAaM,EAAgBN,EAAM,cAAyC,IAAI,EAChF,EAAc,YAAc,gBAG5B,IAAMO,EAAyC,CAC7C,KAAM,GACN,gBAAmB,CAAC,EACpB,QAASN,EAAAA,kBACT,QAAS,GACT,KAAM,UACN,QAAS,GACT,WAAY,QACZ,YAAa,IAAA,EACf,EAOA,SAAgBO,EAAiB,EAA2C,CAC1E,OAAON,EAAAA,mBAAmBI,EAAeG,EAAe,aAAgBF,CAAkB,CAC5F,CAYA,IAAaG,EAAoBV,EAAM,cAA0C,IAAI,EACrF,EAAkB,YAAc,oBAOhC,IAAaW,EAAsBX,EAAM,cAAc,EAAK,EAC5D,EAAoB,YAAc,sBAOlC,IAAaY,EAA2BZ,EAAM,cAAwC,IAAI,EAC1F,EAAyB,YAAc"}
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { inertModalTrigger as e, useRequiredContext as t } from "./Dialog.shared.mjs";
3
+ import * as n from "react";
4
+ //#region src/components/overlays/Drawer.context.ts
5
+ var r = n.createContext(null);
6
+ r.displayName = "DrawerContext";
7
+ var i = {
8
+ open: !1,
9
+ requestOpen: () => {},
10
+ trigger: e,
11
+ panelId: "",
12
+ type: "overlay",
13
+ inPanel: !1,
14
+ closeLabel: "Close",
15
+ closeButton: void 0
16
+ };
17
+ function a(e) {
18
+ return t(r, e, "Drawer", () => i);
19
+ }
20
+ var o = n.createContext(null);
21
+ o.displayName = "DrawerPartContext";
22
+ var s = n.createContext(!1);
23
+ s.displayName = "DrawerHeaderContext";
24
+ var c = n.createContext(null);
25
+ c.displayName = "DrawerScrollStateContext";
26
+ //#endregion
27
+ export { r as DrawerContext, s as DrawerHeaderContext, o as DrawerPartContext, c as DrawerScrollStateContext, a as useDrawerContext };
28
+
29
+ //# sourceMappingURL=Drawer.context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Drawer.context.mjs","names":["React","DrawerContext","inertDrawerContext","inertModalTrigger","useDrawerContext","useRequiredContext","componentName","DrawerPartContext","DrawerHeaderContext","DrawerScrollStateContext"],"sources":["../../../src/components/overlays/Drawer.context.ts"],"sourcesContent":["import * as React from 'react';\nimport type { Slot } from '../../lib/slot';\nimport type {\n ModalOpenChangeReason,\n ModalType,\n OpenChangeDetails,\n SurfaceSize,\n} from '../../lib/types';\nimport {\n inertModalTrigger,\n useRequiredContext,\n type ModalRequestOpen,\n type ModalTrigger,\n} from './Dialog.shared';\nimport type { DrawerScrollState } from './Drawer.scroll';\n\n/*\n * The Drawer's public types and its contexts. Imports no component: the root, the parts and the\n * panel modules read it, never the reverse.\n */\n\n/**\n * Side of the screen the drawer is attached to. `start`/`end` follow the text direction (in a\n * right-to-left layout `end` is the left edge); `left`/`right` are physical sides; `bottom` runs\n * along the bottom edge, as wide as the viewport. An inline drawer sits where the page layout puts\n * it: the position picks its inner edge (the one facing the page content) and its size's axis.\n */\nexport type DrawerPosition = 'start' | 'end' | 'left' | 'right' | 'bottom';\n\n/**\n * How much room a Drawer takes: its width at a side, its height at the bottom. `small` 320px,\n * `medium` 592px, `large` 940px; `full` the viewport (an inline drawer: its container). The shared\n * `SurfaceSize`.\n */\nexport type DrawerSize = SurfaceSize;\n\n/**\n * How a Drawer sits on the page: `overlay`, a panel over the page (in a portal), or `inline`, a\n * panel in the page layout, rendered where the Drawer is. Fluent's `type`.\n */\nexport type DrawerType = 'overlay' | 'inline';\n\n/**\n * How a `Drawer` relates to the page: `modal`, `alert` or `non-modal` (the shared `ModalType`;\n * `DialogModalType` is the same type).\n */\nexport type DrawerModalType = ModalType;\n\n/**\n * Why a `Drawer` asks to open or close: `trigger` (`Drawer.Trigger`), `close`\n * (`Drawer.Close`), `close-button` (the built-in Close button), `escape`, `outside-press` (the\n * backdrop). The shared `ModalOpenChangeReason`, as for Dialog.\n */\nexport type DrawerOpenChangeReason = ModalOpenChangeReason;\n\n/** The second argument of a `Drawer`'s `onOpenChange`: the reason and the DOM event. */\nexport type DrawerOpenChangeDetails = OpenChangeDetails<DrawerOpenChangeReason>;\n\n/** What the Drawer root provides to its parts. */\nexport interface DrawerContextValue {\n open: boolean;\n /** Asks the root to open or close, with the reason and event for `onOpenChange`. */\n requestOpen: ModalRequestOpen;\n /** The trigger element (`attach`) and the focus-restore target resolved from it (`focusRef`). */\n trigger: ModalTrigger;\n /** The panel's id (for the trigger's `aria-controls`). */\n panelId: string;\n /** The drawer's `type`: the trigger of an inline drawer renders no `aria-haspopup`. */\n type: DrawerType;\n /** `true` for sub-components rendered inside the panel (a `Drawer.Trigger` there is misplaced). */\n inPanel: boolean;\n /** The accessible name of the built-in Close button (the Drawer's `closeLabel`). */\n closeLabel: string;\n /** The content of every built-in Close button (the Drawer's `closeButton`; `null` hides them). */\n closeButton: Slot<'span'> | undefined;\n}\n\n/** Provided by the Drawer root (`inPanel: false`) and again inside its panel (`inPanel: true`). */\nexport const DrawerContext = React.createContext<DrawerContextValue | null>(null);\nDrawerContext.displayName = 'DrawerContext';\n\n/** What a part reads outside a Drawer in production (C-CONTEXT): closed, requests ignored. */\nconst inertDrawerContext: DrawerContextValue = {\n open: false,\n requestOpen: () => {},\n trigger: inertModalTrigger,\n panelId: '',\n type: 'overlay',\n inPanel: false,\n closeLabel: 'Close',\n closeButton: undefined,\n};\n\n/**\n * C-CONTEXT: the enclosing Drawer's context. Outside a Drawer it throws\n * `[WaveUI] <componentName> must be used within Drawer` in development; in production it logs once\n * and returns an inert value.\n */\nexport function useDrawerContext(componentName: string): DrawerContextValue {\n return useRequiredContext(DrawerContext, componentName, 'Drawer', () => inertDrawerContext);\n}\n\n/**\n * Where the Drawer put a layout part (`Drawer.Header`, `Drawer.Body`, `Drawer.Footer`): `'placed'`\n * around the parts its scan of its direct children placed in the header area or after the body,\n * `'content'` around the body content. Every part provides `'content'` to its own children, so a\n * part nested in another part, in an element or in a component of yours reads `'content'`: it\n * renders where it is and warns. `null` outside a Drawer's panel (read as `'content'`).\n */\nexport type DrawerPartPlacement = 'placed' | 'content';\n\n/** See {@link DrawerPartPlacement}. */\nexport const DrawerPartContext = React.createContext<DrawerPartPlacement | null>(null);\nDrawerPartContext.displayName = 'DrawerPartContext';\n\n/**\n * `true` inside a `Drawer.Header` (which provides it to its children), so a `Drawer.HeaderTitle`\n * there ends with the built-in Close button. The panel provides `false`, so a Drawer opened from a\n * header does not inherit it.\n */\nexport const DrawerHeaderContext = React.createContext(false);\nDrawerHeaderContext.displayName = 'DrawerHeaderContext';\n\n/**\n * The scroll state of the panel's scrolling body, which the built-in header, `Drawer.Header` and\n * `Drawer.Footer` render as `data-scroll-state` to draw their separators. `null` outside a\n * Drawer's panel (read as `'none'`).\n */\nexport const DrawerScrollStateContext = React.createContext<DrawerScrollState | null>(null);\nDrawerScrollStateContext.displayName = 'DrawerScrollStateContext';\n"],"mappings":";;;;AA8EA,IAAaC,IAAgBD,EAAM,cAAyC,IAAI;AAChF,EAAc,cAAc;AAG5B,IAAME,IAAyC;CAC7C,MAAM;CACN,mBAAmB,CAAC;CACpB,SAASC;CACT,SAAS;CACT,MAAM;CACN,SAAS;CACT,YAAY;CACZ,aAAa,KAAA;AACf;AAOA,SAAgBC,EAAiB,GAA2C;CAC1E,OAAOC,EAAmBJ,GAAeK,GAAe,gBAAgBJ,CAAkB;AAC5F;AAYA,IAAaK,IAAoBP,EAAM,cAA0C,IAAI;AACrF,EAAkB,cAAc;AAOhC,IAAaQ,IAAsBR,EAAM,cAAc,EAAK;AAC5D,EAAoB,cAAc;AAOlC,IAAaS,IAA2BT,EAAM,cAAwC,IAAI;AAC1F,EAAyB,cAAc"}
@@ -1,193 +1,18 @@
1
1
  "use client";
2
- import { cn as e } from "../../lib/cn.mjs";
3
- import { flattenChildren as t, getElementType as n, isElementOfType as r } from "../../lib/children.mjs";
4
- import { isDev as i, warnOnce as a } from "../../lib/dev.mjs";
5
- import { slotRendersContent as o } from "../../lib/slot.mjs";
6
- import { drawerClassNames as s, drawerTitleClassNames as c } from "../../lib/classNames.mjs";
7
- import { useId as l } from "../../hooks/useId.mjs";
8
- import { useMergedRefs as u } from "../../hooks/useMergedRefs.mjs";
9
- import { useIsClient as ee } from "../../hooks/useIsClient.mjs";
10
- import { Portal as d } from "../portal/Portal.mjs";
11
- import { Button as te } from "../button/Button.mjs";
12
- import { DismissIcon as f } from "../../lib/icons.mjs";
13
- import { useModalLayer as p } from "../../hooks/useModalLayer.mjs";
14
- import { ModalSurfaceContext as ne, inertModalTrigger as m, useBackdropPress as re, useModalClosePart as h, useModalDismiss as g, useModalOpenState as _, useModalTitle as v, useModalTrigger as y, useModalTriggerPart as b, useModalTriggerSession as ie, useRequiredContext as x, useTitleRegistry as ae, useUnnamedModalWarning as S } from "./Dialog.shared.mjs";
15
- import * as C from "react";
16
- import { jsx as w, jsxs as T } from "react/jsx-runtime";
2
+ import { DrawerBody as e, DrawerClose as t, DrawerFooter as n, DrawerHeader as r, DrawerHeaderNavigation as i, DrawerHeaderTitle as a, DrawerTitle as o, DrawerTrigger as s } from "./Drawer.parts.mjs";
3
+ import { DrawerRoot as c } from "./Drawer.root.mjs";
17
4
  //#region src/components/overlays/Drawer.tsx
18
- var E = C.createContext(null);
19
- E.displayName = "DrawerContext";
20
- var D = {
21
- open: !1,
22
- requestOpen: () => {},
23
- trigger: m,
24
- panelId: "",
25
- inPanel: !1
26
- };
27
- function O(e) {
28
- return x(E, e, "Drawer", () => D);
29
- }
30
- var k = {
31
- start: "start-0 border-e",
32
- end: "end-0 border-s",
33
- left: "left-0 border-r",
34
- right: "right-0 border-l"
35
- }, A = "Drawer.Trigger:nested", j = "Drawer.Trigger must be a direct child of Drawer (a Fragment is fine). Inside another element or a component it is rendered as panel content, which exists only while the drawer is open, so it cannot open the drawer. Make it a direct child, put wrappers such as a Tooltip inside the trigger, or control the Drawer with `open`/`onOpenChange` and open it from your own button.", oe = "Drawer:unreachable", se = "Drawer has no way to open: a second after mounting it is still uncontrolled (no `open` prop), closed, and has no Drawer.Trigger as a direct child (or in a Fragment there). A Drawer.Trigger rendered by a component or nested in an element is panel content, which exists only while the drawer is open. Make the trigger a direct child of Drawer, or control the Drawer with `open`/`onOpenChange`.", ce = 1e3, M = (e) => {
36
- let { open: t, requestOpen: n, trigger: r, panelId: i, inPanel: o } = O("Drawer.Trigger");
37
- return C.useEffect(() => {
38
- o && a(A, j);
39
- }, [o]), b({
40
- open: t,
41
- requestOpen: n,
42
- trigger: r,
43
- controlsId: i
44
- }, e, "Drawer.Trigger");
45
- };
46
- M.displayName = "DrawerTrigger";
47
- var N = (e) => {
48
- let { requestOpen: t } = O("Drawer.Close");
49
- return h(t, e, "Drawer.Close");
50
- };
51
- N.displayName = "DrawerClose";
52
- var P = ({ id: t, className: n, children: r, ref: i, ...a }) => {
53
- let { id: o, ref: s } = v("Drawer.Title", "Drawer", t, i);
54
- return /* @__PURE__ */ w("h2", {
55
- ...a,
56
- id: o,
57
- ref: s,
58
- className: e(c.root, "text-subtitle-1 font-semibold text-foreground", n),
59
- children: r
60
- });
61
- };
62
- P.displayName = "DrawerTitle";
63
- var F = 32;
64
- function I(e) {
65
- let t = (e, r, i) => {
66
- if (i > F || typeof e != "object" || !e) return !1;
67
- if (Array.isArray(e)) return e.some((e) => t(e, r, i));
68
- if (!C.isValidElement(e)) return !1;
69
- let a = n(e, { suspend: !1 });
70
- if (a === M) return r > 0;
71
- let o = a === C.Fragment;
72
- if (typeof a != "string" && !o) return !1;
73
- let { children: s } = e.props;
74
- return t(s, o ? r : r + 1, i + 1);
75
- };
76
- return t(e, 0, 0);
77
- }
78
- function L(e) {
79
- let n = [], i = [];
80
- for (let { key: a, node: o } of t(e)) {
81
- let e = C.isValidElement(o) ? C.cloneElement(o, { key: a }) : o;
82
- r(o, M) ? n.push(e) : i.push(e);
83
- }
84
- return {
85
- triggers: n,
86
- content: i
87
- };
88
- }
89
- var R = ({ open: t, defaultOpen: n, onOpenChange: r, position: m = "end", title: h, closeLabel: v = "Close", finalFocusRef: b, children: x, className: D, id: O, ref: M, ...N }) => {
90
- let [P, F] = _(t, n, r), R = ee(), z = P && R, B = y(), V = l("wave-drawer"), H = O ?? V, U = l("wave-drawer-title"), W = ae(), [G, le] = C.useState(null), K = C.useRef(null), ue = C.useCallback((e) => {
91
- K.current = e, le(e);
92
- }, []), de = u(M, ue), q = re(K, !0), fe = g(F, "Drawer", q.afterOutsidePress), pe = p({
93
- open: z,
94
- onDismiss: fe,
95
- refs: [K],
96
- container: G,
97
- triggerRef: B.focusRef,
98
- finalFocusRef: b
99
- });
100
- ie(B, z), S(z ? G : null, W.hasTitle, "Drawer", "Drawer.Title");
101
- let { triggers: J, content: me } = L(x), Y = C.useRef(!1);
102
- C.useEffect(() => {
103
- i && !Y.current && I(x) && (Y.current = !0, a(A, j));
104
- }, [x]);
105
- let X = t === void 0 && !n && J.length === 0, Z = C.useRef({
106
- unreachable: X,
107
- children: x
108
- });
109
- C.useLayoutEffect(() => {
110
- Z.current = {
111
- unreachable: X,
112
- children: x
113
- };
114
- }), C.useEffect(() => {
115
- if (!i || !Z.current.unreachable) return;
116
- let e = setTimeout(() => {
117
- let e = Z.current;
118
- e.unreachable && !I(e.children) && a(oe, se);
119
- }, ce);
120
- return () => clearTimeout(e);
121
- }, []);
122
- let Q = C.useMemo(() => ({
123
- open: z,
124
- requestOpen: F,
125
- trigger: B,
126
- panelId: H,
127
- inPanel: !1
128
- }), [
129
- z,
130
- F,
131
- B,
132
- H
133
- ]), he = C.useMemo(() => ({
134
- ...Q,
135
- inPanel: !0
136
- }), [Q]), $ = o(h);
137
- return /* @__PURE__ */ T(E.Provider, {
138
- value: Q,
139
- children: [J, z && /* @__PURE__ */ w(d, {
140
- layerId: pe.layerId,
141
- children: /* @__PURE__ */ w("div", {
142
- className: e(s.backdrop, "fixed inset-0 bg-backdrop"),
143
- onMouseDown: q.onMouseDown,
144
- children: /* @__PURE__ */ w("div", {
145
- ref: de,
146
- role: "dialog",
147
- id: H,
148
- "aria-labelledby": $ ? U : W.titleId,
149
- tabIndex: -1,
150
- ...N,
151
- className: e(s.root, "fixed top-0 flex h-full w-80 max-w-full flex-col border-border bg-background text-foreground shadow-64", k[m], D),
152
- children: /* @__PURE__ */ w(E.Provider, {
153
- value: he,
154
- children: /* @__PURE__ */ T(ne.Provider, {
155
- value: W.context,
156
- children: [/* @__PURE__ */ T("div", {
157
- className: e(s.header, "flex items-center justify-between gap-2 border-b border-border p-4"),
158
- children: [$ && /* @__PURE__ */ w("h2", {
159
- id: U,
160
- className: e(c.root, "text-subtitle-1 font-semibold"),
161
- children: h
162
- }), /* @__PURE__ */ w(te, {
163
- appearance: "subtle",
164
- size: "small",
165
- icon: /* @__PURE__ */ w(f, {}),
166
- "aria-label": v,
167
- onClick: (e) => F(!1, {
168
- reason: "close-button",
169
- event: e.nativeEvent
170
- }),
171
- className: e(s.closeButton, "ms-auto text-muted-foreground")
172
- })]
173
- }), /* @__PURE__ */ w("div", {
174
- className: e(s.body, "min-h-0 flex-1 overflow-y-auto p-4"),
175
- children: me
176
- })]
177
- })
178
- })
179
- })
180
- })
181
- })]
182
- });
183
- };
184
- R.displayName = "Drawer";
185
- var z = /* @__PURE__ */ Object.assign(R, {
186
- Trigger: M,
187
- Close: N,
188
- Title: P
5
+ var l = /* @__PURE__ */ Object.assign(c, {
6
+ Trigger: s,
7
+ Close: t,
8
+ Title: o,
9
+ Header: r,
10
+ HeaderTitle: a,
11
+ HeaderNavigation: i,
12
+ Body: e,
13
+ Footer: n
189
14
  });
190
15
  //#endregion
191
- export { z as Drawer, N as DrawerClose, P as DrawerTitle, M as DrawerTrigger };
16
+ export { l as Drawer, e as DrawerBody, t as DrawerClose, n as DrawerFooter, r as DrawerHeader, i as DrawerHeaderNavigation, a as DrawerHeaderTitle, o as DrawerTitle, s as DrawerTrigger };
192
17
 
193
18
  //# sourceMappingURL=Drawer.mjs.map