@craftzbay/ui 0.10.0 → 0.11.1

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 (187) hide show
  1. package/README.md +18 -12
  2. package/dist-lib/__tests__/helpers/color.d.ts +9 -0
  3. package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
  4. package/dist-lib/components/ui/Accordion.js +18 -7
  5. package/dist-lib/components/ui/Accordion.js.map +1 -1
  6. package/dist-lib/components/ui/Alert.d.ts +16 -0
  7. package/dist-lib/components/ui/Alert.js +47 -34
  8. package/dist-lib/components/ui/Alert.js.map +1 -1
  9. package/dist-lib/components/ui/Avatar.d.ts +1 -1
  10. package/dist-lib/components/ui/Avatar.js +45 -47
  11. package/dist-lib/components/ui/Avatar.js.map +1 -1
  12. package/dist-lib/components/ui/Badge.d.ts +3 -1
  13. package/dist-lib/components/ui/Badge.js +24 -15
  14. package/dist-lib/components/ui/Badge.js.map +1 -1
  15. package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
  16. package/dist-lib/components/ui/Breadcrumbs.js +46 -28
  17. package/dist-lib/components/ui/Breadcrumbs.js.map +1 -1
  18. package/dist-lib/components/ui/Button.d.ts +5 -3
  19. package/dist-lib/components/ui/Button.js +59 -45
  20. package/dist-lib/components/ui/Button.js.map +1 -1
  21. package/dist-lib/components/ui/Calendar.d.ts +1 -1
  22. package/dist-lib/components/ui/Calendar.js +87 -59
  23. package/dist-lib/components/ui/Calendar.js.map +1 -1
  24. package/dist-lib/components/ui/Card.d.ts +2 -0
  25. package/dist-lib/components/ui/Card.js +48 -67
  26. package/dist-lib/components/ui/Card.js.map +1 -1
  27. package/dist-lib/components/ui/Carousel.d.ts +6 -6
  28. package/dist-lib/components/ui/Carousel.js +133 -102
  29. package/dist-lib/components/ui/Carousel.js.map +1 -1
  30. package/dist-lib/components/ui/Chart.d.ts +49 -10
  31. package/dist-lib/components/ui/Chart.js +415 -181
  32. package/dist-lib/components/ui/Chart.js.map +1 -1
  33. package/dist-lib/components/ui/Checkbox.js +42 -28
  34. package/dist-lib/components/ui/Checkbox.js.map +1 -1
  35. package/dist-lib/components/ui/Combobox.d.ts +2 -0
  36. package/dist-lib/components/ui/Combobox.js +142 -111
  37. package/dist-lib/components/ui/Combobox.js.map +1 -1
  38. package/dist-lib/components/ui/CommandPalette.d.ts +6 -3
  39. package/dist-lib/components/ui/CommandPalette.js +92 -87
  40. package/dist-lib/components/ui/CommandPalette.js.map +1 -1
  41. package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
  42. package/dist-lib/components/ui/ContextMenu.js +77 -62
  43. package/dist-lib/components/ui/ContextMenu.js.map +1 -1
  44. package/dist-lib/components/ui/DataGrid.d.ts +17 -4
  45. package/dist-lib/components/ui/DataGrid.js +65 -50
  46. package/dist-lib/components/ui/DataGrid.js.map +1 -1
  47. package/dist-lib/components/ui/DatePicker.js +118 -99
  48. package/dist-lib/components/ui/DatePicker.js.map +1 -1
  49. package/dist-lib/components/ui/DesignSystemProvider.d.ts +94 -40
  50. package/dist-lib/components/ui/DesignSystemProvider.js +111 -55
  51. package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -1
  52. package/dist-lib/components/ui/Dialog.d.ts +18 -3
  53. package/dist-lib/components/ui/Dialog.js +105 -80
  54. package/dist-lib/components/ui/Dialog.js.map +1 -1
  55. package/dist-lib/components/ui/Drawer.d.ts +17 -2
  56. package/dist-lib/components/ui/Drawer.js +89 -55
  57. package/dist-lib/components/ui/Drawer.js.map +1 -1
  58. package/dist-lib/components/ui/DropdownMenu.js +14 -9
  59. package/dist-lib/components/ui/DropdownMenu.js.map +1 -1
  60. package/dist-lib/components/ui/EmptyState.d.ts +2 -0
  61. package/dist-lib/components/ui/EmptyState.js +30 -16
  62. package/dist-lib/components/ui/EmptyState.js.map +1 -1
  63. package/dist-lib/components/ui/ErrorState.d.ts +13 -2
  64. package/dist-lib/components/ui/ErrorState.js +44 -23
  65. package/dist-lib/components/ui/ErrorState.js.map +1 -1
  66. package/dist-lib/components/ui/FileUpload.js +59 -56
  67. package/dist-lib/components/ui/FileUpload.js.map +1 -1
  68. package/dist-lib/components/ui/Form.d.ts +15 -2
  69. package/dist-lib/components/ui/Form.js +97 -71
  70. package/dist-lib/components/ui/Form.js.map +1 -1
  71. package/dist-lib/components/ui/Icon.d.ts +1 -1
  72. package/dist-lib/components/ui/Icon.js +20 -14
  73. package/dist-lib/components/ui/Icon.js.map +1 -1
  74. package/dist-lib/components/ui/IconButton.d.ts +2 -2
  75. package/dist-lib/components/ui/IconButton.js +28 -20
  76. package/dist-lib/components/ui/IconButton.js.map +1 -1
  77. package/dist-lib/components/ui/Input.d.ts +3 -1
  78. package/dist-lib/components/ui/Input.js +102 -79
  79. package/dist-lib/components/ui/Input.js.map +1 -1
  80. package/dist-lib/components/ui/Kbd.js +1 -1
  81. package/dist-lib/components/ui/Kbd.js.map +1 -1
  82. package/dist-lib/components/ui/MultiSelect.js +121 -107
  83. package/dist-lib/components/ui/MultiSelect.js.map +1 -1
  84. package/dist-lib/components/ui/Pagination.js +67 -62
  85. package/dist-lib/components/ui/Pagination.js.map +1 -1
  86. package/dist-lib/components/ui/Popover.js +14 -14
  87. package/dist-lib/components/ui/Popover.js.map +1 -1
  88. package/dist-lib/components/ui/Progress.d.ts +3 -3
  89. package/dist-lib/components/ui/Progress.js +77 -72
  90. package/dist-lib/components/ui/Progress.js.map +1 -1
  91. package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
  92. package/dist-lib/components/ui/RadioGroup.js +69 -52
  93. package/dist-lib/components/ui/RadioGroup.js.map +1 -1
  94. package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
  95. package/dist-lib/components/ui/RelativeTime.js +31 -0
  96. package/dist-lib/components/ui/RelativeTime.js.map +1 -0
  97. package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
  98. package/dist-lib/components/ui/ScrollArea.js +43 -27
  99. package/dist-lib/components/ui/ScrollArea.js.map +1 -1
  100. package/dist-lib/components/ui/Select.d.ts +6 -1
  101. package/dist-lib/components/ui/Select.js +79 -71
  102. package/dist-lib/components/ui/Select.js.map +1 -1
  103. package/dist-lib/components/ui/Separator.js +1 -1
  104. package/dist-lib/components/ui/Separator.js.map +1 -1
  105. package/dist-lib/components/ui/Sheet.d.ts +9 -0
  106. package/dist-lib/components/ui/Sheet.js +69 -46
  107. package/dist-lib/components/ui/Sheet.js.map +1 -1
  108. package/dist-lib/components/ui/Sidebar.d.ts +12 -9
  109. package/dist-lib/components/ui/Sidebar.js +152 -109
  110. package/dist-lib/components/ui/Sidebar.js.map +1 -1
  111. package/dist-lib/components/ui/Skeleton.d.ts +13 -2
  112. package/dist-lib/components/ui/Skeleton.js +15 -14
  113. package/dist-lib/components/ui/Skeleton.js.map +1 -1
  114. package/dist-lib/components/ui/Slider.js +41 -29
  115. package/dist-lib/components/ui/Slider.js.map +1 -1
  116. package/dist-lib/components/ui/Snackbar.js +23 -22
  117. package/dist-lib/components/ui/Snackbar.js.map +1 -1
  118. package/dist-lib/components/ui/Spinner.js +18 -6
  119. package/dist-lib/components/ui/Spinner.js.map +1 -1
  120. package/dist-lib/components/ui/Stepper.d.ts +6 -0
  121. package/dist-lib/components/ui/Stepper.js +71 -48
  122. package/dist-lib/components/ui/Stepper.js.map +1 -1
  123. package/dist-lib/components/ui/Switch.js +46 -43
  124. package/dist-lib/components/ui/Switch.js.map +1 -1
  125. package/dist-lib/components/ui/Table.d.ts +33 -5
  126. package/dist-lib/components/ui/Table.js +141 -119
  127. package/dist-lib/components/ui/Table.js.map +1 -1
  128. package/dist-lib/components/ui/Tabs.js +50 -48
  129. package/dist-lib/components/ui/Tabs.js.map +1 -1
  130. package/dist-lib/components/ui/TagInput.js +45 -45
  131. package/dist-lib/components/ui/TagInput.js.map +1 -1
  132. package/dist-lib/components/ui/Textarea.js +65 -54
  133. package/dist-lib/components/ui/Textarea.js.map +1 -1
  134. package/dist-lib/components/ui/Timeline.js +39 -35
  135. package/dist-lib/components/ui/Timeline.js.map +1 -1
  136. package/dist-lib/components/ui/Toast.js +44 -57
  137. package/dist-lib/components/ui/Toast.js.map +1 -1
  138. package/dist-lib/components/ui/Tooltip.d.ts +4 -1
  139. package/dist-lib/components/ui/Tooltip.js +24 -22
  140. package/dist-lib/components/ui/Tooltip.js.map +1 -1
  141. package/dist-lib/components/ui/TopNav.d.ts +7 -3
  142. package/dist-lib/components/ui/TopNav.js +39 -22
  143. package/dist-lib/components/ui/TopNav.js.map +1 -1
  144. package/dist-lib/components/ui/Tree.d.ts +15 -10
  145. package/dist-lib/components/ui/Tree.js +82 -79
  146. package/dist-lib/components/ui/Tree.js.map +1 -1
  147. package/dist-lib/hooks/use-debounce.d.ts +19 -0
  148. package/dist-lib/hooks/use-debounce.js +36 -0
  149. package/dist-lib/hooks/use-debounce.js.map +1 -0
  150. package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
  151. package/dist-lib/hooks/use-delayed-loading.js +20 -0
  152. package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
  153. package/dist-lib/hooks/use-field-ids.d.ts +2 -1
  154. package/dist-lib/hooks/use-field-ids.js +9 -9
  155. package/dist-lib/hooks/use-field-ids.js.map +1 -1
  156. package/dist-lib/hooks/use-media-query.d.ts +3 -1
  157. package/dist-lib/hooks/use-media-query.js +16 -12
  158. package/dist-lib/hooks/use-media-query.js.map +1 -1
  159. package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
  160. package/dist-lib/hooks/use-modifier-key.js +19 -0
  161. package/dist-lib/hooks/use-modifier-key.js.map +1 -0
  162. package/dist-lib/hooks/use-toast.d.ts +7 -2
  163. package/dist-lib/hooks/use-toast.js +61 -30
  164. package/dist-lib/hooks/use-toast.js.map +1 -1
  165. package/dist-lib/icons/index.d.ts +9 -0
  166. package/dist-lib/icons/index.js +148 -130
  167. package/dist-lib/icons/index.js.map +1 -1
  168. package/dist-lib/illustrations/index.d.ts +1 -0
  169. package/dist-lib/illustrations/index.js +15 -6
  170. package/dist-lib/illustrations/index.js.map +1 -1
  171. package/dist-lib/index.d.ts +6 -0
  172. package/dist-lib/index.js +280 -260
  173. package/dist-lib/index.js.map +1 -1
  174. package/dist-lib/lib/format.d.ts +65 -0
  175. package/dist-lib/lib/format.js +95 -0
  176. package/dist-lib/lib/format.js.map +1 -0
  177. package/dist-lib/lib/return-focus.d.ts +11 -0
  178. package/dist-lib/lib/return-focus.js +12 -0
  179. package/dist-lib/lib/return-focus.js.map +1 -0
  180. package/dist-lib/lib/strings.d.ts +62 -1
  181. package/dist-lib/lib/strings.js +75 -19
  182. package/dist-lib/lib/strings.js.map +1 -1
  183. package/dist-lib/lib/strings.mn.js +50 -5
  184. package/dist-lib/lib/strings.mn.js.map +1 -1
  185. package/dist-lib/styles.css +1 -1
  186. package/dist-lib/theme.css +141 -78
  187. package/package.json +11 -4
@@ -1,38 +1,40 @@
1
1
  "use client";
2
2
  import { jsx as e, jsxs as s } from "react/jsx-runtime";
3
- import { forwardRef as d } from "react";
4
- import * as r from "@radix-ui/react-dialog";
5
- import { X as C } from "../../icons/index.js";
6
- import { cn as n } from "../../lib/utils.js";
7
- import { useStrings as p } from "../../hooks/use-strings.js";
8
- import { Button as u } from "./Button.js";
9
- const w = r.Root, B = r.Trigger, z = r.Portal, T = r.Close, D = d(function({ className: o, ...i }, t) {
3
+ import { useState as b, forwardRef as c } from "react";
4
+ import * as n from "@radix-ui/react-dialog";
5
+ import { X as S } from "../../icons/index.js";
6
+ import { cn as r } from "../../lib/utils.js";
7
+ import { useStrings as C } from "../../hooks/use-strings.js";
8
+ import { Button as N } from "./Button.js";
9
+ import { withReturnFocus as k } from "../../lib/return-focus.js";
10
+ const B = n.Root, Q = n.Trigger, E = n.Portal, H = n.Close, w = c(function({ className: a, ...i }, o) {
10
11
  return /* @__PURE__ */ e(
11
- r.Overlay,
12
+ n.Overlay,
12
13
  {
13
- ref: t,
14
- className: n(
15
- "fixed inset-0 z-[var(--z-overlay)] bg-overlay",
14
+ ref: o,
15
+ className: r(
16
+ "bg-overlay fixed inset-0 z-[var(--z-overlay)]",
16
17
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
17
18
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
18
- o
19
+ a
19
20
  ),
20
21
  ...i
21
22
  }
22
23
  );
23
24
  });
24
- D.displayName = "DialogOverlay";
25
- const x = d(function({ className: o, children: i, showClose: t = !0, size: l = "md", ...c }, m) {
26
- const g = p();
27
- return /* @__PURE__ */ s(z, { children: [
28
- /* @__PURE__ */ e(D, {}),
25
+ w.displayName = "DialogOverlay";
26
+ const z = c(function({ className: a, children: i, showClose: o = !0, size: l = "md", returnFocusTo: m, onCloseAutoFocus: g, ...u }, f) {
27
+ const p = C();
28
+ return /* @__PURE__ */ s(E, { children: [
29
+ /* @__PURE__ */ e(w, {}),
29
30
  /* @__PURE__ */ s(
30
- r.Content,
31
+ n.Content,
31
32
  {
32
- ref: m,
33
- className: n(
34
- "fixed left-1/2 top-1/2 z-[var(--z-modal)] -translate-x-1/2 -translate-y-1/2",
35
- "w-[calc(100%-2rem)] rounded-lg border border-border bg-card text-card-foreground shadow-lg",
33
+ ref: f,
34
+ onCloseAutoFocus: k(m, g),
35
+ className: r(
36
+ "fixed top-1/2 left-1/2 z-[var(--z-modal)] -translate-x-1/2 -translate-y-1/2",
37
+ "border-border bg-card text-card-foreground w-[calc(100%-2rem)] rounded-xl border shadow-lg",
36
38
  "p-6",
37
39
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
38
40
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
@@ -40,22 +42,22 @@ const x = d(function({ className: o, children: i, showClose: t = !0, size: l = "
40
42
  l === "sm" && "max-w-[400px]",
41
43
  l === "md" && "max-w-[520px]",
42
44
  l === "lg" && "max-w-[720px]",
43
- o
45
+ a
44
46
  ),
45
- ...c,
47
+ ...u,
46
48
  children: [
47
49
  i,
48
- t && /* @__PURE__ */ e(
49
- r.Close,
50
+ o && /* @__PURE__ */ e(
51
+ n.Close,
50
52
  {
51
- "aria-label": g.dialog.close,
52
- className: n(
53
- "absolute right-4 top-4 inline-flex size-8 items-center justify-center rounded-md text-foreground-subtle",
53
+ "aria-label": p.dialog.close,
54
+ className: r(
55
+ "text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md",
54
56
  "hover:bg-background-muted hover:text-foreground",
55
- "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card",
57
+ "focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
56
58
  "transition-colors duration-[var(--duration-fast)]"
57
59
  ),
58
- children: /* @__PURE__ */ e(C, { className: "size-4", "aria-hidden": !0 })
60
+ children: /* @__PURE__ */ e(S, { className: "size-4", "aria-hidden": !0 })
59
61
  }
60
62
  )
61
63
  ]
@@ -63,78 +65,101 @@ const x = d(function({ className: o, children: i, showClose: t = !0, size: l = "
63
65
  )
64
66
  ] });
65
67
  });
66
- x.displayName = "DialogContent";
67
- function v({ className: a, ...o }) {
68
- return /* @__PURE__ */ e("div", { className: n("flex flex-col gap-1 pb-4", a), ...o });
68
+ z.displayName = "DialogContent";
69
+ function F({ className: t, ...a }) {
70
+ return /* @__PURE__ */ e("div", { className: r("flex flex-col gap-1 pb-4", t), ...a });
69
71
  }
70
- v.displayName = "DialogHeader";
71
- function h({ className: a, ...o }) {
72
+ F.displayName = "DialogHeader";
73
+ function T({ className: t, ...a }) {
72
74
  return /* @__PURE__ */ e(
73
75
  "div",
74
76
  {
75
- className: n("flex flex-col-reverse gap-2 pt-6 sm:flex-row sm:justify-end", a),
76
- ...o
77
+ className: r("flex flex-col-reverse gap-2 pt-6 sm:flex-row sm:justify-end", t),
78
+ ...a
77
79
  }
78
80
  );
79
81
  }
80
- h.displayName = "DialogFooter";
81
- const y = d(function({ className: o, ...i }, t) {
82
+ T.displayName = "DialogFooter";
83
+ const O = c(function({ className: a, ...i }, o) {
82
84
  return /* @__PURE__ */ e(
83
- r.Title,
85
+ n.Title,
84
86
  {
85
- ref: t,
86
- className: n("text-lg font-semibold text-foreground leading-tight", o),
87
+ ref: o,
88
+ className: r("text-foreground text-lg leading-tight font-semibold", a),
87
89
  ...i
88
90
  }
89
91
  );
90
92
  });
91
- y.displayName = "DialogTitle";
92
- const b = d(function({ className: o, ...i }, t) {
93
+ O.displayName = "DialogTitle";
94
+ const j = c(function({ className: a, ...i }, o) {
93
95
  return /* @__PURE__ */ e(
94
- r.Description,
96
+ n.Description,
95
97
  {
96
- ref: t,
97
- className: n("text-sm text-foreground-muted", o),
98
+ ref: o,
99
+ className: r("text-foreground-muted text-sm", a),
98
100
  ...i
99
101
  }
100
102
  );
101
103
  });
102
- b.displayName = "DialogDescription";
103
- function j({
104
- open: a,
105
- onOpenChange: o,
104
+ j.displayName = "DialogDescription";
105
+ function A({
106
+ open: t,
107
+ onOpenChange: a,
106
108
  title: i,
107
- description: t,
109
+ description: o,
108
110
  confirmLabel: l,
109
- cancelLabel: c,
110
- confirmVariant: m = "primary",
111
- onConfirm: g,
112
- loading: N
111
+ cancelLabel: m,
112
+ confirmVariant: g = "primary",
113
+ onConfirm: u,
114
+ loading: f,
115
+ formatError: p = X
113
116
  }) {
114
- const f = p();
115
- return /* @__PURE__ */ e(w, { open: a, onOpenChange: o, children: /* @__PURE__ */ s(x, { size: "sm", children: [
116
- /* @__PURE__ */ s(v, { children: [
117
- /* @__PURE__ */ e(y, { children: i }),
118
- t && /* @__PURE__ */ e(b, { children: t })
119
- ] }),
120
- /* @__PURE__ */ s(h, { children: [
121
- /* @__PURE__ */ e(T, { asChild: !0, children: /* @__PURE__ */ e(u, { variant: "outline", children: c ?? f.confirmationDialog.cancel }) }),
122
- /* @__PURE__ */ e(u, { variant: m, loading: N, onClick: g, children: l ?? f.confirmationDialog.confirm })
123
- ] })
124
- ] }) });
117
+ const x = C(), [P, h] = b(!1), [v, D] = b(null), y = !!f || P, R = async () => {
118
+ D(null), h(!0);
119
+ try {
120
+ await u();
121
+ } catch (d) {
122
+ D(p(d));
123
+ } finally {
124
+ h(!1);
125
+ }
126
+ };
127
+ return /* @__PURE__ */ e(
128
+ B,
129
+ {
130
+ open: t,
131
+ onOpenChange: (d) => {
132
+ d || D(null), a(d);
133
+ },
134
+ children: /* @__PURE__ */ s(z, { size: "sm", ...o ? {} : { "aria-describedby": void 0 }, children: [
135
+ /* @__PURE__ */ s(F, { children: [
136
+ /* @__PURE__ */ e(O, { children: i }),
137
+ o && /* @__PURE__ */ e(j, { children: o })
138
+ ] }),
139
+ v && /* @__PURE__ */ e("p", { role: "alert", className: "text-danger-text text-sm", children: v }),
140
+ /* @__PURE__ */ s(T, { children: [
141
+ /* @__PURE__ */ e(H, { asChild: !0, children: /* @__PURE__ */ e(N, { variant: "outline", disabled: y, children: m ?? x.confirmationDialog.cancel }) }),
142
+ /* @__PURE__ */ e(N, { variant: g, loading: y, onClick: R, children: l ?? x.confirmationDialog.confirm })
143
+ ] })
144
+ ] })
145
+ }
146
+ );
147
+ }
148
+ function X(t) {
149
+ return t instanceof Error ? t.message : String(t);
125
150
  }
126
- j.displayName = "ConfirmationDialog";
151
+ A.displayName = "ConfirmationDialog";
127
152
  export {
128
- j as ConfirmationDialog,
129
- w as Dialog,
130
- T as DialogClose,
131
- x as DialogContent,
132
- b as DialogDescription,
133
- h as DialogFooter,
134
- v as DialogHeader,
135
- D as DialogOverlay,
136
- z as DialogPortal,
137
- y as DialogTitle,
138
- B as DialogTrigger
153
+ A as ConfirmationDialog,
154
+ B as Dialog,
155
+ H as DialogClose,
156
+ z as DialogContent,
157
+ j as DialogDescription,
158
+ T as DialogFooter,
159
+ F as DialogHeader,
160
+ w as DialogOverlay,
161
+ E as DialogPortal,
162
+ O as DialogTitle,
163
+ Q as DialogTrigger
139
164
  };
140
165
  //# sourceMappingURL=Dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.js","sources":["../../../src/components/ui/Dialog.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { Button, type ButtonProps } from './Button';\n\nexport const Dialog = DialogPrimitive.Root;\nexport const DialogTrigger = DialogPrimitive.Trigger;\nexport const DialogPortal = DialogPrimitive.Portal;\nexport const DialogClose = DialogPrimitive.Close;\n\nexport const DialogOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(function DialogOverlay({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'fixed inset-0 z-[var(--z-overlay)] bg-overlay',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n className,\n )}\n {...props}\n />\n );\n});\nDialogOverlay.displayName = 'DialogOverlay';\n\nexport interface DialogContentProps\n extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {\n /** Show the default close (×) button in the top-right. */\n showClose?: boolean;\n /** Dialog width — `sm` 400 / `md` 520 / `lg` 720. */\n size?: 'sm' | 'md' | 'lg';\n}\n\nexport const DialogContent = forwardRef<\n ElementRef<typeof DialogPrimitive.Content>,\n DialogContentProps\n>(function DialogContent({ className, children, showClose = true, size = 'md', ...props }, ref) {\n const strings = useStrings();\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n 'fixed left-1/2 top-1/2 z-[var(--z-modal)] -translate-x-1/2 -translate-y-1/2',\n 'w-[calc(100%-2rem)] rounded-lg border border-border bg-card text-card-foreground shadow-lg',\n 'p-6',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n size === 'sm' && 'max-w-[400px]',\n size === 'md' && 'max-w-[520px]',\n size === 'lg' && 'max-w-[720px]',\n className,\n )}\n {...props}\n >\n {children}\n {showClose && (\n <DialogPrimitive.Close\n aria-label={strings.dialog.close}\n className={cn(\n 'absolute right-4 top-4 inline-flex size-8 items-center justify-center rounded-md text-foreground-subtle',\n 'hover:bg-background-muted hover:text-foreground',\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n <X className=\"size-4\" aria-hidden />\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n});\nDialogContent.displayName = 'DialogContent';\n\nexport function DialogHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col gap-1 pb-4', className)} {...props} />;\n}\nDialogHeader.displayName = 'DialogHeader';\n\nexport function DialogFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('flex flex-col-reverse gap-2 pt-6 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n );\n}\nDialogFooter.displayName = 'DialogFooter';\n\nexport const DialogTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(function DialogTitle({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold text-foreground leading-tight', className)}\n {...props}\n />\n );\n});\nDialogTitle.displayName = 'DialogTitle';\n\nexport const DialogDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(function DialogDescription({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-foreground-muted', className)}\n {...props}\n />\n );\n});\nDialogDescription.displayName = 'DialogDescription';\n\n/* -----------------------------------------------------------------------------\n * ConfirmationDialog — pre-composed pattern for destructive/important\n * confirmations. Use this when the body is a single sentence and the only\n * controls are Cancel + Confirm.\n * --------------------------------------------------------------------------- */\n\nexport interface ConfirmationDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: ReactNode;\n description?: ReactNode;\n /** Label of the confirm button. */\n confirmLabel?: string;\n /** Label of the cancel button. */\n cancelLabel?: string;\n /** Variant of the confirm button — typically `primary` or `destructive`. */\n confirmVariant?: ButtonProps['variant'];\n /** Called when the user confirms. Awaited — shows a spinner while pending. */\n onConfirm: () => void | Promise<void>;\n /** Whether the confirm button is currently submitting. */\n loading?: boolean;\n}\n\n/**\n * Confirmation dialog with title, description, cancel + confirm buttons.\n *\n * @example Destructive confirmation\n * <ConfirmationDialog\n * open={open} onOpenChange={setOpen}\n * title=\"Delete project?\"\n * description=\"This permanently deletes the project and all its data.\"\n * confirmLabel=\"Delete project\"\n * confirmVariant=\"destructive\"\n * onConfirm={handleDelete}\n * />\n *\n * @do Lead the title with the action: \"Delete project?\" not \"Are you sure?\".\n * State consequences in the description.\n * @dont Use for low-risk reversible actions — those don't need a dialog.\n */\nexport function ConfirmationDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmLabel,\n cancelLabel,\n confirmVariant = 'primary',\n onConfirm,\n loading,\n}: ConfirmationDialogProps) {\n const strings = useStrings();\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent size=\"sm\">\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n {description && <DialogDescription>{description}</DialogDescription>}\n </DialogHeader>\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\">{cancelLabel ?? strings.confirmationDialog.cancel}</Button>\n </DialogClose>\n <Button variant={confirmVariant} loading={loading} onClick={onConfirm}>\n {confirmLabel ?? strings.confirmationDialog.confirm}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\nConfirmationDialog.displayName = 'ConfirmationDialog';\n"],"names":["Dialog","DialogPrimitive","DialogTrigger","DialogPortal","DialogClose","DialogOverlay","forwardRef","className","props","ref","jsx","cn","DialogContent","children","showClose","size","strings","useStrings","jsxs","X","DialogHeader","DialogFooter","DialogTitle","DialogDescription","ConfirmationDialog","open","onOpenChange","title","description","confirmLabel","cancelLabel","confirmVariant","onConfirm","loading","Button"],"mappings":"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"}
1
+ {"version":3,"file":"Dialog.js","sources":["../../../src/components/ui/Dialog.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useState,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { Button, type ButtonProps } from './Button';\nimport { withReturnFocus, type ReturnFocusRef } from '@/lib/return-focus';\n\nexport const Dialog = DialogPrimitive.Root;\nexport const DialogTrigger = DialogPrimitive.Trigger;\nexport const DialogPortal = DialogPrimitive.Portal;\nexport const DialogClose = DialogPrimitive.Close;\n\nexport const DialogOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(function DialogOverlay({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'bg-overlay fixed inset-0 z-[var(--z-overlay)]',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n className,\n )}\n {...props}\n />\n );\n});\nDialogOverlay.displayName = 'DialogOverlay';\n\nexport interface DialogContentProps extends ComponentPropsWithoutRef<\n typeof DialogPrimitive.Content\n> {\n /** Show the default close (×) button in the top-right. */\n showClose?: boolean;\n /** Dialog width — `sm` 400 / `md` 520 / `lg` 720. */\n size?: 'sm' | 'md' | 'lg';\n /**\n * Element to focus when the overlay closes. Overrides Radix's default\n * (the element focused when the content mounted), which is `<body>` for\n * controlled overlays opened from a pointer click on a non-focusable /\n * tooltip-wrapped trigger. A consumer `onCloseAutoFocus` runs first and\n * wins if it calls `preventDefault()`.\n */\n returnFocusTo?: ReturnFocusRef;\n}\n\nexport const DialogContent = forwardRef<\n ElementRef<typeof DialogPrimitive.Content>,\n DialogContentProps\n>(function DialogContent(\n { className, children, showClose = true, size = 'md', returnFocusTo, onCloseAutoFocus, ...props },\n ref,\n) {\n const strings = useStrings();\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n onCloseAutoFocus={withReturnFocus(returnFocusTo, onCloseAutoFocus)}\n className={cn(\n 'fixed top-1/2 left-1/2 z-[var(--z-modal)] -translate-x-1/2 -translate-y-1/2',\n 'border-border bg-card text-card-foreground w-[calc(100%-2rem)] rounded-xl border shadow-lg',\n 'p-6',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n size === 'sm' && 'max-w-[400px]',\n size === 'md' && 'max-w-[520px]',\n size === 'lg' && 'max-w-[720px]',\n className,\n )}\n {...props}\n >\n {children}\n {showClose && (\n <DialogPrimitive.Close\n aria-label={strings.dialog.close}\n className={cn(\n 'text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md',\n 'hover:bg-background-muted hover:text-foreground',\n 'focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n <X className=\"size-4\" aria-hidden />\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n});\nDialogContent.displayName = 'DialogContent';\n\nexport function DialogHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex flex-col gap-1 pb-4', className)} {...props} />;\n}\nDialogHeader.displayName = 'DialogHeader';\n\nexport function DialogFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('flex flex-col-reverse gap-2 pt-6 sm:flex-row sm:justify-end', className)}\n {...props}\n />\n );\n}\nDialogFooter.displayName = 'DialogFooter';\n\nexport const DialogTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(function DialogTitle({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-foreground text-lg leading-tight font-semibold', className)}\n {...props}\n />\n );\n});\nDialogTitle.displayName = 'DialogTitle';\n\nexport const DialogDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(function DialogDescription({ className, ...props }, ref) {\n return (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-foreground-muted text-sm', className)}\n {...props}\n />\n );\n});\nDialogDescription.displayName = 'DialogDescription';\n\n/* -----------------------------------------------------------------------------\n * ConfirmationDialog — pre-composed pattern for destructive/important\n * confirmations. Use this when the body is a single sentence and the only\n * controls are Cancel + Confirm.\n * --------------------------------------------------------------------------- */\n\nexport interface ConfirmationDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: ReactNode;\n description?: ReactNode;\n /** Label of the confirm button. */\n confirmLabel?: string;\n /** Label of the cancel button. */\n cancelLabel?: string;\n /** Variant of the confirm button — typically `primary` or `destructive`. */\n confirmVariant?: ButtonProps['variant'];\n /**\n * Called when the user confirms. Awaited — the confirm button shows a\n * spinner while pending and a rejection is rendered inline (the dialog stays\n * open so the user can retry or cancel).\n */\n onConfirm: () => void | Promise<void>;\n /** Force the submitting state from outside (in addition to the awaited `onConfirm`). */\n loading?: boolean;\n /** Map a rejected `onConfirm` to the message shown. Defaults to `Error.message`. */\n formatError?: (err: unknown) => ReactNode;\n}\n\n/**\n * Confirmation dialog with title, description, cancel + confirm buttons.\n *\n * @example Destructive confirmation\n * <ConfirmationDialog\n * open={open} onOpenChange={setOpen}\n * title=\"Delete project?\"\n * description=\"This permanently deletes the project and all its data.\"\n * confirmLabel=\"Delete project\"\n * confirmVariant=\"destructive\"\n * onConfirm={handleDelete}\n * />\n *\n * @do Lead the title with the action: \"Delete project?\" not \"Are you sure?\".\n * State consequences in the description.\n * @dont Use for low-risk reversible actions — those don't need a dialog.\n */\nexport function ConfirmationDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmLabel,\n cancelLabel,\n confirmVariant = 'primary',\n onConfirm,\n loading,\n formatError = defaultFormatError,\n}: ConfirmationDialogProps) {\n const strings = useStrings();\n const [pending, setPending] = useState(false);\n const [failure, setFailure] = useState<ReactNode>(null);\n const busy = Boolean(loading) || pending;\n\n const handleConfirm = async () => {\n setFailure(null);\n setPending(true);\n try {\n await onConfirm();\n } catch (err) {\n setFailure(formatError(err));\n } finally {\n setPending(false);\n }\n };\n\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!next) setFailure(null);\n onOpenChange(next);\n }}\n >\n {/* No description → drop aria-describedby so Radix does not warn and AT is not pointed at nothing. */}\n <DialogContent size=\"sm\" {...(description ? {} : { 'aria-describedby': undefined })}>\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n {description && <DialogDescription>{description}</DialogDescription>}\n </DialogHeader>\n {failure && (\n <p role=\"alert\" className=\"text-danger-text text-sm\">\n {failure}\n </p>\n )}\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\" disabled={busy}>\n {cancelLabel ?? strings.confirmationDialog.cancel}\n </Button>\n </DialogClose>\n <Button variant={confirmVariant} loading={busy} onClick={handleConfirm}>\n {confirmLabel ?? strings.confirmationDialog.confirm}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction defaultFormatError(err: unknown): ReactNode {\n return err instanceof Error ? err.message : String(err);\n}\nConfirmationDialog.displayName = 'ConfirmationDialog';\n"],"names":["Dialog","DialogPrimitive","DialogTrigger","DialogPortal","DialogClose","DialogOverlay","forwardRef","className","props","ref","jsx","cn","DialogContent","children","showClose","size","returnFocusTo","onCloseAutoFocus","strings","useStrings","jsxs","withReturnFocus","X","DialogHeader","DialogFooter","DialogTitle","DialogDescription","ConfirmationDialog","open","onOpenChange","title","description","confirmLabel","cancelLabel","confirmVariant","onConfirm","loading","formatError","defaultFormatError","pending","setPending","useState","failure","setFailure","busy","handleConfirm","err","next","Button"],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { ComponentPropsWithoutRef, HTMLAttributes } from 'react';
2
2
  import { Drawer as DrawerPrimitive } from 'vaul';
3
+ import { ReturnFocusRef } from '../../lib/return-focus.js';
3
4
  type Direction = 'top' | 'right' | 'bottom' | 'left';
4
5
  export declare const Drawer: {
5
- ({ shouldScaleBackground, ...props }: ComponentPropsWithoutRef<typeof DrawerPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
6
+ ({ shouldScaleBackground, direction, ...props }: ComponentPropsWithoutRef<typeof DrawerPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
6
7
  displayName: string;
7
8
  };
8
9
  export declare const DrawerTrigger: import('react').ForwardRefExoticComponent<import('@radix-ui/react-dialog').DialogTriggerProps & import('react').RefAttributes<HTMLButtonElement>>;
@@ -10,10 +11,24 @@ export declare const DrawerPortal: typeof import('vaul').Portal;
10
11
  export declare const DrawerClose: import('react').ForwardRefExoticComponent<import('@radix-ui/react-dialog').DialogCloseProps & import('react').RefAttributes<HTMLButtonElement>>;
11
12
  export declare const DrawerOverlay: import('react').ForwardRefExoticComponent<Omit<Omit<import('@radix-ui/react-dialog').DialogOverlayProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
12
13
  export interface DrawerContentProps extends ComponentPropsWithoutRef<typeof DrawerPrimitive.Content> {
13
- /** Side the drawer slides in from. Default `bottom`. */
14
+ /**
15
+ * Side the drawer slides in from. Prefer setting `direction` on `<Drawer>`
16
+ * (vaul needs it there for drag physics); this prop only overrides the
17
+ * visual placement.
18
+ */
14
19
  direction?: Direction;
15
20
  /** Hide the drag handle. */
16
21
  hideHandle?: boolean;
22
+ /** Show the close (×) button. Default `true`. */
23
+ showClose?: boolean;
24
+ /**
25
+ * Element to focus when the overlay closes. Overrides Radix's default
26
+ * (the element focused when the content mounted), which is `<body>` for
27
+ * controlled overlays opened from a pointer click on a non-focusable /
28
+ * tooltip-wrapped trigger. A consumer `onCloseAutoFocus` runs first and
29
+ * wins if it calls `preventDefault()`.
30
+ */
31
+ returnFocusTo?: ReturnFocusRef;
17
32
  }
18
33
  export declare const DrawerContent: import('react').ForwardRefExoticComponent<DrawerContentProps & import('react').RefAttributes<HTMLDivElement>>;
19
34
  export declare function DrawerHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
@@ -1,98 +1,132 @@
1
1
  "use client";
2
- import { jsx as o, jsxs as i } from "react/jsx-runtime";
3
- import { forwardRef as s } from "react";
2
+ import { jsx as r, jsxs as c } from "react/jsx-runtime";
3
+ import { forwardRef as s, useContext as v, createContext as y } from "react";
4
4
  import { Drawer as a } from "vaul";
5
+ import { X as N } from "../../icons/index.js";
5
6
  import { cn as n } from "../../lib/utils.js";
6
- const u = ({
7
+ import { useStrings as C } from "../../hooks/use-strings.js";
8
+ import { withReturnFocus as z } from "../../lib/return-focus.js";
9
+ const m = y("bottom"), T = ({
7
10
  shouldScaleBackground: t = !0,
8
- ...r
9
- }) => /* @__PURE__ */ o(a.Root, { shouldScaleBackground: t, ...r });
10
- u.displayName = "Drawer";
11
- const O = a.Trigger, w = a.Portal, H = a.Close, m = s(function({ className: r, ...e }, l) {
12
- return /* @__PURE__ */ o(
11
+ direction: e = "bottom",
12
+ ...o
13
+ }) => /* @__PURE__ */ r(m.Provider, { value: e, children: /* @__PURE__ */ r(
14
+ a.Root,
15
+ {
16
+ shouldScaleBackground: t,
17
+ direction: e,
18
+ ...o
19
+ }
20
+ ) });
21
+ T.displayName = "Drawer";
22
+ const I = a.Trigger, F = a.Portal, J = a.Close, f = s(function({ className: e, ...o }, l) {
23
+ return /* @__PURE__ */ r(
13
24
  a.Overlay,
14
25
  {
15
26
  ref: l,
16
- className: n("fixed inset-0 z-[var(--z-overlay)] bg-overlay", r),
17
- ...e
27
+ className: n("bg-overlay fixed inset-0 z-[var(--z-overlay)]", e),
28
+ ...o
18
29
  }
19
30
  );
20
31
  });
21
- m.displayName = "DrawerOverlay";
22
- const b = {
23
- bottom: "inset-x-0 bottom-0 mt-24 flex h-auto max-h-[90vh] flex-col rounded-t-xl border-t border-border",
24
- top: "inset-x-0 top-0 mb-24 flex h-auto max-h-[90vh] flex-col rounded-b-xl border-b border-border",
25
- left: "inset-y-0 left-0 flex h-full w-[420px] max-w-[90vw] flex-col rounded-r-xl border-r border-border",
26
- right: "inset-y-0 right-0 flex h-full w-[420px] max-w-[90vw] flex-col rounded-l-xl border-l border-border"
27
- }, D = {
32
+ f.displayName = "DrawerOverlay";
33
+ const O = {
34
+ bottom: "inset-x-0 bottom-0 mt-24 flex h-auto max-h-[90dvh] flex-col rounded-t-xl border-t border-border pb-[env(safe-area-inset-bottom)]",
35
+ top: "inset-x-0 top-0 mb-24 flex h-auto max-h-[90dvh] flex-col rounded-b-xl border-b border-border",
36
+ left: "inset-y-0 left-0 flex h-full w-full max-w-[min(26.25rem,90vw)] flex-col rounded-r-xl border-r border-border pl-[env(safe-area-inset-left)]",
37
+ right: "inset-y-0 right-0 flex h-full w-full max-w-[min(26.25rem,90vw)] flex-col rounded-l-xl border-l border-border pr-[env(safe-area-inset-right)]"
38
+ }, j = {
28
39
  bottom: "mx-auto mt-3 h-1.5 w-12 rounded-full bg-border",
29
40
  top: "mx-auto mb-3 h-1.5 w-12 rounded-full bg-border order-last",
30
41
  left: "mx-1.5 my-auto h-12 w-1.5 rounded-full bg-border order-last self-stretch shrink-0",
31
42
  right: "mx-1.5 my-auto h-12 w-1.5 rounded-full bg-border shrink-0 self-stretch"
32
- }, h = s(function({ className: r, direction: e = "bottom", hideHandle: l, children: f, ...c }, x) {
33
- const d = e === "left" || e === "right";
34
- return /* @__PURE__ */ i(w, { children: [
35
- /* @__PURE__ */ o(m, {}),
36
- /* @__PURE__ */ i(
43
+ }, k = s(function({
44
+ className: e,
45
+ direction: o,
46
+ hideHandle: l,
47
+ showClose: u = !0,
48
+ returnFocusTo: x,
49
+ onCloseAutoFocus: b,
50
+ children: w,
51
+ ...h
52
+ }, g) {
53
+ const p = v(m), i = o ?? p, D = C(), d = i === "left" || i === "right";
54
+ return /* @__PURE__ */ c(F, { children: [
55
+ /* @__PURE__ */ r(f, {}),
56
+ /* @__PURE__ */ c(
37
57
  a.Content,
38
58
  {
39
- ref: x,
59
+ ref: g,
60
+ onCloseAutoFocus: z(x, b),
40
61
  className: n(
41
62
  "bg-card fixed z-[var(--z-modal)]",
42
- b[e],
63
+ O[i],
43
64
  d && "flex-row",
44
- r
65
+ e
45
66
  ),
46
- ...c,
67
+ ...h,
47
68
  children: [
48
- !l && /* @__PURE__ */ o("div", { "aria-hidden": !0, className: D[e] }),
49
- /* @__PURE__ */ o("div", { className: n("min-h-0 min-w-0 flex-1", d && "flex flex-col"), children: f })
69
+ !l && /* @__PURE__ */ r("div", { "aria-hidden": !0, className: j[i] }),
70
+ /* @__PURE__ */ r("div", { className: n("min-h-0 min-w-0 flex-1", d && "flex flex-col"), children: w }),
71
+ u && /* @__PURE__ */ r(
72
+ a.Close,
73
+ {
74
+ "aria-label": D.drawer.close,
75
+ className: n(
76
+ "text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md",
77
+ "hover:bg-background-muted hover:text-foreground",
78
+ "focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
79
+ "transition-colors duration-[var(--duration-fast)]"
80
+ ),
81
+ children: /* @__PURE__ */ r(N, { className: "size-4", "aria-hidden": !0 })
82
+ }
83
+ )
50
84
  ]
51
85
  }
52
86
  )
53
87
  ] });
54
88
  });
55
- h.displayName = "DrawerContent";
56
- function p({ className: t, ...r }) {
57
- return /* @__PURE__ */ o("div", { className: n("grid gap-1 p-4 text-center sm:text-left", t), ...r });
89
+ k.displayName = "DrawerContent";
90
+ function H({ className: t, ...e }) {
91
+ return /* @__PURE__ */ r("div", { className: n("grid gap-1 p-4 text-center sm:text-left", t), ...e });
58
92
  }
59
- p.displayName = "DrawerHeader";
60
- function g({ className: t, ...r }) {
61
- return /* @__PURE__ */ o("div", { className: n("mt-auto flex flex-col gap-2 p-4", t), ...r });
93
+ H.displayName = "DrawerHeader";
94
+ function P({ className: t, ...e }) {
95
+ return /* @__PURE__ */ r("div", { className: n("mt-auto flex flex-col gap-2 p-4", t), ...e });
62
96
  }
63
- g.displayName = "DrawerFooter";
64
- const y = s(function({ className: r, ...e }, l) {
65
- return /* @__PURE__ */ o(
97
+ P.displayName = "DrawerFooter";
98
+ const R = s(function({ className: e, ...o }, l) {
99
+ return /* @__PURE__ */ r(
66
100
  a.Title,
67
101
  {
68
102
  ref: l,
69
- className: n("text-lg font-semibold", r),
70
- ...e
103
+ className: n("text-lg font-semibold", e),
104
+ ...o
71
105
  }
72
106
  );
73
107
  });
74
- y.displayName = "DrawerTitle";
75
- const v = s(function({ className: r, ...e }, l) {
76
- return /* @__PURE__ */ o(
108
+ R.displayName = "DrawerTitle";
109
+ const S = s(function({ className: e, ...o }, l) {
110
+ return /* @__PURE__ */ r(
77
111
  a.Description,
78
112
  {
79
113
  ref: l,
80
- className: n("text-foreground-muted text-sm", r),
81
- ...e
114
+ className: n("text-foreground-muted text-sm", e),
115
+ ...o
82
116
  }
83
117
  );
84
118
  });
85
- v.displayName = "DrawerDescription";
119
+ S.displayName = "DrawerDescription";
86
120
  export {
87
- u as Drawer,
88
- H as DrawerClose,
89
- h as DrawerContent,
90
- v as DrawerDescription,
91
- g as DrawerFooter,
92
- p as DrawerHeader,
93
- m as DrawerOverlay,
94
- w as DrawerPortal,
95
- y as DrawerTitle,
96
- O as DrawerTrigger
121
+ T as Drawer,
122
+ J as DrawerClose,
123
+ k as DrawerContent,
124
+ S as DrawerDescription,
125
+ P as DrawerFooter,
126
+ H as DrawerHeader,
127
+ f as DrawerOverlay,
128
+ F as DrawerPortal,
129
+ R as DrawerTitle,
130
+ I as DrawerTrigger
97
131
  };
98
132
  //# sourceMappingURL=Drawer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.js","sources":["../../../src/components/ui/Drawer.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n} from 'react';\nimport { Drawer as DrawerPrimitive } from 'vaul';\nimport { cn } from '@/lib/utils';\n\ntype Direction = 'top' | 'right' | 'bottom' | 'left';\n\nexport const Drawer = ({\n shouldScaleBackground = true,\n ...props\n}: ComponentPropsWithoutRef<typeof DrawerPrimitive.Root>) => (\n <DrawerPrimitive.Root shouldScaleBackground={shouldScaleBackground} {...props} />\n);\nDrawer.displayName = 'Drawer';\n\nexport const DrawerTrigger = DrawerPrimitive.Trigger;\nexport const DrawerPortal = DrawerPrimitive.Portal;\nexport const DrawerClose = DrawerPrimitive.Close;\n\nexport const DrawerOverlay = forwardRef<\n ElementRef<typeof DrawerPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>\n>(function DrawerOverlay({ className, ...props }, ref) {\n return (\n <DrawerPrimitive.Overlay\n ref={ref}\n className={cn('fixed inset-0 z-[var(--z-overlay)] bg-overlay', className)}\n {...props}\n />\n );\n});\nDrawerOverlay.displayName = 'DrawerOverlay';\n\nconst directionStyles: Record<Direction, string> = {\n bottom:\n 'inset-x-0 bottom-0 mt-24 flex h-auto max-h-[90vh] flex-col rounded-t-xl border-t border-border',\n top: 'inset-x-0 top-0 mb-24 flex h-auto max-h-[90vh] flex-col rounded-b-xl border-b border-border',\n left: 'inset-y-0 left-0 flex h-full w-[420px] max-w-[90vw] flex-col rounded-r-xl border-r border-border',\n right:\n 'inset-y-0 right-0 flex h-full w-[420px] max-w-[90vw] flex-col rounded-l-xl border-l border-border',\n};\n\nconst handleStyles: Record<Direction, string> = {\n bottom: 'mx-auto mt-3 h-1.5 w-12 rounded-full bg-border',\n top: 'mx-auto mb-3 h-1.5 w-12 rounded-full bg-border order-last',\n left: 'mx-1.5 my-auto h-12 w-1.5 rounded-full bg-border order-last self-stretch shrink-0',\n right: 'mx-1.5 my-auto h-12 w-1.5 rounded-full bg-border shrink-0 self-stretch',\n};\n\nexport interface DrawerContentProps extends ComponentPropsWithoutRef<\n typeof DrawerPrimitive.Content\n> {\n /** Side the drawer slides in from. Default `bottom`. */\n direction?: Direction;\n /** Hide the drag handle. */\n hideHandle?: boolean;\n}\n\nexport const DrawerContent = forwardRef<\n ElementRef<typeof DrawerPrimitive.Content>,\n DrawerContentProps\n>(function DrawerContent({ className, direction = 'bottom', hideHandle, children, ...props }, ref) {\n const isHorizontal = direction === 'left' || direction === 'right';\n return (\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerPrimitive.Content\n ref={ref}\n className={cn(\n 'bg-card fixed z-[var(--z-modal)]',\n directionStyles[direction],\n isHorizontal && 'flex-row',\n className,\n )}\n {...props}\n >\n {!hideHandle && <div aria-hidden className={handleStyles[direction]} />}\n <div className={cn('min-h-0 min-w-0 flex-1', isHorizontal && 'flex flex-col')}>\n {children}\n </div>\n </DrawerPrimitive.Content>\n </DrawerPortal>\n );\n});\nDrawerContent.displayName = 'DrawerContent';\n\nexport function DrawerHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('grid gap-1 p-4 text-center sm:text-left', className)} {...props} />;\n}\nDrawerHeader.displayName = 'DrawerHeader';\n\nexport function DrawerFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />;\n}\nDrawerFooter.displayName = 'DrawerFooter';\n\nexport const DrawerTitle = forwardRef<\n ElementRef<typeof DrawerPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>\n>(function DrawerTitle({ className, ...props }, ref) {\n return (\n <DrawerPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold', className)}\n {...props}\n />\n );\n});\nDrawerTitle.displayName = 'DrawerTitle';\n\nexport const DrawerDescription = forwardRef<\n ElementRef<typeof DrawerPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>\n>(function DrawerDescription({ className, ...props }, ref) {\n return (\n <DrawerPrimitive.Description\n ref={ref}\n className={cn('text-foreground-muted text-sm', className)}\n {...props}\n />\n );\n});\nDrawerDescription.displayName = 'DrawerDescription';\n"],"names":["Drawer","shouldScaleBackground","props","DrawerPrimitive","DrawerTrigger","DrawerPortal","DrawerClose","DrawerOverlay","forwardRef","className","ref","jsx","cn","directionStyles","handleStyles","DrawerContent","direction","hideHandle","children","isHorizontal","jsxs","DrawerHeader","DrawerFooter","DrawerTitle","DrawerDescription"],"mappings":";;;;;AAaO,MAAMA,IAAS,CAAC;AAAA,EACrB,uBAAAC,IAAwB;AAAA,EACxB,GAAGC;AACL,wBACGC,EAAgB,MAAhB,EAAqB,uBAAAF,GAA+C,GAAGC,EAAA,CAAO;AAEjFF,EAAO,cAAc;AAEd,MAAMI,IAAgBD,EAAgB,SAChCE,IAAeF,EAAgB,QAC/BG,IAAcH,EAAgB,OAE9BI,IAAgBC,EAG3B,SAAuB,EAAE,WAAAC,GAAW,GAAGP,EAAA,GAASQ,GAAK;AACrD,SACE,gBAAAC;AAAA,IAACR,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAO;AAAA,MACA,WAAWE,EAAG,iDAAiDH,CAAS;AAAA,MACvE,GAAGP;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDK,EAAc,cAAc;AAE5B,MAAMM,IAA6C;AAAA,EACjD,QACE;AAAA,EACF,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OACE;AACJ,GAEMC,IAA0C;AAAA,EAC9C,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AACT,GAWaC,IAAgBP,EAG3B,SAAuB,EAAE,WAAAC,GAAW,WAAAO,IAAY,UAAU,YAAAC,GAAY,UAAAC,GAAU,GAAGhB,EAAA,GAASQ,GAAK;AACjG,QAAMS,IAAeH,MAAc,UAAUA,MAAc;AAC3D,2BACGX,GAAA,EACC,UAAA;AAAA,IAAA,gBAAAM,EAACJ,GAAA,EAAc;AAAA,IACf,gBAAAa;AAAA,MAACjB,EAAgB;AAAA,MAAhB;AAAA,QACC,KAAAO;AAAA,QACA,WAAWE;AAAA,UACT;AAAA,UACAC,EAAgBG,CAAS;AAAA,UACzBG,KAAgB;AAAA,UAChBV;AAAA,QAAA;AAAA,QAED,GAAGP;AAAA,QAEH,UAAA;AAAA,UAAA,CAACe,uBAAe,OAAA,EAAI,eAAW,IAAC,WAAWH,EAAaE,CAAS,GAAG;AAAA,UACrE,gBAAAL,EAAC,SAAI,WAAWC,EAAG,0BAA0BO,KAAgB,eAAe,GACzE,UAAAD,EAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ,CAAC;AACDH,EAAc,cAAc;AAErB,SAASM,EAAa,EAAE,WAAAZ,GAAW,GAAGP,KAAyC;AACpF,SAAO,gBAAAS,EAAC,SAAI,WAAWC,EAAG,2CAA2CH,CAAS,GAAI,GAAGP,GAAO;AAC9F;AACAmB,EAAa,cAAc;AAEpB,SAASC,EAAa,EAAE,WAAAb,GAAW,GAAGP,KAAyC;AACpF,SAAO,gBAAAS,EAAC,SAAI,WAAWC,EAAG,mCAAmCH,CAAS,GAAI,GAAGP,GAAO;AACtF;AACAoB,EAAa,cAAc;AAEpB,MAAMC,IAAcf,EAGzB,SAAqB,EAAE,WAAAC,GAAW,GAAGP,EAAA,GAASQ,GAAK;AACnD,SACE,gBAAAC;AAAA,IAACR,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAO;AAAA,MACA,WAAWE,EAAG,yBAAyBH,CAAS;AAAA,MAC/C,GAAGP;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDqB,EAAY,cAAc;AAEnB,MAAMC,IAAoBhB,EAG/B,SAA2B,EAAE,WAAAC,GAAW,GAAGP,EAAA,GAASQ,GAAK;AACzD,SACE,gBAAAC;AAAA,IAACR,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAO;AAAA,MACA,WAAWE,EAAG,iCAAiCH,CAAS;AAAA,MACvD,GAAGP;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDsB,EAAkB,cAAc;"}
1
+ {"version":3,"file":"Drawer.js","sources":["../../../src/components/ui/Drawer.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n forwardRef,\n useContext,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n} from 'react';\nimport { Drawer as DrawerPrimitive } from 'vaul';\nimport { X } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { withReturnFocus, type ReturnFocusRef } from '@/lib/return-focus';\n\ntype Direction = 'top' | 'right' | 'bottom' | 'left';\n\n// vaul needs `direction` on Root for its drag physics; DrawerContent reads it\n// back from here so the side only has to be declared once.\nconst DrawerDirectionContext = createContext<Direction>('bottom');\n\nexport const Drawer = ({\n shouldScaleBackground = true,\n direction = 'bottom',\n ...props\n}: ComponentPropsWithoutRef<typeof DrawerPrimitive.Root>) => (\n <DrawerDirectionContext.Provider value={direction}>\n <DrawerPrimitive.Root\n shouldScaleBackground={shouldScaleBackground}\n direction={direction}\n {...props}\n />\n </DrawerDirectionContext.Provider>\n);\nDrawer.displayName = 'Drawer';\n\nexport const DrawerTrigger = DrawerPrimitive.Trigger;\nexport const DrawerPortal = DrawerPrimitive.Portal;\nexport const DrawerClose = DrawerPrimitive.Close;\n\nexport const DrawerOverlay = forwardRef<\n ElementRef<typeof DrawerPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>\n>(function DrawerOverlay({ className, ...props }, ref) {\n return (\n <DrawerPrimitive.Overlay\n ref={ref}\n className={cn('bg-overlay fixed inset-0 z-[var(--z-overlay)]', className)}\n {...props}\n />\n );\n});\nDrawerOverlay.displayName = 'DrawerOverlay';\n\n// Edge-anchored sides pad by the matching safe-area inset (consumers set viewport-fit=cover).\nconst directionStyles: Record<Direction, string> = {\n bottom:\n 'inset-x-0 bottom-0 mt-24 flex h-auto max-h-[90dvh] flex-col rounded-t-xl border-t border-border pb-[env(safe-area-inset-bottom)]',\n top: 'inset-x-0 top-0 mb-24 flex h-auto max-h-[90dvh] flex-col rounded-b-xl border-b border-border',\n left: 'inset-y-0 left-0 flex h-full w-full max-w-[min(26.25rem,90vw)] flex-col rounded-r-xl border-r border-border pl-[env(safe-area-inset-left)]',\n right:\n 'inset-y-0 right-0 flex h-full w-full max-w-[min(26.25rem,90vw)] flex-col rounded-l-xl border-l border-border pr-[env(safe-area-inset-right)]',\n};\n\nconst handleStyles: Record<Direction, string> = {\n bottom: 'mx-auto mt-3 h-1.5 w-12 rounded-full bg-border',\n top: 'mx-auto mb-3 h-1.5 w-12 rounded-full bg-border order-last',\n left: 'mx-1.5 my-auto h-12 w-1.5 rounded-full bg-border order-last self-stretch shrink-0',\n right: 'mx-1.5 my-auto h-12 w-1.5 rounded-full bg-border shrink-0 self-stretch',\n};\n\nexport interface DrawerContentProps extends ComponentPropsWithoutRef<\n typeof DrawerPrimitive.Content\n> {\n /**\n * Side the drawer slides in from. Prefer setting `direction` on `<Drawer>`\n * (vaul needs it there for drag physics); this prop only overrides the\n * visual placement.\n */\n direction?: Direction;\n /** Hide the drag handle. */\n hideHandle?: boolean;\n /** Show the close (×) button. Default `true`. */\n showClose?: boolean;\n /**\n * Element to focus when the overlay closes. Overrides Radix's default\n * (the element focused when the content mounted), which is `<body>` for\n * controlled overlays opened from a pointer click on a non-focusable /\n * tooltip-wrapped trigger. A consumer `onCloseAutoFocus` runs first and\n * wins if it calls `preventDefault()`.\n */\n returnFocusTo?: ReturnFocusRef;\n}\n\nexport const DrawerContent = forwardRef<\n ElementRef<typeof DrawerPrimitive.Content>,\n DrawerContentProps\n>(function DrawerContent(\n {\n className,\n direction: directionProp,\n hideHandle,\n showClose = true,\n returnFocusTo,\n onCloseAutoFocus,\n children,\n ...props\n },\n ref,\n) {\n const rootDirection = useContext(DrawerDirectionContext);\n const direction = directionProp ?? rootDirection;\n const strings = useStrings();\n const isHorizontal = direction === 'left' || direction === 'right';\n return (\n <DrawerPortal>\n <DrawerOverlay />\n <DrawerPrimitive.Content\n ref={ref}\n onCloseAutoFocus={withReturnFocus(returnFocusTo, onCloseAutoFocus)}\n className={cn(\n 'bg-card fixed z-[var(--z-modal)]',\n directionStyles[direction],\n isHorizontal && 'flex-row',\n className,\n )}\n {...props}\n >\n {!hideHandle && <div aria-hidden className={handleStyles[direction]} />}\n <div className={cn('min-h-0 min-w-0 flex-1', isHorizontal && 'flex flex-col')}>\n {children}\n </div>\n {showClose && (\n <DrawerPrimitive.Close\n aria-label={strings.drawer.close}\n className={cn(\n 'text-foreground-subtle absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md',\n 'hover:bg-background-muted hover:text-foreground',\n 'focus-visible:ring-ring focus-visible:ring-offset-card outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'transition-colors duration-[var(--duration-fast)]',\n )}\n >\n <X className=\"size-4\" aria-hidden />\n </DrawerPrimitive.Close>\n )}\n </DrawerPrimitive.Content>\n </DrawerPortal>\n );\n});\nDrawerContent.displayName = 'DrawerContent';\n\nexport function DrawerHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('grid gap-1 p-4 text-center sm:text-left', className)} {...props} />;\n}\nDrawerHeader.displayName = 'DrawerHeader';\n\nexport function DrawerFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />;\n}\nDrawerFooter.displayName = 'DrawerFooter';\n\nexport const DrawerTitle = forwardRef<\n ElementRef<typeof DrawerPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>\n>(function DrawerTitle({ className, ...props }, ref) {\n return (\n <DrawerPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold', className)}\n {...props}\n />\n );\n});\nDrawerTitle.displayName = 'DrawerTitle';\n\nexport const DrawerDescription = forwardRef<\n ElementRef<typeof DrawerPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>\n>(function DrawerDescription({ className, ...props }, ref) {\n return (\n <DrawerPrimitive.Description\n ref={ref}\n className={cn('text-foreground-muted text-sm', className)}\n {...props}\n />\n );\n});\nDrawerDescription.displayName = 'DrawerDescription';\n"],"names":["DrawerDirectionContext","createContext","Drawer","shouldScaleBackground","direction","props","jsx","DrawerPrimitive","DrawerTrigger","DrawerPortal","DrawerClose","DrawerOverlay","forwardRef","className","ref","cn","directionStyles","handleStyles","DrawerContent","directionProp","hideHandle","showClose","returnFocusTo","onCloseAutoFocus","children","rootDirection","useContext","strings","useStrings","isHorizontal","jsxs","withReturnFocus","X","DrawerHeader","DrawerFooter","DrawerTitle","DrawerDescription"],"mappings":";;;;;;;;AAoBA,MAAMA,IAAyBC,EAAyB,QAAQ,GAEnDC,IAAS,CAAC;AAAA,EACrB,uBAAAC,IAAwB;AAAA,EACxB,WAAAC,IAAY;AAAA,EACZ,GAAGC;AACL,MACE,gBAAAC,EAACN,EAAuB,UAAvB,EAAgC,OAAOI,GACtC,UAAA,gBAAAE;AAAA,EAACC,EAAgB;AAAA,EAAhB;AAAA,IACC,uBAAAJ;AAAA,IACA,WAAAC;AAAA,IACC,GAAGC;AAAA,EAAA;AACN,EAAA,CACF;AAEFH,EAAO,cAAc;AAEd,MAAMM,IAAgBD,EAAgB,SAChCE,IAAeF,EAAgB,QAC/BG,IAAcH,EAAgB,OAE9BI,IAAgBC,EAG3B,SAAuB,EAAE,WAAAC,GAAW,GAAGR,EAAA,GAASS,GAAK;AACrD,SACE,gBAAAR;AAAA,IAACC,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAO;AAAA,MACA,WAAWC,EAAG,iDAAiDF,CAAS;AAAA,MACvE,GAAGR;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACDM,EAAc,cAAc;AAG5B,MAAMK,IAA6C;AAAA,EACjD,QACE;AAAA,EACF,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OACE;AACJ,GAEMC,IAA0C;AAAA,EAC9C,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AACT,GAyBaC,IAAgBN,EAG3B,SACA;AAAA,EACE,WAAAC;AAAA,EACA,WAAWM;AAAA,EACX,YAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,eAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGnB;AACL,GACAS,GACA;AACA,QAAMW,IAAgBC,EAAW1B,CAAsB,GACjDI,IAAYe,KAAiBM,GAC7BE,IAAUC,EAAA,GACVC,IAAezB,MAAc,UAAUA,MAAc;AAC3D,2BACGK,GAAA,EACC,UAAA;AAAA,IAAA,gBAAAH,EAACK,GAAA,EAAc;AAAA,IACf,gBAAAmB;AAAA,MAACvB,EAAgB;AAAA,MAAhB;AAAA,QACC,KAAAO;AAAA,QACA,kBAAkBiB,EAAgBT,GAAeC,CAAgB;AAAA,QACjE,WAAWR;AAAA,UACT;AAAA,UACAC,EAAgBZ,CAAS;AAAA,UACzByB,KAAgB;AAAA,UAChBhB;AAAA,QAAA;AAAA,QAED,GAAGR;AAAA,QAEH,UAAA;AAAA,UAAA,CAACe,uBAAe,OAAA,EAAI,eAAW,IAAC,WAAWH,EAAab,CAAS,GAAG;AAAA,UACrE,gBAAAE,EAAC,SAAI,WAAWS,EAAG,0BAA0Bc,KAAgB,eAAe,GACzE,UAAAL,GACH;AAAA,UACCH,KACC,gBAAAf;AAAA,YAACC,EAAgB;AAAA,YAAhB;AAAA,cACC,cAAYoB,EAAQ,OAAO;AAAA,cAC3B,WAAWZ;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,cAGF,UAAA,gBAAAT,EAAC0B,GAAA,EAAE,WAAU,UAAS,eAAW,GAAA,CAAC;AAAA,YAAA;AAAA,UAAA;AAAA,QACpC;AAAA,MAAA;AAAA,IAAA;AAAA,EAEJ,GACF;AAEJ,CAAC;AACDd,EAAc,cAAc;AAErB,SAASe,EAAa,EAAE,WAAApB,GAAW,GAAGR,KAAyC;AACpF,SAAO,gBAAAC,EAAC,SAAI,WAAWS,EAAG,2CAA2CF,CAAS,GAAI,GAAGR,GAAO;AAC9F;AACA4B,EAAa,cAAc;AAEpB,SAASC,EAAa,EAAE,WAAArB,GAAW,GAAGR,KAAyC;AACpF,SAAO,gBAAAC,EAAC,SAAI,WAAWS,EAAG,mCAAmCF,CAAS,GAAI,GAAGR,GAAO;AACtF;AACA6B,EAAa,cAAc;AAEpB,MAAMC,IAAcvB,EAGzB,SAAqB,EAAE,WAAAC,GAAW,GAAGR,EAAA,GAASS,GAAK;AACnD,SACE,gBAAAR;AAAA,IAACC,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAO;AAAA,MACA,WAAWC,EAAG,yBAAyBF,CAAS;AAAA,MAC/C,GAAGR;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACD8B,EAAY,cAAc;AAEnB,MAAMC,IAAoBxB,EAG/B,SAA2B,EAAE,WAAAC,GAAW,GAAGR,EAAA,GAASS,GAAK;AACzD,SACE,gBAAAR;AAAA,IAACC,EAAgB;AAAA,IAAhB;AAAA,MACC,KAAAO;AAAA,MACA,WAAWC,EAAG,iCAAiCF,CAAS;AAAA,MACvD,GAAGR;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AACD+B,EAAkB,cAAc;"}