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