@tree-ia/design-system 1.6.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
1
+ import React, { cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { createPortal } from "react-dom";
4
- import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Copy, File, GripVertical, Image, Inbox, Info, Lightbulb, LogOut, Monitor, Moon, Search, ShieldAlert, Sun, Upload, User, X, XCircle } from "lucide-react";
4
+ import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Building2, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Copy, File, GripVertical, Image, Inbox, Info, Lightbulb, LogOut, Menu, Monitor, Moon, Search, ShieldAlert, Sun, Text, Upload, User, X, XCircle } from "lucide-react";
5
5
  import { Bar, Doughnut, Line } from "react-chartjs-2";
6
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";
@@ -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$32 = (...classes) => classes.filter(Boolean).join(" ");
38
+ const cn$35 = (...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 = {
@@ -45,18 +45,18 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
45
45
  ghost: "bg-transparent hover:bg-[var(--dashboard-text-secondary,#64748B)]/8 text-[var(--dashboard-text-primary,#0F172A)]"
46
46
  };
47
47
  const sizeStyles = {
48
- sm: "px-2 py-1 text-xs sm:px-3 sm:py-1.5 sm:text-sm",
49
- md: "px-3 py-1.5 text-sm sm:px-4 sm:py-2 sm:text-base",
50
- lg: "px-4 py-2 text-base sm:px-6 sm:py-3 sm:text-lg"
48
+ sm: "h-8 px-2 text-xs sm:px-3 sm:text-sm",
49
+ md: "h-9 px-3 text-sm sm:px-4 sm:text-base",
50
+ lg: "h-10 px-4 text-base sm:px-6 sm:text-lg"
51
51
  };
52
52
  const iconOnlySizeStyles = {
53
- sm: "w-7 h-7 sm:w-8 sm:h-8",
54
- md: "w-9 h-9 sm:w-10 sm:h-10",
55
- lg: "w-10 h-10 sm:w-12 sm:h-12"
53
+ sm: "h-8 w-8",
54
+ md: "h-9 w-9",
55
+ lg: "h-10 w-10"
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$32(baseStyles, variantStyles[variant], isIconOnly ? iconOnlySizeStyles[size] : sizeStyles[size], className),
59
+ className: cn$35(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,8 +81,13 @@ 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$31 = (...classes) => classes.filter(Boolean).join(" ");
85
- const Input = React.forwardRef(({ className, type = "text", label, error, children, id, ...props }, ref) => {
84
+ const cn$34 = (...classes) => classes.filter(Boolean).join(" ");
85
+ const sizeStyles = {
86
+ sm: "h-8 px-2.5 text-xs",
87
+ md: "h-9 px-3 text-sm",
88
+ lg: "h-10 px-4 text-base"
89
+ };
90
+ const Input = React.forwardRef(({ className, type = "text", label, error, children, id, size = "md", ...props }, ref) => {
86
91
  const inputId = id || (label ? `input-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
87
92
  return /* @__PURE__ */ jsxs("div", {
88
93
  className: "w-full",
@@ -97,7 +102,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, childr
97
102
  children: [/* @__PURE__ */ jsx("input", {
98
103
  type,
99
104
  id: inputId,
100
- className: cn$31("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),
105
+ className: cn$34("flex w-full rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] 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", sizeStyles[size], error ? "border-[var(--dashboard-status-danger,#EF4444)] focus:border-[var(--dashboard-status-danger,#EF4444)]" : void 0, children ? "pr-10" : void 0, className),
101
106
  ref,
102
107
  ...props
103
108
  }), children && /* @__PURE__ */ jsx("div", {
@@ -116,7 +121,7 @@ Input.displayName = "Input";
116
121
 
117
122
  //#endregion
118
123
  //#region src/components/Dropdown/index.tsx
119
- function Dropdown({ options, value, onChange, label, placeholder = "Selecione uma opção", disabled = false, className = "", containerClassName = "", fullWidth = false, size = "medium", error, variant = "default", customDropdownHeight, icon, fitContent = false, isActive = false }) {
124
+ function Dropdown({ options, value, onChange, label, placeholder = "Selecione uma opção", disabled = false, className = "", containerClassName = "", fullWidth = false, size = "md", error, variant = "default", customDropdownHeight, icon, fitContent = false, isActive = false }) {
120
125
  const [isOpen, setIsOpen] = useState(false);
121
126
  const [isVisible, setIsVisible] = useState(false);
122
127
  const [position, setPosition] = useState({
@@ -127,23 +132,23 @@ function Dropdown({ options, value, onChange, label, placeholder = "Selecione um
127
132
  const dropdownRef = useRef(null);
128
133
  const selectedOption = options.find((option) => option.value === value);
129
134
  const selectedStyle = {
130
- small: {
131
- container: "h-8 px-2",
135
+ sm: {
136
+ container: "h-8 px-2.5",
132
137
  text: "text-xs",
133
138
  wrapper: "space-y-1",
134
139
  label: "text-sm",
135
140
  iconPadding: "pl-8"
136
141
  },
137
- medium: {
138
- container: "h-10 px-3",
142
+ md: {
143
+ container: "h-9 px-3",
139
144
  text: "text-sm",
140
145
  wrapper: "space-y-2",
141
146
  label: "text-base",
142
147
  iconPadding: "pl-10"
143
148
  },
144
- large: {
145
- container: "h-12 px-4",
146
- text: "text-lg",
149
+ lg: {
150
+ container: "h-10 px-4",
151
+ text: "text-base",
147
152
  wrapper: "space-y-3",
148
153
  label: "text-lg",
149
154
  iconPadding: "pl-12"
@@ -362,13 +367,14 @@ function TableEmpty({ message, icon }) {
362
367
  //#region src/components/Modal/index.tsx
363
368
  const ANIMATION_MS = 200;
364
369
  const sizeClasses$2 = {
365
- small: "max-w-sm",
366
- medium: "max-w-md",
367
- large: "max-w-lg",
368
- largeXl: "max-w-4xl",
369
- extraLarge: "max-w-screen-xl"
370
+ sm: "max-w-sm",
371
+ md: "max-w-md",
372
+ lg: "max-w-lg",
373
+ xl: "max-w-2xl",
374
+ "2xl": "max-w-4xl",
375
+ "3xl": "max-w-screen-xl"
370
376
  };
371
- function Modal({ isOpen, onClose, onSave, title = "", children, showFooter = false, saveButtonText = "Salvar", cancelButtonText = "Cancelar", size = "medium", disableSaveButton = false, saveButtonVariant = "primary", closeOnEscape = true, closeOnOverlayClick = true }) {
377
+ function Modal({ isOpen, onClose, onSave, title = "", children, showFooter = false, saveButtonText = "Salvar", cancelButtonText = "Cancelar", size = "md", disableSaveButton = false, saveButtonVariant = "primary", closeOnEscape = true, closeOnOverlayClick = true }) {
372
378
  const [shouldRender, setShouldRender] = useState(false);
373
379
  const modalRef = useRef(null);
374
380
  if (isOpen && !shouldRender) setShouldRender(true);
@@ -619,7 +625,7 @@ function Pagination({ currentPage, totalPages, onPageChange, itemsPerPage, total
619
625
  options: dropdownOptions,
620
626
  value: String(itemsPerPage),
621
627
  onChange: (val) => onItemsPerPageChange(Number(val)),
622
- size: "small",
628
+ size: "sm",
623
629
  variant: "compact",
624
630
  fitContent: true
625
631
  }), /* @__PURE__ */ jsx("span", {
@@ -751,16 +757,16 @@ function FormField({ label, name, type = "text", value, onChange, error, require
751
757
 
752
758
  //#endregion
753
759
  //#region src/components/Tabs/index.tsx
754
- const cn$30 = (...classes) => classes.filter(Boolean).join(" ");
760
+ const cn$33 = (...classes) => classes.filter(Boolean).join(" ");
755
761
  function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
756
762
  if (variant === "pill") return /* @__PURE__ */ jsx("div", {
757
- className: cn$30("flex flex-wrap gap-2", className),
763
+ className: cn$33("flex flex-wrap gap-2", className),
758
764
  role: "tablist",
759
765
  children: tabs.map((tab) => {
760
766
  const isActive = activeTab === tab.id;
761
767
  return /* @__PURE__ */ jsxs("button", {
762
768
  onClick: () => onChange(tab.id),
763
- className: cn$30("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"),
769
+ className: cn$33("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"),
764
770
  role: "tab",
765
771
  "aria-selected": isActive,
766
772
  children: [
@@ -770,7 +776,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
770
776
  }),
771
777
  tab.label,
772
778
  tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
773
- className: cn$30("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)]"),
779
+ className: cn$33("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)]"),
774
780
  children: tab.count
775
781
  })
776
782
  ]
@@ -778,7 +784,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
778
784
  })
779
785
  });
780
786
  return /* @__PURE__ */ jsx("div", {
781
- className: cn$30("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
787
+ className: cn$33("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
782
788
  children: /* @__PURE__ */ jsx("nav", {
783
789
  className: "flex gap-6",
784
790
  "aria-label": "Tabs",
@@ -786,7 +792,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
786
792
  const isActive = activeTab === tab.id;
787
793
  return /* @__PURE__ */ jsxs("button", {
788
794
  onClick: () => onChange(tab.id),
789
- className: cn$30("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"),
795
+ className: cn$33("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"),
790
796
  role: "tab",
791
797
  "aria-selected": isActive,
792
798
  children: [
@@ -796,7 +802,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
796
802
  }),
797
803
  tab.label,
798
804
  tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
799
- className: cn$30("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)]"),
805
+ className: cn$33("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)]"),
800
806
  children: tab.count
801
807
  })
802
808
  ]
@@ -808,8 +814,8 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
808
814
 
809
815
  //#endregion
810
816
  //#region src/components/DateRangePicker/index.tsx
811
- const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
812
- const locales = {
817
+ const cn$32 = (...classes) => classes.filter(Boolean).join(" ");
818
+ const locales$1 = {
813
819
  pt: {
814
820
  months: [
815
821
  "Janeiro",
@@ -867,7 +873,7 @@ const locales = {
867
873
  };
868
874
  function DateRangePicker({ value, onChange, locale = "pt", className }) {
869
875
  const [currentMonth, setCurrentMonth] = useState(/* @__PURE__ */ new Date());
870
- const l = locales[locale];
876
+ const l = locales$1[locale];
871
877
  const getDaysInMonth = (date) => {
872
878
  const year = date.getFullYear();
873
879
  const month = date.getMonth();
@@ -915,7 +921,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
915
921
  };
916
922
  const days = getDaysInMonth(currentMonth);
917
923
  return /* @__PURE__ */ jsxs("div", {
918
- className: cn$29("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
924
+ className: cn$32("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
919
925
  children: [/* @__PURE__ */ jsxs("div", {
920
926
  className: "flex items-center justify-between mb-4",
921
927
  children: [
@@ -953,9 +959,9 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
953
959
  const isSelected = isStart || isEnd;
954
960
  return /* @__PURE__ */ jsxs("div", {
955
961
  className: "relative h-8 w-8",
956
- children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$29("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
962
+ children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$32("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
957
963
  onClick: () => handleDayClick(day),
958
- className: cn$29("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"),
964
+ className: cn$32("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"),
959
965
  children: day
960
966
  })]
961
967
  }, day);
@@ -964,9 +970,157 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
964
970
  });
965
971
  }
966
972
 
973
+ //#endregion
974
+ //#region src/components/DatePicker/index.tsx
975
+ const cn$31 = (...classes) => classes.filter(Boolean).join(" ");
976
+ const locales = {
977
+ pt: {
978
+ months: [
979
+ "Janeiro",
980
+ "Fevereiro",
981
+ "Março",
982
+ "Abril",
983
+ "Maio",
984
+ "Junho",
985
+ "Julho",
986
+ "Agosto",
987
+ "Setembro",
988
+ "Outubro",
989
+ "Novembro",
990
+ "Dezembro"
991
+ ],
992
+ weekDays: [
993
+ "D",
994
+ "S",
995
+ "T",
996
+ "Q",
997
+ "Q",
998
+ "S",
999
+ "S"
1000
+ ],
1001
+ prevMonth: "Mês anterior",
1002
+ nextMonth: "Próximo mês"
1003
+ },
1004
+ en: {
1005
+ months: [
1006
+ "January",
1007
+ "February",
1008
+ "March",
1009
+ "April",
1010
+ "May",
1011
+ "June",
1012
+ "July",
1013
+ "August",
1014
+ "September",
1015
+ "October",
1016
+ "November",
1017
+ "December"
1018
+ ],
1019
+ weekDays: [
1020
+ "S",
1021
+ "M",
1022
+ "T",
1023
+ "W",
1024
+ "T",
1025
+ "F",
1026
+ "S"
1027
+ ],
1028
+ prevMonth: "Previous month",
1029
+ nextMonth: "Next month"
1030
+ }
1031
+ };
1032
+ const startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate());
1033
+ function DatePicker({ value, onChange, locale = "pt", minDate, maxDate, className }) {
1034
+ const [currentMonth, setCurrentMonth] = useState(value ?? /* @__PURE__ */ new Date());
1035
+ const l = locales[locale];
1036
+ const getDaysInMonth = (date) => {
1037
+ const year = date.getFullYear();
1038
+ const month = date.getMonth();
1039
+ const firstDay = new Date(year, month, 1);
1040
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
1041
+ const startDayOfWeek = firstDay.getDay();
1042
+ const days = [];
1043
+ for (let i = 0; i < startDayOfWeek; i++) days.push(null);
1044
+ for (let i = 1; i <= daysInMonth; i++) days.push(i);
1045
+ return days;
1046
+ };
1047
+ const buildDate = (day) => new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day);
1048
+ const isDisabled = (day) => {
1049
+ const date = buildDate(day);
1050
+ if (minDate && date < startOfDay(minDate)) return true;
1051
+ if (maxDate && date > startOfDay(maxDate)) return true;
1052
+ return false;
1053
+ };
1054
+ const isSelected = (day) => {
1055
+ if (!value) return false;
1056
+ return buildDate(day).getTime() === startOfDay(value).getTime();
1057
+ };
1058
+ const handleDayClick = (day) => {
1059
+ if (isDisabled(day)) return;
1060
+ onChange(buildDate(day));
1061
+ };
1062
+ const previousMonth = () => {
1063
+ setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1));
1064
+ };
1065
+ const nextMonth = () => {
1066
+ setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1));
1067
+ };
1068
+ const days = getDaysInMonth(currentMonth);
1069
+ return /* @__PURE__ */ jsxs("div", {
1070
+ className: cn$31("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
1071
+ children: [/* @__PURE__ */ jsxs("div", {
1072
+ className: "flex items-center justify-between mb-4",
1073
+ children: [
1074
+ /* @__PURE__ */ jsx("button", {
1075
+ type: "button",
1076
+ onClick: previousMonth,
1077
+ className: "p-1 hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 rounded transition-colors cursor-pointer",
1078
+ "aria-label": l.prevMonth,
1079
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-4 h-4 text-[var(--dashboard-text-primary,#2d2d2d)]" })
1080
+ }),
1081
+ /* @__PURE__ */ jsxs("h2", {
1082
+ className: "text-base font-semibold text-[var(--dashboard-text-primary,#2d2d2d)]",
1083
+ children: [
1084
+ l.months[currentMonth.getMonth()],
1085
+ " ",
1086
+ currentMonth.getFullYear()
1087
+ ]
1088
+ }),
1089
+ /* @__PURE__ */ jsx("button", {
1090
+ type: "button",
1091
+ onClick: nextMonth,
1092
+ className: "p-1 hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 rounded transition-colors cursor-pointer",
1093
+ "aria-label": l.nextMonth,
1094
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4 text-[var(--dashboard-text-primary,#2d2d2d)]" })
1095
+ })
1096
+ ]
1097
+ }), /* @__PURE__ */ jsxs("div", {
1098
+ className: "grid grid-cols-7",
1099
+ children: [l.weekDays.map((day, index) => /* @__PURE__ */ jsx("div", {
1100
+ className: "h-8 w-8 flex items-center justify-center text-xs font-medium text-[var(--dashboard-text-secondary,#6b7280)]",
1101
+ children: day
1102
+ }, index)), days.map((day, index) => {
1103
+ if (day === null) return /* @__PURE__ */ jsx("div", { className: "h-8 w-8" }, `empty-${index}`);
1104
+ const selected = isSelected(day);
1105
+ const disabled = isDisabled(day);
1106
+ return /* @__PURE__ */ jsx("div", {
1107
+ className: "relative h-8 w-8",
1108
+ children: /* @__PURE__ */ jsx("button", {
1109
+ type: "button",
1110
+ onClick: () => handleDayClick(day),
1111
+ disabled,
1112
+ className: cn$31("relative h-8 w-8 flex items-center justify-center text-xs font-medium transition-colors z-10 rounded-full", disabled ? "text-[var(--dashboard-text-secondary,#6b7280)]/40 cursor-not-allowed" : "cursor-pointer", !disabled && selected ? "bg-[var(--dashboard-primary,#37a501)] text-white hover:opacity-90" : !disabled && "text-[var(--dashboard-text-primary,#2d2d2d)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
1113
+ children: day
1114
+ })
1115
+ }, day);
1116
+ })]
1117
+ })]
1118
+ });
1119
+ }
1120
+
967
1121
  //#endregion
968
1122
  //#region src/components/Title/index.tsx
969
- const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
1123
+ const cn$30 = (...classes) => classes.filter(Boolean).join(" ");
970
1124
  const defaultSizeByLevel = {
971
1125
  1: "text-2xl sm:text-3xl md:text-4xl lg:text-5xl",
972
1126
  2: "text-xl sm:text-2xl md:text-3xl lg:text-4xl",
@@ -1001,7 +1155,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
1001
1155
  const sizeClass = size ? customSizes[size] : defaultSizeByLevel[level];
1002
1156
  const colorClass = color || "text-[var(--dashboard-text-primary,#2d2d2d)]";
1003
1157
  return /* @__PURE__ */ jsx(Tag, {
1004
- className: cn$28(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
1158
+ className: cn$30(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
1005
1159
  ...props,
1006
1160
  children
1007
1161
  });
@@ -1009,7 +1163,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
1009
1163
 
1010
1164
  //#endregion
1011
1165
  //#region src/components/ToggleSwitch/index.tsx
1012
- const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
1166
+ const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
1013
1167
  const sizeConfig$1 = {
1014
1168
  sm: {
1015
1169
  track: "h-5 w-9",
@@ -1033,7 +1187,7 @@ const sizeConfig$1 = {
1033
1187
  function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label, className }) {
1034
1188
  const config = sizeConfig$1[size];
1035
1189
  return /* @__PURE__ */ jsxs("div", {
1036
- className: cn$27("inline-flex items-center gap-2", className),
1190
+ className: cn$29("inline-flex items-center gap-2", className),
1037
1191
  children: [/* @__PURE__ */ jsx("button", {
1038
1192
  type: "button",
1039
1193
  role: "switch",
@@ -1041,10 +1195,10 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
1041
1195
  "aria-label": label,
1042
1196
  disabled,
1043
1197
  onClick: () => onChange(!enabled),
1044
- className: cn$27("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"),
1045
- children: /* @__PURE__ */ jsx("span", { className: cn$27("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
1198
+ className: cn$29("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"),
1199
+ children: /* @__PURE__ */ jsx("span", { className: cn$29("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
1046
1200
  }), label && /* @__PURE__ */ jsx("span", {
1047
- className: cn$27("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
1201
+ className: cn$29("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
1048
1202
  children: label
1049
1203
  })]
1050
1204
  });
@@ -1052,7 +1206,7 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
1052
1206
 
1053
1207
  //#endregion
1054
1208
  //#region src/components/BadgeStatus/index.tsx
1055
- const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
1209
+ const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
1056
1210
  const variantStyles = {
1057
1211
  success: {
1058
1212
  color: "text-[var(--dashboard-status-success,#10B981)]",
@@ -1083,7 +1237,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
1083
1237
  const styles = variantStyles[variant];
1084
1238
  const useCustomColors = color || bgColor;
1085
1239
  return /* @__PURE__ */ jsx("span", {
1086
- className: cn$26("inline-flex items-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
1240
+ className: cn$28("inline-flex w-fit items-center justify-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
1087
1241
  style: useCustomColors ? {
1088
1242
  color: color || void 0,
1089
1243
  backgroundColor: bgColor || void 0
@@ -1094,15 +1248,15 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
1094
1248
 
1095
1249
  //#endregion
1096
1250
  //#region src/components/Sidebar/index.tsx
1097
- const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
1098
- function DefaultLink({ href, className, children }) {
1251
+ const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
1252
+ function DefaultLink$1({ href, className, children }) {
1099
1253
  return /* @__PURE__ */ jsx("a", {
1100
1254
  href,
1101
1255
  className,
1102
1256
  children
1103
1257
  });
1104
1258
  }
1105
- function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", footerItems, footerSlot, defaultExpandedIds, persistExpandedKey, className }) {
1259
+ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink$1, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", footerItems, footerSlot, defaultExpandedIds, persistExpandedKey, showMobileHeader = true, className }) {
1106
1260
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
1107
1261
  const [expandedIds, setExpandedIds] = useState(() => new Set(defaultExpandedIds ?? []));
1108
1262
  const cubicBezier = "cubic-bezier(0.4, 0, 0.2, 1)";
@@ -1170,7 +1324,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1170
1324
  const isChildActive = item.children?.some((c) => currentPath === c.href);
1171
1325
  if (hasChildren) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
1172
1326
  onClick: () => toggleExpand(item.id),
1173
- className: cn$25("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,#ff521d)]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10"),
1327
+ className: cn$27("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,#ff521d)]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10"),
1174
1328
  style: { transition: "background-color 200ms, color 200ms" },
1175
1329
  title: collapsed && !mobile ? item.label : void 0,
1176
1330
  children: [/* @__PURE__ */ jsx(Icon, {
@@ -1185,7 +1339,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1185
1339
  children: item.label
1186
1340
  }), /* @__PURE__ */ jsx(ChevronRight, {
1187
1341
  size: 14,
1188
- className: cn$25("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
1342
+ className: cn$27("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
1189
1343
  })] })]
1190
1344
  }), (!collapsed || mobile) && /* @__PURE__ */ jsx("div", {
1191
1345
  className: "overflow-hidden transition-all duration-200 ml-7 border-l-2 border-[var(--dashboard-sidebar-border,#e0dfe3)]",
@@ -1197,7 +1351,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1197
1351
  href: child.href,
1198
1352
  className: "block",
1199
1353
  children: /* @__PURE__ */ jsxs("div", {
1200
- className: cn$25("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,#ff521d)] font-semibold border-l-2 border-[var(--dashboard-primary,#ff521d)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:text-[var(--dashboard-sidebar-active-text,#ff521d)]"),
1354
+ className: cn$27("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,#ff521d)] font-semibold border-l-2 border-[var(--dashboard-primary,#ff521d)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:text-[var(--dashboard-sidebar-active-text,#ff521d)]"),
1201
1355
  style: { transition: "background-color 200ms, color 200ms" },
1202
1356
  children: [/* @__PURE__ */ jsx(ChildIcon, {
1203
1357
  size: 15,
@@ -1214,7 +1368,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1214
1368
  href: item.href,
1215
1369
  className: "block",
1216
1370
  children: /* @__PURE__ */ jsxs("div", {
1217
- className: cn$25("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,#ff521d)]/25 text-[var(--dashboard-sidebar-active-text,#ff521d)]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10"),
1371
+ className: cn$27("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,#ff521d)]/25 text-[var(--dashboard-sidebar-active-text,#ff521d)]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10"),
1218
1372
  style: { transition: "background-color 200ms, color 200ms" },
1219
1373
  title: collapsed && !mobile ? item.label : void 0,
1220
1374
  children: [/* @__PURE__ */ jsx(Icon, {
@@ -1242,7 +1396,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1242
1396
  children: [group.section && renderSectionHeader(group.section, collapsed), group.items.map((item) => renderMenuItem(item, collapsed, mobile))]
1243
1397
  }, group.section || `group-${i}`));
1244
1398
  }
1245
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("header", {
1399
+ const mobileHeader = /* @__PURE__ */ jsxs("header", {
1246
1400
  className: "xl:hidden fixed top-0 left-0 right-0 z-40 bg-[var(--dashboard-sidebar-bg,#f0f0f0)] border-b border-[var(--dashboard-sidebar-border,#e0dfe3)]",
1247
1401
  children: [/* @__PURE__ */ jsxs("div", {
1248
1402
  className: "flex items-center justify-center px-4 h-16 relative",
@@ -1307,8 +1461,9 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1307
1461
  })]
1308
1462
  })
1309
1463
  })]
1310
- }), /* @__PURE__ */ jsxs("aside", {
1311
- className: cn$25("hidden xl:flex xl:flex-col xl:fixed xl:left-0 xl:top-0 xl:h-screen bg-[var(--dashboard-sidebar-bg,#f0f0f0)] border-r border-[var(--dashboard-sidebar-border,#e0dfe3)] overflow-visible", isCollapsed ? "xl:w-[109px]" : "xl:w-[280px]", className),
1464
+ });
1465
+ const desktopSidebar = /* @__PURE__ */ jsxs("aside", {
1466
+ className: cn$27("hidden xl:flex xl:flex-col xl:fixed xl:left-0 xl:top-0 xl:h-screen bg-[var(--dashboard-sidebar-bg,#f0f0f0)] border-r border-[var(--dashboard-sidebar-border,#e0dfe3)] overflow-visible", isCollapsed ? "xl:w-[109px]" : "xl:w-[280px]", className),
1312
1467
  style: { transition: `width 400ms ${cubicBezier}` },
1313
1468
  children: [onToggleCollapse && /* @__PURE__ */ jsxs("button", {
1314
1469
  onClick: onToggleCollapse,
@@ -1382,7 +1537,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1382
1537
  children: [
1383
1538
  user && /* @__PURE__ */ jsxs("button", {
1384
1539
  onClick: onUserClick,
1385
- className: cn$25("w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#ff521d)]/5 hover:bg-[var(--dashboard-primary,#ff521d)]/10 transition-colors cursor-pointer", isCollapsed ? "justify-center" : "justify-start"),
1540
+ className: cn$27("w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#ff521d)]/5 hover:bg-[var(--dashboard-primary,#ff521d)]/10 transition-colors cursor-pointer", isCollapsed ? "justify-center" : "justify-start"),
1386
1541
  title: isCollapsed ? `${user.subtitle ? user.subtitle + " - " : ""}${user.name}` : void 0,
1387
1542
  children: [/* @__PURE__ */ jsx("div", {
1388
1543
  className: "flex items-center justify-center w-8 h-8 rounded-full bg-[var(--dashboard-primary,#ff521d)]/30 text-[var(--dashboard-sidebar-text,#403f52)] flex-shrink-0",
@@ -1415,7 +1570,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1415
1570
  footerItems?.map((item) => renderMenuItem(item, isCollapsed, false)),
1416
1571
  onLogout && /* @__PURE__ */ jsxs("button", {
1417
1572
  onClick: onLogout,
1418
- className: cn$25("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10", isCollapsed ? "justify-center" : "justify-start"),
1573
+ className: cn$27("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10", isCollapsed ? "justify-center" : "justify-start"),
1419
1574
  style: { transition: "background-color 200ms" },
1420
1575
  title: isCollapsed ? logoutLabel : void 0,
1421
1576
  children: [/* @__PURE__ */ jsx(LogOut, {
@@ -1438,12 +1593,445 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
1438
1593
  })
1439
1594
  ]
1440
1595
  })]
1441
- })] });
1596
+ });
1597
+ return /* @__PURE__ */ jsxs(Fragment, { children: [showMobileHeader && mobileHeader, desktopSidebar] });
1598
+ }
1599
+
1600
+ //#endregion
1601
+ //#region src/components/Header/index.tsx
1602
+ const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
1603
+ function isGroup(item) {
1604
+ return "children" in item && Array.isArray(item.children);
1605
+ }
1606
+ function DefaultLink({ href, className, onClick, children }) {
1607
+ return /* @__PURE__ */ jsx("a", {
1608
+ href,
1609
+ className,
1610
+ onClick,
1611
+ children
1612
+ });
1613
+ }
1614
+ function useOnClickOutside(ref, handler) {
1615
+ useEffect(() => {
1616
+ const listener = (event) => {
1617
+ if (!ref.current || ref.current.contains(event.target)) return;
1618
+ handler();
1619
+ };
1620
+ document.addEventListener("mousedown", listener);
1621
+ document.addEventListener("touchstart", listener);
1622
+ return () => {
1623
+ document.removeEventListener("mousedown", listener);
1624
+ document.removeEventListener("touchstart", listener);
1625
+ };
1626
+ }, [ref, handler]);
1627
+ }
1628
+ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = DefaultLink, user, establishments = [], establishmentsLabel = "Estabelecimento", onEstablishmentChange, actions, onUserClick, onLogout, logoutLabel = "Sair", menuLabel = "Menu", desktopOffsetLeft = 0, className }) {
1629
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
1630
+ const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
1631
+ const [openDropdownId, setOpenDropdownId] = useState(null);
1632
+ const dropdownRef = useRef(null);
1633
+ const userMenuRef = useRef(null);
1634
+ useOnClickOutside(dropdownRef, () => setOpenDropdownId(null));
1635
+ useOnClickOutside(userMenuRef, () => setIsUserMenuOpen(false));
1636
+ const closeMenus = () => {
1637
+ setIsMobileMenuOpen(false);
1638
+ setIsUserMenuOpen(false);
1639
+ setOpenDropdownId(null);
1640
+ };
1641
+ const isItemActive = (item) => {
1642
+ if (isGroup(item)) return item.children.some((child) => currentPath === child.href || child.href !== "/dashboard" && currentPath.startsWith(child.href));
1643
+ return currentPath === item.href;
1644
+ };
1645
+ const renderNavLink = (item, options = {}) => {
1646
+ const Icon = item.icon;
1647
+ const active = currentPath === item.href;
1648
+ if (item.disabled) return /* @__PURE__ */ jsxs("span", {
1649
+ className: cn$26("flex items-center gap-2 rounded-lg text-sm font-medium cursor-not-allowed", options.mobile ? "px-4 py-3" : "h-10 px-3", "text-[var(--dashboard-text-secondary,#6b7280)]/40"),
1650
+ title: "Em breve",
1651
+ children: [/* @__PURE__ */ jsx(Icon, {
1652
+ size: 18,
1653
+ className: "flex-shrink-0 opacity-40"
1654
+ }), /* @__PURE__ */ jsx("span", {
1655
+ className: "line-through opacity-50",
1656
+ children: item.label
1657
+ })]
1658
+ }, item.id);
1659
+ return /* @__PURE__ */ jsx(LinkComponent, {
1660
+ href: item.href,
1661
+ className: "block",
1662
+ onClick: closeMenus,
1663
+ children: /* @__PURE__ */ jsxs("div", {
1664
+ className: cn$26("flex items-center gap-2 rounded-lg text-sm font-medium transition-colors", options.mobile ? "px-4 py-3" : "h-10 px-3", active ? "bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
1665
+ "aria-current": active ? "page" : void 0,
1666
+ children: [/* @__PURE__ */ jsx(Icon, {
1667
+ size: 18,
1668
+ className: "flex-shrink-0"
1669
+ }), /* @__PURE__ */ jsx("span", { children: item.label })]
1670
+ })
1671
+ }, item.id);
1672
+ };
1673
+ const renderDropdown = (group, options = {}) => {
1674
+ const Icon = group.icon;
1675
+ const groupActive = isItemActive(group);
1676
+ const isOpen = openDropdownId === group.id;
1677
+ if (options.mobile) return /* @__PURE__ */ jsxs("div", {
1678
+ className: "space-y-1",
1679
+ children: [/* @__PURE__ */ jsxs("div", {
1680
+ className: "flex items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#6b7280)]",
1681
+ children: [/* @__PURE__ */ jsx(Icon, { size: 16 }), group.label]
1682
+ }), /* @__PURE__ */ jsx("div", {
1683
+ className: "ml-3 space-y-1 border-l border-[var(--dashboard-text-secondary,#6b7280)]/20 pl-3",
1684
+ children: group.children.map((child) => {
1685
+ const active = currentPath === child.href;
1686
+ return child.disabled ? /* @__PURE__ */ jsxs("span", {
1687
+ className: "flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm font-medium cursor-not-allowed text-[var(--dashboard-text-secondary,#6b7280)]/40",
1688
+ title: "Em breve",
1689
+ children: [/* @__PURE__ */ jsx(child.icon, {
1690
+ size: 16,
1691
+ className: "flex-shrink-0 opacity-40"
1692
+ }), /* @__PURE__ */ jsx("span", {
1693
+ className: "line-through opacity-50",
1694
+ children: child.label
1695
+ })]
1696
+ }, child.id) : /* @__PURE__ */ jsx(LinkComponent, {
1697
+ href: child.href,
1698
+ className: "block",
1699
+ onClick: closeMenus,
1700
+ children: /* @__PURE__ */ jsxs("div", {
1701
+ className: cn$26("flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm font-medium transition-colors", active ? "bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
1702
+ children: [/* @__PURE__ */ jsx(child.icon, {
1703
+ size: 16,
1704
+ className: "flex-shrink-0"
1705
+ }), /* @__PURE__ */ jsx("span", { children: child.label })]
1706
+ })
1707
+ }, child.id);
1708
+ })
1709
+ })]
1710
+ }, group.id);
1711
+ return /* @__PURE__ */ jsxs("div", {
1712
+ className: "relative",
1713
+ ref: isOpen ? dropdownRef : void 0,
1714
+ children: [/* @__PURE__ */ jsxs("button", {
1715
+ type: "button",
1716
+ onClick: () => setOpenDropdownId((prev) => prev === group.id ? null : group.id),
1717
+ className: cn$26("flex items-center gap-1.5 rounded-lg h-10 px-3 text-sm font-medium transition-colors", groupActive ? "bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
1718
+ "aria-expanded": isOpen,
1719
+ children: [
1720
+ /* @__PURE__ */ jsx(Icon, {
1721
+ size: 18,
1722
+ className: "flex-shrink-0"
1723
+ }),
1724
+ /* @__PURE__ */ jsx("span", { children: group.label }),
1725
+ /* @__PURE__ */ jsx(ChevronDown, {
1726
+ size: 14,
1727
+ className: cn$26("flex-shrink-0 transition-transform", isOpen && "rotate-180")
1728
+ })
1729
+ ]
1730
+ }), isOpen && /* @__PURE__ */ jsx("div", {
1731
+ className: "absolute left-1/2 top-[calc(100%+0.5rem)] z-50 w-max min-w-full max-w-[24rem] -translate-x-1/2 rounded-xl border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] p-1.5 shadow-xl",
1732
+ children: group.children.map((child) => {
1733
+ const active = currentPath === child.href;
1734
+ return child.disabled ? /* @__PURE__ */ jsxs("span", {
1735
+ className: "flex cursor-not-allowed items-center gap-2 rounded-lg px-3 py-2 text-sm text-[var(--dashboard-text-secondary,#6b7280)]/40",
1736
+ title: "Em breve",
1737
+ children: [/* @__PURE__ */ jsx(child.icon, {
1738
+ size: 16,
1739
+ className: "flex-shrink-0 opacity-40"
1740
+ }), /* @__PURE__ */ jsx("span", {
1741
+ className: "whitespace-nowrap line-through opacity-50",
1742
+ children: child.label
1743
+ })]
1744
+ }, child.id) : /* @__PURE__ */ jsx(LinkComponent, {
1745
+ href: child.href,
1746
+ className: "block",
1747
+ onClick: () => setOpenDropdownId(null),
1748
+ children: /* @__PURE__ */ jsxs("div", {
1749
+ className: cn$26("flex items-center gap-2 rounded-lg px-3 py-2 text-sm transition-colors", active ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)] font-semibold" : "text-[var(--dashboard-text-primary,#2d2d2d)]/80 hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
1750
+ children: [
1751
+ /* @__PURE__ */ jsx(child.icon, {
1752
+ size: 16,
1753
+ className: "flex-shrink-0"
1754
+ }),
1755
+ /* @__PURE__ */ jsx("span", {
1756
+ className: "whitespace-nowrap",
1757
+ children: child.label
1758
+ }),
1759
+ active && /* @__PURE__ */ jsx("span", { className: "ml-auto h-1.5 w-1.5 rounded-full bg-[var(--dashboard-primary,#37a501)]" })
1760
+ ]
1761
+ })
1762
+ }, child.id);
1763
+ })
1764
+ })]
1765
+ }, group.id);
1766
+ };
1767
+ const renderNavItem = (item, options = {}) => {
1768
+ if (isGroup(item)) return renderDropdown(item, options);
1769
+ return renderNavLink(item, options);
1770
+ };
1771
+ const desktopOffset = typeof desktopOffsetLeft === "number" ? `${desktopOffsetLeft}px` : desktopOffsetLeft;
1772
+ const userEstablishments = establishments.length > 0 ? establishments : user?.subtitle ? [{
1773
+ id: "current",
1774
+ label: user.subtitle,
1775
+ active: true
1776
+ }] : [];
1777
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1778
+ /* @__PURE__ */ jsx("div", {
1779
+ "aria-hidden": "true",
1780
+ className: "pointer-events-none fixed inset-x-0 top-0 z-30 h-2 bg-[var(--dashboard-background,#f2f2f2)]"
1781
+ }),
1782
+ /* @__PURE__ */ jsx("div", {
1783
+ "aria-hidden": "true",
1784
+ className: "pointer-events-none fixed left-[var(--dashboard-page-gutter,0px)] right-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-5 bg-[var(--dashboard-background,#f2f2f2)] transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
1785
+ style: { "--dashboard-header-offset-left": desktopOffset }
1786
+ }),
1787
+ /* @__PURE__ */ jsx("div", {
1788
+ "aria-hidden": "true",
1789
+ className: "pointer-events-none fixed left-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-14 w-5 bg-[var(--dashboard-background,#f2f2f2)] transition-[left] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
1790
+ style: { "--dashboard-header-offset-left": desktopOffset }
1791
+ }),
1792
+ /* @__PURE__ */ jsx("div", {
1793
+ "aria-hidden": "true",
1794
+ className: "pointer-events-none fixed right-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-14 w-5 bg-[var(--dashboard-background,#f2f2f2)] transition-[right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)]"
1795
+ }),
1796
+ /* @__PURE__ */ jsx("div", {
1797
+ "aria-hidden": "true",
1798
+ className: "pointer-events-none fixed left-[var(--dashboard-page-gutter,0px)] right-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-20 rounded-2xl bg-[var(--dashboard-background,#f2f2f2)] transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
1799
+ style: { "--dashboard-header-offset-left": desktopOffset }
1800
+ }),
1801
+ /* @__PURE__ */ jsxs("header", {
1802
+ className: cn$26("fixed left-[var(--dashboard-page-gutter,0px)] right-[var(--dashboard-page-gutter,0px)] top-2 z-40 rounded-2xl border border-[var(--dashboard-text-secondary,#6b7280)]/15 bg-[var(--dashboard-surface,#ffffff)] text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]", className),
1803
+ style: { "--dashboard-header-offset-left": desktopOffset },
1804
+ children: [/* @__PURE__ */ jsxs("div", {
1805
+ className: "flex h-20 items-center gap-4 px-4 sm:px-5 xl:grid xl:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]",
1806
+ children: [
1807
+ /* @__PURE__ */ jsx("div", {
1808
+ className: "flex min-w-0 flex-1 items-center gap-4 lg:flex-none xl:col-start-1 xl:justify-self-start",
1809
+ children: /* @__PURE__ */ jsx("div", {
1810
+ className: "flex min-w-0 items-center",
1811
+ children: logo
1812
+ })
1813
+ }),
1814
+ /* @__PURE__ */ jsx("nav", {
1815
+ className: "hidden min-w-0 items-center justify-center gap-1 xl:col-start-2 xl:flex",
1816
+ "aria-label": "Navegacao principal",
1817
+ children: menuItems.map((item) => renderNavItem(item))
1818
+ }),
1819
+ /* @__PURE__ */ jsxs("div", {
1820
+ className: "hidden items-center gap-3 xl:col-start-3 xl:flex xl:justify-self-end",
1821
+ children: [actions, user && /* @__PURE__ */ jsxs("div", {
1822
+ className: "relative w-[260px]",
1823
+ ref: userMenuRef,
1824
+ children: [/* @__PURE__ */ jsxs("button", {
1825
+ type: "button",
1826
+ onClick: () => setIsUserMenuOpen((open) => !open),
1827
+ className: "flex h-11 w-full items-center gap-3 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] px-3 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
1828
+ "aria-expanded": isUserMenuOpen,
1829
+ children: [
1830
+ /* @__PURE__ */ jsx("div", {
1831
+ className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
1832
+ children: /* @__PURE__ */ jsx(User, { size: 16 })
1833
+ }),
1834
+ /* @__PURE__ */ jsxs("div", {
1835
+ className: "min-w-0 flex-1",
1836
+ children: [user.subtitle && /* @__PURE__ */ jsx("p", {
1837
+ className: "truncate text-[11px] leading-4 text-[var(--dashboard-text-secondary,#6b7280)]",
1838
+ children: user.subtitle
1839
+ }), /* @__PURE__ */ jsx("p", {
1840
+ className: "truncate text-sm font-medium leading-4",
1841
+ children: user.name
1842
+ })]
1843
+ }),
1844
+ /* @__PURE__ */ jsx(ChevronDown, {
1845
+ size: 16,
1846
+ className: cn$26("ml-auto flex-shrink-0 transition-transform", isUserMenuOpen && "rotate-180")
1847
+ })
1848
+ ]
1849
+ }), isUserMenuOpen && /* @__PURE__ */ jsxs("div", {
1850
+ className: "absolute right-0 top-[calc(100%+0.5rem)] w-full rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] p-2 text-[var(--dashboard-text-primary,#2d2d2d)] shadow-xl",
1851
+ children: [
1852
+ /* @__PURE__ */ jsxs("button", {
1853
+ type: "button",
1854
+ onClick: () => {
1855
+ setIsUserMenuOpen(false);
1856
+ onUserClick?.();
1857
+ },
1858
+ className: "flex w-full items-center gap-3 rounded-lg px-3 py-3 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
1859
+ children: [/* @__PURE__ */ jsx("div", {
1860
+ className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
1861
+ children: /* @__PURE__ */ jsx(User, { size: 17 })
1862
+ }), /* @__PURE__ */ jsxs("div", {
1863
+ className: "min-w-0",
1864
+ children: [/* @__PURE__ */ jsx("p", {
1865
+ className: "truncate text-sm font-semibold",
1866
+ children: user.name
1867
+ }), /* @__PURE__ */ jsx("p", {
1868
+ className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
1869
+ children: user.email
1870
+ })]
1871
+ })]
1872
+ }),
1873
+ userEstablishments.length > 0 && /* @__PURE__ */ jsxs("div", {
1874
+ className: "mt-1 border-t border-[var(--dashboard-text-secondary,#6b7280)]/15 pt-2",
1875
+ children: [/* @__PURE__ */ jsx("p", {
1876
+ className: "px-3 pb-1 text-[11px] font-semibold uppercase tracking-wide text-[var(--dashboard-text-secondary,#6b7280)]",
1877
+ children: establishmentsLabel
1878
+ }), /* @__PURE__ */ jsx("div", {
1879
+ className: "space-y-1",
1880
+ children: userEstablishments.map((establishment) => {
1881
+ const isDisabled = establishment.disabled || !onEstablishmentChange || establishment.active;
1882
+ return /* @__PURE__ */ jsxs("button", {
1883
+ type: "button",
1884
+ onClick: () => {
1885
+ if (isDisabled) return;
1886
+ setIsUserMenuOpen(false);
1887
+ onEstablishmentChange?.(establishment.id);
1888
+ },
1889
+ disabled: isDisabled,
1890
+ className: cn$26("flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors", establishment.active ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-primary,#37a501)]/8", isDisabled ? establishment.active ? "cursor-default" : "cursor-not-allowed opacity-60" : "cursor-pointer"),
1891
+ children: [
1892
+ /* @__PURE__ */ jsx("div", {
1893
+ className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
1894
+ children: /* @__PURE__ */ jsx(Building2, { size: 15 })
1895
+ }),
1896
+ /* @__PURE__ */ jsxs("div", {
1897
+ className: "min-w-0 flex-1",
1898
+ children: [/* @__PURE__ */ jsx("p", {
1899
+ className: "truncate text-sm font-semibold",
1900
+ children: establishment.label
1901
+ }), establishment.description && /* @__PURE__ */ jsx("p", {
1902
+ className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
1903
+ children: establishment.description
1904
+ })]
1905
+ }),
1906
+ establishment.active && /* @__PURE__ */ jsx(Check, {
1907
+ size: 16,
1908
+ className: "flex-shrink-0"
1909
+ })
1910
+ ]
1911
+ }, establishment.id);
1912
+ })
1913
+ })]
1914
+ }),
1915
+ onLogout && /* @__PURE__ */ jsxs("button", {
1916
+ type: "button",
1917
+ onClick: () => {
1918
+ setIsUserMenuOpen(false);
1919
+ onLogout();
1920
+ },
1921
+ className: "mt-1 flex w-full items-center gap-3 rounded-lg px-3 py-3 text-sm font-medium transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
1922
+ children: [/* @__PURE__ */ jsx(LogOut, { size: 18 }), logoutLabel]
1923
+ })
1924
+ ]
1925
+ })]
1926
+ })]
1927
+ }),
1928
+ /* @__PURE__ */ jsx("button", {
1929
+ type: "button",
1930
+ onClick: () => setIsMobileMenuOpen((open) => !open),
1931
+ className: "inline-flex h-10 w-10 items-center justify-center rounded-lg bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)] transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/15 xl:hidden",
1932
+ "aria-label": menuLabel,
1933
+ "aria-expanded": isMobileMenuOpen,
1934
+ children: isMobileMenuOpen ? /* @__PURE__ */ jsx(X, { size: 22 }) : /* @__PURE__ */ jsx(Menu, { size: 22 })
1935
+ })
1936
+ ]
1937
+ }), /* @__PURE__ */ jsx("div", {
1938
+ className: cn$26("xl:hidden overflow-hidden border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] shadow-lg transition-[max-height] duration-200", isMobileMenuOpen ? "max-h-[calc(100vh-4rem)]" : "max-h-0"),
1939
+ children: /* @__PURE__ */ jsxs("div", {
1940
+ className: "max-h-[calc(100vh-4rem)] overflow-y-auto px-4 py-3",
1941
+ children: [/* @__PURE__ */ jsx("nav", {
1942
+ className: "space-y-1",
1943
+ "aria-label": "Navegacao principal",
1944
+ children: menuItems.map((item) => renderNavItem(item, { mobile: true }))
1945
+ }), (user || actions || onLogout) && /* @__PURE__ */ jsxs("div", {
1946
+ className: "mt-3 space-y-2 border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 pt-3",
1947
+ children: [
1948
+ actions,
1949
+ user && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("button", {
1950
+ type: "button",
1951
+ onClick: () => {
1952
+ closeMenus();
1953
+ onUserClick?.();
1954
+ },
1955
+ className: "flex w-full items-center gap-3 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] px-4 py-3 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
1956
+ children: [/* @__PURE__ */ jsx("div", {
1957
+ className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
1958
+ children: /* @__PURE__ */ jsx(User, { size: 17 })
1959
+ }), /* @__PURE__ */ jsxs("div", {
1960
+ className: "min-w-0",
1961
+ children: [
1962
+ user.subtitle && /* @__PURE__ */ jsx("p", {
1963
+ className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
1964
+ children: user.subtitle
1965
+ }),
1966
+ /* @__PURE__ */ jsx("p", {
1967
+ className: "truncate text-sm font-semibold",
1968
+ children: user.name
1969
+ }),
1970
+ /* @__PURE__ */ jsx("p", {
1971
+ className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
1972
+ children: user.email
1973
+ })
1974
+ ]
1975
+ })]
1976
+ }), userEstablishments.length > 0 && /* @__PURE__ */ jsxs("div", {
1977
+ className: "space-y-1",
1978
+ children: [/* @__PURE__ */ jsx("p", {
1979
+ className: "px-4 pt-2 text-[11px] font-semibold uppercase tracking-wide text-[var(--dashboard-text-secondary,#6b7280)]",
1980
+ children: establishmentsLabel
1981
+ }), userEstablishments.map((establishment) => {
1982
+ const isDisabled = establishment.disabled || !onEstablishmentChange || establishment.active;
1983
+ return /* @__PURE__ */ jsxs("button", {
1984
+ type: "button",
1985
+ onClick: () => {
1986
+ if (isDisabled) return;
1987
+ closeMenus();
1988
+ onEstablishmentChange?.(establishment.id);
1989
+ },
1990
+ disabled: isDisabled,
1991
+ className: cn$26("flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left transition-colors", establishment.active ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-primary,#37a501)]/8", isDisabled ? establishment.active ? "cursor-default" : "cursor-not-allowed opacity-60" : "cursor-pointer"),
1992
+ children: [
1993
+ /* @__PURE__ */ jsx("div", {
1994
+ className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
1995
+ children: /* @__PURE__ */ jsx(Building2, { size: 15 })
1996
+ }),
1997
+ /* @__PURE__ */ jsxs("div", {
1998
+ className: "min-w-0 flex-1",
1999
+ children: [/* @__PURE__ */ jsx("p", {
2000
+ className: "truncate text-sm font-semibold",
2001
+ children: establishment.label
2002
+ }), establishment.description && /* @__PURE__ */ jsx("p", {
2003
+ className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
2004
+ children: establishment.description
2005
+ })]
2006
+ }),
2007
+ establishment.active && /* @__PURE__ */ jsx(Check, {
2008
+ size: 16,
2009
+ className: "flex-shrink-0"
2010
+ })
2011
+ ]
2012
+ }, establishment.id);
2013
+ })]
2014
+ })] }),
2015
+ onLogout && /* @__PURE__ */ jsxs("button", {
2016
+ type: "button",
2017
+ onClick: () => {
2018
+ closeMenus();
2019
+ onLogout();
2020
+ },
2021
+ className: "flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm font-medium transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
2022
+ children: [/* @__PURE__ */ jsx(LogOut, { size: 18 }), logoutLabel]
2023
+ })
2024
+ ]
2025
+ })]
2026
+ })
2027
+ })]
2028
+ })
2029
+ ] });
1442
2030
  }
1443
2031
 
1444
2032
  //#endregion
1445
2033
  //#region src/components/ThemeSwitcher/index.tsx
1446
- const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
2034
+ const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
1447
2035
  const modes = [
1448
2036
  {
1449
2037
  value: "light",
@@ -1463,11 +2051,11 @@ const modes = [
1463
2051
  ];
1464
2052
  function ThemeSwitcher({ mode, onModeChange, className }) {
1465
2053
  return /* @__PURE__ */ jsx("div", {
1466
- className: cn$24("inline-flex items-center gap-1 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] p-1", className),
2054
+ className: cn$25("inline-flex items-center gap-1 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] p-1", className),
1467
2055
  children: modes.map(({ value, icon: Icon, label }) => /* @__PURE__ */ jsxs("button", {
1468
2056
  type: "button",
1469
2057
  onClick: () => onModeChange(value),
1470
- className: cn$24("flex cursor-pointer items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors", mode === value ? "bg-[var(--dashboard-surface,#ffffff)] text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
2058
+ className: cn$25("flex cursor-pointer items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors", mode === value ? "bg-[var(--dashboard-surface,#ffffff)] text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
1471
2059
  title: label,
1472
2060
  children: [/* @__PURE__ */ jsx(Icon, { size: 14 }), /* @__PURE__ */ jsx("span", { children: label })]
1473
2061
  }, value))
@@ -1476,7 +2064,7 @@ function ThemeSwitcher({ mode, onModeChange, className }) {
1476
2064
 
1477
2065
  //#endregion
1478
2066
  //#region src/components/KPICard/index.tsx
1479
- const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
2067
+ const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
1480
2068
  function formatValue(value, format) {
1481
2069
  switch (format) {
1482
2070
  case "currency": return new Intl.NumberFormat("pt-BR", {
@@ -1502,16 +2090,23 @@ const trendConfigs = {
1502
2090
  color: "text-[var(--dashboard-text-secondary,#64748B)] bg-[var(--dashboard-text-secondary,#64748B)]/8"
1503
2091
  }
1504
2092
  };
1505
- function KPICard({ title, value, variation, trend, format = "number", benchmark, isLoading, className }) {
2093
+ function KPICard({ title, value, variation, trend, format = "number", benchmark, icon, isLoading, className }) {
1506
2094
  if (isLoading) return /* @__PURE__ */ jsx(KPICardSkeleton, { className });
1507
2095
  const trendConfig = trendConfigs[trend];
1508
2096
  return /* @__PURE__ */ jsxs("div", {
1509
- className: cn$23("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),
2097
+ className: cn$24("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),
1510
2098
  children: [/* @__PURE__ */ jsxs("div", {
1511
- className: "flex justify-between items-start mb-4",
1512
- children: [/* @__PURE__ */ jsx("h3", {
1513
- className: "text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#64748B)] whitespace-nowrap",
1514
- children: title
2099
+ className: "flex justify-between items-start mb-4 gap-2",
2100
+ children: [/* @__PURE__ */ jsxs("div", {
2101
+ className: "flex items-center gap-2 min-w-0",
2102
+ children: [icon && /* @__PURE__ */ jsx("span", {
2103
+ className: "shrink-0 text-[var(--dashboard-text-secondary,#64748B)]",
2104
+ "aria-hidden": "true",
2105
+ children: icon
2106
+ }), /* @__PURE__ */ jsx("h3", {
2107
+ className: "text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#64748B)] whitespace-nowrap truncate",
2108
+ children: title
2109
+ })]
1515
2110
  }), benchmark && /* @__PURE__ */ jsx("span", {
1516
2111
  className: "text-xs text-[var(--dashboard-text-secondary,#64748B)]/50 ml-2 whitespace-nowrap flex-shrink-0",
1517
2112
  title: "Benchmark de referência",
@@ -1523,7 +2118,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
1523
2118
  className: "text-3xl font-bold text-[var(--dashboard-text-primary,#0F172A)] whitespace-nowrap tracking-tight",
1524
2119
  children: formatValue(value, format)
1525
2120
  }), /* @__PURE__ */ jsxs("div", {
1526
- className: cn$23("inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
2121
+ className: cn$24("inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
1527
2122
  children: [/* @__PURE__ */ jsx("span", {
1528
2123
  className: "text-sm",
1529
2124
  children: trendConfig.icon
@@ -1537,7 +2132,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
1537
2132
  }
1538
2133
  function KPICardSkeleton({ className }) {
1539
2134
  return /* @__PURE__ */ jsxs("div", {
1540
- className: cn$23("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),
2135
+ className: cn$24("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),
1541
2136
  children: [/* @__PURE__ */ jsx("div", { className: "h-3 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-2/3 mb-4" }), /* @__PURE__ */ jsxs("div", {
1542
2137
  className: "flex items-end gap-3 flex-1",
1543
2138
  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" })]
@@ -1547,51 +2142,63 @@ function KPICardSkeleton({ className }) {
1547
2142
 
1548
2143
  //#endregion
1549
2144
  //#region src/components/PageLayout/index.tsx
1550
- const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
1551
- function PageLayout({ title, description, headerActions, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
2145
+ const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
2146
+ function PageLayout({ title, description, headerActions, appHeader, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
1552
2147
  const marginLeft = sidebar ? sidebarCollapsed ? `max(0px, ${sidebarCollapsedWidth}px)` : `max(0px, ${sidebarWidth}px)` : "0px";
2148
+ const mainTopPadding = appHeader ? "pt-24" : sidebar ? "pt-16 xl:pt-0" : "pt-0";
2149
+ const layoutContainer = "mx-[var(--dashboard-page-gutter)]";
1553
2150
  return /* @__PURE__ */ jsxs("div", {
1554
- className: cn$22("min-h-screen bg-[var(--dashboard-background,#f2f2f2)]", className),
1555
- children: [sidebar, /* @__PURE__ */ jsxs("main", {
1556
- className: cn$22("pt-16 xl:pt-0", !sidebar && "pt-0"),
1557
- style: {
1558
- marginLeft,
1559
- transition: "margin-left 400ms cubic-bezier(0.4, 0, 0.2, 1)"
1560
- },
1561
- children: [
1562
- /* @__PURE__ */ jsx("style", { children: `
2151
+ className: cn$23("min-h-screen bg-[var(--dashboard-background,#f2f2f2)] [--dashboard-page-gutter:1.5rem] sm:[--dashboard-page-gutter:2rem] lg:[--dashboard-page-gutter:2.5rem] xl:[--dashboard-page-gutter:3rem]", className),
2152
+ children: [
2153
+ appHeader,
2154
+ sidebar,
2155
+ /* @__PURE__ */ jsxs("main", {
2156
+ className: mainTopPadding,
2157
+ style: {
2158
+ marginLeft,
2159
+ transition: "margin-left 400ms cubic-bezier(0.4, 0, 0.2, 1)"
2160
+ },
2161
+ children: [
2162
+ /* @__PURE__ */ jsx("style", { children: `
1563
2163
  @media (max-width: 1279px) {
1564
2164
  main {
1565
2165
  margin-left: 0 !important;
1566
2166
  }
1567
2167
  }
1568
2168
  ` }),
1569
- /* @__PURE__ */ jsxs("div", {
1570
- className: "border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 px-6 py-4 bg-[var(--dashboard-surface,#ffffff)]",
1571
- children: [/* @__PURE__ */ jsxs("div", {
1572
- className: "mb-4",
1573
- children: [/* @__PURE__ */ jsx("h1", {
1574
- className: "text-2xl font-bold text-[var(--dashboard-text-primary,#2d2d2d)]",
1575
- children: title
1576
- }), description && /* @__PURE__ */ jsx("p", {
1577
- className: "text-sm text-[var(--dashboard-text-secondary,#6b7280)] mt-1",
1578
- children: description
1579
- })]
1580
- }), headerActions && /* @__PURE__ */ jsx("div", { children: headerActions })]
1581
- }),
1582
- /* @__PURE__ */ jsx("div", {
1583
- className: contentPadding ? "p-6" : "",
1584
- children
1585
- })
1586
- ]
1587
- })]
2169
+ /* @__PURE__ */ jsx("div", {
2170
+ className: cn$23(layoutContainer, "-mt-10 rounded-b-2xl border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] px-7 pb-7 pt-16 sm:px-10 lg:px-12"),
2171
+ children: /* @__PURE__ */ jsxs("div", {
2172
+ className: "flex flex-col gap-5 lg:flex-row lg:items-end lg:justify-between",
2173
+ children: [/* @__PURE__ */ jsxs("div", {
2174
+ className: "min-w-0",
2175
+ children: [/* @__PURE__ */ jsx("h1", {
2176
+ className: "text-2xl font-bold text-[var(--dashboard-text-primary,#2d2d2d)] sm:text-3xl",
2177
+ children: title
2178
+ }), description && /* @__PURE__ */ jsx("p", {
2179
+ className: "mt-2 text-sm font-medium text-[var(--dashboard-text-secondary,#6b7280)] sm:text-base",
2180
+ children: description
2181
+ })]
2182
+ }), headerActions && /* @__PURE__ */ jsx("div", {
2183
+ className: "flex max-w-full justify-start lg:justify-end",
2184
+ children: headerActions
2185
+ })]
2186
+ })
2187
+ }),
2188
+ /* @__PURE__ */ jsx("div", {
2189
+ className: contentPadding ? cn$23(layoutContainer, "py-6") : "",
2190
+ children
2191
+ })
2192
+ ]
2193
+ })
2194
+ ]
1588
2195
  });
1589
2196
  }
1590
2197
 
1591
2198
  //#endregion
1592
2199
  //#region src/components/ComparisonLineChart/index.tsx
1593
2200
  Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
1594
- const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
2201
+ const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
1595
2202
  function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, currentPeriodLabel = "Período atual", previousPeriodLabel = "Período anterior", title, color, height = 300, className }) {
1596
2203
  const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
1597
2204
  const data = {
@@ -1685,7 +2292,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
1685
2292
  }
1686
2293
  };
1687
2294
  return /* @__PURE__ */ jsxs("div", {
1688
- className: cn$21("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
2295
+ className: cn$22("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
1689
2296
  children: [title && /* @__PURE__ */ jsx("h3", {
1690
2297
  className: "text-base font-semibold mb-4 text-[var(--dashboard-text-primary,#2d2d2d)]",
1691
2298
  children: title
@@ -1702,7 +2309,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
1702
2309
  //#endregion
1703
2310
  //#region src/components/HorizontalBarChart/index.tsx
1704
2311
  Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
1705
- const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
2312
+ const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
1706
2313
  function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", className }) {
1707
2314
  const [activeTab, setActiveTab] = useState((tabs ? tabs.map((t) => t.id) : Object.keys(datasets))[0]);
1708
2315
  const [isMobile, setIsMobile] = useState(false);
@@ -1777,7 +2384,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
1777
2384
  }
1778
2385
  };
1779
2386
  return /* @__PURE__ */ jsxs("div", {
1780
- className: cn$20("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),
2387
+ className: cn$21("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),
1781
2388
  children: [
1782
2389
  title && /* @__PURE__ */ jsxs("div", {
1783
2390
  className: "flex items-center gap-2 mb-4",
@@ -1790,7 +2397,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
1790
2397
  className: "flex gap-2 mb-4 flex-wrap",
1791
2398
  children: tabs.map((tab) => /* @__PURE__ */ jsx("button", {
1792
2399
  onClick: () => setActiveTab(tab.id),
1793
- className: cn$20("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"),
2400
+ className: cn$21("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"),
1794
2401
  children: tab.label
1795
2402
  }, tab.id))
1796
2403
  }),
@@ -1829,7 +2436,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
1829
2436
  //#endregion
1830
2437
  //#region src/components/VerticalBarChart/index.tsx
1831
2438
  Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
1832
- const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
2439
+ const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
1833
2440
  function VerticalBarChart({ labels, data: values, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", labelMaxChars = 3, className }) {
1834
2441
  const maxValue = Math.max(...values);
1835
2442
  const bestLabel = labels[values.indexOf(maxValue)];
@@ -1892,7 +2499,7 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
1892
2499
  }
1893
2500
  };
1894
2501
  return /* @__PURE__ */ jsxs("div", {
1895
- className: cn$19("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),
2502
+ className: cn$20("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),
1896
2503
  children: [
1897
2504
  title && /* @__PURE__ */ jsxs("div", {
1898
2505
  className: "flex items-center gap-2 mb-4",
@@ -1948,7 +2555,7 @@ const DEFAULT_COLORS = [
1948
2555
  "#EA580C",
1949
2556
  "#4F46E5"
1950
2557
  ];
1951
- const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
2558
+ const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
1952
2559
  function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, showLegend = true, formatValue, cutout = 65, height = 240, className }) {
1953
2560
  const total = items.reduce((sum, item) => sum + item.value, 0);
1954
2561
  const format = formatValue || ((v) => String(v));
@@ -1988,7 +2595,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
1988
2595
  }
1989
2596
  };
1990
2597
  return /* @__PURE__ */ jsxs("div", {
1991
- className: cn$18("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
2598
+ className: cn$19("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
1992
2599
  children: [title && /* @__PURE__ */ jsxs("div", {
1993
2600
  className: "flex items-center gap-2 mb-4",
1994
2601
  children: [titleIcon, /* @__PURE__ */ jsx("h3", {
@@ -1996,7 +2603,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
1996
2603
  children: title
1997
2604
  })]
1998
2605
  }), /* @__PURE__ */ jsxs("div", {
1999
- className: cn$18("flex items-center", showLegend ? "gap-6" : "justify-center"),
2606
+ className: cn$19("flex items-center", showLegend ? "gap-6" : "justify-center"),
2000
2607
  children: [/* @__PURE__ */ jsxs("div", {
2001
2608
  className: "relative flex-shrink-0",
2002
2609
  style: {
@@ -2049,7 +2656,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
2049
2656
 
2050
2657
  //#endregion
2051
2658
  //#region src/components/ProgressBarList/index.tsx
2052
- const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
2659
+ const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
2053
2660
  function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, sortByValue = true, formatValue, className }) {
2054
2661
  const sortedItems = sortByValue ? [...items].sort((a, b) => b.value - a.value) : items;
2055
2662
  const maxValue = Math.max(...items.map((i) => i.value));
@@ -2058,7 +2665,7 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
2058
2665
  const defaultFormat = (v) => `${v} ${v === 1 ? singular : valueLabel}`;
2059
2666
  const fmt = formatValue || defaultFormat;
2060
2667
  return /* @__PURE__ */ jsxs("div", {
2061
- 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),
2668
+ className: cn$18("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),
2062
2669
  children: [title && /* @__PURE__ */ jsxs("div", {
2063
2670
  className: "flex items-center gap-2 mb-4",
2064
2671
  children: [titleIcon, /* @__PURE__ */ jsx("h3", {
@@ -2107,19 +2714,237 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
2107
2714
  //#endregion
2108
2715
  //#region src/components/MetricPanel/index.tsx
2109
2716
  Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
2110
- const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
2111
- function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, secondaryColor, onActionClick, actionLabel, isLoading = false, className }) {
2717
+ const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
2718
+ function formatMetricValue(value, format) {
2719
+ switch (format) {
2720
+ case "currency": return new Intl.NumberFormat("pt-BR", {
2721
+ style: "currency",
2722
+ currency: "BRL"
2723
+ }).format(value);
2724
+ case "percentage": return `${value.toFixed(2)}%`;
2725
+ case "rating": return value.toFixed(2);
2726
+ default: return new Intl.NumberFormat("pt-BR").format(Math.round(value));
2727
+ }
2728
+ }
2729
+ function calculateVariation(current, previous) {
2730
+ if (previous === 0) return 0;
2731
+ return (current - previous) / previous * 100;
2732
+ }
2733
+ function escapeHtml(value) {
2734
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
2735
+ }
2736
+ function getTooltipDateInfo(label) {
2737
+ const dayNames = [
2738
+ "Domingo",
2739
+ "Segunda",
2740
+ "Terca",
2741
+ "Quarta",
2742
+ "Quinta",
2743
+ "Sexta",
2744
+ "Sabado"
2745
+ ];
2746
+ const [day, month] = label.split("/").map(Number);
2747
+ if (!day || !month) return {
2748
+ dayName: "",
2749
+ previousDate: ""
2750
+ };
2751
+ const date = new Date((/* @__PURE__ */ new Date()).getFullYear(), month - 1, day);
2752
+ const previousDate = new Date(date);
2753
+ previousDate.setDate(previousDate.getDate() - 7);
2754
+ return {
2755
+ dayName: dayNames[date.getDay()],
2756
+ previousDate: `${String(previousDate.getDate()).padStart(2, "0")}/${String(previousDate.getMonth() + 1).padStart(2, "0")}`
2757
+ };
2758
+ }
2759
+ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, secondaryColor, onActionClick, actionLabel, tooltipConfig, isLoading = false, className }) {
2112
2760
  const [selectedMetricKey, setSelectedMetricKey] = useState(metrics[0]?.key);
2113
2761
  const [isMobile, setIsMobile] = useState(false);
2762
+ const hideTooltipTimeoutRef = useRef(null);
2763
+ const isTooltipHoveredRef = useRef(false);
2114
2764
  useEffect(() => {
2115
2765
  const check = () => setIsMobile(window.innerWidth < 768);
2116
2766
  check();
2117
2767
  window.addEventListener("resize", check);
2118
- return () => window.removeEventListener("resize", check);
2768
+ return () => {
2769
+ window.removeEventListener("resize", check);
2770
+ if (hideTooltipTimeoutRef.current) clearTimeout(hideTooltipTimeoutRef.current);
2771
+ };
2119
2772
  }, []);
2120
2773
  const currentMetric = metrics.find((m) => m.key === selectedMetricKey) || metrics[0];
2121
2774
  const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
2122
2775
  const secColor = secondaryColor || `${primaryColor}66`;
2776
+ const renderExternalTooltip = (context) => {
2777
+ const { chart, tooltip } = context;
2778
+ const parent = chart.canvas.parentElement;
2779
+ if (!parent) return;
2780
+ let tooltipEl = parent.querySelector(":scope > .metric-panel-chart-tooltip");
2781
+ if (!tooltipEl) {
2782
+ tooltipEl = document.createElement("div");
2783
+ tooltipEl.className = "metric-panel-chart-tooltip";
2784
+ tooltipEl.style.position = "absolute";
2785
+ tooltipEl.style.pointerEvents = "auto";
2786
+ tooltipEl.style.transition = "opacity 0.2s ease";
2787
+ tooltipEl.style.zIndex = "100";
2788
+ tooltipEl.style.opacity = "0";
2789
+ const createdTooltipEl = tooltipEl;
2790
+ createdTooltipEl.addEventListener("mouseenter", () => {
2791
+ isTooltipHoveredRef.current = true;
2792
+ if (hideTooltipTimeoutRef.current) {
2793
+ clearTimeout(hideTooltipTimeoutRef.current);
2794
+ hideTooltipTimeoutRef.current = null;
2795
+ }
2796
+ });
2797
+ createdTooltipEl.addEventListener("mouseleave", () => {
2798
+ isTooltipHoveredRef.current = false;
2799
+ createdTooltipEl.style.opacity = "0";
2800
+ });
2801
+ parent.appendChild(createdTooltipEl);
2802
+ }
2803
+ if (hideTooltipTimeoutRef.current) {
2804
+ clearTimeout(hideTooltipTimeoutRef.current);
2805
+ hideTooltipTimeoutRef.current = null;
2806
+ }
2807
+ if (tooltip.opacity === 0) {
2808
+ hideTooltipTimeoutRef.current = setTimeout(() => {
2809
+ if (!isTooltipHoveredRef.current && tooltipEl) tooltipEl.style.opacity = "0";
2810
+ }, 300);
2811
+ return;
2812
+ }
2813
+ const dataPoint = tooltip.dataPoints?.find((point) => point.datasetIndex === 0);
2814
+ if (!dataPoint) {
2815
+ tooltipEl.style.opacity = "0";
2816
+ return;
2817
+ }
2818
+ const dataIndex = dataPoint.dataIndex;
2819
+ const label = dataPoint.label;
2820
+ const currentValue = typeof dataPoint.parsed.y === "number" ? dataPoint.parsed.y : 0;
2821
+ const previousValue = chartData.metrics[currentMetric.key]?.previousPeriod[dataIndex] || 0;
2822
+ const variation = calculateVariation(currentValue, previousValue);
2823
+ const formattedValue = formatMetricValue(currentValue, currentMetric.format);
2824
+ const formattedPrevious = formatMetricValue(previousValue, currentMetric.format);
2825
+ const { dayName, previousDate } = getTooltipDateInfo(label);
2826
+ const metricUnit = currentMetric.unit || "";
2827
+ const isButtonDisabled = currentValue === 0;
2828
+ const safeLabel = escapeHtml(label);
2829
+ const safeDayName = escapeHtml(dayName);
2830
+ const safePreviousDate = escapeHtml(previousDate);
2831
+ const safeMetricUnit = escapeHtml(metricUnit);
2832
+ const variationSign = variation > 0 ? "+" : "";
2833
+ const variationIcon = variation >= 0 ? "▲" : "▼";
2834
+ const variationColor = variation >= 0 ? "var(--dashboard-status-success,#10B981)" : "var(--dashboard-status-danger,#EF4444)";
2835
+ if (tooltipConfig?.customContent) tooltipEl.innerHTML = tooltipConfig.customContent({
2836
+ value: currentValue,
2837
+ previousValue,
2838
+ variation,
2839
+ date: label,
2840
+ dayName,
2841
+ previousDate,
2842
+ formattedValue,
2843
+ formattedPrevious,
2844
+ metricUnit
2845
+ });
2846
+ else tooltipEl.innerHTML = `
2847
+ <div style="
2848
+ background: var(--dashboard-surface,#ffffff);
2849
+ border-radius: 8px;
2850
+ box-shadow: 0 8px 20px rgba(15, 23, 42, 0.14);
2851
+ border: 1px solid rgba(93, 114, 128, 0.2);
2852
+ color: var(--dashboard-text-primary,#2d2d2d);
2853
+ padding: 12px;
2854
+ min-width: 220px;
2855
+ max-width: 250px;
2856
+ font-family: inherit;
2857
+ ">
2858
+ <div style="
2859
+ font-size: 11px;
2860
+ font-weight: 500;
2861
+ color: var(--dashboard-text-secondary,#6b7280);
2862
+ margin-bottom: 8px;
2863
+ ">
2864
+ ${safeDayName ? `${safeDayName} ` : ""}${safeLabel}
2865
+ </div>
2866
+ <div style="
2867
+ display: flex;
2868
+ align-items: baseline;
2869
+ gap: 6px;
2870
+ margin-bottom: 10px;
2871
+ ">
2872
+ <div style="
2873
+ font-size: 22px;
2874
+ font-weight: 700;
2875
+ color: ${primaryColor};
2876
+ line-height: 1;
2877
+ ">
2878
+ ${escapeHtml(formattedValue)}${safeMetricUnit ? ` ${safeMetricUnit}` : ""}
2879
+ </div>
2880
+ <div style="
2881
+ display: flex;
2882
+ align-items: center;
2883
+ gap: 3px;
2884
+ color: ${variationColor};
2885
+ font-size: 13px;
2886
+ font-weight: 600;
2887
+ ">
2888
+ <span style="font-size: 10px;">${variationIcon}</span>
2889
+ <span>${variationSign}${Math.abs(variation).toFixed(2)}%</span>
2890
+ </div>
2891
+ </div>
2892
+ <div style="
2893
+ font-size: 11px;
2894
+ color: var(--dashboard-text-secondary,#6b7280);
2895
+ line-height: 1.35;
2896
+ margin-bottom: ${tooltipConfig?.showButton ? "10px" : "0"};
2897
+ padding-bottom: ${tooltipConfig?.showButton ? "10px" : "0"};
2898
+ border-bottom: ${tooltipConfig?.showButton ? "1px solid rgba(93, 114, 128, 0.2)" : "none"};
2899
+ ">
2900
+ em relacao aos <strong style="color: var(--dashboard-text-primary,#2d2d2d);">${escapeHtml(formattedPrevious)}${safeMetricUnit ? ` ${safeMetricUnit}` : ""}</strong>${safePreviousDate ? ` do dia <strong style="color: var(--dashboard-text-primary,#2d2d2d);">${safePreviousDate}</strong>` : ""}
2901
+ </div>
2902
+ ${tooltipConfig?.showButton && tooltipConfig.buttonLabel ? `
2903
+ <button type="button" data-tooltip-action ${isButtonDisabled ? "disabled" : ""} style="
2904
+ width: 100%;
2905
+ padding: 8px 12px;
2906
+ background: ${isButtonDisabled ? "rgba(93, 114, 128, 0.08)" : "var(--dashboard-surface,#ffffff)"};
2907
+ color: ${isButtonDisabled ? "var(--dashboard-text-secondary,#6b7280)" : primaryColor};
2908
+ border: 2px solid ${isButtonDisabled ? "rgba(93, 114, 128, 0.2)" : primaryColor};
2909
+ border-radius: 6px;
2910
+ font-size: 13px;
2911
+ font-weight: 600;
2912
+ font-family: inherit;
2913
+ cursor: ${isButtonDisabled ? "not-allowed" : "pointer"};
2914
+ opacity: ${isButtonDisabled ? "0.65" : "1"};
2915
+ ">
2916
+ ${escapeHtml(tooltipConfig.buttonLabel)}
2917
+ </button>
2918
+ ` : ""}
2919
+ </div>
2920
+ `;
2921
+ const actionButton = tooltipEl.querySelector("[data-tooltip-action]");
2922
+ if (actionButton && !isButtonDisabled) {
2923
+ actionButton.onclick = () => tooltipConfig?.onButtonClick?.(dataIndex, label);
2924
+ actionButton.onmouseenter = () => {
2925
+ actionButton.style.background = primaryColor;
2926
+ actionButton.style.color = "#ffffff";
2927
+ };
2928
+ actionButton.onmouseleave = () => {
2929
+ actionButton.style.background = "var(--dashboard-surface,#ffffff)";
2930
+ actionButton.style.color = primaryColor;
2931
+ };
2932
+ }
2933
+ const tooltipWidth = 250;
2934
+ const tooltipHeight = tooltipConfig?.showButton ? 180 : 140;
2935
+ const offsetX = 15;
2936
+ const centerY = Math.max(0, (chart.height - tooltipHeight) / 2);
2937
+ const isNearRightEdge = tooltip.caretX > chart.width - tooltipWidth - offsetX;
2938
+ tooltipEl.style.opacity = "1";
2939
+ tooltipEl.style.top = `${centerY}px`;
2940
+ if (isNearRightEdge) {
2941
+ tooltipEl.style.left = "auto";
2942
+ tooltipEl.style.right = `${chart.width - tooltip.caretX + offsetX}px`;
2943
+ } else {
2944
+ tooltipEl.style.left = `${tooltip.caretX + offsetX}px`;
2945
+ tooltipEl.style.right = "auto";
2946
+ }
2947
+ };
2123
2948
  const data = {
2124
2949
  labels: chartData.labels,
2125
2950
  datasets: [{
@@ -2171,14 +2996,18 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
2171
2996
  color: "var(--dashboard-text-secondary, #6b7280)"
2172
2997
  }
2173
2998
  },
2174
- tooltip: {
2999
+ tooltip: { ...tooltipConfig ? {
3000
+ enabled: false,
3001
+ position: "nearest",
3002
+ external: tooltipConfig.enabled ? renderExternalTooltip : void 0
3003
+ } : {
2175
3004
  backgroundColor: "rgba(45, 45, 45, 0.95)",
2176
3005
  titleColor: "#fff",
2177
3006
  bodyColor: "#fff",
2178
3007
  borderColor: primaryColor,
2179
3008
  borderWidth: 1,
2180
3009
  padding: 12
2181
- }
3010
+ } }
2182
3011
  },
2183
3012
  scales: {
2184
3013
  x: {
@@ -2205,7 +3034,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
2205
3034
  }
2206
3035
  };
2207
3036
  return /* @__PURE__ */ jsxs("div", {
2208
- className: cn$16("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
3037
+ className: cn$17("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
2209
3038
  style: { overflow: "visible" },
2210
3039
  children: [
2211
3040
  /* @__PURE__ */ jsxs("div", {
@@ -2246,7 +3075,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
2246
3075
  const Icon = metric.icon;
2247
3076
  return /* @__PURE__ */ jsxs("button", {
2248
3077
  onClick: () => setSelectedMetricKey(metric.key),
2249
- className: cn$16("flex items-center gap-2 px-4 md:px-6 py-2 rounded-full text-sm font-medium transition-colors cursor-pointer", selectedMetricKey === metric.key ? "bg-[var(--dashboard-surface,#ffffff)] border-2 text-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-surface,#ffffff)] border border-[var(--dashboard-text-secondary,#6b7280)]/30 text-[var(--dashboard-text-secondary,#6b7280)] hover:border-[var(--dashboard-text-secondary,#6b7280)]/50"),
3078
+ className: cn$17("flex items-center gap-2 px-4 md:px-6 py-2 rounded-full text-sm font-medium transition-colors cursor-pointer", selectedMetricKey === metric.key ? "bg-[var(--dashboard-surface,#ffffff)] border-2 text-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-surface,#ffffff)] border border-[var(--dashboard-text-secondary,#6b7280)]/30 text-[var(--dashboard-text-secondary,#6b7280)] hover:border-[var(--dashboard-text-secondary,#6b7280)]/50"),
2250
3079
  style: selectedMetricKey === metric.key ? {
2251
3080
  borderColor: primaryColor,
2252
3081
  color: primaryColor
@@ -2294,10 +3123,10 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
2294
3123
 
2295
3124
  //#endregion
2296
3125
  //#region src/components/FilterBar/index.tsx
2297
- const cn$15 = (...classes) => classes.filter(Boolean).join(" ");
3126
+ const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
2298
3127
  function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...", children, actions, className }) {
2299
3128
  return /* @__PURE__ */ jsxs("div", {
2300
- className: cn$15("flex flex-col gap-3 sm:flex-row sm:items-center sm:flex-wrap", className),
3129
+ className: cn$16("flex flex-col gap-3 sm:flex-row sm:items-center sm:flex-wrap", className),
2301
3130
  children: [
2302
3131
  onSearchChange !== void 0 && /* @__PURE__ */ jsx("div", {
2303
3132
  className: "flex-1 min-w-[200px]",
@@ -2337,7 +3166,7 @@ function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...
2337
3166
 
2338
3167
  //#endregion
2339
3168
  //#region src/components/Checkbox/index.tsx
2340
- const cn$14 = (...classes) => classes.filter(Boolean).join(" ");
3169
+ const cn$15 = (...classes) => classes.filter(Boolean).join(" ");
2341
3170
  const sizeConfig = {
2342
3171
  sm: {
2343
3172
  box: 16,
@@ -2385,7 +3214,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
2385
3214
  const resolvedColor = primaryColor || "var(--dashboard-primary, #37A501)";
2386
3215
  return /* @__PURE__ */ jsxs("label", {
2387
3216
  htmlFor: inputId,
2388
- className: cn$14("inline-flex items-center cursor-pointer select-none", disabled && "opacity-50 cursor-not-allowed", className),
3217
+ className: cn$15("inline-flex items-center cursor-pointer select-none", disabled && "opacity-50 cursor-not-allowed", className),
2389
3218
  style: { gap: cfg.gap },
2390
3219
  children: [
2391
3220
  /* @__PURE__ */ jsx("input", {
@@ -2436,7 +3265,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
2436
3265
 
2437
3266
  //#endregion
2438
3267
  //#region src/components/AuthLayout/index.tsx
2439
- const cn$13 = (...classes) => classes.filter(Boolean).join(" ");
3268
+ const cn$14 = (...classes) => classes.filter(Boolean).join(" ");
2440
3269
  /** Resolves a CSS color value (including var() references) to a computed hex/rgb string */
2441
3270
  function useResolvedColor(cssValue) {
2442
3271
  const [resolved, setResolved] = useState(cssValue);
@@ -2603,7 +3432,7 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
2603
3432
  if (link.onClick) return /* @__PURE__ */ jsx("button", {
2604
3433
  type: "button",
2605
3434
  onClick: link.onClick,
2606
- className: cn$13("bg-transparent border-none cursor-pointer hover:opacity-80 text-sm font-semibold p-0 transition-colors", extraClass),
3435
+ className: cn$14("bg-transparent border-none cursor-pointer hover:opacity-80 text-sm font-semibold p-0 transition-colors", extraClass),
2607
3436
  style,
2608
3437
  children: link.label
2609
3438
  });
@@ -2611,13 +3440,13 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
2611
3440
  href: link.href,
2612
3441
  target: link.target,
2613
3442
  rel: link.target === "_blank" ? "noopener noreferrer" : void 0,
2614
- className: cn$13("hover:opacity-80 text-sm font-semibold transition-colors", extraClass),
3443
+ className: cn$14("hover:opacity-80 text-sm font-semibold transition-colors", extraClass),
2615
3444
  style,
2616
3445
  children: link.label
2617
3446
  });
2618
3447
  }
2619
3448
  return /* @__PURE__ */ jsxs("div", {
2620
- className: cn$13("fixed inset-0 flex select-none overflow-hidden", className),
3449
+ className: cn$14("fixed inset-0 flex select-none overflow-hidden", className),
2621
3450
  style: bgCss,
2622
3451
  children: [
2623
3452
  branding && branding.logos.length > 0 && /* @__PURE__ */ jsx("div", {
@@ -2900,7 +3729,7 @@ function CodeInput({ length = 6, value, onChange, disabled = false, error = fals
2900
3729
 
2901
3730
  //#endregion
2902
3731
  //#region src/components/Skeleton/index.tsx
2903
- const cn$12 = (...classes) => classes.filter(Boolean).join(" ");
3732
+ const cn$13 = (...classes) => classes.filter(Boolean).join(" ");
2904
3733
  function Skeleton({ variant = "text", width, height, animate = true, className, lines = 1 }) {
2905
3734
  const baseStyles = "bg-[var(--dashboard-text-secondary,#6b7280)]/10 relative overflow-hidden";
2906
3735
  const shimmerStyles = animate ? "after:absolute after:inset-0 after:bg-gradient-to-r after:from-transparent after:via-[var(--dashboard-text-secondary,#6b7280)]/5 after:to-transparent dashboard-animate-shimmer after:content-['']" : "";
@@ -2919,9 +3748,9 @@ function Skeleton({ variant = "text", width, height, animate = true, className,
2919
3748
  }
2920
3749
  if (variant === "card" && !height) style.height = "120px";
2921
3750
  if (variant === "text" && lines > 1) return /* @__PURE__ */ jsx("div", {
2922
- className: cn$12("flex flex-col gap-2", className),
3751
+ className: cn$13("flex flex-col gap-2", className),
2923
3752
  children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx("div", {
2924
- className: cn$12(baseStyles, shimmerStyles, variantStyles.text),
3753
+ className: cn$13(baseStyles, shimmerStyles, variantStyles.text),
2925
3754
  style: {
2926
3755
  ...style,
2927
3756
  width: i === lines - 1 ? "75%" : style.width || "100%"
@@ -2929,14 +3758,14 @@ function Skeleton({ variant = "text", width, height, animate = true, className,
2929
3758
  }, i))
2930
3759
  });
2931
3760
  return /* @__PURE__ */ jsx("div", {
2932
- className: cn$12(baseStyles, shimmerStyles, variantStyles[variant], className),
3761
+ className: cn$13(baseStyles, shimmerStyles, variantStyles[variant], className),
2933
3762
  style
2934
3763
  });
2935
3764
  }
2936
3765
 
2937
3766
  //#endregion
2938
3767
  //#region src/components/DataGrid/index.tsx
2939
- const cn$11 = (...classes) => classes.filter(Boolean).join(" ");
3768
+ const cn$12 = (...classes) => classes.filter(Boolean).join(" ");
2940
3769
  function SortIcon({ sorted }) {
2941
3770
  if (sorted === "asc") return /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" });
2942
3771
  if (sorted === "desc") return /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" });
@@ -2991,7 +3820,7 @@ function VirtualRows({ table, rowHeight, onRowClick, compact }) {
2991
3820
  className: "bg-[var(--dashboard-text-secondary,#6b7280)]/5 sticky top-0 z-10",
2992
3821
  children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
2993
3822
  scope: "col",
2994
- className: cn$11("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", compact ? "px-4 py-2" : "px-6 py-3", header.column.getCanSort() && "cursor-pointer select-none"),
3823
+ className: cn$12("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", compact ? "px-4 py-2" : "px-6 py-3", header.column.getCanSort() && "cursor-pointer select-none"),
2995
3824
  style: { width: header.getSize() },
2996
3825
  onClick: header.column.getToggleSortingHandler(),
2997
3826
  children: /* @__PURE__ */ jsxs("div", {
@@ -3006,10 +3835,10 @@ function VirtualRows({ table, rowHeight, onRowClick, compact }) {
3006
3835
  }),
3007
3836
  visibleRows.map((row) => /* @__PURE__ */ jsx("tr", {
3008
3837
  onClick: () => onRowClick?.(row.original),
3009
- className: cn$11("hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5 transition-colors", onRowClick && "cursor-pointer", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5"),
3838
+ className: cn$12("hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5 transition-colors", onRowClick && "cursor-pointer", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5"),
3010
3839
  style: { height: rowHeight },
3011
3840
  children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
3012
- className: cn$11(cellPadding, "text-sm whitespace-nowrap"),
3841
+ className: cn$12(cellPadding, "text-sm whitespace-nowrap"),
3013
3842
  children: flexRender(cell.column.columnDef.cell, cell.getContext())
3014
3843
  }, cell.id))
3015
3844
  }, row.id)),
@@ -3088,7 +3917,7 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
3088
3917
  const cellPadding = compact ? "px-4 py-2" : "px-6 py-4";
3089
3918
  const headerPadding = compact ? "px-4 py-2" : "px-6 py-3";
3090
3919
  if (enableVirtualization) return /* @__PURE__ */ jsx("div", {
3091
- className: cn$11("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
3920
+ className: cn$12("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
3092
3921
  children: /* @__PURE__ */ jsx(VirtualRows, {
3093
3922
  table,
3094
3923
  rowHeight,
@@ -3097,16 +3926,16 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
3097
3926
  })
3098
3927
  });
3099
3928
  return /* @__PURE__ */ jsxs("div", {
3100
- className: cn$11("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
3929
+ className: cn$12("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
3101
3930
  children: [/* @__PURE__ */ jsx("div", {
3102
3931
  className: "overflow-x-auto",
3103
3932
  children: /* @__PURE__ */ jsxs("table", {
3104
3933
  className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/20",
3105
3934
  children: [/* @__PURE__ */ jsx("thead", {
3106
- className: cn$11("bg-[var(--dashboard-text-secondary,#6b7280)]/5", stickyHeader && "sticky top-0 z-10"),
3935
+ className: cn$12("bg-[var(--dashboard-text-secondary,#6b7280)]/5", stickyHeader && "sticky top-0 z-10"),
3107
3936
  children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
3108
3937
  scope: "col",
3109
- className: cn$11("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", headerPadding, header.column.getCanSort() && "cursor-pointer select-none"),
3938
+ className: cn$12("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", headerPadding, header.column.getCanSort() && "cursor-pointer select-none"),
3110
3939
  style: header.getSize() !== 150 ? { width: header.getSize() } : void 0,
3111
3940
  onClick: header.column.getToggleSortingHandler(),
3112
3941
  children: /* @__PURE__ */ jsxs("div", {
@@ -3143,9 +3972,9 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
3143
3972
  })
3144
3973
  }) }) : table.getRowModel().rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", {
3145
3974
  onClick: () => onRowClick?.(row.original),
3146
- className: cn$11("transition-colors", onRowClick && "cursor-pointer", "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5", striped && rowIndex % 2 === 1 && "bg-[var(--dashboard-text-secondary,#6b7280)]/3"),
3975
+ className: cn$12("transition-colors", onRowClick && "cursor-pointer", "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5", striped && rowIndex % 2 === 1 && "bg-[var(--dashboard-text-secondary,#6b7280)]/3"),
3147
3976
  children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
3148
- className: cn$11(cellPadding, "text-sm text-[var(--dashboard-text-primary,#2d2d2d)]"),
3977
+ className: cn$12(cellPadding, "text-sm text-[var(--dashboard-text-primary,#2d2d2d)]"),
3149
3978
  children: flexRender(cell.column.columnDef.cell, cell.getContext())
3150
3979
  }, cell.id))
3151
3980
  }, row.id))
@@ -3206,7 +4035,7 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
3206
4035
 
3207
4036
  //#endregion
3208
4037
  //#region src/components/TreeView/index.tsx
3209
- const cn$10 = (...classes) => classes.filter(Boolean).join(" ");
4038
+ const cn$11 = (...classes) => classes.filter(Boolean).join(" ");
3210
4039
  function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, onSelect, onToggle, onMove, renderNode, dragState, setDragState }) {
3211
4040
  const hasChildren = node.children && node.children.length > 0;
3212
4041
  const isExpanded = expanded.has(node.id);
@@ -3271,7 +4100,7 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
3271
4100
  "aria-expanded": hasChildren ? isExpanded : void 0,
3272
4101
  "aria-selected": isSelected,
3273
4102
  children: [/* @__PURE__ */ jsxs("div", {
3274
- className: cn$10("group flex items-center gap-1 rounded-md px-2 py-1.5 transition-colors", isSelected ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-primary,#2d2d2d)]", isDragging && "opacity-40", isDropTarget && dragState.position === "inside" && "ring-2 ring-[var(--dashboard-primary,#37a501)] ring-inset", node.disabled && "opacity-50 cursor-not-allowed"),
4103
+ className: cn$11("group flex items-center gap-1 rounded-md px-2 py-1.5 transition-colors", isSelected ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-primary,#2d2d2d)]", isDragging && "opacity-40", isDropTarget && dragState.position === "inside" && "ring-2 ring-[var(--dashboard-primary,#37a501)] ring-inset", node.disabled && "opacity-50 cursor-not-allowed"),
3275
4104
  style: { paddingLeft: `${level * indentSize + 4}px` },
3276
4105
  draggable: draggable && !node.disabled,
3277
4106
  onDragStart: handleDragStart,
@@ -3289,10 +4118,10 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
3289
4118
  /* @__PURE__ */ jsx("button", {
3290
4119
  type: "button",
3291
4120
  onClick: () => hasChildren && onToggle(node.id),
3292
- className: cn$10("flex-shrink-0 w-5 h-5 flex items-center justify-center rounded transition-transform", hasChildren ? "cursor-pointer" : "invisible"),
4121
+ className: cn$11("flex-shrink-0 w-5 h-5 flex items-center justify-center rounded transition-transform", hasChildren ? "cursor-pointer" : "invisible"),
3293
4122
  tabIndex: hasChildren ? 0 : -1,
3294
4123
  "aria-label": isExpanded ? "Recolher" : "Expandir",
3295
- children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$10("h-3.5 w-3.5 transition-transform duration-150", isExpanded && "rotate-90") })
4124
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$11("h-3.5 w-3.5 transition-transform duration-150", isExpanded && "rotate-90") })
3296
4125
  }),
3297
4126
  renderNode ? /* @__PURE__ */ jsx("div", {
3298
4127
  className: "flex-1 min-w-0 cursor-pointer",
@@ -3304,7 +4133,7 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
3304
4133
  children: node.icon
3305
4134
  }),
3306
4135
  /* @__PURE__ */ jsx("span", {
3307
- className: cn$10("flex-1 min-w-0 text-sm truncate", !node.disabled && "cursor-pointer"),
4136
+ className: cn$11("flex-1 min-w-0 text-sm truncate", !node.disabled && "cursor-pointer"),
3308
4137
  onClick: () => !node.disabled && onSelect?.(node),
3309
4138
  children: node.label
3310
4139
  }),
@@ -3357,7 +4186,7 @@ function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, d
3357
4186
  }, [onExpand]);
3358
4187
  return /* @__PURE__ */ jsx("ul", {
3359
4188
  role: "tree",
3360
- className: cn$10("select-none", className),
4189
+ className: cn$11("select-none", className),
3361
4190
  children: nodes.map((node) => /* @__PURE__ */ jsx(TreeItem, {
3362
4191
  node,
3363
4192
  level: 0,
@@ -3377,7 +4206,7 @@ function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, d
3377
4206
 
3378
4207
  //#endregion
3379
4208
  //#region src/components/Stepper/index.tsx
3380
- const cn$9 = (...classes) => classes.filter(Boolean).join(" ");
4209
+ const cn$10 = (...classes) => classes.filter(Boolean).join(" ");
3381
4210
  function StepIcon({ step, index }) {
3382
4211
  const status = step.status || "pending";
3383
4212
  if (status === "completed") return /* @__PURE__ */ jsx("div", {
@@ -3421,17 +4250,17 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
3421
4250
  type: "button",
3422
4251
  onClick: () => onStepChange?.(index),
3423
4252
  disabled: !onStepChange,
3424
- className: cn$9("relative z-10", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
4253
+ className: cn$10("relative z-10", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
3425
4254
  "aria-current": step.status === "active" ? "step" : void 0,
3426
4255
  children: /* @__PURE__ */ jsx(StepIcon, {
3427
4256
  step,
3428
4257
  index
3429
4258
  })
3430
- }), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$9("w-0.5 flex-1 min-h-[32px]", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
4259
+ }), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$10("w-0.5 flex-1 min-h-[32px]", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
3431
4260
  }), /* @__PURE__ */ jsxs("div", {
3432
- className: cn$9("pb-6", index === resolvedSteps.length - 1 && "pb-0"),
4261
+ className: cn$10("pb-6", index === resolvedSteps.length - 1 && "pb-0"),
3433
4262
  children: [/* @__PURE__ */ jsx("p", {
3434
- className: cn$9("text-sm font-medium leading-8", step.status === "active" ? "text-[var(--dashboard-primary,#37a501)]" : step.status === "completed" ? "text-[var(--dashboard-text-primary,#2d2d2d)]" : step.status === "error" ? "text-[var(--dashboard-status-danger,#EF4444)]" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
4263
+ className: cn$10("text-sm font-medium leading-8", step.status === "active" ? "text-[var(--dashboard-primary,#37a501)]" : step.status === "completed" ? "text-[var(--dashboard-text-primary,#2d2d2d)]" : step.status === "error" ? "text-[var(--dashboard-status-danger,#EF4444)]" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
3435
4264
  children: step.label
3436
4265
  }), step.description && /* @__PURE__ */ jsx("p", {
3437
4266
  className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] mt-0.5",
@@ -3447,12 +4276,12 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
3447
4276
  children: /* @__PURE__ */ jsx("ol", {
3448
4277
  className: "flex items-center",
3449
4278
  children: resolvedSteps.map((step, index) => /* @__PURE__ */ jsxs("li", {
3450
- className: cn$9("flex items-center", index < resolvedSteps.length - 1 && "flex-1"),
4279
+ className: cn$10("flex items-center", index < resolvedSteps.length - 1 && "flex-1"),
3451
4280
  children: [/* @__PURE__ */ jsxs("button", {
3452
4281
  type: "button",
3453
4282
  onClick: () => onStepChange?.(index),
3454
4283
  disabled: !onStepChange,
3455
- className: cn$9("flex items-center gap-2 group", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
4284
+ className: cn$10("flex items-center gap-2 group", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
3456
4285
  "aria-current": step.status === "active" ? "step" : void 0,
3457
4286
  children: [/* @__PURE__ */ jsx(StepIcon, {
3458
4287
  step,
@@ -3460,14 +4289,14 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
3460
4289
  }), /* @__PURE__ */ jsxs("div", {
3461
4290
  className: "hidden sm:block text-left",
3462
4291
  children: [/* @__PURE__ */ jsx("p", {
3463
- className: cn$9("text-sm font-medium whitespace-nowrap", step.status === "active" ? "text-[var(--dashboard-primary,#37a501)]" : step.status === "completed" ? "text-[var(--dashboard-text-primary,#2d2d2d)]" : step.status === "error" ? "text-[var(--dashboard-status-danger,#EF4444)]" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
4292
+ className: cn$10("text-sm font-medium whitespace-nowrap", step.status === "active" ? "text-[var(--dashboard-primary,#37a501)]" : step.status === "completed" ? "text-[var(--dashboard-text-primary,#2d2d2d)]" : step.status === "error" ? "text-[var(--dashboard-status-danger,#EF4444)]" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
3464
4293
  children: step.label
3465
4294
  }), step.description && /* @__PURE__ */ jsx("p", {
3466
4295
  className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] whitespace-nowrap",
3467
4296
  children: step.description
3468
4297
  })]
3469
4298
  })]
3470
- }), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$9("flex-1 h-0.5 mx-3", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
4299
+ }), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$10("flex-1 h-0.5 mx-3", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
3471
4300
  }, step.id))
3472
4301
  })
3473
4302
  });
@@ -3475,7 +4304,7 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
3475
4304
 
3476
4305
  //#endregion
3477
4306
  //#region src/components/FileUpload/index.tsx
3478
- const cn$8 = (...classes) => classes.filter(Boolean).join(" ");
4307
+ const cn$9 = (...classes) => classes.filter(Boolean).join(" ");
3479
4308
  function formatSize(bytes) {
3480
4309
  if (bytes < 1024) return `${bytes} B`;
3481
4310
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
@@ -3571,7 +4400,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
3571
4400
  onDragOver: handleDragOver,
3572
4401
  onDragLeave: handleDragLeave,
3573
4402
  onClick: () => !disabled && inputRef.current?.click(),
3574
- className: cn$8("relative flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6 transition-colors", isDragging ? "border-[var(--dashboard-primary,#37a501)] bg-[var(--dashboard-primary,#37a501)]/5" : "border-[var(--dashboard-text-secondary,#6b7280)]/30 hover:border-[var(--dashboard-text-secondary,#6b7280)]/50", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
4403
+ className: cn$9("relative flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6 transition-colors", isDragging ? "border-[var(--dashboard-primary,#37a501)] bg-[var(--dashboard-primary,#37a501)]/5" : "border-[var(--dashboard-text-secondary,#6b7280)]/30 hover:border-[var(--dashboard-text-secondary,#6b7280)]/50", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
3575
4404
  role: "button",
3576
4405
  tabIndex: disabled ? -1 : 0,
3577
4406
  "aria-label": label,
@@ -3594,7 +4423,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
3594
4423
  }), /* @__PURE__ */ jsxs("div", {
3595
4424
  className: "flex flex-col items-center text-center",
3596
4425
  children: [
3597
- icon || /* @__PURE__ */ jsx(Upload, { className: cn$8("h-8 w-8 mb-3", isDragging ? "text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)]") }),
4426
+ icon || /* @__PURE__ */ jsx(Upload, { className: cn$9("h-8 w-8 mb-3", isDragging ? "text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)]") }),
3598
4427
  /* @__PURE__ */ jsx("p", {
3599
4428
  className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)]",
3600
4429
  children: label
@@ -3661,16 +4490,18 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
3661
4490
 
3662
4491
  //#endregion
3663
4492
  //#region src/components/Tooltip/index.tsx
3664
- const cn$7 = (...classes) => classes.filter(Boolean).join(" ");
4493
+ const cn$8 = (...classes) => classes.filter(Boolean).join(" ");
3665
4494
  function Tooltip({ content, position = "top", delay = 200, children, className, maxWidth = 240 }) {
3666
4495
  const [visible, setVisible] = useState(false);
4496
+ const [positioned, setPositioned] = useState(false);
3667
4497
  const [coords, setCoords] = useState({
3668
4498
  top: 0,
3669
4499
  left: 0
3670
4500
  });
4501
+ const [actualPosition, setActualPosition] = useState(position);
3671
4502
  const triggerRef = useRef(null);
3672
4503
  const tooltipRef = useRef(null);
3673
- const timeoutRef = useRef();
4504
+ const timeoutRef = useRef(null);
3674
4505
  const idRef = useRef(`tooltip-${Math.random().toString(36).slice(2, 9)}`);
3675
4506
  const calculatePosition = useCallback(() => {
3676
4507
  if (!triggerRef.current || !tooltipRef.current) return;
@@ -3679,6 +4510,7 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
3679
4510
  const gap = 8;
3680
4511
  let top = 0;
3681
4512
  let left = 0;
4513
+ let resolvedPosition = position;
3682
4514
  switch (position) {
3683
4515
  case "top":
3684
4516
  top = trigger.top - tooltip.height - gap;
@@ -3697,31 +4529,65 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
3697
4529
  left = trigger.right + gap;
3698
4530
  break;
3699
4531
  }
4532
+ if (position === "top" && top < 8) {
4533
+ top = trigger.bottom + gap;
4534
+ resolvedPosition = "bottom";
4535
+ } else if (position === "bottom" && top + tooltip.height > window.innerHeight - 8) {
4536
+ top = trigger.top - tooltip.height - gap;
4537
+ resolvedPosition = "top";
4538
+ }
3700
4539
  left = Math.max(8, Math.min(left, window.innerWidth - tooltip.width - 8));
3701
4540
  top = Math.max(8, Math.min(top, window.innerHeight - tooltip.height - 8));
3702
4541
  setCoords({
3703
4542
  top,
3704
4543
  left
3705
4544
  });
4545
+ setActualPosition(resolvedPosition);
4546
+ setPositioned(true);
3706
4547
  }, [position]);
3707
4548
  const show = useCallback(() => {
3708
4549
  timeoutRef.current = setTimeout(() => {
3709
4550
  setVisible(true);
4551
+ setPositioned(false);
3710
4552
  }, delay);
3711
4553
  }, [delay]);
3712
4554
  const hide = useCallback(() => {
3713
4555
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
3714
4556
  setVisible(false);
4557
+ setPositioned(false);
3715
4558
  }, []);
3716
4559
  useEffect(() => {
3717
- if (visible) requestAnimationFrame(calculatePosition);
4560
+ if (visible) requestAnimationFrame(() => {
4561
+ requestAnimationFrame(calculatePosition);
4562
+ });
3718
4563
  }, [visible, calculatePosition]);
3719
4564
  useEffect(() => {
3720
4565
  return () => {
3721
4566
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
3722
4567
  };
3723
4568
  }, []);
3724
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
4569
+ let trigger;
4570
+ if (isValidElement(children)) trigger = cloneElement(children, {
4571
+ ref: triggerRef,
4572
+ onMouseEnter: (e) => {
4573
+ show();
4574
+ children.props?.onMouseEnter?.(e);
4575
+ },
4576
+ onMouseLeave: (e) => {
4577
+ hide();
4578
+ children.props?.onMouseLeave?.(e);
4579
+ },
4580
+ onFocus: (e) => {
4581
+ show();
4582
+ children.props?.onFocus?.(e);
4583
+ },
4584
+ onBlur: (e) => {
4585
+ hide();
4586
+ children.props?.onBlur?.(e);
4587
+ },
4588
+ "aria-describedby": visible ? idRef.current : void 0
4589
+ });
4590
+ else trigger = /* @__PURE__ */ jsx("span", {
3725
4591
  ref: triggerRef,
3726
4592
  onMouseEnter: show,
3727
4593
  onMouseLeave: hide,
@@ -3730,23 +4596,88 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
3730
4596
  "aria-describedby": visible ? idRef.current : void 0,
3731
4597
  className: "inline-flex",
3732
4598
  children
3733
- }), visible && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsx("div", {
4599
+ });
4600
+ return /* @__PURE__ */ jsxs(Fragment, { children: [trigger, visible && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsxs("div", {
3734
4601
  ref: tooltipRef,
3735
4602
  id: idRef.current,
3736
4603
  role: "tooltip",
3737
- className: cn$7("fixed z-[10002] rounded-md px-3 py-2 text-xs font-medium", "bg-[var(--dashboard-text-primary,#2d2d2d)] text-white", "shadow-lg dashboard-animate-fade-in pointer-events-none", className),
4604
+ className: cn$8("fixed z-[10002] rounded-md px-3 py-2 text-xs font-medium", "bg-[var(--dashboard-tooltip-bg,#1a1a1a)] text-[var(--dashboard-tooltip-text,#ffffff)]", "shadow-lg pointer-events-none", positioned && "dashboard-animate-fade-in", className),
3738
4605
  style: {
3739
4606
  top: coords.top,
3740
4607
  left: coords.left,
3741
- maxWidth
4608
+ maxWidth,
4609
+ opacity: positioned ? 1 : 0
3742
4610
  },
3743
- children: content
4611
+ children: [content, /* @__PURE__ */ jsx("span", { className: cn$8("absolute w-0 h-0 border-[5px]", {
4612
+ top: "left-1/2 -translate-x-1/2 top-full border-t-[var(--dashboard-tooltip-bg,#1a1a1a)] border-x-transparent border-b-transparent",
4613
+ bottom: "left-1/2 -translate-x-1/2 bottom-full border-b-[var(--dashboard-tooltip-bg,#1a1a1a)] border-x-transparent border-t-transparent",
4614
+ left: "top-1/2 -translate-y-1/2 left-full border-l-[var(--dashboard-tooltip-bg,#1a1a1a)] border-y-transparent border-r-transparent",
4615
+ right: "top-1/2 -translate-y-1/2 right-full border-r-[var(--dashboard-tooltip-bg,#1a1a1a)] border-y-transparent border-l-transparent"
4616
+ }[actualPosition]) })]
3744
4617
  }), document.body)] });
3745
4618
  }
3746
4619
 
4620
+ //#endregion
4621
+ //#region src/components/InfoTooltip/index.tsx
4622
+ function InfoTooltip({ content, term, size = 14, position = "top", maxWidth = 280, className }) {
4623
+ return /* @__PURE__ */ jsx(Tooltip, {
4624
+ content: term ? /* @__PURE__ */ jsxs("span", {
4625
+ className: "text-xs leading-relaxed",
4626
+ children: [
4627
+ /* @__PURE__ */ jsx("strong", { children: term }),
4628
+ " — ",
4629
+ content
4630
+ ]
4631
+ }) : /* @__PURE__ */ jsx("span", {
4632
+ className: "text-xs leading-relaxed",
4633
+ children: content
4634
+ }),
4635
+ position,
4636
+ maxWidth,
4637
+ children: /* @__PURE__ */ jsx("button", {
4638
+ type: "button",
4639
+ tabIndex: 0,
4640
+ "aria-label": term ? `Informação sobre ${term}` : "Mais informações",
4641
+ className: [
4642
+ "inline-flex items-center justify-center rounded-full",
4643
+ "text-[var(--dashboard-text-secondary,#6b7280)]",
4644
+ "hover:text-[var(--dashboard-text-primary,#2d2d2d)]",
4645
+ "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10",
4646
+ "transition-colors duration-150 cursor-help",
4647
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--dashboard-primary,#2563EB)]/40",
4648
+ className
4649
+ ].filter(Boolean).join(" "),
4650
+ style: {
4651
+ width: size + 6,
4652
+ height: size + 6
4653
+ },
4654
+ children: /* @__PURE__ */ jsxs("svg", {
4655
+ width: size,
4656
+ height: size,
4657
+ viewBox: "0 0 24 24",
4658
+ fill: "none",
4659
+ stroke: "currentColor",
4660
+ strokeWidth: "2",
4661
+ strokeLinecap: "round",
4662
+ strokeLinejoin: "round",
4663
+ "aria-hidden": "true",
4664
+ children: [
4665
+ /* @__PURE__ */ jsx("circle", {
4666
+ cx: "12",
4667
+ cy: "12",
4668
+ r: "10"
4669
+ }),
4670
+ /* @__PURE__ */ jsx("path", { d: "M12 16v-4" }),
4671
+ /* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
4672
+ ]
4673
+ })
4674
+ })
4675
+ });
4676
+ }
4677
+
3747
4678
  //#endregion
3748
4679
  //#region src/components/Breadcrumb/index.tsx
3749
- const cn$6 = (...classes) => classes.filter(Boolean).join(" ");
4680
+ const cn$7 = (...classes) => classes.filter(Boolean).join(" ");
3750
4681
  function Breadcrumb({ items, separator, onNavigate, className }) {
3751
4682
  const defaultSeparator = /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-[var(--dashboard-text-secondary,#6b7280)] flex-shrink-0" });
3752
4683
  const handleClick = (e, href) => {
@@ -3768,7 +4699,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
3768
4699
  "aria-hidden": "true",
3769
4700
  children: separator || defaultSeparator
3770
4701
  }), isLast ? /* @__PURE__ */ jsxs("span", {
3771
- className: cn$6("flex items-center gap-1.5 text-sm font-medium", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
4702
+ className: cn$7("flex items-center gap-1.5 text-sm font-medium", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
3772
4703
  "aria-current": "page",
3773
4704
  children: [item.icon && /* @__PURE__ */ jsx("span", {
3774
4705
  className: "flex-shrink-0 h-4 w-4",
@@ -3777,7 +4708,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
3777
4708
  }) : /* @__PURE__ */ jsxs("a", {
3778
4709
  href: item.href || "#",
3779
4710
  onClick: (e) => handleClick(e, item.href),
3780
- className: cn$6("flex items-center gap-1.5 text-sm", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-primary,#37a501)] transition-colors"),
4711
+ className: cn$7("flex items-center gap-1.5 text-sm", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-primary,#37a501)] transition-colors"),
3781
4712
  children: [item.icon && /* @__PURE__ */ jsx("span", {
3782
4713
  className: "flex-shrink-0 h-4 w-4",
3783
4714
  children: item.icon
@@ -3791,7 +4722,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
3791
4722
 
3792
4723
  //#endregion
3793
4724
  //#region src/components/Combobox/index.tsx
3794
- const cn$5 = (...classes) => classes.filter(Boolean).join(" ");
4725
+ const cn$6 = (...classes) => classes.filter(Boolean).join(" ");
3795
4726
  function Combobox({ options, value, onChange, multiple = false, searchable = true, placeholder = "Selecione...", label, error, disabled = false, renderOption, noResultsText = "Nenhum resultado encontrado", className }) {
3796
4727
  const [isOpen, setIsOpen] = useState(false);
3797
4728
  const [query, setQuery] = useState("");
@@ -3921,7 +4852,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
3921
4852
  }, [focusedIndex]);
3922
4853
  const selectedLabels = selectedValues.map((v) => options.find((o) => o.value === v)?.label).filter(Boolean);
3923
4854
  return /* @__PURE__ */ jsxs("div", {
3924
- className: cn$5("space-y-2", className),
4855
+ className: cn$6("space-y-2", className),
3925
4856
  children: [
3926
4857
  label && /* @__PURE__ */ jsx("label", {
3927
4858
  className: "block text-sm text-[var(--dashboard-text-primary,#2d2d2d)]",
@@ -3937,7 +4868,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
3937
4868
  "aria-controls": "combobox-listbox",
3938
4869
  tabIndex: disabled ? -1 : 0,
3939
4870
  onClick: () => isOpen ? close() : open(),
3940
- className: cn$5("flex min-h-[40px] w-full items-center gap-2 rounded-lg border px-3 py-2 transition-colors", isOpen ? "border-[var(--dashboard-primary,#37a501)] ring-2 ring-[var(--dashboard-primary,#37a501)]/20" : error ? "border-[var(--dashboard-status-danger,#EF4444)]" : "border-[var(--dashboard-text-secondary,#6b7280)]/30 hover:border-[var(--dashboard-text-secondary,#6b7280)]/50", disabled ? "opacity-50 cursor-not-allowed bg-[var(--dashboard-text-secondary,#6b7280)]/10" : "cursor-pointer bg-[var(--dashboard-surface,#ffffff)]"),
4871
+ className: cn$6("flex min-h-[40px] w-full items-center gap-2 rounded-lg border px-3 py-2 transition-colors", isOpen ? "border-[var(--dashboard-primary,#37a501)] ring-2 ring-[var(--dashboard-primary,#37a501)]/20" : error ? "border-[var(--dashboard-status-danger,#EF4444)]" : "border-[var(--dashboard-text-secondary,#6b7280)]/30 hover:border-[var(--dashboard-text-secondary,#6b7280)]/50", disabled ? "opacity-50 cursor-not-allowed bg-[var(--dashboard-text-secondary,#6b7280)]/10" : "cursor-pointer bg-[var(--dashboard-surface,#ffffff)]"),
3941
4872
  children: [
3942
4873
  /* @__PURE__ */ jsx("div", {
3943
4874
  className: "flex flex-1 flex-wrap items-center gap-1 min-w-0",
@@ -3965,7 +4896,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
3965
4896
  "aria-label": "Limpar seleção",
3966
4897
  children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
3967
4898
  }),
3968
- /* @__PURE__ */ jsx(ChevronDown, { className: cn$5("h-4 w-4 flex-shrink-0 text-[var(--dashboard-text-secondary,#6b7280)] transition-transform", isOpen && "rotate-180") })
4899
+ /* @__PURE__ */ jsx(ChevronDown, { className: cn$6("h-4 w-4 flex-shrink-0 text-[var(--dashboard-text-secondary,#6b7280)] transition-transform", isOpen && "rotate-180") })
3969
4900
  ]
3970
4901
  }), isOpen && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsxs("div", {
3971
4902
  className: "dc-combobox-portal rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] shadow-lg dashboard-animate-fade-in overflow-hidden",
@@ -4010,7 +4941,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
4010
4941
  onClick: () => {
4011
4942
  if (!option.disabled) toggleOption(option.value);
4012
4943
  },
4013
- className: cn$5("flex items-center justify-between px-3 py-2 text-sm transition-colors", option.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer", isFocused && "bg-[var(--dashboard-text-secondary,#6b7280)]/10", !isFocused && !option.disabled && "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10", isSelected ? "text-[var(--dashboard-primary,#37a501)] font-medium" : "text-[var(--dashboard-text-primary,#2d2d2d)]"),
4944
+ className: cn$6("flex items-center justify-between px-3 py-2 text-sm transition-colors", option.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer", isFocused && "bg-[var(--dashboard-text-secondary,#6b7280)]/10", !isFocused && !option.disabled && "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10", isSelected ? "text-[var(--dashboard-primary,#37a501)] font-medium" : "text-[var(--dashboard-text-primary,#2d2d2d)]"),
4014
4945
  children: renderOption ? renderOption(option, isSelected) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
4015
4946
  className: "truncate",
4016
4947
  children: option.label
@@ -4030,7 +4961,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
4030
4961
 
4031
4962
  //#endregion
4032
4963
  //#region src/components/Alert/index.tsx
4033
- const cn$4 = (...classes) => classes.filter(Boolean).join(" ");
4964
+ const cn$5 = (...classes) => classes.filter(Boolean).join(" ");
4034
4965
  const variantConfig$1 = {
4035
4966
  info: {
4036
4967
  border: "border-[var(--dashboard-status-info,#3b82f6)]",
@@ -4060,24 +4991,24 @@ const variantConfig$1 = {
4060
4991
  function Alert({ variant = "info", title, description, onClose, actions, icon, className }) {
4061
4992
  const config = variantConfig$1[variant];
4062
4993
  return /* @__PURE__ */ jsx("div", {
4063
- className: cn$4("rounded-lg border-l-4 p-4", config.border, config.bg, className),
4994
+ className: cn$5("rounded-lg border-l-4 p-4", config.border, config.bg, className),
4064
4995
  role: "alert",
4065
4996
  children: /* @__PURE__ */ jsxs("div", {
4066
4997
  className: "flex gap-3",
4067
4998
  children: [
4068
4999
  /* @__PURE__ */ jsx("div", {
4069
- className: cn$4("flex-shrink-0 mt-0.5", config.text),
5000
+ className: cn$5("flex-shrink-0 mt-0.5", config.text),
4070
5001
  children: icon || config.icon
4071
5002
  }),
4072
5003
  /* @__PURE__ */ jsxs("div", {
4073
5004
  className: "flex-1 min-w-0",
4074
5005
  children: [
4075
5006
  title && /* @__PURE__ */ jsx("h3", {
4076
- className: cn$4("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
5007
+ className: cn$5("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
4077
5008
  children: title
4078
5009
  }),
4079
5010
  description && /* @__PURE__ */ jsx("div", {
4080
- className: cn$4("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
5011
+ className: cn$5("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
4081
5012
  children: description
4082
5013
  }),
4083
5014
  actions && /* @__PURE__ */ jsx("div", {
@@ -4099,7 +5030,7 @@ function Alert({ variant = "info", title, description, onClose, actions, icon, c
4099
5030
 
4100
5031
  //#endregion
4101
5032
  //#region src/components/Callout/index.tsx
4102
- const cn$3 = (...classes) => classes.filter(Boolean).join(" ");
5033
+ const cn$4 = (...classes) => classes.filter(Boolean).join(" ");
4103
5034
  const variantConfig = {
4104
5035
  info: {
4105
5036
  border: "border-[var(--dashboard-status-info,#3b82f6)]",
@@ -4129,20 +5060,20 @@ const variantConfig = {
4129
5060
  function Callout({ variant = "info", title, children, icon, className }) {
4130
5061
  const config = variantConfig[variant];
4131
5062
  return /* @__PURE__ */ jsx("div", {
4132
- className: cn$3("rounded-lg border-l-4 p-4 my-4", config.border, config.bg, className),
5063
+ className: cn$4("rounded-lg border-l-4 p-4 my-4", config.border, config.bg, className),
4133
5064
  role: "note",
4134
5065
  children: /* @__PURE__ */ jsxs("div", {
4135
5066
  className: "flex gap-3",
4136
5067
  children: [/* @__PURE__ */ jsx("div", {
4137
- className: cn$3("flex-shrink-0 mt-0.5", config.text),
5068
+ className: cn$4("flex-shrink-0 mt-0.5", config.text),
4138
5069
  children: icon || config.icon
4139
5070
  }), /* @__PURE__ */ jsxs("div", {
4140
5071
  className: "flex-1 min-w-0",
4141
5072
  children: [title && /* @__PURE__ */ jsx("p", {
4142
- className: cn$3("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
5073
+ className: cn$4("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
4143
5074
  children: title
4144
5075
  }), children && /* @__PURE__ */ jsx("div", {
4145
- className: cn$3("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
5076
+ className: cn$4("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
4146
5077
  children
4147
5078
  })]
4148
5079
  })]
@@ -4152,7 +5083,7 @@ function Callout({ variant = "info", title, children, icon, className }) {
4152
5083
 
4153
5084
  //#endregion
4154
5085
  //#region src/components/CodeBlock/index.tsx
4155
- const cn$2 = (...classes) => classes.filter(Boolean).join(" ");
5086
+ const cn$3 = (...classes) => classes.filter(Boolean).join(" ");
4156
5087
  function CodeBlock({ code, language, filename, showLineNumbers = false, className, copyLabel = "Copiar", copiedLabel = "Copiado!" }) {
4157
5088
  const [copied, setCopied] = useState(false);
4158
5089
  const handleCopy = useCallback(async () => {
@@ -4164,7 +5095,7 @@ function CodeBlock({ code, language, filename, showLineNumbers = false, classNam
4164
5095
  }, [code]);
4165
5096
  const lines = code.split("\n");
4166
5097
  return /* @__PURE__ */ jsxs("div", {
4167
- className: cn$2("relative rounded-lg overflow-hidden border border-[var(--dashboard-text-secondary,#64748B)]/12 my-4", className),
5098
+ className: cn$3("relative rounded-lg overflow-hidden border border-[var(--dashboard-text-secondary,#64748B)]/12 my-4", className),
4168
5099
  children: [(filename || language) && /* @__PURE__ */ jsxs("div", {
4169
5100
  className: "flex items-center justify-between px-4 py-2 bg-[var(--dashboard-text-primary,#0F172A)] border-b border-[var(--dashboard-text-secondary,#64748B)]/20",
4170
5101
  children: [
@@ -4198,7 +5129,7 @@ function CodeBlock({ code, language, filename, showLineNumbers = false, classNam
4198
5129
  })
4199
5130
  }), /* @__PURE__ */ jsxs("button", {
4200
5131
  onClick: handleCopy,
4201
- className: cn$2("absolute top-3 right-3 flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium transition-all duration-200 cursor-pointer", copied ? "bg-[var(--dashboard-status-success,#059669)]/20 text-[var(--dashboard-status-success,#059669)]" : "bg-[var(--dashboard-surface,#FFFFFF)]/10 text-[var(--dashboard-surface,#FFFFFF)]/60 hover:bg-[var(--dashboard-surface,#FFFFFF)]/20 hover:text-[var(--dashboard-surface,#FFFFFF)]/80"),
5132
+ className: cn$3("absolute top-3 right-3 flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium transition-all duration-200 cursor-pointer", copied ? "bg-[var(--dashboard-status-success,#059669)]/20 text-[var(--dashboard-status-success,#059669)]" : "bg-[var(--dashboard-surface,#FFFFFF)]/10 text-[var(--dashboard-surface,#FFFFFF)]/60 hover:bg-[var(--dashboard-surface,#FFFFFF)]/20 hover:text-[var(--dashboard-surface,#FFFFFF)]/80"),
4202
5133
  "aria-label": copied ? copiedLabel : copyLabel,
4203
5134
  title: copied ? copiedLabel : copyLabel,
4204
5135
  children: [copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ jsx("span", { children: copied ? copiedLabel : copyLabel })]
@@ -4209,10 +5140,10 @@ function CodeBlock({ code, language, filename, showLineNumbers = false, classNam
4209
5140
 
4210
5141
  //#endregion
4211
5142
  //#region src/components/EmptyState/index.tsx
4212
- const cn$1 = (...classes) => classes.filter(Boolean).join(" ");
5143
+ const cn$2 = (...classes) => classes.filter(Boolean).join(" ");
4213
5144
  function EmptyState({ icon, title, description, action, className }) {
4214
5145
  return /* @__PURE__ */ jsxs("div", {
4215
- className: cn$1("flex flex-col items-center justify-center py-12 px-6 text-center", className),
5146
+ className: cn$2("flex flex-col items-center justify-center py-12 px-6 text-center", className),
4216
5147
  children: [
4217
5148
  /* @__PURE__ */ jsx("div", {
4218
5149
  className: "flex h-16 w-16 items-center justify-center rounded-full bg-[var(--dashboard-text-secondary,#6b7280)]/10 mb-4",
@@ -4236,7 +5167,7 @@ function EmptyState({ icon, title, description, action, className }) {
4236
5167
 
4237
5168
  //#endregion
4238
5169
  //#region src/components/StatusBadge/index.tsx
4239
- const cn = (...classes) => classes.filter(Boolean).join(" ");
5170
+ const cn$1 = (...classes) => classes.filter(Boolean).join(" ");
4240
5171
  const defaultColorMap = {
4241
5172
  ACTIVE: "var(--dashboard-status-success,#10B981)",
4242
5173
  APPROVED: "var(--dashboard-status-success,#10B981)",
@@ -4260,7 +5191,7 @@ const defaultColorMap = {
4260
5191
  };
4261
5192
  const sizeClasses = {
4262
5193
  sm: "px-2 py-0.5 text-xs",
4263
- md: "px-2.5 py-1 text-xs",
5194
+ md: "px-2.5 py-1 text-sm",
4264
5195
  lg: "px-3 py-1 text-sm"
4265
5196
  };
4266
5197
  const dotSizeClasses = {
@@ -4278,18 +5209,398 @@ function StatusBadge({ status, colorMap, size = "md", label, dot = true, classNa
4278
5209
  }[status.toUpperCase().replace(/[\s-]/g, "_")] || "var(--dashboard-text-secondary,#6b7280)";
4279
5210
  const displayLabel = label || formatLabel(status);
4280
5211
  return /* @__PURE__ */ jsxs("span", {
4281
- className: cn("inline-flex items-center gap-1.5 rounded-full font-medium whitespace-nowrap", sizeClasses[size], className),
5212
+ className: cn$1("inline-flex items-center gap-1.5 rounded-full font-medium whitespace-nowrap", sizeClasses[size], className),
4282
5213
  style: {
4283
5214
  color,
4284
5215
  backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`
4285
5216
  },
4286
5217
  children: [dot && /* @__PURE__ */ jsx("span", {
4287
- className: cn("rounded-full flex-shrink-0", dotSizeClasses[size]),
5218
+ className: cn$1("rounded-full flex-shrink-0", dotSizeClasses[size]),
4288
5219
  style: { backgroundColor: color }
4289
5220
  }), displayLabel]
4290
5221
  });
4291
5222
  }
4292
5223
 
5224
+ //#endregion
5225
+ //#region src/components/TableOfContents/index.tsx
5226
+ const cn = (...classes) => classes.filter(Boolean).join(" ");
5227
+ function getIdFromUrl(url) {
5228
+ if (typeof url === "string" && url.startsWith("#")) return url.slice(1);
5229
+ return null;
5230
+ }
5231
+ function arraysShallowEqual(a, b) {
5232
+ if (a === b) return true;
5233
+ if (a.length !== b.length) return false;
5234
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
5235
+ return true;
5236
+ }
5237
+ function findScrollableParent(el) {
5238
+ let current = el?.parentElement;
5239
+ while (current && current !== document.body) {
5240
+ const overflowY = getComputedStyle(current).overflowY;
5241
+ if (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") {
5242
+ if (current.scrollHeight > current.clientHeight) return current;
5243
+ }
5244
+ current = current.parentElement;
5245
+ }
5246
+ return document.documentElement;
5247
+ }
5248
+ function scrollAnchorIntoView(anchor, container, options = {}) {
5249
+ const { behavior = "smooth", block = "center" } = options;
5250
+ const containerRect = container.getBoundingClientRect();
5251
+ const offsetTopRelativeToContainer = anchor.getBoundingClientRect().top - containerRect.top + container.scrollTop;
5252
+ let targetScroll;
5253
+ if (block === "center") targetScroll = offsetTopRelativeToContainer - container.clientHeight / 2 + anchor.clientHeight / 2;
5254
+ else if (block === "end") targetScroll = offsetTopRelativeToContainer - container.clientHeight + anchor.clientHeight;
5255
+ else targetScroll = offsetTopRelativeToContainer;
5256
+ container.scrollTo({
5257
+ top: Math.max(0, targetScroll),
5258
+ behavior
5259
+ });
5260
+ }
5261
+ var TocObserver = class {
5262
+ constructor() {
5263
+ this.items = [];
5264
+ this.single = false;
5265
+ this.intersectionObserver = null;
5266
+ this.listeners = /* @__PURE__ */ new Set();
5267
+ }
5268
+ listen(fn) {
5269
+ this.listeners.add(fn);
5270
+ }
5271
+ unlisten(fn) {
5272
+ this.listeners.delete(fn);
5273
+ }
5274
+ setItems(nextItems) {
5275
+ if (this.intersectionObserver) for (const item of this.items) {
5276
+ const el = document.getElementById(item.id);
5277
+ if (el) this.intersectionObserver.unobserve(el);
5278
+ }
5279
+ const next = [];
5280
+ for (const item of nextItems) {
5281
+ const id = getIdFromUrl(item.url);
5282
+ if (!id) continue;
5283
+ next.push({
5284
+ id,
5285
+ active: false,
5286
+ fallback: false,
5287
+ t: 0,
5288
+ original: item
5289
+ });
5290
+ }
5291
+ this.update(next);
5292
+ this.observeAll();
5293
+ }
5294
+ watch(options) {
5295
+ if (this.intersectionObserver) return;
5296
+ if (typeof window === "undefined") return;
5297
+ this.intersectionObserver = new IntersectionObserver(this.handleIntersection.bind(this), options);
5298
+ this.observeAll();
5299
+ }
5300
+ unwatch() {
5301
+ this.intersectionObserver?.disconnect();
5302
+ this.intersectionObserver = null;
5303
+ }
5304
+ handleIntersection(entries) {
5305
+ if (entries.length === 0) return;
5306
+ let hasActive = false;
5307
+ const updated = this.items.map((item) => {
5308
+ const entry = entries.find((e) => e.target.id === item.id);
5309
+ let active = entry ? entry.isIntersecting : item.active && !item.fallback;
5310
+ if (this.single && hasActive) active = false;
5311
+ let nextItem = item;
5312
+ if (item.active !== active) nextItem = {
5313
+ ...item,
5314
+ t: Date.now(),
5315
+ active,
5316
+ fallback: false
5317
+ };
5318
+ if (active) hasActive = true;
5319
+ return nextItem;
5320
+ });
5321
+ if (!hasActive && entries[0].rootBounds) {
5322
+ const viewTop = entries[0].rootBounds.top;
5323
+ let min = Number.POSITIVE_INFINITY;
5324
+ let fallbackIdx = -1;
5325
+ for (let i = 0; i < updated.length; i++) {
5326
+ const el = document.getElementById(updated[i].id);
5327
+ if (!el) continue;
5328
+ const distance = Math.abs(viewTop - el.getBoundingClientRect().top);
5329
+ if (distance < min) {
5330
+ min = distance;
5331
+ fallbackIdx = i;
5332
+ }
5333
+ }
5334
+ if (fallbackIdx !== -1) updated[fallbackIdx] = {
5335
+ ...updated[fallbackIdx],
5336
+ active: true,
5337
+ fallback: true,
5338
+ t: Date.now()
5339
+ };
5340
+ }
5341
+ this.update(updated);
5342
+ }
5343
+ observeAll() {
5344
+ if (!this.intersectionObserver) return;
5345
+ for (const item of this.items) {
5346
+ const el = document.getElementById(item.id);
5347
+ if (el) this.intersectionObserver.observe(el);
5348
+ }
5349
+ }
5350
+ update(next) {
5351
+ this.items = next;
5352
+ for (const fn of this.listeners) fn(next);
5353
+ }
5354
+ };
5355
+ const ObserverContext = createContext(null);
5356
+ const ItemsContext = createContext([]);
5357
+ const LinksRefContext = createContext(null);
5358
+ function useObserver() {
5359
+ const observer = useContext(ObserverContext);
5360
+ if (!observer) throw new Error("TableOfContents hooks must be used inside <TOCProvider> or <TableOfContents>.");
5361
+ return observer;
5362
+ }
5363
+ /**
5364
+ * Headless provider that drives the scrollspy. Use directly when you want to
5365
+ * render the visual ToC yourself (e.g. mobile drawer, custom layout).
5366
+ */
5367
+ function TOCProvider({ items, single = false, rootMargin = "0px 0px -70% 0px", threshold = 0, children }) {
5368
+ const observer = useMemo(() => new TocObserver(), []);
5369
+ observer.single = single;
5370
+ useEffect(() => {
5371
+ observer.setItems(items);
5372
+ }, [observer, items]);
5373
+ useEffect(() => {
5374
+ observer.watch({
5375
+ rootMargin,
5376
+ threshold
5377
+ });
5378
+ return () => observer.unwatch();
5379
+ }, [
5380
+ observer,
5381
+ rootMargin,
5382
+ threshold
5383
+ ]);
5384
+ return /* @__PURE__ */ jsx(ObserverContext.Provider, {
5385
+ value: observer,
5386
+ children: /* @__PURE__ */ jsx(ItemsContext.Provider, {
5387
+ value: items,
5388
+ children
5389
+ })
5390
+ });
5391
+ }
5392
+ function useObserverState(select, isEqual = Object.is) {
5393
+ const observer = useObserver();
5394
+ const [value, setValue] = useState(() => select(observer.items));
5395
+ const selectRef = useRef(select);
5396
+ const isEqualRef = useRef(isEqual);
5397
+ selectRef.current = select;
5398
+ isEqualRef.current = isEqual;
5399
+ useEffect(() => {
5400
+ const listener = (items) => {
5401
+ const next = selectRef.current(items);
5402
+ setValue((prev) => isEqualRef.current(prev, next) ? prev : next);
5403
+ };
5404
+ observer.listen(listener);
5405
+ return () => observer.unlisten(listener);
5406
+ }, [observer]);
5407
+ return value;
5408
+ }
5409
+ /** Returns the id of the most recently activated heading (best guess). */
5410
+ function useActiveAnchor() {
5411
+ return useObserverState((items) => {
5412
+ let best;
5413
+ for (const item of items) {
5414
+ if (!item.active) continue;
5415
+ if (!best || item.t > best.t) best = item;
5416
+ }
5417
+ return best?.id;
5418
+ });
5419
+ }
5420
+ /** Returns the ids of every currently active heading. */
5421
+ function useActiveAnchors() {
5422
+ return useObserverState((items) => {
5423
+ const out = [];
5424
+ for (const item of items) if (item.active) out.push(item.id);
5425
+ return out;
5426
+ }, arraysShallowEqual);
5427
+ }
5428
+ /** Returns the static items list registered with the provider. */
5429
+ function useTOCItems() {
5430
+ return useContext(ItemsContext);
5431
+ }
5432
+ function handleAnchorClick(e, id) {
5433
+ const el = document.getElementById(id);
5434
+ if (!el) return;
5435
+ e.preventDefault();
5436
+ el.scrollIntoView({
5437
+ behavior: "smooth",
5438
+ block: "start"
5439
+ });
5440
+ if (typeof window !== "undefined" && window.history) window.history.replaceState(null, "", `#${id}`);
5441
+ }
5442
+ function TocAnchor({ item }) {
5443
+ const id = getIdFromUrl(item.url) ?? "";
5444
+ const activeIds = useActiveAnchors();
5445
+ const isActive = id ? activeIds.includes(id) : false;
5446
+ const linksRef = useContext(LinksRefContext);
5447
+ return /* @__PURE__ */ jsx("a", {
5448
+ ref: useCallback((node) => {
5449
+ if (!linksRef || !id) return;
5450
+ if (node) linksRef.current.set(id, node);
5451
+ else linksRef.current.delete(id);
5452
+ }, [linksRef, id]),
5453
+ href: item.url,
5454
+ "data-active": isActive,
5455
+ onClick: (e) => handleAnchorClick(e, id),
5456
+ className: cn("py-1.5 text-sm transition-colors scroll-m-4 wrap-anywhere first:pt-0 last:pb-0", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-text-primary,#2d2d2d)]", "data-[active=true]:text-[var(--dashboard-primary,#e74410)]", item.depth <= 2 && "pl-3", item.depth === 3 && "pl-6", item.depth >= 4 && "pl-8"),
5457
+ children: item.title
5458
+ });
5459
+ }
5460
+ function TocThumb({ computed }) {
5461
+ const ref = useRef(null);
5462
+ const observer = useObserver();
5463
+ const calculate = useCallback((items) => {
5464
+ const out = {};
5465
+ const startIdx = items.findIndex((item) => item.active);
5466
+ if (startIdx === -1) return out;
5467
+ let endIdx = startIdx;
5468
+ for (let i = items.length - 1; i >= startIdx; i--) if (items[i].active) {
5469
+ endIdx = i;
5470
+ break;
5471
+ }
5472
+ const startPos = computed.positions[startIdx];
5473
+ const endPos = computed.positions[endIdx];
5474
+ if (!startPos || !endPos) return out;
5475
+ out["--track-top"] = `${startPos[0]}px`;
5476
+ out["--track-bottom"] = `${endPos[1]}px`;
5477
+ return out;
5478
+ }, [computed]);
5479
+ useEffect(() => {
5480
+ const el = ref.current;
5481
+ if (!el) return;
5482
+ const apply = (items) => {
5483
+ const styles = calculate(items);
5484
+ for (const [k, v] of Object.entries(styles)) el.style.setProperty(k, v);
5485
+ };
5486
+ apply(observer.items);
5487
+ observer.listen(apply);
5488
+ return () => observer.unlisten(apply);
5489
+ }, [observer, calculate]);
5490
+ const initialStyles = calculate(observer.items);
5491
+ return /* @__PURE__ */ jsx("div", {
5492
+ ref,
5493
+ "aria-hidden": true,
5494
+ className: "absolute inset-y-0 left-0 w-px bg-[var(--dashboard-primary,#e74410)] transition-[clip-path]",
5495
+ style: {
5496
+ clipPath: "polygon(0 var(--track-top, 0), 100% var(--track-top, 0), 100% var(--track-bottom, 0), 0 var(--track-bottom, 0))",
5497
+ ...initialStyles
5498
+ }
5499
+ });
5500
+ }
5501
+ function TocList({ items, showThumb }) {
5502
+ const containerRef = useRef(null);
5503
+ const [computed, setComputed] = useState(null);
5504
+ const recompute = useCallback(() => {
5505
+ const container = containerRef.current;
5506
+ if (!container) return;
5507
+ if (items.length === 0) {
5508
+ setComputed(null);
5509
+ return;
5510
+ }
5511
+ const positions = [];
5512
+ for (const item of items) {
5513
+ const el = container.querySelector(`a[href="${item.url}"]`);
5514
+ if (!el) {
5515
+ positions.push([0, 0]);
5516
+ continue;
5517
+ }
5518
+ const styles = window.getComputedStyle(el);
5519
+ const top = el.offsetTop + parseFloat(styles.paddingTop || "0");
5520
+ const bottom = el.offsetTop + el.clientHeight - parseFloat(styles.paddingBottom || "0");
5521
+ positions.push([top, bottom]);
5522
+ }
5523
+ setComputed({ positions });
5524
+ }, [items]);
5525
+ useLayoutEffect(() => {
5526
+ recompute();
5527
+ }, [recompute]);
5528
+ useEffect(() => {
5529
+ const container = containerRef.current;
5530
+ if (!container || typeof ResizeObserver === "undefined") return;
5531
+ const ro = new ResizeObserver(() => recompute());
5532
+ ro.observe(container);
5533
+ return () => ro.disconnect();
5534
+ }, [recompute]);
5535
+ return /* @__PURE__ */ jsxs("div", {
5536
+ className: "relative",
5537
+ children: [showThumb && computed && /* @__PURE__ */ jsx(TocThumb, { computed }), /* @__PURE__ */ jsx("div", {
5538
+ ref: containerRef,
5539
+ className: "flex flex-col border-l border-[var(--dashboard-text-secondary,#6b7280)]/15",
5540
+ children: items.map((item) => /* @__PURE__ */ jsx(TocAnchor, { item }, item.url))
5541
+ })]
5542
+ });
5543
+ }
5544
+ function ActiveChangeReporter({ onActiveChange }) {
5545
+ const ids = useActiveAnchors();
5546
+ const cbRef = useRef(onActiveChange);
5547
+ cbRef.current = onActiveChange;
5548
+ useEffect(() => {
5549
+ cbRef.current(ids);
5550
+ }, [ids]);
5551
+ return null;
5552
+ }
5553
+ function ActiveScrollSync({ linksRef }) {
5554
+ const activeId = useActiveAnchor();
5555
+ useEffect(() => {
5556
+ if (!activeId) return;
5557
+ const link = linksRef.current.get(activeId);
5558
+ if (!link) return;
5559
+ const container = findScrollableParent(link);
5560
+ if (container === document.documentElement) return;
5561
+ scrollAnchorIntoView(link, container);
5562
+ }, [activeId, linksRef]);
5563
+ return null;
5564
+ }
5565
+ /**
5566
+ * Adapted from Fumadocs (MIT) — https://github.com/fuma-nama/fumadocs
5567
+ *
5568
+ * Scrollspy table of contents. Renders a sticky list of headings and tracks
5569
+ * which are visible in the viewport via IntersectionObserver. The active
5570
+ * range is highlighted with a thin animated bar (TocThumb).
5571
+ */
5572
+ function TableOfContents({ items, title = "Nesta página", showThumb = true, single = false, rootMargin = "0px 0px -70% 0px", threshold = 0, className, onActiveChange }) {
5573
+ const linksRef = useRef(/* @__PURE__ */ new Map());
5574
+ return /* @__PURE__ */ jsx(TOCProvider, {
5575
+ items,
5576
+ single,
5577
+ rootMargin,
5578
+ threshold,
5579
+ children: /* @__PURE__ */ jsx(LinksRefContext.Provider, {
5580
+ value: linksRef,
5581
+ children: /* @__PURE__ */ jsxs("nav", {
5582
+ "aria-label": typeof title === "string" ? title : "Sumário",
5583
+ className: cn("text-sm", className),
5584
+ children: [
5585
+ title !== null && /* @__PURE__ */ jsxs("h3", {
5586
+ className: "inline-flex items-center gap-1.5 text-sm font-medium mb-3 text-[var(--dashboard-text-primary,#2d2d2d)]",
5587
+ children: [/* @__PURE__ */ jsx(Text, {
5588
+ className: "h-4 w-4",
5589
+ "aria-hidden": true
5590
+ }), title]
5591
+ }),
5592
+ /* @__PURE__ */ jsx(TocList, {
5593
+ items,
5594
+ showThumb
5595
+ }),
5596
+ onActiveChange && /* @__PURE__ */ jsx(ActiveChangeReporter, { onActiveChange }),
5597
+ /* @__PURE__ */ jsx(ActiveScrollSync, { linksRef })
5598
+ ]
5599
+ })
5600
+ })
5601
+ });
5602
+ }
5603
+
4293
5604
  //#endregion
4294
5605
  //#region src/config/defaults.ts
4295
5606
  const defaultConfig = {
@@ -4309,7 +5620,9 @@ const defaultConfig = {
4309
5620
  statusDanger: "#DC2626",
4310
5621
  statusWarning: "#D97706",
4311
5622
  statusInfo: "#2563EB",
4312
- statusNeutral: "#64748B"
5623
+ statusNeutral: "#64748B",
5624
+ tooltipBg: "#1a1a1a",
5625
+ tooltipText: "#ffffff"
4313
5626
  },
4314
5627
  components: {
4315
5628
  modal: {
@@ -4523,6 +5836,8 @@ function CSSVarsInjector({ config }) {
4523
5836
  root.style.setProperty("--dashboard-status-warning", colors.statusWarning);
4524
5837
  root.style.setProperty("--dashboard-status-info", colors.statusInfo);
4525
5838
  root.style.setProperty("--dashboard-status-neutral", colors.statusNeutral);
5839
+ root.style.setProperty("--dashboard-tooltip-bg", colors.tooltipBg);
5840
+ root.style.setProperty("--dashboard-tooltip-text", colors.tooltipText);
4526
5841
  }, [config]);
4527
5842
  return null;
4528
5843
  }
@@ -4535,5 +5850,50 @@ function DashboardProvider({ config: configOverrides, children }) {
4535
5850
  }
4536
5851
 
4537
5852
  //#endregion
4538
- export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Callout, Card, Checkbox, CodeBlock, 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 };
5853
+ //#region src/config/sizes.ts
5854
+ const componentSizes = {
5855
+ sm: {
5856
+ height: "h-8",
5857
+ paddingX: "px-3",
5858
+ paddingY: "py-0",
5859
+ font: "text-xs"
5860
+ },
5861
+ md: {
5862
+ height: "h-9",
5863
+ paddingX: "px-4",
5864
+ paddingY: "py-0",
5865
+ font: "text-sm"
5866
+ },
5867
+ lg: {
5868
+ height: "h-10",
5869
+ paddingX: "px-6",
5870
+ paddingY: "py-0",
5871
+ font: "text-base"
5872
+ }
5873
+ };
5874
+ const badgeSizes = {
5875
+ sm: {
5876
+ padding: "px-2 py-0.5",
5877
+ font: "text-xs"
5878
+ },
5879
+ md: {
5880
+ padding: "px-3 py-1",
5881
+ font: "text-sm"
5882
+ },
5883
+ lg: {
5884
+ padding: "px-3 py-1",
5885
+ font: "text-sm"
5886
+ }
5887
+ };
5888
+ const modalSizes = {
5889
+ sm: "max-w-sm",
5890
+ md: "max-w-md",
5891
+ lg: "max-w-lg",
5892
+ xl: "max-w-2xl",
5893
+ "2xl": "max-w-4xl",
5894
+ "3xl": "max-w-screen-xl"
5895
+ };
5896
+
5897
+ //#endregion
5898
+ export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Callout, Card, Checkbox, CodeBlock, CodeInput, Combobox, ComparisonLineChart, DashboardProvider, DataGrid, DatePicker, DateRangePicker, DoughnutChart, Dropdown, EmptyState, FileUpload, FilterBar, FormField, Header, HorizontalBarChart, InfoTooltip, Input, KPICard, Loading, LoadingProvider, MetricPanel, Modal, NotificationsProvider, PageLayout, Pagination, ProgressBarList, Sidebar, Skeleton, StatusBadge, Stepper, TOCProvider, Table, TableBody, TableEmpty, TableHeader, TableOfContents, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, badgeSizes, componentSizes, createColumnHelper, createConfig, defaultConfig, modalSizes, useActiveAnchor, useActiveAnchors, useConfig, useLoading, useNotifications, useTOCItems, useTheme };
4539
5899
  //# sourceMappingURL=index.mjs.map