@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.mjs CHANGED
@@ -493,19 +493,19 @@ import { Slot } from "@radix-ui/react-slot";
493
493
  import { cva } from "class-variance-authority";
494
494
  import { jsx } from "react/jsx-runtime";
495
495
  var buttonVariantsBase = cva(
496
- "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",
496
+ "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",
497
497
  {
498
498
  variants: {
499
499
  variant: {
500
500
  default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
501
501
  destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
502
- outline: "bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
502
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-background dark:border-input dark:hover:bg-background/95",
503
503
  secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
504
504
  ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
505
505
  link: "text-primary underline-offset-4 hover:underline"
506
506
  },
507
507
  size: {
508
- default: " px-4 py-2 has-[>svg]:px-3",
508
+ default: "h-9 py-2 px-4 has-[>svg]:px-3",
509
509
  sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
510
510
  lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
511
511
  icon: "size-9"
@@ -2131,7 +2131,7 @@ var InputBase = React12.forwardRef(
2131
2131
  "div",
2132
2132
  {
2133
2133
  className: cn(
2134
- "flex items-center rounded-md transition focus-within:ring-1 focus-within:ring-ring focus-within:border-ring bg-background overflow-hidden",
2134
+ "flex items-center rounded-md transition h-9 focus-within:ring-1 focus-within:ring-ring focus-within:border-ring bg-background overflow-hidden",
2135
2135
  type !== "file" && "border border-input"
2136
2136
  ),
2137
2137
  children: [
@@ -2141,7 +2141,7 @@ var InputBase = React12.forwardRef(
2141
2141
  {
2142
2142
  type,
2143
2143
  className: cn(
2144
- "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",
2144
+ "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",
2145
2145
  className
2146
2146
  ),
2147
2147
  ref,
@@ -2216,7 +2216,7 @@ function ComboboxBase({
2216
2216
  role: "combobox",
2217
2217
  "aria-expanded": open,
2218
2218
  className: cn(
2219
- "flex items-start gap-2 justify-between h-full border border-input",
2219
+ "flex items-start gap-2 justify-between",
2220
2220
  errorMessage && "border-red-500"
2221
2221
  ),
2222
2222
  "data-testid": testIds.trigger ?? "combobox-trigger",
@@ -2887,34 +2887,78 @@ function NavigationMenuIndicatorBase({
2887
2887
  import * as React17 from "react";
2888
2888
  import * as ProgressPrimitive from "@radix-ui/react-progress";
2889
2889
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
2890
- var ProgressBase = React17.forwardRef(({ className, value, label, leftIcon, rightIcon, ...props }, ref) => {
2891
- return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
2892
- label && /* @__PURE__ */ jsx28(LabelBase_default, { className: "py-2", children: label }),
2893
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
2894
- leftIcon && /* @__PURE__ */ jsx28("div", { className: "flex items-center justify-center", children: leftIcon }),
2895
- /* @__PURE__ */ jsx28(
2896
- ProgressPrimitive.Root,
2897
- {
2898
- ref,
2899
- className: cn(
2900
- "relative h-3 w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-800 shadow-inner transition-all",
2901
- className
2902
- ),
2903
- value,
2904
- ...props,
2905
- children: /* @__PURE__ */ jsx28(
2906
- ProgressPrimitive.Indicator,
2907
- {
2908
- className: "h-full w-full flex-1 bg-primary transition-all duration-500 ease-in-out",
2909
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
2910
- }
2911
- )
2912
- }
2913
- ),
2914
- rightIcon && /* @__PURE__ */ jsx28("div", { className: "flex items-center justify-center", children: rightIcon })
2915
- ] })
2916
- ] });
2917
- });
2890
+ var ProgressBase = React17.forwardRef(
2891
+ ({
2892
+ className,
2893
+ value,
2894
+ label,
2895
+ leftIcon,
2896
+ rightIcon,
2897
+ variant = "bar",
2898
+ segments = 5,
2899
+ steps = [],
2900
+ currentStep = 0,
2901
+ ...props
2902
+ }, ref) => {
2903
+ switch (variant) {
2904
+ case "segments":
2905
+ return /* @__PURE__ */ jsx28(
2906
+ ProgressSegmentsBase,
2907
+ {
2908
+ label,
2909
+ segments,
2910
+ value: value || 0
2911
+ }
2912
+ );
2913
+ case "panels":
2914
+ return /* @__PURE__ */ jsx28(
2915
+ ProgressPanelsBase,
2916
+ {
2917
+ label,
2918
+ steps,
2919
+ currentStep
2920
+ }
2921
+ );
2922
+ case "circles":
2923
+ return /* @__PURE__ */ jsx28(
2924
+ ProgressCirclesBase,
2925
+ {
2926
+ label,
2927
+ steps,
2928
+ currentStep
2929
+ }
2930
+ );
2931
+ case "bar":
2932
+ default:
2933
+ return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1 w-full min-w-[150px]", children: [
2934
+ label && /* @__PURE__ */ jsx28(LabelBase_default, { className: "py-2", children: label }),
2935
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
2936
+ leftIcon && /* @__PURE__ */ jsx28("div", { className: "flex items-center justify-center", children: leftIcon }),
2937
+ /* @__PURE__ */ jsx28(
2938
+ ProgressPrimitive.Root,
2939
+ {
2940
+ ref,
2941
+ className: cn(
2942
+ "relative h-3 w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-800 shadow-inner transition-all",
2943
+ className
2944
+ ),
2945
+ value,
2946
+ ...props,
2947
+ children: /* @__PURE__ */ jsx28(
2948
+ ProgressPrimitive.Indicator,
2949
+ {
2950
+ className: "h-full w-full flex-1 bg-primary transition-all duration-500 ease-in-out",
2951
+ style: { transform: `translateX(-${100 - (value || 0)}%)` }
2952
+ }
2953
+ )
2954
+ }
2955
+ ),
2956
+ rightIcon && /* @__PURE__ */ jsx28("div", { className: "flex items-center justify-center", children: rightIcon })
2957
+ ] })
2958
+ ] });
2959
+ }
2960
+ }
2961
+ );
2918
2962
  ProgressBase.displayName = "ProgressBase";
2919
2963
  var ProgressSegmentsBase = ({
2920
2964
  label,
@@ -4223,7 +4267,8 @@ var TabsListBase = React27.forwardRef(({ className, ...props }, ref) => /* @__PU
4223
4267
  {
4224
4268
  ref,
4225
4269
  className: cn(
4226
- "relative flex w-full items-center justify-start gap-4 border-b-2 border-border",
4270
+ "relative flex w-full items-center justify-start gap-2 border-b border-border",
4271
+ "bg-transparent",
4227
4272
  className
4228
4273
  ),
4229
4274
  ...props
@@ -4235,13 +4280,15 @@ var TabsTriggerBase = React27.forwardRef(({ className, ...props }, ref) => /* @_
4235
4280
  {
4236
4281
  ref,
4237
4282
  className: cn(
4238
- "relative inline-flex items-center justify-center whitespace-nowrap px-3 py-2 text-sm font-medium transition-colors",
4239
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-3",
4283
+ "relative inline-flex items-center justify-center whitespace-nowrap px-4 py-2 text-sm font-medium",
4284
+ "text-muted-foreground hover:text-foreground",
4285
+ "transition-colors duration-300 ease-in-out",
4286
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4240
4287
  "disabled:pointer-events-none disabled:opacity-50",
4241
4288
  "data-[state=active]:text-primary",
4242
- "after:absolute after:bottom-0 after:left-0 after:h-[1.5px] after:w-full",
4289
+ "after:absolute after:bottom-0 after:left-0 after:h-[2px] after:w-full",
4243
4290
  "after:scale-x-0 after:bg-primary after:origin-left",
4244
- "after:transition-transform after:duration-300 after:ease-[cubic-bezier(0.65,0,0.35,1)]",
4291
+ "after:transition-transform after:duration-500 after:ease-[cubic-bezier(0.34,1.56,0.64,1)]",
4245
4292
  "data-[state=active]:after:scale-x-100",
4246
4293
  className
4247
4294
  ),
@@ -4253,8 +4300,8 @@ var TabsContentBase = React27.forwardRef(({ className, ...props }, ref) => /* @_
4253
4300
  {
4254
4301
  ref,
4255
4302
  className: cn(
4256
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4257
- "animate-fade-in",
4303
+ "mt-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4304
+ "animate-in fade-in-0 duration-500 ease-in-out",
4258
4305
  className
4259
4306
  ),
4260
4307
  ...props
@@ -4264,27 +4311,184 @@ TabsContentBase.displayName = TabsPrimitive.Content.displayName;
4264
4311
 
4265
4312
  // src/components/ui/TextAreaBase.tsx
4266
4313
  import * as React28 from "react";
4267
- import { jsx as jsx40 } from "react/jsx-runtime";
4268
- var TextAreaBase = React28.forwardRef(({ className, ...props }, ref) => {
4269
- return /* @__PURE__ */ jsx40(
4270
- "textarea",
4271
- {
4272
- className: cn(
4273
- "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",
4274
- className
4314
+ import { motion as motion6 } from "framer-motion";
4315
+ import { TrashIcon as TrashIcon2 } from "@phosphor-icons/react";
4316
+ import { jsx as jsx40, jsxs as jsxs24 } from "react/jsx-runtime";
4317
+ var TextAreaBase = React28.forwardRef(
4318
+ ({ className, clearable = false, onClear, ...props }, ref) => {
4319
+ const [isFocused, setIsFocused] = React28.useState(false);
4320
+ const [hasContent, setHasContent] = React28.useState(
4321
+ !!props.value || !!props.defaultValue
4322
+ );
4323
+ const [showConfirmTooltip, setShowConfirmTooltip] = React28.useState(false);
4324
+ const textareaRef = React28.useRef(null);
4325
+ const handleFocus = (e) => {
4326
+ setIsFocused(true);
4327
+ props.onFocus?.(e);
4328
+ };
4329
+ const handleBlur = (e) => {
4330
+ setIsFocused(false);
4331
+ props.onBlur?.(e);
4332
+ };
4333
+ const handleChange = (e) => {
4334
+ setHasContent(e.target.value.length > 0);
4335
+ props.onChange?.(e);
4336
+ };
4337
+ const handleClearClick = () => {
4338
+ setShowConfirmTooltip(true);
4339
+ };
4340
+ const handleConfirmClear = () => {
4341
+ if (textareaRef.current) {
4342
+ const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
4343
+ window.HTMLTextAreaElement.prototype,
4344
+ "value"
4345
+ )?.set;
4346
+ if (nativeInputValueSetter) {
4347
+ nativeInputValueSetter.call(textareaRef.current, "");
4348
+ const event = new Event("input", { bubbles: true });
4349
+ textareaRef.current.dispatchEvent(event);
4350
+ }
4351
+ setHasContent(false);
4352
+ setShowConfirmTooltip(false);
4353
+ textareaRef.current.focus();
4354
+ onClear?.();
4355
+ }
4356
+ };
4357
+ const handleCancelClear = () => {
4358
+ setShowConfirmTooltip(false);
4359
+ };
4360
+ React28.useImperativeHandle(ref, () => textareaRef.current);
4361
+ React28.useEffect(() => {
4362
+ setHasContent(!!props.value || !!props.defaultValue);
4363
+ }, [props.value, props.defaultValue]);
4364
+ return /* @__PURE__ */ jsxs24("div", { className: "relative", children: [
4365
+ /* @__PURE__ */ jsx40(
4366
+ "textarea",
4367
+ {
4368
+ className: cn(
4369
+ "peer flex min-h-[80px] min-w-[200px] w-full rounded-lg border border-input bg-background/50 backdrop-blur-sm",
4370
+ "px-4 py-3 text-base shadow-sm placeholder:text-muted-foreground/60",
4371
+ "transition-all duration-300 ease-out",
4372
+ "hover:border-input/80 hover:shadow-md",
4373
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 focus-visible:border-ring",
4374
+ "focus-visible:shadow-lg focus-visible:bg-background",
4375
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-muted/30",
4376
+ "resize",
4377
+ "md:text-sm",
4378
+ clearable && hasContent && "pr-10",
4379
+ className
4380
+ ),
4381
+ ref: textareaRef,
4382
+ onFocus: handleFocus,
4383
+ onBlur: handleBlur,
4384
+ onChange: handleChange,
4385
+ ...props
4386
+ }
4275
4387
  ),
4276
- ref,
4277
- ...props
4278
- }
4279
- );
4280
- });
4388
+ clearable && hasContent && /* @__PURE__ */ jsx40(TooltipProviderBase, { children: /* @__PURE__ */ jsxs24(
4389
+ TooltipBase,
4390
+ {
4391
+ open: showConfirmTooltip,
4392
+ onOpenChange: setShowConfirmTooltip,
4393
+ children: [
4394
+ /* @__PURE__ */ jsx40(TooltipTriggerBase, { asChild: true, children: /* @__PURE__ */ jsx40(
4395
+ motion6.button,
4396
+ {
4397
+ type: "button",
4398
+ initial: { opacity: 0, scale: 0.8 },
4399
+ animate: { opacity: 1, scale: 1 },
4400
+ exit: { opacity: 0, scale: 0.8 },
4401
+ transition: { duration: 0.2 },
4402
+ onClick: handleClearClick,
4403
+ className: cn(
4404
+ "absolute top-3 right-3 p-1.5 rounded-md",
4405
+ "text-muted-foreground/50 hover:text-destructive hover:bg-destructive/10",
4406
+ "transition-all duration-200",
4407
+ "focus:outline-none focus:ring-2 focus:ring-destructive/30",
4408
+ "disabled:opacity-50 disabled:cursor-not-allowed"
4409
+ ),
4410
+ disabled: props.disabled,
4411
+ "aria-label": "Limpar texto",
4412
+ children: /* @__PURE__ */ jsx40(TrashIcon2, { size: 16, weight: "regular" })
4413
+ }
4414
+ ) }),
4415
+ /* @__PURE__ */ jsxs24(
4416
+ TooltipContentBase,
4417
+ {
4418
+ side: "left",
4419
+ className: "bg-background border border-border shadow-lg p-3 flex flex-col gap-2",
4420
+ children: [
4421
+ /* @__PURE__ */ jsx40("p", { className: "text-sm text-foreground font-medium mb-1", children: "Limpar todo o texto?" }),
4422
+ /* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
4423
+ /* @__PURE__ */ jsx40(
4424
+ "button",
4425
+ {
4426
+ type: "button",
4427
+ onClick: handleConfirmClear,
4428
+ className: cn(
4429
+ "px-3 py-1.5 text-xs rounded-md font-medium",
4430
+ "bg-destructive text-destructive-foreground",
4431
+ "hover:bg-destructive/90",
4432
+ "transition-colors"
4433
+ ),
4434
+ children: "Confirmar"
4435
+ }
4436
+ ),
4437
+ /* @__PURE__ */ jsx40(
4438
+ "button",
4439
+ {
4440
+ type: "button",
4441
+ onClick: handleCancelClear,
4442
+ className: cn(
4443
+ "px-3 py-1.5 text-xs rounded-md font-medium",
4444
+ "bg-secondary text-secondary-foreground",
4445
+ "hover:bg-secondary/80",
4446
+ "transition-colors"
4447
+ ),
4448
+ children: "Cancelar"
4449
+ }
4450
+ )
4451
+ ] })
4452
+ ]
4453
+ }
4454
+ )
4455
+ ]
4456
+ }
4457
+ ) }),
4458
+ /* @__PURE__ */ jsx40(
4459
+ motion6.div,
4460
+ {
4461
+ className: "pointer-events-none absolute inset-0 rounded-lg",
4462
+ initial: { opacity: 0 },
4463
+ animate: { opacity: isFocused ? 1 : 0 },
4464
+ transition: { duration: 0.3 },
4465
+ children: /* @__PURE__ */ jsx40("div", { className: "absolute inset-0 rounded-lg bg-gradient-to-r from-ring/20 via-ring/10 to-ring/20 blur-sm" })
4466
+ }
4467
+ ),
4468
+ isFocused && hasContent && props.maxLength && /* @__PURE__ */ jsxs24(
4469
+ motion6.div,
4470
+ {
4471
+ initial: { opacity: 0, y: -10 },
4472
+ animate: { opacity: 1, y: 0 },
4473
+ exit: { opacity: 0, y: -10 },
4474
+ className: "absolute bottom-2 right-3 text-xs text-muted-foreground/70 font-medium",
4475
+ children: [
4476
+ props.value?.length || 0,
4477
+ " / ",
4478
+ props.maxLength
4479
+ ]
4480
+ }
4481
+ )
4482
+ ] });
4483
+ }
4484
+ );
4281
4485
  TextAreaBase.displayName = "TextAreaBase";
4282
4486
 
4283
4487
  // src/components/mode-toggle.tsx
4284
4488
  import { CheckIcon as CheckIcon6, MoonIcon, SunIcon } from "@phosphor-icons/react";
4285
4489
 
4286
4490
  // src/components/theme-provider.tsx
4287
- import { createContext as createContext3, useContext as useContext4, useEffect as useEffect6, useState as useState6 } from "react";
4491
+ import { createContext as createContext3, useContext as useContext4, useEffect as useEffect7, useState as useState7 } from "react";
4288
4492
  import { jsx as jsx41 } from "react/jsx-runtime";
4289
4493
  var initialState = {
4290
4494
  theme: "system",
@@ -4297,8 +4501,8 @@ function ThemeProviderBase({
4297
4501
  storageKey = "app-ui-theme",
4298
4502
  ...props
4299
4503
  }) {
4300
- const [theme, setThemeState] = useState6(defaultTheme);
4301
- useEffect6(() => {
4504
+ const [theme, setThemeState] = useState7(defaultTheme);
4505
+ useEffect7(() => {
4302
4506
  const root = window.document.documentElement;
4303
4507
  root.classList.remove(
4304
4508
  "light",
@@ -4324,7 +4528,7 @@ function ThemeProviderBase({
4324
4528
  document.body.style.color = "";
4325
4529
  }
4326
4530
  }, [theme]);
4327
- useEffect6(() => {
4531
+ useEffect7(() => {
4328
4532
  const stored = localStorage.getItem(storageKey);
4329
4533
  if (stored) setThemeState(stored);
4330
4534
  }, [storageKey]);
@@ -4345,7 +4549,7 @@ var useTheme = () => {
4345
4549
  };
4346
4550
 
4347
4551
  // src/components/mode-toggle.tsx
4348
- import { Fragment as Fragment3, jsx as jsx42, jsxs as jsxs24 } from "react/jsx-runtime";
4552
+ import { Fragment as Fragment3, jsx as jsx42, jsxs as jsxs25 } from "react/jsx-runtime";
4349
4553
  var themeLabels = {
4350
4554
  light: "Light",
4351
4555
  dark: "Dark",
@@ -4362,15 +4566,15 @@ function ModeToggleBase({
4362
4566
  }) {
4363
4567
  const { setTheme, theme: currentTheme } = useTheme();
4364
4568
  const isDark = currentTheme?.includes("dark") || currentTheme === "system" && typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
4365
- return /* @__PURE__ */ jsxs24(DropDownMenuBase, { children: [
4366
- /* @__PURE__ */ jsx42(DropDownMenuTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxs24(
4569
+ return /* @__PURE__ */ jsxs25(DropDownMenuBase, { children: [
4570
+ /* @__PURE__ */ jsx42(DropDownMenuTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxs25(
4367
4571
  ButtonBase,
4368
4572
  {
4369
4573
  variant: "ghost",
4370
4574
  size: "icon",
4371
4575
  className: "relative overflow-hidden border-transparent",
4372
4576
  children: [
4373
- /* @__PURE__ */ jsxs24(Fragment3, { children: [
4577
+ /* @__PURE__ */ jsxs25(Fragment3, { children: [
4374
4578
  /* @__PURE__ */ jsx42(SunIcon, { className: `h-[1.2rem] w-[1.2rem] transition-transform duration-300 ${isDark ? "rotate-90 scale-0" : "rotate-0 scale-100"}` }),
4375
4579
  /* @__PURE__ */ jsx42(MoonIcon, { className: `absolute h-[1.2rem] w-[1.2rem] transition-transform duration-300 ${isDark ? "rotate-0 scale-100" : "rotate-90 scale-0"}` })
4376
4580
  ] }),
@@ -4378,7 +4582,7 @@ function ModeToggleBase({
4378
4582
  ]
4379
4583
  }
4380
4584
  ) }),
4381
- /* @__PURE__ */ jsx42(DropDownMenuContentBase, { align: "end", className: "border-border bg-popover text-popover-foreground", children: themes.map((theme) => /* @__PURE__ */ jsxs24(
4585
+ /* @__PURE__ */ jsx42(DropDownMenuContentBase, { align: "end", className: "border-border bg-popover text-popover-foreground", children: themes.map((theme) => /* @__PURE__ */ jsxs25(
4382
4586
  DropDownMenuItemBase,
4383
4587
  {
4384
4588
  onClick: () => setTheme(theme),
@@ -4393,11 +4597,87 @@ function ModeToggleBase({
4393
4597
  ] });
4394
4598
  }
4395
4599
 
4600
+ // src/components/ui/DestructiveDialog.tsx
4601
+ import * as React29 from "react";
4602
+ import { XCircleIcon as XCircleIcon2 } from "@phosphor-icons/react";
4603
+ import { jsx as jsx43, jsxs as jsxs26 } from "react/jsx-runtime";
4604
+ var DestructiveDialog = ({
4605
+ title,
4606
+ description,
4607
+ onConfirm,
4608
+ onCancel,
4609
+ children,
4610
+ triggerContent
4611
+ }) => {
4612
+ const titleId = "destructive-dialog-title";
4613
+ const descriptionId = "destructive-dialog-description";
4614
+ const triggerEl = React29.isValidElement(children) ? /* @__PURE__ */ jsx43(AlertDialogTriggerBase, { asChild: true, children }) : /* @__PURE__ */ jsx43(AlertDialogTriggerBase, { children: /* @__PURE__ */ jsx43(ButtonBase, { variant: "destructive", children: triggerContent ?? "Excluir" }) });
4615
+ return /* @__PURE__ */ jsxs26(AlertDialogBase, { children: [
4616
+ triggerEl,
4617
+ /* @__PURE__ */ jsxs26(
4618
+ AlertDialogContentBase,
4619
+ {
4620
+ role: "alertdialog",
4621
+ "aria-modal": "true",
4622
+ "aria-labelledby": titleId,
4623
+ "aria-describedby": descriptionId,
4624
+ className: cn("border border-destructive bg-background"),
4625
+ children: [
4626
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-start gap-4", children: [
4627
+ /* @__PURE__ */ jsx43("div", { className: "flex items-center justify-center w-10 h-10 rounded-full ring-1 ring-destructive/30", children: /* @__PURE__ */ jsx43(XCircleIcon2, { className: "w-6 h-6 text-destructive" }) }),
4628
+ /* @__PURE__ */ jsxs26("div", { className: "flex-1", children: [
4629
+ /* @__PURE__ */ jsx43(
4630
+ AlertDialogTitleBase,
4631
+ {
4632
+ id: titleId,
4633
+ className: "text-lg sm:text-xl font-semibold text-destructive",
4634
+ children: title
4635
+ }
4636
+ ),
4637
+ /* @__PURE__ */ jsx43(
4638
+ AlertDialogDescriptionBase,
4639
+ {
4640
+ id: descriptionId,
4641
+ className: "mt-2 text-sm text-muted-foreground",
4642
+ children: description
4643
+ }
4644
+ )
4645
+ ] })
4646
+ ] }),
4647
+ /* @__PURE__ */ jsxs26(AlertDialogFooterBase, { className: "mt-2 flex justify-end gap-3", children: [
4648
+ /* @__PURE__ */ jsx43(
4649
+ AlertDialogCancelBase,
4650
+ {
4651
+ onClick: onCancel,
4652
+ className: cn(
4653
+ buttonVariantsBase({ variant: "outline", size: "default" }),
4654
+ "hover:bg-foreground/5 hover:text-primary hover:opacity-90 hover:shadow-none"
4655
+ ),
4656
+ children: "Cancelar"
4657
+ }
4658
+ ),
4659
+ /* @__PURE__ */ jsx43(
4660
+ AlertDialogActionBase,
4661
+ {
4662
+ onClick: onConfirm,
4663
+ className: cn(
4664
+ buttonVariantsBase({ variant: "destructive", size: "default" })
4665
+ ),
4666
+ children: "Confirmar"
4667
+ }
4668
+ )
4669
+ ] })
4670
+ ]
4671
+ }
4672
+ )
4673
+ ] });
4674
+ };
4675
+
4396
4676
  // src/components/date-time-picker/DateTimePicker.tsx
4397
4677
  import { add, format } from "date-fns";
4398
4678
 
4399
4679
  // src/components/date-time-picker/calendar.tsx
4400
- import * as React29 from "react";
4680
+ import * as React30 from "react";
4401
4681
  import { DayPicker as DayPicker2 } from "react-day-picker";
4402
4682
  import {
4403
4683
  CaretLeftIcon as CaretLeftIcon2,
@@ -4406,35 +4686,35 @@ import {
4406
4686
  CalendarIcon
4407
4687
  } from "@phosphor-icons/react";
4408
4688
  import { AnimatePresence as AnimatePresence4 } from "framer-motion";
4409
- import { jsx as jsx43, jsxs as jsxs25 } from "react/jsx-runtime";
4689
+ import { jsx as jsx44, jsxs as jsxs27 } from "react/jsx-runtime";
4410
4690
  function CalendarBase2({
4411
4691
  className,
4412
4692
  classNames,
4413
4693
  showOutsideDays = true,
4414
4694
  ...props
4415
4695
  }) {
4416
- const [month, setMonth] = React29.useState(
4696
+ const [month, setMonth] = React30.useState(
4417
4697
  props.month || props.defaultMonth || /* @__PURE__ */ new Date()
4418
4698
  );
4419
- const [direction, setDirection] = React29.useState(1);
4699
+ const [direction, setDirection] = React30.useState(1);
4420
4700
  const handleMonthChange = (newMonth) => {
4421
4701
  const isNext = newMonth > month ? 1 : -1;
4422
4702
  setDirection(isNext);
4423
4703
  setMonth(newMonth);
4424
4704
  props.onMonthChange?.(newMonth);
4425
4705
  };
4426
- return /* @__PURE__ */ jsx43(
4706
+ return /* @__PURE__ */ jsx44(
4427
4707
  "div",
4428
4708
  {
4429
4709
  className: cn(
4430
- "rounded-2xl border bg-background p-4 shadow-lg overflow-hidden w-full h-full flex flex-col",
4710
+ "rounded-md border bg-background p-4 shadow-lg overflow-hidden w-full h-full flex flex-col",
4431
4711
  className
4432
4712
  ),
4433
- children: /* @__PURE__ */ jsx43("div", { className: "relative flex-1 flex flex-col min-h-0", children: /* @__PURE__ */ jsx43(AnimatePresence4, { initial: false, mode: "wait", custom: direction, children: /* @__PURE__ */ jsx43(
4713
+ children: /* @__PURE__ */ jsx44("div", { className: "relative flex-1 flex flex-col min-h-0", children: /* @__PURE__ */ jsx44(AnimatePresence4, { initial: false, mode: "wait", custom: direction, children: /* @__PURE__ */ jsx44(
4434
4714
  "div",
4435
4715
  {
4436
4716
  className: "w-full h-full flex flex-col",
4437
- children: /* @__PURE__ */ jsx43(
4717
+ children: /* @__PURE__ */ jsx44(
4438
4718
  DayPicker2,
4439
4719
  {
4440
4720
  showOutsideDays,
@@ -4483,8 +4763,8 @@ function CalendarBase2({
4483
4763
  ...classNames
4484
4764
  },
4485
4765
  components: {
4486
- IconLeft: () => /* @__PURE__ */ jsx43(CaretLeftIcon2, { className: "h-4 w-4" }),
4487
- IconRight: () => /* @__PURE__ */ jsx43(CaretRightIcon5, { className: "h-4 w-4" })
4766
+ IconLeft: () => /* @__PURE__ */ jsx44(CaretLeftIcon2, { className: "h-4 w-4" }),
4767
+ IconRight: () => /* @__PURE__ */ jsx44(CaretRightIcon5, { className: "h-4 w-4" })
4488
4768
  },
4489
4769
  ...props
4490
4770
  }
@@ -4499,15 +4779,15 @@ CalendarBase2.displayName = "CalendarBase";
4499
4779
 
4500
4780
  // src/components/date-time-picker/DateTimePicker.tsx
4501
4781
  import { ptBR } from "date-fns/locale";
4502
- import { useEffect as useEffect7, useState as useState8 } from "react";
4782
+ import { useEffect as useEffect8, useState as useState9 } from "react";
4503
4783
 
4504
4784
  // src/components/date-time-picker/TimePicker.tsx
4505
- import { motion as motion6, AnimatePresence as AnimatePresence5 } from "framer-motion";
4506
- import * as React31 from "react";
4785
+ import { motion as motion7, AnimatePresence as AnimatePresence5 } from "framer-motion";
4786
+ import * as React32 from "react";
4507
4787
 
4508
4788
  // src/components/date-time-picker/TimePickerInput.tsx
4509
4789
  import { CaretUpIcon as CaretUpIcon2, CaretDownIcon as CaretDownIcon4 } from "@phosphor-icons/react";
4510
- import React30 from "react";
4790
+ import React31 from "react";
4511
4791
 
4512
4792
  // src/components/date-time-picker/time-picker-utils.ts
4513
4793
  function isValidHour(value) {
@@ -4649,8 +4929,8 @@ function display12HourValue(hours) {
4649
4929
  }
4650
4930
 
4651
4931
  // src/components/date-time-picker/TimePickerInput.tsx
4652
- import { jsx as jsx44, jsxs as jsxs26 } from "react/jsx-runtime";
4653
- var TimePickerInput = React30.forwardRef(
4932
+ import { jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
4933
+ var TimePickerInput = React31.forwardRef(
4654
4934
  ({
4655
4935
  className,
4656
4936
  type = "tel",
@@ -4669,10 +4949,10 @@ var TimePickerInput = React30.forwardRef(
4669
4949
  label,
4670
4950
  ...props
4671
4951
  }, ref) => {
4672
- const [flag, setFlag] = React30.useState(false);
4673
- const [prevIntKey, setPrevIntKey] = React30.useState("0");
4674
- const [isFocused, setIsFocused] = React30.useState(false);
4675
- React30.useEffect(() => {
4952
+ const [flag, setFlag] = React31.useState(false);
4953
+ const [prevIntKey, setPrevIntKey] = React31.useState("0");
4954
+ const [isFocused, setIsFocused] = React31.useState(false);
4955
+ React31.useEffect(() => {
4676
4956
  if (flag) {
4677
4957
  const timer = setTimeout(() => {
4678
4958
  setFlag(false);
@@ -4680,7 +4960,7 @@ var TimePickerInput = React30.forwardRef(
4680
4960
  return () => clearTimeout(timer);
4681
4961
  }
4682
4962
  }, [flag]);
4683
- const calculatedValue = React30.useMemo(() => {
4963
+ const calculatedValue = React31.useMemo(() => {
4684
4964
  return getDateByType(date, picker);
4685
4965
  }, [date, picker]);
4686
4966
  const calculateNewValue = (key) => {
@@ -4736,8 +5016,8 @@ var TimePickerInput = React30.forwardRef(
4736
5016
  const baseLabel = getPickerLabel();
4737
5017
  return `${baseLabel}, valor atual: ${calculatedValue}.`;
4738
5018
  };
4739
- return /* @__PURE__ */ jsxs26("div", { className: "relative group flex flex-col items-center", children: [
4740
- getPickerLabel() && /* @__PURE__ */ jsx44(
5019
+ return /* @__PURE__ */ jsxs28("div", { className: "relative group flex flex-col items-center", children: [
5020
+ getPickerLabel() && /* @__PURE__ */ jsx45(
4741
5021
  "label",
4742
5022
  {
4743
5023
  htmlFor: id || picker,
@@ -4745,7 +5025,7 @@ var TimePickerInput = React30.forwardRef(
4745
5025
  children: getPickerLabel()
4746
5026
  }
4747
5027
  ),
4748
- /* @__PURE__ */ jsxs26(
5028
+ /* @__PURE__ */ jsxs28(
4749
5029
  "div",
4750
5030
  {
4751
5031
  className: cn(
@@ -4753,7 +5033,7 @@ var TimePickerInput = React30.forwardRef(
4753
5033
  "transition-all duration-200"
4754
5034
  ),
4755
5035
  children: [
4756
- showArrows && /* @__PURE__ */ jsx44(
5036
+ showArrows && /* @__PURE__ */ jsx45(
4757
5037
  "button",
4758
5038
  {
4759
5039
  type: "button",
@@ -4769,11 +5049,11 @@ var TimePickerInput = React30.forwardRef(
4769
5049
  ),
4770
5050
  tabIndex: -1,
4771
5051
  "aria-label": `Incrementar ${getPickerLabel().toLowerCase()}`,
4772
- children: /* @__PURE__ */ jsx44(CaretUpIcon2, { size: 14, className: "sm:w-4 sm:h-4" })
5052
+ children: /* @__PURE__ */ jsx45(CaretUpIcon2, { size: 14, className: "sm:w-4 sm:h-4" })
4773
5053
  }
4774
5054
  ),
4775
- /* @__PURE__ */ jsxs26("div", { className: "relative", children: [
4776
- /* @__PURE__ */ jsx44(
5055
+ /* @__PURE__ */ jsxs28("div", { className: "relative", children: [
5056
+ /* @__PURE__ */ jsx45(
4777
5057
  "input",
4778
5058
  {
4779
5059
  ref,
@@ -4818,9 +5098,9 @@ var TimePickerInput = React30.forwardRef(
4818
5098
  ...props
4819
5099
  }
4820
5100
  ),
4821
- isFocused && /* @__PURE__ */ jsx44("div", { className: "absolute inset-0 rounded-lg ring-2 ring-primary/20 pointer-events-none animate-pulse" })
5101
+ isFocused && /* @__PURE__ */ jsx45("div", { className: "absolute inset-0 rounded-lg ring-2 ring-primary/20 pointer-events-none animate-pulse" })
4822
5102
  ] }),
4823
- showArrows && /* @__PURE__ */ jsx44(
5103
+ showArrows && /* @__PURE__ */ jsx45(
4824
5104
  "button",
4825
5105
  {
4826
5106
  type: "button",
@@ -4836,7 +5116,7 @@ var TimePickerInput = React30.forwardRef(
4836
5116
  ),
4837
5117
  tabIndex: -1,
4838
5118
  "aria-label": `Decrementar ${getPickerLabel().toLowerCase()}`,
4839
- children: /* @__PURE__ */ jsx44(CaretDownIcon4, { size: 14, className: "sm:w-4 sm:h-4" })
5119
+ children: /* @__PURE__ */ jsx45(CaretDownIcon4, { size: 14, className: "sm:w-4 sm:h-4" })
4840
5120
  }
4841
5121
  )
4842
5122
  ]
@@ -4848,16 +5128,16 @@ var TimePickerInput = React30.forwardRef(
4848
5128
  TimePickerInput.displayName = "TimePickerInput";
4849
5129
 
4850
5130
  // src/components/date-time-picker/TimePicker.tsx
4851
- import { Fragment as Fragment4, jsx as jsx45, jsxs as jsxs27 } from "react/jsx-runtime";
5131
+ import { Fragment as Fragment4, jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
4852
5132
  function TimePicker({
4853
5133
  date,
4854
5134
  setDate,
4855
5135
  hideSeconds,
4856
5136
  enableButton
4857
5137
  }) {
4858
- const minuteRef = React31.useRef(null);
4859
- const hourRef = React31.useRef(null);
4860
- const secondRef = React31.useRef(null);
5138
+ const minuteRef = React32.useRef(null);
5139
+ const hourRef = React32.useRef(null);
5140
+ const secondRef = React32.useRef(null);
4861
5141
  const containerVariants = {
4862
5142
  hidden: { opacity: 0, y: 10 },
4863
5143
  visible: {
@@ -4873,20 +5153,20 @@ function TimePicker({
4873
5153
  hidden: { opacity: 0, y: 10 },
4874
5154
  visible: { opacity: 1, y: 0 }
4875
5155
  };
4876
- return /* @__PURE__ */ jsxs27(
4877
- motion6.div,
5156
+ return /* @__PURE__ */ jsxs29(
5157
+ motion7.div,
4878
5158
  {
4879
5159
  variants: containerVariants,
4880
5160
  initial: "hidden",
4881
5161
  animate: "visible",
4882
5162
  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",
4883
5163
  children: [
4884
- /* @__PURE__ */ jsx45(
4885
- motion6.div,
5164
+ /* @__PURE__ */ jsx46(
5165
+ motion7.div,
4886
5166
  {
4887
5167
  variants: itemVariants2,
4888
5168
  className: "grid gap-1 sm:gap-2 text-center flex-shrink-0 min-w-0",
4889
- children: /* @__PURE__ */ jsx45(
5169
+ children: /* @__PURE__ */ jsx46(
4890
5170
  TimePickerInput,
4891
5171
  {
4892
5172
  picker: "hours",
@@ -4899,12 +5179,12 @@ function TimePicker({
4899
5179
  )
4900
5180
  }
4901
5181
  ),
4902
- /* @__PURE__ */ jsx45(
4903
- motion6.div,
5182
+ /* @__PURE__ */ jsx46(
5183
+ motion7.div,
4904
5184
  {
4905
5185
  variants: itemVariants2,
4906
5186
  className: "grid gap-1 sm:gap-2 text-center flex-shrink-0 min-w-0",
4907
- children: /* @__PURE__ */ jsx45(
5187
+ children: /* @__PURE__ */ jsx46(
4908
5188
  TimePickerInput,
4909
5189
  {
4910
5190
  picker: "minutes",
@@ -4918,15 +5198,15 @@ function TimePicker({
4918
5198
  )
4919
5199
  }
4920
5200
  ),
4921
- /* @__PURE__ */ jsx45(AnimatePresence5, { children: !hideSeconds && /* @__PURE__ */ jsx45(Fragment4, { children: /* @__PURE__ */ jsx45(
4922
- motion6.div,
5201
+ /* @__PURE__ */ jsx46(AnimatePresence5, { children: !hideSeconds && /* @__PURE__ */ jsx46(Fragment4, { children: /* @__PURE__ */ jsx46(
5202
+ motion7.div,
4923
5203
  {
4924
5204
  variants: itemVariants2,
4925
5205
  initial: "hidden",
4926
5206
  animate: "visible",
4927
5207
  exit: "hidden",
4928
5208
  className: "grid gap-1 sm:gap-2 text-center flex-shrink-0 min-w-0",
4929
- children: /* @__PURE__ */ jsx45(
5209
+ children: /* @__PURE__ */ jsx46(
4930
5210
  TimePickerInput,
4931
5211
  {
4932
5212
  picker: "seconds",
@@ -4946,7 +5226,7 @@ function TimePicker({
4946
5226
 
4947
5227
  // src/components/date-time-picker/DateTimePicker.tsx
4948
5228
  import { CalendarBlankIcon, ClockIcon } from "@phosphor-icons/react";
4949
- import { jsx as jsx46, jsxs as jsxs28 } from "react/jsx-runtime";
5229
+ import { jsx as jsx47, jsxs as jsxs30 } from "react/jsx-runtime";
4950
5230
  function DateTimePicker({
4951
5231
  label,
4952
5232
  date,
@@ -4959,9 +5239,9 @@ function DateTimePicker({
4959
5239
  disabled,
4960
5240
  className
4961
5241
  }) {
4962
- const [internalDate, setInternalDate] = useState8(date);
4963
- const [open, setOpen] = useState8(false);
4964
- const [timePickerOpen, setTimePickerOpen] = useState8(false);
5242
+ const [internalDate, setInternalDate] = useState9(date);
5243
+ const [open, setOpen] = useState9(false);
5244
+ const [timePickerOpen, setTimePickerOpen] = useState9(false);
4965
5245
  const handleSelect = (newDay) => {
4966
5246
  if (!newDay) return;
4967
5247
  if (!internalDate) {
@@ -4990,32 +5270,31 @@ function DateTimePicker({
4990
5270
  if (!timeFormat) return "PPP";
4991
5271
  return `PPP - ${timeFormat}`;
4992
5272
  };
4993
- useEffect7(() => {
5273
+ useEffect8(() => {
4994
5274
  if (date) {
4995
5275
  setInternalDate(date);
4996
5276
  }
4997
5277
  }, [date, open]);
4998
- return /* @__PURE__ */ jsxs28("div", { className: cn("space-y-2 w-full sm:w-auto", className), children: [
4999
- label && /* @__PURE__ */ jsx46(LabelBase_default, { children: label }),
5000
- /* @__PURE__ */ jsxs28(PopoverBase, { open, onOpenChange: setOpen, children: [
5001
- /* @__PURE__ */ jsx46(PopoverTriggerBase, { disabled, asChild: true, children: /* @__PURE__ */ jsxs28(
5278
+ return /* @__PURE__ */ jsxs30("div", { className: cn("space-y-2 w-full sm:w-auto", className), children: [
5279
+ label && /* @__PURE__ */ jsx47(LabelBase_default, { children: label }),
5280
+ /* @__PURE__ */ jsxs30(PopoverBase, { open, onOpenChange: setOpen, children: [
5281
+ /* @__PURE__ */ jsx47(PopoverTriggerBase, { disabled, asChild: true, children: /* @__PURE__ */ jsxs30(
5002
5282
  ButtonBase,
5003
5283
  {
5004
5284
  variant: "outline",
5005
- size: "lg",
5006
5285
  className: cn(
5007
5286
  "w-full justify-start text-left min-w-0 overflow-hidden",
5008
- "min-h-[44px] sm:min-h-[48px] px-3 sm:px-4",
5287
+ "",
5009
5288
  "text-sm sm:text-base",
5010
5289
  !date && "text-muted-foreground"
5011
5290
  ),
5012
5291
  children: [
5013
- /* @__PURE__ */ jsx46("span", { className: "truncate flex-1", children: date ? format(date, getDisplayFormat(), { locale: ptBR }) : "Pick a date" }),
5014
- /* @__PURE__ */ jsx46(CalendarBlankIcon, { className: "flex-shrink-0 w-5 h-5 sm:w-6 sm:h-6" })
5292
+ /* @__PURE__ */ jsx47("span", { className: "truncate flex-1", children: date ? format(date, getDisplayFormat(), { locale: ptBR }) : "Pick a date" }),
5293
+ /* @__PURE__ */ jsx47(CalendarBlankIcon, { className: "flex-shrink-0 w-5 h-5 sm:w-6 sm:h-6" })
5015
5294
  ]
5016
5295
  }
5017
5296
  ) }),
5018
- /* @__PURE__ */ jsx46(
5297
+ /* @__PURE__ */ jsx47(
5019
5298
  PopoverContentBase,
5020
5299
  {
5021
5300
  className: "w-full p-0",
@@ -5024,8 +5303,8 @@ function DateTimePicker({
5024
5303
  side: "bottom",
5025
5304
  avoidCollisions: true,
5026
5305
  collisionPadding: 8,
5027
- children: /* @__PURE__ */ jsxs28("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: [
5028
- /* @__PURE__ */ jsx46(
5306
+ children: /* @__PURE__ */ jsxs30("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: [
5307
+ /* @__PURE__ */ jsx47(
5029
5308
  CalendarBase2,
5030
5309
  {
5031
5310
  mode: "single",
@@ -5038,13 +5317,13 @@ function DateTimePicker({
5038
5317
  className: "w-full"
5039
5318
  }
5040
5319
  ),
5041
- !(hideHour && hideMinute) && /* @__PURE__ */ jsx46("div", { className: "flex justify-center w-full px-2", children: /* @__PURE__ */ jsxs28(
5320
+ !(hideHour && hideMinute) && /* @__PURE__ */ jsx47("div", { className: "flex justify-center w-full px-2", children: /* @__PURE__ */ jsxs30(
5042
5321
  PopoverBase,
5043
5322
  {
5044
5323
  open: timePickerOpen,
5045
5324
  onOpenChange: setTimePickerOpen,
5046
5325
  children: [
5047
- /* @__PURE__ */ jsx46(PopoverTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxs28(
5326
+ /* @__PURE__ */ jsx47(PopoverTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxs30(
5048
5327
  ButtonBase,
5049
5328
  {
5050
5329
  variant: "outline",
@@ -5054,20 +5333,20 @@ function DateTimePicker({
5054
5333
  "px-2 sm:px-3 py-1.5 sm:py-2",
5055
5334
  "text-sm sm:text-base font-semibold w-full max-w-xs",
5056
5335
  "border-2 border-primary/20 rounded-lg",
5057
- "bg-primary/5 hover:bg-primary/10 hover:border-primary/30",
5336
+ "bg-background hover:bg-primary/10 hover:border-primary/30",
5058
5337
  "transition-all duration-200",
5059
5338
  "shadow-sm hover:shadow-md active:scale-[0.98]",
5060
5339
  "min-h-[36px] sm:min-h-[40px]"
5061
5340
  ),
5062
5341
  children: [
5063
- /* @__PURE__ */ jsx46(ClockIcon, { className: "text-primary/70 flex-shrink-0 w-4 h-4 sm:w-5 sm:h-5" }),
5064
- /* @__PURE__ */ jsx46("span", { className: "text-foreground truncate", children: internalDate ? format(internalDate, getTimeFormat() || "HH:mm", {
5342
+ /* @__PURE__ */ jsx47(ClockIcon, { className: "text-primary flex-shrink-0 w-4 h-4 sm:w-5 sm:h-5" }),
5343
+ /* @__PURE__ */ jsx47("span", { className: "text-foreground truncate", children: internalDate ? format(internalDate, getTimeFormat() || "HH:mm", {
5065
5344
  locale: ptBR
5066
5345
  }) : "00:00" })
5067
5346
  ]
5068
5347
  }
5069
5348
  ) }),
5070
- /* @__PURE__ */ jsx46(
5349
+ /* @__PURE__ */ jsx47(
5071
5350
  PopoverContentBase,
5072
5351
  {
5073
5352
  className: "w-[calc(100vw-2rem)] max-w-sm p-3 sm:p-3 rounded-md",
@@ -5076,9 +5355,9 @@ function DateTimePicker({
5076
5355
  sideOffset: 8,
5077
5356
  avoidCollisions: true,
5078
5357
  collisionPadding: 8,
5079
- children: /* @__PURE__ */ jsxs28("div", { className: "flex flex-col items-center space-y-2 sm:space-y-3", children: [
5080
- /* @__PURE__ */ jsx46("h4", { className: "text-sm sm:text-base font-medium text-center", children: "Alterar Hor\xE1rio" }),
5081
- /* @__PURE__ */ jsx46(
5358
+ children: /* @__PURE__ */ jsxs30("div", { className: "flex flex-col items-center space-y-2 sm:space-y-3", children: [
5359
+ /* @__PURE__ */ jsx47("h4", { className: "text-sm sm:text-base font-medium text-center", children: "Alterar Hor\xE1rio" }),
5360
+ /* @__PURE__ */ jsx47(
5082
5361
  TimePicker,
5083
5362
  {
5084
5363
  setDate: handleTimeChange,
@@ -5086,7 +5365,7 @@ function DateTimePicker({
5086
5365
  hideSeconds
5087
5366
  }
5088
5367
  ),
5089
- /* @__PURE__ */ jsx46(
5368
+ /* @__PURE__ */ jsx47(
5090
5369
  ButtonBase,
5091
5370
  {
5092
5371
  size: "sm",
@@ -5110,7 +5389,7 @@ function DateTimePicker({
5110
5389
  }
5111
5390
 
5112
5391
  // src/components/selects/Select.tsx
5113
- import { Fragment as Fragment5, jsx as jsx47, jsxs as jsxs29 } from "react/jsx-runtime";
5392
+ import { Fragment as Fragment5, jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
5114
5393
  function Select({
5115
5394
  items,
5116
5395
  groupItems,
@@ -5119,9 +5398,9 @@ function Select({
5119
5398
  errorMessage,
5120
5399
  testIds = {}
5121
5400
  }) {
5122
- return /* @__PURE__ */ jsxs29("div", { "data-testid": testIds.root ?? "select-root", children: [
5123
- /* @__PURE__ */ jsxs29(SelectBase, { onValueChange: onChange, "data-testid": testIds.base ?? "select-base", children: [
5124
- /* @__PURE__ */ jsx47(
5401
+ return /* @__PURE__ */ jsxs31("div", { "data-testid": testIds.root ?? "select-root", children: [
5402
+ /* @__PURE__ */ jsxs31(SelectBase, { onValueChange: onChange, "data-testid": testIds.base ?? "select-base", children: [
5403
+ /* @__PURE__ */ jsx48(
5125
5404
  SelectTriggerBase,
5126
5405
  {
5127
5406
  className: cn(
@@ -5129,7 +5408,7 @@ function Select({
5129
5408
  errorMessage && "border-red-500"
5130
5409
  ),
5131
5410
  "data-testid": testIds.trigger ?? "select-trigger",
5132
- children: /* @__PURE__ */ jsx47(
5411
+ children: /* @__PURE__ */ jsx48(
5133
5412
  SelectValueBase,
5134
5413
  {
5135
5414
  placeholder,
@@ -5138,9 +5417,9 @@ function Select({
5138
5417
  )
5139
5418
  }
5140
5419
  ),
5141
- /* @__PURE__ */ jsx47(ScrollAreaBase, { "data-testid": testIds.scrollarea ?? "select-scrollarea", children: /* @__PURE__ */ jsx47(SelectContentBase, { "data-testid": testIds.content ?? "select-content", children: groupItems ? /* @__PURE__ */ jsx47(Fragment5, { children: Object.keys(groupItems).map((key) => /* @__PURE__ */ jsxs29(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: [
5142
- /* @__PURE__ */ jsx47(SelectLabelBase, { "data-testid": testIds.label ?? "select-label", children: key }),
5143
- groupItems[key].map((item) => /* @__PURE__ */ jsx47(
5420
+ /* @__PURE__ */ jsx48(ScrollAreaBase, { "data-testid": testIds.scrollarea ?? "select-scrollarea", children: /* @__PURE__ */ jsx48(SelectContentBase, { "data-testid": testIds.content ?? "select-content", children: groupItems ? /* @__PURE__ */ jsx48(Fragment5, { children: Object.keys(groupItems).map((key) => /* @__PURE__ */ jsxs31(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: [
5421
+ /* @__PURE__ */ jsx48(SelectLabelBase, { "data-testid": testIds.label ?? "select-label", children: key }),
5422
+ groupItems[key].map((item) => /* @__PURE__ */ jsx48(
5144
5423
  SelectItemBase,
5145
5424
  {
5146
5425
  value: item.value,
@@ -5149,7 +5428,7 @@ function Select({
5149
5428
  },
5150
5429
  item.value
5151
5430
  ))
5152
- ] }, key)) }) : /* @__PURE__ */ jsx47(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: items.map((item) => /* @__PURE__ */ jsx47(
5431
+ ] }, key)) }) : /* @__PURE__ */ jsx48(SelectGroupBase, { "data-testid": testIds.group ?? "select-group", children: items.map((item) => /* @__PURE__ */ jsx48(
5153
5432
  SelectItemBase,
5154
5433
  {
5155
5434
  value: item.value,
@@ -5159,7 +5438,7 @@ function Select({
5159
5438
  item.value
5160
5439
  )) }) }) })
5161
5440
  ] }),
5162
- errorMessage && /* @__PURE__ */ jsx47(
5441
+ errorMessage && /* @__PURE__ */ jsx48(
5163
5442
  "p",
5164
5443
  {
5165
5444
  className: "text-sm text-red-500",
@@ -5170,94 +5449,186 @@ function Select({
5170
5449
  ] });
5171
5450
  }
5172
5451
 
5173
- // src/components/ui/DestructiveDialog.tsx
5174
- import * as React32 from "react";
5175
- import { XCircleIcon as XCircleIcon2 } from "@phosphor-icons/react";
5176
- import { jsx as jsx48, jsxs as jsxs30 } from "react/jsx-runtime";
5177
- var DestructiveDialog = ({
5178
- title,
5179
- description,
5180
- onConfirm,
5181
- onCancel,
5182
- children,
5183
- triggerContent
5184
- }) => {
5185
- const titleId = "destructive-dialog-title";
5186
- const descriptionId = "destructive-dialog-description";
5187
- const triggerEl = React32.isValidElement(children) ? /* @__PURE__ */ jsx48(AlertDialogTriggerBase, { asChild: true, children }) : /* @__PURE__ */ jsx48(AlertDialogTriggerBase, { children: /* @__PURE__ */ jsx48(ButtonBase, { variant: "destructive", children: triggerContent ?? "Excluir" }) });
5188
- return /* @__PURE__ */ jsxs30(AlertDialogBase, { children: [
5189
- triggerEl,
5190
- /* @__PURE__ */ jsxs30(
5191
- AlertDialogContentBase,
5192
- {
5193
- role: "alertdialog",
5194
- "aria-modal": "true",
5195
- "aria-labelledby": titleId,
5196
- "aria-describedby": descriptionId,
5197
- className: cn("border border-destructive bg-background"),
5198
- children: [
5199
- /* @__PURE__ */ jsxs30("div", { className: "flex items-start gap-4", children: [
5200
- /* @__PURE__ */ jsx48("div", { className: "flex items-center justify-center w-10 h-10 rounded-full ring-1 ring-destructive/30", children: /* @__PURE__ */ jsx48(XCircleIcon2, { className: "w-6 h-6 text-destructive" }) }),
5201
- /* @__PURE__ */ jsxs30("div", { className: "flex-1", children: [
5202
- /* @__PURE__ */ jsx48(
5203
- AlertDialogTitleBase,
5204
- {
5205
- id: titleId,
5206
- className: "text-lg sm:text-xl font-semibold text-destructive",
5207
- children: title
5208
- }
5209
- ),
5210
- /* @__PURE__ */ jsx48(
5211
- AlertDialogDescriptionBase,
5212
- {
5213
- id: descriptionId,
5214
- className: "mt-2 text-sm text-muted-foreground",
5215
- children: description
5216
- }
5217
- )
5218
- ] })
5219
- ] }),
5220
- /* @__PURE__ */ jsxs30(AlertDialogFooterBase, { className: "mt-2 flex justify-end gap-3", children: [
5221
- /* @__PURE__ */ jsx48(
5222
- AlertDialogCancelBase,
5223
- {
5224
- onClick: onCancel,
5225
- className: cn(
5226
- buttonVariantsBase({ variant: "outline", size: "default" }),
5227
- "hover:bg-foreground/5 hover:text-primary hover:opacity-90 hover:shadow-none"
5228
- ),
5229
- children: "Cancelar"
5230
- }
5231
- ),
5232
- /* @__PURE__ */ jsx48(
5233
- AlertDialogActionBase,
5234
- {
5235
- onClick: onConfirm,
5236
- className: cn(
5237
- buttonVariantsBase({ variant: "destructive", size: "default" })
5238
- ),
5239
- children: "Confirmar"
5240
- }
5241
- )
5242
- ] })
5243
- ]
5244
- }
5245
- )
5246
- ] });
5247
- };
5452
+ // src/components/charts/Chart.tsx
5453
+ import {
5454
+ useState as useState12,
5455
+ useEffect as useEffect11,
5456
+ useCallback as useCallback7,
5457
+ useMemo as useMemo6,
5458
+ useRef as useRef5,
5459
+ useLayoutEffect
5460
+ } from "react";
5461
+ import {
5462
+ ComposedChart,
5463
+ Bar,
5464
+ Line,
5465
+ Area,
5466
+ Rectangle,
5467
+ ReferenceLine,
5468
+ XAxis,
5469
+ YAxis,
5470
+ CartesianGrid,
5471
+ Tooltip,
5472
+ Legend,
5473
+ LabelList,
5474
+ ResponsiveContainer
5475
+ } from "recharts";
5248
5476
 
5249
- // src/components/charts/components/controls/PeriodsDropdown.tsx
5250
- import { useState as useState9, useRef as useRef2, useEffect as useEffect8 } from "react";
5251
- import { motion as motion7, AnimatePresence as AnimatePresence6 } from "framer-motion";
5252
- import { DotsThreeIcon as DotsThreeIcon2 } from "@phosphor-icons/react/dist/ssr";
5253
- import { Check } from "@phosphor-icons/react/dist/ssr";
5254
- import { jsx as jsx49, jsxs as jsxs31 } from "react/jsx-runtime";
5255
- var menuVariants = {
5256
- hidden: { opacity: 0, y: -6, scale: 0.98 },
5257
- visible: { opacity: 1, y: 0, scale: 1 },
5258
- exit: { opacity: 0, y: -6, scale: 0.98 }
5477
+ // src/components/charts/utils/helpers.ts
5478
+ var formatFieldName = (fieldName) => {
5479
+ return fieldName.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()).trim();
5259
5480
  };
5260
- var itemVariants = {
5481
+ var detectDataFields = (data, xAxisKey) => {
5482
+ if (!data || data.length === 0) return [];
5483
+ const firstItem = data[0];
5484
+ return Object.keys(firstItem).filter(
5485
+ (key) => key !== xAxisKey && typeof firstItem[key] === "number"
5486
+ );
5487
+ };
5488
+ var detectXAxis = (data) => {
5489
+ if (!data || data.length === 0) return "name";
5490
+ const firstItem = data[0];
5491
+ const stringFields = Object.keys(firstItem).filter(
5492
+ (key) => typeof firstItem[key] === "string" || typeof firstItem[key] === "number" && String(firstItem[key]).length <= 4
5493
+ );
5494
+ return stringFields[0] || Object.keys(firstItem)[0] || "name";
5495
+ };
5496
+ var generateAdditionalColors = (baseColors, count) => {
5497
+ const hexToRgb = (hex) => {
5498
+ const clean = hex.replace("#", "");
5499
+ const bigint = parseInt(
5500
+ clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean,
5501
+ 16
5502
+ );
5503
+ return { r: bigint >> 16 & 255, g: bigint >> 8 & 255, b: bigint & 255 };
5504
+ };
5505
+ const rgbToHsl = ({ r, g, b }) => {
5506
+ r /= 255;
5507
+ g /= 255;
5508
+ b /= 255;
5509
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
5510
+ let h = 0;
5511
+ let s = 0;
5512
+ const l = (max + min) / 2;
5513
+ if (max !== min) {
5514
+ const d = max - min;
5515
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
5516
+ switch (max) {
5517
+ case r:
5518
+ h = (g - b) / d + (g < b ? 6 : 0);
5519
+ break;
5520
+ case g:
5521
+ h = (b - r) / d + 2;
5522
+ break;
5523
+ case b:
5524
+ h = (r - g) / d + 4;
5525
+ break;
5526
+ }
5527
+ h /= 6;
5528
+ }
5529
+ return {
5530
+ h: Math.round(h * 360),
5531
+ s: Math.round(s * 100),
5532
+ l: Math.round(l * 100)
5533
+ };
5534
+ };
5535
+ const hslToHex = (h, s, l) => {
5536
+ s /= 100;
5537
+ l /= 100;
5538
+ const k = (n) => (n + h / 30) % 5;
5539
+ const a = s * Math.min(l, 1 - l);
5540
+ const f = (n) => {
5541
+ const color = l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
5542
+ return Math.round(255 * color).toString(16).padStart(2, "0");
5543
+ };
5544
+ return `#${f(0)}${f(8)}${f(4)}`;
5545
+ };
5546
+ const anchors = baseColors.map((c) => rgbToHsl(hexToRgb(c)));
5547
+ const colors2 = [...baseColors];
5548
+ let i = 0;
5549
+ while (colors2.length < count) {
5550
+ const anchor = anchors[i % anchors.length];
5551
+ const step = Math.floor(i / anchors.length + 1);
5552
+ const hueOffset = step * 25 * (i % 2 === 0 ? 1 : -1);
5553
+ const satOffset = i % 3 === 0 ? -6 : 6;
5554
+ const lightOffset = i % 4 === 0 ? 6 : -4;
5555
+ const newH = (anchor.h + hueOffset + 360) % 360;
5556
+ const newS = Math.max(30, Math.min(95, anchor.s + satOffset));
5557
+ const newL = Math.max(25, Math.min(45, anchor.l + lightOffset));
5558
+ colors2.push(hslToHex(newH, newS, newL));
5559
+ i += 1;
5560
+ }
5561
+ return colors2.slice(0, count);
5562
+ };
5563
+ var niceCeil = (value) => {
5564
+ if (!isFinite(value) || value <= 0) return 1;
5565
+ const pow = Math.pow(10, Math.floor(Math.log10(value)));
5566
+ const normalized = value / pow;
5567
+ const multipliers = [
5568
+ 1,
5569
+ 1.25,
5570
+ 1.5,
5571
+ 2,
5572
+ 2.5,
5573
+ 3,
5574
+ 4,
5575
+ 5,
5576
+ 7.5,
5577
+ 10,
5578
+ 15,
5579
+ 20,
5580
+ 25,
5581
+ 50,
5582
+ 100
5583
+ ];
5584
+ for (const m of multipliers) {
5585
+ if (m >= normalized) return Math.ceil(m * pow);
5586
+ }
5587
+ return Math.ceil(100 * pow);
5588
+ };
5589
+ var compactTick = (value) => {
5590
+ if (value >= 1e9)
5591
+ return (value / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
5592
+ if (value >= 1e6)
5593
+ return (value / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
5594
+ if (value >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
5595
+ return String(value);
5596
+ };
5597
+ var resolveContainerPaddingLeft = (padding, containerPaddingLeft, defaultLeft = 16) => {
5598
+ if (typeof padding === "number") return padding;
5599
+ if (padding && typeof padding === "object" && padding.left != null)
5600
+ return padding.left;
5601
+ if (typeof containerPaddingLeft === "number") return containerPaddingLeft;
5602
+ return defaultLeft;
5603
+ };
5604
+ var resolveChartMargins = (margins, chartMargins, showLabels) => {
5605
+ const defaultRight = 30;
5606
+ const defaultLeft = 20;
5607
+ const topDefault = showLabels ? 48 : 20;
5608
+ const bottomDefault = 5;
5609
+ return {
5610
+ top: margins?.top ?? chartMargins?.top ?? topDefault,
5611
+ right: margins?.right ?? chartMargins?.right ?? defaultRight,
5612
+ left: margins?.left ?? chartMargins?.left ?? defaultLeft,
5613
+ bottom: margins?.bottom ?? chartMargins?.bottom ?? bottomDefault
5614
+ };
5615
+ };
5616
+
5617
+ // src/components/charts/Chart.tsx
5618
+ import { toast as toast2 } from "sonner";
5619
+
5620
+ // src/components/charts/components/controls/PeriodsDropdown.tsx
5621
+ import { useState as useState10, useRef as useRef3, useEffect as useEffect9 } from "react";
5622
+ import { motion as motion8, AnimatePresence as AnimatePresence6 } from "framer-motion";
5623
+ import { DotsThreeIcon as DotsThreeIcon2 } from "@phosphor-icons/react/dist/ssr";
5624
+ import { Check } from "@phosphor-icons/react/dist/ssr";
5625
+ import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
5626
+ var menuVariants = {
5627
+ hidden: { opacity: 0, y: -6, scale: 0.98 },
5628
+ visible: { opacity: 1, y: 0, scale: 1 },
5629
+ exit: { opacity: 0, y: -6, scale: 0.98 }
5630
+ };
5631
+ var itemVariants = {
5261
5632
  hidden: { opacity: 0, x: -6 },
5262
5633
  visible: { opacity: 1, x: 0 }
5263
5634
  };
@@ -5270,11 +5641,11 @@ function PeriodsDropdown({
5270
5641
  activePeriods
5271
5642
  }) {
5272
5643
  const periods = processedData.map((d) => String(d.name));
5273
- const [open, setOpen] = useState9(false);
5274
- const wrapperRef = useRef2(null);
5275
- const firstItemRef = useRef2(null);
5276
- const listRef = useRef2(null);
5277
- useEffect8(() => {
5644
+ const [open, setOpen] = useState10(false);
5645
+ const wrapperRef = useRef3(null);
5646
+ const firstItemRef = useRef3(null);
5647
+ const listRef = useRef3(null);
5648
+ useEffect9(() => {
5278
5649
  const handleClickOutside = (e) => {
5279
5650
  if (!wrapperRef.current) return;
5280
5651
  if (!wrapperRef.current.contains(e.target)) setOpen(false);
@@ -5289,7 +5660,7 @@ function PeriodsDropdown({
5289
5660
  document.removeEventListener("keydown", handleEscape);
5290
5661
  };
5291
5662
  }, []);
5292
- useEffect8(() => {
5663
+ useEffect9(() => {
5293
5664
  if (open && firstItemRef.current) {
5294
5665
  firstItemRef.current.focus();
5295
5666
  }
@@ -5299,8 +5670,8 @@ function PeriodsDropdown({
5299
5670
  setOpen(false);
5300
5671
  }
5301
5672
  const containerStyle = typeof rightOffset === "number" ? { position: "relative", zIndex: 30 } : { position: "relative", zIndex: 30 };
5302
- return /* @__PURE__ */ jsxs31("div", { ref: wrapperRef, style: containerStyle, className: "mr-4", children: [
5303
- /* @__PURE__ */ jsxs31(
5673
+ return /* @__PURE__ */ jsxs32("div", { ref: wrapperRef, style: containerStyle, className: "mr-4", children: [
5674
+ /* @__PURE__ */ jsxs32(
5304
5675
  "button",
5305
5676
  {
5306
5677
  className: "relative p-2.5 rounded-md hover:bg-accent/10 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-accent/50 transition flex items-center justify-center",
@@ -5323,8 +5694,8 @@ function PeriodsDropdown({
5323
5694
  ]
5324
5695
  }
5325
5696
  ),
5326
- /* @__PURE__ */ jsx49(AnimatePresence6, { children: open && /* @__PURE__ */ jsxs31(
5327
- motion7.div,
5697
+ /* @__PURE__ */ jsx49(AnimatePresence6, { children: open && /* @__PURE__ */ jsxs32(
5698
+ motion8.div,
5328
5699
  {
5329
5700
  initial: "hidden",
5330
5701
  animate: "visible",
@@ -5352,8 +5723,8 @@ function PeriodsDropdown({
5352
5723
  ref: listRef,
5353
5724
  className: "flex flex-col p-2 gap-1",
5354
5725
  style: { maxHeight: 200, overflowY: "auto" },
5355
- children: periods.map((p, idx) => /* @__PURE__ */ jsxs31(
5356
- motion7.button,
5726
+ children: periods.map((p, idx) => /* @__PURE__ */ jsxs32(
5727
+ motion8.button,
5357
5728
  {
5358
5729
  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"),
5359
5730
  variants: itemVariants,
@@ -5381,9 +5752,9 @@ function PeriodsDropdown({
5381
5752
  var PeriodsDropdown_default = PeriodsDropdown;
5382
5753
 
5383
5754
  // src/components/charts/components/controls/ShowOnly.tsx
5384
- import { motion as motion8 } from "framer-motion";
5755
+ import { motion as motion9 } from "framer-motion";
5385
5756
  import { Eye, EyeSlash } from "@phosphor-icons/react";
5386
- import { Fragment as Fragment6, jsx as jsx50, jsxs as jsxs32 } from "react/jsx-runtime";
5757
+ import { Fragment as Fragment6, jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
5387
5758
  var ShowOnly = ({
5388
5759
  showOnlyHighlighted,
5389
5760
  setShowOnlyHighlighted,
@@ -5392,7 +5763,7 @@ var ShowOnly = ({
5392
5763
  const hasHighlights = highlightedSeriesSize > 0;
5393
5764
  if (!hasHighlights) return null;
5394
5765
  return /* @__PURE__ */ jsx50("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx50(
5395
- motion8.div,
5766
+ motion9.div,
5396
5767
  {
5397
5768
  whileTap: { scale: hasHighlights ? 0.985 : 1 },
5398
5769
  whileHover: { y: hasHighlights ? -2 : 0 },
@@ -5410,10 +5781,10 @@ var ShowOnly = ({
5410
5781
  "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-primary/60",
5411
5782
  !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"
5412
5783
  ),
5413
- children: showOnlyHighlighted ? /* @__PURE__ */ jsxs32(Fragment6, { children: [
5784
+ children: showOnlyHighlighted ? /* @__PURE__ */ jsxs33(Fragment6, { children: [
5414
5785
  /* @__PURE__ */ jsx50(EyeSlash, { size: 16, weight: "regular" }),
5415
5786
  /* @__PURE__ */ jsx50("span", { className: "sr-only", children: "Exibir todos" })
5416
- ] }) : /* @__PURE__ */ jsxs32(Fragment6, { children: [
5787
+ ] }) : /* @__PURE__ */ jsxs33(Fragment6, { children: [
5417
5788
  /* @__PURE__ */ jsx50(Eye, { size: 16, weight: "bold" }),
5418
5789
  /* @__PURE__ */ jsx50("span", { className: "sr-only", children: "Mostrar somente destacados" })
5419
5790
  ] })
@@ -5425,9 +5796,9 @@ var ShowOnly = ({
5425
5796
  var ShowOnly_default = ShowOnly;
5426
5797
 
5427
5798
  // src/components/charts/components/controls/Highlights.tsx
5428
- import { motion as motion9, AnimatePresence as AnimatePresence7 } from "framer-motion";
5799
+ import { motion as motion10, AnimatePresence as AnimatePresence7 } from "framer-motion";
5429
5800
  import { CheckIcon as CheckIcon7 } from "@phosphor-icons/react/dist/ssr";
5430
- import { jsx as jsx51, jsxs as jsxs33 } from "react/jsx-runtime";
5801
+ import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
5431
5802
  var Highlights = ({
5432
5803
  allKeys,
5433
5804
  mapperConfig,
@@ -5446,7 +5817,7 @@ var Highlights = ({
5446
5817
  visible: { opacity: 1, transition: { staggerChildren: 0.03 } }
5447
5818
  };
5448
5819
  return /* @__PURE__ */ jsx51(
5449
- motion9.div,
5820
+ motion10.div,
5450
5821
  {
5451
5822
  className: "flex-1 flex items-center gap-2 flex-wrap",
5452
5823
  initial: "hidden",
@@ -5462,7 +5833,7 @@ var Highlights = ({
5462
5833
  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"
5463
5834
  );
5464
5835
  return /* @__PURE__ */ jsx51(
5465
- motion9.div,
5836
+ motion10.div,
5466
5837
  {
5467
5838
  layout: true,
5468
5839
  initial: "hidden",
@@ -5478,8 +5849,8 @@ var Highlights = ({
5478
5849
  className: pillClasses,
5479
5850
  style: { minWidth: showFullLabel ? void 0 : 36 },
5480
5851
  "aria-pressed": isHighlighted,
5481
- children: /* @__PURE__ */ jsxs33(
5482
- motion9.button,
5852
+ children: /* @__PURE__ */ jsxs34(
5853
+ motion10.button,
5483
5854
  {
5484
5855
  whileHover: { scale: isHighlighted ? 1.04 : 1.03 },
5485
5856
  whileTap: { scale: 0.96 },
@@ -5487,7 +5858,7 @@ var Highlights = ({
5487
5858
  className: "flex items-center gap-2 min-w-0 pr-2",
5488
5859
  children: [
5489
5860
  /* @__PURE__ */ jsx51(
5490
- motion9.span,
5861
+ motion10.span,
5491
5862
  {
5492
5863
  className: cn("w-3 h-3 rounded-sm flex-shrink-0 border"),
5493
5864
  style: {
@@ -5501,8 +5872,8 @@ var Highlights = ({
5501
5872
  transition: { type: "spring", stiffness: 400, damping: 30 }
5502
5873
  }
5503
5874
  ),
5504
- showFullLabel ? /* @__PURE__ */ jsx51(motion9.span, { className: "truncate max-w-[10rem] pr-2", layout: true, children: label }) : showShortLabel ? /* @__PURE__ */ jsx51(
5505
- motion9.span,
5875
+ showFullLabel ? /* @__PURE__ */ jsx51(motion10.span, { className: "truncate max-w-[10rem] pr-2", layout: true, children: label }) : showShortLabel ? /* @__PURE__ */ jsx51(
5876
+ motion10.span,
5506
5877
  {
5507
5878
  className: "truncate max-w-[6rem] text-xs pr-2",
5508
5879
  layout: true,
@@ -5510,7 +5881,7 @@ var Highlights = ({
5510
5881
  }
5511
5882
  ) : null,
5512
5883
  /* @__PURE__ */ jsx51(
5513
- motion9.span,
5884
+ motion10.span,
5514
5885
  {
5515
5886
  "aria-hidden": true,
5516
5887
  initial: { opacity: 0, scale: 0.6 },
@@ -5540,7 +5911,7 @@ var Highlights_default = Highlights;
5540
5911
 
5541
5912
  // src/components/charts/components/controls/CloseAllButton.tsx
5542
5913
  import { XIcon as XIcon5 } from "@phosphor-icons/react/dist/ssr";
5543
- import { jsx as jsx52, jsxs as jsxs34 } from "react/jsx-runtime";
5914
+ import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
5544
5915
  var CloseAllButton = ({
5545
5916
  count,
5546
5917
  onCloseAll,
@@ -5576,7 +5947,7 @@ var CloseAllButton = ({
5576
5947
  `;
5577
5948
  };
5578
5949
  if (variant === "inline") {
5579
- return /* @__PURE__ */ jsx52("div", { className: "absolute top-4 right-4 z-30", children: /* @__PURE__ */ jsxs34(
5950
+ return /* @__PURE__ */ jsx52("div", { className: "absolute top-4 right-4 z-30", children: /* @__PURE__ */ jsxs35(
5580
5951
  ButtonBase,
5581
5952
  {
5582
5953
  variant: "ghost",
@@ -5594,7 +5965,7 @@ var CloseAllButton = ({
5594
5965
  "div",
5595
5966
  {
5596
5967
  className: `${getPositionClasses()} animate-in fade-in slide-in-from-top-2 duration-300`,
5597
- children: /* @__PURE__ */ jsx52("div", { children: /* @__PURE__ */ jsxs34(
5968
+ children: /* @__PURE__ */ jsx52("div", { children: /* @__PURE__ */ jsxs35(
5598
5969
  ButtonBase,
5599
5970
  {
5600
5971
  onClick: onCloseAll,
@@ -5620,16 +5991,16 @@ var CloseAllButton_default = CloseAllButton;
5620
5991
 
5621
5992
  // src/components/charts/components/tooltips/DraggableTooltip.tsx
5622
5993
  import React34, {
5623
- useEffect as useEffect9,
5624
- useRef as useRef3,
5625
- useState as useState10,
5994
+ useEffect as useEffect10,
5995
+ useRef as useRef4,
5996
+ useState as useState11,
5626
5997
  useCallback as useCallback6,
5627
5998
  useMemo as useMemo5
5628
5999
  } from "react";
5629
- import { motion as motion10, AnimatePresence as AnimatePresence8 } from "framer-motion";
6000
+ import { motion as motion11, AnimatePresence as AnimatePresence8 } from "framer-motion";
5630
6001
  import { DotsSixVerticalIcon } from "@phosphor-icons/react";
5631
6002
  import { XIcon as XIcon6 } from "@phosphor-icons/react/dist/ssr";
5632
- import { Fragment as Fragment7, jsx as jsx53, jsxs as jsxs35 } from "react/jsx-runtime";
6003
+ import { Fragment as Fragment7, jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
5633
6004
  var ALIGNMENT_THRESHOLD = 25;
5634
6005
  var GUIDE_THRESHOLD = 60;
5635
6006
  var STRONG_SNAP_THRESHOLD = 35;
@@ -5714,7 +6085,7 @@ var DraggableTooltipComponent = ({
5714
6085
  const numeric = visibleKeys2.map((k) => data2[k]).filter((v) => typeof v === "number");
5715
6086
  return numeric.reduce((s, v) => s + (v || 0), 0);
5716
6087
  }, [data2, visibleKeys2]);
5717
- return /* @__PURE__ */ jsxs35("div", { className: "text-sm", children: [
6088
+ return /* @__PURE__ */ jsxs36("div", { className: "text-sm", children: [
5718
6089
  /* @__PURE__ */ jsx53("div", { className: "text-sm text-muted-foreground", children: "Total" }),
5719
6090
  /* @__PURE__ */ jsx53(
5720
6091
  "div",
@@ -5726,13 +6097,13 @@ var DraggableTooltipComponent = ({
5726
6097
  ] });
5727
6098
  }
5728
6099
  );
5729
- const [localPos, setLocalPos] = useState10(position);
5730
- const [dragging, setDragging] = useState10(false);
5731
- const offsetRef = useRef3({ x: 0, y: 0 });
5732
- const lastMouse = useRef3({ x: 0, y: 0 });
5733
- const [alignmentGuides, setAlignmentGuides] = useState10([]);
5734
- const [globalTooltipCountLocal, setGlobalTooltipCountLocal] = useState10(0);
5735
- useEffect9(() => setLocalPos(position), [position]);
6100
+ const [localPos, setLocalPos] = useState11(position);
6101
+ const [dragging, setDragging] = useState11(false);
6102
+ const offsetRef = useRef4({ x: 0, y: 0 });
6103
+ const lastMouse = useRef4({ x: 0, y: 0 });
6104
+ const [alignmentGuides, setAlignmentGuides] = useState11([]);
6105
+ const [globalTooltipCountLocal, setGlobalTooltipCountLocal] = useState11(0);
6106
+ useEffect10(() => setLocalPos(position), [position]);
5736
6107
  const getAllTooltips = useCallback6(() => {
5737
6108
  const response = [];
5738
6109
  const ev = new CustomEvent("requestGlobalTooltips", {
@@ -5837,7 +6208,7 @@ var DraggableTooltipComponent = ({
5837
6208
  },
5838
6209
  [alignmentGuides]
5839
6210
  );
5840
- useEffect9(() => {
6211
+ useEffect10(() => {
5841
6212
  let rafId = null;
5842
6213
  const handleMouseMove = (e) => {
5843
6214
  if (!dragging) return;
@@ -5879,7 +6250,7 @@ var DraggableTooltipComponent = ({
5879
6250
  document.body.style.userSelect = "";
5880
6251
  };
5881
6252
  }, [dragging, snapToGuides, updateAlignmentGuides, id, onPositionChange]);
5882
- useEffect9(() => {
6253
+ useEffect10(() => {
5883
6254
  const handleCloseAll = () => onClose(id);
5884
6255
  const handleRequestTooltipCount = () => {
5885
6256
  window.dispatchEvent(
@@ -5910,7 +6281,7 @@ var DraggableTooltipComponent = ({
5910
6281
  });
5911
6282
  };
5912
6283
  }, [id, localPos, onClose]);
5913
- useEffect9(() => {
6284
+ useEffect10(() => {
5914
6285
  if (dragging) return;
5915
6286
  let total = 0;
5916
6287
  const timeoutId = setTimeout(() => {
@@ -5928,7 +6299,7 @@ var DraggableTooltipComponent = ({
5928
6299
  }, 0);
5929
6300
  return () => clearTimeout(timeoutId);
5930
6301
  }, [localPos, dragging]);
5931
- useEffect9(() => {
6302
+ useEffect10(() => {
5932
6303
  const recount = () => {
5933
6304
  if (dragging) return;
5934
6305
  let total = 0;
@@ -5979,7 +6350,7 @@ var DraggableTooltipComponent = ({
5979
6350
  },
5980
6351
  [id, onClose]
5981
6352
  );
5982
- return /* @__PURE__ */ jsxs35(Fragment7, { children: [
6353
+ return /* @__PURE__ */ jsxs36(Fragment7, { children: [
5983
6354
  dragging && alignmentGuides.map((guide, index) => {
5984
6355
  const isHorizontal = guide.type === "horizontal";
5985
6356
  const color = isHorizontal ? "#3b82f6" : "#ef4444";
@@ -5999,9 +6370,9 @@ var DraggableTooltipComponent = ({
5999
6370
  guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
6000
6371
  guide.targetTooltip.top + guide.targetTooltip.height / 2
6001
6372
  );
6002
- return /* @__PURE__ */ jsxs35("div", { children: [
6373
+ return /* @__PURE__ */ jsxs36("div", { children: [
6003
6374
  /* @__PURE__ */ jsx53(
6004
- motion10.div,
6375
+ motion11.div,
6005
6376
  {
6006
6377
  className: "fixed pointer-events-none z-30",
6007
6378
  variants: guideVariants,
@@ -6023,7 +6394,7 @@ var DraggableTooltipComponent = ({
6023
6394
  }
6024
6395
  ),
6025
6396
  /* @__PURE__ */ jsx53(
6026
- motion10.div,
6397
+ motion11.div,
6027
6398
  {
6028
6399
  className: "fixed pointer-events-none z-31",
6029
6400
  variants: guideDotVariants,
@@ -6042,7 +6413,7 @@ var DraggableTooltipComponent = ({
6042
6413
  }
6043
6414
  ),
6044
6415
  /* @__PURE__ */ jsx53(
6045
- motion10.div,
6416
+ motion11.div,
6046
6417
  {
6047
6418
  className: "fixed pointer-events-none z-31",
6048
6419
  variants: guideDotVariants,
@@ -6062,8 +6433,8 @@ var DraggableTooltipComponent = ({
6062
6433
  )
6063
6434
  ] }, index);
6064
6435
  }),
6065
- /* @__PURE__ */ jsx53(AnimatePresence8, { children: /* @__PURE__ */ jsxs35(
6066
- motion10.div,
6436
+ /* @__PURE__ */ jsx53(AnimatePresence8, { children: /* @__PURE__ */ jsxs36(
6437
+ motion11.div,
6067
6438
  {
6068
6439
  className: "fixed bg-card border border-border rounded-lg shadow-lg z-50 min-w-80 select-none",
6069
6440
  variants: tooltipVariants,
@@ -6080,7 +6451,7 @@ var DraggableTooltipComponent = ({
6080
6451
  role: "dialog",
6081
6452
  "aria-label": title ? `Tooltip ${title}` : `Tooltip ${data.name}`,
6082
6453
  children: [
6083
- /* @__PURE__ */ jsxs35(
6454
+ /* @__PURE__ */ jsxs36(
6084
6455
  "div",
6085
6456
  {
6086
6457
  className: "flex items-center justify-between p-3 pb-2 border-b bg-muted/20 rounded-t-lg",
@@ -6102,14 +6473,14 @@ var DraggableTooltipComponent = ({
6102
6473
  ]
6103
6474
  }
6104
6475
  ),
6105
- /* @__PURE__ */ jsx53("div", { className: "px-3 py-2 bg-accent/5 border-l-4 border-primary", children: /* @__PURE__ */ jsxs35("div", { className: "flex items-center justify-between gap-2", children: [
6106
- /* @__PURE__ */ jsxs35("div", { children: [
6476
+ /* @__PURE__ */ jsx53("div", { className: "px-3 py-2 bg-accent/5 border-l-4 border-primary", children: /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between gap-2", children: [
6477
+ /* @__PURE__ */ jsxs36("div", { children: [
6107
6478
  /* @__PURE__ */ jsx53("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: periodLabel }),
6108
6479
  /* @__PURE__ */ jsx53("p", { className: "font-bold text-lg text-foreground mt-1 truncate", children: data.name })
6109
6480
  ] }),
6110
6481
  /* @__PURE__ */ jsx53("div", { className: "text-right", children: /* @__PURE__ */ jsx53(TotalDisplay, { data, visibleKeys }) })
6111
6482
  ] }) }),
6112
- /* @__PURE__ */ jsxs35("div", { className: "p-3 pt-2 space-y-2", children: [
6483
+ /* @__PURE__ */ jsxs36("div", { className: "p-3 pt-2 space-y-2", children: [
6113
6484
  /* @__PURE__ */ jsx53("p", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2", children: dataLabel }),
6114
6485
  useMemo5(
6115
6486
  () => visibleKeys.map((key) => {
@@ -6126,7 +6497,7 @@ var DraggableTooltipComponent = ({
6126
6497
  const pct = absDenominator > 0 ? Math.abs(val) / absDenominator * 100 : 0;
6127
6498
  const isDimmed = highlightedSeries && highlightedSeries.size > 0 && !highlightedSeries.has(key);
6128
6499
  const isHighlighted = highlightedSeries && highlightedSeries.has(key);
6129
- return /* @__PURE__ */ jsxs35(
6500
+ return /* @__PURE__ */ jsxs36(
6130
6501
  "div",
6131
6502
  {
6132
6503
  role: "button",
@@ -6144,8 +6515,8 @@ var DraggableTooltipComponent = ({
6144
6515
  border: isHighlighted ? `1px solid ${finalColors[key] || "#666"}22` : void 0
6145
6516
  },
6146
6517
  children: [
6147
- /* @__PURE__ */ jsxs35("div", { className: "flex items-center justify-between", children: [
6148
- /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2", children: [
6518
+ /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between", children: [
6519
+ /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2", children: [
6149
6520
  /* @__PURE__ */ jsx53(
6150
6521
  "div",
6151
6522
  {
@@ -6163,7 +6534,7 @@ var DraggableTooltipComponent = ({
6163
6534
  }
6164
6535
  )
6165
6536
  ] }),
6166
- /* @__PURE__ */ jsxs35("div", { className: "flex items-baseline gap-2", children: [
6537
+ /* @__PURE__ */ jsxs36("div", { className: "flex items-baseline gap-2", children: [
6167
6538
  /* @__PURE__ */ jsx53(
6168
6539
  "span",
6169
6540
  {
@@ -6200,7 +6571,7 @@ var DraggableTooltipComponent = ({
6200
6571
  finalColors
6201
6572
  ]
6202
6573
  ),
6203
- /* @__PURE__ */ jsx53("div", { className: "mt-3 pt-2 border-t", children: /* @__PURE__ */ jsxs35("p", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
6574
+ /* @__PURE__ */ jsx53("div", { className: "mt-3 pt-2 border-t", children: /* @__PURE__ */ jsxs36("p", { className: "text-xs text-muted-foreground flex items-center gap-1", children: [
6204
6575
  "Clique no ",
6205
6576
  /* @__PURE__ */ jsx53(XIcon6, { size: 12 }),
6206
6577
  " para remover"
@@ -6226,7 +6597,7 @@ DraggableTooltip.displayName = "DraggableTooltip";
6226
6597
  var DraggableTooltip_default = DraggableTooltip;
6227
6598
 
6228
6599
  // src/components/charts/components/tooltips/TooltipWithTotal.tsx
6229
- import { jsx as jsx54, jsxs as jsxs36 } from "react/jsx-runtime";
6600
+ import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
6230
6601
  var RechartTooltipWithTotal = ({
6231
6602
  active,
6232
6603
  payload,
@@ -6245,7 +6616,7 @@ var RechartTooltipWithTotal = ({
6245
6616
  (sum, p) => sum + Math.abs(typeof p.value === "number" ? p.value : 0),
6246
6617
  0
6247
6618
  );
6248
- return /* @__PURE__ */ jsxs36(
6619
+ return /* @__PURE__ */ jsxs37(
6249
6620
  "div",
6250
6621
  {
6251
6622
  role: "dialog",
@@ -6253,12 +6624,12 @@ var RechartTooltipWithTotal = ({
6253
6624
  className: "bg-card border border-border rounded-lg p-3 shadow-2xl max-w-xs",
6254
6625
  style: { minWidth: 220 },
6255
6626
  children: [
6256
- /* @__PURE__ */ jsxs36("div", { className: "flex items-start justify-between mb-2", children: [
6257
- /* @__PURE__ */ jsxs36("div", { className: "pr-2", children: [
6627
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-start justify-between mb-2", children: [
6628
+ /* @__PURE__ */ jsxs37("div", { className: "pr-2", children: [
6258
6629
  /* @__PURE__ */ jsx54("p", { className: "text-xs text-muted-foreground", children: periodLabel }),
6259
6630
  /* @__PURE__ */ jsx54("p", { className: "font-medium text-foreground truncate", children: label })
6260
6631
  ] }),
6261
- /* @__PURE__ */ jsxs36("div", { className: "text-right ml-3", children: [
6632
+ /* @__PURE__ */ jsxs37("div", { className: "text-right ml-3", children: [
6262
6633
  /* @__PURE__ */ jsx54("p", { className: "text-xs text-muted-foreground", children: totalLabel }),
6263
6634
  /* @__PURE__ */ jsx54(
6264
6635
  "p",
@@ -6274,9 +6645,9 @@ var RechartTooltipWithTotal = ({
6274
6645
  const pct = absDenominator > 0 ? Math.abs(value) / absDenominator * 100 : 0;
6275
6646
  const baseColor = finalColors[entry.dataKey] || entry.color || "#999";
6276
6647
  const isNeg = value < 0;
6277
- return /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-1", children: [
6278
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between text-sm", children: [
6279
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 truncate", children: [
6648
+ return /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-1", children: [
6649
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between text-sm", children: [
6650
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2 truncate", children: [
6280
6651
  /* @__PURE__ */ jsx54(
6281
6652
  "span",
6282
6653
  {
@@ -6287,7 +6658,7 @@ var RechartTooltipWithTotal = ({
6287
6658
  ),
6288
6659
  /* @__PURE__ */ jsx54("span", { className: "text-muted-foreground truncate", children: entry.name })
6289
6660
  ] }),
6290
- /* @__PURE__ */ jsxs36("div", { className: "flex items-baseline gap-3 ml-3", children: [
6661
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-baseline gap-3 ml-3", children: [
6291
6662
  /* @__PURE__ */ jsx54(
6292
6663
  "span",
6293
6664
  {
@@ -6317,7 +6688,7 @@ var RechartTooltipWithTotal = ({
6317
6688
  var TooltipWithTotal_default = RechartTooltipWithTotal;
6318
6689
 
6319
6690
  // src/components/charts/components/tooltips/TooltipSimple.tsx
6320
- import { jsx as jsx55, jsxs as jsxs37 } from "react/jsx-runtime";
6691
+ import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
6321
6692
  var TooltipSimple = ({
6322
6693
  active,
6323
6694
  payload,
@@ -6326,7 +6697,7 @@ var TooltipSimple = ({
6326
6697
  periodLabel = "Per\xEDodo"
6327
6698
  }) => {
6328
6699
  if (!active || !payload || payload.length === 0) return null;
6329
- return /* @__PURE__ */ jsxs37(
6700
+ return /* @__PURE__ */ jsxs38(
6330
6701
  "div",
6331
6702
  {
6332
6703
  role: "dialog",
@@ -6334,19 +6705,19 @@ var TooltipSimple = ({
6334
6705
  className: "bg-card border border-border rounded-lg p-3 shadow-2xl max-w-[280px]",
6335
6706
  style: { minWidth: 220 },
6336
6707
  children: [
6337
- /* @__PURE__ */ jsx55("div", { className: "mb-2", children: /* @__PURE__ */ jsx55("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ jsxs37("div", { className: "min-w-0", children: [
6708
+ /* @__PURE__ */ jsx55("div", { className: "mb-2", children: /* @__PURE__ */ jsx55("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ jsxs38("div", { className: "min-w-0", children: [
6338
6709
  /* @__PURE__ */ jsx55("p", { className: "text-xs text-muted-foreground", children: periodLabel }),
6339
6710
  /* @__PURE__ */ jsx55("p", { className: "font-medium text-foreground truncate", children: label })
6340
6711
  ] }) }) }),
6341
6712
  /* @__PURE__ */ jsx55("div", { className: "divide-y divide-border rounded-md overflow-hidden", children: payload.map((entry, index) => {
6342
6713
  const value = typeof entry.value === "number" ? entry.value : 0;
6343
6714
  const color = finalColors[entry.dataKey] || entry.color || "#999";
6344
- return /* @__PURE__ */ jsxs37(
6715
+ return /* @__PURE__ */ jsxs38(
6345
6716
  "div",
6346
6717
  {
6347
6718
  className: "flex items-center justify-between text-sm px-2 py-2 bg-card/0 hover:bg-muted transition-colors",
6348
6719
  children: [
6349
- /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-3 min-w-0", children: [
6720
+ /* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-3 min-w-0", children: [
6350
6721
  /* @__PURE__ */ jsx55(
6351
6722
  "span",
6352
6723
  {
@@ -6375,178 +6746,38 @@ var TooltipSimple = ({
6375
6746
  };
6376
6747
  var TooltipSimple_default = TooltipSimple;
6377
6748
 
6378
- // src/components/charts/utils/helpers.ts
6379
- var formatFieldName = (fieldName) => {
6380
- return fieldName.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()).trim();
6381
- };
6382
- var detectDataFields = (data, xAxisKey) => {
6383
- if (!data || data.length === 0) return [];
6384
- const firstItem = data[0];
6385
- return Object.keys(firstItem).filter(
6386
- (key) => key !== xAxisKey && typeof firstItem[key] === "number"
6387
- );
6749
+ // src/components/charts/utils/pillLabelRenderer.tsx
6750
+ import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
6751
+ var formatCompactNumber = (value) => {
6752
+ const isNegative = value < 0;
6753
+ const absValue = Math.abs(value);
6754
+ let formatted;
6755
+ if (absValue >= 1e9) {
6756
+ formatted = (absValue / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
6757
+ } else if (absValue >= 1e6) {
6758
+ formatted = (absValue / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
6759
+ } else if (absValue >= 1e3) {
6760
+ formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
6761
+ } else {
6762
+ formatted = absValue.toString();
6763
+ }
6764
+ return isNegative ? `-${formatted}` : formatted;
6388
6765
  };
6389
- var detectXAxis = (data) => {
6390
- if (!data || data.length === 0) return "name";
6391
- const firstItem = data[0];
6392
- const stringFields = Object.keys(firstItem).filter(
6393
- (key) => typeof firstItem[key] === "string" || typeof firstItem[key] === "number" && String(firstItem[key]).length <= 4
6394
- );
6395
- return stringFields[0] || Object.keys(firstItem)[0] || "name";
6766
+ var parseNumber = (v) => {
6767
+ if (typeof v === "number") return v;
6768
+ if (typeof v === "string" && v.trim() !== "" && !Number.isNaN(Number(v)))
6769
+ return Number(v);
6770
+ return void 0;
6396
6771
  };
6397
- var generateAdditionalColors = (baseColors, count) => {
6398
- const hexToRgb = (hex) => {
6399
- const clean = hex.replace("#", "");
6400
- const bigint = parseInt(
6401
- clean.length === 3 ? clean.split("").map((c) => c + c).join("") : clean,
6402
- 16
6403
- );
6404
- return { r: bigint >> 16 & 255, g: bigint >> 8 & 255, b: bigint & 255 };
6405
- };
6406
- const rgbToHsl = ({ r, g, b }) => {
6407
- r /= 255;
6408
- g /= 255;
6409
- b /= 255;
6410
- const max = Math.max(r, g, b), min = Math.min(r, g, b);
6411
- let h = 0;
6412
- let s = 0;
6413
- const l = (max + min) / 2;
6414
- if (max !== min) {
6415
- const d = max - min;
6416
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
6417
- switch (max) {
6418
- case r:
6419
- h = (g - b) / d + (g < b ? 6 : 0);
6420
- break;
6421
- case g:
6422
- h = (b - r) / d + 2;
6423
- break;
6424
- case b:
6425
- h = (r - g) / d + 4;
6426
- break;
6427
- }
6428
- h /= 6;
6429
- }
6430
- return {
6431
- h: Math.round(h * 360),
6432
- s: Math.round(s * 100),
6433
- l: Math.round(l * 100)
6434
- };
6435
- };
6436
- const hslToHex = (h, s, l) => {
6437
- s /= 100;
6438
- l /= 100;
6439
- const k = (n) => (n + h / 30) % 5;
6440
- const a = s * Math.min(l, 1 - l);
6441
- const f = (n) => {
6442
- const color = l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
6443
- return Math.round(255 * color).toString(16).padStart(2, "0");
6444
- };
6445
- return `#${f(0)}${f(8)}${f(4)}`;
6446
- };
6447
- const anchors = baseColors.map((c) => rgbToHsl(hexToRgb(c)));
6448
- const colors2 = [...baseColors];
6449
- let i = 0;
6450
- while (colors2.length < count) {
6451
- const anchor = anchors[i % anchors.length];
6452
- const step = Math.floor(i / anchors.length + 1);
6453
- const hueOffset = step * 25 * (i % 2 === 0 ? 1 : -1);
6454
- const satOffset = i % 3 === 0 ? -6 : 6;
6455
- const lightOffset = i % 4 === 0 ? 6 : -4;
6456
- const newH = (anchor.h + hueOffset + 360) % 360;
6457
- const newS = Math.max(30, Math.min(95, anchor.s + satOffset));
6458
- const newL = Math.max(25, Math.min(45, anchor.l + lightOffset));
6459
- colors2.push(hslToHex(newH, newS, newL));
6460
- i += 1;
6461
- }
6462
- return colors2.slice(0, count);
6463
- };
6464
- var niceCeil = (value) => {
6465
- if (!isFinite(value) || value <= 0) return 1;
6466
- const pow = Math.pow(10, Math.floor(Math.log10(value)));
6467
- const normalized = value / pow;
6468
- const multipliers = [
6469
- 1,
6470
- 1.25,
6471
- 1.5,
6472
- 2,
6473
- 2.5,
6474
- 3,
6475
- 4,
6476
- 5,
6477
- 7.5,
6478
- 10,
6479
- 15,
6480
- 20,
6481
- 25,
6482
- 50,
6483
- 100
6484
- ];
6485
- for (const m of multipliers) {
6486
- if (m >= normalized) return Math.ceil(m * pow);
6487
- }
6488
- return Math.ceil(100 * pow);
6489
- };
6490
- var compactTick = (value) => {
6491
- if (value >= 1e9)
6492
- return (value / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
6493
- if (value >= 1e6)
6494
- return (value / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
6495
- if (value >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
6496
- return String(value);
6497
- };
6498
- var resolveContainerPaddingLeft = (padding, containerPaddingLeft, defaultLeft = 16) => {
6499
- if (typeof padding === "number") return padding;
6500
- if (padding && typeof padding === "object" && padding.left != null)
6501
- return padding.left;
6502
- if (typeof containerPaddingLeft === "number") return containerPaddingLeft;
6503
- return defaultLeft;
6504
- };
6505
- var resolveChartMargins = (margins, chartMargins, showLabels) => {
6506
- const defaultRight = 30;
6507
- const defaultLeft = 20;
6508
- const topDefault = showLabels ? 48 : 20;
6509
- const bottomDefault = 5;
6510
- return {
6511
- top: margins?.top ?? chartMargins?.top ?? topDefault,
6512
- right: margins?.right ?? chartMargins?.right ?? defaultRight,
6513
- left: margins?.left ?? chartMargins?.left ?? defaultLeft,
6514
- bottom: margins?.bottom ?? chartMargins?.bottom ?? bottomDefault
6515
- };
6516
- };
6517
-
6518
- // src/components/charts/utils/pillLabelRenderer.tsx
6519
- import { jsx as jsx56, jsxs as jsxs38 } from "react/jsx-runtime";
6520
- var formatCompactNumber = (value) => {
6521
- const isNegative = value < 0;
6522
- const absValue = Math.abs(value);
6523
- let formatted;
6524
- if (absValue >= 1e9) {
6525
- formatted = (absValue / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
6526
- } else if (absValue >= 1e6) {
6527
- formatted = (absValue / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
6528
- } else if (absValue >= 1e3) {
6529
- formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + "K";
6530
- } else {
6531
- formatted = absValue.toString();
6532
- }
6533
- return isNegative ? `-${formatted}` : formatted;
6534
- };
6535
- var parseNumber = (v) => {
6536
- if (typeof v === "number") return v;
6537
- if (typeof v === "string" && v.trim() !== "" && !Number.isNaN(Number(v)))
6538
- return Number(v);
6539
- return void 0;
6540
- };
6541
- var renderPillLabel = (color, variant) => {
6542
- return (props) => {
6543
- const { x, y, value } = props;
6544
- const text = typeof value === "number" ? formatCompactNumber(value) : String(value ?? "");
6545
- const paddingX = 8;
6546
- const approxCharWidth = 7;
6547
- const pillWidth = Math.max(
6548
- 40,
6549
- String(text).length * approxCharWidth + paddingX * 2
6772
+ var renderPillLabel = (color, variant) => {
6773
+ return (props) => {
6774
+ const { x, y, value } = props;
6775
+ const text = typeof value === "number" ? formatCompactNumber(value) : String(value ?? "");
6776
+ const paddingX = 8;
6777
+ const approxCharWidth = 7;
6778
+ const pillWidth = Math.max(
6779
+ 40,
6780
+ String(text).length * approxCharWidth + paddingX * 2
6550
6781
  );
6551
6782
  const pillHeight = 20;
6552
6783
  const xNum = parseNumber(x);
@@ -6597,7 +6828,7 @@ var renderPillLabel = (color, variant) => {
6597
6828
  textColor = "#374151";
6598
6829
  }
6599
6830
  }
6600
- return /* @__PURE__ */ jsxs38("g", { children: [
6831
+ return /* @__PURE__ */ jsxs39("g", { children: [
6601
6832
  /* @__PURE__ */ jsx56(
6602
6833
  "rect",
6603
6834
  {
@@ -6630,51 +6861,2165 @@ var renderPillLabel = (color, variant) => {
6630
6861
  };
6631
6862
  var pillLabelRenderer_default = renderPillLabel;
6632
6863
 
6633
- // src/hooks/use-drag.tsx
6634
- import { useState as useState11, useCallback as useCallback7, useRef as useRef4, useEffect as useEffect10 } from "react";
6635
- var useDrag = (options = {}) => {
6636
- const [isDragging, setIsDragging] = useState11(null);
6637
- const [positions, setPositions] = useState11({});
6638
- const dragStartPos = useRef4(null);
6639
- const dragId = useRef4(null);
6640
- const handleMouseDown = useCallback7((id, e) => {
6641
- e.preventDefault();
6642
- const currentPosition = positions[id] || { top: 0, left: 0 };
6643
- dragStartPos.current = {
6644
- x: e.clientX,
6645
- y: e.clientY,
6646
- elementX: currentPosition.left,
6647
- elementY: currentPosition.top
6648
- };
6649
- dragId.current = id;
6650
- setIsDragging(id);
6651
- options.onDragStart?.(id);
6652
- }, [positions, options]);
6653
- const handleMouseMove = useCallback7((e) => {
6654
- if (!isDragging || !dragStartPos.current || !dragId.current) return;
6655
- const deltaX = e.clientX - dragStartPos.current.x;
6656
- const deltaY = e.clientY - dragStartPos.current.y;
6657
- const newPosition = {
6658
- left: dragStartPos.current.elementX + deltaX,
6659
- top: dragStartPos.current.elementY + deltaY
6864
+ // src/components/charts/Chart.tsx
6865
+ import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
6866
+ var DEFAULT_COLORS = ["#55af7d", "#8e68ff", "#2273e1"];
6867
+ var Chart = ({
6868
+ data,
6869
+ series,
6870
+ className,
6871
+ height = 350,
6872
+ width = "100%",
6873
+ colors: colors2 = DEFAULT_COLORS,
6874
+ gridColor,
6875
+ showGrid = true,
6876
+ showTooltip = true,
6877
+ showLegend = true,
6878
+ title,
6879
+ titlePosition = "left",
6880
+ showLabels = false,
6881
+ xAxis,
6882
+ labelMap,
6883
+ enableHighlights = false,
6884
+ enableShowOnly = false,
6885
+ enablePeriodsDropdown = false,
6886
+ enableDraggableTooltips = false,
6887
+ showTooltipTotal = false,
6888
+ maxTooltips = 5,
6889
+ chartMargin
6890
+ }) => {
6891
+ const smartConfig = useMemo6(() => {
6892
+ const resolvedXAxisKey = typeof xAxis === "string" ? xAxis : xAxis && xAxis.dataKey || detectXAxis(data);
6893
+ const xAxisConfig2 = typeof xAxis === "string" ? {
6894
+ dataKey: resolvedXAxisKey,
6895
+ label: formatFieldName(resolvedXAxisKey),
6896
+ autoLabel: true
6897
+ } : {
6898
+ dataKey: resolvedXAxisKey,
6899
+ label: xAxis?.label ?? formatFieldName(resolvedXAxisKey),
6900
+ formatter: xAxis?.formatter,
6901
+ autoLabel: xAxis?.autoLabel ?? true
6660
6902
  };
6661
- newPosition.left = Math.max(0, Math.min(window.innerWidth - 300, newPosition.left));
6662
- newPosition.top = Math.max(0, Math.min(window.innerHeight - 200, newPosition.top));
6663
- setPositions((prev) => ({
6664
- ...prev,
6665
- [dragId.current]: newPosition
6666
- }));
6667
- options.onDrag?.(dragId.current, newPosition);
6668
- }, [isDragging, options]);
6669
- const handleMouseUp = useCallback7(() => {
6670
- if (dragId.current) {
6671
- options.onDragEnd?.(dragId.current);
6903
+ const detectedFields = detectDataFields(data, xAxisConfig2.dataKey);
6904
+ const mapperConfig2 = detectedFields.reduce((acc, field) => {
6905
+ acc[field] = {
6906
+ label: labelMap?.[field] ?? formatFieldName(field),
6907
+ type: "number",
6908
+ visible: true
6909
+ };
6910
+ return acc;
6911
+ }, {});
6912
+ return { xAxisConfig: xAxisConfig2, mapperConfig: mapperConfig2 };
6913
+ }, [data, xAxis, labelMap]);
6914
+ const { xAxisConfig, mapperConfig } = smartConfig;
6915
+ const [activeTooltips, setActiveTooltips] = useState12([]);
6916
+ const [highlightedSeries, setHighlightedSeries] = useState12(
6917
+ /* @__PURE__ */ new Set()
6918
+ );
6919
+ const [showOnlyHighlighted, setShowOnlyHighlighted] = useState12(false);
6920
+ useEffect11(() => {
6921
+ if (highlightedSeries.size === 0 && showOnlyHighlighted) {
6922
+ setShowOnlyHighlighted(false);
6672
6923
  }
6673
- setIsDragging(null);
6674
- dragStartPos.current = null;
6675
- dragId.current = null;
6676
- }, [options]);
6677
- useEffect10(() => {
6924
+ }, [highlightedSeries, showOnlyHighlighted]);
6925
+ const processedData = data.map((item) => ({
6926
+ ...item,
6927
+ name: String(item[xAxisConfig.dataKey] || "N/A")
6928
+ }));
6929
+ const wrapperRef = useRef5(null);
6930
+ const [measuredWidth, setMeasuredWidth] = useState12(null);
6931
+ useLayoutEffect(() => {
6932
+ const el = wrapperRef.current;
6933
+ if (!el) return;
6934
+ const ro = new ResizeObserver((entries) => {
6935
+ const r = entries[0];
6936
+ if (r && typeof r.contentRect.width === "number") {
6937
+ setMeasuredWidth(Math.round(r.contentRect.width));
6938
+ }
6939
+ });
6940
+ ro.observe(el);
6941
+ setMeasuredWidth(Math.round(el.getBoundingClientRect().width));
6942
+ return () => ro.disconnect();
6943
+ }, []);
6944
+ const seriesOrder = [];
6945
+ if (series) {
6946
+ if (series.bar)
6947
+ series.bar.forEach((k) => seriesOrder.push({ type: "bar", key: k }));
6948
+ if (series.line)
6949
+ series.line.forEach((k) => seriesOrder.push({ type: "line", key: k }));
6950
+ if (series.area)
6951
+ series.area.forEach((k) => seriesOrder.push({ type: "area", key: k }));
6952
+ } else {
6953
+ Object.keys(mapperConfig).forEach(
6954
+ (k) => seriesOrder.push({ type: "bar", key: k })
6955
+ );
6956
+ }
6957
+ const allKeys = seriesOrder.map((s) => s.key).filter(Boolean);
6958
+ const generateColors = useCallback7(
6959
+ (dataKeys) => {
6960
+ const colorMap = {};
6961
+ const allColors = generateAdditionalColors(colors2, dataKeys.length);
6962
+ dataKeys.forEach((key, index) => {
6963
+ colorMap[key] = mapperConfig[key]?.color || allColors[index] || colors2[index % colors2.length];
6964
+ });
6965
+ return colorMap;
6966
+ },
6967
+ [colors2, mapperConfig]
6968
+ );
6969
+ const finalColors = useMemo6(
6970
+ () => generateColors(allKeys),
6971
+ [generateColors, allKeys]
6972
+ );
6973
+ const adaptDataForTooltip = useCallback7(
6974
+ (universalData) => ({
6975
+ ...universalData,
6976
+ name: String(universalData[xAxisConfig.dataKey] || "N/A")
6977
+ }),
6978
+ [xAxisConfig.dataKey]
6979
+ );
6980
+ const activePeriods = useMemo6(
6981
+ () => activeTooltips.map((t) => adaptDataForTooltip(t.data).name),
6982
+ [activeTooltips, adaptDataForTooltip]
6983
+ );
6984
+ useEffect11(() => {
6985
+ window.dispatchEvent(new Event("recountTooltips"));
6986
+ }, [activeTooltips.length]);
6987
+ const toggleHighlight = useCallback7((key) => {
6988
+ setHighlightedSeries((prev) => {
6989
+ const next = new Set(prev);
6990
+ if (next.has(key)) next.delete(key);
6991
+ else next.add(key);
6992
+ return next;
6993
+ });
6994
+ }, []);
6995
+ const maxDataValue = useMemo6(() => {
6996
+ let max = 0;
6997
+ const numericKeys = allKeys;
6998
+ for (const row of processedData) {
6999
+ const r = row;
7000
+ for (const key of numericKeys) {
7001
+ const v = r[key];
7002
+ if (typeof v === "number" && Number.isFinite(v) && v > max) max = v;
7003
+ }
7004
+ }
7005
+ return max;
7006
+ }, [processedData, allKeys]);
7007
+ const minDataValue = useMemo6(() => {
7008
+ let min = 0;
7009
+ const numericKeys = allKeys;
7010
+ for (const row of processedData) {
7011
+ const r = row;
7012
+ for (const key of numericKeys) {
7013
+ const v = r[key];
7014
+ if (typeof v === "number" && Number.isFinite(v) && v < min)
7015
+ min = v;
7016
+ }
7017
+ }
7018
+ return min;
7019
+ }, [processedData, allKeys]);
7020
+ const niceMax = useMemo6(() => {
7021
+ let padding = 0.08;
7022
+ if (maxDataValue > 1e6) padding = 0.05;
7023
+ if (maxDataValue > 1e7) padding = 0.03;
7024
+ if (maxDataValue === 0) padding = 0.12;
7025
+ const padded = maxDataValue * (1 + padding);
7026
+ return niceCeil(padded);
7027
+ }, [maxDataValue]);
7028
+ const computedWidth = useMemo6(() => {
7029
+ if (typeof width === "number") return width;
7030
+ const points = Math.max(1, processedData.length);
7031
+ const barCount = series?.bar?.length ?? 0;
7032
+ const lineCount = series?.line?.length ?? 0;
7033
+ const areaCount = series?.area?.length ?? 0;
7034
+ const basePerPoint = 60;
7035
+ const perBarExtra = barCount > 0 ? Math.max(0, barCount - 1) * 8 : 0;
7036
+ const perOtherExtra = (lineCount + areaCount) * 4;
7037
+ let sizeFactor = 1;
7038
+ if (niceMax > 1e5) sizeFactor = 1.1;
7039
+ if (niceMax > 1e6) sizeFactor = 1.2;
7040
+ if (niceMax > 1e7) sizeFactor = 1.3;
7041
+ const perPoint = Math.round(
7042
+ (basePerPoint + perBarExtra + perOtherExtra) * sizeFactor
7043
+ );
7044
+ const marginExtra = 120;
7045
+ const calculated = points * perPoint + marginExtra;
7046
+ const minWidth = 300;
7047
+ const maxWidth = 1800;
7048
+ return Math.max(minWidth, Math.min(maxWidth, calculated));
7049
+ }, [
7050
+ width,
7051
+ processedData.length,
7052
+ series?.bar?.length,
7053
+ series?.line?.length,
7054
+ series?.area?.length,
7055
+ niceMax
7056
+ ]);
7057
+ const toggleTooltip = useCallback7(
7058
+ (tooltipId, data2, basePosition) => {
7059
+ const existingIndex = activeTooltips.findIndex((t) => t.id === tooltipId);
7060
+ if (existingIndex !== -1) {
7061
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== tooltipId));
7062
+ } else {
7063
+ if (activeTooltips.length >= maxTooltips) {
7064
+ toast2.warning(
7065
+ `Limite de ${maxTooltips} janelas de informa\xE7\xE3o atingido. A mais antiga ser\xE1 substitu\xEDda.`
7066
+ );
7067
+ }
7068
+ const offsetIndex = activeTooltips.length;
7069
+ const gap = 28;
7070
+ const newTooltip = {
7071
+ id: tooltipId,
7072
+ data: data2,
7073
+ position: {
7074
+ top: basePosition.top + offsetIndex * gap,
7075
+ left: basePosition.left + offsetIndex * gap
7076
+ }
7077
+ };
7078
+ setActiveTooltips((prev) => {
7079
+ const next = [...prev, newTooltip];
7080
+ return next.length > maxTooltips ? next.slice(1) : next;
7081
+ });
7082
+ }
7083
+ },
7084
+ [activeTooltips, maxTooltips]
7085
+ );
7086
+ const handleChartClick = useCallback7(
7087
+ (e) => {
7088
+ if (!enableDraggableTooltips) return;
7089
+ const ev = e;
7090
+ if (ev?.activePayload?.length) {
7091
+ const clickedData = ev.activePayload[0].payload;
7092
+ const xAxisValue = clickedData[xAxisConfig.dataKey] || clickedData.name || "N/A";
7093
+ const tooltipId = String(xAxisValue);
7094
+ toggleTooltip(tooltipId, clickedData, {
7095
+ top: (ev.chartY || 100) - 10,
7096
+ left: (ev.chartX || 100) - 100
7097
+ });
7098
+ } else {
7099
+ setActiveTooltips([]);
7100
+ }
7101
+ },
7102
+ [enableDraggableTooltips, xAxisConfig.dataKey, toggleTooltip]
7103
+ );
7104
+ const handleBarClick = useCallback7(
7105
+ (data2, index, event) => {
7106
+ if (!enableDraggableTooltips) return;
7107
+ event.stopPropagation();
7108
+ const xAxisValue = data2[xAxisConfig.dataKey] || "N/A";
7109
+ const tooltipId = String(xAxisValue);
7110
+ const rect = event.target.getBoundingClientRect();
7111
+ toggleTooltip(tooltipId, data2, {
7112
+ top: Math.max(8, rect.top - 10),
7113
+ left: rect.right + 10
7114
+ });
7115
+ },
7116
+ [enableDraggableTooltips, xAxisConfig.dataKey, toggleTooltip]
7117
+ );
7118
+ const handleSeriesClick = useCallback7(
7119
+ (...args) => {
7120
+ if (args.length >= 3) {
7121
+ const [data2, index, event] = args;
7122
+ handleBarClick(data2, index, event);
7123
+ return;
7124
+ }
7125
+ handleChartClick(args[0]);
7126
+ },
7127
+ [handleBarClick, handleChartClick]
7128
+ );
7129
+ const onTooltipPositionChange = useCallback7(
7130
+ (id, position) => {
7131
+ setActiveTooltips(
7132
+ (prev) => prev.map((t) => t.id === id ? { ...t, position } : t)
7133
+ );
7134
+ },
7135
+ []
7136
+ );
7137
+ const titleClassName = useMemo6(
7138
+ () => "text-xl font-semibold text-foreground mb-3",
7139
+ []
7140
+ );
7141
+ const finalEnableHighlights = enableHighlights;
7142
+ const finalEnableShowOnly = enableShowOnly;
7143
+ const finalEnablePeriodsDropdown = enablePeriodsDropdown && enableDraggableTooltips;
7144
+ const defaultChartRightMargin = 30;
7145
+ const defaultChartLeftMargin = 0;
7146
+ const containerPaddingLeft = 16;
7147
+ const finalChartRightMargin = chartMargin?.right ?? defaultChartRightMargin;
7148
+ const finalChartLeftMargin = chartMargin?.left ?? defaultChartLeftMargin;
7149
+ const finalChartTopMargin = chartMargin?.top ?? (showLabels ? 48 : 20);
7150
+ const finalChartBottomMargin = chartMargin?.bottom ?? 5;
7151
+ const measuredInner = measuredWidth ? Math.max(0, measuredWidth - 32) : void 0;
7152
+ const effectiveChartWidth = typeof width === "number" ? width : measuredInner ?? computedWidth;
7153
+ const chartInnerWidth = effectiveChartWidth - finalChartLeftMargin - finalChartRightMargin;
7154
+ const openTooltipForPeriod = useCallback7(
7155
+ (periodName) => {
7156
+ if (!enableDraggableTooltips) return;
7157
+ const row = processedData.find((r) => String(r.name) === periodName);
7158
+ if (!row) return;
7159
+ const tooltipId = String(periodName);
7160
+ const existingIndex = activeTooltips.findIndex((t) => t.id === tooltipId);
7161
+ if (existingIndex !== -1) {
7162
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== tooltipId));
7163
+ return;
7164
+ }
7165
+ if (activeTooltips.length >= maxTooltips) {
7166
+ toast2.warning(
7167
+ `Limite de ${maxTooltips} janelas de informa\xE7\xE3o atingido. A mais antiga ser\xE1 substitu\xEDda.`
7168
+ );
7169
+ }
7170
+ const offsetIndex = activeTooltips.length;
7171
+ const availableWidth = typeof width === "number" ? width : measuredInner ?? computedWidth;
7172
+ const gap = 28;
7173
+ const leftGap = 28;
7174
+ const newTooltip = {
7175
+ id: tooltipId,
7176
+ data: row,
7177
+ position: {
7178
+ top: 48 + offsetIndex * gap,
7179
+ left: Math.max(120, availableWidth - 280 - offsetIndex * leftGap)
7180
+ }
7181
+ };
7182
+ setActiveTooltips((prev) => {
7183
+ const next = [...prev, newTooltip];
7184
+ return next.length > maxTooltips ? next.slice(1) : next;
7185
+ });
7186
+ },
7187
+ [
7188
+ enableDraggableTooltips,
7189
+ processedData,
7190
+ activeTooltips,
7191
+ width,
7192
+ measuredInner,
7193
+ computedWidth,
7194
+ maxTooltips
7195
+ ]
7196
+ );
7197
+ if (!data) return null;
7198
+ if (Array.isArray(data) && data.length === 0) {
7199
+ return /* @__PURE__ */ jsx57(
7200
+ "div",
7201
+ {
7202
+ className: cn(
7203
+ "rounded-lg bg-card p-4 relative w-full text-muted-foreground"
7204
+ ),
7205
+ children: /* @__PURE__ */ jsx57(
7206
+ "div",
7207
+ {
7208
+ style: {
7209
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`
7210
+ },
7211
+ children: "Sem dados para exibir"
7212
+ }
7213
+ )
7214
+ }
7215
+ );
7216
+ }
7217
+ return /* @__PURE__ */ jsx57(
7218
+ "div",
7219
+ {
7220
+ ref: wrapperRef,
7221
+ style: {
7222
+ width: "100%",
7223
+ overflowX: "hidden",
7224
+ overflowY: "hidden",
7225
+ minWidth: 0
7226
+ },
7227
+ children: /* @__PURE__ */ jsxs40(
7228
+ "div",
7229
+ {
7230
+ className: cn("rounded-lg bg-card p-2 relative", className),
7231
+ style: { width: "100%", maxWidth: "100%", minWidth: 0 },
7232
+ children: [
7233
+ title && /* @__PURE__ */ jsx57(
7234
+ "div",
7235
+ {
7236
+ style: {
7237
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`,
7238
+ width: "100%",
7239
+ maxWidth: `${chartInnerWidth}px`,
7240
+ display: "flex",
7241
+ justifyContent: titlePosition === "center" ? "center" : titlePosition === "right" ? "flex-end" : "flex-start",
7242
+ alignItems: "center",
7243
+ marginTop: 4
7244
+ },
7245
+ children: /* @__PURE__ */ jsx57("h3", { className: titleClassName, children: title })
7246
+ }
7247
+ ),
7248
+ allKeys.length > 0 && (finalEnableHighlights || finalEnableShowOnly) && /* @__PURE__ */ jsxs40(
7249
+ "div",
7250
+ {
7251
+ className: "flex items-center w-full",
7252
+ style: {
7253
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`,
7254
+ width: "98%",
7255
+ display: "flex",
7256
+ alignItems: "center",
7257
+ gap: "0.5rem"
7258
+ },
7259
+ children: [
7260
+ finalEnableHighlights && /* @__PURE__ */ jsx57(
7261
+ Highlights_default,
7262
+ {
7263
+ allKeys,
7264
+ mapperConfig,
7265
+ finalColors,
7266
+ highlightedSeries,
7267
+ toggleHighlight,
7268
+ containerWidth: chartInnerWidth
7269
+ }
7270
+ ),
7271
+ finalEnableShowOnly && /* @__PURE__ */ jsx57(
7272
+ ShowOnly_default,
7273
+ {
7274
+ showOnlyHighlighted,
7275
+ setShowOnlyHighlighted,
7276
+ highlightedSeriesSize: highlightedSeries.size,
7277
+ clearHighlights: () => setHighlightedSeries(/* @__PURE__ */ new Set())
7278
+ }
7279
+ ),
7280
+ finalEnablePeriodsDropdown && /* @__PURE__ */ jsx57(
7281
+ "div",
7282
+ {
7283
+ style: {
7284
+ marginLeft: "auto",
7285
+ display: "flex",
7286
+ alignItems: "center"
7287
+ },
7288
+ children: /* @__PURE__ */ jsx57(
7289
+ PeriodsDropdown_default,
7290
+ {
7291
+ processedData,
7292
+ onOpenPeriod: openTooltipForPeriod,
7293
+ rightOffset: finalChartRightMargin,
7294
+ activePeriods
7295
+ }
7296
+ )
7297
+ }
7298
+ )
7299
+ ]
7300
+ }
7301
+ ),
7302
+ !(allKeys.length > 0 && (finalEnableHighlights || finalEnableShowOnly)) && finalEnablePeriodsDropdown && /* @__PURE__ */ jsx57(
7303
+ "div",
7304
+ {
7305
+ style: {
7306
+ paddingLeft: `${containerPaddingLeft + finalChartLeftMargin}px`,
7307
+ paddingRight: `${finalChartRightMargin}px`,
7308
+ width: "100%",
7309
+ maxWidth: `${chartInnerWidth}px`,
7310
+ display: "flex",
7311
+ justifyContent: "flex-end"
7312
+ },
7313
+ children: /* @__PURE__ */ jsx57(
7314
+ PeriodsDropdown_default,
7315
+ {
7316
+ processedData,
7317
+ onOpenPeriod: openTooltipForPeriod,
7318
+ rightOffset: finalChartRightMargin
7319
+ }
7320
+ )
7321
+ }
7322
+ ),
7323
+ /* @__PURE__ */ jsx57(ResponsiveContainer, { width: "100%", height, children: /* @__PURE__ */ jsxs40(
7324
+ ComposedChart,
7325
+ {
7326
+ data: processedData,
7327
+ height,
7328
+ margin: {
7329
+ top: finalChartTopMargin,
7330
+ right: finalChartRightMargin,
7331
+ left: finalChartLeftMargin,
7332
+ bottom: finalChartBottomMargin
7333
+ },
7334
+ onClick: handleChartClick,
7335
+ children: [
7336
+ showGrid && /* @__PURE__ */ jsx57(
7337
+ CartesianGrid,
7338
+ {
7339
+ strokeDasharray: "3 3",
7340
+ stroke: gridColor || "hsl(var(--muted-foreground))",
7341
+ opacity: 0.5
7342
+ }
7343
+ ),
7344
+ /* @__PURE__ */ jsx57(
7345
+ XAxis,
7346
+ {
7347
+ dataKey: xAxisConfig.dataKey,
7348
+ stroke: "hsl(var(--muted-foreground))",
7349
+ fontSize: 12,
7350
+ tickLine: false,
7351
+ axisLine: false,
7352
+ tickFormatter: xAxisConfig.formatter
7353
+ }
7354
+ ),
7355
+ /* @__PURE__ */ jsx57(
7356
+ YAxis,
7357
+ {
7358
+ stroke: "hsl(var(--muted-foreground))",
7359
+ fontSize: 12,
7360
+ tickLine: false,
7361
+ axisLine: false,
7362
+ tickFormatter: (value) => Number(value).toLocaleString("pt-BR"),
7363
+ domain: [Math.min(minDataValue, 0), niceMax],
7364
+ tickCount: 6
7365
+ }
7366
+ ),
7367
+ minDataValue < 0 && /* @__PURE__ */ jsx57(
7368
+ ReferenceLine,
7369
+ {
7370
+ y: 0,
7371
+ stroke: "hsl(var(--muted-foreground))",
7372
+ strokeWidth: 1,
7373
+ strokeDasharray: "4 4"
7374
+ }
7375
+ ),
7376
+ showTooltip && /* @__PURE__ */ jsx57(
7377
+ Tooltip,
7378
+ {
7379
+ content: showTooltipTotal ? /* @__PURE__ */ jsx57(TooltipWithTotal_default, { finalColors }) : /* @__PURE__ */ jsx57(TooltipSimple_default, { finalColors }),
7380
+ cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
7381
+ }
7382
+ ),
7383
+ showLegend && /* @__PURE__ */ jsx57(
7384
+ Legend,
7385
+ {
7386
+ wrapperStyle: {
7387
+ color: "hsl(var(--foreground))",
7388
+ fontSize: "14px"
7389
+ }
7390
+ }
7391
+ ),
7392
+ seriesOrder.map((s) => {
7393
+ const key = s.key;
7394
+ if (showOnlyHighlighted && !highlightedSeries.has(key))
7395
+ return null;
7396
+ const label = mapperConfig[key]?.label ?? labelMap?.[key] ?? formatFieldName(key);
7397
+ const color = finalColors[key];
7398
+ if (s.type === "bar") {
7399
+ return /* @__PURE__ */ jsx57(
7400
+ Bar,
7401
+ {
7402
+ dataKey: key,
7403
+ name: label,
7404
+ fill: color,
7405
+ radius: [4, 4, 0, 0],
7406
+ onClick: handleBarClick,
7407
+ style: {
7408
+ cursor: "pointer",
7409
+ opacity: highlightedSeries.size > 0 ? highlightedSeries.has(key) ? 1 : 0.25 : 1
7410
+ },
7411
+ activeBar: /* @__PURE__ */ jsx57(
7412
+ Rectangle,
7413
+ {
7414
+ fill: color,
7415
+ stroke: color,
7416
+ strokeWidth: 2,
7417
+ opacity: 0.8
7418
+ }
7419
+ ),
7420
+ children: showLabels && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsx57(
7421
+ LabelList,
7422
+ {
7423
+ dataKey: key,
7424
+ position: "top",
7425
+ content: pillLabelRenderer_default(color, "filled"),
7426
+ offset: 8
7427
+ }
7428
+ ) : null
7429
+ },
7430
+ `bar-${key}`
7431
+ );
7432
+ }
7433
+ if (s.type === "line") {
7434
+ return /* @__PURE__ */ jsx57(
7435
+ Line,
7436
+ {
7437
+ dataKey: key,
7438
+ name: label,
7439
+ stroke: color,
7440
+ strokeWidth: 2,
7441
+ dot: { r: 3 },
7442
+ activeDot: { r: 6 },
7443
+ onClick: handleSeriesClick,
7444
+ style: {
7445
+ cursor: "pointer",
7446
+ pointerEvents: "all",
7447
+ opacity: highlightedSeries.size > 0 ? highlightedSeries.has(key) ? 1 : 0.25 : 1
7448
+ },
7449
+ children: showLabels && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsx57(
7450
+ LabelList,
7451
+ {
7452
+ dataKey: key,
7453
+ position: "top",
7454
+ content: pillLabelRenderer_default(color, "filled"),
7455
+ offset: 14
7456
+ }
7457
+ ) : null
7458
+ },
7459
+ `line-${key}`
7460
+ );
7461
+ }
7462
+ if (s.type === "area") {
7463
+ return /* @__PURE__ */ jsx57(
7464
+ Area,
7465
+ {
7466
+ dataKey: key,
7467
+ name: label,
7468
+ stroke: color,
7469
+ fill: color,
7470
+ fillOpacity: 0.35,
7471
+ strokeWidth: 2,
7472
+ onClick: handleSeriesClick,
7473
+ style: {
7474
+ cursor: "pointer",
7475
+ pointerEvents: "all",
7476
+ opacity: highlightedSeries.size > 0 ? highlightedSeries.has(key) ? 1 : 0.25 : 1
7477
+ },
7478
+ children: showLabels && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsx57(
7479
+ LabelList,
7480
+ {
7481
+ dataKey: key,
7482
+ position: "top",
7483
+ content: pillLabelRenderer_default(color, "soft"),
7484
+ offset: 12
7485
+ }
7486
+ ) : null
7487
+ },
7488
+ `area-${key}`
7489
+ );
7490
+ }
7491
+ return null;
7492
+ })
7493
+ ]
7494
+ }
7495
+ ) }),
7496
+ enableDraggableTooltips && activeTooltips.map((tooltip) => /* @__PURE__ */ jsx57(
7497
+ DraggableTooltip_default,
7498
+ {
7499
+ id: tooltip.id,
7500
+ data: adaptDataForTooltip(tooltip.data),
7501
+ position: tooltip.position,
7502
+ title,
7503
+ dataKeys: allKeys,
7504
+ finalColors,
7505
+ highlightedSeries,
7506
+ toggleHighlight,
7507
+ showOnlyHighlighted,
7508
+ onClose: (id) => setActiveTooltips((prev) => prev.filter((t) => t.id !== id)),
7509
+ onPositionChange: onTooltipPositionChange,
7510
+ periodLabel: "Per\xEDodo Selecionado",
7511
+ dataLabel: "Dados do Per\xEDodo",
7512
+ globalTooltipCount: activeTooltips.length,
7513
+ onCloseAll: () => window.dispatchEvent(new Event("closeAllTooltips")),
7514
+ closeAllButtonPosition: "top-center",
7515
+ closeAllButtonVariant: "floating"
7516
+ },
7517
+ tooltip.id
7518
+ )),
7519
+ enableDraggableTooltips && activeTooltips.length > 1 && /* @__PURE__ */ jsx57(
7520
+ CloseAllButton_default,
7521
+ {
7522
+ count: activeTooltips.length,
7523
+ onCloseAll: () => window.dispatchEvent(new Event("closeAllTooltips")),
7524
+ position: "top-center",
7525
+ variant: "floating"
7526
+ }
7527
+ )
7528
+ ]
7529
+ }
7530
+ )
7531
+ }
7532
+ );
7533
+ };
7534
+ var Chart_default = Chart;
7535
+
7536
+ // src/components/charts/BarChart.tsx
7537
+ import { useState as useState13, useEffect as useEffect12, useCallback as useCallback8, useMemo as useMemo7 } from "react";
7538
+ import {
7539
+ BarChart as RechartsBarChart,
7540
+ Bar as Bar2,
7541
+ Rectangle as Rectangle2,
7542
+ XAxis as XAxis2,
7543
+ YAxis as YAxis2,
7544
+ CartesianGrid as CartesianGrid2,
7545
+ Tooltip as Tooltip2,
7546
+ Legend as Legend2,
7547
+ LabelList as LabelList2
7548
+ } from "recharts";
7549
+ import { jsx as jsx58, jsxs as jsxs41 } from "react/jsx-runtime";
7550
+ var DEFAULT_COLORS2 = ["#55af7d", "#8e68ff", "#2273e1"];
7551
+ var BarChart = ({
7552
+ data,
7553
+ className,
7554
+ height = 350,
7555
+ width = 900,
7556
+ colors: colors2 = DEFAULT_COLORS2,
7557
+ gridColor,
7558
+ showGrid = true,
7559
+ showTooltip = true,
7560
+ showLegend = true,
7561
+ title,
7562
+ titlePosition = "left",
7563
+ showLabels = false,
7564
+ xAxis,
7565
+ mapper,
7566
+ yAxis,
7567
+ labelMap,
7568
+ autoDetect = false,
7569
+ padding,
7570
+ margins,
7571
+ containerPaddingLeft,
7572
+ chartMargins
7573
+ }) => {
7574
+ const resolvedContainerPaddingLeft = resolveContainerPaddingLeft(
7575
+ padding,
7576
+ containerPaddingLeft,
7577
+ 16
7578
+ );
7579
+ const smartConfig = useMemo7(() => {
7580
+ const providedMapper = yAxis ?? mapper;
7581
+ if (autoDetect === true || xAxis == null || providedMapper == null) {
7582
+ const detectedXAxis = detectXAxis(data);
7583
+ const detectedFields = detectDataFields(data, detectedXAxis);
7584
+ return {
7585
+ xAxisConfig: {
7586
+ dataKey: detectedXAxis,
7587
+ label: labelMap?.[detectedXAxis] ?? formatFieldName(detectedXAxis),
7588
+ autoLabel: true
7589
+ },
7590
+ mapperConfig: detectedFields.reduce((acc, field) => {
7591
+ acc[field] = {
7592
+ label: labelMap?.[field] ?? formatFieldName(field),
7593
+ type: "number",
7594
+ visible: true
7595
+ };
7596
+ return acc;
7597
+ }, {})
7598
+ };
7599
+ }
7600
+ const xAxisConfig2 = typeof xAxis === "string" ? { dataKey: xAxis, label: formatFieldName(xAxis), autoLabel: true } : xAxis;
7601
+ let mapperConfig2;
7602
+ if (Array.isArray(providedMapper)) {
7603
+ mapperConfig2 = providedMapper.reduce((acc, field) => {
7604
+ acc[field] = {
7605
+ label: labelMap?.[field] ?? formatFieldName(field),
7606
+ type: "auto",
7607
+ visible: true
7608
+ };
7609
+ return acc;
7610
+ }, {});
7611
+ } else {
7612
+ mapperConfig2 = Object.keys(providedMapper).reduce(
7613
+ (acc, key) => {
7614
+ acc[key] = {
7615
+ label: providedMapper[key]?.label ?? labelMap?.[key] ?? formatFieldName(key),
7616
+ type: "auto",
7617
+ visible: true,
7618
+ ...providedMapper[key]
7619
+ // Sobrescreve com configurações do usuário
7620
+ };
7621
+ return acc;
7622
+ },
7623
+ {}
7624
+ );
7625
+ }
7626
+ return { xAxisConfig: xAxisConfig2, mapperConfig: mapperConfig2 };
7627
+ }, [data, xAxis, mapper, yAxis, autoDetect, labelMap]);
7628
+ const { xAxisConfig, mapperConfig } = smartConfig;
7629
+ const [activeTooltips, setActiveTooltips] = useState13([]);
7630
+ const [isDragging, setIsDragging] = useState13(null);
7631
+ const [dragOffset, setDragOffset] = useState13({
7632
+ x: 0,
7633
+ y: 0
7634
+ });
7635
+ const [globalTooltipCount, setGlobalTooltipCount] = useState13(0);
7636
+ const [alignmentGuides, setAlignmentGuides] = useState13([]);
7637
+ const processedData = data.map((item) => ({
7638
+ ...item,
7639
+ name: String(item[xAxisConfig.dataKey] || "N/A")
7640
+ // Garantir propriedade 'name' para tooltip
7641
+ }));
7642
+ const generateColors = (dataKeys2) => {
7643
+ const colorMap = {};
7644
+ const allColors = generateAdditionalColors(colors2, dataKeys2.length);
7645
+ dataKeys2.forEach((key, index) => {
7646
+ colorMap[key] = allColors[index] || colors2[index % colors2.length];
7647
+ });
7648
+ return colorMap;
7649
+ };
7650
+ const dataKeys = Object.keys(mapperConfig);
7651
+ const finalColors = generateColors(dataKeys);
7652
+ const adaptDataForTooltip = (universalData) => {
7653
+ return {
7654
+ ...universalData,
7655
+ name: String(universalData[xAxisConfig.dataKey] || "N/A")
7656
+ // Garantir que tem a propriedade 'name'
7657
+ };
7658
+ };
7659
+ const maxDataValue = useMemo7(() => {
7660
+ let max = 0;
7661
+ const keys = Object.keys(mapperConfig);
7662
+ for (const row of processedData) {
7663
+ const r = row;
7664
+ for (const key of keys) {
7665
+ const v = r[key];
7666
+ if (typeof v === "number" && Number.isFinite(v) && v > max)
7667
+ max = v;
7668
+ }
7669
+ }
7670
+ return max;
7671
+ }, [processedData, mapperConfig]);
7672
+ const niceMax = useMemo7(() => {
7673
+ let padding2 = 0.08;
7674
+ if (maxDataValue > 1e6) padding2 = 0.05;
7675
+ if (maxDataValue > 1e7) padding2 = 0.03;
7676
+ if (maxDataValue === 0) padding2 = 0.12;
7677
+ const padded = maxDataValue * (1 + padding2);
7678
+ return niceCeil(padded);
7679
+ }, [maxDataValue]);
7680
+ const handleBarClick = (data2, index, event) => {
7681
+ event.stopPropagation();
7682
+ const xAxisValue = data2[xAxisConfig.dataKey] || "N/A";
7683
+ const tooltipId = `${xAxisValue}`;
7684
+ const rect = event.target.getBoundingClientRect();
7685
+ const existingIndex = activeTooltips.findIndex(
7686
+ (tooltip) => tooltip.id === tooltipId
7687
+ );
7688
+ if (existingIndex !== -1) {
7689
+ setActiveTooltips(
7690
+ (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
7691
+ );
7692
+ } else {
7693
+ const newTooltip = {
7694
+ id: tooltipId,
7695
+ data: data2,
7696
+ position: {
7697
+ top: rect.top - 10,
7698
+ // Posição fixa da viewport
7699
+ left: rect.right + 10
7700
+ // À direita da barra clicada
7701
+ }
7702
+ };
7703
+ setActiveTooltips((prev) => [...prev, newTooltip]);
7704
+ }
7705
+ };
7706
+ const handleChartClick = () => {
7707
+ setActiveTooltips([]);
7708
+ };
7709
+ const ALIGNMENT_THRESHOLD2 = 25;
7710
+ const GUIDE_THRESHOLD2 = 60;
7711
+ const STRONG_SNAP_THRESHOLD2 = 35;
7712
+ const PRECISION_SNAP_THRESHOLD2 = 8;
7713
+ const updateAlignmentGuides = useCallback8(
7714
+ (draggedTooltipId, currentPosition) => {
7715
+ if (!isDragging) return;
7716
+ const getAllTooltips = () => {
7717
+ const allTooltips2 = [];
7718
+ allTooltips2.push(...activeTooltips);
7719
+ const globalEvent = new CustomEvent("requestGlobalTooltips", {
7720
+ detail: { requesterId: draggedTooltipId, response: allTooltips2 }
7721
+ });
7722
+ window.dispatchEvent(globalEvent);
7723
+ return allTooltips2;
7724
+ };
7725
+ const allTooltips = getAllTooltips();
7726
+ const otherTooltips = allTooltips.filter(
7727
+ (t) => t.id !== draggedTooltipId
7728
+ );
7729
+ const guides = [];
7730
+ const tooltipDimensions = { width: 224, height: 120 };
7731
+ otherTooltips.forEach((tooltip) => {
7732
+ const topDiff = Math.abs(currentPosition.top - tooltip.position.top);
7733
+ if (topDiff <= GUIDE_THRESHOLD2) {
7734
+ guides.push({
7735
+ type: "horizontal",
7736
+ position: tooltip.position.top,
7737
+ visible: true,
7738
+ sourceTooltip: {
7739
+ top: currentPosition.top,
7740
+ left: currentPosition.left,
7741
+ width: tooltipDimensions.width,
7742
+ height: tooltipDimensions.height
7743
+ },
7744
+ targetTooltip: {
7745
+ top: tooltip.position.top,
7746
+ left: tooltip.position.left,
7747
+ width: tooltipDimensions.width,
7748
+ height: tooltipDimensions.height
7749
+ }
7750
+ });
7751
+ }
7752
+ const leftDiff = Math.abs(currentPosition.left - tooltip.position.left);
7753
+ if (leftDiff <= GUIDE_THRESHOLD2) {
7754
+ guides.push({
7755
+ type: "vertical",
7756
+ position: tooltip.position.left,
7757
+ visible: true,
7758
+ sourceTooltip: {
7759
+ top: currentPosition.top,
7760
+ left: currentPosition.left,
7761
+ width: tooltipDimensions.width,
7762
+ height: tooltipDimensions.height
7763
+ },
7764
+ targetTooltip: {
7765
+ top: tooltip.position.top,
7766
+ left: tooltip.position.left,
7767
+ width: tooltipDimensions.width,
7768
+ height: tooltipDimensions.height
7769
+ }
7770
+ });
7771
+ }
7772
+ });
7773
+ setAlignmentGuides(guides);
7774
+ },
7775
+ [isDragging, activeTooltips]
7776
+ );
7777
+ const snapToGuides = useCallback8(
7778
+ (position) => {
7779
+ const snappedPosition = { ...position };
7780
+ let hasSnapped = false;
7781
+ alignmentGuides.forEach((guide) => {
7782
+ if (guide.type === "horizontal") {
7783
+ const diff = Math.abs(position.top - guide.position);
7784
+ if (diff <= PRECISION_SNAP_THRESHOLD2) {
7785
+ snappedPosition.top = guide.position;
7786
+ hasSnapped = true;
7787
+ }
7788
+ } else if (guide.type === "vertical") {
7789
+ const diff = Math.abs(position.left - guide.position);
7790
+ if (diff <= PRECISION_SNAP_THRESHOLD2) {
7791
+ snappedPosition.left = guide.position;
7792
+ hasSnapped = true;
7793
+ }
7794
+ }
7795
+ });
7796
+ if (!hasSnapped) {
7797
+ alignmentGuides.forEach((guide) => {
7798
+ if (guide.type === "horizontal") {
7799
+ const diff = Math.abs(position.top - guide.position);
7800
+ if (diff <= STRONG_SNAP_THRESHOLD2) {
7801
+ snappedPosition.top = guide.position;
7802
+ }
7803
+ } else if (guide.type === "vertical") {
7804
+ const diff = Math.abs(position.left - guide.position);
7805
+ if (diff <= STRONG_SNAP_THRESHOLD2) {
7806
+ snappedPosition.left = guide.position;
7807
+ }
7808
+ }
7809
+ });
7810
+ }
7811
+ alignmentGuides.forEach((guide) => {
7812
+ if (guide.type === "horizontal") {
7813
+ const diff = Math.abs(position.top - guide.position);
7814
+ if (diff <= ALIGNMENT_THRESHOLD2 && snappedPosition.top === position.top) {
7815
+ snappedPosition.top = guide.position;
7816
+ }
7817
+ } else if (guide.type === "vertical") {
7818
+ const diff = Math.abs(position.left - guide.position);
7819
+ if (diff <= ALIGNMENT_THRESHOLD2 && snappedPosition.left === position.left) {
7820
+ snappedPosition.left = guide.position;
7821
+ }
7822
+ }
7823
+ });
7824
+ return snappedPosition;
7825
+ },
7826
+ [alignmentGuides]
7827
+ );
7828
+ const handleMouseDown = (e, tooltipId) => {
7829
+ e.preventDefault();
7830
+ e.stopPropagation();
7831
+ const tooltip = activeTooltips.find((t) => t.id === tooltipId);
7832
+ if (!tooltip) return;
7833
+ const rect = e.currentTarget.getBoundingClientRect();
7834
+ const offsetX = e.clientX - rect.left;
7835
+ const offsetY = e.clientY - rect.top;
7836
+ setIsDragging(tooltipId);
7837
+ setDragOffset({ x: offsetX, y: offsetY });
7838
+ };
7839
+ useEffect12(() => {
7840
+ let rafId;
7841
+ let lastMousePosition = { x: 0, y: 0 };
7842
+ const handleGlobalMouseMove = (e) => {
7843
+ if (!isDragging) return;
7844
+ lastMousePosition = { x: e.clientX, y: e.clientY };
7845
+ if (rafId) cancelAnimationFrame(rafId);
7846
+ rafId = requestAnimationFrame(() => {
7847
+ const newLeft = lastMousePosition.x - dragOffset.x;
7848
+ const newTop = lastMousePosition.y - dragOffset.y;
7849
+ const rawPosition = {
7850
+ top: Math.max(0, Math.min(newTop, window.innerHeight - 200)),
7851
+ left: Math.max(0, Math.min(newLeft, window.innerWidth - 250))
7852
+ };
7853
+ updateAlignmentGuides(isDragging, rawPosition);
7854
+ const snappedPosition = snapToGuides(rawPosition);
7855
+ setActiveTooltips(
7856
+ (prev) => prev.map((tooltip) => {
7857
+ if (tooltip.id === isDragging) {
7858
+ return {
7859
+ ...tooltip,
7860
+ position: snappedPosition
7861
+ };
7862
+ }
7863
+ return tooltip;
7864
+ })
7865
+ );
7866
+ });
7867
+ };
7868
+ const handleGlobalMouseUp = () => {
7869
+ if (isDragging) {
7870
+ setIsDragging(null);
7871
+ setAlignmentGuides([]);
7872
+ if (rafId) cancelAnimationFrame(rafId);
7873
+ }
7874
+ };
7875
+ if (isDragging) {
7876
+ document.addEventListener("mousemove", handleGlobalMouseMove, {
7877
+ passive: true
7878
+ });
7879
+ document.addEventListener("mouseup", handleGlobalMouseUp);
7880
+ document.body.style.cursor = "grabbing";
7881
+ document.body.style.userSelect = "none";
7882
+ }
7883
+ return () => {
7884
+ if (rafId) cancelAnimationFrame(rafId);
7885
+ document.removeEventListener("mousemove", handleGlobalMouseMove);
7886
+ document.removeEventListener("mouseup", handleGlobalMouseUp);
7887
+ document.body.style.cursor = "";
7888
+ document.body.style.userSelect = "";
7889
+ };
7890
+ }, [
7891
+ isDragging,
7892
+ dragOffset,
7893
+ alignmentGuides,
7894
+ updateAlignmentGuides,
7895
+ snapToGuides
7896
+ ]);
7897
+ useEffect12(() => {
7898
+ const handleCloseAllTooltips = () => {
7899
+ setActiveTooltips([]);
7900
+ setGlobalTooltipCount(0);
7901
+ };
7902
+ window.addEventListener("closeAllTooltips", handleCloseAllTooltips);
7903
+ return () => {
7904
+ window.removeEventListener("closeAllTooltips", handleCloseAllTooltips);
7905
+ };
7906
+ }, []);
7907
+ useEffect12(() => {
7908
+ const handleTooltipCountRequest = () => {
7909
+ window.dispatchEvent(
7910
+ new CustomEvent("tooltipCountResponse", {
7911
+ detail: { count: activeTooltips.length }
7912
+ })
7913
+ );
7914
+ };
7915
+ const handleGlobalTooltipsRequest = (event) => {
7916
+ const { detail } = event;
7917
+ if (detail && detail.response && detail.requesterId) {
7918
+ activeTooltips.forEach((tooltip) => {
7919
+ if (!detail.response.find(
7920
+ (t) => t.id === tooltip.id
7921
+ )) {
7922
+ detail.response.push({
7923
+ id: tooltip.id,
7924
+ position: tooltip.position
7925
+ });
7926
+ }
7927
+ });
7928
+ }
7929
+ };
7930
+ window.addEventListener("requestTooltipCount", handleTooltipCountRequest);
7931
+ window.addEventListener(
7932
+ "requestGlobalTooltips",
7933
+ handleGlobalTooltipsRequest
7934
+ );
7935
+ return () => {
7936
+ window.removeEventListener(
7937
+ "requestTooltipCount",
7938
+ handleTooltipCountRequest
7939
+ );
7940
+ window.removeEventListener(
7941
+ "requestGlobalTooltips",
7942
+ handleGlobalTooltipsRequest
7943
+ );
7944
+ };
7945
+ }, [activeTooltips]);
7946
+ useEffect12(() => {
7947
+ if (isDragging) return;
7948
+ let totalCount = 0;
7949
+ const handleCountResponse = (event) => {
7950
+ const customEvent = event;
7951
+ totalCount += customEvent.detail.count;
7952
+ };
7953
+ window.addEventListener("tooltipCountResponse", handleCountResponse);
7954
+ window.dispatchEvent(new CustomEvent("requestTooltipCount"));
7955
+ const timeoutId = setTimeout(() => {
7956
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
7957
+ setGlobalTooltipCount(totalCount);
7958
+ }, 5);
7959
+ return () => {
7960
+ clearTimeout(timeoutId);
7961
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
7962
+ };
7963
+ }, [activeTooltips.length, isDragging]);
7964
+ const CustomTooltip = ({
7965
+ active,
7966
+ payload,
7967
+ label
7968
+ }) => {
7969
+ if (!active || !payload) return null;
7970
+ return /* @__PURE__ */ jsxs41("div", { className: "bg-card border border-border rounded-lg p-3 shadow-lg", children: [
7971
+ /* @__PURE__ */ jsx58("p", { className: "font-medium text-foreground mb-2", children: label }),
7972
+ payload.map(
7973
+ (entry, index) => /* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-2 text-sm", children: [
7974
+ /* @__PURE__ */ jsx58(
7975
+ "div",
7976
+ {
7977
+ className: "w-3 h-3 rounded-sm",
7978
+ style: { backgroundColor: entry.color }
7979
+ }
7980
+ ),
7981
+ /* @__PURE__ */ jsxs41("span", { className: "text-muted-foreground", children: [
7982
+ entry.name,
7983
+ ":"
7984
+ ] }),
7985
+ /* @__PURE__ */ jsx58("span", { className: "text-foreground font-medium", children: entry.value?.toLocaleString("pt-BR") })
7986
+ ] }, index)
7987
+ ),
7988
+ /* @__PURE__ */ jsx58("p", { className: "text-xs text-muted-foreground mt-1", children: "Clique para fixar este tooltip" })
7989
+ ] });
7990
+ };
7991
+ const getTitleClassName = (position) => {
7992
+ const baseClasses = "text-xl font-semibold text-foreground mb-3";
7993
+ switch (position) {
7994
+ case "center":
7995
+ return `${baseClasses} text-center`;
7996
+ case "right":
7997
+ return `${baseClasses} text-right`;
7998
+ default:
7999
+ return `${baseClasses} text-left`;
8000
+ }
8001
+ };
8002
+ return /* @__PURE__ */ jsxs41(
8003
+ "div",
8004
+ {
8005
+ className: cn("rounded-lg bg-card p-4 relative", className),
8006
+ style: {
8007
+ width: typeof width === "number" ? `${width + 32}px` : "fit-content",
8008
+ maxWidth: "100%"
8009
+ },
8010
+ children: [
8011
+ title && /* @__PURE__ */ jsx58("div", { style: { paddingLeft: `${resolvedContainerPaddingLeft}px` }, children: /* @__PURE__ */ jsx58("h3", { className: getTitleClassName(titlePosition), children: title }) }),
8012
+ /* @__PURE__ */ jsxs41(
8013
+ RechartsBarChart,
8014
+ {
8015
+ data: processedData,
8016
+ width: typeof width === "number" ? width : 900,
8017
+ height,
8018
+ margin: resolveChartMargins(margins, chartMargins, showLabels),
8019
+ onClick: handleChartClick,
8020
+ children: [
8021
+ showGrid && /* @__PURE__ */ jsx58(
8022
+ CartesianGrid2,
8023
+ {
8024
+ strokeDasharray: "3 3",
8025
+ stroke: gridColor || "hsl(var(--muted-foreground))",
8026
+ opacity: 0.5
8027
+ }
8028
+ ),
8029
+ /* @__PURE__ */ jsx58(
8030
+ XAxis2,
8031
+ {
8032
+ dataKey: xAxisConfig.dataKey,
8033
+ stroke: "hsl(var(--muted-foreground))",
8034
+ fontSize: 12,
8035
+ tickLine: false,
8036
+ axisLine: false,
8037
+ tickFormatter: xAxisConfig.formatter
8038
+ }
8039
+ ),
8040
+ /* @__PURE__ */ jsx58(
8041
+ YAxis2,
8042
+ {
8043
+ stroke: "hsl(var(--muted-foreground))",
8044
+ fontSize: 12,
8045
+ tickLine: false,
8046
+ axisLine: false,
8047
+ tickFormatter: (value) => value.toLocaleString("pt-BR"),
8048
+ domain: [0, niceMax],
8049
+ tickCount: 6
8050
+ }
8051
+ ),
8052
+ showTooltip && /* @__PURE__ */ jsx58(
8053
+ Tooltip2,
8054
+ {
8055
+ content: /* @__PURE__ */ jsx58(CustomTooltip, {}),
8056
+ cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
8057
+ }
8058
+ ),
8059
+ showLegend && /* @__PURE__ */ jsx58(
8060
+ Legend2,
8061
+ {
8062
+ wrapperStyle: {
8063
+ color: "hsl(var(--foreground))",
8064
+ fontSize: "14px"
8065
+ }
8066
+ }
8067
+ ),
8068
+ dataKeys.map((key) => {
8069
+ const fieldConfig = mapperConfig[key];
8070
+ return /* @__PURE__ */ jsx58(
8071
+ Bar2,
8072
+ {
8073
+ dataKey: key,
8074
+ name: fieldConfig?.label || key,
8075
+ fill: fieldConfig?.color || finalColors[key],
8076
+ radius: [4, 4, 0, 0],
8077
+ onClick: handleBarClick,
8078
+ style: { cursor: "pointer" },
8079
+ activeBar: /* @__PURE__ */ jsx58(
8080
+ Rectangle2,
8081
+ {
8082
+ fill: finalColors[key],
8083
+ stroke: finalColors[key],
8084
+ strokeWidth: 2,
8085
+ opacity: 0.8
8086
+ }
8087
+ ),
8088
+ children: showLabels && /* @__PURE__ */ jsx58(
8089
+ LabelList2,
8090
+ {
8091
+ dataKey: key,
8092
+ position: "top",
8093
+ content: pillLabelRenderer_default(
8094
+ finalColors[key] || "#000",
8095
+ "filled"
8096
+ )
8097
+ }
8098
+ )
8099
+ },
8100
+ key
8101
+ );
8102
+ })
8103
+ ]
8104
+ }
8105
+ ),
8106
+ alignmentGuides.map((guide, index) => {
8107
+ const isHorizontal = guide.type === "horizontal";
8108
+ const color = isHorizontal ? "#3b82f6" : "#ef4444";
8109
+ const startX = isHorizontal ? Math.min(
8110
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8111
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8112
+ ) : guide.sourceTooltip.left + (isHorizontal ? 0 : guide.sourceTooltip.width / 2);
8113
+ const endX = isHorizontal ? Math.max(
8114
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8115
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8116
+ ) : guide.targetTooltip.left + (isHorizontal ? 0 : guide.targetTooltip.width / 2);
8117
+ const startY = isHorizontal ? guide.sourceTooltip.top + (isHorizontal ? guide.sourceTooltip.height / 2 : 0) : Math.min(
8118
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8119
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8120
+ );
8121
+ const endY = isHorizontal ? guide.targetTooltip.top + (isHorizontal ? guide.targetTooltip.height / 2 : 0) : Math.max(
8122
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8123
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8124
+ );
8125
+ return /* @__PURE__ */ jsxs41("div", { children: [
8126
+ /* @__PURE__ */ jsx58(
8127
+ "div",
8128
+ {
8129
+ className: "fixed pointer-events-none z-30",
8130
+ style: {
8131
+ left: startX,
8132
+ top: startY,
8133
+ width: isHorizontal ? endX - startX : "2px",
8134
+ height: isHorizontal ? "2px" : endY - startY,
8135
+ backgroundColor: color,
8136
+ boxShadow: `0 0 8px ${color}60`,
8137
+ opacity: 0.9,
8138
+ borderStyle: "dashed",
8139
+ borderWidth: "1px",
8140
+ borderColor: color,
8141
+ transform: "translateZ(0)"
8142
+ }
8143
+ }
8144
+ ),
8145
+ /* @__PURE__ */ jsx58(
8146
+ "div",
8147
+ {
8148
+ className: "fixed pointer-events-none z-31",
8149
+ style: {
8150
+ left: guide.sourceTooltip.left + guide.sourceTooltip.width / 2 - 4,
8151
+ top: guide.sourceTooltip.top + guide.sourceTooltip.height / 2 - 4,
8152
+ width: "8px",
8153
+ height: "8px",
8154
+ backgroundColor: color,
8155
+ borderRadius: "50%",
8156
+ boxShadow: `0 0 4px ${color}80`,
8157
+ opacity: 0.8
8158
+ }
8159
+ }
8160
+ ),
8161
+ /* @__PURE__ */ jsx58(
8162
+ "div",
8163
+ {
8164
+ className: "fixed pointer-events-none z-31",
8165
+ style: {
8166
+ left: guide.targetTooltip.left + guide.targetTooltip.width / 2 - 4,
8167
+ top: guide.targetTooltip.top + guide.targetTooltip.height / 2 - 4,
8168
+ width: "8px",
8169
+ height: "8px",
8170
+ backgroundColor: color,
8171
+ borderRadius: "50%",
8172
+ boxShadow: `0 0 4px ${color}80`,
8173
+ opacity: 0.8
8174
+ }
8175
+ }
8176
+ )
8177
+ ] }, index);
8178
+ }),
8179
+ activeTooltips.map((tooltip, index) => /* @__PURE__ */ jsx58(
8180
+ DraggableTooltip_default,
8181
+ {
8182
+ id: tooltip.id,
8183
+ data: adaptDataForTooltip(tooltip.data),
8184
+ position: tooltip.position,
8185
+ isDragging: isDragging === tooltip.id,
8186
+ title,
8187
+ dataKeys,
8188
+ finalColors,
8189
+ onMouseDown: (id, e) => handleMouseDown(e, id),
8190
+ onClose: (id) => {
8191
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== id));
8192
+ },
8193
+ periodLabel: "Per\xEDodo Selecionado",
8194
+ dataLabel: "Dados do Per\xEDodo",
8195
+ showCloseAllButton: index === 0,
8196
+ globalTooltipCount,
8197
+ onCloseAll: () => {
8198
+ window.dispatchEvent(new Event("closeAllTooltips"));
8199
+ },
8200
+ closeAllButtonPosition: "top-center",
8201
+ closeAllButtonVariant: "floating"
8202
+ },
8203
+ tooltip.id
8204
+ ))
8205
+ ]
8206
+ }
8207
+ );
8208
+ };
8209
+ var BarChart_default = BarChart;
8210
+
8211
+ // src/components/charts/LineChart.tsx
8212
+ import { useState as useState14, useEffect as useEffect13, useCallback as useCallback9, useMemo as useMemo8 } from "react";
8213
+ import {
8214
+ LineChart as RechartsLineChart,
8215
+ Line as Line2,
8216
+ XAxis as XAxis3,
8217
+ YAxis as YAxis3,
8218
+ CartesianGrid as CartesianGrid3,
8219
+ Tooltip as Tooltip3,
8220
+ Legend as Legend3,
8221
+ LabelList as LabelList3
8222
+ } from "recharts";
8223
+ import { jsx as jsx59, jsxs as jsxs42 } from "react/jsx-runtime";
8224
+ var defaultData = [
8225
+ { name: "A", value: 100 },
8226
+ { name: "B", value: 200 },
8227
+ { name: "C", value: 150 }
8228
+ ];
8229
+ var DEFAULT_COLORS3 = ["#55af7d", "#8e68ff", "#2273e1"];
8230
+ var CustomLineChart = ({
8231
+ data = defaultData,
8232
+ className,
8233
+ height = 300,
8234
+ width = "100%",
8235
+ colors: colors2 = DEFAULT_COLORS3,
8236
+ gridColor,
8237
+ showGrid = true,
8238
+ showTooltip = true,
8239
+ showLegend = true,
8240
+ title,
8241
+ titlePosition = "left",
8242
+ strokeWidth = 2,
8243
+ showDots = true,
8244
+ showLabels = false,
8245
+ padding,
8246
+ margins,
8247
+ containerPaddingLeft,
8248
+ chartMargins
8249
+ }) => {
8250
+ const resolvedContainerPaddingLeft = resolveContainerPaddingLeft(
8251
+ padding,
8252
+ containerPaddingLeft,
8253
+ 16
8254
+ );
8255
+ const [activeTooltips, setActiveTooltips] = useState14([]);
8256
+ const [isDragging, setIsDragging] = useState14(null);
8257
+ const [dragOffset, setDragOffset] = useState14({
8258
+ x: 0,
8259
+ y: 0
8260
+ });
8261
+ const [globalTooltipCount, setGlobalTooltipCount] = useState14(0);
8262
+ const [alignmentGuides, setAlignmentGuides] = useState14([]);
8263
+ const generateColors = (dataKeys2) => {
8264
+ const colorMap = {};
8265
+ const allColors = generateAdditionalColors(colors2, dataKeys2.length);
8266
+ dataKeys2.forEach((key, index) => {
8267
+ colorMap[key] = allColors[index] || colors2[index % colors2.length];
8268
+ });
8269
+ return colorMap;
8270
+ };
8271
+ const dataKeys = useMemo8(
8272
+ () => data.length > 0 ? Object.keys(data[0]).filter((key) => key !== "name") : [],
8273
+ [data]
8274
+ );
8275
+ const finalColors = generateColors(dataKeys);
8276
+ const maxDataValue = useMemo8(() => {
8277
+ let max = 0;
8278
+ for (const row of data) {
8279
+ const r = row;
8280
+ for (const key of dataKeys) {
8281
+ const v = r[key];
8282
+ if (typeof v === "number" && Number.isFinite(v) && v > max)
8283
+ max = v;
8284
+ }
8285
+ }
8286
+ return max;
8287
+ }, [data, dataKeys]);
8288
+ const niceMax = useMemo8(() => {
8289
+ let padding2 = 0.08;
8290
+ if (maxDataValue > 1e6) padding2 = 0.05;
8291
+ if (maxDataValue > 1e7) padding2 = 0.03;
8292
+ if (maxDataValue === 0) padding2 = 0.12;
8293
+ const padded = maxDataValue * (1 + padding2);
8294
+ return niceCeil(padded);
8295
+ }, [maxDataValue]);
8296
+ const ClickableDot = (props) => {
8297
+ const { cx, cy, payload, dataKey } = props;
8298
+ const handleDotClick = (e) => {
8299
+ e.stopPropagation();
8300
+ if (!payload || !cx || !cy) return;
8301
+ const tooltipId = `${payload.name}`;
8302
+ const existingIndex = activeTooltips.findIndex(
8303
+ (tooltip) => tooltip.id === tooltipId
8304
+ );
8305
+ if (existingIndex !== -1) {
8306
+ setActiveTooltips(
8307
+ (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
8308
+ );
8309
+ } else {
8310
+ const newTooltip = {
8311
+ id: tooltipId,
8312
+ data: payload,
8313
+ position: {
8314
+ top: cy - 50,
8315
+ // Posição relativa ao SVG
8316
+ left: cx - 100
8317
+ }
8318
+ };
8319
+ setActiveTooltips((prev) => [...prev, newTooltip]);
8320
+ }
8321
+ };
8322
+ return /* @__PURE__ */ jsx59(
8323
+ "circle",
8324
+ {
8325
+ cx,
8326
+ cy,
8327
+ r: 6,
8328
+ fill: finalColors[dataKey || ""] || colors2[0],
8329
+ stroke: finalColors[dataKey || ""] || colors2[0],
8330
+ strokeWidth: 2,
8331
+ style: { cursor: "pointer" },
8332
+ onClick: handleDotClick
8333
+ }
8334
+ );
8335
+ };
8336
+ const handleChartClick = (e) => {
8337
+ if (e && e.activePayload && e.activePayload.length > 0) {
8338
+ const clickedData = e.activePayload[0].payload;
8339
+ const tooltipId = `${clickedData.name}`;
8340
+ const existingIndex = activeTooltips.findIndex(
8341
+ (tooltip) => tooltip.id === tooltipId
8342
+ );
8343
+ if (existingIndex !== -1) {
8344
+ setActiveTooltips(
8345
+ (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
8346
+ );
8347
+ } else {
8348
+ const newTooltip = {
8349
+ id: tooltipId,
8350
+ data: clickedData,
8351
+ position: {
8352
+ top: (e.chartY || 100) - 10,
8353
+ left: (e.chartX || 100) - 100
8354
+ }
8355
+ };
8356
+ setActiveTooltips((prev) => [...prev, newTooltip]);
8357
+ }
8358
+ } else {
8359
+ }
8360
+ };
8361
+ const handleChartBackgroundClick = () => {
8362
+ setActiveTooltips([]);
8363
+ };
8364
+ const handleCloseAllTooltips = useCallback9(() => {
8365
+ window.dispatchEvent(new CustomEvent("closeAllTooltips"));
8366
+ }, []);
8367
+ const updateAlignmentGuides = useCallback9(
8368
+ (draggedTooltipId, draggedPosition) => {
8369
+ const SNAP_THRESHOLD = 15;
8370
+ const draggedTooltip = activeTooltips.find(
8371
+ (t) => t.id === draggedTooltipId
8372
+ );
8373
+ if (!draggedTooltip) return;
8374
+ const tooltipWidth = 200;
8375
+ const tooltipHeight = 80;
8376
+ const globalTooltips = [];
8377
+ window.dispatchEvent(
8378
+ new CustomEvent("requestGlobalTooltips", {
8379
+ detail: { requesterId: draggedTooltipId }
8380
+ })
8381
+ );
8382
+ activeTooltips.forEach((tooltip) => {
8383
+ if (tooltip.id !== draggedTooltipId) {
8384
+ globalTooltips.push({
8385
+ top: tooltip.position.top,
8386
+ left: tooltip.position.left,
8387
+ width: tooltipWidth,
8388
+ height: tooltipHeight,
8389
+ id: tooltip.id
8390
+ });
8391
+ }
8392
+ });
8393
+ const newGuides = [];
8394
+ globalTooltips.forEach((otherTooltip) => {
8395
+ const draggedCenter = {
8396
+ x: draggedPosition.left + tooltipWidth / 2,
8397
+ y: draggedPosition.top + tooltipHeight / 2
8398
+ };
8399
+ const otherCenter = {
8400
+ x: otherTooltip.left + otherTooltip.width / 2,
8401
+ y: otherTooltip.top + otherTooltip.height / 2
8402
+ };
8403
+ const horizontalDistance = Math.abs(draggedCenter.y - otherCenter.y);
8404
+ if (horizontalDistance <= SNAP_THRESHOLD) {
8405
+ newGuides.push({
8406
+ type: "horizontal",
8407
+ position: otherCenter.y,
8408
+ visible: true,
8409
+ sourceTooltip: {
8410
+ top: draggedPosition.top,
8411
+ left: draggedPosition.left,
8412
+ width: tooltipWidth,
8413
+ height: tooltipHeight
8414
+ },
8415
+ targetTooltip: {
8416
+ top: otherTooltip.top,
8417
+ left: otherTooltip.left,
8418
+ width: otherTooltip.width,
8419
+ height: otherTooltip.height
8420
+ }
8421
+ });
8422
+ }
8423
+ const verticalDistance = Math.abs(draggedCenter.x - otherCenter.x);
8424
+ if (verticalDistance <= SNAP_THRESHOLD) {
8425
+ newGuides.push({
8426
+ type: "vertical",
8427
+ position: otherCenter.x,
8428
+ visible: true,
8429
+ sourceTooltip: {
8430
+ top: draggedPosition.top,
8431
+ left: draggedPosition.left,
8432
+ width: tooltipWidth,
8433
+ height: tooltipHeight
8434
+ },
8435
+ targetTooltip: {
8436
+ top: otherTooltip.top,
8437
+ left: otherTooltip.left,
8438
+ width: otherTooltip.width,
8439
+ height: otherTooltip.height
8440
+ }
8441
+ });
8442
+ }
8443
+ });
8444
+ setAlignmentGuides(newGuides);
8445
+ },
8446
+ [activeTooltips]
8447
+ );
8448
+ const snapToGuides = useCallback9(
8449
+ (position) => {
8450
+ const SNAP_DISTANCE = 10;
8451
+ const snappedPosition = { ...position };
8452
+ alignmentGuides.forEach((guide) => {
8453
+ if (guide.type === "horizontal") {
8454
+ const tooltipCenter = position.top + 40;
8455
+ if (Math.abs(tooltipCenter - guide.position) <= SNAP_DISTANCE) {
8456
+ snappedPosition.top = guide.position - 40;
8457
+ }
8458
+ } else if (guide.type === "vertical") {
8459
+ const tooltipCenter = position.left + 100;
8460
+ if (Math.abs(tooltipCenter - guide.position) <= SNAP_DISTANCE) {
8461
+ snappedPosition.left = guide.position - 100;
8462
+ }
8463
+ }
8464
+ });
8465
+ return snappedPosition;
8466
+ },
8467
+ [alignmentGuides]
8468
+ );
8469
+ const handleMouseDown = (tooltipId, e) => {
8470
+ const rect = e.target.getBoundingClientRect();
8471
+ const offsetX = e.clientX - rect.left;
8472
+ const offsetY = e.clientY - rect.top;
8473
+ setIsDragging(tooltipId);
8474
+ setDragOffset({ x: offsetX, y: offsetY });
8475
+ };
8476
+ useEffect13(() => {
8477
+ let rafId;
8478
+ let lastMousePosition = { x: 0, y: 0 };
8479
+ const handleGlobalMouseMove = (e) => {
8480
+ if (!isDragging) return;
8481
+ lastMousePosition = { x: e.clientX, y: e.clientY };
8482
+ if (rafId) cancelAnimationFrame(rafId);
8483
+ rafId = requestAnimationFrame(() => {
8484
+ const newLeft = lastMousePosition.x - dragOffset.x;
8485
+ const newTop = lastMousePosition.y - dragOffset.y;
8486
+ let finalPosition = { top: newTop, left: newLeft };
8487
+ finalPosition = snapToGuides(finalPosition);
8488
+ setActiveTooltips(
8489
+ (prev) => prev.map(
8490
+ (tooltip) => tooltip.id === isDragging ? { ...tooltip, position: finalPosition } : tooltip
8491
+ )
8492
+ );
8493
+ updateAlignmentGuides(isDragging, finalPosition);
8494
+ });
8495
+ };
8496
+ const handleGlobalMouseUp = () => {
8497
+ if (rafId) cancelAnimationFrame(rafId);
8498
+ setIsDragging(null);
8499
+ setAlignmentGuides([]);
8500
+ document.body.style.cursor = "";
8501
+ document.body.style.userSelect = "";
8502
+ };
8503
+ if (isDragging) {
8504
+ document.body.style.cursor = "grabbing";
8505
+ document.body.style.userSelect = "none";
8506
+ window.addEventListener("mousemove", handleGlobalMouseMove);
8507
+ window.addEventListener("mouseup", handleGlobalMouseUp);
8508
+ }
8509
+ return () => {
8510
+ if (rafId) cancelAnimationFrame(rafId);
8511
+ window.removeEventListener("mousemove", handleGlobalMouseMove);
8512
+ window.removeEventListener("mouseup", handleGlobalMouseUp);
8513
+ document.body.style.cursor = "";
8514
+ document.body.style.userSelect = "";
8515
+ };
8516
+ }, [
8517
+ isDragging,
8518
+ dragOffset,
8519
+ alignmentGuides,
8520
+ updateAlignmentGuides,
8521
+ snapToGuides
8522
+ ]);
8523
+ useEffect13(() => {
8524
+ const handleCloseAllTooltips2 = () => {
8525
+ setActiveTooltips([]);
8526
+ setGlobalTooltipCount(0);
8527
+ };
8528
+ window.addEventListener("closeAllTooltips", handleCloseAllTooltips2);
8529
+ return () => {
8530
+ window.removeEventListener("closeAllTooltips", handleCloseAllTooltips2);
8531
+ };
8532
+ }, []);
8533
+ useEffect13(() => {
8534
+ const handleTooltipCountRequest = () => {
8535
+ window.dispatchEvent(
8536
+ new CustomEvent("tooltipCountResponse", {
8537
+ detail: { count: activeTooltips.length }
8538
+ })
8539
+ );
8540
+ };
8541
+ const handleGlobalTooltipsRequest = (event) => {
8542
+ const requesterId = event.detail?.requesterId;
8543
+ activeTooltips.forEach((tooltip) => {
8544
+ if (tooltip.id !== requesterId) {
8545
+ window.dispatchEvent(
8546
+ new CustomEvent("globalTooltipResponse", {
8547
+ detail: {
8548
+ tooltip: {
8549
+ top: tooltip.position.top,
8550
+ left: tooltip.position.left,
8551
+ width: 200,
8552
+ height: 80,
8553
+ id: tooltip.id
8554
+ }
8555
+ }
8556
+ })
8557
+ );
8558
+ }
8559
+ });
8560
+ };
8561
+ window.addEventListener("requestTooltipCount", handleTooltipCountRequest);
8562
+ window.addEventListener(
8563
+ "requestGlobalTooltips",
8564
+ handleGlobalTooltipsRequest
8565
+ );
8566
+ return () => {
8567
+ window.removeEventListener(
8568
+ "requestTooltipCount",
8569
+ handleTooltipCountRequest
8570
+ );
8571
+ window.removeEventListener(
8572
+ "requestGlobalTooltips",
8573
+ handleGlobalTooltipsRequest
8574
+ );
8575
+ };
8576
+ }, [activeTooltips]);
8577
+ useEffect13(() => {
8578
+ if (isDragging) return;
8579
+ let totalCount = 0;
8580
+ const handleCountResponse = (event) => {
8581
+ const customEvent = event;
8582
+ totalCount += customEvent.detail.count;
8583
+ };
8584
+ window.addEventListener("tooltipCountResponse", handleCountResponse);
8585
+ window.dispatchEvent(new CustomEvent("requestTooltipCount"));
8586
+ const timeoutId = setTimeout(() => {
8587
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
8588
+ setGlobalTooltipCount(totalCount);
8589
+ }, 5);
8590
+ return () => {
8591
+ clearTimeout(timeoutId);
8592
+ window.removeEventListener("tooltipCountResponse", handleCountResponse);
8593
+ };
8594
+ }, [activeTooltips.length, isDragging]);
8595
+ const getTitleClass = () => {
8596
+ switch (titlePosition) {
8597
+ case "center":
8598
+ return "text-center";
8599
+ case "right":
8600
+ return "text-right";
8601
+ default:
8602
+ return "text-left";
8603
+ }
8604
+ };
8605
+ return /* @__PURE__ */ jsx59("div", { className: cn("relative", className), children: /* @__PURE__ */ jsxs42(
8606
+ "div",
8607
+ {
8608
+ className: "rounded-lg bg-card p-4 relative border border-border",
8609
+ style: {
8610
+ width: typeof width === "number" ? `${width + 32}px` : "fit-content",
8611
+ maxWidth: "100%"
8612
+ },
8613
+ onClick: handleChartBackgroundClick,
8614
+ children: [
8615
+ title && /* @__PURE__ */ jsx59("div", { style: { paddingLeft: `${resolvedContainerPaddingLeft}px` }, children: /* @__PURE__ */ jsx59("div", { className: cn("mb-4", getTitleClass()), children: /* @__PURE__ */ jsx59("h3", { className: "text-lg font-semibold text-foreground", children: title }) }) }),
8616
+ /* @__PURE__ */ jsxs42(
8617
+ RechartsLineChart,
8618
+ {
8619
+ data,
8620
+ width: typeof width === "number" ? width : 900,
8621
+ height,
8622
+ margin: resolveChartMargins(margins, chartMargins, showLabels),
8623
+ onClick: handleChartClick,
8624
+ children: [
8625
+ showGrid && /* @__PURE__ */ jsx59(
8626
+ CartesianGrid3,
8627
+ {
8628
+ strokeDasharray: "3 3",
8629
+ stroke: gridColor || "hsl(var(--muted-foreground))",
8630
+ opacity: 0.3
8631
+ }
8632
+ ),
8633
+ /* @__PURE__ */ jsx59(
8634
+ XAxis3,
8635
+ {
8636
+ dataKey: "name",
8637
+ className: "fill-muted-foreground text-xs",
8638
+ fontSize: 12
8639
+ }
8640
+ ),
8641
+ /* @__PURE__ */ jsx59(
8642
+ YAxis3,
8643
+ {
8644
+ className: "fill-muted-foreground text-xs",
8645
+ fontSize: 12,
8646
+ tickFormatter: (value) => compactTick(Number(value)),
8647
+ domain: [0, niceMax],
8648
+ tickCount: 6
8649
+ }
8650
+ ),
8651
+ showTooltip && /* @__PURE__ */ jsx59(Tooltip3, { content: () => null }),
8652
+ showLegend && /* @__PURE__ */ jsx59(
8653
+ Legend3,
8654
+ {
8655
+ wrapperStyle: {
8656
+ fontSize: "12px",
8657
+ color: "hsl(var(--muted-foreground))"
8658
+ }
8659
+ }
8660
+ ),
8661
+ dataKeys.map((key) => /* @__PURE__ */ jsx59(
8662
+ Line2,
8663
+ {
8664
+ type: "monotone",
8665
+ dataKey: key,
8666
+ stroke: finalColors[key],
8667
+ strokeWidth,
8668
+ dot: showDots ? { r: 4, cursor: "pointer" } : false,
8669
+ activeDot: (props) => /* @__PURE__ */ jsx59(ClickableDot, { ...props, dataKey: key }),
8670
+ children: showLabels && /* @__PURE__ */ jsx59(
8671
+ LabelList3,
8672
+ {
8673
+ dataKey: key,
8674
+ position: "top",
8675
+ content: pillLabelRenderer_default(
8676
+ finalColors[key] || "#000",
8677
+ "filled"
8678
+ ),
8679
+ offset: 14
8680
+ }
8681
+ )
8682
+ },
8683
+ key
8684
+ ))
8685
+ ]
8686
+ }
8687
+ ),
8688
+ alignmentGuides.map((guide, index) => {
8689
+ const isHorizontal = guide.type === "horizontal";
8690
+ const color = isHorizontal ? "#3b82f6" : "#ef4444";
8691
+ const startX = isHorizontal ? Math.min(
8692
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8693
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8694
+ ) : guide.sourceTooltip.left + (isHorizontal ? 0 : guide.sourceTooltip.width / 2);
8695
+ const endX = isHorizontal ? Math.max(
8696
+ guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
8697
+ guide.targetTooltip.left + guide.targetTooltip.width / 2
8698
+ ) : guide.targetTooltip.left + (isHorizontal ? 0 : guide.targetTooltip.width / 2);
8699
+ const startY = isHorizontal ? guide.sourceTooltip.top + (isHorizontal ? guide.sourceTooltip.height / 2 : 0) : Math.min(
8700
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8701
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8702
+ );
8703
+ const endY = isHorizontal ? guide.targetTooltip.top + (isHorizontal ? guide.targetTooltip.height / 2 : 0) : Math.max(
8704
+ guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
8705
+ guide.targetTooltip.top + guide.targetTooltip.height / 2
8706
+ );
8707
+ return /* @__PURE__ */ jsxs42("div", { children: [
8708
+ /* @__PURE__ */ jsx59(
8709
+ "div",
8710
+ {
8711
+ className: "fixed pointer-events-none z-30",
8712
+ style: {
8713
+ left: startX,
8714
+ top: startY,
8715
+ width: isHorizontal ? endX - startX : "2px",
8716
+ height: isHorizontal ? "2px" : endY - startY,
8717
+ backgroundColor: color,
8718
+ boxShadow: `0 0 8px ${color}60`,
8719
+ opacity: 0.9,
8720
+ borderStyle: "dashed",
8721
+ borderWidth: "1px",
8722
+ borderColor: color,
8723
+ transform: "translateZ(0)"
8724
+ }
8725
+ }
8726
+ ),
8727
+ /* @__PURE__ */ jsx59(
8728
+ "div",
8729
+ {
8730
+ className: "fixed pointer-events-none z-31",
8731
+ style: {
8732
+ left: guide.sourceTooltip.left + guide.sourceTooltip.width / 2 - 4,
8733
+ top: guide.sourceTooltip.top + guide.sourceTooltip.height / 2 - 4,
8734
+ width: "8px",
8735
+ height: "8px",
8736
+ backgroundColor: color,
8737
+ borderRadius: "50%",
8738
+ boxShadow: `0 0 4px ${color}80`,
8739
+ opacity: 0.8
8740
+ }
8741
+ }
8742
+ ),
8743
+ /* @__PURE__ */ jsx59(
8744
+ "div",
8745
+ {
8746
+ className: "fixed pointer-events-none z-31",
8747
+ style: {
8748
+ left: guide.targetTooltip.left + guide.targetTooltip.width / 2 - 4,
8749
+ top: guide.targetTooltip.top + guide.targetTooltip.height / 2 - 4,
8750
+ width: "8px",
8751
+ height: "8px",
8752
+ backgroundColor: color,
8753
+ borderRadius: "50%",
8754
+ boxShadow: `0 0 4px ${color}80`,
8755
+ opacity: 0.8
8756
+ }
8757
+ }
8758
+ )
8759
+ ] }, index);
8760
+ }),
8761
+ activeTooltips.map((tooltip, index) => /* @__PURE__ */ jsx59(
8762
+ DraggableTooltip_default,
8763
+ {
8764
+ id: tooltip.id,
8765
+ data: tooltip.data,
8766
+ position: tooltip.position,
8767
+ isDragging: isDragging === tooltip.id,
8768
+ title,
8769
+ dataKeys,
8770
+ finalColors,
8771
+ onMouseDown: (id, e) => handleMouseDown(id, e),
8772
+ onClose: (id) => {
8773
+ setActiveTooltips((prev) => prev.filter((t) => t.id !== id));
8774
+ },
8775
+ periodLabel: "Ponto Selecionado",
8776
+ dataLabel: "Dados do Ponto",
8777
+ showCloseAllButton: index === 0,
8778
+ globalTooltipCount,
8779
+ onCloseAll: handleCloseAllTooltips,
8780
+ closeAllButtonPosition: "top-center",
8781
+ closeAllButtonVariant: "floating"
8782
+ },
8783
+ tooltip.id
8784
+ ))
8785
+ ]
8786
+ }
8787
+ ) });
8788
+ };
8789
+ var LineChart_default = CustomLineChart;
8790
+
8791
+ // src/components/charts/PieChart.tsx
8792
+ import {
8793
+ PieChart as RechartsPieChart,
8794
+ Pie,
8795
+ Cell,
8796
+ ResponsiveContainer as ResponsiveContainer2,
8797
+ Tooltip as Tooltip4,
8798
+ Legend as Legend4
8799
+ } from "recharts";
8800
+ import { jsx as jsx60, jsxs as jsxs43 } from "react/jsx-runtime";
8801
+ var defaultData2 = [
8802
+ { name: "Vendas", value: 4e3 },
8803
+ { name: "Marketing", value: 3e3 },
8804
+ { name: "Desenvolvimento", value: 2e3 },
8805
+ { name: "Suporte", value: 1e3 },
8806
+ { name: "Outros", value: 800 }
8807
+ ];
8808
+ var DEFAULT_COLORS4 = [
8809
+ "#55af7d",
8810
+ // verde do projeto
8811
+ "#8e68ff",
8812
+ // roxo do projeto
8813
+ "#2273e1",
8814
+ // azul do projeto
8815
+ "#f59e0b",
8816
+ // amarelo complementar
8817
+ "#ef4444",
8818
+ // vermelho complementar
8819
+ "#8b5cf6",
8820
+ // roxo claro
8821
+ "#06b6d4",
8822
+ // ciano
8823
+ "#84cc16"
8824
+ // verde lima
8825
+ ];
8826
+ var RADIAN = Math.PI / 180;
8827
+ var renderCustomizedLabel = ({
8828
+ cx = 0,
8829
+ cy = 0,
8830
+ midAngle = 0,
8831
+ innerRadius = 0,
8832
+ outerRadius = 0,
8833
+ percent = 0
8834
+ }) => {
8835
+ const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
8836
+ const x = cx + radius * Math.cos(-midAngle * RADIAN);
8837
+ const y = cy + radius * Math.sin(-midAngle * RADIAN);
8838
+ return /* @__PURE__ */ jsx60(
8839
+ "text",
8840
+ {
8841
+ x,
8842
+ y,
8843
+ fill: "white",
8844
+ textAnchor: x > cx ? "start" : "end",
8845
+ dominantBaseline: "central",
8846
+ fontSize: 12,
8847
+ fontWeight: "600",
8848
+ children: `${(percent * 100).toFixed(0)}%`
8849
+ }
8850
+ );
8851
+ };
8852
+ var CustomPieChart = ({
8853
+ data = defaultData2,
8854
+ className,
8855
+ height = 400,
8856
+ width = "100%",
8857
+ colors: colors2,
8858
+ showTooltip = true,
8859
+ showLegend = true,
8860
+ showLabels = true,
8861
+ innerRadius = 0,
8862
+ outerRadius = 120,
8863
+ centerX = "50%",
8864
+ centerY = "50%"
8865
+ }) => {
8866
+ const finalColors = colors2 || DEFAULT_COLORS4;
8867
+ return /* @__PURE__ */ jsx60("div", { className: cn("w-full rounded-lg bg-card p-4", className), children: /* @__PURE__ */ jsx60(ResponsiveContainer2, { width, height, children: /* @__PURE__ */ jsxs43(RechartsPieChart, { children: [
8868
+ /* @__PURE__ */ jsx60(
8869
+ Pie,
8870
+ {
8871
+ data,
8872
+ cx: centerX,
8873
+ cy: centerY,
8874
+ labelLine: false,
8875
+ label: showLabels ? renderCustomizedLabel : false,
8876
+ outerRadius,
8877
+ innerRadius,
8878
+ fill: "#8884d8",
8879
+ dataKey: "value",
8880
+ children: data.map((entry, index) => /* @__PURE__ */ jsx60(
8881
+ Cell,
8882
+ {
8883
+ fill: finalColors[index % finalColors.length]
8884
+ },
8885
+ `cell-${entry.name}-${index}`
8886
+ ))
8887
+ }
8888
+ ),
8889
+ showTooltip && /* @__PURE__ */ jsx60(
8890
+ Tooltip4,
8891
+ {
8892
+ contentStyle: {
8893
+ backgroundColor: "hsl(var(--popover))",
8894
+ border: "1px solid hsl(var(--border))",
8895
+ borderRadius: "6px",
8896
+ color: "hsl(var(--popover-foreground))"
8897
+ }
8898
+ }
8899
+ ),
8900
+ showLegend && /* @__PURE__ */ jsx60(Legend4, {})
8901
+ ] }) }) });
8902
+ };
8903
+ var PieChart_default = CustomPieChart;
8904
+
8905
+ // src/components/charts/hooks/useChartHighlights.tsx
8906
+ import { useState as useState15, useCallback as useCallback10 } from "react";
8907
+ var useChartHighlights = () => {
8908
+ const [highlightedSeries, setHighlightedSeries] = useState15(
8909
+ /* @__PURE__ */ new Set()
8910
+ );
8911
+ const [showOnlyHighlighted, setShowOnlyHighlighted] = useState15(false);
8912
+ const toggleHighlight = useCallback10((key) => {
8913
+ setHighlightedSeries((prev) => {
8914
+ const next = new Set(prev);
8915
+ if (next.has(key)) {
8916
+ next.delete(key);
8917
+ } else {
8918
+ next.add(key);
8919
+ }
8920
+ return next;
8921
+ });
8922
+ }, []);
8923
+ const clearHighlights = useCallback10(() => {
8924
+ setHighlightedSeries(/* @__PURE__ */ new Set());
8925
+ setShowOnlyHighlighted(false);
8926
+ }, []);
8927
+ const isHighlighted = useCallback10(
8928
+ (key) => {
8929
+ return highlightedSeries.has(key);
8930
+ },
8931
+ [highlightedSeries]
8932
+ );
8933
+ const getSeriesStyle = useCallback10(
8934
+ (key) => {
8935
+ const hasHighlights = highlightedSeries.size > 0;
8936
+ const isSeriesHighlighted = highlightedSeries.has(key);
8937
+ if (showOnlyHighlighted && !isSeriesHighlighted) {
8938
+ return {
8939
+ opacity: 0,
8940
+ pointerEvents: "none",
8941
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
8942
+ };
8943
+ }
8944
+ if (!hasHighlights) {
8945
+ return {
8946
+ opacity: 1,
8947
+ transform: "scale(1)",
8948
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
8949
+ };
8950
+ }
8951
+ if (isSeriesHighlighted) {
8952
+ return {
8953
+ opacity: 1,
8954
+ transform: "scale(1.02)",
8955
+ filter: "drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15))",
8956
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
8957
+ };
8958
+ }
8959
+ return {
8960
+ opacity: 0.25,
8961
+ transform: "scale(0.98)",
8962
+ transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1)"
8963
+ };
8964
+ },
8965
+ [highlightedSeries, showOnlyHighlighted]
8966
+ );
8967
+ return {
8968
+ highlightedSeries,
8969
+ showOnlyHighlighted,
8970
+ toggleHighlight,
8971
+ setShowOnlyHighlighted,
8972
+ clearHighlights,
8973
+ getSeriesStyle,
8974
+ isHighlighted
8975
+ };
8976
+ };
8977
+
8978
+ // src/hooks/use-drag.tsx
8979
+ import { useState as useState16, useCallback as useCallback11, useRef as useRef6, useEffect as useEffect14 } from "react";
8980
+ var useDrag = (options = {}) => {
8981
+ const [isDragging, setIsDragging] = useState16(null);
8982
+ const [positions, setPositions] = useState16({});
8983
+ const dragStartPos = useRef6(null);
8984
+ const dragId = useRef6(null);
8985
+ const handleMouseDown = useCallback11((id, e) => {
8986
+ e.preventDefault();
8987
+ const currentPosition = positions[id] || { top: 0, left: 0 };
8988
+ dragStartPos.current = {
8989
+ x: e.clientX,
8990
+ y: e.clientY,
8991
+ elementX: currentPosition.left,
8992
+ elementY: currentPosition.top
8993
+ };
8994
+ dragId.current = id;
8995
+ setIsDragging(id);
8996
+ options.onDragStart?.(id);
8997
+ }, [positions, options]);
8998
+ const handleMouseMove = useCallback11((e) => {
8999
+ if (!isDragging || !dragStartPos.current || !dragId.current) return;
9000
+ const deltaX = e.clientX - dragStartPos.current.x;
9001
+ const deltaY = e.clientY - dragStartPos.current.y;
9002
+ const newPosition = {
9003
+ left: dragStartPos.current.elementX + deltaX,
9004
+ top: dragStartPos.current.elementY + deltaY
9005
+ };
9006
+ newPosition.left = Math.max(0, Math.min(window.innerWidth - 300, newPosition.left));
9007
+ newPosition.top = Math.max(0, Math.min(window.innerHeight - 200, newPosition.top));
9008
+ setPositions((prev) => ({
9009
+ ...prev,
9010
+ [dragId.current]: newPosition
9011
+ }));
9012
+ options.onDrag?.(dragId.current, newPosition);
9013
+ }, [isDragging, options]);
9014
+ const handleMouseUp = useCallback11(() => {
9015
+ if (dragId.current) {
9016
+ options.onDragEnd?.(dragId.current);
9017
+ }
9018
+ setIsDragging(null);
9019
+ dragStartPos.current = null;
9020
+ dragId.current = null;
9021
+ }, [options]);
9022
+ useEffect14(() => {
6678
9023
  if (isDragging) {
6679
9024
  document.addEventListener("mousemove", handleMouseMove);
6680
9025
  document.addEventListener("mouseup", handleMouseUp);
@@ -6686,16 +9031,16 @@ var useDrag = (options = {}) => {
6686
9031
  };
6687
9032
  }
6688
9033
  }, [isDragging, handleMouseMove, handleMouseUp]);
6689
- const setPosition = useCallback7((id, position) => {
9034
+ const setPosition = useCallback11((id, position) => {
6690
9035
  setPositions((prev) => ({
6691
9036
  ...prev,
6692
9037
  [id]: position
6693
9038
  }));
6694
9039
  }, []);
6695
- const getPosition = useCallback7((id) => {
9040
+ const getPosition = useCallback11((id) => {
6696
9041
  return positions[id] || { top: 0, left: 0 };
6697
9042
  }, [positions]);
6698
- const isElementDragging = useCallback7((id) => {
9043
+ const isElementDragging = useCallback11((id) => {
6699
9044
  return isDragging === id;
6700
9045
  }, [isDragging]);
6701
9046
  return {
@@ -6722,6 +9067,7 @@ export {
6722
9067
  AvatarFallbackBase,
6723
9068
  AvatarImageBase,
6724
9069
  BadgeBase,
9070
+ BarChart_default as BarChart,
6725
9071
  BreadcrumbBase,
6726
9072
  BreadcrumbEllipsisBase,
6727
9073
  BreadcrumbItemBase,
@@ -6743,6 +9089,7 @@ export {
6743
9089
  CarouselItemBase,
6744
9090
  CarouselNextBase,
6745
9091
  CarouselPrevious,
9092
+ Chart_default as Chart,
6746
9093
  CheckboxBase,
6747
9094
  CloseAllButton_default as CloseAllButton,
6748
9095
  CollapsibleBase,
@@ -6821,6 +9168,7 @@ export {
6821
9168
  InputOTPSeparatorBase,
6822
9169
  InputOTPSlotBase,
6823
9170
  LabelBase_default as LabelBase,
9171
+ LineChart_default as LineChart,
6824
9172
  LoadingBase,
6825
9173
  ModeToggleBase,
6826
9174
  MultiCombobox,
@@ -6833,6 +9181,7 @@ export {
6833
9181
  NavigationMenuTriggerBase,
6834
9182
  NavigationMenuViewportBase,
6835
9183
  PeriodsDropdown_default as PeriodsDropdown,
9184
+ PieChart_default as PieChart,
6836
9185
  PopoverAnchorBase,
6837
9186
  PopoverBase,
6838
9187
  PopoverContentBase,
@@ -6928,6 +9277,7 @@ export {
6928
9277
  resolveChartMargins,
6929
9278
  resolveContainerPaddingLeft,
6930
9279
  toast,
9280
+ useChartHighlights,
6931
9281
  useDrag,
6932
9282
  useIsMobile,
6933
9283
  useTheme