@mlw-packages/react-components 1.5.7 → 1.5.9

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.js CHANGED
@@ -500,6 +500,7 @@ __export(index_exports, {
500
500
  AvatarFallbackBase: () => AvatarFallbackBase,
501
501
  AvatarImageBase: () => AvatarImageBase,
502
502
  BadgeBase: () => BadgeBase,
503
+ BarChart: () => BarChart_default,
503
504
  BreadcrumbBase: () => BreadcrumbBase,
504
505
  BreadcrumbEllipsisBase: () => BreadcrumbEllipsisBase,
505
506
  BreadcrumbItemBase: () => BreadcrumbItemBase,
@@ -521,6 +522,7 @@ __export(index_exports, {
521
522
  CarouselItemBase: () => CarouselItemBase,
522
523
  CarouselNextBase: () => CarouselNextBase,
523
524
  CarouselPrevious: () => CarouselPrevious,
525
+ Chart: () => Chart_default,
524
526
  CheckboxBase: () => CheckboxBase,
525
527
  CloseAllButton: () => CloseAllButton_default,
526
528
  CollapsibleBase: () => CollapsibleBase,
@@ -599,6 +601,7 @@ __export(index_exports, {
599
601
  InputOTPSeparatorBase: () => InputOTPSeparatorBase,
600
602
  InputOTPSlotBase: () => InputOTPSlotBase,
601
603
  LabelBase: () => LabelBase_default,
604
+ LineChart: () => LineChart_default,
602
605
  LoadingBase: () => LoadingBase,
603
606
  ModeToggleBase: () => ModeToggleBase,
604
607
  MultiCombobox: () => MultiCombobox,
@@ -611,6 +614,7 @@ __export(index_exports, {
611
614
  NavigationMenuTriggerBase: () => NavigationMenuTriggerBase,
612
615
  NavigationMenuViewportBase: () => NavigationMenuViewportBase,
613
616
  PeriodsDropdown: () => PeriodsDropdown_default,
617
+ PieChart: () => PieChart_default,
614
618
  PopoverAnchorBase: () => PopoverAnchorBase,
615
619
  PopoverBase: () => PopoverBase,
616
620
  PopoverContentBase: () => PopoverContentBase,
@@ -706,6 +710,7 @@ __export(index_exports, {
706
710
  resolveChartMargins: () => resolveChartMargins,
707
711
  resolveContainerPaddingLeft: () => resolveContainerPaddingLeft,
708
712
  toast: () => toast,
713
+ useChartHighlights: () => useChartHighlights,
709
714
  useDrag: () => useDrag,
710
715
  useIsMobile: () => useIsMobile,
711
716
  useTheme: () => useTheme
@@ -729,19 +734,19 @@ var import_react_slot = require("@radix-ui/react-slot");
729
734
  var import_class_variance_authority = require("class-variance-authority");
730
735
  var import_jsx_runtime = require("react/jsx-runtime");
731
736
  var buttonVariantsBase = (0, import_class_variance_authority.cva)(
732
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
737
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive active:scale-95",
733
738
  {
734
739
  variants: {
735
740
  variant: {
736
741
  default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
737
742
  destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
738
- outline: "bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
743
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-background dark:border-input dark:hover:bg-background/95",
739
744
  secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
740
745
  ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
741
746
  link: "text-primary underline-offset-4 hover:underline"
742
747
  },
743
748
  size: {
744
- default: " px-4 py-2 has-[>svg]:px-3",
749
+ default: "h-9 py-2 px-4 has-[>svg]:px-3",
745
750
  sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
746
751
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
747
752
  icon: "size-9"
@@ -2367,7 +2372,7 @@ var InputBase = React12.forwardRef(
2367
2372
  "div",
2368
2373
  {
2369
2374
  className: cn(
2370
- "flex items-center rounded-md transition focus-within:ring-1 focus-within:ring-ring focus-within:border-ring bg-background overflow-hidden",
2375
+ "flex items-center rounded-md transition h-9 focus-within:ring-1 focus-within:ring-ring focus-within:border-ring bg-background overflow-hidden",
2371
2376
  type !== "file" && "border border-input"
2372
2377
  ),
2373
2378
  children: [
@@ -2377,7 +2382,7 @@ var InputBase = React12.forwardRef(
2377
2382
  {
2378
2383
  type,
2379
2384
  className: cn(
2380
- "w-full flex-1 text-sm py-2 px-3 focus:outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 bg-background text-foreground",
2385
+ "w-full flex-1 text-sm p-1.5 px-3 focus:outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 bg-background text-foreground",
2381
2386
  className
2382
2387
  ),
2383
2388
  ref,
@@ -2452,7 +2457,7 @@ function ComboboxBase({
2452
2457
  role: "combobox",
2453
2458
  "aria-expanded": open,
2454
2459
  className: cn(
2455
- "flex items-start gap-2 justify-between h-full border border-input",
2460
+ "flex items-start gap-2 justify-between",
2456
2461
  errorMessage && "border-red-500"
2457
2462
  ),
2458
2463
  "data-testid": testIds.trigger ?? "combobox-trigger",
@@ -3123,34 +3128,78 @@ function NavigationMenuIndicatorBase({
3123
3128
  var React17 = __toESM(require("react"));
3124
3129
  var ProgressPrimitive = __toESM(require("@radix-ui/react-progress"));
3125
3130
  var import_jsx_runtime28 = require("react/jsx-runtime");
3126
- var ProgressBase = React17.forwardRef(({ className, value, label, leftIcon, rightIcon, ...props }, ref) => {
3127
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
3128
- label && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(LabelBase_default, { className: "py-2", children: label }),
3129
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-2", children: [
3130
- leftIcon && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center", children: leftIcon }),
3131
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3132
- ProgressPrimitive.Root,
3133
- {
3134
- ref,
3135
- className: cn(
3136
- "relative h-3 w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-800 shadow-inner transition-all",
3137
- className
3138
- ),
3139
- value,
3140
- ...props,
3141
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3142
- ProgressPrimitive.Indicator,
3143
- {
3144
- className: "h-full w-full flex-1 bg-primary transition-all duration-500 ease-in-out",
3145
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
3146
- }
3147
- )
3148
- }
3149
- ),
3150
- rightIcon && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center", children: rightIcon })
3151
- ] })
3152
- ] });
3153
- });
3131
+ var ProgressBase = React17.forwardRef(
3132
+ ({
3133
+ className,
3134
+ value,
3135
+ label,
3136
+ leftIcon,
3137
+ rightIcon,
3138
+ variant = "bar",
3139
+ segments = 5,
3140
+ steps = [],
3141
+ currentStep = 0,
3142
+ ...props
3143
+ }, ref) => {
3144
+ switch (variant) {
3145
+ case "segments":
3146
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3147
+ ProgressSegmentsBase,
3148
+ {
3149
+ label,
3150
+ segments,
3151
+ value: value || 0
3152
+ }
3153
+ );
3154
+ case "panels":
3155
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3156
+ ProgressPanelsBase,
3157
+ {
3158
+ label,
3159
+ steps,
3160
+ currentStep
3161
+ }
3162
+ );
3163
+ case "circles":
3164
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3165
+ ProgressCirclesBase,
3166
+ {
3167
+ label,
3168
+ steps,
3169
+ currentStep
3170
+ }
3171
+ );
3172
+ case "bar":
3173
+ default:
3174
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
3175
+ label && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(LabelBase_default, { className: "py-2", children: label }),
3176
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-2", children: [
3177
+ leftIcon && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center", children: leftIcon }),
3178
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3179
+ ProgressPrimitive.Root,
3180
+ {
3181
+ ref,
3182
+ className: cn(
3183
+ "relative h-3 w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-800 shadow-inner transition-all",
3184
+ className
3185
+ ),
3186
+ value,
3187
+ ...props,
3188
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3189
+ ProgressPrimitive.Indicator,
3190
+ {
3191
+ className: "h-full w-full flex-1 bg-primary transition-all duration-500 ease-in-out",
3192
+ style: { transform: `translateX(-${100 - (value || 0)}%)` }
3193
+ }
3194
+ )
3195
+ }
3196
+ ),
3197
+ rightIcon && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex items-center justify-center", children: rightIcon })
3198
+ ] })
3199
+ ] });
3200
+ }
3201
+ }
3202
+ );
3154
3203
  ProgressBase.displayName = "ProgressBase";
3155
3204
  var ProgressSegmentsBase = ({
3156
3205
  label,
@@ -4453,7 +4502,8 @@ var TabsListBase = React27.forwardRef(({ className, ...props }, ref) => /* @__PU
4453
4502
  {
4454
4503
  ref,
4455
4504
  className: cn(
4456
- "relative flex w-full items-center justify-start gap-4 border-b-2 border-border",
4505
+ "relative flex w-full items-center justify-start gap-2 border-b border-border",
4506
+ "bg-transparent",
4457
4507
  className
4458
4508
  ),
4459
4509
  ...props
@@ -4465,13 +4515,15 @@ var TabsTriggerBase = React27.forwardRef(({ className, ...props }, ref) => /* @_
4465
4515
  {
4466
4516
  ref,
4467
4517
  className: cn(
4468
- "relative inline-flex items-center justify-center whitespace-nowrap px-3 py-2 text-sm font-medium transition-colors",
4469
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-3",
4518
+ "relative inline-flex items-center justify-center whitespace-nowrap px-4 py-2 text-sm font-medium",
4519
+ "text-muted-foreground hover:text-foreground",
4520
+ "transition-colors duration-300 ease-in-out",
4521
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4470
4522
  "disabled:pointer-events-none disabled:opacity-50",
4471
4523
  "data-[state=active]:text-primary",
4472
- "after:absolute after:bottom-0 after:left-0 after:h-[1.5px] after:w-full",
4524
+ "after:absolute after:bottom-0 after:left-0 after:h-[2px] after:w-full",
4473
4525
  "after:scale-x-0 after:bg-primary after:origin-left",
4474
- "after:transition-transform after:duration-300 after:ease-[cubic-bezier(0.65,0,0.35,1)]",
4526
+ "after:transition-transform after:duration-500 after:ease-[cubic-bezier(0.34,1.56,0.64,1)]",
4475
4527
  "data-[state=active]:after:scale-x-100",
4476
4528
  className
4477
4529
  ),
@@ -4483,8 +4535,8 @@ var TabsContentBase = React27.forwardRef(({ className, ...props }, ref) => /* @_
4483
4535
  {
4484
4536
  ref,
4485
4537
  className: cn(
4486
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4487
- "animate-fade-in",
4538
+ "mt-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4539
+ "animate-in fade-in-0 duration-500 ease-in-out",
4488
4540
  className
4489
4541
  ),
4490
4542
  ...props
@@ -4494,41 +4546,198 @@ TabsContentBase.displayName = TabsPrimitive.Content.displayName;
4494
4546
 
4495
4547
  // src/components/ui/TextAreaBase.tsx
4496
4548
  var React28 = __toESM(require("react"));
4549
+ var import_framer_motion6 = require("framer-motion");
4550
+ var import_react23 = require("@phosphor-icons/react");
4497
4551
  var import_jsx_runtime40 = require("react/jsx-runtime");
4498
- var TextAreaBase = React28.forwardRef(({ className, ...props }, ref) => {
4499
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4500
- "textarea",
4501
- {
4502
- className: cn(
4503
- "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
4504
- className
4552
+ var TextAreaBase = React28.forwardRef(
4553
+ ({ className, clearable = false, onClear, ...props }, ref) => {
4554
+ const [isFocused, setIsFocused] = React28.useState(false);
4555
+ const [hasContent, setHasContent] = React28.useState(
4556
+ !!props.value || !!props.defaultValue
4557
+ );
4558
+ const [showConfirmTooltip, setShowConfirmTooltip] = React28.useState(false);
4559
+ const textareaRef = React28.useRef(null);
4560
+ const handleFocus = (e) => {
4561
+ setIsFocused(true);
4562
+ props.onFocus?.(e);
4563
+ };
4564
+ const handleBlur = (e) => {
4565
+ setIsFocused(false);
4566
+ props.onBlur?.(e);
4567
+ };
4568
+ const handleChange = (e) => {
4569
+ setHasContent(e.target.value.length > 0);
4570
+ props.onChange?.(e);
4571
+ };
4572
+ const handleClearClick = () => {
4573
+ setShowConfirmTooltip(true);
4574
+ };
4575
+ const handleConfirmClear = () => {
4576
+ if (textareaRef.current) {
4577
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
4578
+ window.HTMLTextAreaElement.prototype,
4579
+ "value"
4580
+ )?.set;
4581
+ if (nativeInputValueSetter) {
4582
+ nativeInputValueSetter.call(textareaRef.current, "");
4583
+ const event = new Event("input", { bubbles: true });
4584
+ textareaRef.current.dispatchEvent(event);
4585
+ }
4586
+ setHasContent(false);
4587
+ setShowConfirmTooltip(false);
4588
+ textareaRef.current.focus();
4589
+ onClear?.();
4590
+ }
4591
+ };
4592
+ const handleCancelClear = () => {
4593
+ setShowConfirmTooltip(false);
4594
+ };
4595
+ React28.useImperativeHandle(ref, () => textareaRef.current);
4596
+ React28.useEffect(() => {
4597
+ setHasContent(!!props.value || !!props.defaultValue);
4598
+ }, [props.value, props.defaultValue]);
4599
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "relative", children: [
4600
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4601
+ "textarea",
4602
+ {
4603
+ className: cn(
4604
+ "peer flex min-h-[80px] min-w-[200px] w-full rounded-lg border border-input bg-background/50 backdrop-blur-sm",
4605
+ "px-4 py-3 text-base shadow-sm placeholder:text-muted-foreground/60",
4606
+ "transition-all duration-300 ease-out",
4607
+ "hover:border-input/80 hover:shadow-md",
4608
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:border-ring",
4609
+ "focus-visible:shadow-lg focus-visible:bg-background",
4610
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-muted/30",
4611
+ "resize",
4612
+ "md:text-sm",
4613
+ clearable && hasContent && "pr-10",
4614
+ className
4615
+ ),
4616
+ ref: textareaRef,
4617
+ onFocus: handleFocus,
4618
+ onBlur: handleBlur,
4619
+ onChange: handleChange,
4620
+ ...props
4621
+ }
4505
4622
  ),
4506
- ref,
4507
- ...props
4508
- }
4509
- );
4510
- });
4623
+ clearable && hasContent && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TooltipProviderBase, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4624
+ TooltipBase,
4625
+ {
4626
+ open: showConfirmTooltip,
4627
+ onOpenChange: setShowConfirmTooltip,
4628
+ children: [
4629
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(TooltipTriggerBase, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4630
+ import_framer_motion6.motion.button,
4631
+ {
4632
+ type: "button",
4633
+ initial: { opacity: 0, scale: 0.8 },
4634
+ animate: { opacity: 1, scale: 1 },
4635
+ exit: { opacity: 0, scale: 0.8 },
4636
+ transition: { duration: 0.2 },
4637
+ onClick: handleClearClick,
4638
+ className: cn(
4639
+ "absolute top-3 right-3 p-1.5 rounded-md",
4640
+ "text-muted-foreground/50 hover:text-destructive hover:bg-destructive/10",
4641
+ "transition-all duration-200",
4642
+ "focus:outline-none focus:ring-2 focus:ring-destructive/30",
4643
+ "disabled:opacity-50 disabled:cursor-not-allowed"
4644
+ ),
4645
+ disabled: props.disabled,
4646
+ "aria-label": "Limpar texto",
4647
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react23.TrashIcon, { size: 16, weight: "regular" })
4648
+ }
4649
+ ) }),
4650
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4651
+ TooltipContentBase,
4652
+ {
4653
+ side: "left",
4654
+ className: "bg-background border border-border shadow-lg p-3 flex flex-col gap-2",
4655
+ children: [
4656
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("p", { className: "text-sm text-foreground font-medium mb-1", children: "Limpar todo o texto?" }),
4657
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex gap-2", children: [
4658
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4659
+ "button",
4660
+ {
4661
+ type: "button",
4662
+ onClick: handleConfirmClear,
4663
+ className: cn(
4664
+ "px-3 py-1.5 text-xs rounded-md font-medium",
4665
+ "bg-destructive text-destructive-foreground",
4666
+ "hover:bg-destructive/90",
4667
+ "transition-colors"
4668
+ ),
4669
+ children: "Confirmar"
4670
+ }
4671
+ ),
4672
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4673
+ "button",
4674
+ {
4675
+ type: "button",
4676
+ onClick: handleCancelClear,
4677
+ className: cn(
4678
+ "px-3 py-1.5 text-xs rounded-md font-medium",
4679
+ "bg-secondary text-secondary-foreground",
4680
+ "hover:bg-secondary/80",
4681
+ "transition-colors"
4682
+ ),
4683
+ children: "Cancelar"
4684
+ }
4685
+ )
4686
+ ] })
4687
+ ]
4688
+ }
4689
+ )
4690
+ ]
4691
+ }
4692
+ ) }),
4693
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4694
+ import_framer_motion6.motion.div,
4695
+ {
4696
+ className: "pointer-events-none absolute inset-0 rounded-lg",
4697
+ initial: { opacity: 0 },
4698
+ animate: { opacity: isFocused ? 1 : 0 },
4699
+ transition: { duration: 0.3 },
4700
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "absolute inset-0 rounded-lg bg-gradient-to-r from-ring/20 via-ring/10 to-ring/20 blur-sm" })
4701
+ }
4702
+ ),
4703
+ isFocused && hasContent && props.maxLength && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4704
+ import_framer_motion6.motion.div,
4705
+ {
4706
+ initial: { opacity: 0, y: -10 },
4707
+ animate: { opacity: 1, y: 0 },
4708
+ exit: { opacity: 0, y: -10 },
4709
+ className: "absolute bottom-2 right-3 text-xs text-muted-foreground/70 font-medium",
4710
+ children: [
4711
+ props.value?.length || 0,
4712
+ " / ",
4713
+ props.maxLength
4714
+ ]
4715
+ }
4716
+ )
4717
+ ] });
4718
+ }
4719
+ );
4511
4720
  TextAreaBase.displayName = "TextAreaBase";
4512
4721
 
4513
4722
  // src/components/mode-toggle.tsx
4514
- var import_react24 = require("@phosphor-icons/react");
4723
+ var import_react25 = require("@phosphor-icons/react");
4515
4724
 
4516
4725
  // src/components/theme-provider.tsx
4517
- var import_react23 = require("react");
4726
+ var import_react24 = require("react");
4518
4727
  var import_jsx_runtime41 = require("react/jsx-runtime");
4519
4728
  var initialState = {
4520
4729
  theme: "system",
4521
4730
  setTheme: () => null
4522
4731
  };
4523
- var ThemeProviderContext = (0, import_react23.createContext)(initialState);
4732
+ var ThemeProviderContext = (0, import_react24.createContext)(initialState);
4524
4733
  function ThemeProviderBase({
4525
4734
  children,
4526
4735
  defaultTheme = "system",
4527
4736
  storageKey = "app-ui-theme",
4528
4737
  ...props
4529
4738
  }) {
4530
- const [theme, setThemeState] = (0, import_react23.useState)(defaultTheme);
4531
- (0, import_react23.useEffect)(() => {
4739
+ const [theme, setThemeState] = (0, import_react24.useState)(defaultTheme);
4740
+ (0, import_react24.useEffect)(() => {
4532
4741
  const root = window.document.documentElement;
4533
4742
  root.classList.remove(
4534
4743
  "light",
@@ -4554,7 +4763,7 @@ function ThemeProviderBase({
4554
4763
  document.body.style.color = "";
4555
4764
  }
4556
4765
  }, [theme]);
4557
- (0, import_react23.useEffect)(() => {
4766
+ (0, import_react24.useEffect)(() => {
4558
4767
  const stored = localStorage.getItem(storageKey);
4559
4768
  if (stored) setThemeState(stored);
4560
4769
  }, [storageKey]);
@@ -4568,7 +4777,7 @@ function ThemeProviderBase({
4568
4777
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
4569
4778
  }
4570
4779
  var useTheme = () => {
4571
- const context = (0, import_react23.useContext)(ThemeProviderContext);
4780
+ const context = (0, import_react24.useContext)(ThemeProviderContext);
4572
4781
  if (context === void 0)
4573
4782
  throw new Error("useTheme must be used within a ThemeProvider");
4574
4783
  return context;
@@ -4601,8 +4810,8 @@ function ModeToggleBase({
4601
4810
  className: "relative overflow-hidden border-transparent",
4602
4811
  children: [
4603
4812
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
4604
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react24.SunIcon, { className: `h-[1.2rem] w-[1.2rem] transition-transform duration-300 ${isDark ? "rotate-90 scale-0" : "rotate-0 scale-100"}` }),
4605
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react24.MoonIcon, { className: `absolute h-[1.2rem] w-[1.2rem] transition-transform duration-300 ${isDark ? "rotate-0 scale-100" : "rotate-90 scale-0"}` })
4813
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react25.SunIcon, { className: `h-[1.2rem] w-[1.2rem] transition-transform duration-300 ${isDark ? "rotate-90 scale-0" : "rotate-0 scale-100"}` }),
4814
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react25.MoonIcon, { className: `absolute h-[1.2rem] w-[1.2rem] transition-transform duration-300 ${isDark ? "rotate-0 scale-100" : "rotate-90 scale-0"}` })
4606
4815
  ] }),
4607
4816
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "sr-only", children: "Toggle theme" })
4608
4817
  ]
@@ -4615,7 +4824,7 @@ function ModeToggleBase({
4615
4824
  className: "flex items-center justify-between hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground",
4616
4825
  children: [
4617
4826
  themeLabels[theme],
4618
- currentTheme === theme && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react24.CheckIcon, { className: "h-4 w-4 opacity-100" })
4827
+ currentTheme === theme && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react25.CheckIcon, { className: "h-4 w-4 opacity-100" })
4619
4828
  ]
4620
4829
  },
4621
4830
  theme
@@ -4623,43 +4832,119 @@ function ModeToggleBase({
4623
4832
  ] });
4624
4833
  }
4625
4834
 
4835
+ // src/components/ui/DestructiveDialog.tsx
4836
+ var React29 = __toESM(require("react"));
4837
+ var import_react26 = require("@phosphor-icons/react");
4838
+ var import_jsx_runtime43 = require("react/jsx-runtime");
4839
+ var DestructiveDialog = ({
4840
+ title,
4841
+ description,
4842
+ onConfirm,
4843
+ onCancel,
4844
+ children,
4845
+ triggerContent
4846
+ }) => {
4847
+ const titleId = "destructive-dialog-title";
4848
+ const descriptionId = "destructive-dialog-description";
4849
+ const triggerEl = React29.isValidElement(children) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(AlertDialogTriggerBase, { asChild: true, children }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(AlertDialogTriggerBase, { children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ButtonBase, { variant: "destructive", children: triggerContent ?? "Excluir" }) });
4850
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(AlertDialogBase, { children: [
4851
+ triggerEl,
4852
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
4853
+ AlertDialogContentBase,
4854
+ {
4855
+ role: "alertdialog",
4856
+ "aria-modal": "true",
4857
+ "aria-labelledby": titleId,
4858
+ "aria-describedby": descriptionId,
4859
+ className: cn("border border-destructive bg-background"),
4860
+ children: [
4861
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-start gap-4", children: [
4862
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex items-center justify-center w-10 h-10 rounded-full ring-1 ring-destructive/30", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react26.XCircleIcon, { className: "w-6 h-6 text-destructive" }) }),
4863
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex-1", children: [
4864
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4865
+ AlertDialogTitleBase,
4866
+ {
4867
+ id: titleId,
4868
+ className: "text-lg sm:text-xl font-semibold text-destructive",
4869
+ children: title
4870
+ }
4871
+ ),
4872
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4873
+ AlertDialogDescriptionBase,
4874
+ {
4875
+ id: descriptionId,
4876
+ className: "mt-2 text-sm text-muted-foreground",
4877
+ children: description
4878
+ }
4879
+ )
4880
+ ] })
4881
+ ] }),
4882
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(AlertDialogFooterBase, { className: "mt-2 flex justify-end gap-3", children: [
4883
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4884
+ AlertDialogCancelBase,
4885
+ {
4886
+ onClick: onCancel,
4887
+ className: cn(
4888
+ buttonVariantsBase({ variant: "outline", size: "default" }),
4889
+ "hover:bg-foreground/5 hover:text-primary hover:opacity-90 hover:shadow-none"
4890
+ ),
4891
+ children: "Cancelar"
4892
+ }
4893
+ ),
4894
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4895
+ AlertDialogActionBase,
4896
+ {
4897
+ onClick: onConfirm,
4898
+ className: cn(
4899
+ buttonVariantsBase({ variant: "destructive", size: "default" })
4900
+ ),
4901
+ children: "Confirmar"
4902
+ }
4903
+ )
4904
+ ] })
4905
+ ]
4906
+ }
4907
+ )
4908
+ ] });
4909
+ };
4910
+
4626
4911
  // src/components/date-time-picker/DateTimePicker.tsx
4627
4912
  var import_date_fns = require("date-fns");
4628
4913
 
4629
4914
  // src/components/date-time-picker/calendar.tsx
4630
- var React29 = __toESM(require("react"));
4915
+ var React30 = __toESM(require("react"));
4631
4916
  var import_react_day_picker2 = require("react-day-picker");
4632
- var import_react25 = require("@phosphor-icons/react");
4633
- var import_framer_motion6 = require("framer-motion");
4634
- var import_jsx_runtime43 = require("react/jsx-runtime");
4917
+ var import_react27 = require("@phosphor-icons/react");
4918
+ var import_framer_motion7 = require("framer-motion");
4919
+ var import_jsx_runtime44 = require("react/jsx-runtime");
4635
4920
  function CalendarBase2({
4636
4921
  className,
4637
4922
  classNames,
4638
4923
  showOutsideDays = true,
4639
4924
  ...props
4640
4925
  }) {
4641
- const [month, setMonth] = React29.useState(
4926
+ const [month, setMonth] = React30.useState(
4642
4927
  props.month || props.defaultMonth || /* @__PURE__ */ new Date()
4643
4928
  );
4644
- const [direction, setDirection] = React29.useState(1);
4929
+ const [direction, setDirection] = React30.useState(1);
4645
4930
  const handleMonthChange = (newMonth) => {
4646
4931
  const isNext = newMonth > month ? 1 : -1;
4647
4932
  setDirection(isNext);
4648
4933
  setMonth(newMonth);
4649
4934
  props.onMonthChange?.(newMonth);
4650
4935
  };
4651
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4936
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4652
4937
  "div",
4653
4938
  {
4654
4939
  className: cn(
4655
- "rounded-2xl border bg-background p-4 shadow-lg overflow-hidden w-full h-full flex flex-col",
4940
+ "rounded-md border bg-background p-4 shadow-lg overflow-hidden w-full h-full flex flex-col",
4656
4941
  className
4657
4942
  ),
4658
- children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "relative flex-1 flex flex-col min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_framer_motion6.AnimatePresence, { initial: false, mode: "wait", custom: direction, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4943
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "relative flex-1 flex flex-col min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_framer_motion7.AnimatePresence, { initial: false, mode: "wait", custom: direction, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4659
4944
  "div",
4660
4945
  {
4661
4946
  className: "w-full h-full flex flex-col",
4662
- children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4947
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4663
4948
  import_react_day_picker2.DayPicker,
4664
4949
  {
4665
4950
  showOutsideDays,
@@ -4708,8 +4993,8 @@ function CalendarBase2({
4708
4993
  ...classNames
4709
4994
  },
4710
4995
  components: {
4711
- IconLeft: () => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react25.CaretLeftIcon, { className: "h-4 w-4" }),
4712
- IconRight: () => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react25.CaretRightIcon, { className: "h-4 w-4" })
4996
+ IconLeft: () => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react27.CaretLeftIcon, { className: "h-4 w-4" }),
4997
+ IconRight: () => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react27.CaretRightIcon, { className: "h-4 w-4" })
4713
4998
  },
4714
4999
  ...props
4715
5000
  }
@@ -4724,15 +5009,15 @@ CalendarBase2.displayName = "CalendarBase";
4724
5009
 
4725
5010
  // src/components/date-time-picker/DateTimePicker.tsx
4726
5011
  var import_locale = require("date-fns/locale");
4727
- var import_react28 = require("react");
5012
+ var import_react30 = require("react");
4728
5013
 
4729
5014
  // src/components/date-time-picker/TimePicker.tsx
4730
- var import_framer_motion7 = require("framer-motion");
4731
- var React31 = __toESM(require("react"));
5015
+ var import_framer_motion8 = require("framer-motion");
5016
+ var React32 = __toESM(require("react"));
4732
5017
 
4733
5018
  // src/components/date-time-picker/TimePickerInput.tsx
4734
- var import_react26 = require("@phosphor-icons/react");
4735
- var import_react27 = __toESM(require("react"));
5019
+ var import_react28 = require("@phosphor-icons/react");
5020
+ var import_react29 = __toESM(require("react"));
4736
5021
 
4737
5022
  // src/components/date-time-picker/time-picker-utils.ts
4738
5023
  function isValidHour(value) {
@@ -4874,8 +5159,8 @@ function display12HourValue(hours) {
4874
5159
  }
4875
5160
 
4876
5161
  // src/components/date-time-picker/TimePickerInput.tsx
4877
- var import_jsx_runtime44 = require("react/jsx-runtime");
4878
- var TimePickerInput = import_react27.default.forwardRef(
5162
+ var import_jsx_runtime45 = require("react/jsx-runtime");
5163
+ var TimePickerInput = import_react29.default.forwardRef(
4879
5164
  ({
4880
5165
  className,
4881
5166
  type = "tel",
@@ -4894,10 +5179,10 @@ var TimePickerInput = import_react27.default.forwardRef(
4894
5179
  label,
4895
5180
  ...props
4896
5181
  }, ref) => {
4897
- const [flag, setFlag] = import_react27.default.useState(false);
4898
- const [prevIntKey, setPrevIntKey] = import_react27.default.useState("0");
4899
- const [isFocused, setIsFocused] = import_react27.default.useState(false);
4900
- import_react27.default.useEffect(() => {
5182
+ const [flag, setFlag] = import_react29.default.useState(false);
5183
+ const [prevIntKey, setPrevIntKey] = import_react29.default.useState("0");
5184
+ const [isFocused, setIsFocused] = import_react29.default.useState(false);
5185
+ import_react29.default.useEffect(() => {
4901
5186
  if (flag) {
4902
5187
  const timer = setTimeout(() => {
4903
5188
  setFlag(false);
@@ -4905,7 +5190,7 @@ var TimePickerInput = import_react27.default.forwardRef(
4905
5190
  return () => clearTimeout(timer);
4906
5191
  }
4907
5192
  }, [flag]);
4908
- const calculatedValue = import_react27.default.useMemo(() => {
5193
+ const calculatedValue = import_react29.default.useMemo(() => {
4909
5194
  return getDateByType(date, picker);
4910
5195
  }, [date, picker]);
4911
5196
  const calculateNewValue = (key) => {
@@ -4961,8 +5246,8 @@ var TimePickerInput = import_react27.default.forwardRef(
4961
5246
  const baseLabel = getPickerLabel();
4962
5247
  return `${baseLabel}, valor atual: ${calculatedValue}.`;
4963
5248
  };
4964
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "relative group flex flex-col items-center", children: [
4965
- getPickerLabel() && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5249
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "relative group flex flex-col items-center", children: [
5250
+ getPickerLabel() && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4966
5251
  "label",
4967
5252
  {
4968
5253
  htmlFor: id || picker,
@@ -4970,7 +5255,7 @@ var TimePickerInput = import_react27.default.forwardRef(
4970
5255
  children: getPickerLabel()
4971
5256
  }
4972
5257
  ),
4973
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
5258
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
4974
5259
  "div",
4975
5260
  {
4976
5261
  className: cn(
@@ -4978,7 +5263,7 @@ var TimePickerInput = import_react27.default.forwardRef(
4978
5263
  "transition-all duration-200"
4979
5264
  ),
4980
5265
  children: [
4981
- showArrows && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5266
+ showArrows && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4982
5267
  "button",
4983
5268
  {
4984
5269
  type: "button",
@@ -4994,11 +5279,11 @@ var TimePickerInput = import_react27.default.forwardRef(
4994
5279
  ),
4995
5280
  tabIndex: -1,
4996
5281
  "aria-label": `Incrementar ${getPickerLabel().toLowerCase()}`,
4997
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react26.CaretUpIcon, { size: 14, className: "sm:w-4 sm:h-4" })
5282
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react28.CaretUpIcon, { size: 14, className: "sm:w-4 sm:h-4" })
4998
5283
  }
4999
5284
  ),
5000
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "relative", children: [
5001
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5285
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "relative", children: [
5286
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5002
5287
  "input",
5003
5288
  {
5004
5289
  ref,
@@ -5043,9 +5328,9 @@ var TimePickerInput = import_react27.default.forwardRef(
5043
5328
  ...props
5044
5329
  }
5045
5330
  ),
5046
- isFocused && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "absolute inset-0 rounded-lg ring-2 ring-primary/20 pointer-events-none animate-pulse" })
5331
+ isFocused && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "absolute inset-0 rounded-lg ring-2 ring-primary/20 pointer-events-none animate-pulse" })
5047
5332
  ] }),
5048
- showArrows && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5333
+ showArrows && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5049
5334
  "button",
5050
5335
  {
5051
5336
  type: "button",
@@ -5061,7 +5346,7 @@ var TimePickerInput = import_react27.default.forwardRef(
5061
5346
  ),
5062
5347
  tabIndex: -1,
5063
5348
  "aria-label": `Decrementar ${getPickerLabel().toLowerCase()}`,
5064
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react26.CaretDownIcon, { size: 14, className: "sm:w-4 sm:h-4" })
5349
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react28.CaretDownIcon, { size: 14, className: "sm:w-4 sm:h-4" })
5065
5350
  }
5066
5351
  )
5067
5352
  ]
@@ -5073,16 +5358,16 @@ var TimePickerInput = import_react27.default.forwardRef(
5073
5358
  TimePickerInput.displayName = "TimePickerInput";
5074
5359
 
5075
5360
  // src/components/date-time-picker/TimePicker.tsx
5076
- var import_jsx_runtime45 = require("react/jsx-runtime");
5361
+ var import_jsx_runtime46 = require("react/jsx-runtime");
5077
5362
  function TimePicker({
5078
5363
  date,
5079
5364
  setDate,
5080
5365
  hideSeconds,
5081
5366
  enableButton
5082
5367
  }) {
5083
- const minuteRef = React31.useRef(null);
5084
- const hourRef = React31.useRef(null);
5085
- const secondRef = React31.useRef(null);
5368
+ const minuteRef = React32.useRef(null);
5369
+ const hourRef = React32.useRef(null);
5370
+ const secondRef = React32.useRef(null);
5086
5371
  const containerVariants = {
5087
5372
  hidden: { opacity: 0, y: 10 },
5088
5373
  visible: {
@@ -5098,20 +5383,20 @@ function TimePicker({
5098
5383
  hidden: { opacity: 0, y: 10 },
5099
5384
  visible: { opacity: 1, y: 0 }
5100
5385
  };
5101
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
5102
- import_framer_motion7.motion.div,
5386
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
5387
+ import_framer_motion8.motion.div,
5103
5388
  {
5104
5389
  variants: containerVariants,
5105
5390
  initial: "hidden",
5106
5391
  animate: "visible",
5107
5392
  className: "flex items-end justify-center gap-2 sm:gap-3 p-2 sm:p-3 md:p-4 rounded-lg bg-muted/20 border border-border/50 w-full max-w-full overflow-hidden",
5108
5393
  children: [
5109
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5110
- import_framer_motion7.motion.div,
5394
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5395
+ import_framer_motion8.motion.div,
5111
5396
  {
5112
5397
  variants: itemVariants2,
5113
5398
  className: "grid gap-1 sm:gap-2 text-center flex-shrink-0 min-w-0",
5114
- children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5399
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5115
5400
  TimePickerInput,
5116
5401
  {
5117
5402
  picker: "hours",
@@ -5124,12 +5409,12 @@ function TimePicker({
5124
5409
  )
5125
5410
  }
5126
5411
  ),
5127
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5128
- import_framer_motion7.motion.div,
5412
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5413
+ import_framer_motion8.motion.div,
5129
5414
  {
5130
5415
  variants: itemVariants2,
5131
5416
  className: "grid gap-1 sm:gap-2 text-center flex-shrink-0 min-w-0",
5132
- children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5417
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5133
5418
  TimePickerInput,
5134
5419
  {
5135
5420
  picker: "minutes",
@@ -5143,15 +5428,15 @@ function TimePicker({
5143
5428
  )
5144
5429
  }
5145
5430
  ),
5146
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_framer_motion7.AnimatePresence, { children: !hideSeconds && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_jsx_runtime45.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5147
- import_framer_motion7.motion.div,
5431
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_framer_motion8.AnimatePresence, { children: !hideSeconds && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_jsx_runtime46.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5432
+ import_framer_motion8.motion.div,
5148
5433
  {
5149
5434
  variants: itemVariants2,
5150
5435
  initial: "hidden",
5151
5436
  animate: "visible",
5152
5437
  exit: "hidden",
5153
5438
  className: "grid gap-1 sm:gap-2 text-center flex-shrink-0 min-w-0",
5154
- children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5439
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5155
5440
  TimePickerInput,
5156
5441
  {
5157
5442
  picker: "seconds",
@@ -5170,8 +5455,8 @@ function TimePicker({
5170
5455
  }
5171
5456
 
5172
5457
  // src/components/date-time-picker/DateTimePicker.tsx
5173
- var import_react29 = require("@phosphor-icons/react");
5174
- var import_jsx_runtime46 = require("react/jsx-runtime");
5458
+ var import_react31 = require("@phosphor-icons/react");
5459
+ var import_jsx_runtime47 = require("react/jsx-runtime");
5175
5460
  function DateTimePicker({
5176
5461
  label,
5177
5462
  date,
@@ -5184,9 +5469,9 @@ function DateTimePicker({
5184
5469
  disabled,
5185
5470
  className
5186
5471
  }) {
5187
- const [internalDate, setInternalDate] = (0, import_react28.useState)(date);
5188
- const [open, setOpen] = (0, import_react28.useState)(false);
5189
- const [timePickerOpen, setTimePickerOpen] = (0, import_react28.useState)(false);
5472
+ const [internalDate, setInternalDate] = (0, import_react30.useState)(date);
5473
+ const [open, setOpen] = (0, import_react30.useState)(false);
5474
+ const [timePickerOpen, setTimePickerOpen] = (0, import_react30.useState)(false);
5190
5475
  const handleSelect = (newDay) => {
5191
5476
  if (!newDay) return;
5192
5477
  if (!internalDate) {
@@ -5215,32 +5500,31 @@ function DateTimePicker({
5215
5500
  if (!timeFormat) return "PPP";
5216
5501
  return `PPP - ${timeFormat}`;
5217
5502
  };
5218
- (0, import_react28.useEffect)(() => {
5503
+ (0, import_react30.useEffect)(() => {
5219
5504
  if (date) {
5220
5505
  setInternalDate(date);
5221
5506
  }
5222
5507
  }, [date, open]);
5223
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("space-y-2 w-full sm:w-auto", className), children: [
5224
- label && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(LabelBase_default, { children: label }),
5225
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(PopoverBase, { open, onOpenChange: setOpen, children: [
5226
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(PopoverTriggerBase, { disabled, asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
5508
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn("space-y-2 w-full sm:w-auto", className), children: [
5509
+ label && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(LabelBase_default, { children: label }),
5510
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(PopoverBase, { open, onOpenChange: setOpen, children: [
5511
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverTriggerBase, { disabled, asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
5227
5512
  ButtonBase,
5228
5513
  {
5229
5514
  variant: "outline",
5230
- size: "lg",
5231
5515
  className: cn(
5232
5516
  "w-full justify-start text-left min-w-0 overflow-hidden",
5233
- "min-h-[44px] sm:min-h-[48px] px-3 sm:px-4",
5517
+ "",
5234
5518
  "text-sm sm:text-base",
5235
5519
  !date && "text-muted-foreground"
5236
5520
  ),
5237
5521
  children: [
5238
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "truncate flex-1", children: date ? (0, import_date_fns.format)(date, getDisplayFormat(), { locale: import_locale.ptBR }) : "Pick a date" }),
5239
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react29.CalendarBlankIcon, { className: "flex-shrink-0 w-5 h-5 sm:w-6 sm:h-6" })
5522
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "truncate flex-1", children: date ? (0, import_date_fns.format)(date, getDisplayFormat(), { locale: import_locale.ptBR }) : "Pick a date" }),
5523
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react31.CalendarBlankIcon, { className: "flex-shrink-0 w-5 h-5 sm:w-6 sm:h-6" })
5240
5524
  ]
5241
5525
  }
5242
5526
  ) }),
5243
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5527
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5244
5528
  PopoverContentBase,
5245
5529
  {
5246
5530
  className: "w-full p-0",
@@ -5249,8 +5533,8 @@ function DateTimePicker({
5249
5533
  side: "bottom",
5250
5534
  avoidCollisions: true,
5251
5535
  collisionPadding: 8,
5252
- children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-col space-y-2 sm:space-y-3 p-2 sm:p-3 md:p-4 max-h-[calc(100vh-4rem)] overflow-y-auto", children: [
5253
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5536
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col space-y-2 sm:space-y-3 p-2 sm:p-3 md:p-4 max-h-[calc(100vh-4rem)] overflow-y-auto", children: [
5537
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5254
5538
  CalendarBase2,
5255
5539
  {
5256
5540
  mode: "single",
@@ -5263,13 +5547,13 @@ function DateTimePicker({
5263
5547
  className: "w-full"
5264
5548
  }
5265
5549
  ),
5266
- !(hideHour && hideMinute) && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex justify-center w-full px-2", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
5550
+ !(hideHour && hideMinute) && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex justify-center w-full px-2", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
5267
5551
  PopoverBase,
5268
5552
  {
5269
5553
  open: timePickerOpen,
5270
5554
  onOpenChange: setTimePickerOpen,
5271
5555
  children: [
5272
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(PopoverTriggerBase, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
5556
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverTriggerBase, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
5273
5557
  ButtonBase,
5274
5558
  {
5275
5559
  variant: "outline",
@@ -5279,20 +5563,20 @@ function DateTimePicker({
5279
5563
  "px-2 sm:px-3 py-1.5 sm:py-2",
5280
5564
  "text-sm sm:text-base font-semibold w-full max-w-xs",
5281
5565
  "border-2 border-primary/20 rounded-lg",
5282
- "bg-primary/5 hover:bg-primary/10 hover:border-primary/30",
5566
+ "bg-background hover:bg-primary/10 hover:border-primary/30",
5283
5567
  "transition-all duration-200",
5284
5568
  "shadow-sm hover:shadow-md active:scale-[0.98]",
5285
5569
  "min-h-[36px] sm:min-h-[40px]"
5286
5570
  ),
5287
5571
  children: [
5288
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react29.ClockIcon, { className: "text-primary/70 flex-shrink-0 w-4 h-4 sm:w-5 sm:h-5" }),
5289
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-foreground truncate", children: internalDate ? (0, import_date_fns.format)(internalDate, getTimeFormat() || "HH:mm", {
5572
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react31.ClockIcon, { className: "text-primary flex-shrink-0 w-4 h-4 sm:w-5 sm:h-5" }),
5573
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-foreground truncate", children: internalDate ? (0, import_date_fns.format)(internalDate, getTimeFormat() || "HH:mm", {
5290
5574
  locale: import_locale.ptBR
5291
5575
  }) : "00:00" })
5292
5576
  ]
5293
5577
  }
5294
5578
  ) }),
5295
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5579
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5296
5580
  PopoverContentBase,
5297
5581
  {
5298
5582
  className: "w-[calc(100vw-2rem)] max-w-sm p-3 sm:p-3 rounded-md",
@@ -5301,9 +5585,9 @@ function DateTimePicker({
5301
5585
  sideOffset: 8,
5302
5586
  avoidCollisions: true,
5303
5587
  collisionPadding: 8,
5304
- children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-col items-center space-y-2 sm:space-y-3", children: [
5305
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h4", { className: "text-sm sm:text-base font-medium text-center", children: "Alterar Hor\xE1rio" }),
5306
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5588
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex flex-col items-center space-y-2 sm:space-y-3", children: [
5589
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h4", { className: "text-sm sm:text-base font-medium text-center", children: "Alterar Hor\xE1rio" }),
5590
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5307
5591
  TimePicker,
5308
5592
  {
5309
5593
  setDate: handleTimeChange,
@@ -5311,7 +5595,7 @@ function DateTimePicker({
5311
5595
  hideSeconds
5312
5596
  }
5313
5597
  ),
5314
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5598
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5315
5599
  ButtonBase,
5316
5600
  {
5317
5601
  size: "sm",
@@ -5335,7 +5619,7 @@ function DateTimePicker({
5335
5619
  }
5336
5620
 
5337
5621
  // src/components/selects/Select.tsx
5338
- var import_jsx_runtime47 = require("react/jsx-runtime");
5622
+ var import_jsx_runtime48 = require("react/jsx-runtime");
5339
5623
  function Select({
5340
5624
  items,
5341
5625
  groupItems,
@@ -5344,9 +5628,9 @@ function Select({
5344
5628
  errorMessage,
5345
5629
  testIds = {}
5346
5630
  }) {
5347
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { "data-testid": testIds.root ?? "select-root", children: [
5348
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(SelectBase, { onValueChange: onChange, "data-testid": testIds.base ?? "select-base", children: [
5349
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5631
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { "data-testid": testIds.root ?? "select-root", children: [
5632
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(SelectBase, { onValueChange: onChange, "data-testid": testIds.base ?? "select-base", children: [
5633
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5350
5634
  SelectTriggerBase,
5351
5635
  {
5352
5636
  className: cn(
@@ -5354,7 +5638,7 @@ function Select({
5354
5638
  errorMessage && "border-red-500"
5355
5639
  ),
5356
5640
  "data-testid": testIds.trigger ?? "select-trigger",
5357
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5641
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5358
5642
  SelectValueBase,
5359
5643
  {
5360
5644
  placeholder,
@@ -5363,9 +5647,9 @@ function Select({
5363
5647
  )
5364
5648
  }
5365
5649
  ),
5366
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ScrollAreaBase, { "data-testid": testIds.scrollarea ?? "select-scrollarea", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SelectContentBase, { "data-testid": testIds.content ?? "select-content", children: groupItems ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_jsx_runtime47.Fragment, { children: Object.keys(groupItems).map((key) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: [
5367
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SelectLabelBase, { "data-testid": testIds.label ?? "select-label", children: key }),
5368
- groupItems[key].map((item) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5650
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ScrollAreaBase, { "data-testid": testIds.scrollarea ?? "select-scrollarea", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(SelectContentBase, { "data-testid": testIds.content ?? "select-content", children: groupItems ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_jsx_runtime48.Fragment, { children: Object.keys(groupItems).map((key) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: [
5651
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(SelectLabelBase, { "data-testid": testIds.label ?? "select-label", children: key }),
5652
+ groupItems[key].map((item) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5369
5653
  SelectItemBase,
5370
5654
  {
5371
5655
  value: item.value,
@@ -5374,7 +5658,7 @@ function Select({
5374
5658
  },
5375
5659
  item.value
5376
5660
  ))
5377
- ] }, key)) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5661
+ ] }, key)) }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5378
5662
  SelectItemBase,
5379
5663
  {
5380
5664
  value: item.value,
@@ -5384,7 +5668,7 @@ function Select({
5384
5668
  item.value
5385
5669
  )) }) }) })
5386
5670
  ] }),
5387
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5671
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5388
5672
  "p",
5389
5673
  {
5390
5674
  className: "text-sm text-red-500",
@@ -5395,85 +5679,156 @@ function Select({
5395
5679
  ] });
5396
5680
  }
5397
5681
 
5398
- // src/components/ui/DestructiveDialog.tsx
5399
- var React32 = __toESM(require("react"));
5400
- var import_react30 = require("@phosphor-icons/react");
5401
- var import_jsx_runtime48 = require("react/jsx-runtime");
5402
- var DestructiveDialog = ({
5403
- title,
5404
- description,
5405
- onConfirm,
5406
- onCancel,
5407
- children,
5408
- triggerContent
5409
- }) => {
5410
- const titleId = "destructive-dialog-title";
5411
- const descriptionId = "destructive-dialog-description";
5412
- const triggerEl = React32.isValidElement(children) ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(AlertDialogTriggerBase, { asChild: true, children }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(AlertDialogTriggerBase, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ButtonBase, { variant: "destructive", children: triggerContent ?? "Excluir" }) });
5413
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(AlertDialogBase, { children: [
5414
- triggerEl,
5415
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
5416
- AlertDialogContentBase,
5417
- {
5418
- role: "alertdialog",
5419
- "aria-modal": "true",
5420
- "aria-labelledby": titleId,
5421
- "aria-describedby": descriptionId,
5422
- className: cn("border border-destructive bg-background"),
5423
- children: [
5424
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-start gap-4", children: [
5425
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex items-center justify-center w-10 h-10 rounded-full ring-1 ring-destructive/30", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react30.XCircleIcon, { className: "w-6 h-6 text-destructive" }) }),
5426
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex-1", children: [
5427
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5428
- AlertDialogTitleBase,
5429
- {
5430
- id: titleId,
5431
- className: "text-lg sm:text-xl font-semibold text-destructive",
5432
- children: title
5433
- }
5434
- ),
5435
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5436
- AlertDialogDescriptionBase,
5437
- {
5438
- id: descriptionId,
5439
- className: "mt-2 text-sm text-muted-foreground",
5440
- children: description
5441
- }
5442
- )
5443
- ] })
5444
- ] }),
5445
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(AlertDialogFooterBase, { className: "mt-2 flex justify-end gap-3", children: [
5446
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5447
- AlertDialogCancelBase,
5448
- {
5449
- onClick: onCancel,
5450
- className: cn(
5451
- buttonVariantsBase({ variant: "outline", size: "default" }),
5452
- "hover:bg-foreground/5 hover:text-primary hover:opacity-90 hover:shadow-none"
5453
- ),
5454
- children: "Cancelar"
5455
- }
5456
- ),
5457
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5458
- AlertDialogActionBase,
5459
- {
5460
- onClick: onConfirm,
5461
- className: cn(
5462
- buttonVariantsBase({ variant: "destructive", size: "default" })
5463
- ),
5464
- children: "Confirmar"
5465
- }
5466
- )
5467
- ] })
5468
- ]
5469
- }
5470
- )
5471
- ] });
5472
- };
5682
+ // src/components/charts/Chart.tsx
5683
+ var import_react36 = require("react");
5684
+ var import_recharts = require("recharts");
5685
+
5686
+ // src/components/charts/utils/helpers.ts
5687
+ var formatFieldName = (fieldName) => {
5688
+ return fieldName.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()).trim();
5689
+ };
5690
+ var detectDataFields = (data, xAxisKey) => {
5691
+ if (!data || data.length === 0) return [];
5692
+ const firstItem = data[0];
5693
+ return Object.keys(firstItem).filter(
5694
+ (key) => key !== xAxisKey && typeof firstItem[key] === "number"
5695
+ );
5696
+ };
5697
+ var detectXAxis = (data) => {
5698
+ if (!data || data.length === 0) return "name";
5699
+ const firstItem = data[0];
5700
+ const stringFields = Object.keys(firstItem).filter(
5701
+ (key) => typeof firstItem[key] === "string" || typeof firstItem[key] === "number" && String(firstItem[key]).length <= 4
5702
+ );
5703
+ return stringFields[0] || Object.keys(firstItem)[0] || "name";
5704
+ };
5705
+ var generateAdditionalColors = (baseColors, count) => {
5706
+ const hexToRgb = (hex) => {
5707
+ const clean = hex.replace("#", "");
5708
+ const bigint = parseInt(
5709
+ clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean,
5710
+ 16
5711
+ );
5712
+ return { r: bigint >> 16 & 255, g: bigint >> 8 & 255, b: bigint & 255 };
5713
+ };
5714
+ const rgbToHsl = ({ r, g, b }) => {
5715
+ r /= 255;
5716
+ g /= 255;
5717
+ b /= 255;
5718
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
5719
+ let h = 0;
5720
+ let s = 0;
5721
+ const l = (max + min) / 2;
5722
+ if (max !== min) {
5723
+ const d = max - min;
5724
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
5725
+ switch (max) {
5726
+ case r:
5727
+ h = (g - b) / d + (g < b ? 6 : 0);
5728
+ break;
5729
+ case g:
5730
+ h = (b - r) / d + 2;
5731
+ break;
5732
+ case b:
5733
+ h = (r - g) / d + 4;
5734
+ break;
5735
+ }
5736
+ h /= 6;
5737
+ }
5738
+ return {
5739
+ h: Math.round(h * 360),
5740
+ s: Math.round(s * 100),
5741
+ l: Math.round(l * 100)
5742
+ };
5743
+ };
5744
+ const hslToHex = (h, s, l) => {
5745
+ s /= 100;
5746
+ l /= 100;
5747
+ const k = (n) => (n + h / 30) % 5;
5748
+ const a = s * Math.min(l, 1 - l);
5749
+ const f = (n) => {
5750
+ const color = l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
5751
+ return Math.round(255 * color).toString(16).padStart(2, "0");
5752
+ };
5753
+ return `#${f(0)}${f(8)}${f(4)}`;
5754
+ };
5755
+ const anchors = baseColors.map((c) => rgbToHsl(hexToRgb(c)));
5756
+ const colors2 = [...baseColors];
5757
+ let i = 0;
5758
+ while (colors2.length < count) {
5759
+ const anchor = anchors[i % anchors.length];
5760
+ const step = Math.floor(i / anchors.length + 1);
5761
+ const hueOffset = step * 25 * (i % 2 === 0 ? 1 : -1);
5762
+ const satOffset = i % 3 === 0 ? -6 : 6;
5763
+ const lightOffset = i % 4 === 0 ? 6 : -4;
5764
+ const newH = (anchor.h + hueOffset + 360) % 360;
5765
+ const newS = Math.max(30, Math.min(95, anchor.s + satOffset));
5766
+ const newL = Math.max(25, Math.min(45, anchor.l + lightOffset));
5767
+ colors2.push(hslToHex(newH, newS, newL));
5768
+ i += 1;
5769
+ }
5770
+ return colors2.slice(0, count);
5771
+ };
5772
+ var niceCeil = (value) => {
5773
+ if (!isFinite(value) || value <= 0) return 1;
5774
+ const pow = Math.pow(10, Math.floor(Math.log10(value)));
5775
+ const normalized = value / pow;
5776
+ const multipliers = [
5777
+ 1,
5778
+ 1.25,
5779
+ 1.5,
5780
+ 2,
5781
+ 2.5,
5782
+ 3,
5783
+ 4,
5784
+ 5,
5785
+ 7.5,
5786
+ 10,
5787
+ 15,
5788
+ 20,
5789
+ 25,
5790
+ 50,
5791
+ 100
5792
+ ];
5793
+ for (const m of multipliers) {
5794
+ if (m >= normalized) return Math.ceil(m * pow);
5795
+ }
5796
+ return Math.ceil(100 * pow);
5797
+ };
5798
+ var compactTick = (value) => {
5799
+ if (value >= 1e9)
5800
+ return (value / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
5801
+ if (value >= 1e6)
5802
+ return (value / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
5803
+ if (value >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
5804
+ return String(value);
5805
+ };
5806
+ var resolveContainerPaddingLeft = (padding, containerPaddingLeft, defaultLeft = 16) => {
5807
+ if (typeof padding === "number") return padding;
5808
+ if (padding && typeof padding === "object" && padding.left != null)
5809
+ return padding.left;
5810
+ if (typeof containerPaddingLeft === "number") return containerPaddingLeft;
5811
+ return defaultLeft;
5812
+ };
5813
+ var resolveChartMargins = (margins, chartMargins, showLabels) => {
5814
+ const defaultRight = 30;
5815
+ const defaultLeft = 20;
5816
+ const topDefault = showLabels ? 48 : 20;
5817
+ const bottomDefault = 5;
5818
+ return {
5819
+ top: margins?.top ?? chartMargins?.top ?? topDefault,
5820
+ right: margins?.right ?? chartMargins?.right ?? defaultRight,
5821
+ left: margins?.left ?? chartMargins?.left ?? defaultLeft,
5822
+ bottom: margins?.bottom ?? chartMargins?.bottom ?? bottomDefault
5823
+ };
5824
+ };
5825
+
5826
+ // src/components/charts/Chart.tsx
5827
+ var import_sonner2 = require("sonner");
5473
5828
 
5474
5829
  // src/components/charts/components/controls/PeriodsDropdown.tsx
5475
- var import_react31 = require("react");
5476
- var import_framer_motion8 = require("framer-motion");
5830
+ var import_react32 = require("react");
5831
+ var import_framer_motion9 = require("framer-motion");
5477
5832
  var import_ssr = require("@phosphor-icons/react/dist/ssr");
5478
5833
  var import_ssr2 = require("@phosphor-icons/react/dist/ssr");
5479
5834
  var import_jsx_runtime49 = require("react/jsx-runtime");
@@ -5495,11 +5850,11 @@ function PeriodsDropdown({
5495
5850
  activePeriods
5496
5851
  }) {
5497
5852
  const periods = processedData.map((d) => String(d.name));
5498
- const [open, setOpen] = (0, import_react31.useState)(false);
5499
- const wrapperRef = (0, import_react31.useRef)(null);
5500
- const firstItemRef = (0, import_react31.useRef)(null);
5501
- const listRef = (0, import_react31.useRef)(null);
5502
- (0, import_react31.useEffect)(() => {
5853
+ const [open, setOpen] = (0, import_react32.useState)(false);
5854
+ const wrapperRef = (0, import_react32.useRef)(null);
5855
+ const firstItemRef = (0, import_react32.useRef)(null);
5856
+ const listRef = (0, import_react32.useRef)(null);
5857
+ (0, import_react32.useEffect)(() => {
5503
5858
  const handleClickOutside = (e) => {
5504
5859
  if (!wrapperRef.current) return;
5505
5860
  if (!wrapperRef.current.contains(e.target)) setOpen(false);
@@ -5514,7 +5869,7 @@ function PeriodsDropdown({
5514
5869
  document.removeEventListener("keydown", handleEscape);
5515
5870
  };
5516
5871
  }, []);
5517
- (0, import_react31.useEffect)(() => {
5872
+ (0, import_react32.useEffect)(() => {
5518
5873
  if (open && firstItemRef.current) {
5519
5874
  firstItemRef.current.focus();
5520
5875
  }
@@ -5548,8 +5903,8 @@ function PeriodsDropdown({
5548
5903
  ]
5549
5904
  }
5550
5905
  ),
5551
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_framer_motion8.AnimatePresence, { children: open && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
5552
- import_framer_motion8.motion.div,
5906
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_framer_motion9.AnimatePresence, { children: open && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
5907
+ import_framer_motion9.motion.div,
5553
5908
  {
5554
5909
  initial: "hidden",
5555
5910
  animate: "visible",
@@ -5578,7 +5933,7 @@ function PeriodsDropdown({
5578
5933
  className: "flex flex-col p-2 gap-1",
5579
5934
  style: { maxHeight: 200, overflowY: "auto" },
5580
5935
  children: periods.map((p, idx) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
5581
- import_framer_motion8.motion.button,
5936
+ import_framer_motion9.motion.button,
5582
5937
  {
5583
5938
  className: "flex items-center justify-between w-full text-left px-3 py-2.5 rounded focus:outline-none transition-colors " + (activePeriods && activePeriods.includes(p) || p === activePeriod ? "bg-accent/10 font-medium" : "hover:bg-accent/15 focus-visible:ring-2 focus-visible:ring-accent/30"),
5584
5939
  variants: itemVariants,
@@ -5606,8 +5961,8 @@ function PeriodsDropdown({
5606
5961
  var PeriodsDropdown_default = PeriodsDropdown;
5607
5962
 
5608
5963
  // src/components/charts/components/controls/ShowOnly.tsx
5609
- var import_framer_motion9 = require("framer-motion");
5610
- var import_react32 = require("@phosphor-icons/react");
5964
+ var import_framer_motion10 = require("framer-motion");
5965
+ var import_react33 = require("@phosphor-icons/react");
5611
5966
  var import_jsx_runtime50 = require("react/jsx-runtime");
5612
5967
  var ShowOnly = ({
5613
5968
  showOnlyHighlighted,
@@ -5617,7 +5972,7 @@ var ShowOnly = ({
5617
5972
  const hasHighlights = highlightedSeriesSize > 0;
5618
5973
  if (!hasHighlights) return null;
5619
5974
  return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
5620
- import_framer_motion9.motion.div,
5975
+ import_framer_motion10.motion.div,
5621
5976
  {
5622
5977
  whileTap: { scale: hasHighlights ? 0.985 : 1 },
5623
5978
  whileHover: { y: hasHighlights ? -2 : 0 },
@@ -5636,10 +5991,10 @@ var ShowOnly = ({
5636
5991
  !hasHighlights ? "opacity-60 cursor-not-allowed pointer-events-none" : showOnlyHighlighted ? "bg-primary/10 text-primary shadow-sm border border-primary/20" : "bg-transparent text-muted-foreground border border-transparent hover:bg-muted/10 hover:text-foreground"
5637
5992
  ),
5638
5993
  children: showOnlyHighlighted ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
5639
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react32.EyeSlash, { size: 16, weight: "regular" }),
5994
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react33.EyeSlash, { size: 16, weight: "regular" }),
5640
5995
  /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "sr-only", children: "Exibir todos" })
5641
5996
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
5642
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react32.Eye, { size: 16, weight: "bold" }),
5997
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_react33.Eye, { size: 16, weight: "bold" }),
5643
5998
  /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "sr-only", children: "Mostrar somente destacados" })
5644
5999
  ] })
5645
6000
  }
@@ -5650,7 +6005,7 @@ var ShowOnly = ({
5650
6005
  var ShowOnly_default = ShowOnly;
5651
6006
 
5652
6007
  // src/components/charts/components/controls/Highlights.tsx
5653
- var import_framer_motion10 = require("framer-motion");
6008
+ var import_framer_motion11 = require("framer-motion");
5654
6009
  var import_ssr3 = require("@phosphor-icons/react/dist/ssr");
5655
6010
  var import_jsx_runtime51 = require("react/jsx-runtime");
5656
6011
  var Highlights = ({
@@ -5671,13 +6026,13 @@ var Highlights = ({
5671
6026
  visible: { opacity: 1, transition: { staggerChildren: 0.03 } }
5672
6027
  };
5673
6028
  return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
5674
- import_framer_motion10.motion.div,
6029
+ import_framer_motion11.motion.div,
5675
6030
  {
5676
6031
  className: "flex-1 flex items-center gap-2 flex-wrap",
5677
6032
  initial: "hidden",
5678
6033
  animate: "visible",
5679
6034
  variants: containerVariants,
5680
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_framer_motion10.AnimatePresence, { initial: false, mode: "popLayout", children: allKeys.map((k) => {
6035
+ children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_framer_motion11.AnimatePresence, { initial: false, mode: "popLayout", children: allKeys.map((k) => {
5681
6036
  const isHighlighted = highlightedSeries.has(k);
5682
6037
  const label = mapperConfig[k]?.label ?? k;
5683
6038
  const color = finalColors[k];
@@ -5687,7 +6042,7 @@ var Highlights = ({
5687
6042
  isHighlighted ? "bg-card/95 border-2 text-foreground shadow-[0_6px_18px_rgba(0,0,0,0.12)]" : "bg-muted/10 border-border text-muted-foreground hover:bg-muted/5"
5688
6043
  );
5689
6044
  return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
5690
- import_framer_motion10.motion.div,
6045
+ import_framer_motion11.motion.div,
5691
6046
  {
5692
6047
  layout: true,
5693
6048
  initial: "hidden",
@@ -5704,7 +6059,7 @@ var Highlights = ({
5704
6059
  style: { minWidth: showFullLabel ? void 0 : 36 },
5705
6060
  "aria-pressed": isHighlighted,
5706
6061
  children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
5707
- import_framer_motion10.motion.button,
6062
+ import_framer_motion11.motion.button,
5708
6063
  {
5709
6064
  whileHover: { scale: isHighlighted ? 1.04 : 1.03 },
5710
6065
  whileTap: { scale: 0.96 },
@@ -5712,7 +6067,7 @@ var Highlights = ({
5712
6067
  className: "flex items-center gap-2 min-w-0 pr-2",
5713
6068
  children: [
5714
6069
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
5715
- import_framer_motion10.motion.span,
6070
+ import_framer_motion11.motion.span,
5716
6071
  {
5717
6072
  className: cn("w-3 h-3 rounded-sm flex-shrink-0 border"),
5718
6073
  style: {
@@ -5726,8 +6081,8 @@ var Highlights = ({
5726
6081
  transition: { type: "spring", stiffness: 400, damping: 30 }
5727
6082
  }
5728
6083
  ),
5729
- showFullLabel ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_framer_motion10.motion.span, { className: "truncate max-w-[10rem] pr-2", layout: true, children: label }) : showShortLabel ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
5730
- import_framer_motion10.motion.span,
6084
+ showFullLabel ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_framer_motion11.motion.span, { className: "truncate max-w-[10rem] pr-2", layout: true, children: label }) : showShortLabel ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6085
+ import_framer_motion11.motion.span,
5731
6086
  {
5732
6087
  className: "truncate max-w-[6rem] text-xs pr-2",
5733
6088
  layout: true,
@@ -5735,7 +6090,7 @@ var Highlights = ({
5735
6090
  }
5736
6091
  ) : null,
5737
6092
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
5738
- import_framer_motion10.motion.span,
6093
+ import_framer_motion11.motion.span,
5739
6094
  {
5740
6095
  "aria-hidden": true,
5741
6096
  initial: { opacity: 0, scale: 0.6 },
@@ -5844,9 +6199,9 @@ var CloseAllButton = ({
5844
6199
  var CloseAllButton_default = CloseAllButton;
5845
6200
 
5846
6201
  // src/components/charts/components/tooltips/DraggableTooltip.tsx
5847
- var import_react33 = __toESM(require("react"));
5848
- var import_framer_motion11 = require("framer-motion");
5849
- var import_react34 = require("@phosphor-icons/react");
6202
+ var import_react34 = __toESM(require("react"));
6203
+ var import_framer_motion12 = require("framer-motion");
6204
+ var import_react35 = require("@phosphor-icons/react");
5850
6205
  var import_ssr5 = require("@phosphor-icons/react/dist/ssr");
5851
6206
  var import_jsx_runtime53 = require("react/jsx-runtime");
5852
6207
  var ALIGNMENT_THRESHOLD = 25;
@@ -5923,13 +6278,13 @@ var DraggableTooltipComponent = ({
5923
6278
  toggleHighlight,
5924
6279
  showOnlyHighlighted
5925
6280
  }) => {
5926
- const visibleKeys = (0, import_react33.useMemo)(
6281
+ const visibleKeys = (0, import_react34.useMemo)(
5927
6282
  () => showOnlyHighlighted && highlightedSeries && highlightedSeries.size > 0 ? dataKeys.filter((k) => highlightedSeries.has(k)) : dataKeys,
5928
6283
  [showOnlyHighlighted, highlightedSeries, dataKeys]
5929
6284
  );
5930
- const TotalDisplay = import_react33.default.memo(
6285
+ const TotalDisplay = import_react34.default.memo(
5931
6286
  ({ data: data2, visibleKeys: visibleKeys2 }) => {
5932
- const total = (0, import_react33.useMemo)(() => {
6287
+ const total = (0, import_react34.useMemo)(() => {
5933
6288
  const numeric = visibleKeys2.map((k) => data2[k]).filter((v) => typeof v === "number");
5934
6289
  return numeric.reduce((s, v) => s + (v || 0), 0);
5935
6290
  }, [data2, visibleKeys2]);
@@ -5945,14 +6300,14 @@ var DraggableTooltipComponent = ({
5945
6300
  ] });
5946
6301
  }
5947
6302
  );
5948
- const [localPos, setLocalPos] = (0, import_react33.useState)(position);
5949
- const [dragging, setDragging] = (0, import_react33.useState)(false);
5950
- const offsetRef = (0, import_react33.useRef)({ x: 0, y: 0 });
5951
- const lastMouse = (0, import_react33.useRef)({ x: 0, y: 0 });
5952
- const [alignmentGuides, setAlignmentGuides] = (0, import_react33.useState)([]);
5953
- const [globalTooltipCountLocal, setGlobalTooltipCountLocal] = (0, import_react33.useState)(0);
5954
- (0, import_react33.useEffect)(() => setLocalPos(position), [position]);
5955
- const getAllTooltips = (0, import_react33.useCallback)(() => {
6303
+ const [localPos, setLocalPos] = (0, import_react34.useState)(position);
6304
+ const [dragging, setDragging] = (0, import_react34.useState)(false);
6305
+ const offsetRef = (0, import_react34.useRef)({ x: 0, y: 0 });
6306
+ const lastMouse = (0, import_react34.useRef)({ x: 0, y: 0 });
6307
+ const [alignmentGuides, setAlignmentGuides] = (0, import_react34.useState)([]);
6308
+ const [globalTooltipCountLocal, setGlobalTooltipCountLocal] = (0, import_react34.useState)(0);
6309
+ (0, import_react34.useEffect)(() => setLocalPos(position), [position]);
6310
+ const getAllTooltips = (0, import_react34.useCallback)(() => {
5956
6311
  const response = [];
5957
6312
  const ev = new CustomEvent("requestGlobalTooltips", {
5958
6313
  detail: { requesterId: id, response }
@@ -5960,7 +6315,7 @@ var DraggableTooltipComponent = ({
5960
6315
  window.dispatchEvent(ev);
5961
6316
  return response;
5962
6317
  }, [id]);
5963
- const updateAlignmentGuides = (0, import_react33.useCallback)(
6318
+ const updateAlignmentGuides = (0, import_react34.useCallback)(
5964
6319
  (currentPosition) => {
5965
6320
  const allTooltips = getAllTooltips();
5966
6321
  const otherTooltips = allTooltips.filter((t) => t.id !== id);
@@ -6009,7 +6364,7 @@ var DraggableTooltipComponent = ({
6009
6364
  },
6010
6365
  [getAllTooltips, id]
6011
6366
  );
6012
- const snapToGuides = (0, import_react33.useCallback)(
6367
+ const snapToGuides = (0, import_react34.useCallback)(
6013
6368
  (position2) => {
6014
6369
  const snappedPosition = { ...position2 };
6015
6370
  let hasSnapped = false;
@@ -6056,7 +6411,7 @@ var DraggableTooltipComponent = ({
6056
6411
  },
6057
6412
  [alignmentGuides]
6058
6413
  );
6059
- (0, import_react33.useEffect)(() => {
6414
+ (0, import_react34.useEffect)(() => {
6060
6415
  let rafId = null;
6061
6416
  const handleMouseMove = (e) => {
6062
6417
  if (!dragging) return;
@@ -6098,7 +6453,7 @@ var DraggableTooltipComponent = ({
6098
6453
  document.body.style.userSelect = "";
6099
6454
  };
6100
6455
  }, [dragging, snapToGuides, updateAlignmentGuides, id, onPositionChange]);
6101
- (0, import_react33.useEffect)(() => {
6456
+ (0, import_react34.useEffect)(() => {
6102
6457
  const handleCloseAll = () => onClose(id);
6103
6458
  const handleRequestTooltipCount = () => {
6104
6459
  window.dispatchEvent(
@@ -6129,7 +6484,7 @@ var DraggableTooltipComponent = ({
6129
6484
  });
6130
6485
  };
6131
6486
  }, [id, localPos, onClose]);
6132
- (0, import_react33.useEffect)(() => {
6487
+ (0, import_react34.useEffect)(() => {
6133
6488
  if (dragging) return;
6134
6489
  let total = 0;
6135
6490
  const timeoutId = setTimeout(() => {
@@ -6147,7 +6502,7 @@ var DraggableTooltipComponent = ({
6147
6502
  }, 0);
6148
6503
  return () => clearTimeout(timeoutId);
6149
6504
  }, [localPos, dragging]);
6150
- (0, import_react33.useEffect)(() => {
6505
+ (0, import_react34.useEffect)(() => {
6151
6506
  const recount = () => {
6152
6507
  if (dragging) return;
6153
6508
  let total = 0;
@@ -6165,7 +6520,7 @@ var DraggableTooltipComponent = ({
6165
6520
  window.addEventListener("recountTooltips", recount);
6166
6521
  return () => window.removeEventListener("recountTooltips", recount);
6167
6522
  }, [dragging]);
6168
- const handleMouseDownLocal = (0, import_react33.useCallback)(
6523
+ const handleMouseDownLocal = (0, import_react34.useCallback)(
6169
6524
  (e) => {
6170
6525
  e.preventDefault();
6171
6526
  e.stopPropagation();
@@ -6176,7 +6531,7 @@ var DraggableTooltipComponent = ({
6176
6531
  },
6177
6532
  [id, onMouseDown]
6178
6533
  );
6179
- const handleTouchStartLocal = (0, import_react33.useCallback)(
6534
+ const handleTouchStartLocal = (0, import_react34.useCallback)(
6180
6535
  (e) => {
6181
6536
  e.stopPropagation();
6182
6537
  const touch = e.touches[0];
@@ -6191,7 +6546,7 @@ var DraggableTooltipComponent = ({
6191
6546
  },
6192
6547
  [id, onMouseDown]
6193
6548
  );
6194
- const handleCloseClick = (0, import_react33.useCallback)(
6549
+ const handleCloseClick = (0, import_react34.useCallback)(
6195
6550
  (e) => {
6196
6551
  e.stopPropagation();
6197
6552
  onClose(id);
@@ -6220,7 +6575,7 @@ var DraggableTooltipComponent = ({
6220
6575
  );
6221
6576
  return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { children: [
6222
6577
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6223
- import_framer_motion11.motion.div,
6578
+ import_framer_motion12.motion.div,
6224
6579
  {
6225
6580
  className: "fixed pointer-events-none z-30",
6226
6581
  variants: guideVariants,
@@ -6242,7 +6597,7 @@ var DraggableTooltipComponent = ({
6242
6597
  }
6243
6598
  ),
6244
6599
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6245
- import_framer_motion11.motion.div,
6600
+ import_framer_motion12.motion.div,
6246
6601
  {
6247
6602
  className: "fixed pointer-events-none z-31",
6248
6603
  variants: guideDotVariants,
@@ -6261,7 +6616,7 @@ var DraggableTooltipComponent = ({
6261
6616
  }
6262
6617
  ),
6263
6618
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6264
- import_framer_motion11.motion.div,
6619
+ import_framer_motion12.motion.div,
6265
6620
  {
6266
6621
  className: "fixed pointer-events-none z-31",
6267
6622
  variants: guideDotVariants,
@@ -6281,8 +6636,8 @@ var DraggableTooltipComponent = ({
6281
6636
  )
6282
6637
  ] }, index);
6283
6638
  }),
6284
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_framer_motion11.AnimatePresence, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
6285
- import_framer_motion11.motion.div,
6639
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_framer_motion12.AnimatePresence, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
6640
+ import_framer_motion12.motion.div,
6286
6641
  {
6287
6642
  className: "fixed bg-card border border-border rounded-lg shadow-lg z-50 min-w-80 select-none",
6288
6643
  variants: tooltipVariants,
@@ -6307,7 +6662,7 @@ var DraggableTooltipComponent = ({
6307
6662
  onTouchStart: handleTouchStartLocal,
6308
6663
  style: { touchAction: "none" },
6309
6664
  children: [
6310
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react34.DotsSixVerticalIcon, { size: 16 }),
6665
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react35.DotsSixVerticalIcon, { size: 16 }),
6311
6666
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "flex flex-col gap-1", children: title && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "flex items-center gap-2 pb-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "font-bold text-foreground text-base", children: title }) }) }),
6312
6667
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6313
6668
  "button",
@@ -6330,7 +6685,7 @@ var DraggableTooltipComponent = ({
6330
6685
  ] }) }),
6331
6686
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "p-3 pt-2 space-y-2", children: [
6332
6687
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2", children: dataLabel }),
6333
- (0, import_react33.useMemo)(
6688
+ (0, import_react34.useMemo)(
6334
6689
  () => visibleKeys.map((key) => {
6335
6690
  const value = data[key];
6336
6691
  if (value === void 0) return null;
@@ -6440,7 +6795,7 @@ var DraggableTooltipComponent = ({
6440
6795
  )
6441
6796
  ] });
6442
6797
  };
6443
- var DraggableTooltip = import_react33.default.memo(DraggableTooltipComponent);
6798
+ var DraggableTooltip = import_react34.default.memo(DraggableTooltipComponent);
6444
6799
  DraggableTooltip.displayName = "DraggableTooltip";
6445
6800
  var DraggableTooltip_default = DraggableTooltip;
6446
6801
 
@@ -6594,200 +6949,60 @@ var TooltipSimple = ({
6594
6949
  };
6595
6950
  var TooltipSimple_default = TooltipSimple;
6596
6951
 
6597
- // src/components/charts/utils/helpers.ts
6598
- var formatFieldName = (fieldName) => {
6599
- return fieldName.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()).trim();
6600
- };
6601
- var detectDataFields = (data, xAxisKey) => {
6602
- if (!data || data.length === 0) return [];
6603
- const firstItem = data[0];
6604
- return Object.keys(firstItem).filter(
6605
- (key) => key !== xAxisKey && typeof firstItem[key] === "number"
6606
- );
6952
+ // src/components/charts/utils/pillLabelRenderer.tsx
6953
+ var import_jsx_runtime56 = require("react/jsx-runtime");
6954
+ var formatCompactNumber = (value) => {
6955
+ const isNegative = value < 0;
6956
+ const absValue = Math.abs(value);
6957
+ let formatted;
6958
+ if (absValue >= 1e9) {
6959
+ formatted = (absValue / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
6960
+ } else if (absValue >= 1e6) {
6961
+ formatted = (absValue / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
6962
+ } else if (absValue >= 1e3) {
6963
+ formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
6964
+ } else {
6965
+ formatted = absValue.toString();
6966
+ }
6967
+ return isNegative ? `-${formatted}` : formatted;
6607
6968
  };
6608
- var detectXAxis = (data) => {
6609
- if (!data || data.length === 0) return "name";
6610
- const firstItem = data[0];
6611
- const stringFields = Object.keys(firstItem).filter(
6612
- (key) => typeof firstItem[key] === "string" || typeof firstItem[key] === "number" && String(firstItem[key]).length <= 4
6613
- );
6614
- return stringFields[0] || Object.keys(firstItem)[0] || "name";
6969
+ var parseNumber = (v) => {
6970
+ if (typeof v === "number") return v;
6971
+ if (typeof v === "string" && v.trim() !== "" && !Number.isNaN(Number(v)))
6972
+ return Number(v);
6973
+ return void 0;
6615
6974
  };
6616
- var generateAdditionalColors = (baseColors, count) => {
6617
- const hexToRgb = (hex) => {
6618
- const clean = hex.replace("#", "");
6619
- const bigint = parseInt(
6620
- clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean,
6621
- 16
6975
+ var renderPillLabel = (color, variant) => {
6976
+ return (props) => {
6977
+ const { x, y, value } = props;
6978
+ const text = typeof value === "number" ? formatCompactNumber(value) : String(value ?? "");
6979
+ const paddingX = 8;
6980
+ const approxCharWidth = 7;
6981
+ const pillWidth = Math.max(
6982
+ 40,
6983
+ String(text).length * approxCharWidth + paddingX * 2
6622
6984
  );
6623
- return { r: bigint >> 16 & 255, g: bigint >> 8 & 255, b: bigint & 255 };
6624
- };
6625
- const rgbToHsl = ({ r, g, b }) => {
6626
- r /= 255;
6627
- g /= 255;
6628
- b /= 255;
6629
- const max = Math.max(r, g, b), min = Math.min(r, g, b);
6630
- let h = 0;
6631
- let s = 0;
6632
- const l = (max + min) / 2;
6633
- if (max !== min) {
6634
- const d = max - min;
6635
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
6636
- switch (max) {
6637
- case r:
6638
- h = (g - b) / d + (g < b ? 6 : 0);
6639
- break;
6640
- case g:
6641
- h = (b - r) / d + 2;
6642
- break;
6643
- case b:
6644
- h = (r - g) / d + 4;
6645
- break;
6646
- }
6647
- h /= 6;
6648
- }
6649
- return {
6650
- h: Math.round(h * 360),
6651
- s: Math.round(s * 100),
6652
- l: Math.round(l * 100)
6653
- };
6654
- };
6655
- const hslToHex = (h, s, l) => {
6656
- s /= 100;
6657
- l /= 100;
6658
- const k = (n) => (n + h / 30) % 5;
6659
- const a = s * Math.min(l, 1 - l);
6660
- const f = (n) => {
6661
- const color = l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
6662
- return Math.round(255 * color).toString(16).padStart(2, "0");
6663
- };
6664
- return `#${f(0)}${f(8)}${f(4)}`;
6665
- };
6666
- const anchors = baseColors.map((c) => rgbToHsl(hexToRgb(c)));
6667
- const colors2 = [...baseColors];
6668
- let i = 0;
6669
- while (colors2.length < count) {
6670
- const anchor = anchors[i % anchors.length];
6671
- const step = Math.floor(i / anchors.length + 1);
6672
- const hueOffset = step * 25 * (i % 2 === 0 ? 1 : -1);
6673
- const satOffset = i % 3 === 0 ? -6 : 6;
6674
- const lightOffset = i % 4 === 0 ? 6 : -4;
6675
- const newH = (anchor.h + hueOffset + 360) % 360;
6676
- const newS = Math.max(30, Math.min(95, anchor.s + satOffset));
6677
- const newL = Math.max(25, Math.min(45, anchor.l + lightOffset));
6678
- colors2.push(hslToHex(newH, newS, newL));
6679
- i += 1;
6680
- }
6681
- return colors2.slice(0, count);
6682
- };
6683
- var niceCeil = (value) => {
6684
- if (!isFinite(value) || value <= 0) return 1;
6685
- const pow = Math.pow(10, Math.floor(Math.log10(value)));
6686
- const normalized = value / pow;
6687
- const multipliers = [
6688
- 1,
6689
- 1.25,
6690
- 1.5,
6691
- 2,
6692
- 2.5,
6693
- 3,
6694
- 4,
6695
- 5,
6696
- 7.5,
6697
- 10,
6698
- 15,
6699
- 20,
6700
- 25,
6701
- 50,
6702
- 100
6703
- ];
6704
- for (const m of multipliers) {
6705
- if (m >= normalized) return Math.ceil(m * pow);
6706
- }
6707
- return Math.ceil(100 * pow);
6708
- };
6709
- var compactTick = (value) => {
6710
- if (value >= 1e9)
6711
- return (value / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
6712
- if (value >= 1e6)
6713
- return (value / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
6714
- if (value >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
6715
- return String(value);
6716
- };
6717
- var resolveContainerPaddingLeft = (padding, containerPaddingLeft, defaultLeft = 16) => {
6718
- if (typeof padding === "number") return padding;
6719
- if (padding && typeof padding === "object" && padding.left != null)
6720
- return padding.left;
6721
- if (typeof containerPaddingLeft === "number") return containerPaddingLeft;
6722
- return defaultLeft;
6723
- };
6724
- var resolveChartMargins = (margins, chartMargins, showLabels) => {
6725
- const defaultRight = 30;
6726
- const defaultLeft = 20;
6727
- const topDefault = showLabels ? 48 : 20;
6728
- const bottomDefault = 5;
6729
- return {
6730
- top: margins?.top ?? chartMargins?.top ?? topDefault,
6731
- right: margins?.right ?? chartMargins?.right ?? defaultRight,
6732
- left: margins?.left ?? chartMargins?.left ?? defaultLeft,
6733
- bottom: margins?.bottom ?? chartMargins?.bottom ?? bottomDefault
6734
- };
6735
- };
6736
-
6737
- // src/components/charts/utils/pillLabelRenderer.tsx
6738
- var import_jsx_runtime56 = require("react/jsx-runtime");
6739
- var formatCompactNumber = (value) => {
6740
- const isNegative = value < 0;
6741
- const absValue = Math.abs(value);
6742
- let formatted;
6743
- if (absValue >= 1e9) {
6744
- formatted = (absValue / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
6745
- } else if (absValue >= 1e6) {
6746
- formatted = (absValue / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
6747
- } else if (absValue >= 1e3) {
6748
- formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
6749
- } else {
6750
- formatted = absValue.toString();
6751
- }
6752
- return isNegative ? `-${formatted}` : formatted;
6753
- };
6754
- var parseNumber = (v) => {
6755
- if (typeof v === "number") return v;
6756
- if (typeof v === "string" && v.trim() !== "" && !Number.isNaN(Number(v)))
6757
- return Number(v);
6758
- return void 0;
6759
- };
6760
- var renderPillLabel = (color, variant) => {
6761
- return (props) => {
6762
- const { x, y, value } = props;
6763
- const text = typeof value === "number" ? formatCompactNumber(value) : String(value ?? "");
6764
- const paddingX = 8;
6765
- const approxCharWidth = 7;
6766
- const pillWidth = Math.max(
6767
- 40,
6768
- String(text).length * approxCharWidth + paddingX * 2
6769
- );
6770
- const pillHeight = 20;
6771
- const xNum = parseNumber(x);
6772
- const px = parseNumber(props.x);
6773
- const pWidth = parseNumber(props.width);
6774
- const vb = props.viewBox;
6775
- const cxNum = parseNumber(props.cx);
6776
- let centerX;
6777
- if (typeof px === "number" && typeof pWidth === "number") {
6778
- centerX = px + pWidth / 2;
6779
- } else if (typeof xNum === "number" && typeof pWidth === "number") {
6780
- centerX = xNum + pWidth / 2;
6781
- } else if (typeof cxNum === "number") {
6782
- centerX = cxNum;
6783
- } else if (vb && typeof vb.x === "number" && typeof vb.width === "number" && typeof props.index === "number") {
6784
- const approxCols = Math.max(1, props.index + 1);
6785
- const colWidth = vb.width / approxCols;
6786
- centerX = vb.x + colWidth * (props.index + 0.5);
6787
- } else if (vb && typeof vb.x === "number" && typeof vb.width === "number") {
6788
- centerX = vb.x + vb.width / 2;
6789
- } else {
6790
- centerX = typeof props.index === "number" ? props.index * 40 + 24 : 0;
6985
+ const pillHeight = 20;
6986
+ const xNum = parseNumber(x);
6987
+ const px = parseNumber(props.x);
6988
+ const pWidth = parseNumber(props.width);
6989
+ const vb = props.viewBox;
6990
+ const cxNum = parseNumber(props.cx);
6991
+ let centerX;
6992
+ if (typeof px === "number" && typeof pWidth === "number") {
6993
+ centerX = px + pWidth / 2;
6994
+ } else if (typeof xNum === "number" && typeof pWidth === "number") {
6995
+ centerX = xNum + pWidth / 2;
6996
+ } else if (typeof cxNum === "number") {
6997
+ centerX = cxNum;
6998
+ } else if (vb && typeof vb.x === "number" && typeof vb.width === "number" && typeof props.index === "number") {
6999
+ const approxCols = Math.max(1, props.index + 1);
7000
+ const colWidth = vb.width / approxCols;
7001
+ centerX = vb.x + colWidth * (props.index + 0.5);
7002
+ } else if (vb && typeof vb.x === "number" && typeof vb.width === "number") {
7003
+ centerX = vb.x + vb.width / 2;
7004
+ } else {
7005
+ centerX = typeof props.index === "number" ? props.index * 40 + 24 : 0;
6791
7006
  }
6792
7007
  if (vb && typeof vb.x === "number" && typeof vb.width === "number") {
6793
7008
  const minX = vb.x + 0 + pillWidth / 22;
@@ -6849,14 +7064,2102 @@ var renderPillLabel = (color, variant) => {
6849
7064
  };
6850
7065
  var pillLabelRenderer_default = renderPillLabel;
6851
7066
 
7067
+ // src/components/charts/Chart.tsx
7068
+ var import_jsx_runtime57 = require("react/jsx-runtime");
7069
+ var DEFAULT_COLORS = ["#55af7d", "#8e68ff", "#2273e1"];
7070
+ var Chart = ({
7071
+ data,
7072
+ series,
7073
+ className,
7074
+ height = 350,
7075
+ width = "100%",
7076
+ colors: colors2 = DEFAULT_COLORS,
7077
+ gridColor,
7078
+ showGrid = true,
7079
+ showTooltip = true,
7080
+ showLegend = true,
7081
+ title,
7082
+ titlePosition = "left",
7083
+ showLabels = false,
7084
+ xAxis,
7085
+ labelMap,
7086
+ enableHighlights = false,
7087
+ enableShowOnly = false,
7088
+ enablePeriodsDropdown = false,
7089
+ enableDraggableTooltips = false,
7090
+ showTooltipTotal = false,
7091
+ maxTooltips = 5,
7092
+ chartMargin
7093
+ }) => {
7094
+ const smartConfig = (0, import_react36.useMemo)(() => {
7095
+ const resolvedXAxisKey = typeof xAxis === "string" ? xAxis : xAxis && xAxis.dataKey || detectXAxis(data);
7096
+ const xAxisConfig2 = typeof xAxis === "string" ? {
7097
+ dataKey: resolvedXAxisKey,
7098
+ label: formatFieldName(resolvedXAxisKey),
7099
+ autoLabel: true
7100
+ } : {
7101
+ dataKey: resolvedXAxisKey,
7102
+ label: xAxis?.label ?? formatFieldName(resolvedXAxisKey),
7103
+ formatter: xAxis?.formatter,
7104
+ autoLabel: xAxis?.autoLabel ?? true
7105
+ };
7106
+ const detectedFields = detectDataFields(data, xAxisConfig2.dataKey);
7107
+ const mapperConfig2 = detectedFields.reduce((acc, field) => {
7108
+ acc[field] = {
7109
+ label: labelMap?.[field] ?? formatFieldName(field),
7110
+ type: "number",
7111
+ visible: true
7112
+ };
7113
+ return acc;
7114
+ }, {});
7115
+ return { xAxisConfig: xAxisConfig2, mapperConfig: mapperConfig2 };
7116
+ }, [data, xAxis, labelMap]);
7117
+ const { xAxisConfig, mapperConfig } = smartConfig;
7118
+ const [activeTooltips, setActiveTooltips] = (0, import_react36.useState)([]);
7119
+ const [highlightedSeries, setHighlightedSeries] = (0, import_react36.useState)(
7120
+ /* @__PURE__ */ new Set()
7121
+ );
7122
+ const [showOnlyHighlighted, setShowOnlyHighlighted] = (0, import_react36.useState)(false);
7123
+ (0, import_react36.useEffect)(() => {
7124
+ if (highlightedSeries.size === 0 && showOnlyHighlighted) {
7125
+ setShowOnlyHighlighted(false);
7126
+ }
7127
+ }, [highlightedSeries, showOnlyHighlighted]);
7128
+ const processedData = data.map((item) => ({
7129
+ ...item,
7130
+ name: String(item[xAxisConfig.dataKey] || "N/A")
7131
+ }));
7132
+ const wrapperRef = (0, import_react36.useRef)(null);
7133
+ const [measuredWidth, setMeasuredWidth] = (0, import_react36.useState)(null);
7134
+ (0, import_react36.useLayoutEffect)(() => {
7135
+ const el = wrapperRef.current;
7136
+ if (!el) return;
7137
+ const ro = new ResizeObserver((entries) => {
7138
+ const r = entries[0];
7139
+ if (r && typeof r.contentRect.width === "number") {
7140
+ setMeasuredWidth(Math.round(r.contentRect.width));
7141
+ }
7142
+ });
7143
+ ro.observe(el);
7144
+ setMeasuredWidth(Math.round(el.getBoundingClientRect().width));
7145
+ return () => ro.disconnect();
7146
+ }, []);
7147
+ const seriesOrder = [];
7148
+ if (series) {
7149
+ if (series.bar)
7150
+ series.bar.forEach((k) => seriesOrder.push({ type: "bar", key: k }));
7151
+ if (series.line)
7152
+ series.line.forEach((k) => seriesOrder.push({ type: "line", key: k }));
7153
+ if (series.area)
7154
+ series.area.forEach((k) => seriesOrder.push({ type: "area", key: k }));
7155
+ } else {
7156
+ Object.keys(mapperConfig).forEach(
7157
+ (k) => seriesOrder.push({ type: "bar", key: k })
7158
+ );
7159
+ }
7160
+ const allKeys = seriesOrder.map((s) => s.key).filter(Boolean);
7161
+ const generateColors = (0, import_react36.useCallback)(
7162
+ (dataKeys) => {
7163
+ const colorMap = {};
7164
+ const allColors = generateAdditionalColors(colors2, dataKeys.length);
7165
+ dataKeys.forEach((key, index) => {
7166
+ colorMap[key] = mapperConfig[key]?.color || allColors[index] || colors2[index % colors2.length];
7167
+ });
7168
+ return colorMap;
7169
+ },
7170
+ [colors2, mapperConfig]
7171
+ );
7172
+ const finalColors = (0, import_react36.useMemo)(
7173
+ () => generateColors(allKeys),
7174
+ [generateColors, allKeys]
7175
+ );
7176
+ const adaptDataForTooltip = (0, import_react36.useCallback)(
7177
+ (universalData) => ({
7178
+ ...universalData,
7179
+ name: String(universalData[xAxisConfig.dataKey] || "N/A")
7180
+ }),
7181
+ [xAxisConfig.dataKey]
7182
+ );
7183
+ const activePeriods = (0, import_react36.useMemo)(
7184
+ () => activeTooltips.map((t) => adaptDataForTooltip(t.data).name),
7185
+ [activeTooltips, adaptDataForTooltip]
7186
+ );
7187
+ (0, import_react36.useEffect)(() => {
7188
+ window.dispatchEvent(new Event("recountTooltips"));
7189
+ }, [activeTooltips.length]);
7190
+ const toggleHighlight = (0, import_react36.useCallback)((key) => {
7191
+ setHighlightedSeries((prev) => {
7192
+ const next = new Set(prev);
7193
+ if (next.has(key)) next.delete(key);
7194
+ else next.add(key);
7195
+ return next;
7196
+ });
7197
+ }, []);
7198
+ const maxDataValue = (0, import_react36.useMemo)(() => {
7199
+ let max = 0;
7200
+ const numericKeys = allKeys;
7201
+ for (const row of processedData) {
7202
+ const r = row;
7203
+ for (const key of numericKeys) {
7204
+ const v = r[key];
7205
+ if (typeof v === "number" && Number.isFinite(v) && v > max) max = v;
7206
+ }
7207
+ }
7208
+ return max;
7209
+ }, [processedData, allKeys]);
7210
+ const minDataValue = (0, import_react36.useMemo)(() => {
7211
+ let min = 0;
7212
+ const numericKeys = allKeys;
7213
+ for (const row of processedData) {
7214
+ const r = row;
7215
+ for (const key of numericKeys) {
7216
+ const v = r[key];
7217
+ if (typeof v === "number" && Number.isFinite(v) && v < min)
7218
+ min = v;
7219
+ }
7220
+ }
7221
+ return min;
7222
+ }, [processedData, allKeys]);
7223
+ const niceMax = (0, import_react36.useMemo)(() => {
7224
+ let padding = 0.08;
7225
+ if (maxDataValue > 1e6) padding = 0.05;
7226
+ if (maxDataValue > 1e7) padding = 0.03;
7227
+ if (maxDataValue === 0) padding = 0.12;
7228
+ const padded = maxDataValue * (1 + padding);
7229
+ return niceCeil(padded);
7230
+ }, [maxDataValue]);
7231
+ const computedWidth = (0, import_react36.useMemo)(() => {
7232
+ if (typeof width === "number") return width;
7233
+ const points = Math.max(1, processedData.length);
7234
+ const barCount = series?.bar?.length ?? 0;
7235
+ const lineCount = series?.line?.length ?? 0;
7236
+ const areaCount = series?.area?.length ?? 0;
7237
+ const basePerPoint = 60;
7238
+ const perBarExtra = barCount > 0 ? Math.max(0, barCount - 1) * 8 : 0;
7239
+ const perOtherExtra = (lineCount + areaCount) * 4;
7240
+ let sizeFactor = 1;
7241
+ if (niceMax > 1e5) sizeFactor = 1.1;
7242
+ if (niceMax > 1e6) sizeFactor = 1.2;
7243
+ if (niceMax > 1e7) sizeFactor = 1.3;
7244
+ const perPoint = Math.round(
7245
+ (basePerPoint + perBarExtra + perOtherExtra) * sizeFactor
7246
+ );
7247
+ const marginExtra = 120;
7248
+ const calculated = points * perPoint + marginExtra;
7249
+ const minWidth = 300;
7250
+ const maxWidth = 1800;
7251
+ return Math.max(minWidth, Math.min(maxWidth, calculated));
7252
+ }, [
7253
+ width,
7254
+ processedData.length,
7255
+ series?.bar?.length,
7256
+ series?.line?.length,
7257
+ series?.area?.length,
7258
+ niceMax
7259
+ ]);
7260
+ const toggleTooltip = (0, import_react36.useCallback)(
7261
+ (tooltipId, data2, basePosition) => {
7262
+ const existingIndex = activeTooltips.findIndex((t) => t.id === tooltipId);
7263
+ if (existingIndex !== -1) {
7264
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== tooltipId));
7265
+ } else {
7266
+ if (activeTooltips.length >= maxTooltips) {
7267
+ import_sonner2.toast.warning(
7268
+ `Limite de ${maxTooltips} janelas de informa\xE7\xE3o atingido. A mais antiga ser\xE1 substitu\xEDda.`
7269
+ );
7270
+ }
7271
+ const offsetIndex = activeTooltips.length;
7272
+ const gap = 28;
7273
+ const newTooltip = {
7274
+ id: tooltipId,
7275
+ data: data2,
7276
+ position: {
7277
+ top: basePosition.top + offsetIndex * gap,
7278
+ left: basePosition.left + offsetIndex * gap
7279
+ }
7280
+ };
7281
+ setActiveTooltips((prev) => {
7282
+ const next = [...prev, newTooltip];
7283
+ return next.length > maxTooltips ? next.slice(1) : next;
7284
+ });
7285
+ }
7286
+ },
7287
+ [activeTooltips, maxTooltips]
7288
+ );
7289
+ const handleChartClick = (0, import_react36.useCallback)(
7290
+ (e) => {
7291
+ if (!enableDraggableTooltips) return;
7292
+ const ev = e;
7293
+ if (ev?.activePayload?.length) {
7294
+ const clickedData = ev.activePayload[0].payload;
7295
+ const xAxisValue = clickedData[xAxisConfig.dataKey] || clickedData.name || "N/A";
7296
+ const tooltipId = String(xAxisValue);
7297
+ toggleTooltip(tooltipId, clickedData, {
7298
+ top: (ev.chartY || 100) - 10,
7299
+ left: (ev.chartX || 100) - 100
7300
+ });
7301
+ } else {
7302
+ setActiveTooltips([]);
7303
+ }
7304
+ },
7305
+ [enableDraggableTooltips, xAxisConfig.dataKey, toggleTooltip]
7306
+ );
7307
+ const handleBarClick = (0, import_react36.useCallback)(
7308
+ (data2, index, event) => {
7309
+ if (!enableDraggableTooltips) return;
7310
+ event.stopPropagation();
7311
+ const xAxisValue = data2[xAxisConfig.dataKey] || "N/A";
7312
+ const tooltipId = String(xAxisValue);
7313
+ const rect = event.target.getBoundingClientRect();
7314
+ toggleTooltip(tooltipId, data2, {
7315
+ top: Math.max(8, rect.top - 10),
7316
+ left: rect.right + 10
7317
+ });
7318
+ },
7319
+ [enableDraggableTooltips, xAxisConfig.dataKey, toggleTooltip]
7320
+ );
7321
+ const handleSeriesClick = (0, import_react36.useCallback)(
7322
+ (...args) => {
7323
+ if (args.length >= 3) {
7324
+ const [data2, index, event] = args;
7325
+ handleBarClick(data2, index, event);
7326
+ return;
7327
+ }
7328
+ handleChartClick(args[0]);
7329
+ },
7330
+ [handleBarClick, handleChartClick]
7331
+ );
7332
+ const onTooltipPositionChange = (0, import_react36.useCallback)(
7333
+ (id, position) => {
7334
+ setActiveTooltips(
7335
+ (prev) => prev.map((t) => t.id === id ? { ...t, position } : t)
7336
+ );
7337
+ },
7338
+ []
7339
+ );
7340
+ const titleClassName = (0, import_react36.useMemo)(
7341
+ () => "text-xl font-semibold text-foreground mb-3",
7342
+ []
7343
+ );
7344
+ const finalEnableHighlights = enableHighlights;
7345
+ const finalEnableShowOnly = enableShowOnly;
7346
+ const finalEnablePeriodsDropdown = enablePeriodsDropdown && enableDraggableTooltips;
7347
+ const defaultChartRightMargin = 30;
7348
+ const defaultChartLeftMargin = 0;
7349
+ const containerPaddingLeft = 16;
7350
+ const finalChartRightMargin = chartMargin?.right ?? defaultChartRightMargin;
7351
+ const finalChartLeftMargin = chartMargin?.left ?? defaultChartLeftMargin;
7352
+ const finalChartTopMargin = chartMargin?.top ?? (showLabels ? 48 : 20);
7353
+ const finalChartBottomMargin = chartMargin?.bottom ?? 5;
7354
+ const measuredInner = measuredWidth ? Math.max(0, measuredWidth - 32) : void 0;
7355
+ const effectiveChartWidth = typeof width === "number" ? width : measuredInner ?? computedWidth;
7356
+ const chartInnerWidth = effectiveChartWidth - finalChartLeftMargin - finalChartRightMargin;
7357
+ const openTooltipForPeriod = (0, import_react36.useCallback)(
7358
+ (periodName) => {
7359
+ if (!enableDraggableTooltips) return;
7360
+ const row = processedData.find((r) => String(r.name) === periodName);
7361
+ if (!row) return;
7362
+ const tooltipId = String(periodName);
7363
+ const existingIndex = activeTooltips.findIndex((t) => t.id === tooltipId);
7364
+ if (existingIndex !== -1) {
7365
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== tooltipId));
7366
+ return;
7367
+ }
7368
+ if (activeTooltips.length >= maxTooltips) {
7369
+ import_sonner2.toast.warning(
7370
+ `Limite de ${maxTooltips} janelas de informa\xE7\xE3o atingido. A mais antiga ser\xE1 substitu\xEDda.`
7371
+ );
7372
+ }
7373
+ const offsetIndex = activeTooltips.length;
7374
+ const availableWidth = typeof width === "number" ? width : measuredInner ?? computedWidth;
7375
+ const gap = 28;
7376
+ const leftGap = 28;
7377
+ const newTooltip = {
7378
+ id: tooltipId,
7379
+ data: row,
7380
+ position: {
7381
+ top: 48 + offsetIndex * gap,
7382
+ left: Math.max(120, availableWidth - 280 - offsetIndex * leftGap)
7383
+ }
7384
+ };
7385
+ setActiveTooltips((prev) => {
7386
+ const next = [...prev, newTooltip];
7387
+ return next.length > maxTooltips ? next.slice(1) : next;
7388
+ });
7389
+ },
7390
+ [
7391
+ enableDraggableTooltips,
7392
+ processedData,
7393
+ activeTooltips,
7394
+ width,
7395
+ measuredInner,
7396
+ computedWidth,
7397
+ maxTooltips
7398
+ ]
7399
+ );
7400
+ if (!data) return null;
7401
+ if (Array.isArray(data) && data.length === 0) {
7402
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7403
+ "div",
7404
+ {
7405
+ className: cn(
7406
+ "rounded-lg bg-card p-4 relative w-full text-muted-foreground"
7407
+ ),
7408
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7409
+ "div",
7410
+ {
7411
+ style: {
7412
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`
7413
+ },
7414
+ children: "Sem dados para exibir"
7415
+ }
7416
+ )
7417
+ }
7418
+ );
7419
+ }
7420
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7421
+ "div",
7422
+ {
7423
+ ref: wrapperRef,
7424
+ style: {
7425
+ width: "100%",
7426
+ overflowX: "hidden",
7427
+ overflowY: "hidden",
7428
+ minWidth: 0
7429
+ },
7430
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
7431
+ "div",
7432
+ {
7433
+ className: cn("rounded-lg bg-card p-2 relative", className),
7434
+ style: { width: "100%", maxWidth: "100%", minWidth: 0 },
7435
+ children: [
7436
+ title && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7437
+ "div",
7438
+ {
7439
+ style: {
7440
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`,
7441
+ width: "100%",
7442
+ maxWidth: `${chartInnerWidth}px`,
7443
+ display: "flex",
7444
+ justifyContent: titlePosition === "center" ? "center" : titlePosition === "right" ? "flex-end" : "flex-start",
7445
+ alignItems: "center",
7446
+ marginTop: 4
7447
+ },
7448
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h3", { className: titleClassName, children: title })
7449
+ }
7450
+ ),
7451
+ allKeys.length > 0 && (finalEnableHighlights || finalEnableShowOnly) && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
7452
+ "div",
7453
+ {
7454
+ className: "flex items-center w-full",
7455
+ style: {
7456
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`,
7457
+ width: "98%",
7458
+ display: "flex",
7459
+ alignItems: "center",
7460
+ gap: "0.5rem"
7461
+ },
7462
+ children: [
7463
+ finalEnableHighlights && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7464
+ Highlights_default,
7465
+ {
7466
+ allKeys,
7467
+ mapperConfig,
7468
+ finalColors,
7469
+ highlightedSeries,
7470
+ toggleHighlight,
7471
+ containerWidth: chartInnerWidth
7472
+ }
7473
+ ),
7474
+ finalEnableShowOnly && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7475
+ ShowOnly_default,
7476
+ {
7477
+ showOnlyHighlighted,
7478
+ setShowOnlyHighlighted,
7479
+ highlightedSeriesSize: highlightedSeries.size,
7480
+ clearHighlights: () => setHighlightedSeries(/* @__PURE__ */ new Set())
7481
+ }
7482
+ ),
7483
+ finalEnablePeriodsDropdown && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7484
+ "div",
7485
+ {
7486
+ style: {
7487
+ marginLeft: "auto",
7488
+ display: "flex",
7489
+ alignItems: "center"
7490
+ },
7491
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7492
+ PeriodsDropdown_default,
7493
+ {
7494
+ processedData,
7495
+ onOpenPeriod: openTooltipForPeriod,
7496
+ rightOffset: finalChartRightMargin,
7497
+ activePeriods
7498
+ }
7499
+ )
7500
+ }
7501
+ )
7502
+ ]
7503
+ }
7504
+ ),
7505
+ !(allKeys.length > 0 && (finalEnableHighlights || finalEnableShowOnly)) && finalEnablePeriodsDropdown && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7506
+ "div",
7507
+ {
7508
+ style: {
7509
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`,
7510
+ paddingRight: `${finalChartRightMargin}px`,
7511
+ width: "100%",
7512
+ maxWidth: `${chartInnerWidth}px`,
7513
+ display: "flex",
7514
+ justifyContent: "flex-end"
7515
+ },
7516
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7517
+ PeriodsDropdown_default,
7518
+ {
7519
+ processedData,
7520
+ onOpenPeriod: openTooltipForPeriod,
7521
+ rightOffset: finalChartRightMargin
7522
+ }
7523
+ )
7524
+ }
7525
+ ),
7526
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_recharts.ResponsiveContainer, { width: "100%", height, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
7527
+ import_recharts.ComposedChart,
7528
+ {
7529
+ data: processedData,
7530
+ height,
7531
+ margin: {
7532
+ top: finalChartTopMargin,
7533
+ right: finalChartRightMargin,
7534
+ left: finalChartLeftMargin,
7535
+ bottom: finalChartBottomMargin
7536
+ },
7537
+ onClick: handleChartClick,
7538
+ children: [
7539
+ showGrid && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7540
+ import_recharts.CartesianGrid,
7541
+ {
7542
+ strokeDasharray: "3 3",
7543
+ stroke: gridColor || "hsl(var(--muted-foreground))",
7544
+ opacity: 0.5
7545
+ }
7546
+ ),
7547
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7548
+ import_recharts.XAxis,
7549
+ {
7550
+ dataKey: xAxisConfig.dataKey,
7551
+ stroke: "hsl(var(--muted-foreground))",
7552
+ fontSize: 12,
7553
+ tickLine: false,
7554
+ axisLine: false,
7555
+ tickFormatter: xAxisConfig.formatter
7556
+ }
7557
+ ),
7558
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7559
+ import_recharts.YAxis,
7560
+ {
7561
+ stroke: "hsl(var(--muted-foreground))",
7562
+ fontSize: 12,
7563
+ tickLine: false,
7564
+ axisLine: false,
7565
+ tickFormatter: (value) => Number(value).toLocaleString("pt-BR"),
7566
+ domain: [Math.min(minDataValue, 0), niceMax],
7567
+ tickCount: 6
7568
+ }
7569
+ ),
7570
+ minDataValue < 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7571
+ import_recharts.ReferenceLine,
7572
+ {
7573
+ y: 0,
7574
+ stroke: "hsl(var(--muted-foreground))",
7575
+ strokeWidth: 1,
7576
+ strokeDasharray: "4 4"
7577
+ }
7578
+ ),
7579
+ showTooltip && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7580
+ import_recharts.Tooltip,
7581
+ {
7582
+ content: showTooltipTotal ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipWithTotal_default, { finalColors }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TooltipSimple_default, { finalColors }),
7583
+ cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
7584
+ }
7585
+ ),
7586
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7587
+ import_recharts.Legend,
7588
+ {
7589
+ wrapperStyle: {
7590
+ color: "hsl(var(--foreground))",
7591
+ fontSize: "14px"
7592
+ }
7593
+ }
7594
+ ),
7595
+ seriesOrder.map((s) => {
7596
+ const key = s.key;
7597
+ if (showOnlyHighlighted && !highlightedSeries.has(key))
7598
+ return null;
7599
+ const label = mapperConfig[key]?.label ?? labelMap?.[key] ?? formatFieldName(key);
7600
+ const color = finalColors[key];
7601
+ if (s.type === "bar") {
7602
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7603
+ import_recharts.Bar,
7604
+ {
7605
+ dataKey: key,
7606
+ name: label,
7607
+ fill: color,
7608
+ radius: [4, 4, 0, 0],
7609
+ onClick: handleBarClick,
7610
+ style: {
7611
+ cursor: "pointer",
7612
+ opacity: highlightedSeries.size > 0 ? highlightedSeries.has(key) ? 1 : 0.25 : 1
7613
+ },
7614
+ activeBar: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7615
+ import_recharts.Rectangle,
7616
+ {
7617
+ fill: color,
7618
+ stroke: color,
7619
+ strokeWidth: 2,
7620
+ opacity: 0.8
7621
+ }
7622
+ ),
7623
+ children: showLabels && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7624
+ import_recharts.LabelList,
7625
+ {
7626
+ dataKey: key,
7627
+ position: "top",
7628
+ content: pillLabelRenderer_default(color, "filled"),
7629
+ offset: 8
7630
+ }
7631
+ ) : null
7632
+ },
7633
+ `bar-${key}`
7634
+ );
7635
+ }
7636
+ if (s.type === "line") {
7637
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7638
+ import_recharts.Line,
7639
+ {
7640
+ dataKey: key,
7641
+ name: label,
7642
+ stroke: color,
7643
+ strokeWidth: 2,
7644
+ dot: { r: 3 },
7645
+ activeDot: { r: 6 },
7646
+ onClick: handleSeriesClick,
7647
+ style: {
7648
+ cursor: "pointer",
7649
+ pointerEvents: "all",
7650
+ opacity: highlightedSeries.size > 0 ? highlightedSeries.has(key) ? 1 : 0.25 : 1
7651
+ },
7652
+ children: showLabels && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7653
+ import_recharts.LabelList,
7654
+ {
7655
+ dataKey: key,
7656
+ position: "top",
7657
+ content: pillLabelRenderer_default(color, "filled"),
7658
+ offset: 14
7659
+ }
7660
+ ) : null
7661
+ },
7662
+ `line-${key}`
7663
+ );
7664
+ }
7665
+ if (s.type === "area") {
7666
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7667
+ import_recharts.Area,
7668
+ {
7669
+ dataKey: key,
7670
+ name: label,
7671
+ stroke: color,
7672
+ fill: color,
7673
+ fillOpacity: 0.35,
7674
+ strokeWidth: 2,
7675
+ onClick: handleSeriesClick,
7676
+ style: {
7677
+ cursor: "pointer",
7678
+ pointerEvents: "all",
7679
+ opacity: highlightedSeries.size > 0 ? highlightedSeries.has(key) ? 1 : 0.25 : 1
7680
+ },
7681
+ children: showLabels && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7682
+ import_recharts.LabelList,
7683
+ {
7684
+ dataKey: key,
7685
+ position: "top",
7686
+ content: pillLabelRenderer_default(color, "soft"),
7687
+ offset: 12
7688
+ }
7689
+ ) : null
7690
+ },
7691
+ `area-${key}`
7692
+ );
7693
+ }
7694
+ return null;
7695
+ })
7696
+ ]
7697
+ }
7698
+ ) }),
7699
+ enableDraggableTooltips && activeTooltips.map((tooltip) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7700
+ DraggableTooltip_default,
7701
+ {
7702
+ id: tooltip.id,
7703
+ data: adaptDataForTooltip(tooltip.data),
7704
+ position: tooltip.position,
7705
+ title,
7706
+ dataKeys: allKeys,
7707
+ finalColors,
7708
+ highlightedSeries,
7709
+ toggleHighlight,
7710
+ showOnlyHighlighted,
7711
+ onClose: (id) => setActiveTooltips((prev) => prev.filter((t) => t.id !== id)),
7712
+ onPositionChange: onTooltipPositionChange,
7713
+ periodLabel: "Per\xEDodo Selecionado",
7714
+ dataLabel: "Dados do Per\xEDodo",
7715
+ globalTooltipCount: activeTooltips.length,
7716
+ onCloseAll: () => window.dispatchEvent(new Event("closeAllTooltips")),
7717
+ closeAllButtonPosition: "top-center",
7718
+ closeAllButtonVariant: "floating"
7719
+ },
7720
+ tooltip.id
7721
+ )),
7722
+ enableDraggableTooltips && activeTooltips.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
7723
+ CloseAllButton_default,
7724
+ {
7725
+ count: activeTooltips.length,
7726
+ onCloseAll: () => window.dispatchEvent(new Event("closeAllTooltips")),
7727
+ position: "top-center",
7728
+ variant: "floating"
7729
+ }
7730
+ )
7731
+ ]
7732
+ }
7733
+ )
7734
+ }
7735
+ );
7736
+ };
7737
+ var Chart_default = Chart;
7738
+
7739
+ // src/components/charts/BarChart.tsx
7740
+ var import_react37 = require("react");
7741
+ var import_recharts2 = require("recharts");
7742
+ var import_jsx_runtime58 = require("react/jsx-runtime");
7743
+ var DEFAULT_COLORS2 = ["#55af7d", "#8e68ff", "#2273e1"];
7744
+ var BarChart = ({
7745
+ data,
7746
+ className,
7747
+ height = 350,
7748
+ width = 900,
7749
+ colors: colors2 = DEFAULT_COLORS2,
7750
+ gridColor,
7751
+ showGrid = true,
7752
+ showTooltip = true,
7753
+ showLegend = true,
7754
+ title,
7755
+ titlePosition = "left",
7756
+ showLabels = false,
7757
+ xAxis,
7758
+ mapper,
7759
+ yAxis,
7760
+ labelMap,
7761
+ autoDetect = false,
7762
+ padding,
7763
+ margins,
7764
+ containerPaddingLeft,
7765
+ chartMargins
7766
+ }) => {
7767
+ const resolvedContainerPaddingLeft = resolveContainerPaddingLeft(
7768
+ padding,
7769
+ containerPaddingLeft,
7770
+ 16
7771
+ );
7772
+ const smartConfig = (0, import_react37.useMemo)(() => {
7773
+ const providedMapper = yAxis ?? mapper;
7774
+ if (autoDetect === true || xAxis == null || providedMapper == null) {
7775
+ const detectedXAxis = detectXAxis(data);
7776
+ const detectedFields = detectDataFields(data, detectedXAxis);
7777
+ return {
7778
+ xAxisConfig: {
7779
+ dataKey: detectedXAxis,
7780
+ label: labelMap?.[detectedXAxis] ?? formatFieldName(detectedXAxis),
7781
+ autoLabel: true
7782
+ },
7783
+ mapperConfig: detectedFields.reduce((acc, field) => {
7784
+ acc[field] = {
7785
+ label: labelMap?.[field] ?? formatFieldName(field),
7786
+ type: "number",
7787
+ visible: true
7788
+ };
7789
+ return acc;
7790
+ }, {})
7791
+ };
7792
+ }
7793
+ const xAxisConfig2 = typeof xAxis === "string" ? { dataKey: xAxis, label: formatFieldName(xAxis), autoLabel: true } : xAxis;
7794
+ let mapperConfig2;
7795
+ if (Array.isArray(providedMapper)) {
7796
+ mapperConfig2 = providedMapper.reduce((acc, field) => {
7797
+ acc[field] = {
7798
+ label: labelMap?.[field] ?? formatFieldName(field),
7799
+ type: "auto",
7800
+ visible: true
7801
+ };
7802
+ return acc;
7803
+ }, {});
7804
+ } else {
7805
+ mapperConfig2 = Object.keys(providedMapper).reduce(
7806
+ (acc, key) => {
7807
+ acc[key] = {
7808
+ label: providedMapper[key]?.label ?? labelMap?.[key] ?? formatFieldName(key),
7809
+ type: "auto",
7810
+ visible: true,
7811
+ ...providedMapper[key]
7812
+ // Sobrescreve com configurações do usuário
7813
+ };
7814
+ return acc;
7815
+ },
7816
+ {}
7817
+ );
7818
+ }
7819
+ return { xAxisConfig: xAxisConfig2, mapperConfig: mapperConfig2 };
7820
+ }, [data, xAxis, mapper, yAxis, autoDetect, labelMap]);
7821
+ const { xAxisConfig, mapperConfig } = smartConfig;
7822
+ const [activeTooltips, setActiveTooltips] = (0, import_react37.useState)([]);
7823
+ const [isDragging, setIsDragging] = (0, import_react37.useState)(null);
7824
+ const [dragOffset, setDragOffset] = (0, import_react37.useState)({
7825
+ x: 0,
7826
+ y: 0
7827
+ });
7828
+ const [globalTooltipCount, setGlobalTooltipCount] = (0, import_react37.useState)(0);
7829
+ const [alignmentGuides, setAlignmentGuides] = (0, import_react37.useState)([]);
7830
+ const processedData = data.map((item) => ({
7831
+ ...item,
7832
+ name: String(item[xAxisConfig.dataKey] || "N/A")
7833
+ // Garantir propriedade 'name' para tooltip
7834
+ }));
7835
+ const generateColors = (dataKeys2) => {
7836
+ const colorMap = {};
7837
+ const allColors = generateAdditionalColors(colors2, dataKeys2.length);
7838
+ dataKeys2.forEach((key, index) => {
7839
+ colorMap[key] = allColors[index] || colors2[index % colors2.length];
7840
+ });
7841
+ return colorMap;
7842
+ };
7843
+ const dataKeys = Object.keys(mapperConfig);
7844
+ const finalColors = generateColors(dataKeys);
7845
+ const adaptDataForTooltip = (universalData) => {
7846
+ return {
7847
+ ...universalData,
7848
+ name: String(universalData[xAxisConfig.dataKey] || "N/A")
7849
+ // Garantir que tem a propriedade 'name'
7850
+ };
7851
+ };
7852
+ const maxDataValue = (0, import_react37.useMemo)(() => {
7853
+ let max = 0;
7854
+ const keys = Object.keys(mapperConfig);
7855
+ for (const row of processedData) {
7856
+ const r = row;
7857
+ for (const key of keys) {
7858
+ const v = r[key];
7859
+ if (typeof v === "number" && Number.isFinite(v) && v > max)
7860
+ max = v;
7861
+ }
7862
+ }
7863
+ return max;
7864
+ }, [processedData, mapperConfig]);
7865
+ const niceMax = (0, import_react37.useMemo)(() => {
7866
+ let padding2 = 0.08;
7867
+ if (maxDataValue > 1e6) padding2 = 0.05;
7868
+ if (maxDataValue > 1e7) padding2 = 0.03;
7869
+ if (maxDataValue === 0) padding2 = 0.12;
7870
+ const padded = maxDataValue * (1 + padding2);
7871
+ return niceCeil(padded);
7872
+ }, [maxDataValue]);
7873
+ const handleBarClick = (data2, index, event) => {
7874
+ event.stopPropagation();
7875
+ const xAxisValue = data2[xAxisConfig.dataKey] || "N/A";
7876
+ const tooltipId = `${xAxisValue}`;
7877
+ const rect = event.target.getBoundingClientRect();
7878
+ const existingIndex = activeTooltips.findIndex(
7879
+ (tooltip) => tooltip.id === tooltipId
7880
+ );
7881
+ if (existingIndex !== -1) {
7882
+ setActiveTooltips(
7883
+ (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
7884
+ );
7885
+ } else {
7886
+ const newTooltip = {
7887
+ id: tooltipId,
7888
+ data: data2,
7889
+ position: {
7890
+ top: rect.top - 10,
7891
+ // Posição fixa da viewport
7892
+ left: rect.right + 10
7893
+ // À direita da barra clicada
7894
+ }
7895
+ };
7896
+ setActiveTooltips((prev) => [...prev, newTooltip]);
7897
+ }
7898
+ };
7899
+ const handleChartClick = () => {
7900
+ setActiveTooltips([]);
7901
+ };
7902
+ const ALIGNMENT_THRESHOLD2 = 25;
7903
+ const GUIDE_THRESHOLD2 = 60;
7904
+ const STRONG_SNAP_THRESHOLD2 = 35;
7905
+ const PRECISION_SNAP_THRESHOLD2 = 8;
7906
+ const updateAlignmentGuides = (0, import_react37.useCallback)(
7907
+ (draggedTooltipId, currentPosition) => {
7908
+ if (!isDragging) return;
7909
+ const getAllTooltips = () => {
7910
+ const allTooltips2 = [];
7911
+ allTooltips2.push(...activeTooltips);
7912
+ const globalEvent = new CustomEvent("requestGlobalTooltips", {
7913
+ detail: { requesterId: draggedTooltipId, response: allTooltips2 }
7914
+ });
7915
+ window.dispatchEvent(globalEvent);
7916
+ return allTooltips2;
7917
+ };
7918
+ const allTooltips = getAllTooltips();
7919
+ const otherTooltips = allTooltips.filter(
7920
+ (t) => t.id !== draggedTooltipId
7921
+ );
7922
+ const guides = [];
7923
+ const tooltipDimensions = { width: 224, height: 120 };
7924
+ otherTooltips.forEach((tooltip) => {
7925
+ const topDiff = Math.abs(currentPosition.top - tooltip.position.top);
7926
+ if (topDiff <= GUIDE_THRESHOLD2) {
7927
+ guides.push({
7928
+ type: "horizontal",
7929
+ position: tooltip.position.top,
7930
+ visible: true,
7931
+ sourceTooltip: {
7932
+ top: currentPosition.top,
7933
+ left: currentPosition.left,
7934
+ width: tooltipDimensions.width,
7935
+ height: tooltipDimensions.height
7936
+ },
7937
+ targetTooltip: {
7938
+ top: tooltip.position.top,
7939
+ left: tooltip.position.left,
7940
+ width: tooltipDimensions.width,
7941
+ height: tooltipDimensions.height
7942
+ }
7943
+ });
7944
+ }
7945
+ const leftDiff = Math.abs(currentPosition.left - tooltip.position.left);
7946
+ if (leftDiff <= GUIDE_THRESHOLD2) {
7947
+ guides.push({
7948
+ type: "vertical",
7949
+ position: tooltip.position.left,
7950
+ visible: true,
7951
+ sourceTooltip: {
7952
+ top: currentPosition.top,
7953
+ left: currentPosition.left,
7954
+ width: tooltipDimensions.width,
7955
+ height: tooltipDimensions.height
7956
+ },
7957
+ targetTooltip: {
7958
+ top: tooltip.position.top,
7959
+ left: tooltip.position.left,
7960
+ width: tooltipDimensions.width,
7961
+ height: tooltipDimensions.height
7962
+ }
7963
+ });
7964
+ }
7965
+ });
7966
+ setAlignmentGuides(guides);
7967
+ },
7968
+ [isDragging, activeTooltips]
7969
+ );
7970
+ const snapToGuides = (0, import_react37.useCallback)(
7971
+ (position) => {
7972
+ const snappedPosition = { ...position };
7973
+ let hasSnapped = false;
7974
+ alignmentGuides.forEach((guide) => {
7975
+ if (guide.type === "horizontal") {
7976
+ const diff = Math.abs(position.top - guide.position);
7977
+ if (diff <= PRECISION_SNAP_THRESHOLD2) {
7978
+ snappedPosition.top = guide.position;
7979
+ hasSnapped = true;
7980
+ }
7981
+ } else if (guide.type === "vertical") {
7982
+ const diff = Math.abs(position.left - guide.position);
7983
+ if (diff <= PRECISION_SNAP_THRESHOLD2) {
7984
+ snappedPosition.left = guide.position;
7985
+ hasSnapped = true;
7986
+ }
7987
+ }
7988
+ });
7989
+ if (!hasSnapped) {
7990
+ alignmentGuides.forEach((guide) => {
7991
+ if (guide.type === "horizontal") {
7992
+ const diff = Math.abs(position.top - guide.position);
7993
+ if (diff <= STRONG_SNAP_THRESHOLD2) {
7994
+ snappedPosition.top = guide.position;
7995
+ }
7996
+ } else if (guide.type === "vertical") {
7997
+ const diff = Math.abs(position.left - guide.position);
7998
+ if (diff <= STRONG_SNAP_THRESHOLD2) {
7999
+ snappedPosition.left = guide.position;
8000
+ }
8001
+ }
8002
+ });
8003
+ }
8004
+ alignmentGuides.forEach((guide) => {
8005
+ if (guide.type === "horizontal") {
8006
+ const diff = Math.abs(position.top - guide.position);
8007
+ if (diff <= ALIGNMENT_THRESHOLD2 && snappedPosition.top === position.top) {
8008
+ snappedPosition.top = guide.position;
8009
+ }
8010
+ } else if (guide.type === "vertical") {
8011
+ const diff = Math.abs(position.left - guide.position);
8012
+ if (diff <= ALIGNMENT_THRESHOLD2 && snappedPosition.left === position.left) {
8013
+ snappedPosition.left = guide.position;
8014
+ }
8015
+ }
8016
+ });
8017
+ return snappedPosition;
8018
+ },
8019
+ [alignmentGuides]
8020
+ );
8021
+ const handleMouseDown = (e, tooltipId) => {
8022
+ e.preventDefault();
8023
+ e.stopPropagation();
8024
+ const tooltip = activeTooltips.find((t) => t.id === tooltipId);
8025
+ if (!tooltip) return;
8026
+ const rect = e.currentTarget.getBoundingClientRect();
8027
+ const offsetX = e.clientX - rect.left;
8028
+ const offsetY = e.clientY - rect.top;
8029
+ setIsDragging(tooltipId);
8030
+ setDragOffset({ x: offsetX, y: offsetY });
8031
+ };
8032
+ (0, import_react37.useEffect)(() => {
8033
+ let rafId;
8034
+ let lastMousePosition = { x: 0, y: 0 };
8035
+ const handleGlobalMouseMove = (e) => {
8036
+ if (!isDragging) return;
8037
+ lastMousePosition = { x: e.clientX, y: e.clientY };
8038
+ if (rafId) cancelAnimationFrame(rafId);
8039
+ rafId = requestAnimationFrame(() => {
8040
+ const newLeft = lastMousePosition.x - dragOffset.x;
8041
+ const newTop = lastMousePosition.y - dragOffset.y;
8042
+ const rawPosition = {
8043
+ top: Math.max(0, Math.min(newTop, window.innerHeight - 200)),
8044
+ left: Math.max(0, Math.min(newLeft, window.innerWidth - 250))
8045
+ };
8046
+ updateAlignmentGuides(isDragging, rawPosition);
8047
+ const snappedPosition = snapToGuides(rawPosition);
8048
+ setActiveTooltips(
8049
+ (prev) => prev.map((tooltip) => {
8050
+ if (tooltip.id === isDragging) {
8051
+ return {
8052
+ ...tooltip,
8053
+ position: snappedPosition
8054
+ };
8055
+ }
8056
+ return tooltip;
8057
+ })
8058
+ );
8059
+ });
8060
+ };
8061
+ const handleGlobalMouseUp = () => {
8062
+ if (isDragging) {
8063
+ setIsDragging(null);
8064
+ setAlignmentGuides([]);
8065
+ if (rafId) cancelAnimationFrame(rafId);
8066
+ }
8067
+ };
8068
+ if (isDragging) {
8069
+ document.addEventListener("mousemove", handleGlobalMouseMove, {
8070
+ passive: true
8071
+ });
8072
+ document.addEventListener("mouseup", handleGlobalMouseUp);
8073
+ document.body.style.cursor = "grabbing";
8074
+ document.body.style.userSelect = "none";
8075
+ }
8076
+ return () => {
8077
+ if (rafId) cancelAnimationFrame(rafId);
8078
+ document.removeEventListener("mousemove", handleGlobalMouseMove);
8079
+ document.removeEventListener("mouseup", handleGlobalMouseUp);
8080
+ document.body.style.cursor = "";
8081
+ document.body.style.userSelect = "";
8082
+ };
8083
+ }, [
8084
+ isDragging,
8085
+ dragOffset,
8086
+ alignmentGuides,
8087
+ updateAlignmentGuides,
8088
+ snapToGuides
8089
+ ]);
8090
+ (0, import_react37.useEffect)(() => {
8091
+ const handleCloseAllTooltips = () => {
8092
+ setActiveTooltips([]);
8093
+ setGlobalTooltipCount(0);
8094
+ };
8095
+ window.addEventListener("closeAllTooltips", handleCloseAllTooltips);
8096
+ return () => {
8097
+ window.removeEventListener("closeAllTooltips", handleCloseAllTooltips);
8098
+ };
8099
+ }, []);
8100
+ (0, import_react37.useEffect)(() => {
8101
+ const handleTooltipCountRequest = () => {
8102
+ window.dispatchEvent(
8103
+ new CustomEvent("tooltipCountResponse", {
8104
+ detail: { count: activeTooltips.length }
8105
+ })
8106
+ );
8107
+ };
8108
+ const handleGlobalTooltipsRequest = (event) => {
8109
+ const { detail } = event;
8110
+ if (detail && detail.response && detail.requesterId) {
8111
+ activeTooltips.forEach((tooltip) => {
8112
+ if (!detail.response.find(
8113
+ (t) => t.id === tooltip.id
8114
+ )) {
8115
+ detail.response.push({
8116
+ id: tooltip.id,
8117
+ position: tooltip.position
8118
+ });
8119
+ }
8120
+ });
8121
+ }
8122
+ };
8123
+ window.addEventListener("requestTooltipCount", handleTooltipCountRequest);
8124
+ window.addEventListener(
8125
+ "requestGlobalTooltips",
8126
+ handleGlobalTooltipsRequest
8127
+ );
8128
+ return () => {
8129
+ window.removeEventListener(
8130
+ "requestTooltipCount",
8131
+ handleTooltipCountRequest
8132
+ );
8133
+ window.removeEventListener(
8134
+ "requestGlobalTooltips",
8135
+ handleGlobalTooltipsRequest
8136
+ );
8137
+ };
8138
+ }, [activeTooltips]);
8139
+ (0, import_react37.useEffect)(() => {
8140
+ if (isDragging) return;
8141
+ let totalCount = 0;
8142
+ const handleCountResponse = (event) => {
8143
+ const customEvent = event;
8144
+ totalCount += customEvent.detail.count;
8145
+ };
8146
+ window.addEventListener("tooltipCountResponse", handleCountResponse);
8147
+ window.dispatchEvent(new CustomEvent("requestTooltipCount"));
8148
+ const timeoutId = setTimeout(() => {
8149
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
8150
+ setGlobalTooltipCount(totalCount);
8151
+ }, 5);
8152
+ return () => {
8153
+ clearTimeout(timeoutId);
8154
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
8155
+ };
8156
+ }, [activeTooltips.length, isDragging]);
8157
+ const CustomTooltip = ({
8158
+ active,
8159
+ payload,
8160
+ label
8161
+ }) => {
8162
+ if (!active || !payload) return null;
8163
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "bg-card border border-border rounded-lg p-3 shadow-lg", children: [
8164
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "font-medium text-foreground mb-2", children: label }),
8165
+ payload.map(
8166
+ (entry, index) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex items-center gap-2 text-sm", children: [
8167
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8168
+ "div",
8169
+ {
8170
+ className: "w-3 h-3 rounded-sm",
8171
+ style: { backgroundColor: entry.color }
8172
+ }
8173
+ ),
8174
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "text-muted-foreground", children: [
8175
+ entry.name,
8176
+ ":"
8177
+ ] }),
8178
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-foreground font-medium", children: entry.value?.toLocaleString("pt-BR") })
8179
+ ] }, index)
8180
+ ),
8181
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "text-xs text-muted-foreground mt-1", children: "Clique para fixar este tooltip" })
8182
+ ] });
8183
+ };
8184
+ const getTitleClassName = (position) => {
8185
+ const baseClasses = "text-xl font-semibold text-foreground mb-3";
8186
+ switch (position) {
8187
+ case "center":
8188
+ return `${baseClasses} text-center`;
8189
+ case "right":
8190
+ return `${baseClasses} text-right`;
8191
+ default:
8192
+ return `${baseClasses} text-left`;
8193
+ }
8194
+ };
8195
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
8196
+ "div",
8197
+ {
8198
+ className: cn("rounded-lg bg-card p-4 relative", className),
8199
+ style: {
8200
+ width: typeof width === "number" ? `${width + 32}px` : "fit-content",
8201
+ maxWidth: "100%"
8202
+ },
8203
+ children: [
8204
+ title && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { style: { paddingLeft: `${resolvedContainerPaddingLeft}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h3", { className: getTitleClassName(titlePosition), children: title }) }),
8205
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
8206
+ import_recharts2.BarChart,
8207
+ {
8208
+ data: processedData,
8209
+ width: typeof width === "number" ? width : 900,
8210
+ height,
8211
+ margin: resolveChartMargins(margins, chartMargins, showLabels),
8212
+ onClick: handleChartClick,
8213
+ children: [
8214
+ showGrid && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8215
+ import_recharts2.CartesianGrid,
8216
+ {
8217
+ strokeDasharray: "3 3",
8218
+ stroke: gridColor || "hsl(var(--muted-foreground))",
8219
+ opacity: 0.5
8220
+ }
8221
+ ),
8222
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8223
+ import_recharts2.XAxis,
8224
+ {
8225
+ dataKey: xAxisConfig.dataKey,
8226
+ stroke: "hsl(var(--muted-foreground))",
8227
+ fontSize: 12,
8228
+ tickLine: false,
8229
+ axisLine: false,
8230
+ tickFormatter: xAxisConfig.formatter
8231
+ }
8232
+ ),
8233
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8234
+ import_recharts2.YAxis,
8235
+ {
8236
+ stroke: "hsl(var(--muted-foreground))",
8237
+ fontSize: 12,
8238
+ tickLine: false,
8239
+ axisLine: false,
8240
+ tickFormatter: (value) => value.toLocaleString("pt-BR"),
8241
+ domain: [0, niceMax],
8242
+ tickCount: 6
8243
+ }
8244
+ ),
8245
+ showTooltip && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8246
+ import_recharts2.Tooltip,
8247
+ {
8248
+ content: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(CustomTooltip, {}),
8249
+ cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
8250
+ }
8251
+ ),
8252
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8253
+ import_recharts2.Legend,
8254
+ {
8255
+ wrapperStyle: {
8256
+ color: "hsl(var(--foreground))",
8257
+ fontSize: "14px"
8258
+ }
8259
+ }
8260
+ ),
8261
+ dataKeys.map((key) => {
8262
+ const fieldConfig = mapperConfig[key];
8263
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8264
+ import_recharts2.Bar,
8265
+ {
8266
+ dataKey: key,
8267
+ name: fieldConfig?.label || key,
8268
+ fill: fieldConfig?.color || finalColors[key],
8269
+ radius: [4, 4, 0, 0],
8270
+ onClick: handleBarClick,
8271
+ style: { cursor: "pointer" },
8272
+ activeBar: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8273
+ import_recharts2.Rectangle,
8274
+ {
8275
+ fill: finalColors[key],
8276
+ stroke: finalColors[key],
8277
+ strokeWidth: 2,
8278
+ opacity: 0.8
8279
+ }
8280
+ ),
8281
+ children: showLabels && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8282
+ import_recharts2.LabelList,
8283
+ {
8284
+ dataKey: key,
8285
+ position: "top",
8286
+ content: pillLabelRenderer_default(
8287
+ finalColors[key] || "#000",
8288
+ "filled"
8289
+ )
8290
+ }
8291
+ )
8292
+ },
8293
+ key
8294
+ );
8295
+ })
8296
+ ]
8297
+ }
8298
+ ),
8299
+ alignmentGuides.map((guide, index) => {
8300
+ const isHorizontal = guide.type === "horizontal";
8301
+ const color = isHorizontal ? "#3b82f6" : "#ef4444";
8302
+ const startX = isHorizontal ? Math.min(
8303
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8304
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8305
+ ) : guide.sourceTooltip.left + (isHorizontal ? 0 : guide.sourceTooltip.width / 2);
8306
+ const endX = isHorizontal ? Math.max(
8307
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8308
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8309
+ ) : guide.targetTooltip.left + (isHorizontal ? 0 : guide.targetTooltip.width / 2);
8310
+ const startY = isHorizontal ? guide.sourceTooltip.top + (isHorizontal ? guide.sourceTooltip.height / 2 : 0) : Math.min(
8311
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8312
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8313
+ );
8314
+ const endY = isHorizontal ? guide.targetTooltip.top + (isHorizontal ? guide.targetTooltip.height / 2 : 0) : Math.max(
8315
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8316
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8317
+ );
8318
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
8319
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8320
+ "div",
8321
+ {
8322
+ className: "fixed pointer-events-none z-30",
8323
+ style: {
8324
+ left: startX,
8325
+ top: startY,
8326
+ width: isHorizontal ? endX - startX : "2px",
8327
+ height: isHorizontal ? "2px" : endY - startY,
8328
+ backgroundColor: color,
8329
+ boxShadow: `0 0 8px ${color}60`,
8330
+ opacity: 0.9,
8331
+ borderStyle: "dashed",
8332
+ borderWidth: "1px",
8333
+ borderColor: color,
8334
+ transform: "translateZ(0)"
8335
+ }
8336
+ }
8337
+ ),
8338
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8339
+ "div",
8340
+ {
8341
+ className: "fixed pointer-events-none z-31",
8342
+ style: {
8343
+ left: guide.sourceTooltip.left + guide.sourceTooltip.width / 2 - 4,
8344
+ top: guide.sourceTooltip.top + guide.sourceTooltip.height / 2 - 4,
8345
+ width: "8px",
8346
+ height: "8px",
8347
+ backgroundColor: color,
8348
+ borderRadius: "50%",
8349
+ boxShadow: `0 0 4px ${color}80`,
8350
+ opacity: 0.8
8351
+ }
8352
+ }
8353
+ ),
8354
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8355
+ "div",
8356
+ {
8357
+ className: "fixed pointer-events-none z-31",
8358
+ style: {
8359
+ left: guide.targetTooltip.left + guide.targetTooltip.width / 2 - 4,
8360
+ top: guide.targetTooltip.top + guide.targetTooltip.height / 2 - 4,
8361
+ width: "8px",
8362
+ height: "8px",
8363
+ backgroundColor: color,
8364
+ borderRadius: "50%",
8365
+ boxShadow: `0 0 4px ${color}80`,
8366
+ opacity: 0.8
8367
+ }
8368
+ }
8369
+ )
8370
+ ] }, index);
8371
+ }),
8372
+ activeTooltips.map((tooltip, index) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
8373
+ DraggableTooltip_default,
8374
+ {
8375
+ id: tooltip.id,
8376
+ data: adaptDataForTooltip(tooltip.data),
8377
+ position: tooltip.position,
8378
+ isDragging: isDragging === tooltip.id,
8379
+ title,
8380
+ dataKeys,
8381
+ finalColors,
8382
+ onMouseDown: (id, e) => handleMouseDown(e, id),
8383
+ onClose: (id) => {
8384
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== id));
8385
+ },
8386
+ periodLabel: "Per\xEDodo Selecionado",
8387
+ dataLabel: "Dados do Per\xEDodo",
8388
+ showCloseAllButton: index === 0,
8389
+ globalTooltipCount,
8390
+ onCloseAll: () => {
8391
+ window.dispatchEvent(new Event("closeAllTooltips"));
8392
+ },
8393
+ closeAllButtonPosition: "top-center",
8394
+ closeAllButtonVariant: "floating"
8395
+ },
8396
+ tooltip.id
8397
+ ))
8398
+ ]
8399
+ }
8400
+ );
8401
+ };
8402
+ var BarChart_default = BarChart;
8403
+
8404
+ // src/components/charts/LineChart.tsx
8405
+ var import_react38 = require("react");
8406
+ var import_recharts3 = require("recharts");
8407
+ var import_jsx_runtime59 = require("react/jsx-runtime");
8408
+ var defaultData = [
8409
+ { name: "A", value: 100 },
8410
+ { name: "B", value: 200 },
8411
+ { name: "C", value: 150 }
8412
+ ];
8413
+ var DEFAULT_COLORS3 = ["#55af7d", "#8e68ff", "#2273e1"];
8414
+ var CustomLineChart = ({
8415
+ data = defaultData,
8416
+ className,
8417
+ height = 300,
8418
+ width = "100%",
8419
+ colors: colors2 = DEFAULT_COLORS3,
8420
+ gridColor,
8421
+ showGrid = true,
8422
+ showTooltip = true,
8423
+ showLegend = true,
8424
+ title,
8425
+ titlePosition = "left",
8426
+ strokeWidth = 2,
8427
+ showDots = true,
8428
+ showLabels = false,
8429
+ padding,
8430
+ margins,
8431
+ containerPaddingLeft,
8432
+ chartMargins
8433
+ }) => {
8434
+ const resolvedContainerPaddingLeft = resolveContainerPaddingLeft(
8435
+ padding,
8436
+ containerPaddingLeft,
8437
+ 16
8438
+ );
8439
+ const [activeTooltips, setActiveTooltips] = (0, import_react38.useState)([]);
8440
+ const [isDragging, setIsDragging] = (0, import_react38.useState)(null);
8441
+ const [dragOffset, setDragOffset] = (0, import_react38.useState)({
8442
+ x: 0,
8443
+ y: 0
8444
+ });
8445
+ const [globalTooltipCount, setGlobalTooltipCount] = (0, import_react38.useState)(0);
8446
+ const [alignmentGuides, setAlignmentGuides] = (0, import_react38.useState)([]);
8447
+ const generateColors = (dataKeys2) => {
8448
+ const colorMap = {};
8449
+ const allColors = generateAdditionalColors(colors2, dataKeys2.length);
8450
+ dataKeys2.forEach((key, index) => {
8451
+ colorMap[key] = allColors[index] || colors2[index % colors2.length];
8452
+ });
8453
+ return colorMap;
8454
+ };
8455
+ const dataKeys = (0, import_react38.useMemo)(
8456
+ () => data.length > 0 ? Object.keys(data[0]).filter((key) => key !== "name") : [],
8457
+ [data]
8458
+ );
8459
+ const finalColors = generateColors(dataKeys);
8460
+ const maxDataValue = (0, import_react38.useMemo)(() => {
8461
+ let max = 0;
8462
+ for (const row of data) {
8463
+ const r = row;
8464
+ for (const key of dataKeys) {
8465
+ const v = r[key];
8466
+ if (typeof v === "number" && Number.isFinite(v) && v > max)
8467
+ max = v;
8468
+ }
8469
+ }
8470
+ return max;
8471
+ }, [data, dataKeys]);
8472
+ const niceMax = (0, import_react38.useMemo)(() => {
8473
+ let padding2 = 0.08;
8474
+ if (maxDataValue > 1e6) padding2 = 0.05;
8475
+ if (maxDataValue > 1e7) padding2 = 0.03;
8476
+ if (maxDataValue === 0) padding2 = 0.12;
8477
+ const padded = maxDataValue * (1 + padding2);
8478
+ return niceCeil(padded);
8479
+ }, [maxDataValue]);
8480
+ const ClickableDot = (props) => {
8481
+ const { cx, cy, payload, dataKey } = props;
8482
+ const handleDotClick = (e) => {
8483
+ e.stopPropagation();
8484
+ if (!payload || !cx || !cy) return;
8485
+ const tooltipId = `${payload.name}`;
8486
+ const existingIndex = activeTooltips.findIndex(
8487
+ (tooltip) => tooltip.id === tooltipId
8488
+ );
8489
+ if (existingIndex !== -1) {
8490
+ setActiveTooltips(
8491
+ (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
8492
+ );
8493
+ } else {
8494
+ const newTooltip = {
8495
+ id: tooltipId,
8496
+ data: payload,
8497
+ position: {
8498
+ top: cy - 50,
8499
+ // Posição relativa ao SVG
8500
+ left: cx - 100
8501
+ }
8502
+ };
8503
+ setActiveTooltips((prev) => [...prev, newTooltip]);
8504
+ }
8505
+ };
8506
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8507
+ "circle",
8508
+ {
8509
+ cx,
8510
+ cy,
8511
+ r: 6,
8512
+ fill: finalColors[dataKey || ""] || colors2[0],
8513
+ stroke: finalColors[dataKey || ""] || colors2[0],
8514
+ strokeWidth: 2,
8515
+ style: { cursor: "pointer" },
8516
+ onClick: handleDotClick
8517
+ }
8518
+ );
8519
+ };
8520
+ const handleChartClick = (e) => {
8521
+ if (e && e.activePayload && e.activePayload.length > 0) {
8522
+ const clickedData = e.activePayload[0].payload;
8523
+ const tooltipId = `${clickedData.name}`;
8524
+ const existingIndex = activeTooltips.findIndex(
8525
+ (tooltip) => tooltip.id === tooltipId
8526
+ );
8527
+ if (existingIndex !== -1) {
8528
+ setActiveTooltips(
8529
+ (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
8530
+ );
8531
+ } else {
8532
+ const newTooltip = {
8533
+ id: tooltipId,
8534
+ data: clickedData,
8535
+ position: {
8536
+ top: (e.chartY || 100) - 10,
8537
+ left: (e.chartX || 100) - 100
8538
+ }
8539
+ };
8540
+ setActiveTooltips((prev) => [...prev, newTooltip]);
8541
+ }
8542
+ } else {
8543
+ }
8544
+ };
8545
+ const handleChartBackgroundClick = () => {
8546
+ setActiveTooltips([]);
8547
+ };
8548
+ const handleCloseAllTooltips = (0, import_react38.useCallback)(() => {
8549
+ window.dispatchEvent(new CustomEvent("closeAllTooltips"));
8550
+ }, []);
8551
+ const updateAlignmentGuides = (0, import_react38.useCallback)(
8552
+ (draggedTooltipId, draggedPosition) => {
8553
+ const SNAP_THRESHOLD = 15;
8554
+ const draggedTooltip = activeTooltips.find(
8555
+ (t) => t.id === draggedTooltipId
8556
+ );
8557
+ if (!draggedTooltip) return;
8558
+ const tooltipWidth = 200;
8559
+ const tooltipHeight = 80;
8560
+ const globalTooltips = [];
8561
+ window.dispatchEvent(
8562
+ new CustomEvent("requestGlobalTooltips", {
8563
+ detail: { requesterId: draggedTooltipId }
8564
+ })
8565
+ );
8566
+ activeTooltips.forEach((tooltip) => {
8567
+ if (tooltip.id !== draggedTooltipId) {
8568
+ globalTooltips.push({
8569
+ top: tooltip.position.top,
8570
+ left: tooltip.position.left,
8571
+ width: tooltipWidth,
8572
+ height: tooltipHeight,
8573
+ id: tooltip.id
8574
+ });
8575
+ }
8576
+ });
8577
+ const newGuides = [];
8578
+ globalTooltips.forEach((otherTooltip) => {
8579
+ const draggedCenter = {
8580
+ x: draggedPosition.left + tooltipWidth / 2,
8581
+ y: draggedPosition.top + tooltipHeight / 2
8582
+ };
8583
+ const otherCenter = {
8584
+ x: otherTooltip.left + otherTooltip.width / 2,
8585
+ y: otherTooltip.top + otherTooltip.height / 2
8586
+ };
8587
+ const horizontalDistance = Math.abs(draggedCenter.y - otherCenter.y);
8588
+ if (horizontalDistance <= SNAP_THRESHOLD) {
8589
+ newGuides.push({
8590
+ type: "horizontal",
8591
+ position: otherCenter.y,
8592
+ visible: true,
8593
+ sourceTooltip: {
8594
+ top: draggedPosition.top,
8595
+ left: draggedPosition.left,
8596
+ width: tooltipWidth,
8597
+ height: tooltipHeight
8598
+ },
8599
+ targetTooltip: {
8600
+ top: otherTooltip.top,
8601
+ left: otherTooltip.left,
8602
+ width: otherTooltip.width,
8603
+ height: otherTooltip.height
8604
+ }
8605
+ });
8606
+ }
8607
+ const verticalDistance = Math.abs(draggedCenter.x - otherCenter.x);
8608
+ if (verticalDistance <= SNAP_THRESHOLD) {
8609
+ newGuides.push({
8610
+ type: "vertical",
8611
+ position: otherCenter.x,
8612
+ visible: true,
8613
+ sourceTooltip: {
8614
+ top: draggedPosition.top,
8615
+ left: draggedPosition.left,
8616
+ width: tooltipWidth,
8617
+ height: tooltipHeight
8618
+ },
8619
+ targetTooltip: {
8620
+ top: otherTooltip.top,
8621
+ left: otherTooltip.left,
8622
+ width: otherTooltip.width,
8623
+ height: otherTooltip.height
8624
+ }
8625
+ });
8626
+ }
8627
+ });
8628
+ setAlignmentGuides(newGuides);
8629
+ },
8630
+ [activeTooltips]
8631
+ );
8632
+ const snapToGuides = (0, import_react38.useCallback)(
8633
+ (position) => {
8634
+ const SNAP_DISTANCE = 10;
8635
+ const snappedPosition = { ...position };
8636
+ alignmentGuides.forEach((guide) => {
8637
+ if (guide.type === "horizontal") {
8638
+ const tooltipCenter = position.top + 40;
8639
+ if (Math.abs(tooltipCenter - guide.position) <= SNAP_DISTANCE) {
8640
+ snappedPosition.top = guide.position - 40;
8641
+ }
8642
+ } else if (guide.type === "vertical") {
8643
+ const tooltipCenter = position.left + 100;
8644
+ if (Math.abs(tooltipCenter - guide.position) <= SNAP_DISTANCE) {
8645
+ snappedPosition.left = guide.position - 100;
8646
+ }
8647
+ }
8648
+ });
8649
+ return snappedPosition;
8650
+ },
8651
+ [alignmentGuides]
8652
+ );
8653
+ const handleMouseDown = (tooltipId, e) => {
8654
+ const rect = e.target.getBoundingClientRect();
8655
+ const offsetX = e.clientX - rect.left;
8656
+ const offsetY = e.clientY - rect.top;
8657
+ setIsDragging(tooltipId);
8658
+ setDragOffset({ x: offsetX, y: offsetY });
8659
+ };
8660
+ (0, import_react38.useEffect)(() => {
8661
+ let rafId;
8662
+ let lastMousePosition = { x: 0, y: 0 };
8663
+ const handleGlobalMouseMove = (e) => {
8664
+ if (!isDragging) return;
8665
+ lastMousePosition = { x: e.clientX, y: e.clientY };
8666
+ if (rafId) cancelAnimationFrame(rafId);
8667
+ rafId = requestAnimationFrame(() => {
8668
+ const newLeft = lastMousePosition.x - dragOffset.x;
8669
+ const newTop = lastMousePosition.y - dragOffset.y;
8670
+ let finalPosition = { top: newTop, left: newLeft };
8671
+ finalPosition = snapToGuides(finalPosition);
8672
+ setActiveTooltips(
8673
+ (prev) => prev.map(
8674
+ (tooltip) => tooltip.id === isDragging ? { ...tooltip, position: finalPosition } : tooltip
8675
+ )
8676
+ );
8677
+ updateAlignmentGuides(isDragging, finalPosition);
8678
+ });
8679
+ };
8680
+ const handleGlobalMouseUp = () => {
8681
+ if (rafId) cancelAnimationFrame(rafId);
8682
+ setIsDragging(null);
8683
+ setAlignmentGuides([]);
8684
+ document.body.style.cursor = "";
8685
+ document.body.style.userSelect = "";
8686
+ };
8687
+ if (isDragging) {
8688
+ document.body.style.cursor = "grabbing";
8689
+ document.body.style.userSelect = "none";
8690
+ window.addEventListener("mousemove", handleGlobalMouseMove);
8691
+ window.addEventListener("mouseup", handleGlobalMouseUp);
8692
+ }
8693
+ return () => {
8694
+ if (rafId) cancelAnimationFrame(rafId);
8695
+ window.removeEventListener("mousemove", handleGlobalMouseMove);
8696
+ window.removeEventListener("mouseup", handleGlobalMouseUp);
8697
+ document.body.style.cursor = "";
8698
+ document.body.style.userSelect = "";
8699
+ };
8700
+ }, [
8701
+ isDragging,
8702
+ dragOffset,
8703
+ alignmentGuides,
8704
+ updateAlignmentGuides,
8705
+ snapToGuides
8706
+ ]);
8707
+ (0, import_react38.useEffect)(() => {
8708
+ const handleCloseAllTooltips2 = () => {
8709
+ setActiveTooltips([]);
8710
+ setGlobalTooltipCount(0);
8711
+ };
8712
+ window.addEventListener("closeAllTooltips", handleCloseAllTooltips2);
8713
+ return () => {
8714
+ window.removeEventListener("closeAllTooltips", handleCloseAllTooltips2);
8715
+ };
8716
+ }, []);
8717
+ (0, import_react38.useEffect)(() => {
8718
+ const handleTooltipCountRequest = () => {
8719
+ window.dispatchEvent(
8720
+ new CustomEvent("tooltipCountResponse", {
8721
+ detail: { count: activeTooltips.length }
8722
+ })
8723
+ );
8724
+ };
8725
+ const handleGlobalTooltipsRequest = (event) => {
8726
+ const requesterId = event.detail?.requesterId;
8727
+ activeTooltips.forEach((tooltip) => {
8728
+ if (tooltip.id !== requesterId) {
8729
+ window.dispatchEvent(
8730
+ new CustomEvent("globalTooltipResponse", {
8731
+ detail: {
8732
+ tooltip: {
8733
+ top: tooltip.position.top,
8734
+ left: tooltip.position.left,
8735
+ width: 200,
8736
+ height: 80,
8737
+ id: tooltip.id
8738
+ }
8739
+ }
8740
+ })
8741
+ );
8742
+ }
8743
+ });
8744
+ };
8745
+ window.addEventListener("requestTooltipCount", handleTooltipCountRequest);
8746
+ window.addEventListener(
8747
+ "requestGlobalTooltips",
8748
+ handleGlobalTooltipsRequest
8749
+ );
8750
+ return () => {
8751
+ window.removeEventListener(
8752
+ "requestTooltipCount",
8753
+ handleTooltipCountRequest
8754
+ );
8755
+ window.removeEventListener(
8756
+ "requestGlobalTooltips",
8757
+ handleGlobalTooltipsRequest
8758
+ );
8759
+ };
8760
+ }, [activeTooltips]);
8761
+ (0, import_react38.useEffect)(() => {
8762
+ if (isDragging) return;
8763
+ let totalCount = 0;
8764
+ const handleCountResponse = (event) => {
8765
+ const customEvent = event;
8766
+ totalCount += customEvent.detail.count;
8767
+ };
8768
+ window.addEventListener("tooltipCountResponse", handleCountResponse);
8769
+ window.dispatchEvent(new CustomEvent("requestTooltipCount"));
8770
+ const timeoutId = setTimeout(() => {
8771
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
8772
+ setGlobalTooltipCount(totalCount);
8773
+ }, 5);
8774
+ return () => {
8775
+ clearTimeout(timeoutId);
8776
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
8777
+ };
8778
+ }, [activeTooltips.length, isDragging]);
8779
+ const getTitleClass = () => {
8780
+ switch (titlePosition) {
8781
+ case "center":
8782
+ return "text-center";
8783
+ case "right":
8784
+ return "text-right";
8785
+ default:
8786
+ return "text-left";
8787
+ }
8788
+ };
8789
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn("relative", className), children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8790
+ "div",
8791
+ {
8792
+ className: "rounded-lg bg-card p-4 relative border border-border",
8793
+ style: {
8794
+ width: typeof width === "number" ? `${width + 32}px` : "fit-content",
8795
+ maxWidth: "100%"
8796
+ },
8797
+ onClick: handleChartBackgroundClick,
8798
+ children: [
8799
+ title && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { style: { paddingLeft: `${resolvedContainerPaddingLeft}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn("mb-4", getTitleClass()), children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: title }) }) }),
8800
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
8801
+ import_recharts3.LineChart,
8802
+ {
8803
+ data,
8804
+ width: typeof width === "number" ? width : 900,
8805
+ height,
8806
+ margin: resolveChartMargins(margins, chartMargins, showLabels),
8807
+ onClick: handleChartClick,
8808
+ children: [
8809
+ showGrid && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8810
+ import_recharts3.CartesianGrid,
8811
+ {
8812
+ strokeDasharray: "3 3",
8813
+ stroke: gridColor || "hsl(var(--muted-foreground))",
8814
+ opacity: 0.3
8815
+ }
8816
+ ),
8817
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8818
+ import_recharts3.XAxis,
8819
+ {
8820
+ dataKey: "name",
8821
+ className: "fill-muted-foreground text-xs",
8822
+ fontSize: 12
8823
+ }
8824
+ ),
8825
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8826
+ import_recharts3.YAxis,
8827
+ {
8828
+ className: "fill-muted-foreground text-xs",
8829
+ fontSize: 12,
8830
+ tickFormatter: (value) => compactTick(Number(value)),
8831
+ domain: [0, niceMax],
8832
+ tickCount: 6
8833
+ }
8834
+ ),
8835
+ showTooltip && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_recharts3.Tooltip, { content: () => null }),
8836
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8837
+ import_recharts3.Legend,
8838
+ {
8839
+ wrapperStyle: {
8840
+ fontSize: "12px",
8841
+ color: "hsl(var(--muted-foreground))"
8842
+ }
8843
+ }
8844
+ ),
8845
+ dataKeys.map((key) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8846
+ import_recharts3.Line,
8847
+ {
8848
+ type: "monotone",
8849
+ dataKey: key,
8850
+ stroke: finalColors[key],
8851
+ strokeWidth,
8852
+ dot: showDots ? { r: 4, cursor: "pointer" } : false,
8853
+ activeDot: (props) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(ClickableDot, { ...props, dataKey: key }),
8854
+ children: showLabels && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8855
+ import_recharts3.LabelList,
8856
+ {
8857
+ dataKey: key,
8858
+ position: "top",
8859
+ content: pillLabelRenderer_default(
8860
+ finalColors[key] || "#000",
8861
+ "filled"
8862
+ ),
8863
+ offset: 14
8864
+ }
8865
+ )
8866
+ },
8867
+ key
8868
+ ))
8869
+ ]
8870
+ }
8871
+ ),
8872
+ alignmentGuides.map((guide, index) => {
8873
+ const isHorizontal = guide.type === "horizontal";
8874
+ const color = isHorizontal ? "#3b82f6" : "#ef4444";
8875
+ const startX = isHorizontal ? Math.min(
8876
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8877
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8878
+ ) : guide.sourceTooltip.left + (isHorizontal ? 0 : guide.sourceTooltip.width / 2);
8879
+ const endX = isHorizontal ? Math.max(
8880
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8881
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8882
+ ) : guide.targetTooltip.left + (isHorizontal ? 0 : guide.targetTooltip.width / 2);
8883
+ const startY = isHorizontal ? guide.sourceTooltip.top + (isHorizontal ? guide.sourceTooltip.height / 2 : 0) : Math.min(
8884
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8885
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8886
+ );
8887
+ const endY = isHorizontal ? guide.targetTooltip.top + (isHorizontal ? guide.targetTooltip.height / 2 : 0) : Math.max(
8888
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8889
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8890
+ );
8891
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { children: [
8892
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8893
+ "div",
8894
+ {
8895
+ className: "fixed pointer-events-none z-30",
8896
+ style: {
8897
+ left: startX,
8898
+ top: startY,
8899
+ width: isHorizontal ? endX - startX : "2px",
8900
+ height: isHorizontal ? "2px" : endY - startY,
8901
+ backgroundColor: color,
8902
+ boxShadow: `0 0 8px ${color}60`,
8903
+ opacity: 0.9,
8904
+ borderStyle: "dashed",
8905
+ borderWidth: "1px",
8906
+ borderColor: color,
8907
+ transform: "translateZ(0)"
8908
+ }
8909
+ }
8910
+ ),
8911
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8912
+ "div",
8913
+ {
8914
+ className: "fixed pointer-events-none z-31",
8915
+ style: {
8916
+ left: guide.sourceTooltip.left + guide.sourceTooltip.width / 2 - 4,
8917
+ top: guide.sourceTooltip.top + guide.sourceTooltip.height / 2 - 4,
8918
+ width: "8px",
8919
+ height: "8px",
8920
+ backgroundColor: color,
8921
+ borderRadius: "50%",
8922
+ boxShadow: `0 0 4px ${color}80`,
8923
+ opacity: 0.8
8924
+ }
8925
+ }
8926
+ ),
8927
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8928
+ "div",
8929
+ {
8930
+ className: "fixed pointer-events-none z-31",
8931
+ style: {
8932
+ left: guide.targetTooltip.left + guide.targetTooltip.width / 2 - 4,
8933
+ top: guide.targetTooltip.top + guide.targetTooltip.height / 2 - 4,
8934
+ width: "8px",
8935
+ height: "8px",
8936
+ backgroundColor: color,
8937
+ borderRadius: "50%",
8938
+ boxShadow: `0 0 4px ${color}80`,
8939
+ opacity: 0.8
8940
+ }
8941
+ }
8942
+ )
8943
+ ] }, index);
8944
+ }),
8945
+ activeTooltips.map((tooltip, index) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
8946
+ DraggableTooltip_default,
8947
+ {
8948
+ id: tooltip.id,
8949
+ data: tooltip.data,
8950
+ position: tooltip.position,
8951
+ isDragging: isDragging === tooltip.id,
8952
+ title,
8953
+ dataKeys,
8954
+ finalColors,
8955
+ onMouseDown: (id, e) => handleMouseDown(id, e),
8956
+ onClose: (id) => {
8957
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== id));
8958
+ },
8959
+ periodLabel: "Ponto Selecionado",
8960
+ dataLabel: "Dados do Ponto",
8961
+ showCloseAllButton: index === 0,
8962
+ globalTooltipCount,
8963
+ onCloseAll: handleCloseAllTooltips,
8964
+ closeAllButtonPosition: "top-center",
8965
+ closeAllButtonVariant: "floating"
8966
+ },
8967
+ tooltip.id
8968
+ ))
8969
+ ]
8970
+ }
8971
+ ) });
8972
+ };
8973
+ var LineChart_default = CustomLineChart;
8974
+
8975
+ // src/components/charts/PieChart.tsx
8976
+ var import_recharts4 = require("recharts");
8977
+ var import_jsx_runtime60 = require("react/jsx-runtime");
8978
+ var defaultData2 = [
8979
+ { name: "Vendas", value: 4e3 },
8980
+ { name: "Marketing", value: 3e3 },
8981
+ { name: "Desenvolvimento", value: 2e3 },
8982
+ { name: "Suporte", value: 1e3 },
8983
+ { name: "Outros", value: 800 }
8984
+ ];
8985
+ var DEFAULT_COLORS4 = [
8986
+ "#55af7d",
8987
+ // verde do projeto
8988
+ "#8e68ff",
8989
+ // roxo do projeto
8990
+ "#2273e1",
8991
+ // azul do projeto
8992
+ "#f59e0b",
8993
+ // amarelo complementar
8994
+ "#ef4444",
8995
+ // vermelho complementar
8996
+ "#8b5cf6",
8997
+ // roxo claro
8998
+ "#06b6d4",
8999
+ // ciano
9000
+ "#84cc16"
9001
+ // verde lima
9002
+ ];
9003
+ var RADIAN = Math.PI / 180;
9004
+ var renderCustomizedLabel = ({
9005
+ cx = 0,
9006
+ cy = 0,
9007
+ midAngle = 0,
9008
+ innerRadius = 0,
9009
+ outerRadius = 0,
9010
+ percent = 0
9011
+ }) => {
9012
+ const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
9013
+ const x = cx + radius * Math.cos(-midAngle * RADIAN);
9014
+ const y = cy + radius * Math.sin(-midAngle * RADIAN);
9015
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9016
+ "text",
9017
+ {
9018
+ x,
9019
+ y,
9020
+ fill: "white",
9021
+ textAnchor: x > cx ? "start" : "end",
9022
+ dominantBaseline: "central",
9023
+ fontSize: 12,
9024
+ fontWeight: "600",
9025
+ children: `${(percent * 100).toFixed(0)}%`
9026
+ }
9027
+ );
9028
+ };
9029
+ var CustomPieChart = ({
9030
+ data = defaultData2,
9031
+ className,
9032
+ height = 400,
9033
+ width = "100%",
9034
+ colors: colors2,
9035
+ showTooltip = true,
9036
+ showLegend = true,
9037
+ showLabels = true,
9038
+ innerRadius = 0,
9039
+ outerRadius = 120,
9040
+ centerX = "50%",
9041
+ centerY = "50%"
9042
+ }) => {
9043
+ const finalColors = colors2 || DEFAULT_COLORS4;
9044
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: cn("w-full rounded-lg bg-card p-4", className), children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_recharts4.ResponsiveContainer, { width, height, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_recharts4.PieChart, { children: [
9045
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9046
+ import_recharts4.Pie,
9047
+ {
9048
+ data,
9049
+ cx: centerX,
9050
+ cy: centerY,
9051
+ labelLine: false,
9052
+ label: showLabels ? renderCustomizedLabel : false,
9053
+ outerRadius,
9054
+ innerRadius,
9055
+ fill: "#8884d8",
9056
+ dataKey: "value",
9057
+ children: data.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9058
+ import_recharts4.Cell,
9059
+ {
9060
+ fill: finalColors[index % finalColors.length]
9061
+ },
9062
+ `cell-${entry.name}-${index}`
9063
+ ))
9064
+ }
9065
+ ),
9066
+ showTooltip && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
9067
+ import_recharts4.Tooltip,
9068
+ {
9069
+ contentStyle: {
9070
+ backgroundColor: "hsl(var(--popover))",
9071
+ border: "1px solid hsl(var(--border))",
9072
+ borderRadius: "6px",
9073
+ color: "hsl(var(--popover-foreground))"
9074
+ }
9075
+ }
9076
+ ),
9077
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_recharts4.Legend, {})
9078
+ ] }) }) });
9079
+ };
9080
+ var PieChart_default = CustomPieChart;
9081
+
9082
+ // src/components/charts/hooks/useChartHighlights.tsx
9083
+ var import_react39 = require("react");
9084
+ var useChartHighlights = () => {
9085
+ const [highlightedSeries, setHighlightedSeries] = (0, import_react39.useState)(
9086
+ /* @__PURE__ */ new Set()
9087
+ );
9088
+ const [showOnlyHighlighted, setShowOnlyHighlighted] = (0, import_react39.useState)(false);
9089
+ const toggleHighlight = (0, import_react39.useCallback)((key) => {
9090
+ setHighlightedSeries((prev) => {
9091
+ const next = new Set(prev);
9092
+ if (next.has(key)) {
9093
+ next.delete(key);
9094
+ } else {
9095
+ next.add(key);
9096
+ }
9097
+ return next;
9098
+ });
9099
+ }, []);
9100
+ const clearHighlights = (0, import_react39.useCallback)(() => {
9101
+ setHighlightedSeries(/* @__PURE__ */ new Set());
9102
+ setShowOnlyHighlighted(false);
9103
+ }, []);
9104
+ const isHighlighted = (0, import_react39.useCallback)(
9105
+ (key) => {
9106
+ return highlightedSeries.has(key);
9107
+ },
9108
+ [highlightedSeries]
9109
+ );
9110
+ const getSeriesStyle = (0, import_react39.useCallback)(
9111
+ (key) => {
9112
+ const hasHighlights = highlightedSeries.size > 0;
9113
+ const isSeriesHighlighted = highlightedSeries.has(key);
9114
+ if (showOnlyHighlighted && !isSeriesHighlighted) {
9115
+ return {
9116
+ opacity: 0,
9117
+ pointerEvents: "none",
9118
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
9119
+ };
9120
+ }
9121
+ if (!hasHighlights) {
9122
+ return {
9123
+ opacity: 1,
9124
+ transform: "scale(1)",
9125
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
9126
+ };
9127
+ }
9128
+ if (isSeriesHighlighted) {
9129
+ return {
9130
+ opacity: 1,
9131
+ transform: "scale(1.02)",
9132
+ filter: "drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15))",
9133
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
9134
+ };
9135
+ }
9136
+ return {
9137
+ opacity: 0.25,
9138
+ transform: "scale(0.98)",
9139
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
9140
+ };
9141
+ },
9142
+ [highlightedSeries, showOnlyHighlighted]
9143
+ );
9144
+ return {
9145
+ highlightedSeries,
9146
+ showOnlyHighlighted,
9147
+ toggleHighlight,
9148
+ setShowOnlyHighlighted,
9149
+ clearHighlights,
9150
+ getSeriesStyle,
9151
+ isHighlighted
9152
+ };
9153
+ };
9154
+
6852
9155
  // src/hooks/use-drag.tsx
6853
- var import_react35 = require("react");
9156
+ var import_react40 = require("react");
6854
9157
  var useDrag = (options = {}) => {
6855
- const [isDragging, setIsDragging] = (0, import_react35.useState)(null);
6856
- const [positions, setPositions] = (0, import_react35.useState)({});
6857
- const dragStartPos = (0, import_react35.useRef)(null);
6858
- const dragId = (0, import_react35.useRef)(null);
6859
- const handleMouseDown = (0, import_react35.useCallback)((id, e) => {
9158
+ const [isDragging, setIsDragging] = (0, import_react40.useState)(null);
9159
+ const [positions, setPositions] = (0, import_react40.useState)({});
9160
+ const dragStartPos = (0, import_react40.useRef)(null);
9161
+ const dragId = (0, import_react40.useRef)(null);
9162
+ const handleMouseDown = (0, import_react40.useCallback)((id, e) => {
6860
9163
  e.preventDefault();
6861
9164
  const currentPosition = positions[id] || { top: 0, left: 0 };
6862
9165
  dragStartPos.current = {
@@ -6869,7 +9172,7 @@ var useDrag = (options = {}) => {
6869
9172
  setIsDragging(id);
6870
9173
  options.onDragStart?.(id);
6871
9174
  }, [positions, options]);
6872
- const handleMouseMove = (0, import_react35.useCallback)((e) => {
9175
+ const handleMouseMove = (0, import_react40.useCallback)((e) => {
6873
9176
  if (!isDragging || !dragStartPos.current || !dragId.current) return;
6874
9177
  const deltaX = e.clientX - dragStartPos.current.x;
6875
9178
  const deltaY = e.clientY - dragStartPos.current.y;
@@ -6885,7 +9188,7 @@ var useDrag = (options = {}) => {
6885
9188
  }));
6886
9189
  options.onDrag?.(dragId.current, newPosition);
6887
9190
  }, [isDragging, options]);
6888
- const handleMouseUp = (0, import_react35.useCallback)(() => {
9191
+ const handleMouseUp = (0, import_react40.useCallback)(() => {
6889
9192
  if (dragId.current) {
6890
9193
  options.onDragEnd?.(dragId.current);
6891
9194
  }
@@ -6893,7 +9196,7 @@ var useDrag = (options = {}) => {
6893
9196
  dragStartPos.current = null;
6894
9197
  dragId.current = null;
6895
9198
  }, [options]);
6896
- (0, import_react35.useEffect)(() => {
9199
+ (0, import_react40.useEffect)(() => {
6897
9200
  if (isDragging) {
6898
9201
  document.addEventListener("mousemove", handleMouseMove);
6899
9202
  document.addEventListener("mouseup", handleMouseUp);
@@ -6905,16 +9208,16 @@ var useDrag = (options = {}) => {
6905
9208
  };
6906
9209
  }
6907
9210
  }, [isDragging, handleMouseMove, handleMouseUp]);
6908
- const setPosition = (0, import_react35.useCallback)((id, position) => {
9211
+ const setPosition = (0, import_react40.useCallback)((id, position) => {
6909
9212
  setPositions((prev) => ({
6910
9213
  ...prev,
6911
9214
  [id]: position
6912
9215
  }));
6913
9216
  }, []);
6914
- const getPosition = (0, import_react35.useCallback)((id) => {
9217
+ const getPosition = (0, import_react40.useCallback)((id) => {
6915
9218
  return positions[id] || { top: 0, left: 0 };
6916
9219
  }, [positions]);
6917
- const isElementDragging = (0, import_react35.useCallback)((id) => {
9220
+ const isElementDragging = (0, import_react40.useCallback)((id) => {
6918
9221
  return isDragging === id;
6919
9222
  }, [isDragging]);
6920
9223
  return {