@yomologic/react-ui 0.2.5 → 0.2.7

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.mjs CHANGED
@@ -32,9 +32,11 @@ var Button = React.forwardRef(
32
32
  danger: "[background-color:var(--color-error)] text-white hover:bg-red-700 focus:[--tw-ring-color:var(--color-error)]"
33
33
  };
34
34
  const sizes = {
35
- sm: "[font-size:var(--button-text-sm)] [padding-left:var(--button-padding-sm-x)] [padding-right:var(--button-padding-sm-x)] [padding-top:var(--button-padding-sm-y)] [padding-bottom:var(--button-padding-sm-y)] gap-1.5",
36
- md: "[font-size:var(--button-text-md)] [padding-left:var(--button-padding-md-x)] [padding-right:var(--button-padding-md-x)] [padding-top:var(--button-padding-md-y)] [padding-bottom:var(--button-padding-md-y)] gap-2",
37
- lg: "[font-size:var(--button-text-lg)] [padding-left:var(--button-padding-lg-x)] [padding-right:var(--button-padding-lg-x)] [padding-top:var(--button-padding-lg-y)] [padding-bottom:var(--button-padding-lg-y)] gap-2.5"
35
+ xs: "[font-size:var(--button-font-size-xs)] [padding-left:var(--button-padding-xs-x)] [padding-right:var(--button-padding-xs-x)] [padding-top:var(--button-padding-xs-y)] [padding-bottom:var(--button-padding-xs-y)] gap-1",
36
+ sm: "[font-size:var(--button-font-size-sm)] [padding-left:var(--button-padding-sm-x)] [padding-right:var(--button-padding-sm-x)] [padding-top:var(--button-padding-sm-y)] [padding-bottom:var(--button-padding-sm-y)] gap-1.5",
37
+ md: "[font-size:var(--button-font-size-md)] [padding-left:var(--button-padding-md-x)] [padding-right:var(--button-padding-md-x)] [padding-top:var(--button-padding-md-y)] [padding-bottom:var(--button-padding-md-y)] gap-2",
38
+ lg: "[font-size:var(--button-font-size-lg)] [padding-left:var(--button-padding-lg-x)] [padding-right:var(--button-padding-lg-x)] [padding-top:var(--button-padding-lg-y)] [padding-bottom:var(--button-padding-lg-y)] gap-2.5",
39
+ xl: "[font-size:var(--button-font-size-xl)] [padding-left:var(--button-padding-xl-x)] [padding-right:var(--button-padding-xl-x)] [padding-top:var(--button-padding-xl-y)] [padding-bottom:var(--button-padding-xl-y)] gap-3"
38
40
  };
39
41
  const radiusStyle = "[border-radius:var(--button-radius)]";
40
42
  const fontWeightStyle = "[font-weight:var(--button-font-weight)]";
@@ -94,7 +96,7 @@ var Button = React.forwardRef(
94
96
  Button.displayName = "Button";
95
97
 
96
98
  // src/ui/input.tsx
97
- import React2 from "react";
99
+ import React2, { useId } from "react";
98
100
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
99
101
  var Input = React2.forwardRef(
100
102
  ({
@@ -109,7 +111,8 @@ var Input = React2.forwardRef(
109
111
  id,
110
112
  ...props
111
113
  }, ref) => {
112
- const inputId = id || label?.toLowerCase().replace(/\s+/g, "-");
114
+ const autoId = useId();
115
+ const inputId = id || `input-${autoId}`;
113
116
  return /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col", fullWidth && "w-full"), children: [
114
117
  label && /* @__PURE__ */ jsxs2(
115
118
  "label",
@@ -249,9 +252,11 @@ var Badge = React4.forwardRef(
249
252
  info: "bg-cyan-100 text-cyan-800"
250
253
  };
251
254
  const sizes = {
255
+ xs: "text-[0.625rem] px-1.5 py-0.5",
252
256
  sm: "text-xs px-2 py-0.5",
253
257
  md: "text-sm px-2.5 py-1",
254
- lg: "text-base px-3 py-1.5"
258
+ lg: "text-base px-3 py-1.5",
259
+ xl: "text-lg px-3.5 py-2"
255
260
  };
256
261
  const dotVariants = {
257
262
  default: "bg-gray-600",
@@ -283,6 +288,7 @@ var Badge = React4.forwardRef(
283
288
  Badge.displayName = "Badge";
284
289
 
285
290
  // src/ui/checkbox.tsx
291
+ import { useId as useId2 } from "react";
286
292
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
287
293
  function Checkbox({
288
294
  label,
@@ -290,14 +296,37 @@ function Checkbox({
290
296
  onChange,
291
297
  disabled = false,
292
298
  className,
293
- id
299
+ id,
300
+ size = "md"
294
301
  }) {
295
- const checkboxId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
302
+ const autoId = useId2();
303
+ const checkboxId = id || `checkbox-${autoId}`;
296
304
  const handleChange = (e) => {
297
305
  if (onChange) {
298
306
  onChange(e.target.checked);
299
307
  }
300
308
  };
309
+ const sizeStyles = {
310
+ xs: `[width:var(--checkbox-size-xs)] [height:var(--checkbox-size-xs)]`,
311
+ sm: `[width:var(--checkbox-size-sm)] [height:var(--checkbox-size-sm)]`,
312
+ md: `[width:var(--checkbox-size-md)] [height:var(--checkbox-size-md)]`,
313
+ lg: `[width:var(--checkbox-size-lg)] [height:var(--checkbox-size-lg)]`,
314
+ xl: `[width:var(--checkbox-size-xl)] [height:var(--checkbox-size-xl)]`
315
+ };
316
+ const labelSizeStyles = {
317
+ xs: `[font-size:var(--checkbox-label-font-size-xs)]`,
318
+ sm: `[font-size:var(--checkbox-label-font-size-sm)]`,
319
+ md: `[font-size:var(--checkbox-label-font-size-md)]`,
320
+ lg: `[font-size:var(--checkbox-label-font-size-lg)]`,
321
+ xl: `[font-size:var(--checkbox-label-font-size-xl)]`
322
+ };
323
+ const labelSpacingStyles = {
324
+ xs: `[margin-left:var(--checkbox-label-spacing-xs)]`,
325
+ sm: `[margin-left:var(--checkbox-label-spacing-sm)]`,
326
+ md: `[margin-left:var(--checkbox-label-spacing-md)]`,
327
+ lg: `[margin-left:var(--checkbox-label-spacing-lg)]`,
328
+ xl: `[margin-left:var(--checkbox-label-spacing-xl)]`
329
+ };
301
330
  return /* @__PURE__ */ jsxs4("div", { className: cn("flex items-center", className), children: [
302
331
  /* @__PURE__ */ jsx5(
303
332
  "input",
@@ -308,7 +337,8 @@ function Checkbox({
308
337
  onChange: handleChange,
309
338
  disabled,
310
339
  className: cn(
311
- "h-4 w-4 rounded border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
340
+ sizeStyles[size],
341
+ "rounded-(--checkbox-radius) border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
312
342
  disabled && "cursor-not-allowed opacity-50"
313
343
  )
314
344
  }
@@ -318,7 +348,9 @@ function Checkbox({
318
348
  {
319
349
  htmlFor: checkboxId,
320
350
  className: cn(
321
- "ml-2 text-sm font-medium text-gray-600",
351
+ labelSpacingStyles[size],
352
+ labelSizeStyles[size],
353
+ "font-medium text-gray-600",
322
354
  disabled && "cursor-not-allowed opacity-50",
323
355
  !disabled && "cursor-pointer"
324
356
  ),
@@ -336,7 +368,8 @@ function CheckboxGroup({
336
368
  className,
337
369
  orientation = "vertical",
338
370
  required = false,
339
- disabled = false
371
+ disabled = false,
372
+ size = "md"
340
373
  }) {
341
374
  const handleChange = (optionValue, checked) => {
342
375
  if (onChange) {
@@ -347,6 +380,27 @@ function CheckboxGroup({
347
380
  }
348
381
  }
349
382
  };
383
+ const sizeStyles = {
384
+ xs: `[width:var(--checkbox-size-xs)] [height:var(--checkbox-size-xs)]`,
385
+ sm: `[width:var(--checkbox-size-sm)] [height:var(--checkbox-size-sm)]`,
386
+ md: `[width:var(--checkbox-size-md)] [height:var(--checkbox-size-md)]`,
387
+ lg: `[width:var(--checkbox-size-lg)] [height:var(--checkbox-size-lg)]`,
388
+ xl: `[width:var(--checkbox-size-xl)] [height:var(--checkbox-size-xl)]`
389
+ };
390
+ const labelSizeStyles = {
391
+ xs: `[font-size:var(--checkbox-label-font-size-xs)]`,
392
+ sm: `[font-size:var(--checkbox-label-font-size-sm)]`,
393
+ md: `[font-size:var(--checkbox-label-font-size-md)]`,
394
+ lg: `[font-size:var(--checkbox-label-font-size-lg)]`,
395
+ xl: `[font-size:var(--checkbox-label-font-size-xl)]`
396
+ };
397
+ const labelSpacingStyles = {
398
+ xs: `[margin-left:var(--checkbox-label-spacing-xs)]`,
399
+ sm: `[margin-left:var(--checkbox-label-spacing-sm)]`,
400
+ md: `[margin-left:var(--checkbox-label-spacing-md)]`,
401
+ lg: `[margin-left:var(--checkbox-label-spacing-lg)]`,
402
+ xl: `[margin-left:var(--checkbox-label-spacing-xl)]`
403
+ };
350
404
  return /* @__PURE__ */ jsxs4("div", { className, children: [
351
405
  label && /* @__PURE__ */ jsxs4("label", { className: "block text-sm font-semibold text-gray-600 mb-1", children: [
352
406
  label,
@@ -373,7 +427,8 @@ function CheckboxGroup({
373
427
  onChange: (e) => handleChange(option.value, e.target.checked),
374
428
  disabled: isDisabled,
375
429
  className: cn(
376
- "h-4 w-4 rounded border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
430
+ sizeStyles[size],
431
+ "rounded-(--checkbox-radius) border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
377
432
  isDisabled && "cursor-not-allowed opacity-50"
378
433
  )
379
434
  }
@@ -383,7 +438,9 @@ function CheckboxGroup({
383
438
  {
384
439
  htmlFor: `${name}-${option.value}`,
385
440
  className: cn(
386
- "ml-2 text-sm font-medium text-gray-600",
441
+ labelSpacingStyles[size],
442
+ labelSizeStyles[size],
443
+ "font-medium text-gray-600",
387
444
  isDisabled && "cursor-not-allowed opacity-50",
388
445
  !isDisabled && "cursor-pointer"
389
446
  ),
@@ -408,13 +465,35 @@ function RadioGroup({
408
465
  className,
409
466
  orientation = "vertical",
410
467
  required = false,
411
- disabled = false
468
+ disabled = false,
469
+ size = "md"
412
470
  }) {
413
471
  const handleChange = (e) => {
414
472
  if (onChange) {
415
473
  onChange(e.target.value);
416
474
  }
417
475
  };
476
+ const sizeStyles = {
477
+ xs: `[width:var(--radio-size-xs)] [height:var(--radio-size-xs)]`,
478
+ sm: `[width:var(--radio-size-sm)] [height:var(--radio-size-sm)]`,
479
+ md: `[width:var(--radio-size-md)] [height:var(--radio-size-md)]`,
480
+ lg: `[width:var(--radio-size-lg)] [height:var(--radio-size-lg)]`,
481
+ xl: `[width:var(--radio-size-xl)] [height:var(--radio-size-xl)]`
482
+ };
483
+ const labelSizeStyles = {
484
+ xs: `[font-size:var(--radio-label-font-size-xs)]`,
485
+ sm: `[font-size:var(--radio-label-font-size-sm)]`,
486
+ md: `[font-size:var(--radio-label-font-size-md)]`,
487
+ lg: `[font-size:var(--radio-label-font-size-lg)]`,
488
+ xl: `[font-size:var(--radio-label-font-size-xl)]`
489
+ };
490
+ const labelSpacingStyles = {
491
+ xs: `[margin-left:var(--radio-label-spacing-xs)]`,
492
+ sm: `[margin-left:var(--radio-label-spacing-sm)]`,
493
+ md: `[margin-left:var(--radio-label-spacing-md)]`,
494
+ lg: `[margin-left:var(--radio-label-spacing-lg)]`,
495
+ xl: `[margin-left:var(--radio-label-spacing-xl)]`
496
+ };
418
497
  return /* @__PURE__ */ jsxs5("div", { className, children: [
419
498
  label && /* @__PURE__ */ jsxs5("label", { className: "block text-sm font-semibold text-gray-600 mb-1", children: [
420
499
  label,
@@ -441,7 +520,8 @@ function RadioGroup({
441
520
  onChange: handleChange,
442
521
  disabled: isDisabled,
443
522
  className: cn(
444
- "h-4 w-4 border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
523
+ sizeStyles[size],
524
+ "border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
445
525
  isDisabled && "cursor-not-allowed opacity-50"
446
526
  )
447
527
  }
@@ -451,7 +531,9 @@ function RadioGroup({
451
531
  {
452
532
  htmlFor: `${name}-${option.value}`,
453
533
  className: cn(
454
- "ml-2 text-sm font-medium text-gray-600",
534
+ labelSpacingStyles[size],
535
+ labelSizeStyles[size],
536
+ "font-medium text-gray-600",
455
537
  isDisabled && "cursor-not-allowed opacity-50",
456
538
  !isDisabled && "cursor-pointer"
457
539
  ),
@@ -480,6 +562,7 @@ function Dropdown({
480
562
  error,
481
563
  helperText,
482
564
  required = false,
565
+ size = "md",
483
566
  className = ""
484
567
  }) {
485
568
  const [isOpen, setIsOpen] = useState(false);
@@ -489,6 +572,27 @@ function Dropdown({
489
572
  const selected = options.find((opt) => opt.value === value);
490
573
  return selected ? selected.label : placeholder;
491
574
  };
575
+ const sizeStyles = {
576
+ xs: `[padding-left:var(--dropdown-padding-xs-x)] [padding-right:var(--dropdown-padding-xs-x)] [padding-top:var(--dropdown-padding-xs-y)] [padding-bottom:var(--dropdown-padding-xs-y)] [font-size:var(--dropdown-font-size-xs)]`,
577
+ sm: `[padding-left:var(--dropdown-padding-sm-x)] [padding-right:var(--dropdown-padding-sm-x)] [padding-top:var(--dropdown-padding-sm-y)] [padding-bottom:var(--dropdown-padding-sm-y)] [font-size:var(--dropdown-font-size-sm)]`,
578
+ md: `[padding-left:var(--dropdown-padding-md-x)] [padding-right:var(--dropdown-padding-md-x)] [padding-top:var(--dropdown-padding-md-y)] [padding-bottom:var(--dropdown-padding-md-y)] [font-size:var(--dropdown-font-size-md)]`,
579
+ lg: `[padding-left:var(--dropdown-padding-lg-x)] [padding-right:var(--dropdown-padding-lg-x)] [padding-top:var(--dropdown-padding-lg-y)] [padding-bottom:var(--dropdown-padding-lg-y)] [font-size:var(--dropdown-font-size-lg)]`,
580
+ xl: `[padding-left:var(--dropdown-padding-xl-x)] [padding-right:var(--dropdown-padding-xl-x)] [padding-top:var(--dropdown-padding-xl-y)] [padding-bottom:var(--dropdown-padding-xl-y)] [font-size:var(--dropdown-font-size-xl)]`
581
+ };
582
+ const iconSizeStyles = {
583
+ xs: `[width:var(--dropdown-icon-size-xs)] [height:var(--dropdown-icon-size-xs)]`,
584
+ sm: `[width:var(--dropdown-icon-size-sm)] [height:var(--dropdown-icon-size-sm)]`,
585
+ md: `[width:var(--dropdown-icon-size-md)] [height:var(--dropdown-icon-size-md)]`,
586
+ lg: `[width:var(--dropdown-icon-size-lg)] [height:var(--dropdown-icon-size-lg)]`,
587
+ xl: `[width:var(--dropdown-icon-size-xl)] [height:var(--dropdown-icon-size-xl)]`
588
+ };
589
+ const optionSizeStyles = {
590
+ xs: `[padding-left:var(--dropdown-option-padding-xs-x)] [padding-right:var(--dropdown-option-padding-xs-x)] [padding-top:var(--dropdown-option-padding-xs-y)] [padding-bottom:var(--dropdown-option-padding-xs-y)] [font-size:var(--dropdown-option-font-size-xs)]`,
591
+ sm: `[padding-left:var(--dropdown-option-padding-sm-x)] [padding-right:var(--dropdown-option-padding-sm-x)] [padding-top:var(--dropdown-option-padding-sm-y)] [padding-bottom:var(--dropdown-option-padding-sm-y)] [font-size:var(--dropdown-option-font-size-sm)]`,
592
+ md: `[padding-left:var(--dropdown-option-padding-md-x)] [padding-right:var(--dropdown-option-padding-md-x)] [padding-top:var(--dropdown-option-padding-md-y)] [padding-bottom:var(--dropdown-option-padding-md-y)] [font-size:var(--dropdown-option-font-size-md)]`,
593
+ lg: `[padding-left:var(--dropdown-option-padding-lg-x)] [padding-right:var(--dropdown-option-padding-lg-x)] [padding-top:var(--dropdown-option-padding-lg-y)] [padding-bottom:var(--dropdown-option-padding-lg-y)] [font-size:var(--dropdown-option-font-size-lg)]`,
594
+ xl: `[padding-left:var(--dropdown-option-padding-xl-x)] [padding-right:var(--dropdown-option-padding-xl-x)] [padding-top:var(--dropdown-option-padding-xl-y)] [padding-bottom:var(--dropdown-option-padding-xl-y)] [font-size:var(--dropdown-option-font-size-xl)]`
595
+ };
492
596
  useEffect(() => {
493
597
  const handleClickOutside = (event) => {
494
598
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -525,7 +629,7 @@ function Dropdown({
525
629
  onKeyDown: handleKeyDown,
526
630
  disabled,
527
631
  className: `
528
- w-full px-4 py-2 text-left bg-white border rounded-lg
632
+ w-full ${sizeStyles[size]} text-left bg-white border rounded-(--dropdown-radius)
529
633
  flex items-center justify-between
530
634
  transition-all duration-200
531
635
  ${error ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500" : "border-gray-400 focus:ring-2 focus:ring-blue-200 focus:border-blue-500"}
@@ -537,7 +641,7 @@ function Dropdown({
537
641
  /* @__PURE__ */ jsx7(
538
642
  ChevronDown,
539
643
  {
540
- className: `w-5 h-5 text-gray-400 transition-transform duration-200 shrink-0 ml-2 ${isOpen ? "transform rotate-180" : ""}`
644
+ className: `${iconSizeStyles[size]} text-gray-400 transition-transform duration-200 shrink-0 ml-2 ${isOpen ? "transform rotate-180" : ""}`
541
645
  }
542
646
  )
543
647
  ]
@@ -560,7 +664,7 @@ function Dropdown({
560
664
  onClick: () => !option.disabled && handleSelect(option.value),
561
665
  disabled: option.disabled,
562
666
  className: `
563
- w-full px-4 py-2 text-left text-sm
667
+ w-full ${optionSizeStyles[size]} text-left
564
668
  transition-colors duration-150
565
669
  ${option.value === value ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-900 hover:bg-gray-100"}
566
670
  ${option.disabled ? "opacity-50 cursor-not-allowed" : ""}
@@ -912,48 +1016,452 @@ function SectionLayout({
912
1016
  ] });
913
1017
  }
914
1018
 
915
- // src/layout/sidebar-nav.tsx
916
- import { useState as useState3 } from "react";
917
- import { Menu, X } from "lucide-react";
1019
+ // src/layout/nav.tsx
1020
+ import React9, { useState as useState3, useEffect as useEffect2, useRef as useRef2 } from "react";
1021
+ import { Menu, X, ChevronDown as ChevronDown2 } from "lucide-react";
918
1022
  import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1023
+ var Nav = React9.forwardRef(
1024
+ ({
1025
+ className,
1026
+ items,
1027
+ variant = "primary",
1028
+ orientation = "horizontal",
1029
+ size = "md",
1030
+ mobileBreakpoint = "md",
1031
+ mobileMenuDirection = "top",
1032
+ logo,
1033
+ actions,
1034
+ sticky = false,
1035
+ activeId,
1036
+ onItemClick,
1037
+ ...props
1038
+ }, ref) => {
1039
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState3(false);
1040
+ const [openDropdownId, setOpenDropdownId] = useState3(null);
1041
+ const dropdownRef = useRef2(null);
1042
+ useEffect2(() => {
1043
+ function handleClickOutside(event) {
1044
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
1045
+ setOpenDropdownId(null);
1046
+ }
1047
+ }
1048
+ document.addEventListener("mousedown", handleClickOutside);
1049
+ return () => {
1050
+ document.removeEventListener("mousedown", handleClickOutside);
1051
+ };
1052
+ }, []);
1053
+ useEffect2(() => {
1054
+ function handleEscape(event) {
1055
+ if (event.key === "Escape") {
1056
+ setIsMobileMenuOpen(false);
1057
+ setOpenDropdownId(null);
1058
+ }
1059
+ }
1060
+ document.addEventListener("keydown", handleEscape);
1061
+ return () => {
1062
+ document.removeEventListener("keydown", handleEscape);
1063
+ };
1064
+ }, []);
1065
+ useEffect2(() => {
1066
+ setIsMobileMenuOpen(false);
1067
+ }, [mobileMenuDirection]);
1068
+ const baseStyles = cn(
1069
+ "bg-[var(--color-background)] border-b border-[var(--color-border)]",
1070
+ sticky && "sticky top-0 [z-index:var(--z-index-nav)]"
1071
+ );
1072
+ const containerStyles = cn(
1073
+ "[min-height:var(--nav-height)]",
1074
+ "flex items-center justify-between",
1075
+ "px-[var(--spacing-lg)]"
1076
+ );
1077
+ const itemPaddingStyles = {
1078
+ xs: "[padding-left:var(--nav-item-padding-xs-x)] [padding-right:var(--nav-item-padding-xs-x)] [padding-top:var(--nav-item-padding-xs-y)] [padding-bottom:var(--nav-item-padding-xs-y)]",
1079
+ sm: "[padding-left:var(--nav-item-padding-sm-x)] [padding-right:var(--nav-item-padding-sm-x)] [padding-top:var(--nav-item-padding-sm-y)] [padding-bottom:var(--nav-item-padding-sm-y)]",
1080
+ md: "[padding-left:var(--nav-item-padding-md-x)] [padding-right:var(--nav-item-padding-md-x)] [padding-top:var(--nav-item-padding-md-y)] [padding-bottom:var(--nav-item-padding-md-y)]",
1081
+ lg: "[padding-left:var(--nav-item-padding-lg-x)] [padding-right:var(--nav-item-padding-lg-x)] [padding-top:var(--nav-item-padding-lg-y)] [padding-bottom:var(--nav-item-padding-lg-y)]",
1082
+ xl: "[padding-left:var(--nav-item-padding-xl-x)] [padding-right:var(--nav-item-padding-xl-x)] [padding-top:var(--nav-item-padding-xl-y)] [padding-bottom:var(--nav-item-padding-xl-y)]"
1083
+ };
1084
+ const fontSizeStyles = {
1085
+ xs: "[font-size:var(--nav-font-size-xs)]",
1086
+ sm: "[font-size:var(--nav-font-size-sm)]",
1087
+ md: "[font-size:var(--nav-font-size-md)]",
1088
+ lg: "[font-size:var(--nav-font-size-lg)]",
1089
+ xl: "[font-size:var(--nav-font-size-xl)]"
1090
+ };
1091
+ const variantItemStyles = {
1092
+ primary: "rounded-[var(--nav-border-radius)] hover:bg-blue-50 transition-colors",
1093
+ secondary: "rounded-[var(--nav-border-radius)] hover:bg-[var(--color-muted)] transition-colors",
1094
+ outline: cn(
1095
+ "rounded-[var(--nav-border-radius)] border border-[var(--color-border)] hover:bg-[var(--color-muted)] transition-colors"
1096
+ ),
1097
+ ghost: "rounded-[var(--nav-border-radius)] hover:bg-[var(--color-muted)]/50 transition-colors"
1098
+ };
1099
+ const activeItemStyles = {
1100
+ primary: "bg-blue-100 text-blue-700",
1101
+ secondary: "bg-[var(--color-muted)] [font-weight:var(--font-semibold)]",
1102
+ outline: "border-blue-600 bg-blue-50 text-blue-700",
1103
+ ghost: "bg-[var(--color-muted)]"
1104
+ };
1105
+ const breakpointClasses = {
1106
+ sm: "sm:hidden",
1107
+ md: "md:hidden",
1108
+ lg: "lg:hidden"
1109
+ };
1110
+ const breakpointShowClasses = {
1111
+ sm: "hidden sm:flex",
1112
+ md: "hidden md:flex",
1113
+ lg: "hidden lg:flex"
1114
+ };
1115
+ const handleItemClick = (item) => {
1116
+ if (item.disabled) return;
1117
+ if (item.type === "dropdown") {
1118
+ setOpenDropdownId(openDropdownId === item.id ? null : item.id);
1119
+ return;
1120
+ }
1121
+ if (item.onClick) {
1122
+ item.onClick();
1123
+ }
1124
+ if (onItemClick) {
1125
+ onItemClick(item);
1126
+ }
1127
+ setIsMobileMenuOpen(false);
1128
+ setOpenDropdownId(null);
1129
+ };
1130
+ const renderNavItem = (item, isMobile = false) => {
1131
+ if (item.type === "divider") {
1132
+ return /* @__PURE__ */ jsx13(
1133
+ "div",
1134
+ {
1135
+ className: cn(
1136
+ orientation === "horizontal" && !isMobile && "h-6 border-l border-[var(--color-border)] mx-2",
1137
+ (orientation === "vertical" || isMobile) && "w-full h-0 border-t border-[var(--color-border)] my-2"
1138
+ )
1139
+ },
1140
+ item.id
1141
+ );
1142
+ }
1143
+ if (item.type === "custom" && item.render) {
1144
+ return /* @__PURE__ */ jsx13("div", { children: item.render() }, item.id);
1145
+ }
1146
+ const isActive = activeId === item.id;
1147
+ const isDropdownOpen = openDropdownId === item.id;
1148
+ const hasChildren = item.children && item.children.length > 0;
1149
+ const itemBaseStyles = cn(
1150
+ "flex items-center [gap:var(--nav-gap)] font-medium text-[var(--color-foreground)] cursor-pointer select-none",
1151
+ itemPaddingStyles[size],
1152
+ fontSizeStyles[size],
1153
+ variantItemStyles[variant],
1154
+ isActive && activeItemStyles[variant],
1155
+ orientation === "vertical" && "w-full",
1156
+ item.disabled && "opacity-50 cursor-not-allowed"
1157
+ );
1158
+ const content = /* @__PURE__ */ jsxs11(Fragment2, { children: [
1159
+ item.icon && /* @__PURE__ */ jsx13("span", { className: "flex-shrink-0", children: item.icon }),
1160
+ /* @__PURE__ */ jsx13("span", { children: item.label }),
1161
+ item.badge && /* @__PURE__ */ jsx13("span", { className: "ml-auto px-2 py-0.5 [font-size:var(--text-xs)] font-semibold bg-red-500 text-white rounded-[var(--radius-full)]", children: item.badge }),
1162
+ hasChildren && /* @__PURE__ */ jsx13(
1163
+ ChevronDown2,
1164
+ {
1165
+ className: cn(
1166
+ "w-4 h-4 transition-transform",
1167
+ isDropdownOpen && "rotate-180"
1168
+ )
1169
+ }
1170
+ )
1171
+ ] });
1172
+ if (hasChildren) {
1173
+ return /* @__PURE__ */ jsxs11("div", { className: "relative", ref: dropdownRef, children: [
1174
+ /* @__PURE__ */ jsx13(
1175
+ "button",
1176
+ {
1177
+ onClick: () => handleItemClick(item),
1178
+ className: itemBaseStyles,
1179
+ disabled: item.disabled,
1180
+ children: content
1181
+ }
1182
+ ),
1183
+ isDropdownOpen && /* @__PURE__ */ jsx13(
1184
+ "div",
1185
+ {
1186
+ className: cn(
1187
+ "absolute left-0 mt-[var(--nav-gap)] min-w-[200px] bg-[var(--color-background)] border border-[var(--color-border)] rounded-[var(--nav-border-radius)] shadow-lg z-50",
1188
+ orientation === "vertical" && "left-full top-0 ml-2 mt-0"
1189
+ ),
1190
+ children: /* @__PURE__ */ jsx13("div", { className: "py-1", children: item.children.map((child) => /* @__PURE__ */ jsxs11(
1191
+ "button",
1192
+ {
1193
+ onClick: () => handleItemClick(child),
1194
+ disabled: child.disabled,
1195
+ className: cn(
1196
+ "w-full flex items-center gap-2 px-4 py-2 [font-size:var(--text-sm)] text-[var(--color-foreground)] hover:bg-[var(--color-muted)] transition-colors",
1197
+ child.disabled && "opacity-50 cursor-not-allowed",
1198
+ activeId === child.id && "bg-[var(--color-muted)] [font-weight:var(--font-semibold)]"
1199
+ ),
1200
+ children: [
1201
+ child.icon && /* @__PURE__ */ jsx13("span", { className: "flex-shrink-0", children: child.icon }),
1202
+ /* @__PURE__ */ jsx13("span", { children: child.label }),
1203
+ child.badge && /* @__PURE__ */ jsx13("span", { className: "ml-auto px-2 py-0.5 [font-size:var(--text-xs)] font-semibold bg-red-500 text-white rounded-[var(--radius-full)]", children: child.badge })
1204
+ ]
1205
+ },
1206
+ child.id
1207
+ )) })
1208
+ }
1209
+ )
1210
+ ] }, item.id);
1211
+ }
1212
+ if (item.href) {
1213
+ return /* @__PURE__ */ jsx13(
1214
+ "a",
1215
+ {
1216
+ href: item.href,
1217
+ target: item.target,
1218
+ onClick: () => handleItemClick(item),
1219
+ className: itemBaseStyles,
1220
+ children: content
1221
+ },
1222
+ item.id
1223
+ );
1224
+ }
1225
+ return /* @__PURE__ */ jsx13(
1226
+ "button",
1227
+ {
1228
+ onClick: () => handleItemClick(item),
1229
+ disabled: item.disabled,
1230
+ className: itemBaseStyles,
1231
+ children: content
1232
+ },
1233
+ item.id
1234
+ );
1235
+ };
1236
+ const desktopNav = /* @__PURE__ */ jsx13(
1237
+ "div",
1238
+ {
1239
+ className: cn(
1240
+ "items-center [gap:var(--nav-gap)]",
1241
+ breakpointShowClasses[mobileBreakpoint],
1242
+ orientation === "horizontal" ? "flex flex-row" : "flex flex-col"
1243
+ ),
1244
+ children: items.map((item) => renderNavItem(item))
1245
+ }
1246
+ );
1247
+ const mobileNav = /* @__PURE__ */ jsxs11(Fragment2, { children: [
1248
+ /* @__PURE__ */ jsx13(
1249
+ "button",
1250
+ {
1251
+ onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen),
1252
+ className: cn(
1253
+ "p-2 text-[var(--color-foreground)] hover:bg-[var(--color-muted)] rounded-[var(--nav-border-radius)] transition-colors",
1254
+ breakpointClasses[mobileBreakpoint]
1255
+ ),
1256
+ "aria-label": "Toggle menu",
1257
+ children: isMobileMenuOpen ? /* @__PURE__ */ jsx13(X, { className: "w-6 h-6" }) : /* @__PURE__ */ jsx13(Menu, { className: "w-6 h-6" })
1258
+ }
1259
+ ),
1260
+ isMobileMenuOpen && /* @__PURE__ */ jsx13(
1261
+ "div",
1262
+ {
1263
+ className: cn(
1264
+ "fixed inset-0 bg-black/50 [z-index:var(--z-index-nav-mobile-overlay)]",
1265
+ breakpointClasses[mobileBreakpoint]
1266
+ ),
1267
+ onClick: () => setIsMobileMenuOpen(false)
1268
+ }
1269
+ ),
1270
+ /* @__PURE__ */ jsx13(
1271
+ "div",
1272
+ {
1273
+ className: cn(
1274
+ "fixed bg-[var(--color-background)] shadow-lg [z-index:var(--z-index-nav-mobile-menu)] overflow-y-auto transition-transform duration-300 ease-in-out",
1275
+ breakpointClasses[mobileBreakpoint],
1276
+ // Always hide when closed
1277
+ !isMobileMenuOpen && "invisible",
1278
+ // Direction-specific positioning and animation
1279
+ mobileMenuDirection === "top" && [
1280
+ "top-0 left-0 right-0 border-b border-[var(--color-border)] max-h-screen",
1281
+ isMobileMenuOpen ? "translate-y-0" : "-translate-y-full"
1282
+ ],
1283
+ mobileMenuDirection === "left" && [
1284
+ "top-0 left-0 bottom-0 w-64 border-r border-[var(--color-border)]",
1285
+ isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"
1286
+ ],
1287
+ mobileMenuDirection === "right" && [
1288
+ "top-0 right-0 bottom-0 w-64 border-l border-[var(--color-border)]",
1289
+ isMobileMenuOpen ? "translate-x-0" : "translate-x-full"
1290
+ ]
1291
+ ),
1292
+ children: /* @__PURE__ */ jsx13(
1293
+ "div",
1294
+ {
1295
+ className: cn(
1296
+ "flex flex-col",
1297
+ mobileMenuDirection === "top" ? "py-2" : "space-y-1 px-2 pt-2"
1298
+ ),
1299
+ children: items.map((item) => renderNavItem(item, true))
1300
+ }
1301
+ )
1302
+ }
1303
+ )
1304
+ ] });
1305
+ return /* @__PURE__ */ jsx13("nav", { ref, className: cn(baseStyles, className), ...props, children: /* @__PURE__ */ jsxs11("div", { className: containerStyles, children: [
1306
+ logo && /* @__PURE__ */ jsx13("div", { className: "shrink-0", children: logo }),
1307
+ desktopNav,
1308
+ actions && /* @__PURE__ */ jsx13("div", { className: "shrink-0 flex items-center gap-2", children: actions }),
1309
+ mobileNav
1310
+ ] }) });
1311
+ }
1312
+ );
1313
+ Nav.displayName = "Nav";
1314
+
1315
+ // src/layout/drawer.tsx
1316
+ import { useState as useState4 } from "react";
1317
+ import { Menu as Menu2, X as X2 } from "lucide-react";
1318
+ import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1319
+ function Drawer({
1320
+ title,
1321
+ subtitle,
1322
+ items,
1323
+ sections,
1324
+ activeItem,
1325
+ onItemClick,
1326
+ footer,
1327
+ position = "right"
1328
+ }) {
1329
+ const [mobileMenuOpen, setMobileMenuOpen] = useState4(false);
1330
+ const isLeft = position === "left";
1331
+ const handleItemClick = (itemId) => {
1332
+ onItemClick(itemId);
1333
+ setMobileMenuOpen(false);
1334
+ };
1335
+ const useSections = sections || (items ? [{ title: "", items }] : []);
1336
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
1337
+ /* @__PURE__ */ jsx14("div", { className: "lg:hidden fixed top-0 left-0 right-0 bg-white border-b border-gray-200 px-4 py-3 [z-index:var(--z-index-drawer-header)]", children: /* @__PURE__ */ jsxs12(
1338
+ "div",
1339
+ {
1340
+ className: `flex items-center ${isLeft ? "justify-between" : "justify-between flex-row-reverse"}`,
1341
+ children: [
1342
+ /* @__PURE__ */ jsx14(
1343
+ "button",
1344
+ {
1345
+ onClick: () => setMobileMenuOpen(!mobileMenuOpen),
1346
+ className: "p-2 rounded-lg hover:bg-gray-100 transition-colors relative [z-index:var(--z-index-drawer-button)]",
1347
+ "aria-label": "Toggle menu",
1348
+ children: mobileMenuOpen ? /* @__PURE__ */ jsx14(X2, { className: "w-6 h-6 text-gray-700" }) : /* @__PURE__ */ jsx14(Menu2, { className: "w-6 h-6 text-gray-700" })
1349
+ }
1350
+ ),
1351
+ /* @__PURE__ */ jsxs12("div", { children: [
1352
+ /* @__PURE__ */ jsx14("h1", { className: "text-lg font-bold text-gray-900", children: title }),
1353
+ subtitle && /* @__PURE__ */ jsx14("p", { className: "text-xs text-gray-500", children: subtitle })
1354
+ ] })
1355
+ ]
1356
+ }
1357
+ ) }),
1358
+ mobileMenuOpen && /* @__PURE__ */ jsx14(
1359
+ "div",
1360
+ {
1361
+ className: "fixed inset-0 bg-black/50 lg:hidden",
1362
+ style: { zIndex: 9998 },
1363
+ onClick: () => setMobileMenuOpen(false)
1364
+ }
1365
+ ),
1366
+ /* @__PURE__ */ jsxs12(
1367
+ "aside",
1368
+ {
1369
+ className: `
1370
+ fixed top-0 bottom-0 w-64 bg-white
1371
+ transition-transform duration-300 ease-in-out overflow-y-auto
1372
+ ${isLeft ? "left-0 border-r" : "right-0 border-l"} border-gray-200
1373
+ lg:translate-x-0 lg:top-0
1374
+ ${mobileMenuOpen ? "translate-x-0 top-0" : `${isLeft ? "-translate-x-full" : "translate-x-full"} top-0`}
1375
+ `,
1376
+ style: mobileMenuOpen && typeof window !== "undefined" && window.innerWidth < 1024 ? { zIndex: 9999 } : void 0,
1377
+ children: [
1378
+ /* @__PURE__ */ jsxs12("div", { className: "hidden lg:block p-6 border-b border-gray-200", children: [
1379
+ /* @__PURE__ */ jsx14("h1", { className: "text-xl font-bold text-gray-900", children: title }),
1380
+ subtitle && /* @__PURE__ */ jsx14("p", { className: "text-xs text-gray-500 mt-1", children: subtitle })
1381
+ ] }),
1382
+ /* @__PURE__ */ jsxs12("div", { className: "lg:hidden p-4 border-b border-gray-200 flex items-center justify-between", children: [
1383
+ /* @__PURE__ */ jsxs12("div", { children: [
1384
+ /* @__PURE__ */ jsx14("h1", { className: "text-lg font-bold text-gray-900", children: title }),
1385
+ subtitle && /* @__PURE__ */ jsx14("p", { className: "text-xs text-gray-500 mt-1", children: subtitle })
1386
+ ] }),
1387
+ /* @__PURE__ */ jsx14(
1388
+ "button",
1389
+ {
1390
+ onClick: () => setMobileMenuOpen(false),
1391
+ className: "p-2 rounded-lg hover:bg-gray-100 transition-colors",
1392
+ "aria-label": "Close menu",
1393
+ children: /* @__PURE__ */ jsx14(X2, { className: "w-5 h-5 text-gray-700" })
1394
+ }
1395
+ )
1396
+ ] }),
1397
+ /* @__PURE__ */ jsx14("nav", { className: "p-4", children: useSections.map((section, sectionIndex) => /* @__PURE__ */ jsxs12("div", { className: sectionIndex > 0 ? "mt-6" : "", children: [
1398
+ section.title && /* @__PURE__ */ jsx14("h3", { className: "px-4 mb-2 text-xs font-semibold text-gray-500 uppercase tracking-wider", children: section.title }),
1399
+ /* @__PURE__ */ jsx14("ul", { className: "space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsx14("li", { children: /* @__PURE__ */ jsxs12(
1400
+ "button",
1401
+ {
1402
+ onClick: () => handleItemClick(item.id),
1403
+ className: `
1404
+ w-full flex items-center gap-3 px-4 py-3 rounded-lg text-sm font-medium transition-colors
1405
+ ${activeItem === item.id ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-50"}
1406
+ `,
1407
+ children: [
1408
+ item.icon && /* @__PURE__ */ jsx14("span", { className: "shrink-0", children: item.icon }),
1409
+ /* @__PURE__ */ jsx14("span", { children: item.label })
1410
+ ]
1411
+ }
1412
+ ) }, item.id)) })
1413
+ ] }, sectionIndex)) }),
1414
+ footer && /* @__PURE__ */ jsx14("div", { className: "p-4 border-t border-gray-200 mt-auto", children: footer })
1415
+ ]
1416
+ }
1417
+ )
1418
+ ] });
1419
+ }
1420
+
1421
+ // src/layout/sidebar-nav.tsx
1422
+ import { useState as useState5 } from "react";
1423
+ import { Menu as Menu3, X as X3 } from "lucide-react";
1424
+ import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
919
1425
  function SidebarNav({
920
1426
  title,
921
1427
  subtitle,
922
1428
  items,
1429
+ sections,
923
1430
  activeItem,
924
1431
  onItemClick,
925
1432
  footer,
926
1433
  position = "right"
927
1434
  }) {
928
- const [mobileMenuOpen, setMobileMenuOpen] = useState3(false);
1435
+ const [mobileMenuOpen, setMobileMenuOpen] = useState5(false);
929
1436
  const isLeft = position === "left";
930
1437
  const handleItemClick = (itemId) => {
931
1438
  onItemClick(itemId);
932
1439
  setMobileMenuOpen(false);
933
1440
  };
934
- return /* @__PURE__ */ jsxs11(Fragment2, { children: [
935
- /* @__PURE__ */ jsx13("div", { className: "lg:hidden fixed top-0 left-0 right-0 z-50 bg-white border-b border-gray-200 px-4 py-3", children: /* @__PURE__ */ jsxs11(
1441
+ const useSections = sections || (items ? [{ title: "", items }] : []);
1442
+ return /* @__PURE__ */ jsxs13(Fragment4, { children: [
1443
+ /* @__PURE__ */ jsx15("div", { className: "lg:hidden fixed top-0 left-0 right-0 z-50 bg-white border-b border-gray-200 px-4 py-3", children: /* @__PURE__ */ jsxs13(
936
1444
  "div",
937
1445
  {
938
1446
  className: `flex items-center ${isLeft ? "justify-between" : "justify-between flex-row-reverse"}`,
939
1447
  children: [
940
- /* @__PURE__ */ jsx13(
1448
+ /* @__PURE__ */ jsx15(
941
1449
  "button",
942
1450
  {
943
1451
  onClick: () => setMobileMenuOpen(!mobileMenuOpen),
944
1452
  className: "p-2 rounded-lg hover:bg-gray-100 transition-colors",
945
1453
  "aria-label": "Toggle menu",
946
- children: mobileMenuOpen ? /* @__PURE__ */ jsx13(X, { className: "w-6 h-6 text-gray-700" }) : /* @__PURE__ */ jsx13(Menu, { className: "w-6 h-6 text-gray-700" })
1454
+ children: mobileMenuOpen ? /* @__PURE__ */ jsx15(X3, { className: "w-6 h-6 text-gray-700" }) : /* @__PURE__ */ jsx15(Menu3, { className: "w-6 h-6 text-gray-700" })
947
1455
  }
948
1456
  ),
949
- /* @__PURE__ */ jsxs11("div", { children: [
950
- /* @__PURE__ */ jsx13("h1", { className: "text-lg font-bold text-gray-900", children: title }),
951
- subtitle && /* @__PURE__ */ jsx13("p", { className: "text-xs text-gray-500", children: subtitle })
1457
+ /* @__PURE__ */ jsxs13("div", { children: [
1458
+ /* @__PURE__ */ jsx15("h1", { className: "text-lg font-bold text-gray-900", children: title }),
1459
+ subtitle && /* @__PURE__ */ jsx15("p", { className: "text-xs text-gray-500", children: subtitle })
952
1460
  ] })
953
1461
  ]
954
1462
  }
955
1463
  ) }),
956
- mobileMenuOpen && /* @__PURE__ */ jsx13(
1464
+ mobileMenuOpen && /* @__PURE__ */ jsx15(
957
1465
  "div",
958
1466
  {
959
1467
  className: "fixed inset-0 bg-black/50 lg:hidden",
@@ -961,7 +1469,7 @@ function SidebarNav({
961
1469
  onClick: () => setMobileMenuOpen(false)
962
1470
  }
963
1471
  ),
964
- /* @__PURE__ */ jsxs11(
1472
+ /* @__PURE__ */ jsxs13(
965
1473
  "aside",
966
1474
  {
967
1475
  className: `
@@ -972,26 +1480,29 @@ function SidebarNav({
972
1480
  ${mobileMenuOpen ? "translate-x-0" : `${isLeft ? "-translate-x-full" : "translate-x-full"} lg:translate-x-0`}
973
1481
  `,
974
1482
  children: [
975
- /* @__PURE__ */ jsxs11("div", { className: "hidden lg:block p-6 border-b border-gray-200", children: [
976
- /* @__PURE__ */ jsx13("h1", { className: "text-xl font-bold text-gray-900", children: title }),
977
- subtitle && /* @__PURE__ */ jsx13("p", { className: "text-xs text-gray-500 mt-1", children: subtitle })
1483
+ /* @__PURE__ */ jsxs13("div", { className: "hidden lg:block p-6 border-b border-gray-200", children: [
1484
+ /* @__PURE__ */ jsx15("h1", { className: "text-xl font-bold text-gray-900", children: title }),
1485
+ subtitle && /* @__PURE__ */ jsx15("p", { className: "text-xs text-gray-500 mt-1", children: subtitle })
978
1486
  ] }),
979
- /* @__PURE__ */ jsx13("div", { className: "lg:hidden h-[57px]", "aria-hidden": "true" }),
980
- /* @__PURE__ */ jsx13("nav", { className: "p-4", children: /* @__PURE__ */ jsx13("ul", { className: "space-y-1", children: items.map((item) => /* @__PURE__ */ jsx13("li", { children: /* @__PURE__ */ jsxs11(
981
- "button",
982
- {
983
- onClick: () => handleItemClick(item.id),
984
- className: `
985
- w-full flex items-center gap-3 px-4 py-3 rounded-lg text-sm font-medium transition-colors
986
- ${activeItem === item.id ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-50"}
987
- `,
988
- children: [
989
- item.icon && /* @__PURE__ */ jsx13("span", { className: "shrink-0", children: item.icon }),
990
- /* @__PURE__ */ jsx13("span", { children: item.label })
991
- ]
992
- }
993
- ) }, item.id)) }) }),
994
- footer && /* @__PURE__ */ jsx13("div", { className: "p-4 border-t border-gray-200 mt-auto", children: footer })
1487
+ /* @__PURE__ */ jsx15("div", { className: "lg:hidden h-[57px]", "aria-hidden": "true" }),
1488
+ /* @__PURE__ */ jsx15("nav", { className: "p-4", children: useSections.map((section, sectionIndex) => /* @__PURE__ */ jsxs13("div", { className: sectionIndex > 0 ? "mt-6" : "", children: [
1489
+ section.title && /* @__PURE__ */ jsx15("h3", { className: "px-4 mb-2 text-xs font-semibold text-gray-500 uppercase tracking-wider", children: section.title }),
1490
+ /* @__PURE__ */ jsx15("ul", { className: "space-y-1", children: section.items.map((item) => /* @__PURE__ */ jsx15("li", { children: /* @__PURE__ */ jsxs13(
1491
+ "button",
1492
+ {
1493
+ onClick: () => handleItemClick(item.id),
1494
+ className: `
1495
+ w-full flex items-center gap-3 px-4 py-3 rounded-lg text-sm font-medium transition-colors
1496
+ ${activeItem === item.id ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-50"}
1497
+ `,
1498
+ children: [
1499
+ item.icon && /* @__PURE__ */ jsx15("span", { className: "shrink-0", children: item.icon }),
1500
+ /* @__PURE__ */ jsx15("span", { children: item.label })
1501
+ ]
1502
+ }
1503
+ ) }, item.id)) })
1504
+ ] }, sectionIndex)) }),
1505
+ footer && /* @__PURE__ */ jsx15("div", { className: "p-4 border-t border-gray-200 mt-auto", children: footer })
995
1506
  ]
996
1507
  }
997
1508
  )
@@ -999,11 +1510,11 @@ function SidebarNav({
999
1510
  }
1000
1511
 
1001
1512
  // src/shared/empty-state.tsx
1002
- import React10 from "react";
1003
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1004
- var EmptyState = React10.forwardRef(
1513
+ import React12 from "react";
1514
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1515
+ var EmptyState = React12.forwardRef(
1005
1516
  ({ className, icon, title, description, action, ...props }, ref) => {
1006
- return /* @__PURE__ */ jsxs12(
1517
+ return /* @__PURE__ */ jsxs14(
1007
1518
  "div",
1008
1519
  {
1009
1520
  ref,
@@ -1013,16 +1524,477 @@ var EmptyState = React10.forwardRef(
1013
1524
  ),
1014
1525
  ...props,
1015
1526
  children: [
1016
- icon && /* @__PURE__ */ jsx14("div", { className: "mb-4 text-gray-400", children: icon }),
1017
- /* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: title }),
1018
- description && /* @__PURE__ */ jsx14("p", { className: "text-sm text-gray-500 mb-6 max-w-sm", children: description }),
1019
- action && /* @__PURE__ */ jsx14("div", { children: action })
1527
+ icon && /* @__PURE__ */ jsx16("div", { className: "mb-4 text-gray-400", children: icon }),
1528
+ /* @__PURE__ */ jsx16("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: title }),
1529
+ description && /* @__PURE__ */ jsx16("p", { className: "text-sm text-gray-500 mb-6 max-w-sm", children: description }),
1530
+ action && /* @__PURE__ */ jsx16("div", { children: action })
1020
1531
  ]
1021
1532
  }
1022
1533
  );
1023
1534
  }
1024
1535
  );
1025
1536
  EmptyState.displayName = "EmptyState";
1537
+
1538
+ // src/shared/contexts/ThemeContext.tsx
1539
+ import {
1540
+ createContext,
1541
+ useContext,
1542
+ useState as useState6,
1543
+ useEffect as useEffect3
1544
+ } from "react";
1545
+
1546
+ // src/styles/themes/default.json
1547
+ var default_default = {
1548
+ name: "Default Theme",
1549
+ version: "1.0.0",
1550
+ colors: {
1551
+ primary: {
1552
+ "50": "#eff6ff",
1553
+ "100": "#dbeafe",
1554
+ "200": "#bfdbfe",
1555
+ "300": "#93c5fd",
1556
+ "400": "#60a5fa",
1557
+ "500": "#3b82f6",
1558
+ "600": "#2563eb",
1559
+ "700": "#1d4ed8",
1560
+ "800": "#1e40af",
1561
+ "900": "#1e3a8a"
1562
+ },
1563
+ secondary: {
1564
+ "50": "#f8fafc",
1565
+ "100": "#f1f5f9",
1566
+ "200": "#e2e8f0",
1567
+ "300": "#cbd5e1",
1568
+ "400": "#94a3b8",
1569
+ "500": "#64748b",
1570
+ "600": "#475569",
1571
+ "700": "#334155",
1572
+ "800": "#1e293b",
1573
+ "900": "#0f172a"
1574
+ },
1575
+ success: "#10b981",
1576
+ error: "#ef4444",
1577
+ warning: "#f59e0b",
1578
+ info: "#3b82f6",
1579
+ gray: {
1580
+ "50": "#f9fafb",
1581
+ "100": "#f3f4f6",
1582
+ "200": "#e5e7eb",
1583
+ "300": "#d1d5db",
1584
+ "400": "#9ca3af",
1585
+ "500": "#6b7280",
1586
+ "600": "#4b5563",
1587
+ "700": "#374151",
1588
+ "800": "#1f2937",
1589
+ "900": "#111827"
1590
+ },
1591
+ background: "#ffffff",
1592
+ foreground: "#111827",
1593
+ muted: "#f3f4f6",
1594
+ mutedForeground: "#6b7280"
1595
+ },
1596
+ spacing: {
1597
+ xs: "0.25rem",
1598
+ sm: "0.5rem",
1599
+ md: "1rem",
1600
+ lg: "1.5rem",
1601
+ xl: "2rem",
1602
+ "2xl": "3rem"
1603
+ },
1604
+ borderRadius: {
1605
+ none: "0",
1606
+ sm: "0.25rem",
1607
+ md: "0.5rem",
1608
+ lg: "0.75rem",
1609
+ xl: "1rem",
1610
+ full: "9999px"
1611
+ },
1612
+ typography: {
1613
+ fontFamily: {
1614
+ sans: [
1615
+ "Inter",
1616
+ "system-ui",
1617
+ "-apple-system",
1618
+ "BlinkMacSystemFont",
1619
+ "Segoe UI",
1620
+ "Roboto",
1621
+ "Helvetica Neue",
1622
+ "Arial",
1623
+ "sans-serif"
1624
+ ],
1625
+ mono: [
1626
+ "Monaco",
1627
+ "Consolas",
1628
+ "Liberation Mono",
1629
+ "Courier New",
1630
+ "monospace"
1631
+ ]
1632
+ },
1633
+ fontSize: {
1634
+ xs: "0.75rem",
1635
+ sm: "0.875rem",
1636
+ base: "1rem",
1637
+ lg: "1.125rem",
1638
+ xl: "1.25rem",
1639
+ "2xl": "1.5rem",
1640
+ "3xl": "1.875rem"
1641
+ },
1642
+ fontWeight: {
1643
+ normal: "400",
1644
+ medium: "500",
1645
+ semibold: "600",
1646
+ bold: "700"
1647
+ }
1648
+ },
1649
+ zIndex: {
1650
+ dropdown: 1e3,
1651
+ popover: 1100,
1652
+ tooltip: 1500,
1653
+ overlay: 1200,
1654
+ nav: 50,
1655
+ navMobileOverlay: 60,
1656
+ navMobileMenu: 70,
1657
+ drawerHeader: 100,
1658
+ drawerButton: 101,
1659
+ drawerOverlay: 90,
1660
+ drawerPanel: 95,
1661
+ modalBackdrop: 1300,
1662
+ modal: 1400,
1663
+ snackbar: 1600,
1664
+ toast: 1700
1665
+ },
1666
+ components: {
1667
+ button: {
1668
+ padding: {
1669
+ xs: { x: "0.5rem", y: "0.375rem" },
1670
+ sm: { x: "0.75rem", y: "0.5rem" },
1671
+ md: { x: "1rem", y: "0.625rem" },
1672
+ lg: { x: "1.25rem", y: "0.75rem" },
1673
+ xl: { x: "1.5rem", y: "0.875rem" }
1674
+ },
1675
+ fontSize: {
1676
+ xs: "0.75rem",
1677
+ sm: "0.875rem",
1678
+ md: "1rem",
1679
+ lg: "1.125rem",
1680
+ xl: "1.25rem"
1681
+ },
1682
+ borderRadius: "0.5rem",
1683
+ fontWeight: "500"
1684
+ },
1685
+ card: {
1686
+ padding: {
1687
+ none: "0",
1688
+ sm: "0.75rem",
1689
+ md: "1rem",
1690
+ lg: "1.5rem"
1691
+ },
1692
+ borderRadius: "0.75rem",
1693
+ borderWidth: "1px",
1694
+ shadow: {
1695
+ flat: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
1696
+ elevated: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
1697
+ }
1698
+ },
1699
+ input: {
1700
+ padding: {
1701
+ xs: "0.375rem 0.5rem",
1702
+ sm: "0.5rem 0.75rem",
1703
+ md: "0.625rem 1rem",
1704
+ lg: "0.75rem 1.25rem",
1705
+ xl: "0.875rem 1.5rem"
1706
+ },
1707
+ fontSize: {
1708
+ xs: "0.75rem",
1709
+ sm: "0.875rem",
1710
+ md: "1rem",
1711
+ lg: "1.125rem",
1712
+ xl: "1.25rem"
1713
+ },
1714
+ borderRadius: "0.5rem",
1715
+ borderWidth: "1px"
1716
+ },
1717
+ checkbox: {
1718
+ size: {
1719
+ xs: "0.75rem",
1720
+ sm: "0.875rem",
1721
+ md: "1rem",
1722
+ lg: "1.25rem",
1723
+ xl: "1.5rem"
1724
+ },
1725
+ labelSpacing: {
1726
+ xs: "0.25rem",
1727
+ sm: "0.375rem",
1728
+ md: "0.5rem",
1729
+ lg: "0.625rem",
1730
+ xl: "0.75rem"
1731
+ },
1732
+ labelFontSize: {
1733
+ xs: "0.625rem",
1734
+ sm: "0.75rem",
1735
+ md: "0.875rem",
1736
+ lg: "1rem",
1737
+ xl: "1.125rem"
1738
+ },
1739
+ borderRadius: "0.25rem"
1740
+ },
1741
+ radio: {
1742
+ size: {
1743
+ xs: "0.75rem",
1744
+ sm: "0.875rem",
1745
+ md: "1rem",
1746
+ lg: "1.25rem",
1747
+ xl: "1.5rem"
1748
+ },
1749
+ labelSpacing: {
1750
+ xs: "0.25rem",
1751
+ sm: "0.375rem",
1752
+ md: "0.5rem",
1753
+ lg: "0.625rem",
1754
+ xl: "0.75rem"
1755
+ },
1756
+ labelFontSize: {
1757
+ xs: "0.625rem",
1758
+ sm: "0.75rem",
1759
+ md: "0.875rem",
1760
+ lg: "1rem",
1761
+ xl: "1.125rem"
1762
+ }
1763
+ },
1764
+ dropdown: {
1765
+ padding: {
1766
+ xs: { x: "0.5rem", y: "0.25rem" },
1767
+ sm: { x: "0.75rem", y: "0.375rem" },
1768
+ md: { x: "1rem", y: "0.5rem" },
1769
+ lg: { x: "1.25rem", y: "0.625rem" },
1770
+ xl: { x: "1.5rem", y: "0.75rem" }
1771
+ },
1772
+ fontSize: {
1773
+ xs: "0.75rem",
1774
+ sm: "0.875rem",
1775
+ md: "1rem",
1776
+ lg: "1.125rem",
1777
+ xl: "1.25rem"
1778
+ },
1779
+ iconSize: {
1780
+ xs: "0.875rem",
1781
+ sm: "1rem",
1782
+ md: "1.25rem",
1783
+ lg: "1.5rem",
1784
+ xl: "1.75rem"
1785
+ },
1786
+ optionPadding: {
1787
+ xs: { x: "0.5rem", y: "0.25rem" },
1788
+ sm: { x: "0.75rem", y: "0.375rem" },
1789
+ md: { x: "1rem", y: "0.5rem" },
1790
+ lg: { x: "1.25rem", y: "0.625rem" },
1791
+ xl: { x: "1.5rem", y: "0.75rem" }
1792
+ },
1793
+ optionFontSize: {
1794
+ xs: "0.625rem",
1795
+ sm: "0.75rem",
1796
+ md: "0.875rem",
1797
+ lg: "1rem",
1798
+ xl: "1.125rem"
1799
+ },
1800
+ borderRadius: "0.5rem",
1801
+ borderWidth: "1px"
1802
+ },
1803
+ nav: {
1804
+ height: "4rem",
1805
+ itemPadding: {
1806
+ xs: { x: "0.375rem", y: "0.25rem" },
1807
+ sm: { x: "0.5rem", y: "0.375rem" },
1808
+ md: { x: "0.75rem", y: "0.5rem" },
1809
+ lg: { x: "1rem", y: "0.625rem" },
1810
+ xl: { x: "1.25rem", y: "0.75rem" }
1811
+ },
1812
+ fontSize: {
1813
+ xs: "0.625rem",
1814
+ sm: "0.75rem",
1815
+ md: "0.875rem",
1816
+ lg: "1rem",
1817
+ xl: "1.125rem"
1818
+ },
1819
+ borderRadius: "0.375rem",
1820
+ gap: "0.25rem"
1821
+ }
1822
+ }
1823
+ };
1824
+
1825
+ // src/shared/contexts/ThemeContext.tsx
1826
+ import { jsx as jsx17 } from "react/jsx-runtime";
1827
+ var ThemeContext = createContext(void 0);
1828
+ function ThemeProvider({ children }) {
1829
+ const [theme, setThemeState] = useState6(default_default);
1830
+ const applyTheme = (newTheme) => {
1831
+ const root = document.documentElement;
1832
+ const colors = newTheme.colors;
1833
+ Object.entries(colors.primary).forEach(([shade, value]) => {
1834
+ if (value) {
1835
+ root.style.setProperty(`--color-primary-${shade}`, value);
1836
+ }
1837
+ });
1838
+ Object.entries(colors.secondary).forEach(([shade, value]) => {
1839
+ if (value) {
1840
+ root.style.setProperty(`--color-secondary-${shade}`, value);
1841
+ }
1842
+ });
1843
+ root.style.setProperty("--color-success", colors.success);
1844
+ root.style.setProperty("--color-error", colors.error);
1845
+ root.style.setProperty("--color-warning", colors.warning);
1846
+ root.style.setProperty("--color-info", colors.info);
1847
+ Object.entries(colors.gray).forEach(([shade, value]) => {
1848
+ if (value) {
1849
+ root.style.setProperty(`--color-gray-${shade}`, value);
1850
+ }
1851
+ });
1852
+ root.style.setProperty("--color-background", colors.background);
1853
+ root.style.setProperty("--color-foreground", colors.foreground);
1854
+ root.style.setProperty("--color-muted", colors.muted);
1855
+ root.style.setProperty("--color-muted-foreground", colors.mutedForeground);
1856
+ Object.entries(newTheme.spacing).forEach(([key, value]) => {
1857
+ root.style.setProperty(`--spacing-${key}`, value);
1858
+ });
1859
+ Object.entries(newTheme.borderRadius).forEach(([key, value]) => {
1860
+ root.style.setProperty(`--radius-${key}`, value);
1861
+ });
1862
+ const { typography } = newTheme;
1863
+ root.style.setProperty(
1864
+ "--font-sans",
1865
+ typography.fontFamily.sans.join(", ")
1866
+ );
1867
+ root.style.setProperty(
1868
+ "--font-mono",
1869
+ typography.fontFamily.mono.join(", ")
1870
+ );
1871
+ Object.entries(typography.fontSize).forEach(([key, value]) => {
1872
+ root.style.setProperty(`--text-${key}`, value);
1873
+ });
1874
+ Object.entries(typography.fontWeight).forEach(([key, value]) => {
1875
+ root.style.setProperty(`--font-${key}`, value);
1876
+ });
1877
+ const button = newTheme.components.button;
1878
+ Object.entries(button.padding).forEach(([size, padding]) => {
1879
+ root.style.setProperty(`--button-padding-${size}-x`, padding.x);
1880
+ root.style.setProperty(`--button-padding-${size}-y`, padding.y);
1881
+ });
1882
+ Object.entries(button.fontSize).forEach(([size, fontSize]) => {
1883
+ root.style.setProperty(`--button-font-size-${size}`, fontSize);
1884
+ });
1885
+ root.style.setProperty("--button-radius", button.borderRadius);
1886
+ root.style.setProperty("--button-font-weight", button.fontWeight);
1887
+ const card = newTheme.components.card;
1888
+ Object.entries(card.padding).forEach(([size, padding]) => {
1889
+ root.style.setProperty(`--card-padding-${size}`, padding);
1890
+ });
1891
+ root.style.setProperty("--card-radius", card.borderRadius);
1892
+ root.style.setProperty("--card-border-width", card.borderWidth);
1893
+ root.style.setProperty("--card-shadow-flat", card.shadow.flat);
1894
+ root.style.setProperty("--card-shadow-elevated", card.shadow.elevated);
1895
+ const input = newTheme.components.input;
1896
+ Object.entries(input.padding).forEach(([size, padding]) => {
1897
+ root.style.setProperty(`--input-padding-${size}`, padding);
1898
+ });
1899
+ Object.entries(input.fontSize).forEach(([size, fontSize]) => {
1900
+ root.style.setProperty(`--input-font-size-${size}`, fontSize);
1901
+ });
1902
+ root.style.setProperty("--input-radius", input.borderRadius);
1903
+ root.style.setProperty("--input-border-width", input.borderWidth);
1904
+ const checkbox = newTheme.components.checkbox;
1905
+ Object.entries(checkbox.size).forEach(([size, dimension]) => {
1906
+ root.style.setProperty(`--checkbox-size-${size}`, dimension);
1907
+ });
1908
+ Object.entries(checkbox.labelSpacing).forEach(([size, spacing]) => {
1909
+ root.style.setProperty(`--checkbox-label-spacing-${size}`, spacing);
1910
+ });
1911
+ Object.entries(checkbox.labelFontSize).forEach(([size, fontSize]) => {
1912
+ root.style.setProperty(`--checkbox-label-font-size-${size}`, fontSize);
1913
+ });
1914
+ root.style.setProperty("--checkbox-radius", checkbox.borderRadius);
1915
+ const radio = newTheme.components.radio;
1916
+ Object.entries(radio.size).forEach(([size, dimension]) => {
1917
+ root.style.setProperty(`--radio-size-${size}`, dimension);
1918
+ });
1919
+ Object.entries(radio.labelSpacing).forEach(([size, spacing]) => {
1920
+ root.style.setProperty(`--radio-label-spacing-${size}`, spacing);
1921
+ });
1922
+ Object.entries(radio.labelFontSize).forEach(([size, fontSize]) => {
1923
+ root.style.setProperty(`--radio-label-font-size-${size}`, fontSize);
1924
+ });
1925
+ const dropdown = newTheme.components.dropdown;
1926
+ Object.entries(dropdown.padding).forEach(([size, padding]) => {
1927
+ root.style.setProperty(`--dropdown-padding-${size}-x`, padding.x);
1928
+ root.style.setProperty(`--dropdown-padding-${size}-y`, padding.y);
1929
+ });
1930
+ Object.entries(dropdown.fontSize).forEach(([size, fontSize]) => {
1931
+ root.style.setProperty(`--dropdown-font-size-${size}`, fontSize);
1932
+ });
1933
+ Object.entries(dropdown.iconSize).forEach(([size, iconSize]) => {
1934
+ root.style.setProperty(`--dropdown-icon-size-${size}`, iconSize);
1935
+ });
1936
+ Object.entries(dropdown.optionPadding).forEach(([size, padding]) => {
1937
+ root.style.setProperty(`--dropdown-option-padding-${size}-x`, padding.x);
1938
+ root.style.setProperty(`--dropdown-option-padding-${size}-y`, padding.y);
1939
+ });
1940
+ Object.entries(dropdown.optionFontSize).forEach(([size, fontSize]) => {
1941
+ root.style.setProperty(`--dropdown-option-font-size-${size}`, fontSize);
1942
+ });
1943
+ root.style.setProperty("--dropdown-radius", dropdown.borderRadius);
1944
+ root.style.setProperty("--dropdown-border-width", dropdown.borderWidth);
1945
+ const nav = newTheme.components.nav;
1946
+ root.style.setProperty("--nav-height", nav.height);
1947
+ Object.entries(nav.itemPadding).forEach(([size, padding]) => {
1948
+ root.style.setProperty(`--nav-item-padding-${size}-x`, padding.x);
1949
+ root.style.setProperty(`--nav-item-padding-${size}-y`, padding.y);
1950
+ });
1951
+ Object.entries(nav.fontSize).forEach(([size, fontSize]) => {
1952
+ root.style.setProperty(`--nav-font-size-${size}`, fontSize);
1953
+ });
1954
+ root.style.setProperty("--nav-border-radius", nav.borderRadius);
1955
+ root.style.setProperty("--nav-gap", nav.gap);
1956
+ Object.entries(newTheme.zIndex).forEach(([key, value]) => {
1957
+ root.style.setProperty(`--z-index-${key}`, value.toString());
1958
+ });
1959
+ setThemeState(newTheme);
1960
+ };
1961
+ const setTheme = (newTheme) => {
1962
+ applyTheme(newTheme);
1963
+ if (typeof window !== "undefined") {
1964
+ localStorage.setItem("theme", JSON.stringify(newTheme));
1965
+ }
1966
+ };
1967
+ const resetTheme = () => {
1968
+ applyTheme(default_default);
1969
+ if (typeof window !== "undefined") {
1970
+ localStorage.removeItem("theme");
1971
+ }
1972
+ };
1973
+ useEffect3(() => {
1974
+ if (typeof window !== "undefined") {
1975
+ const savedTheme = localStorage.getItem("theme");
1976
+ if (savedTheme) {
1977
+ try {
1978
+ const parsedTheme = JSON.parse(savedTheme);
1979
+ applyTheme(parsedTheme);
1980
+ } catch (error) {
1981
+ console.error("Failed to parse saved theme:", error);
1982
+ applyTheme(default_default);
1983
+ }
1984
+ } else {
1985
+ applyTheme(default_default);
1986
+ }
1987
+ }
1988
+ }, []);
1989
+ return /* @__PURE__ */ jsx17(ThemeContext.Provider, { value: { theme, setTheme, applyTheme, resetTheme }, children });
1990
+ }
1991
+ function useTheme() {
1992
+ const context = useContext(ThemeContext);
1993
+ if (context === void 0) {
1994
+ throw new Error("useTheme must be used within a ThemeProvider");
1995
+ }
1996
+ return context;
1997
+ }
1026
1998
  export {
1027
1999
  Alert,
1028
2000
  Badge,
@@ -1037,13 +2009,17 @@ export {
1037
2009
  CheckboxGroup,
1038
2010
  CodeSnippet,
1039
2011
  Container,
2012
+ Drawer,
1040
2013
  Dropdown,
1041
2014
  EmptyState,
1042
2015
  Input,
2016
+ Nav,
1043
2017
  RadioGroup,
1044
2018
  SectionLayout,
1045
2019
  SidebarNav,
1046
2020
  Spinner,
1047
- cn
2021
+ ThemeProvider,
2022
+ cn,
2023
+ useTheme
1048
2024
  };
1049
2025
  //# sourceMappingURL=index.mjs.map