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