@mlw-packages/react-components 1.8.14 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -584,7 +584,7 @@ var AlertDialogContentBase = React33__namespace.forwardRef(({ className, testid
584
584
  {
585
585
  ref,
586
586
  className: cn(
587
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
587
+ "fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-3 sm:gap-4 border bg-background p-4 sm:p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] rounded-md sm:rounded-lg max-h-[calc(100dvh-2rem)] sm:max-h-[90dvh] overflow-auto border-border",
588
588
  className
589
589
  ),
590
590
  "data-testid": testid,
@@ -600,7 +600,7 @@ var AlertDialogHeaderBase = ({
600
600
  "div",
601
601
  {
602
602
  className: cn(
603
- "flex flex-col space-y-2 text-center sm:text-left",
603
+ "flex flex-col space-y-1 sm:space-y-2 text-center sm:text-left",
604
604
  className
605
605
  ),
606
606
  ...props
@@ -614,7 +614,7 @@ var AlertDialogFooterBase = ({
614
614
  "div",
615
615
  {
616
616
  className: cn(
617
- "flex flex-col-reverse sm:flex-row sm:justify-end",
617
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end sm:space-x-2 sm:gap-0",
618
618
  className
619
619
  ),
620
620
  ...props
@@ -1327,19 +1327,21 @@ function useIsMobile() {
1327
1327
  }, []);
1328
1328
  return !!isMobile;
1329
1329
  }
1330
+ var isTouchDevice = () => {
1331
+ return "ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints !== void 0;
1332
+ };
1330
1333
  var useDrag = (options = {}) => {
1331
1334
  const [isDragging, setIsDragging] = React33.useState(null);
1332
1335
  const [positions, setPositions] = React33.useState({});
1333
1336
  const dragStartPos = React33.useRef(null);
1334
1337
  const dragId = React33.useRef(null);
1338
+ const isTouch = React33.useRef(isTouchDevice());
1335
1339
  const handleDragStart = React33.useCallback(
1336
1340
  (id, e) => {
1337
1341
  const isTouchEvent = "touches" in e;
1338
1342
  const clientX = isTouchEvent ? e.touches[0].clientX : e.clientX;
1339
1343
  const clientY = isTouchEvent ? e.touches[0].clientY : e.clientY;
1340
- if (!isTouchEvent) {
1341
- e.preventDefault();
1342
- }
1344
+ e.preventDefault();
1343
1345
  const currentPosition = positions[id] || { top: 0, left: 0 };
1344
1346
  dragStartPos.current = {
1345
1347
  x: clientX,
@@ -1357,6 +1359,9 @@ var useDrag = (options = {}) => {
1357
1359
  (e) => {
1358
1360
  if (!isDragging || !dragStartPos.current || !dragId.current) return;
1359
1361
  const isTouchEvent = "touches" in e;
1362
+ if (isTouchEvent) {
1363
+ e.preventDefault();
1364
+ }
1360
1365
  const clientX = isTouchEvent ? e.touches[0].clientX : e.clientX;
1361
1366
  const clientY = isTouchEvent ? e.touches[0].clientY : e.clientY;
1362
1367
  const deltaX = clientX - dragStartPos.current.x;
@@ -1391,18 +1396,25 @@ var useDrag = (options = {}) => {
1391
1396
  }, [options]);
1392
1397
  React33.useEffect(() => {
1393
1398
  if (isDragging) {
1394
- document.addEventListener("mousemove", handleMouseMove);
1395
- document.addEventListener("mouseup", handleMouseUp);
1396
- document.addEventListener("touchmove", handleMouseMove, {
1397
- passive: false
1398
- });
1399
- document.addEventListener("touchend", handleMouseUp);
1399
+ const isTouchDev = isTouch.current;
1400
+ if (isTouchDev) {
1401
+ document.addEventListener("touchmove", handleMouseMove, {
1402
+ passive: false
1403
+ });
1404
+ document.addEventListener("touchend", handleMouseUp);
1405
+ } else {
1406
+ document.addEventListener("mousemove", handleMouseMove);
1407
+ document.addEventListener("mouseup", handleMouseUp);
1408
+ }
1400
1409
  document.body.style.userSelect = "none";
1401
1410
  return () => {
1402
- document.removeEventListener("mousemove", handleMouseMove);
1403
- document.removeEventListener("mouseup", handleMouseUp);
1404
- document.removeEventListener("touchmove", handleMouseMove);
1405
- document.removeEventListener("touchend", handleMouseUp);
1411
+ if (isTouchDev) {
1412
+ document.removeEventListener("touchmove", handleMouseMove);
1413
+ document.removeEventListener("touchend", handleMouseUp);
1414
+ } else {
1415
+ document.removeEventListener("mousemove", handleMouseMove);
1416
+ document.removeEventListener("mouseup", handleMouseUp);
1417
+ }
1406
1418
  document.body.style.userSelect = "";
1407
1419
  };
1408
1420
  }
@@ -1662,7 +1674,7 @@ var ModalContentBase = React33__namespace.forwardRef(
1662
1674
  {
1663
1675
  ref,
1664
1676
  className: cn(
1665
- "fixed z-50 grid w-full gap-4 border bg-background p-6 shadow-lg sm:rounded-lg max-h-[90dvh] overflow-auto",
1677
+ "fixed z-50 grid w-[calc(100%-2rem)] gap-3 sm:gap-4 border bg-background p-4 sm:p-6 shadow-lg rounded-md sm:rounded-lg max-h-[calc(100dvh-2rem)] sm:max-h-[90dvh] overflow-auto",
1666
1678
  "data-[state=open]:animate-modal-in data-[state=closed]:animate-modal-out border-border",
1667
1679
  positionClass,
1668
1680
  sizeClass,
@@ -1672,7 +1684,7 @@ var ModalContentBase = React33__namespace.forwardRef(
1672
1684
  ...props,
1673
1685
  children: [
1674
1686
  children,
1675
- /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-3 top-3 sm:right-4 sm:top-4 rounded-md bg-muted/10 p-1.5 opacity-80 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none z-10 hover:bg-muted/20 transition-colors", children: [
1687
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-2 top-2 sm:right-4 sm:top-4 rounded-md bg-muted/10 p-1.5 sm:p-1.5 opacity-80 hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none z-10 hover:bg-muted/20 transition-colors", children: [
1676
1688
  /* @__PURE__ */ jsxRuntime.jsx(react.XIcon, { className: "h-5 w-5 sm:h-4 sm:w-4 text-foreground" }),
1677
1689
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
1678
1690
  ] })
@@ -1688,7 +1700,7 @@ var ModalHeaderBase = React33__namespace.forwardRef(({ className, testid: dataTe
1688
1700
  {
1689
1701
  ref,
1690
1702
  className: cn(
1691
- "flex flex-col space-y-1.5 text-center sm:text-left",
1703
+ "flex flex-col space-y-1 sm:space-y-1.5 text-center sm:text-left pr-8 sm:pr-0",
1692
1704
  className
1693
1705
  ),
1694
1706
  "data-testid": dataTestId,
@@ -1701,7 +1713,7 @@ var ModalFooterBase = React33__namespace.forwardRef(({ className, testid: dataTe
1701
1713
  {
1702
1714
  ref,
1703
1715
  className: cn(
1704
- "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
1716
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end sm:space-x-2 sm:gap-0",
1705
1717
  className
1706
1718
  ),
1707
1719
  "data-testid": dataTestId,
@@ -2127,6 +2139,7 @@ function ComboboxBase({
2127
2139
  hideClear = false
2128
2140
  }) {
2129
2141
  const [open, setOpen] = React33.useState(false);
2142
+ const isMobile = useIsMobile();
2130
2143
  return /* @__PURE__ */ jsxRuntime.jsxs(
2131
2144
  "div",
2132
2145
  {
@@ -2138,7 +2151,7 @@ function ComboboxBase({
2138
2151
  {
2139
2152
  open,
2140
2153
  onOpenChange: (v) => !disabled && setOpen(v),
2141
- modal: false,
2154
+ modal: isMobile,
2142
2155
  children: [
2143
2156
  /* @__PURE__ */ jsxRuntime.jsx(
2144
2157
  PopoverTriggerBase,
@@ -2588,7 +2601,7 @@ function MultiSelectValueBase({
2588
2601
  {
2589
2602
  "data-selected-item": true,
2590
2603
  size: "sm",
2591
- className: "group flex items-center gap-1",
2604
+ className: "group flex items-center gap-1 border-border",
2592
2605
  onClick: clickToRemove ? (e) => {
2593
2606
  e.stopPropagation();
2594
2607
  toggleValue(value);
@@ -2653,7 +2666,7 @@ function MultiSelectContentBase({
2653
2666
  {
2654
2667
  placeholder: typeof search === "object" ? search.placeholder : void 0
2655
2668
  }
2656
- ) : /* @__PURE__ */ jsxRuntime.jsx("button", { autoFocus: true, className: "sr-only" }),
2669
+ ) : /* @__PURE__ */ jsxRuntime.jsx("button", { autoFocus: true, className: "sr-only " }),
2657
2670
  /* @__PURE__ */ jsxRuntime.jsxs(CommandListBase, { className: "border-border", children: [
2658
2671
  canSearch && /* @__PURE__ */ jsxRuntime.jsx(CommandEmptyBase, { children: typeof search === "object" ? search.emptyMessage ?? emptyMessage : emptyMessage }),
2659
2672
  children
@@ -2711,7 +2724,7 @@ function useMultiSelectContext() {
2711
2724
  const context = React33.useContext(MultiSelectContext);
2712
2725
  if (context == null) {
2713
2726
  throw new Error(
2714
- "useMultiSelectContext must be used within a MultiSelectContext"
2727
+ "useMultiSelectContext must be used within a MultiSelectContext "
2715
2728
  );
2716
2729
  }
2717
2730
  return context;
@@ -2896,7 +2909,7 @@ var SelectContentBase = React33__namespace.forwardRef(
2896
2909
  {
2897
2910
  className: cn(
2898
2911
  "p-1",
2899
- position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
2912
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] max-w-[var(--radix-select-trigger-width)]"
2900
2913
  ),
2901
2914
  children
2902
2915
  }
@@ -2960,6 +2973,20 @@ var SelectSeparatorBase = React33__namespace.forwardRef(({ className, ...props }
2960
2973
  }
2961
2974
  ));
2962
2975
  SelectSeparatorBase.displayName = SelectPrimitive__namespace.Separator.displayName;
2976
+ var SelectEmpty = React33__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
2977
+ "div",
2978
+ {
2979
+ ref,
2980
+ className: cn(
2981
+ "w-full min-h-[3rem] flex items-center justify-center px-4 py-3 text-sm text-center",
2982
+ className
2983
+ ),
2984
+ ...props,
2985
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block w-full break-words hyphens-auto", children })
2986
+ }
2987
+ ));
2988
+ SelectEmpty.displayName = "SelectEmpty";
2989
+ SelectItemBase.displayName = SelectPrimitive__namespace.Item.displayName;
2963
2990
  var DropDownMenuBase = DropdownMenuPrimitive__namespace.Root;
2964
2991
  var DropDownMenuTriggerBase = DropdownMenuPrimitive__namespace.Trigger;
2965
2992
  var DropDownMenuGroupBase = DropdownMenuPrimitive__namespace.Group;
@@ -3220,36 +3247,45 @@ function ModeToggleBase({
3220
3247
  }, []);
3221
3248
  const isDark = mounted && (currentTheme?.includes("dark") || currentTheme === "system" && typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches);
3222
3249
  const toggleTheme = async (newTheme) => {
3223
- if (!buttonRef.current || !document.startViewTransition) {
3250
+ if (!buttonRef.current) {
3224
3251
  setTheme(newTheme);
3225
3252
  return;
3226
3253
  }
3227
- const rect = buttonRef.current.getBoundingClientRect();
3228
- const x = rect.left + rect.width / 2;
3229
- const y = rect.top + rect.height / 2;
3230
- const endRadius = Math.hypot(
3231
- Math.max(x, window.innerWidth - x),
3232
- Math.max(y, window.innerHeight - y)
3233
- );
3234
- const transition = document.startViewTransition(async () => {
3254
+ const supportsViewTransition = typeof document !== "undefined" && "startViewTransition" in document && typeof document.startViewTransition === "function";
3255
+ if (!supportsViewTransition) {
3235
3256
  setTheme(newTheme);
3236
- });
3237
- await transition.ready;
3238
- document.documentElement.animate(
3239
- [
3240
- {
3241
- clipPath: `circle(0px at ${x}px ${y}px)`
3242
- },
3257
+ return;
3258
+ }
3259
+ try {
3260
+ const rect = buttonRef.current.getBoundingClientRect();
3261
+ const x = rect.left + rect.width / 2;
3262
+ const y = rect.top + rect.height / 2;
3263
+ const endRadius = Math.hypot(
3264
+ Math.max(x, window.innerWidth - x),
3265
+ Math.max(y, window.innerHeight - y)
3266
+ );
3267
+ const transition = document.startViewTransition(async () => {
3268
+ setTheme(newTheme);
3269
+ });
3270
+ await transition.ready;
3271
+ document.documentElement.animate(
3272
+ [
3273
+ {
3274
+ clipPath: `circle(0px at ${x}px ${y}px)`
3275
+ },
3276
+ {
3277
+ clipPath: `circle(${Math.ceil(endRadius)}px at ${x}px ${y}px)`
3278
+ }
3279
+ ],
3243
3280
  {
3244
- clipPath: `circle(${Math.ceil(endRadius)}px at ${x}px ${y}px)`
3281
+ duration: 400,
3282
+ easing: "cubic-bezier(0.4, 0, 0.2, 1)",
3283
+ pseudoElement: "::view-transition-new(root)"
3245
3284
  }
3246
- ],
3247
- {
3248
- duration: 400,
3249
- easing: "cubic-bezier(0.4, 0, 0.2, 1)",
3250
- pseudoElement: "::view-transition-new(root)"
3251
- }
3252
- );
3285
+ );
3286
+ } catch {
3287
+ setTheme(newTheme);
3288
+ }
3253
3289
  };
3254
3290
  return /* @__PURE__ */ jsxRuntime.jsxs(DropDownMenuBase, { children: [
3255
3291
  /* @__PURE__ */ jsxRuntime.jsx(DropDownMenuTriggerBase, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3258,10 +3294,7 @@ function ModeToggleBase({
3258
3294
  ref: buttonRef,
3259
3295
  variant,
3260
3296
  size: "icon",
3261
- className: cn(
3262
- "relative overflow-hidden group",
3263
- className
3264
- ),
3297
+ className: cn("relative overflow-hidden group", className),
3265
3298
  children: [
3266
3299
  /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3267
3300
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -7646,117 +7679,68 @@ function useScrollColumn({
7646
7679
  }) {
7647
7680
  const containerRef = React33.useRef(null);
7648
7681
  const items = getItems(max, step);
7649
- const [isDragging, setIsDragging] = React33.useState(false);
7650
- const [startY, setStartY] = React33.useState(0);
7651
- const [scrollTop, setScrollTop] = React33.useState(0);
7652
7682
  const scrollTimeoutRef = React33.useRef(null);
7653
- const isTouchRef = React33.useRef(false);
7683
+ const isScrollingRef = React33.useRef(false);
7684
+ const [isDragging, setIsDragging] = React33.useState(false);
7685
+ const startYRef = React33.useRef(0);
7686
+ const startScrollRef = React33.useRef(0);
7654
7687
  const itemHeight = ITEM_HEIGHT;
7655
7688
  const centerIndex = CENTER_INDEX;
7656
7689
  const visibleItems = VISIBLE_ITEMS;
7657
7690
  const containerHeight = visibleItems * itemHeight;
7658
7691
  React33.useEffect(() => {
7659
- if (containerRef.current && !isDragging) {
7660
- requestAnimationFrame(() => {
7661
- if (containerRef.current) {
7662
- const index = Math.round(value / step);
7663
- const clampedIndex = Math.max(0, Math.min(items.length - 1, index));
7664
- const scrollPosition = clampedIndex * itemHeight;
7665
- containerRef.current.scrollTop = scrollPosition;
7666
- }
7667
- });
7692
+ if (containerRef.current && !isScrollingRef.current) {
7693
+ const index = Math.round(value / step);
7694
+ const clampedIndex = Math.max(0, Math.min(items.length - 1, index));
7695
+ const scrollPosition = clampedIndex * itemHeight;
7696
+ containerRef.current.scrollTop = scrollPosition;
7668
7697
  }
7669
- }, [value, isDragging, itemHeight, step, items.length]);
7698
+ }, [value, itemHeight, step, items.length]);
7670
7699
  React33.useEffect(() => {
7671
7700
  return () => {
7672
7701
  if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
7673
7702
  };
7674
7703
  }, []);
7675
- const handleScroll = (e) => {
7676
- e.stopPropagation();
7677
- e.preventDefault();
7678
- if (!containerRef.current || isDragging) return;
7704
+ const handleScroll = () => {
7705
+ if (!containerRef.current) return;
7706
+ isScrollingRef.current = true;
7679
7707
  if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
7680
7708
  scrollTimeoutRef.current = setTimeout(() => {
7681
7709
  if (!containerRef.current) return;
7682
7710
  const newIndex = Math.round(containerRef.current.scrollTop / itemHeight);
7683
7711
  const newValue = items[newIndex];
7684
- if (newValue !== void 0) {
7685
- containerRef.current.scrollTop = newIndex * itemHeight;
7686
- if (newValue !== value) onChange(newValue);
7712
+ if (newValue !== void 0 && newValue !== value) {
7713
+ onChange(newValue);
7687
7714
  }
7688
- }, 100);
7715
+ isScrollingRef.current = false;
7716
+ }, 150);
7689
7717
  };
7690
- const handleStart = (pageY) => {
7718
+ const handleMouseDown = (e) => {
7691
7719
  if (!containerRef.current) return;
7692
7720
  setIsDragging(true);
7693
- setStartY(pageY);
7694
- setScrollTop(containerRef.current.scrollTop);
7721
+ startYRef.current = e.clientY;
7722
+ startScrollRef.current = containerRef.current.scrollTop;
7723
+ e.preventDefault();
7695
7724
  };
7696
- const handleMove = (pageY) => {
7725
+ const handleMouseMove = (e) => {
7697
7726
  if (!isDragging || !containerRef.current) return;
7698
- const multiplier = isTouchRef.current ? 0.6 : 1;
7699
- containerRef.current.scrollTop = scrollTop + (startY - pageY) * multiplier;
7727
+ const deltaY = startYRef.current - e.clientY;
7728
+ containerRef.current.scrollTop = startScrollRef.current + deltaY;
7700
7729
  };
7701
- const handleEnd = () => {
7702
- if (!containerRef.current) return;
7730
+ const handleMouseUp = () => {
7703
7731
  setIsDragging(false);
7704
- requestAnimationFrame(() => {
7705
- if (!containerRef.current) return;
7706
- const newIndex = Math.round(containerRef.current.scrollTop / itemHeight);
7707
- const newValue = items[newIndex];
7708
- if (newValue !== void 0) {
7709
- containerRef.current.scrollTop = newIndex * itemHeight;
7710
- onChange(newValue);
7711
- }
7712
- });
7713
- };
7714
- const handlers = {
7715
- onScroll: handleScroll,
7716
- onWheel: (e) => e.stopPropagation(),
7717
- onMouseDown: (e) => {
7718
- isTouchRef.current = false;
7719
- handleStart(e.pageY);
7720
- },
7721
- onMouseMove: (e) => {
7722
- if (isDragging) {
7723
- e.preventDefault();
7724
- handleMove(e.pageY);
7725
- }
7726
- },
7727
- onMouseUp: () => handleEnd(),
7728
- onMouseLeave: () => {
7729
- if (isDragging) handleEnd();
7730
- },
7731
- onTouchStart: (e) => {
7732
- isTouchRef.current = true;
7733
- handleStart(e.touches[0].pageY);
7734
- },
7735
- onTouchMove: (e) => {
7736
- if (isDragging) {
7737
- if (e.cancelable) e.preventDefault();
7738
- handleMove(e.touches[0].pageY);
7739
- }
7740
- },
7741
- onTouchEnd: () => {
7742
- isTouchRef.current = false;
7743
- handleEnd();
7744
- }
7745
- };
7746
- const scrollToIndex = (index) => {
7747
- if (!containerRef.current) return;
7748
- const clamped = Math.max(0, Math.min(items.length - 1, index));
7749
- containerRef.current.scrollTop = clamped * itemHeight;
7750
7732
  };
7751
7733
  return {
7752
7734
  items,
7753
7735
  containerRef,
7754
- isDragging,
7755
7736
  itemHeight,
7756
7737
  containerHeight,
7757
7738
  centerIndex,
7758
- handlers,
7759
- scrollToIndex
7739
+ handleScroll,
7740
+ handleMouseDown,
7741
+ handleMouseMove,
7742
+ handleMouseUp,
7743
+ isDragging
7760
7744
  };
7761
7745
  }
7762
7746
  function ScrollColumn({
@@ -7769,57 +7753,68 @@ function ScrollColumn({
7769
7753
  const {
7770
7754
  items,
7771
7755
  containerRef,
7772
- isDragging,
7773
7756
  itemHeight,
7774
7757
  containerHeight,
7775
7758
  centerIndex,
7776
- handlers
7759
+ handleScroll,
7760
+ handleMouseDown,
7761
+ handleMouseMove,
7762
+ handleMouseUp,
7763
+ isDragging
7777
7764
  } = useScrollColumn({ value, onChange, max, step });
7778
7765
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
7779
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground rounded-md font-semibold text-sm sm:text-sm text-center pb-2 uppercase tracking-wider", children: label }),
7780
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative w-20 sm:w-16"), children: /* @__PURE__ */ jsxRuntime.jsx(
7781
- "div",
7782
- {
7783
- ref: containerRef,
7784
- className: "overflow-y-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none] touch-action-pan-y",
7785
- onScroll: handlers.onScroll,
7786
- onWheel: handlers.onWheel,
7787
- onMouseDown: handlers.onMouseDown,
7788
- onMouseMove: handlers.onMouseMove,
7789
- onMouseUp: handlers.onMouseUp,
7790
- onMouseLeave: handlers.onMouseLeave,
7791
- onTouchStart: handlers.onTouchStart,
7792
- onTouchMove: handlers.onTouchMove,
7793
- onTouchEnd: handlers.onTouchEnd,
7794
- style: {
7795
- height: `${containerHeight}px`,
7796
- paddingTop: `${centerIndex * itemHeight}px`,
7797
- paddingBottom: `${centerIndex * itemHeight}px`,
7798
- cursor: isDragging ? "grabbing" : ""
7799
- },
7800
- children: items.map((item, idx) => {
7801
- const isSelected = item === value;
7802
- return /* @__PURE__ */ jsxRuntime.jsx(
7803
- "div",
7804
- {
7805
- className: cn(
7806
- "flex items-center justify-center select-none font-semibold tabular-nums transition-all duration-150",
7807
- isDragging ? "cursor-grabbing" : "",
7808
- isSelected ? "text-lg sm:text-xl text-foreground scale-110" : "text-sm sm:text-base text-muted-foreground opacity-60"
7809
- ),
7810
- style: { height: `${itemHeight}px` },
7811
- onClick: () => {
7812
- if (isDragging || !containerRef.current) return;
7813
- containerRef.current.scrollTop = idx * itemHeight;
7814
- onChange(item);
7766
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground rounded-md font-semibold text-sm text-center pb-2 uppercase tracking-wider", children: label }),
7767
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative w-24 sm:w-20"), children: [
7768
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 left-0 right-0 h-16 bg-gradient-to-b from-background via-background/80 to-transparent pointer-events-none z-20" }),
7769
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 h-16 bg-gradient-to-t from-background via-background/80 to-transparent pointer-events-none z-20" }),
7770
+ /* @__PURE__ */ jsxRuntime.jsx(
7771
+ "div",
7772
+ {
7773
+ className: "absolute left-0 right-0 pointer-events-none bg-muted/50 backdrop-blur-sm rounded-md border border-border",
7774
+ style: {
7775
+ top: `${centerIndex * itemHeight}px`,
7776
+ height: `${itemHeight}px`
7777
+ }
7778
+ }
7779
+ ),
7780
+ /* @__PURE__ */ jsxRuntime.jsx(
7781
+ "div",
7782
+ {
7783
+ ref: containerRef,
7784
+ onScroll: handleScroll,
7785
+ onMouseDown: handleMouseDown,
7786
+ onMouseMove: handleMouseMove,
7787
+ onMouseUp: handleMouseUp,
7788
+ onMouseLeave: handleMouseUp,
7789
+ className: cn(
7790
+ "overflow-y-scroll snap-y snap-mandatory [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none] overscroll-contain",
7791
+ isDragging && "cursor-grabbing"
7792
+ ),
7793
+ style: {
7794
+ height: `${containerHeight}px`,
7795
+ paddingTop: `${centerIndex * itemHeight}px`,
7796
+ paddingBottom: `${centerIndex * itemHeight}px`,
7797
+ cursor: isDragging ? "grabbing" : "grab"
7798
+ },
7799
+ children: items.map((item, idx) => {
7800
+ const itemIndex = items.indexOf(value);
7801
+ const isCentered = idx === itemIndex;
7802
+ return /* @__PURE__ */ jsxRuntime.jsx(
7803
+ "div",
7804
+ {
7805
+ className: cn(
7806
+ "snap-center flex items-center justify-center select-none font-bold tabular-nums transition-all duration-200",
7807
+ isCentered ? "text-2xl sm:text-xl text-foreground scale-110" : "text-base sm:text-sm text-muted-foreground/60"
7808
+ ),
7809
+ style: { height: `${itemHeight}px` },
7810
+ children: item.toString().padStart(2, "0")
7815
7811
  },
7816
- children: item.toString().padStart(2, "0")
7817
- },
7818
- item
7819
- );
7820
- })
7821
- }
7822
- ) })
7812
+ item
7813
+ );
7814
+ })
7815
+ }
7816
+ )
7817
+ ] })
7823
7818
  ] });
7824
7819
  }
7825
7820
  function TimeScrollPicker({
@@ -7828,8 +7823,6 @@ function TimeScrollPicker({
7828
7823
  hideSeconds = false
7829
7824
  }) {
7830
7825
  const currentDate = date || /* @__PURE__ */ new Date();
7831
- const itemHeight = ITEM_HEIGHT;
7832
- const centerIndex = CENTER_INDEX;
7833
7826
  const handleTimeChange = (type, value) => {
7834
7827
  const newDate = new Date(currentDate);
7835
7828
  if (type === "hours") newDate.setHours(value);
@@ -7837,17 +7830,7 @@ function TimeScrollPicker({
7837
7830
  else newDate.setSeconds(value);
7838
7831
  setDate(newDate);
7839
7832
  };
7840
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center gap-2 p-1.5 sm:p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative flex gap-2 sm:gap-3"), children: [
7841
- /* @__PURE__ */ jsxRuntime.jsx(
7842
- "div",
7843
- {
7844
- className: "absolute left-0 right-0 pointer-events-none z-10 rounded-lg bg-primary/10 border border-primary/20",
7845
- style: {
7846
- top: `calc(1.85rem + ${centerIndex * itemHeight}px)`,
7847
- height: `${itemHeight}px`
7848
- }
7849
- }
7850
- ),
7833
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center gap-2 p-1.5 sm:p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex gap-2 sm:gap-3", children: [
7851
7834
  /* @__PURE__ */ jsxRuntime.jsx(
7852
7835
  ScrollColumn,
7853
7836
  {
@@ -7855,7 +7838,7 @@ function TimeScrollPicker({
7855
7838
  onChange: (v) => handleTimeChange("hours", v),
7856
7839
  max: 24,
7857
7840
  label: "Hora",
7858
- hideSeconds
7841
+ step: 1
7859
7842
  }
7860
7843
  ),
7861
7844
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -7865,8 +7848,7 @@ function TimeScrollPicker({
7865
7848
  onChange: (v) => handleTimeChange("minutes", v),
7866
7849
  max: 60,
7867
7850
  step: 5,
7868
- label: "Min",
7869
- hideSeconds
7851
+ label: "Min"
7870
7852
  }
7871
7853
  ),
7872
7854
  !hideSeconds && /* @__PURE__ */ jsxRuntime.jsx(
@@ -7876,7 +7858,7 @@ function TimeScrollPicker({
7876
7858
  onChange: (v) => handleTimeChange("seconds", v),
7877
7859
  max: 60,
7878
7860
  label: "Seg",
7879
- hideSeconds
7861
+ step: 1
7880
7862
  }
7881
7863
  )
7882
7864
  ] }) });
@@ -9897,7 +9879,7 @@ function Select({
9897
9879
  ]
9898
9880
  }
9899
9881
  ),
9900
- /* @__PURE__ */ jsxRuntime.jsx(ScrollAreaBase, { "data-testid": testIds.scrollarea ?? "select-scrollarea", children: /* @__PURE__ */ jsxRuntime.jsx(SelectContentBase, { "data-testid": testIds.content ?? "select-content", children: empty ? /* @__PURE__ */ jsxRuntime.jsx("div", { children: empty }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: pagination && pagination > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9882
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollAreaBase, { "data-testid": testIds.scrollarea ?? "select-scrollarea", children: /* @__PURE__ */ jsxRuntime.jsx(SelectContentBase, { "data-testid": testIds.content ?? "select-content", children: pagination && pagination > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9901
9883
  /* @__PURE__ */ jsxRuntime.jsx(
9902
9884
  "div",
9903
9885
  {
@@ -9972,7 +9954,7 @@ function Select({
9972
9954
  }
9973
9955
  )
9974
9956
  ] })
9975
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: groupItems ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Object.keys(groupItems).map((key) => /* @__PURE__ */ jsxRuntime.jsxs(
9957
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: groupItems ? Object.keys(groupItems).length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: Object.keys(groupItems).map((key) => /* @__PURE__ */ jsxRuntime.jsxs(
9976
9958
  SelectGroupBase,
9977
9959
  {
9978
9960
  "data-testid": testIds.group ?? "select-group",
@@ -9996,7 +9978,7 @@ function Select({
9996
9978
  ]
9997
9979
  },
9998
9980
  key
9999
- )) }) : /* @__PURE__ */ jsxRuntime.jsx(
9981
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx(SelectEmpty, { "data-testid": testIds.empty ?? "select-empty", children: empty ?? "Nenhum item dispon\xEDvel" }) : items && items.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
10000
9982
  SelectGroupBase,
10001
9983
  {
10002
9984
  "data-testid": testIds.group ?? "select-group",
@@ -10010,7 +9992,7 @@ function Select({
10010
9992
  item.value
10011
9993
  ))
10012
9994
  }
10013
- ) }) }) }) })
9995
+ ) : /* @__PURE__ */ jsxRuntime.jsx(SelectEmpty, { "data-testid": testIds.empty ?? "select-empty", children: empty ?? "Nenhum item dispon\xEDvel" }) }) }) })
10014
9996
  ]
10015
9997
  }
10016
9998
  ),
@@ -14848,6 +14830,24 @@ var DraggableTooltipComponent = ({
14848
14830
  if (onPositionChange) onPositionChange(id, snapped);
14849
14831
  });
14850
14832
  };
14833
+ const handleTouchMove = (e) => {
14834
+ if (!dragging || !e.touches[0]) return;
14835
+ e.preventDefault();
14836
+ lastMouse.current = { x: e.touches[0].clientX, y: e.touches[0].clientY };
14837
+ if (rafId) cancelAnimationFrame(rafId);
14838
+ rafId = requestAnimationFrame(() => {
14839
+ const newLeft = lastMouse.current.x - offsetRef.current.x;
14840
+ const newTop = lastMouse.current.y - offsetRef.current.y;
14841
+ const rawPosition = {
14842
+ top: Math.max(0, Math.min(newTop, window.innerHeight - 200)),
14843
+ left: Math.max(0, Math.min(newLeft, window.innerWidth - 250))
14844
+ };
14845
+ updateAlignmentGuides(rawPosition);
14846
+ const snapped = snapToGuides(rawPosition);
14847
+ setLocalPos(snapped);
14848
+ if (onPositionChange) onPositionChange(id, snapped);
14849
+ });
14850
+ };
14851
14851
  const handleMouseUp = () => {
14852
14852
  if (dragging) {
14853
14853
  setDragging(false);
@@ -14855,11 +14855,23 @@ var DraggableTooltipComponent = ({
14855
14855
  if (rafId) cancelAnimationFrame(rafId);
14856
14856
  }
14857
14857
  };
14858
+ const handleTouchEnd = () => {
14859
+ if (dragging) {
14860
+ setDragging(false);
14861
+ setAlignmentGuides([]);
14862
+ if (rafId) cancelAnimationFrame(rafId);
14863
+ }
14864
+ };
14858
14865
  if (dragging) {
14859
14866
  document.addEventListener("mousemove", handleMouseMove, {
14860
14867
  passive: true
14861
14868
  });
14862
14869
  document.addEventListener("mouseup", handleMouseUp);
14870
+ document.addEventListener("touchmove", handleTouchMove, {
14871
+ passive: false
14872
+ // Permite preventDefault para evitar scroll
14873
+ });
14874
+ document.addEventListener("touchend", handleTouchEnd);
14863
14875
  document.body.style.cursor = "grabbing";
14864
14876
  document.body.style.userSelect = "none";
14865
14877
  }
@@ -14867,6 +14879,8 @@ var DraggableTooltipComponent = ({
14867
14879
  if (rafId) cancelAnimationFrame(rafId);
14868
14880
  document.removeEventListener("mousemove", handleMouseMove);
14869
14881
  document.removeEventListener("mouseup", handleMouseUp);
14882
+ document.removeEventListener("touchmove", handleTouchMove);
14883
+ document.removeEventListener("touchend", handleTouchEnd);
14870
14884
  document.body.style.cursor = "";
14871
14885
  document.body.style.userSelect = "";
14872
14886
  };
@@ -14951,6 +14965,7 @@ var DraggableTooltipComponent = ({
14951
14965
  );
14952
14966
  const handleTouchStartLocal = React33.useCallback(
14953
14967
  (e) => {
14968
+ e.preventDefault();
14954
14969
  e.stopPropagation();
14955
14970
  const touch = e.touches[0];
14956
14971
  if (!touch) return;
@@ -17023,13 +17038,13 @@ var Chart = ({
17023
17038
  "div",
17024
17039
  {
17025
17040
  ref: wrapperRef,
17026
- className: cn("w-full overflow-hidden min-w-0 rounded-lg", className),
17027
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-card relative w-full max-w-full min-w-0", children: [
17041
+ className: cn("w-full overflow-hidden min-w-0 rounded-lg border-border", className),
17042
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-card relative w-full max-w-full min-w-0 py-1", children: [
17028
17043
  title && /* @__PURE__ */ jsxRuntime.jsx(
17029
17044
  "div",
17030
17045
  {
17031
17046
  className: cn(
17032
- "w-full flex items-center mt-5 mb-2",
17047
+ "w-full flex items-center mt-3 mb-2",
17033
17048
  HORIZONTAL_PADDING_CLASS,
17034
17049
  titlePosition === "center" && "justify-center",
17035
17050
  titlePosition === "right" && "justify-end",
@@ -17479,1284 +17494,59 @@ var Chart = ({
17479
17494
  );
17480
17495
  };
17481
17496
  var Chart_default = Chart;
17482
- var DEFAULT_COLORS3 = ["#55af7d", "#8e68ff", "#2273e1"];
17483
- var BarChart = ({
17484
- data,
17485
- className,
17486
- height = 350,
17487
- width = 900,
17488
- colors: colors2 = DEFAULT_COLORS3,
17489
- gridColor,
17490
- showGrid = true,
17491
- showTooltip = true,
17492
- showLegend = true,
17493
- title,
17494
- titlePosition = "left",
17495
- showLabels = false,
17496
- xAxis,
17497
- mapper,
17498
- yAxis,
17499
- labelMap,
17500
- autoDetect = false,
17501
- padding,
17502
- margins,
17503
- containerPaddingLeft,
17504
- chartMargins
17497
+ var defaultData = [
17498
+ { name: "Vendas", value: 4e3 },
17499
+ { name: "Marketing", value: 3e3 },
17500
+ { name: "Desenvolvimento", value: 2e3 },
17501
+ { name: "Suporte", value: 1e3 },
17502
+ { name: "Outros", value: 800 }
17503
+ ];
17504
+ var DEFAULT_COLORS3 = [
17505
+ "#55af7d",
17506
+ // verde do projeto
17507
+ "#8e68ff",
17508
+ // roxo do projeto
17509
+ "#2273e1",
17510
+ // azul do projeto
17511
+ "#f59e0b",
17512
+ // amarelo complementar
17513
+ "#ef4444",
17514
+ // vermelho complementar
17515
+ "#8b5cf6",
17516
+ // roxo claro
17517
+ "#06b6d4",
17518
+ // ciano
17519
+ "#84cc16"
17520
+ // verde lima
17521
+ ];
17522
+ var RADIAN = Math.PI / 180;
17523
+ var renderCustomizedLabel = ({
17524
+ cx = 0,
17525
+ cy = 0,
17526
+ midAngle = 0,
17527
+ innerRadius = 0,
17528
+ outerRadius = 0,
17529
+ percent = 0
17505
17530
  }) => {
17506
- const resolvedContainerPaddingLeft = resolveContainerPaddingLeft(
17507
- padding,
17508
- containerPaddingLeft,
17509
- 16
17510
- );
17511
- const smartConfig = React33.useMemo(() => {
17512
- const providedMapper = yAxis ?? mapper;
17513
- if (autoDetect === true || xAxis == null || providedMapper == null) {
17514
- const detectedXAxis = detectXAxis(data);
17515
- const detectedFields = detectDataFields(data, detectedXAxis);
17516
- return {
17517
- xAxisConfig: {
17518
- dataKey: detectedXAxis,
17519
- label: labelMap?.[detectedXAxis] ?? formatFieldName(detectedXAxis),
17520
- autoLabel: true
17521
- },
17522
- mapperConfig: detectedFields.reduce((acc, field) => {
17523
- acc[field] = {
17524
- label: labelMap?.[field] ?? formatFieldName(field),
17525
- type: "number",
17526
- visible: true
17527
- };
17528
- return acc;
17529
- }, {})
17530
- };
17531
- }
17532
- const xAxisConfig2 = typeof xAxis === "string" ? { dataKey: xAxis, label: formatFieldName(xAxis), autoLabel: true } : xAxis;
17533
- let mapperConfig2;
17534
- if (Array.isArray(providedMapper)) {
17535
- mapperConfig2 = providedMapper.reduce((acc, field) => {
17536
- acc[field] = {
17537
- label: labelMap?.[field] ?? formatFieldName(field),
17538
- type: "auto",
17539
- visible: true
17540
- };
17541
- return acc;
17542
- }, {});
17543
- } else {
17544
- mapperConfig2 = Object.keys(providedMapper).reduce(
17545
- (acc, key) => {
17546
- acc[key] = {
17547
- label: providedMapper[key]?.label ?? labelMap?.[key] ?? formatFieldName(key),
17548
- type: "auto",
17549
- visible: true,
17550
- ...providedMapper[key]
17551
- // Sobrescreve com configurações do usuário
17552
- };
17553
- return acc;
17554
- },
17555
- {}
17556
- );
17557
- }
17558
- return { xAxisConfig: xAxisConfig2, mapperConfig: mapperConfig2 };
17559
- }, [data, xAxis, mapper, yAxis, autoDetect, labelMap]);
17560
- const { xAxisConfig, mapperConfig } = smartConfig;
17561
- const [activeTooltips, setActiveTooltips] = React33.useState([]);
17562
- const [isDragging, setIsDragging] = React33.useState(null);
17563
- const [dragOffset, setDragOffset] = React33.useState({
17564
- x: 0,
17565
- y: 0
17566
- });
17567
- const [globalTooltipCount, setGlobalTooltipCount] = React33.useState(0);
17568
- const [alignmentGuides, setAlignmentGuides] = React33.useState([]);
17569
- const processedData = data.map((item) => ({
17570
- ...item,
17571
- name: String(item[xAxisConfig.dataKey] || "N/A")
17572
- // Garantir propriedade 'name' para tooltip
17573
- }));
17574
- const generateColors = (dataKeys2) => {
17575
- const colorMap = {};
17576
- const allColors = generateAdditionalColors(colors2, dataKeys2.length);
17577
- dataKeys2.forEach((key, index) => {
17578
- colorMap[key] = allColors[index] || colors2[index % colors2.length];
17579
- });
17580
- return colorMap;
17581
- };
17582
- const dataKeys = Object.keys(mapperConfig);
17583
- const finalColors = generateColors(dataKeys);
17584
- const adaptDataForTooltip2 = (universalData) => {
17585
- return {
17586
- ...universalData,
17587
- name: String(universalData[xAxisConfig.dataKey] || "N/A")
17588
- // Garantir que tem a propriedade 'name'
17589
- };
17590
- };
17591
- const maxDataValue = React33.useMemo(() => {
17592
- let max = 0;
17593
- const keys = Object.keys(mapperConfig);
17594
- for (const row of processedData) {
17595
- const r = row;
17596
- for (const key of keys) {
17597
- const v = r[key];
17598
- if (typeof v === "number" && Number.isFinite(v) && v > max)
17599
- max = v;
17600
- }
17601
- }
17602
- return max;
17603
- }, [processedData, mapperConfig]);
17604
- const niceMax = React33.useMemo(() => {
17605
- let padding2 = 0.08;
17606
- if (maxDataValue > 1e6) padding2 = 0.05;
17607
- if (maxDataValue > 1e7) padding2 = 0.03;
17608
- if (maxDataValue === 0) padding2 = 0.12;
17609
- const padded = maxDataValue * (1 + padding2);
17610
- return niceCeil(padded);
17611
- }, [maxDataValue]);
17612
- const handleBarClick = (data2, index, event) => {
17613
- event.stopPropagation();
17614
- const xAxisValue = data2[xAxisConfig.dataKey] || "N/A";
17615
- const tooltipId = `${xAxisValue}`;
17616
- const rect = event.target.getBoundingClientRect();
17617
- const existingIndex = activeTooltips.findIndex(
17618
- (tooltip) => tooltip.id === tooltipId
17619
- );
17620
- if (existingIndex !== -1) {
17621
- setActiveTooltips(
17622
- (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
17623
- );
17624
- } else {
17625
- const newTooltip = {
17626
- id: tooltipId,
17627
- data: data2,
17628
- position: {
17629
- top: rect.top - 10,
17630
- // Posição fixa da viewport
17631
- left: rect.right + 10
17632
- // À direita da barra clicada
17633
- }
17634
- };
17635
- setActiveTooltips((prev) => [...prev, newTooltip]);
17636
- }
17637
- };
17638
- const handleChartClick = () => {
17639
- setActiveTooltips([]);
17640
- };
17641
- const ALIGNMENT_THRESHOLD2 = 25;
17642
- const GUIDE_THRESHOLD2 = 60;
17643
- const STRONG_SNAP_THRESHOLD2 = 35;
17644
- const PRECISION_SNAP_THRESHOLD2 = 8;
17645
- const updateAlignmentGuides = React33.useCallback(
17646
- (draggedTooltipId, currentPosition) => {
17647
- if (!isDragging) return;
17648
- const getAllTooltips = () => {
17649
- const allTooltips2 = [];
17650
- allTooltips2.push(...activeTooltips);
17651
- const globalEvent = new CustomEvent("requestGlobalTooltips", {
17652
- detail: { requesterId: draggedTooltipId, response: allTooltips2 }
17653
- });
17654
- window.dispatchEvent(globalEvent);
17655
- return allTooltips2;
17656
- };
17657
- const allTooltips = getAllTooltips();
17658
- const otherTooltips = allTooltips.filter(
17659
- (t) => t.id !== draggedTooltipId
17660
- );
17661
- const guides = [];
17662
- const tooltipDimensions = { width: 224, height: 120 };
17663
- otherTooltips.forEach((tooltip) => {
17664
- const topDiff = Math.abs(currentPosition.top - tooltip.position.top);
17665
- if (topDiff <= GUIDE_THRESHOLD2) {
17666
- guides.push({
17667
- type: "horizontal",
17668
- position: tooltip.position.top,
17669
- visible: true,
17670
- sourceTooltip: {
17671
- top: currentPosition.top,
17672
- left: currentPosition.left,
17673
- width: tooltipDimensions.width,
17674
- height: tooltipDimensions.height
17675
- },
17676
- targetTooltip: {
17677
- top: tooltip.position.top,
17678
- left: tooltip.position.left,
17679
- width: tooltipDimensions.width,
17680
- height: tooltipDimensions.height
17681
- }
17682
- });
17683
- }
17684
- const leftDiff = Math.abs(currentPosition.left - tooltip.position.left);
17685
- if (leftDiff <= GUIDE_THRESHOLD2) {
17686
- guides.push({
17687
- type: "vertical",
17688
- position: tooltip.position.left,
17689
- visible: true,
17690
- sourceTooltip: {
17691
- top: currentPosition.top,
17692
- left: currentPosition.left,
17693
- width: tooltipDimensions.width,
17694
- height: tooltipDimensions.height
17695
- },
17696
- targetTooltip: {
17697
- top: tooltip.position.top,
17698
- left: tooltip.position.left,
17699
- width: tooltipDimensions.width,
17700
- height: tooltipDimensions.height
17701
- }
17702
- });
17703
- }
17704
- });
17705
- setAlignmentGuides(guides);
17706
- },
17707
- [isDragging, activeTooltips]
17708
- );
17709
- const snapToGuides = React33.useCallback(
17710
- (position) => {
17711
- const snappedPosition = { ...position };
17712
- let hasSnapped = false;
17713
- alignmentGuides.forEach((guide) => {
17714
- if (guide.type === "horizontal") {
17715
- const diff = Math.abs(position.top - guide.position);
17716
- if (diff <= PRECISION_SNAP_THRESHOLD2) {
17717
- snappedPosition.top = guide.position;
17718
- hasSnapped = true;
17719
- }
17720
- } else if (guide.type === "vertical") {
17721
- const diff = Math.abs(position.left - guide.position);
17722
- if (diff <= PRECISION_SNAP_THRESHOLD2) {
17723
- snappedPosition.left = guide.position;
17724
- hasSnapped = true;
17725
- }
17726
- }
17727
- });
17728
- if (!hasSnapped) {
17729
- alignmentGuides.forEach((guide) => {
17730
- if (guide.type === "horizontal") {
17731
- const diff = Math.abs(position.top - guide.position);
17732
- if (diff <= STRONG_SNAP_THRESHOLD2) {
17733
- snappedPosition.top = guide.position;
17734
- }
17735
- } else if (guide.type === "vertical") {
17736
- const diff = Math.abs(position.left - guide.position);
17737
- if (diff <= STRONG_SNAP_THRESHOLD2) {
17738
- snappedPosition.left = guide.position;
17739
- }
17740
- }
17741
- });
17742
- }
17743
- alignmentGuides.forEach((guide) => {
17744
- if (guide.type === "horizontal") {
17745
- const diff = Math.abs(position.top - guide.position);
17746
- if (diff <= ALIGNMENT_THRESHOLD2 && snappedPosition.top === position.top) {
17747
- snappedPosition.top = guide.position;
17748
- }
17749
- } else if (guide.type === "vertical") {
17750
- const diff = Math.abs(position.left - guide.position);
17751
- if (diff <= ALIGNMENT_THRESHOLD2 && snappedPosition.left === position.left) {
17752
- snappedPosition.left = guide.position;
17753
- }
17754
- }
17755
- });
17756
- return snappedPosition;
17757
- },
17758
- [alignmentGuides]
17759
- );
17760
- const handleMouseDown = (e, tooltipId) => {
17761
- e.preventDefault();
17762
- e.stopPropagation();
17763
- const tooltip = activeTooltips.find((t) => t.id === tooltipId);
17764
- if (!tooltip) return;
17765
- const rect = e.currentTarget.getBoundingClientRect();
17766
- const offsetX = e.clientX - rect.left;
17767
- const offsetY = e.clientY - rect.top;
17768
- setIsDragging(tooltipId);
17769
- setDragOffset({ x: offsetX, y: offsetY });
17770
- };
17771
- React33.useEffect(() => {
17772
- let rafId;
17773
- let lastMousePosition = { x: 0, y: 0 };
17774
- const handleGlobalMouseMove = (e) => {
17775
- if (!isDragging) return;
17776
- lastMousePosition = { x: e.clientX, y: e.clientY };
17777
- if (rafId) cancelAnimationFrame(rafId);
17778
- rafId = requestAnimationFrame(() => {
17779
- const newLeft = lastMousePosition.x - dragOffset.x;
17780
- const newTop = lastMousePosition.y - dragOffset.y;
17781
- const rawPosition = {
17782
- top: Math.max(0, Math.min(newTop, window.innerHeight - 200)),
17783
- left: Math.max(0, Math.min(newLeft, window.innerWidth - 250))
17784
- };
17785
- updateAlignmentGuides(isDragging, rawPosition);
17786
- const snappedPosition = snapToGuides(rawPosition);
17787
- setActiveTooltips(
17788
- (prev) => prev.map((tooltip) => {
17789
- if (tooltip.id === isDragging) {
17790
- return {
17791
- ...tooltip,
17792
- position: snappedPosition
17793
- };
17794
- }
17795
- return tooltip;
17796
- })
17797
- );
17798
- });
17799
- };
17800
- const handleGlobalMouseUp = () => {
17801
- if (isDragging) {
17802
- setIsDragging(null);
17803
- setAlignmentGuides([]);
17804
- if (rafId) cancelAnimationFrame(rafId);
17805
- }
17806
- };
17807
- if (isDragging) {
17808
- document.addEventListener("mousemove", handleGlobalMouseMove, {
17809
- passive: true
17810
- });
17811
- document.addEventListener("mouseup", handleGlobalMouseUp);
17812
- document.body.style.cursor = "grabbing";
17813
- document.body.style.userSelect = "none";
17814
- }
17815
- return () => {
17816
- if (rafId) cancelAnimationFrame(rafId);
17817
- document.removeEventListener("mousemove", handleGlobalMouseMove);
17818
- document.removeEventListener("mouseup", handleGlobalMouseUp);
17819
- document.body.style.cursor = "";
17820
- document.body.style.userSelect = "";
17821
- };
17822
- }, [
17823
- isDragging,
17824
- dragOffset,
17825
- alignmentGuides,
17826
- updateAlignmentGuides,
17827
- snapToGuides
17828
- ]);
17829
- React33.useEffect(() => {
17830
- const handleCloseAllTooltips = () => {
17831
- setActiveTooltips([]);
17832
- setGlobalTooltipCount(0);
17833
- };
17834
- window.addEventListener("closeAllTooltips", handleCloseAllTooltips);
17835
- return () => {
17836
- window.removeEventListener("closeAllTooltips", handleCloseAllTooltips);
17837
- };
17838
- }, []);
17839
- React33.useEffect(() => {
17840
- const handleTooltipCountRequest = () => {
17841
- window.dispatchEvent(
17842
- new CustomEvent("tooltipCountResponse", {
17843
- detail: { count: activeTooltips.length }
17844
- })
17845
- );
17846
- };
17847
- const handleGlobalTooltipsRequest = (event) => {
17848
- const { detail } = event;
17849
- if (detail && detail.response && detail.requesterId) {
17850
- activeTooltips.forEach((tooltip) => {
17851
- if (!detail.response.find(
17852
- (t) => t.id === tooltip.id
17853
- )) {
17854
- detail.response.push({
17855
- id: tooltip.id,
17856
- position: tooltip.position
17857
- });
17858
- }
17859
- });
17860
- }
17861
- };
17862
- window.addEventListener("requestTooltipCount", handleTooltipCountRequest);
17863
- window.addEventListener(
17864
- "requestGlobalTooltips",
17865
- handleGlobalTooltipsRequest
17866
- );
17867
- return () => {
17868
- window.removeEventListener(
17869
- "requestTooltipCount",
17870
- handleTooltipCountRequest
17871
- );
17872
- window.removeEventListener(
17873
- "requestGlobalTooltips",
17874
- handleGlobalTooltipsRequest
17875
- );
17876
- };
17877
- }, [activeTooltips]);
17878
- React33.useEffect(() => {
17879
- if (isDragging) return;
17880
- let totalCount = 0;
17881
- const handleCountResponse = (event) => {
17882
- const customEvent = event;
17883
- totalCount += customEvent.detail.count;
17884
- };
17885
- window.addEventListener("tooltipCountResponse", handleCountResponse);
17886
- window.dispatchEvent(new CustomEvent("requestTooltipCount"));
17887
- const timeoutId = setTimeout(() => {
17888
- window.removeEventListener("tooltipCountResponse", handleCountResponse);
17889
- setGlobalTooltipCount(totalCount);
17890
- }, 5);
17891
- return () => {
17892
- clearTimeout(timeoutId);
17893
- window.removeEventListener("tooltipCountResponse", handleCountResponse);
17894
- };
17895
- }, [activeTooltips.length, isDragging]);
17896
- const CustomTooltip = ({
17897
- active,
17898
- payload,
17899
- label
17900
- }) => {
17901
- if (!active || !payload) return null;
17902
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-card border border-border rounded-lg p-3 shadow-lg", children: [
17903
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium text-foreground mb-2", children: label }),
17904
- payload.map(
17905
- (entry, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
17906
- /* @__PURE__ */ jsxRuntime.jsx(
17907
- "div",
17908
- {
17909
- className: "w-3 h-3 rounded-sm",
17910
- style: { backgroundColor: entry.color }
17911
- }
17912
- ),
17913
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
17914
- entry.name,
17915
- ":"
17916
- ] }),
17917
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium", children: entry.value?.toLocaleString("pt-BR") })
17918
- ] }, index)
17919
- ),
17920
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Clique para fixar este tooltip" })
17921
- ] });
17922
- };
17923
- const getTitleClassName = (position) => {
17924
- const baseClasses = "text-xl font-semibold text-foreground mb-3";
17925
- switch (position) {
17926
- case "center":
17927
- return `${baseClasses} text-center`;
17928
- case "right":
17929
- return `${baseClasses} text-right`;
17930
- default:
17931
- return `${baseClasses} text-left`;
17932
- }
17933
- };
17934
- return /* @__PURE__ */ jsxRuntime.jsxs(
17935
- "div",
17936
- {
17937
- className: cn("rounded-lg bg-card p-4 relative", className),
17938
- style: {
17939
- width: typeof width === "number" ? `${width + 32}px` : "fit-content",
17940
- maxWidth: "100%"
17941
- },
17942
- children: [
17943
- title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: `${resolvedContainerPaddingLeft}px` }, children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: getTitleClassName(titlePosition), children: title }) }),
17944
- /* @__PURE__ */ jsxRuntime.jsxs(
17945
- recharts.BarChart,
17946
- {
17947
- data: processedData,
17948
- width: typeof width === "number" ? width : 900,
17949
- height,
17950
- margin: resolveChartMargins(margins, chartMargins, showLabels),
17951
- onClick: handleChartClick,
17952
- children: [
17953
- showGrid && /* @__PURE__ */ jsxRuntime.jsx(
17954
- recharts.CartesianGrid,
17955
- {
17956
- strokeDasharray: "3 3",
17957
- stroke: gridColor || "hsl(var(--muted-foreground))",
17958
- opacity: 0.5
17959
- }
17960
- ),
17961
- /* @__PURE__ */ jsxRuntime.jsx(
17962
- recharts.XAxis,
17963
- {
17964
- dataKey: xAxisConfig.dataKey,
17965
- stroke: "hsl(var(--muted-foreground))",
17966
- fontSize: 12,
17967
- tickLine: false,
17968
- axisLine: false,
17969
- tickFormatter: xAxisConfig.valueFormatter
17970
- }
17971
- ),
17972
- /* @__PURE__ */ jsxRuntime.jsx(
17973
- recharts.YAxis,
17974
- {
17975
- stroke: "hsl(var(--muted-foreground))",
17976
- fontSize: 12,
17977
- tickLine: false,
17978
- axisLine: false,
17979
- tickFormatter: (value) => value.toLocaleString("pt-BR"),
17980
- domain: [0, niceMax],
17981
- tickCount: 6
17982
- }
17983
- ),
17984
- showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
17985
- recharts.Tooltip,
17986
- {
17987
- content: /* @__PURE__ */ jsxRuntime.jsx(CustomTooltip, {}),
17988
- cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
17989
- }
17990
- ),
17991
- showLegend && /* @__PURE__ */ jsxRuntime.jsx(
17992
- recharts.Legend,
17993
- {
17994
- wrapperStyle: {
17995
- color: "hsl(var(--foreground))",
17996
- fontSize: "14px"
17997
- }
17998
- }
17999
- ),
18000
- dataKeys.map((key) => {
18001
- const fieldConfig = mapperConfig[key];
18002
- return /* @__PURE__ */ jsxRuntime.jsx(
18003
- recharts.Bar,
18004
- {
18005
- dataKey: key,
18006
- name: fieldConfig?.label || key,
18007
- fill: fieldConfig?.color || finalColors[key],
18008
- radius: [4, 4, 0, 0],
18009
- onClick: handleBarClick,
18010
- style: { cursor: "pointer" },
18011
- activeBar: /* @__PURE__ */ jsxRuntime.jsx(
18012
- recharts.Rectangle,
18013
- {
18014
- fill: finalColors[key],
18015
- stroke: finalColors[key],
18016
- strokeWidth: 2,
18017
- opacity: 0.8
18018
- }
18019
- ),
18020
- children: showLabels && /* @__PURE__ */ jsxRuntime.jsx(
18021
- recharts.LabelList,
18022
- {
18023
- dataKey: key,
18024
- position: "top",
18025
- content: pillLabelRenderer_default(
18026
- finalColors[key] || "#000",
18027
- "filled"
18028
- )
18029
- }
18030
- )
18031
- },
18032
- key
18033
- );
18034
- })
18035
- ]
18036
- }
18037
- ),
18038
- alignmentGuides.map((guide, index) => {
18039
- const isHorizontal = guide.type === "horizontal";
18040
- const color = isHorizontal ? "#3b82f6" : "#ef4444";
18041
- const startX = isHorizontal ? Math.min(
18042
- guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
18043
- guide.targetTooltip.left + guide.targetTooltip.width / 2
18044
- ) : guide.sourceTooltip.left + (isHorizontal ? 0 : guide.sourceTooltip.width / 2);
18045
- const endX = isHorizontal ? Math.max(
18046
- guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
18047
- guide.targetTooltip.left + guide.targetTooltip.width / 2
18048
- ) : guide.targetTooltip.left + (isHorizontal ? 0 : guide.targetTooltip.width / 2);
18049
- const startY = isHorizontal ? guide.sourceTooltip.top + (isHorizontal ? guide.sourceTooltip.height / 2 : 0) : Math.min(
18050
- guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
18051
- guide.targetTooltip.top + guide.targetTooltip.height / 2
18052
- );
18053
- const endY = isHorizontal ? guide.targetTooltip.top + (isHorizontal ? guide.targetTooltip.height / 2 : 0) : Math.max(
18054
- guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
18055
- guide.targetTooltip.top + guide.targetTooltip.height / 2
18056
- );
18057
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
18058
- /* @__PURE__ */ jsxRuntime.jsx(
18059
- "div",
18060
- {
18061
- className: "fixed pointer-events-none z-30",
18062
- style: {
18063
- left: startX,
18064
- top: startY,
18065
- width: isHorizontal ? endX - startX : "2px",
18066
- height: isHorizontal ? "2px" : endY - startY,
18067
- backgroundColor: color,
18068
- boxShadow: `0 0 8px ${color}60`,
18069
- opacity: 0.9,
18070
- borderStyle: "dashed",
18071
- borderWidth: "1px",
18072
- borderColor: color,
18073
- transform: "translateZ(0)"
18074
- }
18075
- }
18076
- ),
18077
- /* @__PURE__ */ jsxRuntime.jsx(
18078
- "div",
18079
- {
18080
- className: "fixed pointer-events-none z-31",
18081
- style: {
18082
- left: guide.sourceTooltip.left + guide.sourceTooltip.width / 2 - 4,
18083
- top: guide.sourceTooltip.top + guide.sourceTooltip.height / 2 - 4,
18084
- width: "8px",
18085
- height: "8px",
18086
- backgroundColor: color,
18087
- borderRadius: "50%",
18088
- boxShadow: `0 0 4px ${color}80`,
18089
- opacity: 0.8
18090
- }
18091
- }
18092
- ),
18093
- /* @__PURE__ */ jsxRuntime.jsx(
18094
- "div",
18095
- {
18096
- className: "fixed pointer-events-none z-31",
18097
- style: {
18098
- left: guide.targetTooltip.left + guide.targetTooltip.width / 2 - 4,
18099
- top: guide.targetTooltip.top + guide.targetTooltip.height / 2 - 4,
18100
- width: "8px",
18101
- height: "8px",
18102
- backgroundColor: color,
18103
- borderRadius: "50%",
18104
- boxShadow: `0 0 4px ${color}80`,
18105
- opacity: 0.8
18106
- }
18107
- }
18108
- )
18109
- ] }, index);
18110
- }),
18111
- activeTooltips.map((tooltip, index) => /* @__PURE__ */ jsxRuntime.jsx(
18112
- DraggableTooltip_default,
18113
- {
18114
- id: tooltip.id,
18115
- data: adaptDataForTooltip2(tooltip.data),
18116
- position: tooltip.position,
18117
- isDragging: isDragging === tooltip.id,
18118
- title,
18119
- dataKeys,
18120
- finalColors,
18121
- onMouseDown: (id, e) => handleMouseDown(e, id),
18122
- onClose: (id) => {
18123
- setActiveTooltips((prev) => prev.filter((t) => t.id !== id));
18124
- },
18125
- periodLabel: "Per\xEDodo Selecionado",
18126
- dataLabel: "Dados do Per\xEDodo",
18127
- showCloseAllButton: index === 0,
18128
- globalTooltipCount,
18129
- onCloseAll: () => {
18130
- window.dispatchEvent(new Event("closeAllTooltips"));
18131
- },
18132
- closeAllButtonPosition: "top-center",
18133
- closeAllButtonVariant: "floating"
18134
- },
18135
- tooltip.id
18136
- ))
18137
- ]
18138
- }
18139
- );
18140
- };
18141
- var BarChart_default = BarChart;
18142
- var defaultData = [
18143
- { name: "A", value: 100 },
18144
- { name: "B", value: 200 },
18145
- { name: "C", value: 150 }
18146
- ];
18147
- var DEFAULT_COLORS4 = ["#55af7d", "#8e68ff", "#2273e1"];
18148
- var CustomLineChart = ({
18149
- data = defaultData,
18150
- className,
18151
- height = 300,
18152
- width = "100%",
18153
- colors: colors2 = DEFAULT_COLORS4,
18154
- gridColor,
18155
- showGrid = true,
18156
- showTooltip = true,
18157
- showLegend = true,
18158
- title,
18159
- titlePosition = "left",
18160
- strokeWidth = 2,
18161
- showDots = true,
18162
- showLabels = false,
18163
- padding,
18164
- margins,
18165
- containerPaddingLeft,
18166
- chartMargins
18167
- }) => {
18168
- const resolvedContainerPaddingLeft = resolveContainerPaddingLeft(
18169
- padding,
18170
- containerPaddingLeft,
18171
- 16
18172
- );
18173
- const [activeTooltips, setActiveTooltips] = React33.useState([]);
18174
- const [isDragging, setIsDragging] = React33.useState(null);
18175
- const [dragOffset, setDragOffset] = React33.useState({
18176
- x: 0,
18177
- y: 0
18178
- });
18179
- const [globalTooltipCount, setGlobalTooltipCount] = React33.useState(0);
18180
- const [alignmentGuides, setAlignmentGuides] = React33.useState([]);
18181
- const generateColors = (dataKeys2) => {
18182
- const colorMap = {};
18183
- const allColors = generateAdditionalColors(colors2, dataKeys2.length);
18184
- dataKeys2.forEach((key, index) => {
18185
- colorMap[key] = allColors[index] || colors2[index % colors2.length];
18186
- });
18187
- return colorMap;
18188
- };
18189
- const dataKeys = React33.useMemo(
18190
- () => data.length > 0 ? Object.keys(data[0]).filter((key) => key !== "name") : [],
18191
- [data]
18192
- );
18193
- const finalColors = generateColors(dataKeys);
18194
- const maxDataValue = React33.useMemo(() => {
18195
- let max = 0;
18196
- for (const row of data) {
18197
- const r = row;
18198
- for (const key of dataKeys) {
18199
- const v = r[key];
18200
- if (typeof v === "number" && Number.isFinite(v) && v > max)
18201
- max = v;
18202
- }
18203
- }
18204
- return max;
18205
- }, [data, dataKeys]);
18206
- const niceMax = React33.useMemo(() => {
18207
- let padding2 = 0.08;
18208
- if (maxDataValue > 1e6) padding2 = 0.05;
18209
- if (maxDataValue > 1e7) padding2 = 0.03;
18210
- if (maxDataValue === 0) padding2 = 0.12;
18211
- const padded = maxDataValue * (1 + padding2);
18212
- return niceCeil(padded);
18213
- }, [maxDataValue]);
18214
- const ClickableDot = (props) => {
18215
- const { cx, cy, payload, dataKey } = props;
18216
- const handleDotClick = (e) => {
18217
- e.stopPropagation();
18218
- if (!payload || !cx || !cy) return;
18219
- const tooltipId = `${payload.name}`;
18220
- const existingIndex = activeTooltips.findIndex(
18221
- (tooltip) => tooltip.id === tooltipId
18222
- );
18223
- if (existingIndex !== -1) {
18224
- setActiveTooltips(
18225
- (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
18226
- );
18227
- } else {
18228
- const newTooltip = {
18229
- id: tooltipId,
18230
- data: payload,
18231
- position: {
18232
- top: cy - 50,
18233
- // Posição relativa ao SVG
18234
- left: cx - 100
18235
- }
18236
- };
18237
- setActiveTooltips((prev) => [...prev, newTooltip]);
18238
- }
18239
- };
18240
- return /* @__PURE__ */ jsxRuntime.jsx(
18241
- "circle",
18242
- {
18243
- cx,
18244
- cy,
18245
- r: 6,
18246
- fill: finalColors[dataKey || ""] || colors2[0],
18247
- stroke: finalColors[dataKey || ""] || colors2[0],
18248
- strokeWidth: 2,
18249
- style: { cursor: "pointer" },
18250
- onClick: handleDotClick
18251
- }
18252
- );
18253
- };
18254
- const handleChartClick = (e) => {
18255
- if (e && e.activePayload && e.activePayload.length > 0) {
18256
- const clickedData = e.activePayload[0].payload;
18257
- const tooltipId = `${clickedData.name}`;
18258
- const existingIndex = activeTooltips.findIndex(
18259
- (tooltip) => tooltip.id === tooltipId
18260
- );
18261
- if (existingIndex !== -1) {
18262
- setActiveTooltips(
18263
- (prev) => prev.filter((tooltip) => tooltip.id !== tooltipId)
18264
- );
18265
- } else {
18266
- const newTooltip = {
18267
- id: tooltipId,
18268
- data: clickedData,
18269
- position: {
18270
- top: (e.chartY || 100) - 10,
18271
- left: (e.chartX || 100) - 100
18272
- }
18273
- };
18274
- setActiveTooltips((prev) => [...prev, newTooltip]);
18275
- }
18276
- }
18277
- };
18278
- const handleChartBackgroundClick = () => {
18279
- setActiveTooltips([]);
18280
- };
18281
- const handleCloseAllTooltips = React33.useCallback(() => {
18282
- window.dispatchEvent(new CustomEvent("closeAllTooltips"));
18283
- }, []);
18284
- const updateAlignmentGuides = React33.useCallback(
18285
- (draggedTooltipId, draggedPosition) => {
18286
- const SNAP_THRESHOLD = 15;
18287
- const draggedTooltip = activeTooltips.find(
18288
- (t) => t.id === draggedTooltipId
18289
- );
18290
- if (!draggedTooltip) return;
18291
- const tooltipWidth = 200;
18292
- const tooltipHeight = 80;
18293
- const globalTooltips = [];
18294
- window.dispatchEvent(
18295
- new CustomEvent("requestGlobalTooltips", {
18296
- detail: { requesterId: draggedTooltipId }
18297
- })
18298
- );
18299
- activeTooltips.forEach((tooltip) => {
18300
- if (tooltip.id !== draggedTooltipId) {
18301
- globalTooltips.push({
18302
- top: tooltip.position.top,
18303
- left: tooltip.position.left,
18304
- width: tooltipWidth,
18305
- height: tooltipHeight,
18306
- id: tooltip.id
18307
- });
18308
- }
18309
- });
18310
- const newGuides = [];
18311
- globalTooltips.forEach((otherTooltip) => {
18312
- const draggedCenter = {
18313
- x: draggedPosition.left + tooltipWidth / 2,
18314
- y: draggedPosition.top + tooltipHeight / 2
18315
- };
18316
- const otherCenter = {
18317
- x: otherTooltip.left + otherTooltip.width / 2,
18318
- y: otherTooltip.top + otherTooltip.height / 2
18319
- };
18320
- const horizontalDistance = Math.abs(draggedCenter.y - otherCenter.y);
18321
- if (horizontalDistance <= SNAP_THRESHOLD) {
18322
- newGuides.push({
18323
- type: "horizontal",
18324
- position: otherCenter.y,
18325
- visible: true,
18326
- sourceTooltip: {
18327
- top: draggedPosition.top,
18328
- left: draggedPosition.left,
18329
- width: tooltipWidth,
18330
- height: tooltipHeight
18331
- },
18332
- targetTooltip: {
18333
- top: otherTooltip.top,
18334
- left: otherTooltip.left,
18335
- width: otherTooltip.width,
18336
- height: otherTooltip.height
18337
- }
18338
- });
18339
- }
18340
- const verticalDistance = Math.abs(draggedCenter.x - otherCenter.x);
18341
- if (verticalDistance <= SNAP_THRESHOLD) {
18342
- newGuides.push({
18343
- type: "vertical",
18344
- position: otherCenter.x,
18345
- visible: true,
18346
- sourceTooltip: {
18347
- top: draggedPosition.top,
18348
- left: draggedPosition.left,
18349
- width: tooltipWidth,
18350
- height: tooltipHeight
18351
- },
18352
- targetTooltip: {
18353
- top: otherTooltip.top,
18354
- left: otherTooltip.left,
18355
- width: otherTooltip.width,
18356
- height: otherTooltip.height
18357
- }
18358
- });
18359
- }
18360
- });
18361
- setAlignmentGuides(newGuides);
18362
- },
18363
- [activeTooltips]
18364
- );
18365
- const snapToGuides = React33.useCallback(
18366
- (position) => {
18367
- const SNAP_DISTANCE = 10;
18368
- const snappedPosition = { ...position };
18369
- alignmentGuides.forEach((guide) => {
18370
- if (guide.type === "horizontal") {
18371
- const tooltipCenter = position.top + 40;
18372
- if (Math.abs(tooltipCenter - guide.position) <= SNAP_DISTANCE) {
18373
- snappedPosition.top = guide.position - 40;
18374
- }
18375
- } else if (guide.type === "vertical") {
18376
- const tooltipCenter = position.left + 100;
18377
- if (Math.abs(tooltipCenter - guide.position) <= SNAP_DISTANCE) {
18378
- snappedPosition.left = guide.position - 100;
18379
- }
18380
- }
18381
- });
18382
- return snappedPosition;
18383
- },
18384
- [alignmentGuides]
18385
- );
18386
- const handleMouseDown = (tooltipId, e) => {
18387
- const rect = e.target.getBoundingClientRect();
18388
- const offsetX = e.clientX - rect.left;
18389
- const offsetY = e.clientY - rect.top;
18390
- setIsDragging(tooltipId);
18391
- setDragOffset({ x: offsetX, y: offsetY });
18392
- };
18393
- React33.useEffect(() => {
18394
- let rafId;
18395
- let lastMousePosition = { x: 0, y: 0 };
18396
- const handleGlobalMouseMove = (e) => {
18397
- if (!isDragging) return;
18398
- lastMousePosition = { x: e.clientX, y: e.clientY };
18399
- if (rafId) cancelAnimationFrame(rafId);
18400
- rafId = requestAnimationFrame(() => {
18401
- const newLeft = lastMousePosition.x - dragOffset.x;
18402
- const newTop = lastMousePosition.y - dragOffset.y;
18403
- let finalPosition = { top: newTop, left: newLeft };
18404
- finalPosition = snapToGuides(finalPosition);
18405
- setActiveTooltips(
18406
- (prev) => prev.map(
18407
- (tooltip) => tooltip.id === isDragging ? { ...tooltip, position: finalPosition } : tooltip
18408
- )
18409
- );
18410
- updateAlignmentGuides(isDragging, finalPosition);
18411
- });
18412
- };
18413
- const handleGlobalMouseUp = () => {
18414
- if (rafId) cancelAnimationFrame(rafId);
18415
- setIsDragging(null);
18416
- setAlignmentGuides([]);
18417
- document.body.style.cursor = "";
18418
- document.body.style.userSelect = "";
18419
- };
18420
- if (isDragging) {
18421
- document.body.style.cursor = "grabbing";
18422
- document.body.style.userSelect = "none";
18423
- window.addEventListener("mousemove", handleGlobalMouseMove);
18424
- window.addEventListener("mouseup", handleGlobalMouseUp);
18425
- }
18426
- return () => {
18427
- if (rafId) cancelAnimationFrame(rafId);
18428
- window.removeEventListener("mousemove", handleGlobalMouseMove);
18429
- window.removeEventListener("mouseup", handleGlobalMouseUp);
18430
- document.body.style.cursor = "";
18431
- document.body.style.userSelect = "";
18432
- };
18433
- }, [
18434
- isDragging,
18435
- dragOffset,
18436
- alignmentGuides,
18437
- updateAlignmentGuides,
18438
- snapToGuides
18439
- ]);
18440
- React33.useEffect(() => {
18441
- const handleCloseAllTooltips2 = () => {
18442
- setActiveTooltips([]);
18443
- setGlobalTooltipCount(0);
18444
- };
18445
- window.addEventListener("closeAllTooltips", handleCloseAllTooltips2);
18446
- return () => {
18447
- window.removeEventListener("closeAllTooltips", handleCloseAllTooltips2);
18448
- };
18449
- }, []);
18450
- React33.useEffect(() => {
18451
- const handleTooltipCountRequest = () => {
18452
- window.dispatchEvent(
18453
- new CustomEvent("tooltipCountResponse", {
18454
- detail: { count: activeTooltips.length }
18455
- })
18456
- );
18457
- };
18458
- const handleGlobalTooltipsRequest = (event) => {
18459
- const requesterId = event.detail?.requesterId;
18460
- activeTooltips.forEach((tooltip) => {
18461
- if (tooltip.id !== requesterId) {
18462
- window.dispatchEvent(
18463
- new CustomEvent("globalTooltipResponse", {
18464
- detail: {
18465
- tooltip: {
18466
- top: tooltip.position.top,
18467
- left: tooltip.position.left,
18468
- width: 200,
18469
- height: 80,
18470
- id: tooltip.id
18471
- }
18472
- }
18473
- })
18474
- );
18475
- }
18476
- });
18477
- };
18478
- window.addEventListener("requestTooltipCount", handleTooltipCountRequest);
18479
- window.addEventListener(
18480
- "requestGlobalTooltips",
18481
- handleGlobalTooltipsRequest
18482
- );
18483
- return () => {
18484
- window.removeEventListener(
18485
- "requestTooltipCount",
18486
- handleTooltipCountRequest
18487
- );
18488
- window.removeEventListener(
18489
- "requestGlobalTooltips",
18490
- handleGlobalTooltipsRequest
18491
- );
18492
- };
18493
- }, [activeTooltips]);
18494
- React33.useEffect(() => {
18495
- if (isDragging) return;
18496
- let totalCount = 0;
18497
- const handleCountResponse = (event) => {
18498
- const customEvent = event;
18499
- totalCount += customEvent.detail.count;
18500
- };
18501
- window.addEventListener("tooltipCountResponse", handleCountResponse);
18502
- window.dispatchEvent(new CustomEvent("requestTooltipCount"));
18503
- const timeoutId = setTimeout(() => {
18504
- window.removeEventListener("tooltipCountResponse", handleCountResponse);
18505
- setGlobalTooltipCount(totalCount);
18506
- }, 5);
18507
- return () => {
18508
- clearTimeout(timeoutId);
18509
- window.removeEventListener("tooltipCountResponse", handleCountResponse);
18510
- };
18511
- }, [activeTooltips.length, isDragging]);
18512
- const getTitleClass = () => {
18513
- switch (titlePosition) {
18514
- case "center":
18515
- return "text-center";
18516
- case "right":
18517
- return "text-right";
18518
- default:
18519
- return "text-left";
18520
- }
18521
- };
18522
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative", className), children: /* @__PURE__ */ jsxRuntime.jsxs(
18523
- "div",
18524
- {
18525
- className: "rounded-lg bg-card p-4 relative border border-border",
18526
- style: {
18527
- width: typeof width === "number" ? `${width + 32}px` : "fit-content",
18528
- maxWidth: "100%"
18529
- },
18530
- onClick: handleChartBackgroundClick,
18531
- children: [
18532
- title && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { paddingLeft: `${resolvedContainerPaddingLeft}px` }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mb-4", getTitleClass()), children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground", children: title }) }) }),
18533
- /* @__PURE__ */ jsxRuntime.jsxs(
18534
- recharts.LineChart,
18535
- {
18536
- data,
18537
- width: typeof width === "number" ? width : 900,
18538
- height,
18539
- margin: resolveChartMargins(margins, chartMargins, showLabels),
18540
- onClick: handleChartClick,
18541
- children: [
18542
- showGrid && /* @__PURE__ */ jsxRuntime.jsx(
18543
- recharts.CartesianGrid,
18544
- {
18545
- strokeDasharray: "3 3",
18546
- stroke: gridColor || "hsl(var(--muted-foreground))",
18547
- opacity: 0.3
18548
- }
18549
- ),
18550
- /* @__PURE__ */ jsxRuntime.jsx(
18551
- recharts.XAxis,
18552
- {
18553
- dataKey: "name",
18554
- className: "fill-muted-foreground text-xs",
18555
- fontSize: 12
18556
- }
18557
- ),
18558
- /* @__PURE__ */ jsxRuntime.jsx(
18559
- recharts.YAxis,
18560
- {
18561
- className: "fill-muted-foreground text-xs",
18562
- fontSize: 12,
18563
- tickFormatter: (value) => compactTick(Number(value)),
18564
- domain: [0, niceMax],
18565
- tickCount: 6
18566
- }
18567
- ),
18568
- showTooltip && /* @__PURE__ */ jsxRuntime.jsx(recharts.Tooltip, { content: () => null }),
18569
- showLegend && /* @__PURE__ */ jsxRuntime.jsx(
18570
- recharts.Legend,
18571
- {
18572
- wrapperStyle: {
18573
- fontSize: "12px",
18574
- color: "hsl(var(--muted-foreground))"
18575
- }
18576
- }
18577
- ),
18578
- dataKeys.map((key) => /* @__PURE__ */ jsxRuntime.jsx(
18579
- recharts.Line,
18580
- {
18581
- type: "monotone",
18582
- dataKey: key,
18583
- stroke: finalColors[key],
18584
- strokeWidth,
18585
- dot: showDots ? { r: 4, cursor: "pointer" } : false,
18586
- activeDot: (props) => /* @__PURE__ */ jsxRuntime.jsx(ClickableDot, { ...props, dataKey: key }),
18587
- children: showLabels && /* @__PURE__ */ jsxRuntime.jsx(
18588
- recharts.LabelList,
18589
- {
18590
- dataKey: key,
18591
- position: "top",
18592
- content: pillLabelRenderer_default(
18593
- finalColors[key] || "#000",
18594
- "filled"
18595
- ),
18596
- offset: 14
18597
- }
18598
- )
18599
- },
18600
- key
18601
- ))
18602
- ]
18603
- }
18604
- ),
18605
- alignmentGuides.map((guide, index) => {
18606
- const isHorizontal = guide.type === "horizontal";
18607
- const color = isHorizontal ? "#3b82f6" : "#ef4444";
18608
- const startX = isHorizontal ? Math.min(
18609
- guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
18610
- guide.targetTooltip.left + guide.targetTooltip.width / 2
18611
- ) : guide.sourceTooltip.left + (isHorizontal ? 0 : guide.sourceTooltip.width / 2);
18612
- const endX = isHorizontal ? Math.max(
18613
- guide.sourceTooltip.left + guide.sourceTooltip.width / 2,
18614
- guide.targetTooltip.left + guide.targetTooltip.width / 2
18615
- ) : guide.targetTooltip.left + (isHorizontal ? 0 : guide.targetTooltip.width / 2);
18616
- const startY = isHorizontal ? guide.sourceTooltip.top + (isHorizontal ? guide.sourceTooltip.height / 2 : 0) : Math.min(
18617
- guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
18618
- guide.targetTooltip.top + guide.targetTooltip.height / 2
18619
- );
18620
- const endY = isHorizontal ? guide.targetTooltip.top + (isHorizontal ? guide.targetTooltip.height / 2 : 0) : Math.max(
18621
- guide.sourceTooltip.top + guide.sourceTooltip.height / 2,
18622
- guide.targetTooltip.top + guide.targetTooltip.height / 2
18623
- );
18624
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
18625
- /* @__PURE__ */ jsxRuntime.jsx(
18626
- "div",
18627
- {
18628
- className: "fixed pointer-events-none z-30",
18629
- style: {
18630
- left: startX,
18631
- top: startY,
18632
- width: isHorizontal ? endX - startX : "2px",
18633
- height: isHorizontal ? "2px" : endY - startY,
18634
- backgroundColor: color,
18635
- boxShadow: `0 0 8px ${color}60`,
18636
- opacity: 0.9,
18637
- borderStyle: "dashed",
18638
- borderWidth: "1px",
18639
- borderColor: color,
18640
- transform: "translateZ(0)"
18641
- }
18642
- }
18643
- ),
18644
- /* @__PURE__ */ jsxRuntime.jsx(
18645
- "div",
18646
- {
18647
- className: "fixed pointer-events-none z-31",
18648
- style: {
18649
- left: guide.sourceTooltip.left + guide.sourceTooltip.width / 2 - 4,
18650
- top: guide.sourceTooltip.top + guide.sourceTooltip.height / 2 - 4,
18651
- width: "8px",
18652
- height: "8px",
18653
- backgroundColor: color,
18654
- borderRadius: "50%",
18655
- boxShadow: `0 0 4px ${color}80`,
18656
- opacity: 0.8
18657
- }
18658
- }
18659
- ),
18660
- /* @__PURE__ */ jsxRuntime.jsx(
18661
- "div",
18662
- {
18663
- className: "fixed pointer-events-none z-31",
18664
- style: {
18665
- left: guide.targetTooltip.left + guide.targetTooltip.width / 2 - 4,
18666
- top: guide.targetTooltip.top + guide.targetTooltip.height / 2 - 4,
18667
- width: "8px",
18668
- height: "8px",
18669
- backgroundColor: color,
18670
- borderRadius: "50%",
18671
- boxShadow: `0 0 4px ${color}80`,
18672
- opacity: 0.8
18673
- }
18674
- }
18675
- )
18676
- ] }, index);
18677
- }),
18678
- activeTooltips.map((tooltip, index) => /* @__PURE__ */ jsxRuntime.jsx(
18679
- DraggableTooltip_default,
18680
- {
18681
- id: tooltip.id,
18682
- data: tooltip.data,
18683
- position: tooltip.position,
18684
- isDragging: isDragging === tooltip.id,
18685
- title,
18686
- dataKeys,
18687
- finalColors,
18688
- onMouseDown: (id, e) => handleMouseDown(id, e),
18689
- onClose: (id) => {
18690
- setActiveTooltips((prev) => prev.filter((t) => t.id !== id));
18691
- },
18692
- periodLabel: "Ponto Selecionado",
18693
- dataLabel: "Dados do Ponto",
18694
- showCloseAllButton: index === 0,
18695
- globalTooltipCount,
18696
- onCloseAll: handleCloseAllTooltips,
18697
- closeAllButtonPosition: "top-center",
18698
- closeAllButtonVariant: "floating"
18699
- },
18700
- tooltip.id
18701
- ))
18702
- ]
18703
- }
18704
- ) });
18705
- };
18706
- var LineChart_default = CustomLineChart;
18707
- var defaultData2 = [
18708
- { name: "Vendas", value: 4e3 },
18709
- { name: "Marketing", value: 3e3 },
18710
- { name: "Desenvolvimento", value: 2e3 },
18711
- { name: "Suporte", value: 1e3 },
18712
- { name: "Outros", value: 800 }
18713
- ];
18714
- var DEFAULT_COLORS5 = [
18715
- "#55af7d",
18716
- // verde do projeto
18717
- "#8e68ff",
18718
- // roxo do projeto
18719
- "#2273e1",
18720
- // azul do projeto
18721
- "#f59e0b",
18722
- // amarelo complementar
18723
- "#ef4444",
18724
- // vermelho complementar
18725
- "#8b5cf6",
18726
- // roxo claro
18727
- "#06b6d4",
18728
- // ciano
18729
- "#84cc16"
18730
- // verde lima
18731
- ];
18732
- var RADIAN = Math.PI / 180;
18733
- var renderCustomizedLabel = ({
18734
- cx = 0,
18735
- cy = 0,
18736
- midAngle = 0,
18737
- innerRadius = 0,
18738
- outerRadius = 0,
18739
- percent = 0
18740
- }) => {
18741
- const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
18742
- const x = cx + radius * Math.cos(-midAngle * RADIAN);
18743
- const y = cy + radius * Math.sin(-midAngle * RADIAN);
18744
- return /* @__PURE__ */ jsxRuntime.jsx(
18745
- "text",
18746
- {
18747
- x,
18748
- y,
18749
- fill: "white",
18750
- textAnchor: x > cx ? "start" : "end",
18751
- dominantBaseline: "central",
18752
- fontSize: 12,
18753
- fontWeight: "600",
18754
- children: `${(percent * 100).toFixed(0)}%`
17531
+ const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
17532
+ const x = cx + radius * Math.cos(-midAngle * RADIAN);
17533
+ const y = cy + radius * Math.sin(-midAngle * RADIAN);
17534
+ return /* @__PURE__ */ jsxRuntime.jsx(
17535
+ "text",
17536
+ {
17537
+ x,
17538
+ y,
17539
+ fill: "white",
17540
+ textAnchor: x > cx ? "start" : "end",
17541
+ dominantBaseline: "central",
17542
+ fontSize: 12,
17543
+ fontWeight: "600",
17544
+ children: `${(percent * 100).toFixed(0)}%`
18755
17545
  }
18756
17546
  );
18757
17547
  };
18758
17548
  var CustomPieChart = ({
18759
- data = defaultData2,
17549
+ data = defaultData,
18760
17550
  className,
18761
17551
  height = 400,
18762
17552
  width = "100%",
@@ -18769,7 +17559,7 @@ var CustomPieChart = ({
18769
17559
  centerX = "50%",
18770
17560
  centerY = "50%"
18771
17561
  }) => {
18772
- const finalColors = colors2 || DEFAULT_COLORS5;
17562
+ const finalColors = colors2 || DEFAULT_COLORS3;
18773
17563
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full rounded-lg bg-card p-4", className), children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width, height, children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
18774
17564
  /* @__PURE__ */ jsxRuntime.jsx(
18775
17565
  recharts.Pie,
@@ -19088,7 +17878,6 @@ exports.AvatarFallbackBase = AvatarFallbackBase;
19088
17878
  exports.AvatarImageBase = AvatarImageBase;
19089
17879
  exports.BackButton = BackButton;
19090
17880
  exports.Badge = Badge;
19091
- exports.BarChart = BarChart_default;
19092
17881
  exports.BreadcrumbBase = BreadcrumbBase;
19093
17882
  exports.BreadcrumbEllipsisBase = BreadcrumbEllipsisBase;
19094
17883
  exports.BreadcrumbItemBase = BreadcrumbItemBase;
@@ -19232,7 +18021,6 @@ exports.InputOTPSlotBase = InputOTPSlotBase;
19232
18021
  exports.LabelBase = LabelBase_default;
19233
18022
  exports.Leaderboard = Leaderboard;
19234
18023
  exports.LikeButton = LikeButton;
19235
- exports.LineChart = LineChart_default;
19236
18024
  exports.LoadingBase = LoadingBase;
19237
18025
  exports.LockButton = LockButton;
19238
18026
  exports.ModalBase = ModalBase;
@@ -19288,6 +18076,7 @@ exports.SearchButton = SearchButton;
19288
18076
  exports.Select = Select;
19289
18077
  exports.SelectBase = SelectBase;
19290
18078
  exports.SelectContentBase = SelectContentBase;
18079
+ exports.SelectEmpty = SelectEmpty;
19291
18080
  exports.SelectGroupBase = SelectGroupBase;
19292
18081
  exports.SelectItemBase = SelectItemBase;
19293
18082
  exports.SelectLabelBase = SelectLabelBase;