@tomny-dev/uzi 0.1.4 → 0.1.6

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.
package/dist/index.cjs CHANGED
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  "use strict";
3
+ var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
6
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
9
  var __export = (target, all) => {
8
10
  for (var name in all)
@@ -16,24 +18,61 @@ var __copyProps = (to, from, except, desc) => {
16
18
  }
17
19
  return to;
18
20
  };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
19
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
30
 
21
31
  // src/index.ts
22
32
  var index_exports = {};
23
33
  __export(index_exports, {
34
+ Alert: () => Alert,
24
35
  AppShell: () => AppShell,
36
+ Avatar: () => Avatar,
37
+ AvatarFallback: () => AvatarFallback,
38
+ AvatarImage: () => AvatarImage,
25
39
  Button: () => Button,
26
40
  Card: () => Card,
41
+ Checkbox: () => Checkbox,
27
42
  Dropdown: () => Dropdown,
43
+ DropdownMenu: () => DropdownMenu,
44
+ DropdownMenuCheckboxItem: () => DropdownMenuCheckboxItem,
45
+ DropdownMenuContent: () => DropdownMenuContent,
46
+ DropdownMenuGroup: () => DropdownMenuGroup,
47
+ DropdownMenuItem: () => DropdownMenuItem,
48
+ DropdownMenuLabel: () => DropdownMenuLabel,
49
+ DropdownMenuPortal: () => DropdownMenuPortal,
50
+ DropdownMenuRadioGroup: () => DropdownMenuRadioGroup,
51
+ DropdownMenuRadioItem: () => DropdownMenuRadioItem,
52
+ DropdownMenuSeparator: () => DropdownMenuSeparator,
53
+ DropdownMenuSub: () => DropdownMenuSub,
54
+ DropdownMenuSubContent: () => DropdownMenuSubContent,
55
+ DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
56
+ DropdownMenuTrigger: () => DropdownMenuTrigger,
57
+ Input: () => Input,
58
+ Label: () => Label,
28
59
  Modal: () => Modal,
60
+ ModalOverlay: () => ModalOverlay,
29
61
  Pill: () => Pill,
30
62
  SidebarNav: () => SidebarNav,
63
+ ThemeProvider: () => ThemeProvider,
64
+ ThemeToggleButton: () => ThemeToggleButton,
31
65
  ToastProvider: () => ToastProvider,
66
+ TopBar: () => TopBar,
32
67
  cx: () => cx,
68
+ useTheme: () => useTheme,
33
69
  useToast: () => useToast
34
70
  });
35
71
  module.exports = __toCommonJS(index_exports);
36
72
 
73
+ // src/components/button/Button.tsx
74
+ var import_react_slot = require("@radix-ui/react-slot");
75
+
37
76
  // src/utils/cx.ts
38
77
  function cx(...values) {
39
78
  return values.filter(Boolean).join(" ");
@@ -44,22 +83,49 @@ var button_default = {};
44
83
 
45
84
  // src/components/button/Button.tsx
46
85
  var import_jsx_runtime = require("react/jsx-runtime");
86
+ var variantClass = {
87
+ default: button_default["variant-primary"],
88
+ primary: button_default["variant-primary"],
89
+ secondary: button_default["variant-secondary"],
90
+ outline: button_default["variant-outline"],
91
+ ghost: button_default["variant-ghost"],
92
+ destructive: button_default["variant-destructive"],
93
+ link: button_default["variant-link"]
94
+ };
95
+ var sizeClass = {
96
+ default: button_default["size-md"],
97
+ sm: button_default["size-sm"],
98
+ md: button_default["size-md"],
99
+ lg: button_default["size-lg"],
100
+ icon: button_default["size-icon"]
101
+ };
47
102
  function Button({
48
103
  as,
49
- variant = "primary",
50
- size = "md",
104
+ variant = "default",
105
+ size = "default",
51
106
  className,
52
107
  children,
108
+ asChild = false,
53
109
  ...rest
54
110
  }) {
55
111
  const classes = cx(
56
112
  button_default.button,
57
- button_default[`variant-${variant}`],
58
- button_default[`size-${size}`],
113
+ variantClass[variant],
114
+ sizeClass[size],
59
115
  className
60
116
  );
117
+ if (asChild) {
118
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_slot.Slot, { className: classes, ...rest, children });
119
+ }
61
120
  if (as === "a") {
62
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: classes, ...rest, children });
121
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
122
+ "a",
123
+ {
124
+ className: classes,
125
+ ...rest,
126
+ children
127
+ }
128
+ );
63
129
  }
64
130
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
65
131
  "button",
@@ -72,11 +138,57 @@ function Button({
72
138
  );
73
139
  }
74
140
 
141
+ // src/components/avatar/Avatar.tsx
142
+ var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"), 1);
143
+
144
+ // src/components/avatar/avatar.module.css
145
+ var avatar_default = {};
146
+
147
+ // src/components/avatar/Avatar.tsx
148
+ var import_jsx_runtime2 = require("react/jsx-runtime");
149
+ function Avatar({
150
+ className,
151
+ size = "md",
152
+ ...props
153
+ }) {
154
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
155
+ AvatarPrimitive.Root,
156
+ {
157
+ className: cx(avatar_default.avatar, avatar_default[`size-${size}`], className),
158
+ ...props
159
+ }
160
+ );
161
+ }
162
+ function AvatarImage({
163
+ className,
164
+ ...props
165
+ }) {
166
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
167
+ AvatarPrimitive.Image,
168
+ {
169
+ className: cx(avatar_default.image, className),
170
+ ...props
171
+ }
172
+ );
173
+ }
174
+ function AvatarFallback({
175
+ className,
176
+ ...props
177
+ }) {
178
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
179
+ AvatarPrimitive.Fallback,
180
+ {
181
+ className: cx(avatar_default.fallback, className),
182
+ ...props
183
+ }
184
+ );
185
+ }
186
+
75
187
  // src/components/card/card.module.css
76
188
  var card_default = {};
77
189
 
78
190
  // src/components/card/Card.tsx
79
- var import_jsx_runtime2 = require("react/jsx-runtime");
191
+ var import_jsx_runtime3 = require("react/jsx-runtime");
80
192
  function Card({
81
193
  as,
82
194
  tone = "default",
@@ -95,14 +207,14 @@ function Card({
95
207
  interactive && card_default.interactive,
96
208
  className
97
209
  );
98
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, { className: classes, ...rest, children });
210
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Component, { className: classes, ...rest, children });
99
211
  }
100
212
 
101
213
  // src/components/pill/pill.module.css
102
214
  var pill_default = {};
103
215
 
104
216
  // src/components/pill/Pill.tsx
105
- var import_jsx_runtime3 = require("react/jsx-runtime");
217
+ var import_jsx_runtime4 = require("react/jsx-runtime");
106
218
  function Pill({
107
219
  as,
108
220
  tone = "neutral",
@@ -114,9 +226,9 @@ function Pill({
114
226
  }) {
115
227
  const Component = as ?? "span";
116
228
  const classes = cx(pill_default.pill, pill_default[`tone-${tone}`], pill_default[`size-${size}`], className);
117
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Component, { className: classes, ...rest, children: [
118
- icon ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: pill_default.icon, "aria-hidden": "true", children: icon }) : null,
119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: pill_default.content, children })
229
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Component, { className: classes, ...rest, children: [
230
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: pill_default.icon, "aria-hidden": "true", children: icon }) : null,
231
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: pill_default.content, children })
120
232
  ] });
121
233
  }
122
234
 
@@ -127,14 +239,27 @@ var import_react = require("react");
127
239
  var modal_default = {};
128
240
 
129
241
  // src/components/modal/Modal.tsx
130
- var import_jsx_runtime4 = require("react/jsx-runtime");
131
- function Modal({ open, onClose, title, subtitle, size = "md", children, footer }) {
242
+ var import_jsx_runtime5 = require("react/jsx-runtime");
243
+ function ModalOverlay({ open, onClose, className, children }) {
132
244
  const mouseDownOnBackdrop = (0, import_react.useRef)(false);
245
+ (0, import_react.useEffect)(() => {
246
+ if (!open) return;
247
+ const handleKeyDown = (e) => {
248
+ if (e.key === "Escape") {
249
+ e.stopPropagation();
250
+ onClose();
251
+ }
252
+ };
253
+ window.addEventListener("keydown", handleKeyDown, true);
254
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
255
+ }, [open, onClose]);
133
256
  if (!open) return null;
134
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
257
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
135
258
  "div",
136
259
  {
137
- className: modal_default.backdrop,
260
+ className: cx(modal_default.backdrop, className),
261
+ role: "dialog",
262
+ "aria-modal": "true",
138
263
  onMouseDown: (e) => {
139
264
  mouseDownOnBackdrop.current = e.target === e.currentTarget;
140
265
  },
@@ -142,23 +267,35 @@ function Modal({ open, onClose, title, subtitle, size = "md", children, footer }
142
267
  if (mouseDownOnBackdrop.current && e.target === e.currentTarget) onClose();
143
268
  mouseDownOnBackdrop.current = false;
144
269
  },
145
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cx(modal_default.modal, modal_default[`size-${size}`]), children: [
146
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: modal_default.header, children: [
147
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: modal_default.titles, children: [
148
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: modal_default.title, children: title }),
149
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: modal_default.subtitle, children: subtitle })
150
- ] }),
151
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: modal_default.closeButton, onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
152
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
153
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
154
- ] }) })
155
- ] }),
156
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: modal_default.body, children }),
157
- footer && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: modal_default.footer, children: footer })
158
- ] })
270
+ children
159
271
  }
160
272
  );
161
273
  }
274
+ function Modal({ open, onClose, title, subtitle, size = "md", children, footer }) {
275
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModalOverlay, { open, onClose, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cx(modal_default.modal, modal_default[`size-${size}`]), children: [
276
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: modal_default.header, children: [
277
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: modal_default.titles, children: [
278
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: modal_default.title, children: title }),
279
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: modal_default.subtitle, children: subtitle })
280
+ ] }),
281
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: modal_default.closeButton, onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
282
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
283
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
284
+ ] }) })
285
+ ] }),
286
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: modal_default.body, children }),
287
+ footer && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: modal_default.footer, children: footer })
288
+ ] }) });
289
+ }
290
+
291
+ // src/components/alert/alert.module.css
292
+ var alert_default = {};
293
+
294
+ // src/components/alert/Alert.tsx
295
+ var import_jsx_runtime6 = require("react/jsx-runtime");
296
+ function Alert({ tone, children, className }) {
297
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cx(alert_default.alert, alert_default[tone], className), role: "alert", children });
298
+ }
162
299
 
163
300
  // src/components/toast/ToastContext.tsx
164
301
  var import_react2 = require("react");
@@ -167,7 +304,7 @@ var import_react2 = require("react");
167
304
  var toast_default = {};
168
305
 
169
306
  // src/components/toast/ToastContext.tsx
170
- var import_jsx_runtime5 = require("react/jsx-runtime");
307
+ var import_jsx_runtime7 = require("react/jsx-runtime");
171
308
  var DEFAULT_CONFIG = {
172
309
  position: "top-right",
173
310
  maxToasts: 5,
@@ -237,9 +374,9 @@ function ToastProvider({
237
374
  () => ({ toasts, push, success, error, warning, info, dismiss, dismissAll }),
238
375
  [toasts, push, success, error, warning, info, dismiss, dismissAll]
239
376
  );
240
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ToastContext.Provider, { value, children: [
377
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ToastContext.Provider, { value, children: [
241
378
  children,
242
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
379
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
243
380
  ToastContainer,
244
381
  {
245
382
  toasts,
@@ -282,14 +419,14 @@ function ToastContainer({
282
419
  return toast_default.topRight;
283
420
  }
284
421
  })();
285
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
422
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
286
423
  "div",
287
424
  {
288
425
  className: cx(toast_default.stack, posClass),
289
426
  role: "presentation",
290
427
  onMouseEnter: () => pauseOnHover && onPauseChange(true),
291
428
  onMouseLeave: () => pauseOnHover && onPauseChange(false),
292
- children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ToastItem, { toast, isPaused, onDismiss }, toast.id))
429
+ children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastItem, { toast, isPaused, onDismiss }, toast.id))
293
430
  }
294
431
  );
295
432
  }
@@ -351,11 +488,11 @@ function ToastItem({
351
488
  }
352
489
  }, [isPaused, schedule, toast.duration]);
353
490
  const icon = getIcon(toast.type);
354
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cx(toast_default.toast, exiting && toast_default.exit), style: styleVars, role: "status", "aria-live": "polite", children: [
355
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: toast_default.icon, "aria-hidden": true, children: icon }),
356
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: toast_default.body, children: [
357
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: toast_default.message, children: toast.message }),
358
- toast.action && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: toast_default.actions, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
491
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cx(toast_default.toast, exiting && toast_default.exit), style: styleVars, role: "status", "aria-live": "polite", children: [
492
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: toast_default.icon, "aria-hidden": true, children: icon }),
493
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: toast_default.body, children: [
494
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: toast_default.message, children: toast.message }),
495
+ toast.action && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: toast_default.actions, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
359
496
  "button",
360
497
  {
361
498
  type: "button",
@@ -368,14 +505,14 @@ function ToastItem({
368
505
  }
369
506
  ) })
370
507
  ] }),
371
- toast.dismissible !== false && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
508
+ toast.dismissible !== false && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
372
509
  "button",
373
510
  {
374
511
  type: "button",
375
512
  className: toast_default.closeButton,
376
513
  onClick: triggerDismiss,
377
514
  "aria-label": "Dismiss notification",
378
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
515
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
379
516
  "path",
380
517
  {
381
518
  d: "M11 3L3 11M3 3l8 8",
@@ -447,6 +584,65 @@ function getIcon(type) {
447
584
  }
448
585
  }
449
586
 
587
+ // src/components/input/Input.tsx
588
+ var React = __toESM(require("react"), 1);
589
+
590
+ // src/components/input/input.module.css
591
+ var input_default = {};
592
+
593
+ // src/components/input/Input.tsx
594
+ var import_jsx_runtime8 = require("react/jsx-runtime");
595
+ var Input = React.forwardRef(
596
+ ({ className, type, ...props }, ref) => {
597
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
598
+ "input",
599
+ {
600
+ ref,
601
+ type,
602
+ className: cx(input_default.input, className),
603
+ ...props
604
+ }
605
+ );
606
+ }
607
+ );
608
+ Input.displayName = "Input";
609
+
610
+ // src/components/label/Label.tsx
611
+ var React2 = __toESM(require("react"), 1);
612
+
613
+ // src/components/label/label.module.css
614
+ var label_default = {};
615
+
616
+ // src/components/label/Label.tsx
617
+ var import_jsx_runtime9 = require("react/jsx-runtime");
618
+ var Label = React2.forwardRef(
619
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { ref, className: cx(label_default.label, className), ...props })
620
+ );
621
+ Label.displayName = "Label";
622
+
623
+ // src/components/checkbox/Checkbox.tsx
624
+ var React3 = __toESM(require("react"), 1);
625
+
626
+ // src/components/checkbox/checkbox.module.css
627
+ var checkbox_default = {};
628
+
629
+ // src/components/checkbox/Checkbox.tsx
630
+ var import_jsx_runtime10 = require("react/jsx-runtime");
631
+ var Checkbox = React3.forwardRef(
632
+ ({ className, ...props }, ref) => {
633
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
634
+ "input",
635
+ {
636
+ ref,
637
+ type: "checkbox",
638
+ className: cx(checkbox_default.checkbox, className),
639
+ ...props
640
+ }
641
+ );
642
+ }
643
+ );
644
+ Checkbox.displayName = "Checkbox";
645
+
450
646
  // src/components/dropdown/Dropdown.tsx
451
647
  var import_react3 = require("react");
452
648
 
@@ -454,7 +650,7 @@ var import_react3 = require("react");
454
650
  var dropdown_default = {};
455
651
 
456
652
  // src/components/dropdown/Dropdown.tsx
457
- var import_jsx_runtime6 = require("react/jsx-runtime");
653
+ var import_jsx_runtime11 = require("react/jsx-runtime");
458
654
  function Dropdown({
459
655
  options,
460
656
  value,
@@ -478,8 +674,8 @@ function Dropdown({
478
674
  document.addEventListener("mousedown", handleClickOutside);
479
675
  return () => document.removeEventListener("mousedown", handleClickOutside);
480
676
  }, []);
481
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: cx(dropdown_default.wrapper, className), ref, children: [
482
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
677
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cx(dropdown_default.wrapper, className), ref, children: [
678
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
483
679
  "button",
484
680
  {
485
681
  type: "button",
@@ -489,12 +685,12 @@ function Dropdown({
489
685
  "aria-label": ariaLabel,
490
686
  children: [
491
687
  selected ? selected.label : placeholder,
492
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: cx(dropdown_default.chevron, open && dropdown_default["chevron-open"]), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 10 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: "10", height: "10", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M2 3.5L5 6.5L8 3.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
688
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: cx(dropdown_default.chevron, open && dropdown_default["chevron-open"]), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { viewBox: "0 0 10 10", fill: "none", xmlns: "http://www.w3.org/2000/svg", width: "10", height: "10", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M2 3.5L5 6.5L8 3.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
493
689
  ]
494
690
  }
495
691
  ),
496
- open && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: dropdown_default.menu, children: [
497
- allowClear && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
692
+ open && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: dropdown_default.menu, children: [
693
+ allowClear && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
498
694
  "button",
499
695
  {
500
696
  type: "button",
@@ -506,7 +702,7 @@ function Dropdown({
506
702
  children: placeholder
507
703
  }
508
704
  ),
509
- options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
705
+ options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
510
706
  "button",
511
707
  {
512
708
  type: "button",
@@ -523,14 +719,429 @@ function Dropdown({
523
719
  ] });
524
720
  }
525
721
 
722
+ // src/components/dropdown-menu/DropdownMenu.tsx
723
+ var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
724
+
725
+ // src/components/dropdown-menu/dropdown-menu.module.css
726
+ var dropdown_menu_default = {};
727
+
728
+ // src/components/dropdown-menu/DropdownMenu.tsx
729
+ var import_jsx_runtime12 = require("react/jsx-runtime");
730
+ function DropdownMenu(props) {
731
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.Root, { ...props });
732
+ }
733
+ function DropdownMenuTrigger(props) {
734
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.Trigger, { ...props });
735
+ }
736
+ function DropdownMenuGroup(props) {
737
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.Group, { ...props });
738
+ }
739
+ function DropdownMenuPortal(props) {
740
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.Portal, { ...props });
741
+ }
742
+ function DropdownMenuSub(props) {
743
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.Sub, { ...props });
744
+ }
745
+ function DropdownMenuRadioGroup(props) {
746
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.RadioGroup, { ...props });
747
+ }
748
+ function DropdownMenuContent({
749
+ className,
750
+ sideOffset = 4,
751
+ ...props
752
+ }) {
753
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
754
+ DropdownMenuPrimitive.Content,
755
+ {
756
+ sideOffset,
757
+ className: cx(dropdown_menu_default.content, className),
758
+ ...props
759
+ }
760
+ ) });
761
+ }
762
+ function DropdownMenuItem({
763
+ className,
764
+ inset,
765
+ variant = "default",
766
+ ...props
767
+ }) {
768
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
769
+ DropdownMenuPrimitive.Item,
770
+ {
771
+ "data-inset": inset ? "true" : void 0,
772
+ className: cx(
773
+ dropdown_menu_default.item,
774
+ variant === "destructive" && dropdown_menu_default.destructive,
775
+ className
776
+ ),
777
+ ...props
778
+ }
779
+ );
780
+ }
781
+ function DropdownMenuCheckboxItem({
782
+ className,
783
+ children,
784
+ ...props
785
+ }) {
786
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
787
+ DropdownMenuPrimitive.CheckboxItem,
788
+ {
789
+ className: cx(dropdown_menu_default.item, dropdown_menu_default.insetItem, className),
790
+ ...props,
791
+ children: [
792
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: dropdown_menu_default.indicator, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
793
+ "svg",
794
+ {
795
+ viewBox: "0 0 16 16",
796
+ width: "16",
797
+ height: "16",
798
+ "aria-hidden": "true",
799
+ className: dropdown_menu_default.indicatorIcon,
800
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
801
+ "path",
802
+ {
803
+ d: "M3.5 8.5 6.5 11.5 12.5 4.5",
804
+ fill: "none",
805
+ stroke: "currentColor",
806
+ strokeWidth: "1.8",
807
+ strokeLinecap: "round",
808
+ strokeLinejoin: "round"
809
+ }
810
+ )
811
+ }
812
+ ) }) }),
813
+ children
814
+ ]
815
+ }
816
+ );
817
+ }
818
+ function DropdownMenuRadioItem({
819
+ className,
820
+ children,
821
+ ...props
822
+ }) {
823
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
824
+ DropdownMenuPrimitive.RadioItem,
825
+ {
826
+ className: cx(dropdown_menu_default.item, dropdown_menu_default.insetItem, className),
827
+ ...props,
828
+ children: [
829
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: dropdown_menu_default.indicator, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: dropdown_menu_default.radioDot }) }) }),
830
+ children
831
+ ]
832
+ }
833
+ );
834
+ }
835
+ function DropdownMenuLabel({
836
+ className,
837
+ inset,
838
+ ...props
839
+ }) {
840
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
841
+ DropdownMenuPrimitive.Label,
842
+ {
843
+ "data-inset": inset ? "true" : void 0,
844
+ className: cx(dropdown_menu_default.label, className),
845
+ ...props
846
+ }
847
+ );
848
+ }
849
+ function DropdownMenuSeparator({
850
+ className,
851
+ ...props
852
+ }) {
853
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
854
+ DropdownMenuPrimitive.Separator,
855
+ {
856
+ className: cx(dropdown_menu_default.separator, className),
857
+ ...props
858
+ }
859
+ );
860
+ }
861
+ function DropdownMenuSubTrigger({
862
+ className,
863
+ inset,
864
+ children,
865
+ ...props
866
+ }) {
867
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
868
+ DropdownMenuPrimitive.SubTrigger,
869
+ {
870
+ "data-inset": inset ? "true" : void 0,
871
+ className: cx(dropdown_menu_default.item, className),
872
+ ...props,
873
+ children: [
874
+ children,
875
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
876
+ "svg",
877
+ {
878
+ viewBox: "0 0 16 16",
879
+ width: "16",
880
+ height: "16",
881
+ "aria-hidden": "true",
882
+ className: dropdown_menu_default.chevron,
883
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
884
+ "path",
885
+ {
886
+ d: "M6 3.5 10.5 8 6 12.5",
887
+ fill: "none",
888
+ stroke: "currentColor",
889
+ strokeWidth: "1.6",
890
+ strokeLinecap: "round",
891
+ strokeLinejoin: "round"
892
+ }
893
+ )
894
+ }
895
+ )
896
+ ]
897
+ }
898
+ );
899
+ }
900
+ function DropdownMenuSubContent({
901
+ className,
902
+ ...props
903
+ }) {
904
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
905
+ DropdownMenuPrimitive.SubContent,
906
+ {
907
+ className: cx(dropdown_menu_default.content, className),
908
+ ...props
909
+ }
910
+ );
911
+ }
912
+
526
913
  // src/components/app-shell/AppShell.tsx
914
+ var import_react5 = require("react");
915
+
916
+ // src/theme/ThemeProvider.tsx
527
917
  var import_react4 = require("react");
528
918
 
919
+ // src/theme/constants.ts
920
+ var UZI_THEMES = ["light", "dark", "system"];
921
+ var UZI_ACCENTS = ["blue", "cyan", "violet", "emerald", "amber", "rose"];
922
+ var THEME_STORAGE_KEY = "uzi-theme";
923
+ var ACCENT_STORAGE_KEY = "uzi-accent";
924
+
925
+ // src/theme/ThemeProvider.tsx
926
+ var import_jsx_runtime13 = require("react/jsx-runtime");
927
+ var THEME_STORAGE_KEY2 = THEME_STORAGE_KEY;
928
+ var ACCENT_STORAGE_KEY2 = ACCENT_STORAGE_KEY;
929
+ var THEME_ATTRIBUTE = "data-uzi-theme";
930
+ var ACCENT_ATTRIBUTE = "data-uzi-accent";
931
+ var ThemeContext = (0, import_react4.createContext)(void 0);
932
+ function isTheme(value) {
933
+ return UZI_THEMES.includes(value);
934
+ }
935
+ function isAccent(value) {
936
+ return UZI_ACCENTS.includes(value);
937
+ }
938
+ function getSystemTheme() {
939
+ if (typeof window === "undefined") return "light";
940
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
941
+ }
942
+ function ThemeProvider({
943
+ children,
944
+ theme,
945
+ defaultTheme = "system",
946
+ accent,
947
+ defaultAccent = "blue",
948
+ onThemeChange,
949
+ onAccentChange,
950
+ storageKey = THEME_STORAGE_KEY2,
951
+ accentStorageKey = ACCENT_STORAGE_KEY2,
952
+ disableStorage = false
953
+ }) {
954
+ const [internalTheme, setInternalTheme] = (0, import_react4.useState)(defaultTheme);
955
+ const [internalAccent, setInternalAccent] = (0, import_react4.useState)(defaultAccent);
956
+ const [systemTheme, setSystemTheme] = (0, import_react4.useState)("light");
957
+ (0, import_react4.useEffect)(() => {
958
+ setSystemTheme(getSystemTheme());
959
+ if (!disableStorage) {
960
+ const storedTheme = window.localStorage.getItem(storageKey);
961
+ if (isTheme(storedTheme)) setInternalTheme(storedTheme);
962
+ const storedAccent = window.localStorage.getItem(accentStorageKey);
963
+ if (isAccent(storedAccent)) setInternalAccent(storedAccent);
964
+ }
965
+ }, [disableStorage, storageKey, accentStorageKey]);
966
+ const isThemeControlled = theme !== void 0;
967
+ const isAccentControlled = accent !== void 0;
968
+ const currentTheme = isThemeControlled ? theme : internalTheme;
969
+ const currentAccent = isAccentControlled ? accent : internalAccent;
970
+ const resolvedTheme = currentTheme === "system" ? systemTheme : currentTheme;
971
+ (0, import_react4.useEffect)(() => {
972
+ if (typeof window === "undefined") return;
973
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
974
+ const handleChange = () => setSystemTheme(mediaQuery.matches ? "dark" : "light");
975
+ handleChange();
976
+ mediaQuery.addEventListener("change", handleChange);
977
+ return () => mediaQuery.removeEventListener("change", handleChange);
978
+ }, []);
979
+ (0, import_react4.useEffect)(() => {
980
+ if (typeof document === "undefined") return;
981
+ const root = document.documentElement;
982
+ root.setAttribute(THEME_ATTRIBUTE, resolvedTheme);
983
+ root.setAttribute(ACCENT_ATTRIBUTE, currentAccent);
984
+ root.style.colorScheme = resolvedTheme;
985
+ root.classList.toggle("dark", resolvedTheme === "dark");
986
+ }, [currentAccent, resolvedTheme]);
987
+ const setTheme = (0, import_react4.useCallback)(
988
+ (nextTheme) => {
989
+ if (!isThemeControlled) setInternalTheme(nextTheme);
990
+ if (!disableStorage && typeof window !== "undefined") {
991
+ window.localStorage.setItem(storageKey, nextTheme);
992
+ }
993
+ onThemeChange?.(nextTheme);
994
+ },
995
+ [disableStorage, isThemeControlled, onThemeChange, storageKey]
996
+ );
997
+ const setAccent = (0, import_react4.useCallback)(
998
+ (nextAccent) => {
999
+ if (!isAccentControlled) setInternalAccent(nextAccent);
1000
+ if (!disableStorage && typeof window !== "undefined") {
1001
+ window.localStorage.setItem(accentStorageKey, nextAccent);
1002
+ }
1003
+ onAccentChange?.(nextAccent);
1004
+ },
1005
+ [accentStorageKey, disableStorage, isAccentControlled, onAccentChange]
1006
+ );
1007
+ const toggleTheme = (0, import_react4.useCallback)(() => {
1008
+ setTheme(resolvedTheme === "dark" ? "light" : "dark");
1009
+ }, [resolvedTheme, setTheme]);
1010
+ const value = (0, import_react4.useMemo)(
1011
+ () => ({
1012
+ theme: currentTheme,
1013
+ resolvedTheme,
1014
+ accent: currentAccent,
1015
+ setTheme,
1016
+ setAccent,
1017
+ toggleTheme
1018
+ }),
1019
+ [currentAccent, currentTheme, resolvedTheme, setAccent, setTheme, toggleTheme]
1020
+ );
1021
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ThemeContext.Provider, { value, children });
1022
+ }
1023
+ function useTheme() {
1024
+ const context = (0, import_react4.useContext)(ThemeContext);
1025
+ if (!context) throw new Error("useTheme must be used within a ThemeProvider");
1026
+ return context;
1027
+ }
1028
+
1029
+ // src/components/theme-toggle-button/theme-toggle-button.module.css
1030
+ var theme_toggle_button_default = {};
1031
+
1032
+ // src/components/theme-toggle-button/ThemeToggleButton.tsx
1033
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1034
+ function MoonIcon() {
1035
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", width: "16", height: "16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1036
+ "path",
1037
+ {
1038
+ d: "M20 15.2A8.5 8.5 0 0 1 8.8 4 9 9 0 1 0 20 15.2Z",
1039
+ stroke: "currentColor",
1040
+ strokeWidth: "1.8",
1041
+ strokeLinecap: "round",
1042
+ strokeLinejoin: "round"
1043
+ }
1044
+ ) });
1045
+ }
1046
+ function SunIcon() {
1047
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", width: "16", height: "16", fill: "none", children: [
1048
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("circle", { cx: "12", cy: "12", r: "4", stroke: "currentColor", strokeWidth: "1.8" }),
1049
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1050
+ "path",
1051
+ {
1052
+ d: "M12 2.75v2.5M12 18.75v2.5M21.25 12h-2.5M5.25 12h-2.5M18.54 5.46l-1.77 1.77M7.23 16.77l-1.77 1.77M18.54 18.54l-1.77-1.77M7.23 7.23 5.46 5.46",
1053
+ stroke: "currentColor",
1054
+ strokeWidth: "1.8",
1055
+ strokeLinecap: "round"
1056
+ }
1057
+ )
1058
+ ] });
1059
+ }
1060
+ function ThemeToggleButton({
1061
+ showLabel = false,
1062
+ lightLabel = "Light mode",
1063
+ darkLabel = "Dark mode",
1064
+ className,
1065
+ onClick,
1066
+ ...rest
1067
+ }) {
1068
+ const { resolvedTheme, toggleTheme } = useTheme();
1069
+ const nextThemeLabel = resolvedTheme === "dark" ? lightLabel : darkLabel;
1070
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1071
+ Button,
1072
+ {
1073
+ type: "button",
1074
+ variant: "ghost",
1075
+ size: showLabel ? "sm" : "icon",
1076
+ className: cx(showLabel && theme_toggle_button_default.withLabel, className),
1077
+ "aria-label": `Switch to ${nextThemeLabel.toLowerCase()}`,
1078
+ title: `Switch to ${nextThemeLabel.toLowerCase()}`,
1079
+ onClick: (event) => {
1080
+ onClick?.(event);
1081
+ if (!event.defaultPrevented) toggleTheme();
1082
+ },
1083
+ ...rest,
1084
+ children: [
1085
+ resolvedTheme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SunIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MoonIcon, {}),
1086
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: nextThemeLabel })
1087
+ ]
1088
+ }
1089
+ );
1090
+ }
1091
+
1092
+ // src/components/top-bar/top-bar.module.css
1093
+ var top_bar_default = {};
1094
+
1095
+ // src/components/top-bar/TopBar.tsx
1096
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1097
+ function TopBar({
1098
+ leading,
1099
+ brand,
1100
+ brandHref,
1101
+ brandingLocation = "left",
1102
+ start,
1103
+ center,
1104
+ actions,
1105
+ showThemeToggle = false,
1106
+ themeToggleProps,
1107
+ className,
1108
+ innerClassName,
1109
+ isSticky,
1110
+ sticky = true,
1111
+ children,
1112
+ ...rest
1113
+ }) {
1114
+ const shouldStick = isSticky ?? sticky;
1115
+ const brandNode = !brand ? null : brandHref ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: brandHref, className: top_bar_default.topBarBrand, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: top_bar_default.topBarBrandContent, children: brand }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: top_bar_default.topBarBrand, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: top_bar_default.topBarBrandContent, children: brand }) });
1116
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1117
+ "header",
1118
+ {
1119
+ className: cx(top_bar_default.topBar, !shouldStick && top_bar_default.topBarStatic, className),
1120
+ ...rest,
1121
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cx(top_bar_default.topBarInner, innerClassName), children: [
1122
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: top_bar_default.topBarStart, children: [
1123
+ leading,
1124
+ brandingLocation === "left" && brandNode,
1125
+ start
1126
+ ] }),
1127
+ brandNode && brandingLocation === "center" || center || children ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: top_bar_default.topBarCenter, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: top_bar_default.topBarCenterGroup, children: [
1128
+ brandingLocation === "center" && brandNode,
1129
+ center ?? children
1130
+ ] }) }) : null,
1131
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: top_bar_default.topBarActions, children: [
1132
+ showThemeToggle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeToggleButton, { ...themeToggleProps }),
1133
+ actions
1134
+ ] })
1135
+ ] })
1136
+ }
1137
+ );
1138
+ }
1139
+
529
1140
  // src/components/app-shell/app-shell.module.css
530
1141
  var app_shell_default = {};
531
1142
 
532
1143
  // src/components/app-shell/AppShell.tsx
533
- var import_jsx_runtime7 = require("react/jsx-runtime");
1144
+ var import_jsx_runtime16 = require("react/jsx-runtime");
534
1145
  var DESKTOP_BREAKPOINT = 960;
535
1146
  function getIsDesktop() {
536
1147
  if (typeof window === "undefined") return false;
@@ -543,6 +1154,9 @@ function AppShell({
543
1154
  brandHref,
544
1155
  topbarStart,
545
1156
  topbarEnd,
1157
+ showThemeToggle = false,
1158
+ themeToggleProps,
1159
+ topBarBrandingLocation = "left",
546
1160
  className,
547
1161
  sidebarClassName,
548
1162
  topbarClassName,
@@ -552,19 +1166,23 @@ function AppShell({
552
1166
  hamburgerLabel = "Toggle navigation",
553
1167
  onSidebarToggle
554
1168
  }) {
555
- const [isDesktop, setIsDesktop] = (0, import_react4.useState)(false);
556
- const [sidebarOpen, setSidebarOpen] = (0, import_react4.useState)(false);
557
- const prevIsDesktopRef = (0, import_react4.useRef)(false);
558
- const closeKeyRef = (0, import_react4.useRef)(closeSidebarOnChangeKey);
559
- const sidebarRef = (0, import_react4.useRef)(null);
560
- const hamburgerRef = (0, import_react4.useRef)(null);
561
- const mainRef = (0, import_react4.useRef)(null);
562
- const sidebarId = (0, import_react4.useId)();
563
- (0, import_react4.useEffect)(() => {
1169
+ const [isDesktop, setIsDesktop] = (0, import_react5.useState)(false);
1170
+ const [sidebarOpen, setSidebarOpen] = (0, import_react5.useState)(false);
1171
+ const [transitionsReady, setTransitionsReady] = (0, import_react5.useState)(false);
1172
+ const prevIsDesktopRef = (0, import_react5.useRef)(false);
1173
+ const closeKeyRef = (0, import_react5.useRef)(closeSidebarOnChangeKey);
1174
+ const sidebarRef = (0, import_react5.useRef)(null);
1175
+ const hamburgerRef = (0, import_react5.useRef)(null);
1176
+ const mainRef = (0, import_react5.useRef)(null);
1177
+ const sidebarId = (0, import_react5.useId)();
1178
+ (0, import_react5.useEffect)(() => {
564
1179
  const desktop = getIsDesktop();
565
1180
  setIsDesktop(desktop);
566
1181
  setSidebarOpen(desktop);
567
1182
  prevIsDesktopRef.current = desktop;
1183
+ const transitionFrame = window.requestAnimationFrame(() => {
1184
+ setTransitionsReady(true);
1185
+ });
568
1186
  const handleResize = () => {
569
1187
  const nowDesktop = getIsDesktop();
570
1188
  setIsDesktop(nowDesktop);
@@ -574,9 +1192,12 @@ function AppShell({
574
1192
  }
575
1193
  };
576
1194
  window.addEventListener("resize", handleResize);
577
- return () => window.removeEventListener("resize", handleResize);
1195
+ return () => {
1196
+ window.cancelAnimationFrame(transitionFrame);
1197
+ window.removeEventListener("resize", handleResize);
1198
+ };
578
1199
  }, []);
579
- (0, import_react4.useEffect)(() => {
1200
+ (0, import_react5.useEffect)(() => {
580
1201
  if (isDesktop || !sidebarOpen) return;
581
1202
  const mainElement = mainRef.current;
582
1203
  const closeSidebar = () => setSidebarOpen(false);
@@ -601,25 +1222,26 @@ function AppShell({
601
1222
  document.removeEventListener("touchmove", closeSidebar);
602
1223
  };
603
1224
  }, [sidebarOpen, isDesktop]);
604
- (0, import_react4.useEffect)(() => {
1225
+ (0, import_react5.useEffect)(() => {
605
1226
  if (!isDesktop && closeKeyRef.current !== closeSidebarOnChangeKey) {
606
1227
  setSidebarOpen(false);
607
1228
  }
608
1229
  closeKeyRef.current = closeSidebarOnChangeKey;
609
1230
  }, [closeSidebarOnChangeKey, isDesktop]);
610
- (0, import_react4.useEffect)(() => {
1231
+ (0, import_react5.useEffect)(() => {
611
1232
  onSidebarToggle?.(sidebarOpen);
612
1233
  }, [sidebarOpen, onSidebarToggle]);
613
1234
  const toggleSidebar = () => setSidebarOpen((open) => !open);
614
1235
  const sidebarWidthValue = sidebarWidth === void 0 ? void 0 : typeof sidebarWidth === "number" ? `${sidebarWidth}px` : sidebarWidth;
615
1236
  const shellStyle = sidebarWidthValue ? { ["--app-shell-sidebar-width"]: sidebarWidthValue } : void 0;
616
1237
  const shellClasses = cx(
617
- app_shell_default.shell,
618
- sidebarOpen ? app_shell_default.sidebarOpen : app_shell_default.sidebarCollapsed,
1238
+ app_shell_default.appShell,
1239
+ transitionsReady && app_shell_default.appShellAnimated,
1240
+ sidebarOpen ? app_shell_default.appShellOpen : app_shell_default.appShellCollapsed,
619
1241
  className
620
1242
  );
621
- const sidebarClasses = cx(app_shell_default.sidebar, sidebarOpen && app_shell_default.open, sidebarClassName);
622
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1243
+ const sidebarClasses = cx(app_shell_default.appShellSidebar, sidebarOpen && app_shell_default.appShellSidebarOpen, sidebarClassName);
1244
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
623
1245
  "div",
624
1246
  {
625
1247
  className: shellClasses,
@@ -628,29 +1250,35 @@ function AppShell({
628
1250
  "data-desktop": isDesktop ? "true" : "false",
629
1251
  "data-sidebar-open": sidebarOpen ? "true" : "false",
630
1252
  children: [
631
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { className: cx(app_shell_default.topbar, topbarClassName), children: [
632
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: app_shell_default.topbarLeft, children: [
633
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1253
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1254
+ TopBar,
1255
+ {
1256
+ className: cx(app_shell_default.appShellTopbar, topbarClassName),
1257
+ leading: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
634
1258
  "button",
635
1259
  {
636
1260
  ref: hamburgerRef,
637
1261
  type: "button",
638
- className: app_shell_default.hamburger,
1262
+ className: app_shell_default.appShellHamburger,
639
1263
  onClick: toggleSidebar,
640
1264
  "aria-label": hamburgerLabel,
641
1265
  "aria-expanded": sidebarOpen,
642
1266
  "aria-controls": sidebarId,
643
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M3 6h18M3 12h18M3 18h18", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }) })
1267
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M3 6h18M3 12h18M3 18h18", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }) })
644
1268
  }
645
1269
  ),
646
- brand && (brandHref ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { className: app_shell_default.brand, href: brandHref, children: brand }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: app_shell_default.brand, children: brand })),
647
- topbarStart && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: app_shell_default.topbarStart, children: topbarStart })
648
- ] }),
649
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: app_shell_default.topbarRight, children: topbarEnd })
650
- ] }),
651
- !isDesktop && sidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: app_shell_default.backdrop, onClick: () => setSidebarOpen(false), onTouchStart: () => setSidebarOpen(false), "aria-hidden": "true" }),
652
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("aside", { ref: sidebarRef, id: sidebarId, className: sidebarClasses, "aria-label": "Sidebar navigation", children: sidebar }),
653
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("main", { ref: mainRef, className: cx(app_shell_default.main, mainClassName), children })
1270
+ brand,
1271
+ brandHref,
1272
+ brandingLocation: topBarBrandingLocation,
1273
+ start: topbarStart,
1274
+ actions: topbarEnd,
1275
+ showThemeToggle,
1276
+ themeToggleProps
1277
+ }
1278
+ ),
1279
+ !isDesktop && sidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: app_shell_default.appShellBackdrop, onClick: () => setSidebarOpen(false), onTouchStart: () => setSidebarOpen(false), "aria-hidden": "true" }),
1280
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("aside", { ref: sidebarRef, id: sidebarId, className: sidebarClasses, "aria-label": "Sidebar navigation", children: sidebar }),
1281
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("main", { ref: mainRef, className: cx(app_shell_default.appShellMain, mainClassName), children })
654
1282
  ]
655
1283
  }
656
1284
  );
@@ -660,57 +1288,176 @@ function AppShell({
660
1288
  var sidebar_nav_default = {};
661
1289
 
662
1290
  // src/components/sidebar-nav/SidebarNav.tsx
663
- var import_jsx_runtime8 = require("react/jsx-runtime");
1291
+ var import_jsx_runtime17 = require("react/jsx-runtime");
664
1292
  var defaultIsActive = (item, path) => {
665
1293
  if (item.active !== void 0) return item.active;
1294
+ if (!item.href) return false;
666
1295
  if (!path) return false;
667
1296
  if (item.href === "/") return path === "/";
668
1297
  return path.startsWith(item.href);
669
1298
  };
670
1299
  function SidebarNav({
671
- items,
1300
+ items = [],
1301
+ sections,
672
1302
  currentPath,
673
1303
  getIsActive = defaultIsActive,
674
1304
  onItemClick,
1305
+ header,
1306
+ footer,
1307
+ ariaLabel = "Sidebar navigation",
1308
+ collapsed = false,
1309
+ iconSize,
675
1310
  className,
676
- itemClassName
1311
+ itemClassName,
1312
+ sectionClassName
677
1313
  }) {
678
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("nav", { className: cx(sidebar_nav_default.nav, className), "aria-label": "Sidebar navigation", children: items.map((item) => {
679
- const active = getIsActive(item, currentPath);
680
- const rel = item.rel ?? (item.target === "_blank" ? "noreferrer" : void 0);
681
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
682
- "a",
1314
+ const resolvedSections = sections?.length ? sections : [{ id: "default", items }];
1315
+ const style = iconSize !== void 0 ? {
1316
+ ["--sidebar-nav-icon-size"]: typeof iconSize === "number" ? `${iconSize}px` : iconSize
1317
+ } : void 0;
1318
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1319
+ "nav",
1320
+ {
1321
+ className: cx(sidebar_nav_default.uziSidebarNav, collapsed && sidebar_nav_default.uziSidebarNavCollapsed, className),
1322
+ "aria-label": ariaLabel,
1323
+ style,
1324
+ children: [
1325
+ header ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: sidebar_nav_default.uziSidebarNavHeader, children: header }) : null,
1326
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: sidebar_nav_default.uziSidebarNavSections, children: resolvedSections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1327
+ "div",
1328
+ {
1329
+ className: cx(sidebar_nav_default.uziSidebarNavSection, sectionClassName),
1330
+ children: [
1331
+ section.label && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: sidebar_nav_default.uziSidebarNavSectionLabel, children: section.label }) : null,
1332
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: sidebar_nav_default.uziSidebarNavSectionItems, children: section.items.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1333
+ SidebarNavEntry,
1334
+ {
1335
+ item,
1336
+ active: getIsActive(item, currentPath),
1337
+ collapsed,
1338
+ itemClassName,
1339
+ onItemClick
1340
+ },
1341
+ `${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`
1342
+ )) })
1343
+ ]
1344
+ },
1345
+ section.id ?? `section-${sectionIndex}`
1346
+ )) }),
1347
+ footer ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: sidebar_nav_default.uziSidebarNavFooter, children: footer }) : null
1348
+ ]
1349
+ }
1350
+ );
1351
+ }
1352
+ function SidebarNavEntry({
1353
+ item,
1354
+ active,
1355
+ collapsed,
1356
+ itemClassName,
1357
+ onItemClick
1358
+ }) {
1359
+ const rel = item.rel ?? (item.target === "_blank" ? "noreferrer" : void 0);
1360
+ const title = item.title ?? (typeof item.label === "string" ? item.label : void 0);
1361
+ const classes = cx(
1362
+ sidebar_nav_default.uziSidebarNavItem,
1363
+ active && sidebar_nav_default.uziSidebarNavItemActive,
1364
+ collapsed && sidebar_nav_default.uziSidebarNavItemCollapsed,
1365
+ item.disabled && sidebar_nav_default.uziSidebarNavItemDisabled,
1366
+ itemClassName
1367
+ );
1368
+ const content = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
1369
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: sidebar_nav_default.uziSidebarNavIcon, children: item.icon }),
1370
+ !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: sidebar_nav_default.uziSidebarNavItemBody, children: [
1371
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: sidebar_nav_default.uziSidebarNavLabelRow, children: [
1372
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: sidebar_nav_default.uziSidebarNavLabel, children: item.label }),
1373
+ item.badge && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: sidebar_nav_default.uziSidebarNavBadge, children: item.badge })
1374
+ ] }),
1375
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: sidebar_nav_default.uziSidebarNavDescription, children: item.description }) : null
1376
+ ] }) : null
1377
+ ] });
1378
+ const handleClick = () => {
1379
+ if (item.disabled) return;
1380
+ item.onClick?.();
1381
+ onItemClick?.(item);
1382
+ };
1383
+ if (!item.href) {
1384
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1385
+ "button",
683
1386
  {
684
- className: cx(sidebar_nav_default.item, active && sidebar_nav_default.active, itemClassName),
685
- href: item.href,
686
- target: item.target,
687
- rel,
1387
+ type: "button",
1388
+ className: classes,
688
1389
  "aria-current": active ? "page" : void 0,
689
- onClick: () => {
690
- item.onClick?.();
691
- onItemClick?.(item);
692
- },
693
- children: [
694
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: sidebar_nav_default.icon, children: item.icon }),
695
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: sidebar_nav_default.label, children: item.label }),
696
- item.badge && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: sidebar_nav_default.badge, children: item.badge })
697
- ]
698
- },
699
- item.href
1390
+ "aria-disabled": item.disabled ? "true" : void 0,
1391
+ disabled: item.disabled,
1392
+ title: collapsed ? title : void 0,
1393
+ onClick: handleClick,
1394
+ children: content
1395
+ }
700
1396
  );
701
- }) });
1397
+ }
1398
+ if (item.disabled) {
1399
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1400
+ "div",
1401
+ {
1402
+ className: classes,
1403
+ "aria-current": active ? "page" : void 0,
1404
+ "aria-disabled": "true",
1405
+ title: collapsed ? title : void 0,
1406
+ children: content
1407
+ }
1408
+ );
1409
+ }
1410
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1411
+ "a",
1412
+ {
1413
+ className: classes,
1414
+ href: item.href,
1415
+ target: item.target,
1416
+ rel,
1417
+ "aria-current": active ? "page" : void 0,
1418
+ title: collapsed ? title : void 0,
1419
+ onClick: handleClick,
1420
+ children: content
1421
+ }
1422
+ );
702
1423
  }
703
1424
  // Annotate the CommonJS export names for ESM import in node:
704
1425
  0 && (module.exports = {
1426
+ Alert,
705
1427
  AppShell,
1428
+ Avatar,
1429
+ AvatarFallback,
1430
+ AvatarImage,
706
1431
  Button,
707
1432
  Card,
1433
+ Checkbox,
708
1434
  Dropdown,
1435
+ DropdownMenu,
1436
+ DropdownMenuCheckboxItem,
1437
+ DropdownMenuContent,
1438
+ DropdownMenuGroup,
1439
+ DropdownMenuItem,
1440
+ DropdownMenuLabel,
1441
+ DropdownMenuPortal,
1442
+ DropdownMenuRadioGroup,
1443
+ DropdownMenuRadioItem,
1444
+ DropdownMenuSeparator,
1445
+ DropdownMenuSub,
1446
+ DropdownMenuSubContent,
1447
+ DropdownMenuSubTrigger,
1448
+ DropdownMenuTrigger,
1449
+ Input,
1450
+ Label,
709
1451
  Modal,
1452
+ ModalOverlay,
710
1453
  Pill,
711
1454
  SidebarNav,
1455
+ ThemeProvider,
1456
+ ThemeToggleButton,
712
1457
  ToastProvider,
1458
+ TopBar,
713
1459
  cx,
1460
+ useTheme,
714
1461
  useToast
715
1462
  });
716
1463
  //# sourceMappingURL=index.cjs.map