@tree-ia/design-system 1.5.1 → 1.5.3

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
@@ -2,8 +2,8 @@ import React, { createContext, useCallback, useContext, useEffect, useMemo, useR
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { createPortal } from "react-dom";
4
4
  import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, File, GripVertical, Image, Inbox, Info, LogOut, Moon, Search, Sun, Upload, User, X, XCircle } from "lucide-react";
5
- import { Bar, Line } from "react-chartjs-2";
6
- import { BarElement, CategoryScale, Chart, Filler, Legend, LineElement, LinearScale, PointElement, Title as Title$1, Tooltip as Tooltip$1 } from "chart.js";
5
+ import { Bar, Doughnut, Line } from "react-chartjs-2";
6
+ import { ArcElement, BarElement, CategoryScale, Chart, Filler, Legend, LineElement, LinearScale, PointElement, Title as Title$1, Tooltip as Tooltip$1 } from "chart.js";
7
7
  import { createColumnHelper, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
8
8
 
9
9
  //#region src/components/Loading/index.tsx
@@ -35,7 +35,7 @@ function Loading({ size = "md", className = "", text, textColor, color, variant
35
35
 
36
36
  //#endregion
37
37
  //#region src/components/Button/index.tsx
38
- const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
38
+ const cn$30 = (...classes) => classes.filter(Boolean).join(" ");
39
39
  function Button({ children, variant = "primary", size = "md", isLoading = false, icon, iconPosition = "left", className, disabled, ...props }) {
40
40
  const baseStyles = "font-medium rounded-lg transition-all duration-200 ease-out cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center justify-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--dashboard-primary,#2563EB)] active:scale-[0.97]";
41
41
  const variantStyles = {
@@ -56,7 +56,7 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
56
56
  };
57
57
  const isIconOnly = !!icon && (children === void 0 || children === null || typeof children === "string" && children.trim() === "");
58
58
  return /* @__PURE__ */ jsx("button", {
59
- className: cn$29(baseStyles, variantStyles[variant], isIconOnly ? iconOnlySizeStyles[size] : sizeStyles[size], className),
59
+ className: cn$30(baseStyles, variantStyles[variant], isIconOnly ? iconOnlySizeStyles[size] : sizeStyles[size], className),
60
60
  disabled: disabled || isLoading,
61
61
  ...props,
62
62
  children: isLoading ? /* @__PURE__ */ jsxs("span", {
@@ -81,7 +81,7 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
81
81
 
82
82
  //#endregion
83
83
  //#region src/components/Input/index.tsx
84
- const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
84
+ const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
85
85
  const Input = React.forwardRef(({ className, type = "text", label, error, children, id, ...props }, ref) => {
86
86
  const inputId = id || (label ? `input-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
87
87
  return /* @__PURE__ */ jsxs("div", {
@@ -97,7 +97,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, childr
97
97
  children: [/* @__PURE__ */ jsx("input", {
98
98
  type,
99
99
  id: inputId,
100
- className: cn$28("flex h-10 w-full rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] px-3 py-2 text-sm text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm transition-colors duration-200 focus:border-[var(--dashboard-primary,#37a501)] placeholder:text-[var(--dashboard-text-secondary,#6b7280)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", error ? "border-[var(--dashboard-status-danger,#EF4444)] focus:border-[var(--dashboard-status-danger,#EF4444)]" : void 0, children ? "pr-10" : void 0, className),
100
+ className: cn$29("flex h-10 w-full rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] px-3 py-2 text-sm text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm transition-colors duration-200 focus:border-[var(--dashboard-primary,#37a501)] placeholder:text-[var(--dashboard-text-secondary,#6b7280)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", error ? "border-[var(--dashboard-status-danger,#EF4444)] focus:border-[var(--dashboard-status-danger,#EF4444)]" : void 0, children ? "pr-10" : void 0, className),
101
101
  ref,
102
102
  ...props
103
103
  }), children && /* @__PURE__ */ jsx("div", {
@@ -761,16 +761,16 @@ function FormField({ label, name, type = "text", value, onChange, error, require
761
761
 
762
762
  //#endregion
763
763
  //#region src/components/Tabs/index.tsx
764
- const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
764
+ const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
765
765
  function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
766
766
  if (variant === "pill") return /* @__PURE__ */ jsx("div", {
767
- className: cn$27("flex flex-wrap gap-2", className),
767
+ className: cn$28("flex flex-wrap gap-2", className),
768
768
  role: "tablist",
769
769
  children: tabs.map((tab) => {
770
770
  const isActive = activeTab === tab.id;
771
771
  return /* @__PURE__ */ jsxs("button", {
772
772
  onClick: () => onChange(tab.id),
773
- className: cn$27("flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-colors cursor-pointer", isActive ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
773
+ className: cn$28("flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-colors cursor-pointer", isActive ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
774
774
  role: "tab",
775
775
  "aria-selected": isActive,
776
776
  children: [
@@ -780,7 +780,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
780
780
  }),
781
781
  tab.label,
782
782
  tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
783
- className: cn$27("ml-1 text-xs rounded-full px-1.5 py-0.5", isActive ? "bg-white/20 text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)]"),
783
+ className: cn$28("ml-1 text-xs rounded-full px-1.5 py-0.5", isActive ? "bg-white/20 text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)]"),
784
784
  children: tab.count
785
785
  })
786
786
  ]
@@ -788,7 +788,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
788
788
  })
789
789
  });
790
790
  return /* @__PURE__ */ jsx("div", {
791
- className: cn$27("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
791
+ className: cn$28("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
792
792
  children: /* @__PURE__ */ jsx("nav", {
793
793
  className: "flex gap-6",
794
794
  "aria-label": "Tabs",
@@ -796,7 +796,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
796
796
  const isActive = activeTab === tab.id;
797
797
  return /* @__PURE__ */ jsxs("button", {
798
798
  onClick: () => onChange(tab.id),
799
- className: cn$27("relative pb-3 px-1 text-sm font-medium transition-colors border-b-2 flex items-center gap-2 cursor-pointer", isActive ? "text-[var(--dashboard-primary,#37a501)] border-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:text-[var(--dashboard-text-primary,#2d2d2d)] border-transparent"),
799
+ className: cn$28("relative pb-3 px-1 text-sm font-medium transition-colors border-b-2 flex items-center gap-2 cursor-pointer", isActive ? "text-[var(--dashboard-primary,#37a501)] border-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:text-[var(--dashboard-text-primary,#2d2d2d)] border-transparent"),
800
800
  role: "tab",
801
801
  "aria-selected": isActive,
802
802
  children: [
@@ -806,7 +806,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
806
806
  }),
807
807
  tab.label,
808
808
  tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
809
- className: cn$27("ml-1 text-xs rounded-full px-1.5 py-0.5", isActive ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)]"),
809
+ className: cn$28("ml-1 text-xs rounded-full px-1.5 py-0.5", isActive ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)]"),
810
810
  children: tab.count
811
811
  })
812
812
  ]
@@ -818,7 +818,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
818
818
 
819
819
  //#endregion
820
820
  //#region src/components/DateRangePicker/index.tsx
821
- const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
821
+ const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
822
822
  const locales = {
823
823
  pt: {
824
824
  months: [
@@ -925,7 +925,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
925
925
  };
926
926
  const days = getDaysInMonth(currentMonth);
927
927
  return /* @__PURE__ */ jsxs("div", {
928
- className: cn$26("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
928
+ className: cn$27("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
929
929
  children: [/* @__PURE__ */ jsxs("div", {
930
930
  className: "flex items-center justify-between mb-4",
931
931
  children: [
@@ -963,9 +963,9 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
963
963
  const isSelected = isStart || isEnd;
964
964
  return /* @__PURE__ */ jsxs("div", {
965
965
  className: "relative h-8 w-8",
966
- children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$26("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
966
+ children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$27("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
967
967
  onClick: () => handleDayClick(day),
968
- className: cn$26("relative h-8 w-8 flex items-center justify-center text-xs font-medium transition-colors z-10 rounded-full cursor-pointer", isSelected ? "bg-[var(--dashboard-primary,#37a501)] text-white hover:opacity-90" : "text-[var(--dashboard-text-primary,#2d2d2d)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
968
+ className: cn$27("relative h-8 w-8 flex items-center justify-center text-xs font-medium transition-colors z-10 rounded-full cursor-pointer", isSelected ? "bg-[var(--dashboard-primary,#37a501)] text-white hover:opacity-90" : "text-[var(--dashboard-text-primary,#2d2d2d)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
969
969
  children: day
970
970
  })]
971
971
  }, day);
@@ -976,7 +976,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
976
976
 
977
977
  //#endregion
978
978
  //#region src/components/Title/index.tsx
979
- const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
979
+ const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
980
980
  const defaultSizeByLevel = {
981
981
  1: "text-2xl sm:text-3xl md:text-4xl lg:text-5xl",
982
982
  2: "text-xl sm:text-2xl md:text-3xl lg:text-4xl",
@@ -1011,7 +1011,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
1011
1011
  const sizeClass = size ? customSizes[size] : defaultSizeByLevel[level];
1012
1012
  const colorClass = color || "text-[var(--dashboard-text-primary,#2d2d2d)]";
1013
1013
  return /* @__PURE__ */ jsx(Tag, {
1014
- className: cn$25(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
1014
+ className: cn$26(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
1015
1015
  ...props,
1016
1016
  children
1017
1017
  });
@@ -1019,7 +1019,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
1019
1019
 
1020
1020
  //#endregion
1021
1021
  //#region src/components/ToggleSwitch/index.tsx
1022
- const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
1022
+ const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
1023
1023
  const sizeConfig$1 = {
1024
1024
  sm: {
1025
1025
  track: "h-5 w-9",
@@ -1043,7 +1043,7 @@ const sizeConfig$1 = {
1043
1043
  function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label, className }) {
1044
1044
  const config = sizeConfig$1[size];
1045
1045
  return /* @__PURE__ */ jsxs("div", {
1046
- className: cn$24("inline-flex items-center gap-2", className),
1046
+ className: cn$25("inline-flex items-center gap-2", className),
1047
1047
  children: [/* @__PURE__ */ jsx("button", {
1048
1048
  type: "button",
1049
1049
  role: "switch",
@@ -1051,10 +1051,10 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
1051
1051
  "aria-label": label,
1052
1052
  disabled,
1053
1053
  onClick: () => onChange(!enabled),
1054
- className: cn$24("relative inline-flex items-center rounded-full transition-colors outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--dashboard-primary,#37a501)]", config.track, enabled ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/30", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
1055
- children: /* @__PURE__ */ jsx("span", { className: cn$24("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
1054
+ className: cn$25("relative inline-flex items-center rounded-full transition-colors outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--dashboard-primary,#37a501)]", config.track, enabled ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/30", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
1055
+ children: /* @__PURE__ */ jsx("span", { className: cn$25("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
1056
1056
  }), label && /* @__PURE__ */ jsx("span", {
1057
- className: cn$24("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
1057
+ className: cn$25("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
1058
1058
  children: label
1059
1059
  })]
1060
1060
  });
@@ -1062,7 +1062,7 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
1062
1062
 
1063
1063
  //#endregion
1064
1064
  //#region src/components/BadgeStatus/index.tsx
1065
- const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
1065
+ const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
1066
1066
  const variantStyles = {
1067
1067
  success: {
1068
1068
  color: "text-[var(--dashboard-status-success,#10B981)]",
@@ -1093,7 +1093,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
1093
1093
  const styles = variantStyles[variant];
1094
1094
  const useCustomColors = color || bgColor;
1095
1095
  return /* @__PURE__ */ jsx("span", {
1096
- className: cn$23("inline-flex items-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
1096
+ className: cn$24("inline-flex items-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
1097
1097
  style: useCustomColors ? {
1098
1098
  color: color || void 0,
1099
1099
  backgroundColor: bgColor || void 0
@@ -1104,7 +1104,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
1104
1104
 
1105
1105
  //#endregion
1106
1106
  //#region src/components/Sidebar/index.tsx
1107
- const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
1107
+ const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
1108
1108
  function DefaultLink({ href, className, children }) {
1109
1109
  return /* @__PURE__ */ jsx("a", {
1110
1110
  href,
@@ -1112,10 +1112,35 @@ function DefaultLink({ href, className, children }) {
1112
1112
  children
1113
1113
  });
1114
1114
  }
1115
- function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", footerItems, className }) {
1115
+ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", footerItems, footerSlot, defaultExpandedIds, persistExpandedKey, className }) {
1116
1116
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
1117
- const [expandedIds, setExpandedIds] = useState(/* @__PURE__ */ new Set());
1117
+ const [expandedIds, setExpandedIds] = useState(() => new Set(defaultExpandedIds ?? []));
1118
1118
  const cubicBezier = "cubic-bezier(0.4, 0, 0.2, 1)";
1119
+ useEffect(() => {
1120
+ const idsToExpand = [];
1121
+ for (const item of menuItems) if (item.children?.some((c) => currentPath === c.href)) idsToExpand.push(item.id);
1122
+ if (footerItems) {
1123
+ for (const item of footerItems) if (item.children?.some((c) => currentPath === c.href)) idsToExpand.push(item.id);
1124
+ }
1125
+ if (idsToExpand.length > 0) setExpandedIds((prev) => {
1126
+ const next = new Set(prev);
1127
+ for (const id of idsToExpand) next.add(id);
1128
+ return next;
1129
+ });
1130
+ }, [
1131
+ currentPath,
1132
+ menuItems,
1133
+ footerItems
1134
+ ]);
1135
+ useEffect(() => {
1136
+ if (persistExpandedKey && typeof document !== "undefined") {
1137
+ const json = JSON.stringify([...expandedIds]);
1138
+ try {
1139
+ localStorage.setItem(persistExpandedKey, json);
1140
+ } catch {}
1141
+ document.cookie = `${persistExpandedKey}=${encodeURIComponent(json)}; path=/; max-age=31536000; SameSite=Lax`;
1142
+ }
1143
+ }, [expandedIds, persistExpandedKey]);
1119
1144
  function toggleExpand(id) {
1120
1145
  setExpandedIds((prev) => {
1121
1146
  const next = new Set(prev);
@@ -1153,10 +1178,9 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1153
1178
  const isActive = currentPath === item.href;
1154
1179
  const isExpanded = expandedIds.has(item.id);
1155
1180
  const isChildActive = item.children?.some((c) => currentPath === c.href);
1156
- if (isChildActive && !isExpanded) setTimeout(() => setExpandedIds((p) => new Set(p).add(item.id)), 0);
1157
1181
  if (hasChildren) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
1158
1182
  onClick: () => toggleExpand(item.id),
1159
- className: cn$22("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", collapsed && !mobile ? "justify-center" : "justify-start", isChildActive ? "text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10"),
1183
+ className: cn$23("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", collapsed && !mobile ? "justify-center" : "justify-start", isChildActive ? "text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10"),
1160
1184
  style: { transition: "background-color 200ms, color 200ms" },
1161
1185
  title: collapsed && !mobile ? item.label : void 0,
1162
1186
  children: [/* @__PURE__ */ jsx(Icon, {
@@ -1171,7 +1195,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1171
1195
  children: item.label
1172
1196
  }), /* @__PURE__ */ jsx(ChevronRight, {
1173
1197
  size: 14,
1174
- className: cn$22("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
1198
+ className: cn$23("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
1175
1199
  })] })]
1176
1200
  }), (!collapsed || mobile) && /* @__PURE__ */ jsx("div", {
1177
1201
  className: "overflow-hidden transition-all duration-200 ml-7 border-l-2 border-[var(--dashboard-sidebar-border,#2A6510)]",
@@ -1183,7 +1207,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1183
1207
  href: child.href,
1184
1208
  className: "block",
1185
1209
  children: /* @__PURE__ */ jsxs("div", {
1186
- className: cn$22("w-full flex items-center pl-4 pr-4 py-2 rounded-r-lg text-[13px] cursor-pointer", childActive ? "text-[var(--dashboard-sidebar-active-text,#5DD611)] font-semibold border-l-2 border-[var(--dashboard-primary,#37a501)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:text-[var(--dashboard-sidebar-active-text,#5DD611)]"),
1210
+ className: cn$23("w-full flex items-center pl-4 pr-4 py-2 rounded-r-lg text-[13px] cursor-pointer", childActive ? "text-[var(--dashboard-sidebar-active-text,#5DD611)] font-semibold border-l-2 border-[var(--dashboard-primary,#37a501)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:text-[var(--dashboard-sidebar-active-text,#5DD611)]"),
1187
1211
  style: { transition: "background-color 200ms, color 200ms" },
1188
1212
  children: [/* @__PURE__ */ jsx(ChildIcon, {
1189
1213
  size: 15,
@@ -1200,7 +1224,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1200
1224
  href: item.href,
1201
1225
  className: "block",
1202
1226
  children: /* @__PURE__ */ jsxs("div", {
1203
- className: cn$22("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", collapsed && !mobile ? "justify-center" : "justify-start", isActive ? "bg-[var(--dashboard-primary,#37a501)]/25 text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10"),
1227
+ className: cn$23("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", collapsed && !mobile ? "justify-center" : "justify-start", isActive ? "bg-[var(--dashboard-primary,#37a501)]/25 text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10"),
1204
1228
  style: { transition: "background-color 200ms, color 200ms" },
1205
1229
  title: collapsed && !mobile ? item.label : void 0,
1206
1230
  children: [/* @__PURE__ */ jsx(Icon, {
@@ -1276,6 +1300,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1276
1300
  ]
1277
1301
  })]
1278
1302
  }),
1303
+ footerSlot,
1279
1304
  footerItems?.map((item) => renderMenuItem(item, false, true)),
1280
1305
  onLogout && /* @__PURE__ */ jsxs("button", {
1281
1306
  onClick: onLogout,
@@ -1293,7 +1318,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1293
1318
  })
1294
1319
  })]
1295
1320
  }), /* @__PURE__ */ jsxs("aside", {
1296
- className: cn$22("hidden xl:flex xl:flex-col xl:fixed xl:left-0 xl:top-0 xl:h-screen bg-[var(--dashboard-sidebar-bg,#1B4D08)] border-r border-[var(--dashboard-sidebar-border,#2A6510)] overflow-visible", isCollapsed ? "xl:w-[109px]" : "xl:w-[280px]", className),
1321
+ className: cn$23("hidden xl:flex xl:flex-col xl:fixed xl:left-0 xl:top-0 xl:h-screen bg-[var(--dashboard-sidebar-bg,#1B4D08)] border-r border-[var(--dashboard-sidebar-border,#2A6510)] overflow-visible", isCollapsed ? "xl:w-[109px]" : "xl:w-[280px]", className),
1297
1322
  style: { transition: `width 400ms ${cubicBezier}` },
1298
1323
  children: [onToggleCollapse && /* @__PURE__ */ jsxs("button", {
1299
1324
  onClick: onToggleCollapse,
@@ -1362,7 +1387,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1362
1387
  children: [
1363
1388
  user && /* @__PURE__ */ jsxs("button", {
1364
1389
  onClick: onUserClick,
1365
- className: cn$22("w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#37a501)]/5 hover:bg-[var(--dashboard-primary,#37a501)]/10 transition-colors cursor-pointer", isCollapsed ? "justify-center" : "justify-start"),
1390
+ className: cn$23("w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#37a501)]/5 hover:bg-[var(--dashboard-primary,#37a501)]/10 transition-colors cursor-pointer", isCollapsed ? "justify-center" : "justify-start"),
1366
1391
  title: isCollapsed ? `${user.subtitle ? user.subtitle + " - " : ""}${user.name}` : void 0,
1367
1392
  children: [/* @__PURE__ */ jsx("div", {
1368
1393
  className: "flex items-center justify-center w-8 h-8 rounded-full bg-[var(--dashboard-primary,#37a501)]/30 text-[var(--dashboard-sidebar-text,#FFFFFF)] flex-shrink-0",
@@ -1390,10 +1415,11 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1390
1415
  ]
1391
1416
  })]
1392
1417
  }),
1418
+ footerSlot,
1393
1419
  footerItems?.map((item) => renderMenuItem(item, isCollapsed, false)),
1394
1420
  onLogout && /* @__PURE__ */ jsxs("button", {
1395
1421
  onClick: onLogout,
1396
- className: cn$22("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10", isCollapsed ? "justify-center" : "justify-start"),
1422
+ className: cn$23("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10", isCollapsed ? "justify-center" : "justify-start"),
1397
1423
  style: { transition: "background-color 200ms" },
1398
1424
  title: isCollapsed ? logoutLabel : void 0,
1399
1425
  children: [/* @__PURE__ */ jsx(LogOut, {
@@ -1430,7 +1456,7 @@ function useTheme() {
1430
1456
 
1431
1457
  //#endregion
1432
1458
  //#region src/components/ThemeSwitcher/index.tsx
1433
- const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
1459
+ const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
1434
1460
  function ThemeSwitcher({ className }) {
1435
1461
  const { resolvedTheme, setTheme } = useTheme();
1436
1462
  const toggle = () => {
@@ -1439,7 +1465,7 @@ function ThemeSwitcher({ className }) {
1439
1465
  return /* @__PURE__ */ jsxs("button", {
1440
1466
  type: "button",
1441
1467
  onClick: toggle,
1442
- className: cn$21("relative inline-flex items-center justify-center h-9 w-9 rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] shadow-sm transition-colors cursor-pointer hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--dashboard-primary,#37a501)] focus-visible:ring-offset-2", className),
1468
+ className: cn$22("relative inline-flex items-center justify-center h-9 w-9 rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] shadow-sm transition-colors cursor-pointer hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--dashboard-primary,#37a501)] focus-visible:ring-offset-2", className),
1443
1469
  "aria-label": "Alternar tema",
1444
1470
  children: [
1445
1471
  /* @__PURE__ */ jsx(Sun, { className: "h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
@@ -1454,7 +1480,7 @@ function ThemeSwitcher({ className }) {
1454
1480
 
1455
1481
  //#endregion
1456
1482
  //#region src/components/KPICard/index.tsx
1457
- const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
1483
+ const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
1458
1484
  function formatValue(value, format) {
1459
1485
  switch (format) {
1460
1486
  case "currency": return new Intl.NumberFormat("pt-BR", {
@@ -1484,7 +1510,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
1484
1510
  if (isLoading) return /* @__PURE__ */ jsx(KPICardSkeleton, { className });
1485
1511
  const trendConfig = trendConfigs[trend];
1486
1512
  return /* @__PURE__ */ jsxs("div", {
1487
- className: cn$20("h-full w-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-6 border border-[var(--dashboard-text-secondary,#64748B)]/12 transition-all duration-200 ease-out dashboard-shadow-sm hover:dashboard-shadow-md flex flex-col", className),
1513
+ className: cn$21("h-full w-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-6 border border-[var(--dashboard-text-secondary,#64748B)]/12 transition-all duration-200 ease-out dashboard-shadow-sm hover:dashboard-shadow-md flex flex-col", className),
1488
1514
  children: [/* @__PURE__ */ jsxs("div", {
1489
1515
  className: "flex justify-between items-start mb-4",
1490
1516
  children: [/* @__PURE__ */ jsx("h3", {
@@ -1501,7 +1527,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
1501
1527
  className: "text-3xl font-bold text-[var(--dashboard-text-primary,#0F172A)] whitespace-nowrap tracking-tight",
1502
1528
  children: formatValue(value, format)
1503
1529
  }), /* @__PURE__ */ jsxs("div", {
1504
- className: cn$20("inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
1530
+ className: cn$21("inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
1505
1531
  children: [/* @__PURE__ */ jsx("span", {
1506
1532
  className: "text-sm",
1507
1533
  children: trendConfig.icon
@@ -1515,7 +1541,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
1515
1541
  }
1516
1542
  function KPICardSkeleton({ className }) {
1517
1543
  return /* @__PURE__ */ jsxs("div", {
1518
- className: cn$20("h-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-6 border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm animate-pulse flex flex-col", className),
1544
+ className: cn$21("h-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-6 border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm animate-pulse flex flex-col", className),
1519
1545
  children: [/* @__PURE__ */ jsx("div", { className: "h-3 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-2/3 mb-4" }), /* @__PURE__ */ jsxs("div", {
1520
1546
  className: "flex items-end gap-3 flex-1",
1521
1547
  children: [/* @__PURE__ */ jsx("div", { className: "h-8 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-1/2" }), /* @__PURE__ */ jsx("div", { className: "h-5 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded-full w-1/4" })]
@@ -1525,13 +1551,13 @@ function KPICardSkeleton({ className }) {
1525
1551
 
1526
1552
  //#endregion
1527
1553
  //#region src/components/PageLayout/index.tsx
1528
- const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
1554
+ const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
1529
1555
  function PageLayout({ title, description, headerActions, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
1530
1556
  const marginLeft = sidebar ? sidebarCollapsed ? `max(0px, ${sidebarCollapsedWidth}px)` : `max(0px, ${sidebarWidth}px)` : "0px";
1531
1557
  return /* @__PURE__ */ jsxs("div", {
1532
- className: cn$19("min-h-screen bg-[var(--dashboard-background,#f2f2f2)]", className),
1558
+ className: cn$20("min-h-screen bg-[var(--dashboard-background,#f2f2f2)]", className),
1533
1559
  children: [sidebar, /* @__PURE__ */ jsxs("main", {
1534
- className: cn$19("pt-16 xl:pt-0", !sidebar && "pt-0"),
1560
+ className: cn$20("pt-16 xl:pt-0", !sidebar && "pt-0"),
1535
1561
  style: {
1536
1562
  marginLeft,
1537
1563
  transition: "margin-left 400ms cubic-bezier(0.4, 0, 0.2, 1)"
@@ -1569,7 +1595,7 @@ function PageLayout({ title, description, headerActions, children, contentPaddin
1569
1595
  //#endregion
1570
1596
  //#region src/components/ComparisonLineChart/index.tsx
1571
1597
  Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
1572
- const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
1598
+ const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
1573
1599
  function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, currentPeriodLabel = "Período atual", previousPeriodLabel = "Período anterior", title, color, height = 300, className }) {
1574
1600
  const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
1575
1601
  const data = {
@@ -1663,7 +1689,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
1663
1689
  }
1664
1690
  };
1665
1691
  return /* @__PURE__ */ jsxs("div", {
1666
- className: cn$18("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
1692
+ className: cn$19("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
1667
1693
  children: [title && /* @__PURE__ */ jsx("h3", {
1668
1694
  className: "text-base font-semibold mb-4 text-[var(--dashboard-text-primary,#2d2d2d)]",
1669
1695
  children: title
@@ -1680,7 +1706,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
1680
1706
  //#endregion
1681
1707
  //#region src/components/HorizontalBarChart/index.tsx
1682
1708
  Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
1683
- const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
1709
+ const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
1684
1710
  function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", className }) {
1685
1711
  const [activeTab, setActiveTab] = useState((tabs ? tabs.map((t) => t.id) : Object.keys(datasets))[0]);
1686
1712
  const [isMobile, setIsMobile] = useState(false);
@@ -1755,7 +1781,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
1755
1781
  }
1756
1782
  };
1757
1783
  return /* @__PURE__ */ jsxs("div", {
1758
- className: cn$17("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-5 sm:p-6 min-h-[850px] sm:h-full flex flex-col", className),
1784
+ className: cn$18("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-5 sm:p-6 min-h-[850px] sm:h-full flex flex-col", className),
1759
1785
  children: [
1760
1786
  title && /* @__PURE__ */ jsxs("div", {
1761
1787
  className: "flex items-center gap-2 mb-4",
@@ -1768,7 +1794,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
1768
1794
  className: "flex gap-2 mb-4 flex-wrap",
1769
1795
  children: tabs.map((tab) => /* @__PURE__ */ jsx("button", {
1770
1796
  onClick: () => setActiveTab(tab.id),
1771
- className: cn$17("px-3.5 py-2 sm:px-4 sm:py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap cursor-pointer", activeTab === tab.id ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
1797
+ className: cn$18("px-3.5 py-2 sm:px-4 sm:py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap cursor-pointer", activeTab === tab.id ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
1772
1798
  children: tab.label
1773
1799
  }, tab.id))
1774
1800
  }),
@@ -1807,7 +1833,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
1807
1833
  //#endregion
1808
1834
  //#region src/components/VerticalBarChart/index.tsx
1809
1835
  Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
1810
- const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
1836
+ const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
1811
1837
  function VerticalBarChart({ labels, data: values, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", labelMaxChars = 3, className }) {
1812
1838
  const maxValue = Math.max(...values);
1813
1839
  const bestLabel = labels[values.indexOf(maxValue)];
@@ -1870,7 +1896,7 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
1870
1896
  }
1871
1897
  };
1872
1898
  return /* @__PURE__ */ jsxs("div", {
1873
- className: cn$16("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6 flex-1 flex flex-col", className),
1899
+ className: cn$17("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6 flex-1 flex flex-col", className),
1874
1900
  children: [
1875
1901
  title && /* @__PURE__ */ jsxs("div", {
1876
1902
  className: "flex items-center gap-2 mb-4",
@@ -1911,6 +1937,120 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
1911
1937
  });
1912
1938
  }
1913
1939
 
1940
+ //#endregion
1941
+ //#region src/components/DoughnutChart/index.tsx
1942
+ Chart.register(ArcElement, Tooltip$1, Legend);
1943
+ const DEFAULT_COLORS = [
1944
+ "#2563EB",
1945
+ "#059669",
1946
+ "#D97706",
1947
+ "#DC2626",
1948
+ "#7C3AED",
1949
+ "#0891B2",
1950
+ "#DB2777",
1951
+ "#65A30D",
1952
+ "#EA580C",
1953
+ "#4F46E5"
1954
+ ];
1955
+ const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
1956
+ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, showLegend = true, formatValue, cutout = 65, height = 240, className }) {
1957
+ const total = items.reduce((sum, item) => sum + item.value, 0);
1958
+ const format = formatValue || ((v) => String(v));
1959
+ const colors = items.map((item, i) => item.color || DEFAULT_COLORS[i % DEFAULT_COLORS.length]);
1960
+ const chartData = {
1961
+ labels: items.map((i) => i.label),
1962
+ datasets: [{
1963
+ data: items.map((i) => i.value),
1964
+ backgroundColor: colors,
1965
+ borderColor: "var(--dashboard-surface, #ffffff)",
1966
+ borderWidth: 2,
1967
+ hoverOffset: 4
1968
+ }]
1969
+ };
1970
+ const options = {
1971
+ responsive: true,
1972
+ maintainAspectRatio: false,
1973
+ cutout: `${cutout}%`,
1974
+ plugins: {
1975
+ legend: { display: false },
1976
+ tooltip: {
1977
+ backgroundColor: "rgba(45, 45, 45, 0.95)",
1978
+ titleColor: "#fff",
1979
+ bodyColor: "#fff",
1980
+ padding: 12,
1981
+ displayColors: true,
1982
+ titleFont: {
1983
+ size: 12,
1984
+ weight: "bold"
1985
+ },
1986
+ bodyFont: { size: 11 },
1987
+ callbacks: { label: (context) => {
1988
+ const pct = total > 0 ? (context.parsed / total * 100).toFixed(1) : "0";
1989
+ return ` ${context.label}: ${format(context.parsed)} (${pct}%)`;
1990
+ } }
1991
+ }
1992
+ }
1993
+ };
1994
+ return /* @__PURE__ */ jsxs("div", {
1995
+ className: cn$16("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
1996
+ children: [title && /* @__PURE__ */ jsxs("div", {
1997
+ className: "flex items-center gap-2 mb-4",
1998
+ children: [titleIcon, /* @__PURE__ */ jsx("h3", {
1999
+ className: "text-base font-semibold text-[var(--dashboard-text-primary,#2d2d2d)]",
2000
+ children: title
2001
+ })]
2002
+ }), /* @__PURE__ */ jsxs("div", {
2003
+ className: cn$16("flex items-center", showLegend ? "gap-6" : "justify-center"),
2004
+ children: [/* @__PURE__ */ jsxs("div", {
2005
+ className: "relative flex-shrink-0",
2006
+ style: {
2007
+ width: height,
2008
+ height
2009
+ },
2010
+ children: [/* @__PURE__ */ jsx(Doughnut, {
2011
+ data: chartData,
2012
+ options
2013
+ }), (centerLabel || centerValue) && /* @__PURE__ */ jsxs("div", {
2014
+ className: "absolute inset-0 flex flex-col items-center justify-center pointer-events-none",
2015
+ children: [centerValue && /* @__PURE__ */ jsx("span", {
2016
+ className: "text-2xl font-bold text-[var(--dashboard-text-primary,#2d2d2d)]",
2017
+ children: centerValue
2018
+ }), centerLabel && /* @__PURE__ */ jsx("span", {
2019
+ className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
2020
+ children: centerLabel
2021
+ })]
2022
+ })]
2023
+ }), showLegend && items.length > 0 && /* @__PURE__ */ jsx("div", {
2024
+ className: "flex-1 min-w-0 space-y-2",
2025
+ children: items.map((item, i) => {
2026
+ const pct = total > 0 ? (item.value / total * 100).toFixed(1) : "0";
2027
+ return /* @__PURE__ */ jsxs("div", {
2028
+ className: "flex items-center gap-2",
2029
+ children: [
2030
+ /* @__PURE__ */ jsx("span", {
2031
+ className: "w-3 h-3 rounded-full flex-shrink-0",
2032
+ style: { backgroundColor: colors[i] }
2033
+ }),
2034
+ /* @__PURE__ */ jsx("span", {
2035
+ className: "text-sm text-[var(--dashboard-text-secondary,#6b7280)] truncate flex-1",
2036
+ children: item.label
2037
+ }),
2038
+ /* @__PURE__ */ jsx("span", {
2039
+ className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)] whitespace-nowrap",
2040
+ children: format(item.value)
2041
+ }),
2042
+ /* @__PURE__ */ jsxs("span", {
2043
+ className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] whitespace-nowrap",
2044
+ children: [pct, "%"]
2045
+ })
2046
+ ]
2047
+ }, item.label);
2048
+ })
2049
+ })]
2050
+ })]
2051
+ });
2052
+ }
2053
+
1914
2054
  //#endregion
1915
2055
  //#region src/components/ProgressBarList/index.tsx
1916
2056
  const cn$15 = (...classes) => classes.filter(Boolean).join(" ");
@@ -4297,5 +4437,5 @@ function DashboardProvider({ config: configOverrides, children }) {
4297
4437
  }
4298
4438
 
4299
4439
  //#endregion
4300
- export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Card, Checkbox, CodeInput, Combobox, ComparisonLineChart, DashboardProvider, DataGrid, DateRangePicker, Dropdown, EmptyState, FileUpload, FilterBar, FormField, HorizontalBarChart, Input, KPICard, Loading, LoadingProvider, MetricPanel, Modal, NotificationsProvider, PageLayout, Pagination, ProgressBarList, Sidebar, Skeleton, StatusBadge, Stepper, Table, TableBody, TableEmpty, TableHeader, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, createColumnHelper, createConfig, defaultConfig, useConfig, useLoading, useNotifications, useTheme };
4440
+ export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Card, Checkbox, CodeInput, Combobox, ComparisonLineChart, DashboardProvider, DataGrid, DateRangePicker, DoughnutChart, Dropdown, EmptyState, FileUpload, FilterBar, FormField, HorizontalBarChart, Input, KPICard, Loading, LoadingProvider, MetricPanel, Modal, NotificationsProvider, PageLayout, Pagination, ProgressBarList, Sidebar, Skeleton, StatusBadge, Stepper, Table, TableBody, TableEmpty, TableHeader, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, createColumnHelper, createConfig, defaultConfig, useConfig, useLoading, useNotifications, useTheme };
4301
4441
  //# sourceMappingURL=index.mjs.map