@tree-ia/design-system 1.6.0 → 2.0.0

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, 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$34 = (...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$34(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$33 = (...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$33("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$32 = (...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$32("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$32("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$32("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$32("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$32("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$32("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$31 = (...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$31("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$31("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$31("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$30 = (...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$30("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$30("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$29 = (...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$29(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$28 = (...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$28("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$28("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$28("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$28("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$27 = (...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$27("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$26 = (...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$26("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$26("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$26("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$26("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$26("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$26("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$26("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,7 +1593,440 @@ 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$25 = (...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$25("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$25("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$25("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$25("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$25("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$25("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$25("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$25("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$25("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$25("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$25("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
@@ -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
2097
  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),
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",
@@ -1548,43 +2143,55 @@ function KPICardSkeleton({ className }) {
1548
2143
  //#endregion
1549
2144
  //#region src/components/PageLayout/index.tsx
1550
2145
  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 }) {
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$22("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$22(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$22(layoutContainer, "py-6") : "",
2190
+ children
2191
+ })
2192
+ ]
2193
+ })
2194
+ ]
1588
2195
  });
1589
2196
  }
1590
2197
 
@@ -2108,18 +2715,236 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
2108
2715
  //#region src/components/MetricPanel/index.tsx
2109
2716
  Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
2110
2717
  const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
2111
- function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, secondaryColor, onActionClick, actionLabel, isLoading = false, className }) {
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: {
@@ -3664,13 +4493,15 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
3664
4493
  const cn$7 = (...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,20 +4596,85 @@ 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$7("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$7("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
4680
  const cn$6 = (...classes) => classes.filter(Boolean).join(" ");
@@ -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 = {
@@ -4309,7 +5240,9 @@ const defaultConfig = {
4309
5240
  statusDanger: "#DC2626",
4310
5241
  statusWarning: "#D97706",
4311
5242
  statusInfo: "#2563EB",
4312
- statusNeutral: "#64748B"
5243
+ statusNeutral: "#64748B",
5244
+ tooltipBg: "#1a1a1a",
5245
+ tooltipText: "#ffffff"
4313
5246
  },
4314
5247
  components: {
4315
5248
  modal: {
@@ -4523,6 +5456,8 @@ function CSSVarsInjector({ config }) {
4523
5456
  root.style.setProperty("--dashboard-status-warning", colors.statusWarning);
4524
5457
  root.style.setProperty("--dashboard-status-info", colors.statusInfo);
4525
5458
  root.style.setProperty("--dashboard-status-neutral", colors.statusNeutral);
5459
+ root.style.setProperty("--dashboard-tooltip-bg", colors.tooltipBg);
5460
+ root.style.setProperty("--dashboard-tooltip-text", colors.tooltipText);
4526
5461
  }, [config]);
4527
5462
  return null;
4528
5463
  }
@@ -4535,5 +5470,50 @@ function DashboardProvider({ config: configOverrides, children }) {
4535
5470
  }
4536
5471
 
4537
5472
  //#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 };
5473
+ //#region src/config/sizes.ts
5474
+ const componentSizes = {
5475
+ sm: {
5476
+ height: "h-8",
5477
+ paddingX: "px-3",
5478
+ paddingY: "py-0",
5479
+ font: "text-xs"
5480
+ },
5481
+ md: {
5482
+ height: "h-9",
5483
+ paddingX: "px-4",
5484
+ paddingY: "py-0",
5485
+ font: "text-sm"
5486
+ },
5487
+ lg: {
5488
+ height: "h-10",
5489
+ paddingX: "px-6",
5490
+ paddingY: "py-0",
5491
+ font: "text-base"
5492
+ }
5493
+ };
5494
+ const badgeSizes = {
5495
+ sm: {
5496
+ padding: "px-2 py-0.5",
5497
+ font: "text-xs"
5498
+ },
5499
+ md: {
5500
+ padding: "px-3 py-1",
5501
+ font: "text-sm"
5502
+ },
5503
+ lg: {
5504
+ padding: "px-3 py-1",
5505
+ font: "text-sm"
5506
+ }
5507
+ };
5508
+ const modalSizes = {
5509
+ sm: "max-w-sm",
5510
+ md: "max-w-md",
5511
+ lg: "max-w-lg",
5512
+ xl: "max-w-2xl",
5513
+ "2xl": "max-w-4xl",
5514
+ "3xl": "max-w-screen-xl"
5515
+ };
5516
+
5517
+ //#endregion
5518
+ 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, Table, TableBody, TableEmpty, TableHeader, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, badgeSizes, componentSizes, createColumnHelper, createConfig, defaultConfig, modalSizes, useConfig, useLoading, useNotifications, useTheme };
4539
5519
  //# sourceMappingURL=index.mjs.map