@tomny-dev/uzi 0.1.9-pr.2.1.1 → 0.1.9-pr.2.2.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.
package/dist/index.cjs CHANGED
@@ -224,36 +224,20 @@ function Pill({
224
224
  }
225
225
 
226
226
  // src/components/modal/Modal.tsx
227
- var import_react = require("react");
227
+ var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
228
228
  var import_jsx_runtime5 = require("react/jsx-runtime");
229
229
  function ModalOverlay({ open, onClose, className, children }) {
230
- const mouseDownOnBackdrop = (0, import_react.useRef)(false);
231
- (0, import_react.useEffect)(() => {
232
- if (!open) return;
233
- const handleKeyDown = (e) => {
234
- if (e.key === "Escape") {
235
- e.stopPropagation();
236
- onClose();
237
- }
238
- };
239
- window.addEventListener("keydown", handleKeyDown, true);
240
- return () => window.removeEventListener("keydown", handleKeyDown, true);
241
- }, [open, onClose]);
242
- if (!open) return null;
243
230
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
244
- "div",
231
+ DialogPrimitive.Root,
245
232
  {
246
- className: cx("backdrop", className),
247
- role: "dialog",
248
- "aria-modal": "true",
249
- onMouseDown: (e) => {
250
- mouseDownOnBackdrop.current = e.target === e.currentTarget;
233
+ open,
234
+ onOpenChange: (nextOpen) => {
235
+ if (!nextOpen) onClose();
251
236
  },
252
- onMouseUp: (e) => {
253
- if (mouseDownOnBackdrop.current && e.target === e.currentTarget) onClose();
254
- mouseDownOnBackdrop.current = false;
255
- },
256
- children
237
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "portalLayer", children: [
238
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Overlay, { className: cx("backdrop", className) }),
239
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Content, { className: "overlayContent", children })
240
+ ] }) })
257
241
  }
258
242
  );
259
243
  }
@@ -261,13 +245,13 @@ function Modal({ open, onClose, title, subtitle, size = "md", children, footer }
261
245
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModalOverlay, { open, onClose, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cx("modal", `size-${size}`), children: [
262
246
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "header", children: [
263
247
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "titles", children: [
264
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "title", children: title }),
265
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "subtitle", children: subtitle })
248
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Title, { className: "title", children: title }),
249
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Description, { className: "subtitle", children: subtitle }) : null
266
250
  ] }),
267
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "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: [
251
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "closeButton", "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: [
268
252
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
269
253
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
270
- ] }) })
254
+ ] }) }) })
271
255
  ] }),
272
256
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "body", children }),
273
257
  footer && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "footer", children: footer })
@@ -287,7 +271,8 @@ function Alert({ tone, children, className }) {
287
271
  }
288
272
 
289
273
  // src/components/toast/ToastContext.tsx
290
- var import_react2 = require("react");
274
+ var import_react = require("react");
275
+ var ToastPrimitive = __toESM(require("@radix-ui/react-toast"), 1);
291
276
  var import_jsx_runtime7 = require("react/jsx-runtime");
292
277
  var DEFAULT_CONFIG = {
293
278
  position: "top-right",
@@ -296,17 +281,17 @@ var DEFAULT_CONFIG = {
296
281
  pauseOnHover: true,
297
282
  pauseOnFocusLoss: true
298
283
  };
299
- var ToastContext = (0, import_react2.createContext)(void 0);
284
+ var ToastContext = (0, import_react.createContext)(void 0);
300
285
  var toastIdCounter = 0;
301
286
  var generateToastId = () => `toast-${++toastIdCounter}-${Date.now()}`;
302
287
  function ToastProvider({
303
288
  children,
304
289
  config
305
290
  }) {
306
- const [toasts, setToasts] = (0, import_react2.useState)([]);
307
- const [isPaused, setIsPaused] = (0, import_react2.useState)(false);
308
- const merged = (0, import_react2.useMemo)(() => ({ ...DEFAULT_CONFIG, ...config }), [config]);
309
- const push = (0, import_react2.useCallback)(
291
+ const [toasts, setToasts] = (0, import_react.useState)([]);
292
+ const [isPaused, setIsPaused] = (0, import_react.useState)(false);
293
+ const merged = (0, import_react.useMemo)(() => ({ ...DEFAULT_CONFIG, ...config }), [config]);
294
+ const push = (0, import_react.useCallback)(
310
295
  (message, options = {}) => {
311
296
  const id = generateToastId();
312
297
  setToasts((prev) => {
@@ -328,37 +313,37 @@ function ToastProvider({
328
313
  },
329
314
  [merged.defaultDuration, merged.maxToasts]
330
315
  );
331
- const success = (0, import_react2.useCallback)(
316
+ const success = (0, import_react.useCallback)(
332
317
  (message, options) => push(message, { ...options, type: "success" }),
333
318
  [push]
334
319
  );
335
- const error = (0, import_react2.useCallback)(
320
+ const error = (0, import_react.useCallback)(
336
321
  (message, options) => push(message, { ...options, type: "error", duration: options?.duration ?? 6e3 }),
337
322
  [push]
338
323
  );
339
- const warning = (0, import_react2.useCallback)(
324
+ const warning = (0, import_react.useCallback)(
340
325
  (message, options) => push(message, { ...options, type: "warning" }),
341
326
  [push]
342
327
  );
343
- const info = (0, import_react2.useCallback)(
328
+ const info = (0, import_react.useCallback)(
344
329
  (message, options) => push(message, { ...options, type: "info" }),
345
330
  [push]
346
331
  );
347
- const dismiss = (0, import_react2.useCallback)((id) => {
332
+ const dismiss = (0, import_react.useCallback)((id) => {
348
333
  setToasts((prev) => prev.filter((t) => t.id !== id));
349
334
  }, []);
350
- const dismissAll = (0, import_react2.useCallback)(() => setToasts([]), []);
351
- (0, import_react2.useEffect)(() => {
335
+ const dismissAll = (0, import_react.useCallback)(() => setToasts([]), []);
336
+ (0, import_react.useEffect)(() => {
352
337
  if (!merged.pauseOnFocusLoss) return;
353
338
  const handleVisibility = () => setIsPaused(document.visibilityState !== "visible");
354
339
  document.addEventListener("visibilitychange", handleVisibility);
355
340
  return () => document.removeEventListener("visibilitychange", handleVisibility);
356
341
  }, [merged.pauseOnFocusLoss]);
357
- const value = (0, import_react2.useMemo)(
342
+ const value = (0, import_react.useMemo)(
358
343
  () => ({ toasts, push, success, error, warning, info, dismiss, dismissAll }),
359
344
  [toasts, push, success, error, warning, info, dismiss, dismissAll]
360
345
  );
361
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ToastContext.Provider, { value, children: [
346
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ToastPrimitive.Provider, { swipeDirection: "right", children: [
362
347
  children,
363
348
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
364
349
  ToastContainer,
@@ -371,10 +356,10 @@ function ToastProvider({
371
356
  onPauseChange: setIsPaused
372
357
  }
373
358
  )
374
- ] });
359
+ ] }) });
375
360
  }
376
361
  function useToast() {
377
- const ctx = (0, import_react2.useContext)(ToastContext);
362
+ const ctx = (0, import_react.useContext)(ToastContext);
378
363
  if (!ctx) throw new Error("useToast must be used within a ToastProvider");
379
364
  return ctx;
380
365
  }
@@ -403,26 +388,29 @@ function ToastContainer({
403
388
  return "topRight";
404
389
  }
405
390
  })();
406
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
407
- "div",
408
- {
409
- className: cx("stack", posClass),
410
- role: "presentation",
411
- onMouseEnter: () => pauseOnHover && onPauseChange(true),
412
- onMouseLeave: () => pauseOnHover && onPauseChange(false),
413
- children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastItem, { toast, isPaused, onDismiss }, toast.id))
414
- }
415
- );
391
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
392
+ toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastItem, { toast, isPaused, onDismiss }, toast.id)),
393
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
394
+ ToastPrimitive.Viewport,
395
+ {
396
+ className: cx("stack", posClass),
397
+ label: "Notifications",
398
+ onMouseEnter: () => pauseOnHover && onPauseChange(true),
399
+ onMouseLeave: () => pauseOnHover && onPauseChange(false)
400
+ }
401
+ )
402
+ ] });
416
403
  }
417
404
  function ToastItem({
418
405
  toast,
419
406
  isPaused,
420
407
  onDismiss
421
408
  }) {
422
- const [exiting, setExiting] = (0, import_react2.useState)(false);
423
- const timerRef = (0, import_react2.useRef)(null);
424
- const startRef = (0, import_react2.useRef)(0);
425
- const remainingRef = (0, import_react2.useRef)(toast.duration ?? 0);
409
+ const [open, setOpen] = (0, import_react.useState)(true);
410
+ const timerRef = (0, import_react.useRef)(null);
411
+ const startRef = (0, import_react.useRef)(0);
412
+ const remainingRef = (0, import_react.useRef)(toast.duration ?? 0);
413
+ const closingRef = (0, import_react.useRef)(false);
426
414
  const palette = getPalette(toast.type);
427
415
  const styleVars = {
428
416
  ["--toast-bg"]: palette.background,
@@ -439,12 +427,14 @@ function ToastItem({
439
427
  timerRef.current = null;
440
428
  }
441
429
  };
442
- const triggerDismiss = (0, import_react2.useCallback)(() => {
443
- setExiting(true);
430
+ const triggerDismiss = (0, import_react.useCallback)(() => {
431
+ if (closingRef.current) return;
432
+ closingRef.current = true;
433
+ setOpen(false);
444
434
  stopTimer();
445
435
  window.setTimeout(() => onDismiss(toast.id), 160);
446
436
  }, [onDismiss, toast.id]);
447
- const schedule = (0, import_react2.useCallback)(
437
+ const schedule = (0, import_react.useCallback)(
448
438
  (delay) => {
449
439
  if (!delay || delay <= 0) {
450
440
  triggerDismiss();
@@ -456,12 +446,12 @@ function ToastItem({
456
446
  },
457
447
  [triggerDismiss]
458
448
  );
459
- (0, import_react2.useEffect)(() => {
449
+ (0, import_react.useEffect)(() => {
460
450
  if (!toast.duration || toast.duration <= 0) return void 0;
461
451
  schedule(toast.duration);
462
452
  return stopTimer;
463
453
  }, [schedule, toast.duration]);
464
- (0, import_react2.useEffect)(() => {
454
+ (0, import_react.useEffect)(() => {
465
455
  if (!toast.duration || toast.duration <= 0) return;
466
456
  if (isPaused) {
467
457
  const elapsed = performance.now() - startRef.current;
@@ -472,42 +462,60 @@ function ToastItem({
472
462
  }
473
463
  }, [isPaused, schedule, toast.duration]);
474
464
  const icon = getIcon(toast.type);
475
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cx("toast", exiting && "exit"), style: styleVars, role: "status", "aria-live": "polite", children: [
476
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "icon", "aria-hidden": true, children: icon }),
477
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "body", children: [
478
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "message", children: toast.message }),
479
- toast.action && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "actions", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
480
- "button",
481
- {
482
- type: "button",
483
- className: "actionButton",
484
- onClick: () => {
485
- toast.action?.onClick();
486
- triggerDismiss();
487
- },
488
- children: toast.action.label
489
- }
490
- ) })
491
- ] }),
492
- toast.dismissible !== false && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
493
- "button",
494
- {
495
- type: "button",
496
- className: "closeButton",
497
- onClick: triggerDismiss,
498
- "aria-label": "Dismiss notification",
499
- 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)(
500
- "path",
465
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
466
+ ToastPrimitive.Root,
467
+ {
468
+ open,
469
+ onOpenChange: (nextOpen) => {
470
+ if (!nextOpen) triggerDismiss();
471
+ },
472
+ duration: 2147483647,
473
+ className: "toast",
474
+ style: styleVars,
475
+ children: [
476
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "icon", "aria-hidden": true, children: icon }),
477
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "body", children: [
478
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastPrimitive.Description, { className: "message", children: toast.message }),
479
+ toast.action && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "actions", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
480
+ ToastPrimitive.Action,
481
+ {
482
+ asChild: true,
483
+ altText: toast.action.label,
484
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
485
+ "button",
486
+ {
487
+ type: "button",
488
+ className: "actionButton",
489
+ onClick: () => {
490
+ toast.action?.onClick();
491
+ triggerDismiss();
492
+ },
493
+ children: toast.action.label
494
+ }
495
+ )
496
+ }
497
+ ) })
498
+ ] }),
499
+ toast.dismissible !== false && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ToastPrimitive.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
500
+ "button",
501
501
  {
502
- d: "M11 3L3 11M3 3l8 8",
503
- stroke: "currentColor",
504
- strokeWidth: "1.5",
505
- strokeLinecap: "round"
502
+ type: "button",
503
+ className: "closeButton",
504
+ "aria-label": "Dismiss notification",
505
+ 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)(
506
+ "path",
507
+ {
508
+ d: "M11 3L3 11M3 3l8 8",
509
+ stroke: "currentColor",
510
+ strokeWidth: "1.5",
511
+ strokeLinecap: "round"
512
+ }
513
+ ) })
506
514
  }
507
515
  ) })
508
- }
509
- )
510
- ] });
516
+ ]
517
+ }
518
+ );
511
519
  }
512
520
  function getPalette(type) {
513
521
  switch (type) {
@@ -772,7 +780,9 @@ var React6 = __toESM(require("react"), 1);
772
780
 
773
781
  // src/components/select/Select.tsx
774
782
  var React5 = __toESM(require("react"), 1);
783
+ var SelectPrimitive = __toESM(require("@radix-ui/react-select"), 1);
775
784
  var import_jsx_runtime12 = require("react/jsx-runtime");
785
+ var EMPTY_OPTION_VALUE = "__uzi_select_empty__";
776
786
  var Select = React5.forwardRef(
777
787
  ({
778
788
  options,
@@ -782,27 +792,144 @@ var Select = React5.forwardRef(
782
792
  allowEmptyOption = false,
783
793
  fullWidth = true,
784
794
  className,
785
- ...rest
795
+ id,
796
+ name,
797
+ disabled,
798
+ required,
799
+ autoComplete,
800
+ form,
801
+ title,
802
+ "aria-label": ariaLabel,
803
+ "aria-labelledby": ariaLabelledBy,
804
+ onBlur,
805
+ onFocus
786
806
  }, ref) => {
787
- const isPlaceholderShown = Boolean(placeholder) && value === "";
788
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cx("wrapper", fullWidth && "wrapper-fullWidth", className), children: [
789
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
790
- "select",
791
- {
792
- ref,
793
- value,
794
- onChange: (e) => onChange(e.target.value),
795
- className: cx("select", isPlaceholderShown && "select-placeholder"),
796
- "data-placeholder-shown": isPlaceholderShown ? "true" : void 0,
797
- ...rest,
798
- children: [
799
- placeholder ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: "", disabled: !allowEmptyOption, children: placeholder }) : null,
800
- options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: opt.value, disabled: opt.disabled, children: opt.label }, opt.value))
801
- ]
802
- }
803
- ),
804
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "chevron", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime12.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_runtime12.jsx)("path", { d: "M2 3.5L5 6.5L8 3.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
805
- ] });
807
+ const internalValue = value === "" && allowEmptyOption ? EMPTY_OPTION_VALUE : value;
808
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cx("wrapper", fullWidth && "wrapper-fullWidth", className), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
809
+ SelectPrimitive.Root,
810
+ {
811
+ value: internalValue,
812
+ onValueChange: (nextValue) => onChange(nextValue === EMPTY_OPTION_VALUE ? "" : nextValue),
813
+ name,
814
+ disabled,
815
+ required,
816
+ autoComplete,
817
+ children: [
818
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
819
+ SelectPrimitive.Trigger,
820
+ {
821
+ ref,
822
+ id,
823
+ className: "select",
824
+ form,
825
+ title,
826
+ "aria-label": ariaLabel,
827
+ "aria-labelledby": ariaLabelledBy,
828
+ onBlur,
829
+ onFocus,
830
+ children: [
831
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.Value, { placeholder }),
832
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.Icon, { className: "chevron", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
833
+ "svg",
834
+ {
835
+ viewBox: "0 0 10 10",
836
+ fill: "none",
837
+ xmlns: "http://www.w3.org/2000/svg",
838
+ width: "10",
839
+ height: "10",
840
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
841
+ "path",
842
+ {
843
+ d: "M2 3.5L5 6.5L8 3.5",
844
+ stroke: "currentColor",
845
+ strokeWidth: "1.5",
846
+ strokeLinecap: "round",
847
+ strokeLinejoin: "round"
848
+ }
849
+ )
850
+ }
851
+ ) })
852
+ ]
853
+ }
854
+ ),
855
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
856
+ SelectPrimitive.Content,
857
+ {
858
+ className: "content",
859
+ position: "popper",
860
+ sideOffset: 4,
861
+ align: "start",
862
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(SelectPrimitive.Viewport, { className: "viewport", children: [
863
+ placeholder && allowEmptyOption ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
864
+ SelectPrimitive.Item,
865
+ {
866
+ value: EMPTY_OPTION_VALUE,
867
+ className: "item",
868
+ children: [
869
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "indicator", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
870
+ "svg",
871
+ {
872
+ viewBox: "0 0 16 16",
873
+ width: "16",
874
+ height: "16",
875
+ "aria-hidden": "true",
876
+ className: "indicatorIcon",
877
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
878
+ "path",
879
+ {
880
+ d: "M3.5 8.5 6.5 11.5 12.5 4.5",
881
+ fill: "none",
882
+ stroke: "currentColor",
883
+ strokeWidth: "1.8",
884
+ strokeLinecap: "round",
885
+ strokeLinejoin: "round"
886
+ }
887
+ )
888
+ }
889
+ ) }) }),
890
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.ItemText, { children: placeholder })
891
+ ]
892
+ }
893
+ ) : null,
894
+ options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
895
+ SelectPrimitive.Item,
896
+ {
897
+ value: opt.value,
898
+ disabled: opt.disabled,
899
+ className: "item",
900
+ children: [
901
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "indicator", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
902
+ "svg",
903
+ {
904
+ viewBox: "0 0 16 16",
905
+ width: "16",
906
+ height: "16",
907
+ "aria-hidden": "true",
908
+ className: "indicatorIcon",
909
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
910
+ "path",
911
+ {
912
+ d: "M3.5 8.5 6.5 11.5 12.5 4.5",
913
+ fill: "none",
914
+ stroke: "currentColor",
915
+ strokeWidth: "1.8",
916
+ strokeLinecap: "round",
917
+ strokeLinejoin: "round"
918
+ }
919
+ )
920
+ }
921
+ ) }) }),
922
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SelectPrimitive.ItemText, { children: opt.label })
923
+ ]
924
+ },
925
+ opt.value
926
+ ))
927
+ ] })
928
+ }
929
+ ) })
930
+ ]
931
+ }
932
+ ) });
806
933
  }
807
934
  );
808
935
  Select.displayName = "Select";
@@ -1022,10 +1149,10 @@ function DropdownMenuSubContent({
1022
1149
  }
1023
1150
 
1024
1151
  // src/components/app-shell/AppShell.tsx
1025
- var import_react4 = require("react");
1152
+ var import_react3 = require("react");
1026
1153
 
1027
1154
  // src/theme/ThemeProvider.tsx
1028
- var import_react3 = require("react");
1155
+ var import_react2 = require("react");
1029
1156
 
1030
1157
  // src/theme/constants.ts
1031
1158
  var UZI_THEMES = ["light", "dark", "system"];
@@ -1039,7 +1166,7 @@ var THEME_STORAGE_KEY2 = THEME_STORAGE_KEY;
1039
1166
  var ACCENT_STORAGE_KEY2 = ACCENT_STORAGE_KEY;
1040
1167
  var THEME_ATTRIBUTE = "data-uzi-theme";
1041
1168
  var ACCENT_ATTRIBUTE = "data-uzi-accent";
1042
- var ThemeContext = (0, import_react3.createContext)(void 0);
1169
+ var ThemeContext = (0, import_react2.createContext)(void 0);
1043
1170
  function isTheme(value) {
1044
1171
  return UZI_THEMES.includes(value);
1045
1172
  }
@@ -1062,10 +1189,10 @@ function ThemeProvider({
1062
1189
  accentStorageKey = ACCENT_STORAGE_KEY2,
1063
1190
  disableStorage = false
1064
1191
  }) {
1065
- const [internalTheme, setInternalTheme] = (0, import_react3.useState)(defaultTheme);
1066
- const [internalAccent, setInternalAccent] = (0, import_react3.useState)(defaultAccent);
1067
- const [systemTheme, setSystemTheme] = (0, import_react3.useState)("light");
1068
- (0, import_react3.useEffect)(() => {
1192
+ const [internalTheme, setInternalTheme] = (0, import_react2.useState)(defaultTheme);
1193
+ const [internalAccent, setInternalAccent] = (0, import_react2.useState)(defaultAccent);
1194
+ const [systemTheme, setSystemTheme] = (0, import_react2.useState)("light");
1195
+ (0, import_react2.useEffect)(() => {
1069
1196
  setSystemTheme(getSystemTheme());
1070
1197
  if (!disableStorage) {
1071
1198
  const storedTheme = window.localStorage.getItem(storageKey);
@@ -1079,7 +1206,7 @@ function ThemeProvider({
1079
1206
  const currentTheme = isThemeControlled ? theme : internalTheme;
1080
1207
  const currentAccent = isAccentControlled ? accent : internalAccent;
1081
1208
  const resolvedTheme = currentTheme === "system" ? systemTheme : currentTheme;
1082
- (0, import_react3.useEffect)(() => {
1209
+ (0, import_react2.useEffect)(() => {
1083
1210
  if (typeof window === "undefined") return;
1084
1211
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1085
1212
  const handleChange = () => setSystemTheme(mediaQuery.matches ? "dark" : "light");
@@ -1087,7 +1214,7 @@ function ThemeProvider({
1087
1214
  mediaQuery.addEventListener("change", handleChange);
1088
1215
  return () => mediaQuery.removeEventListener("change", handleChange);
1089
1216
  }, []);
1090
- (0, import_react3.useEffect)(() => {
1217
+ (0, import_react2.useEffect)(() => {
1091
1218
  if (typeof document === "undefined") return;
1092
1219
  const root = document.documentElement;
1093
1220
  root.setAttribute(THEME_ATTRIBUTE, resolvedTheme);
@@ -1095,7 +1222,7 @@ function ThemeProvider({
1095
1222
  root.style.colorScheme = resolvedTheme;
1096
1223
  root.classList.toggle("dark", resolvedTheme === "dark");
1097
1224
  }, [currentAccent, resolvedTheme]);
1098
- const setTheme = (0, import_react3.useCallback)(
1225
+ const setTheme = (0, import_react2.useCallback)(
1099
1226
  (nextTheme) => {
1100
1227
  if (!isThemeControlled) setInternalTheme(nextTheme);
1101
1228
  if (!disableStorage && typeof window !== "undefined") {
@@ -1105,7 +1232,7 @@ function ThemeProvider({
1105
1232
  },
1106
1233
  [disableStorage, isThemeControlled, onThemeChange, storageKey]
1107
1234
  );
1108
- const setAccent = (0, import_react3.useCallback)(
1235
+ const setAccent = (0, import_react2.useCallback)(
1109
1236
  (nextAccent) => {
1110
1237
  if (!isAccentControlled) setInternalAccent(nextAccent);
1111
1238
  if (!disableStorage && typeof window !== "undefined") {
@@ -1115,10 +1242,10 @@ function ThemeProvider({
1115
1242
  },
1116
1243
  [accentStorageKey, disableStorage, isAccentControlled, onAccentChange]
1117
1244
  );
1118
- const toggleTheme = (0, import_react3.useCallback)(() => {
1245
+ const toggleTheme = (0, import_react2.useCallback)(() => {
1119
1246
  setTheme(resolvedTheme === "dark" ? "light" : "dark");
1120
1247
  }, [resolvedTheme, setTheme]);
1121
- const value = (0, import_react3.useMemo)(
1248
+ const value = (0, import_react2.useMemo)(
1122
1249
  () => ({
1123
1250
  theme: currentTheme,
1124
1251
  resolvedTheme,
@@ -1132,7 +1259,7 @@ function ThemeProvider({
1132
1259
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ThemeContext.Provider, { value, children });
1133
1260
  }
1134
1261
  function useTheme() {
1135
- const context = (0, import_react3.useContext)(ThemeContext);
1262
+ const context = (0, import_react2.useContext)(ThemeContext);
1136
1263
  if (!context) throw new Error("useTheme must be used within a ThemeProvider");
1137
1264
  return context;
1138
1265
  }
@@ -1268,16 +1395,16 @@ function AppShell({
1268
1395
  hamburgerLabel = "Toggle navigation",
1269
1396
  onSidebarToggle
1270
1397
  }) {
1271
- const [isDesktop, setIsDesktop] = (0, import_react4.useState)(false);
1272
- const [sidebarOpen, setSidebarOpen] = (0, import_react4.useState)(false);
1273
- const [transitionsReady, setTransitionsReady] = (0, import_react4.useState)(false);
1274
- const prevIsDesktopRef = (0, import_react4.useRef)(false);
1275
- const closeKeyRef = (0, import_react4.useRef)(closeSidebarOnChangeKey);
1276
- const sidebarRef = (0, import_react4.useRef)(null);
1277
- const hamburgerRef = (0, import_react4.useRef)(null);
1278
- const mainRef = (0, import_react4.useRef)(null);
1279
- const sidebarId = (0, import_react4.useId)();
1280
- (0, import_react4.useEffect)(() => {
1398
+ const [isDesktop, setIsDesktop] = (0, import_react3.useState)(false);
1399
+ const [sidebarOpen, setSidebarOpen] = (0, import_react3.useState)(false);
1400
+ const [transitionsReady, setTransitionsReady] = (0, import_react3.useState)(false);
1401
+ const prevIsDesktopRef = (0, import_react3.useRef)(false);
1402
+ const closeKeyRef = (0, import_react3.useRef)(closeSidebarOnChangeKey);
1403
+ const sidebarRef = (0, import_react3.useRef)(null);
1404
+ const hamburgerRef = (0, import_react3.useRef)(null);
1405
+ const mainRef = (0, import_react3.useRef)(null);
1406
+ const sidebarId = (0, import_react3.useId)();
1407
+ (0, import_react3.useEffect)(() => {
1281
1408
  const desktop = getIsDesktop();
1282
1409
  setIsDesktop(desktop);
1283
1410
  setSidebarOpen(desktop);
@@ -1299,7 +1426,7 @@ function AppShell({
1299
1426
  window.removeEventListener("resize", handleResize);
1300
1427
  };
1301
1428
  }, []);
1302
- (0, import_react4.useEffect)(() => {
1429
+ (0, import_react3.useEffect)(() => {
1303
1430
  if (isDesktop || !sidebarOpen) return;
1304
1431
  const mainElement = mainRef.current;
1305
1432
  const closeSidebar = () => setSidebarOpen(false);
@@ -1324,13 +1451,13 @@ function AppShell({
1324
1451
  document.removeEventListener("touchmove", closeSidebar);
1325
1452
  };
1326
1453
  }, [sidebarOpen, isDesktop]);
1327
- (0, import_react4.useEffect)(() => {
1454
+ (0, import_react3.useEffect)(() => {
1328
1455
  if (!isDesktop && closeKeyRef.current !== closeSidebarOnChangeKey) {
1329
1456
  setSidebarOpen(false);
1330
1457
  }
1331
1458
  closeKeyRef.current = closeSidebarOnChangeKey;
1332
1459
  }, [closeSidebarOnChangeKey, isDesktop]);
1333
- (0, import_react4.useEffect)(() => {
1460
+ (0, import_react3.useEffect)(() => {
1334
1461
  onSidebarToggle?.(sidebarOpen);
1335
1462
  }, [sidebarOpen, onSidebarToggle]);
1336
1463
  const toggleSidebar = () => setSidebarOpen((open) => !open);