@mlw-packages/react-components 1.9.1 → 1.9.3

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
@@ -670,7 +670,7 @@ var DialogOverlayBase = React33__namespace.forwardRef(({ className, testid: data
670
670
  {
671
671
  ref,
672
672
  className: cn(
673
- "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border",
673
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 ",
674
674
  className
675
675
  ),
676
676
  "data-testid": dataTestId,
@@ -688,7 +688,7 @@ var DialogContentBase = React33__namespace.forwardRef(
688
688
  {
689
689
  ref,
690
690
  className: cn(
691
- "fixed left-[50%] top-[50%] z-50 w-lg grid 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 max-h-[100dvh] overflow-auto rounded-md border-border",
691
+ "fixed left-[50%] top-[50%] z-50 w-[90%] sm:w-lg grid 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 max-h-[100dvh] overflow-y-auto overflow-x-hidden rounded-md border-border",
692
692
  className
693
693
  ),
694
694
  "data-testid": dataTestId,
@@ -1315,15 +1315,27 @@ var toast = {
1315
1315
  };
1316
1316
  var MOBILE_BREAKPOINT = 768;
1317
1317
  function useIsMobile() {
1318
- const [isMobile, setIsMobile] = React33__namespace.useState(void 0);
1318
+ const [isMobile, setIsMobile] = React33__namespace.useState(
1319
+ void 0
1320
+ );
1319
1321
  React33__namespace.useEffect(() => {
1322
+ const checkIsMobile = () => {
1323
+ const isTouch = window.matchMedia("(pointer: coarse)").matches || navigator.maxTouchPoints > 0;
1324
+ const isSmallScreen = window.innerWidth < MOBILE_BREAKPOINT;
1325
+ return isTouch || isSmallScreen;
1326
+ };
1320
1327
  const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
1328
+ const touchMql = window.matchMedia("(pointer: coarse)");
1321
1329
  const onChange = () => {
1322
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
1330
+ setIsMobile(checkIsMobile());
1323
1331
  };
1324
1332
  mql.addEventListener("change", onChange);
1325
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
1326
- return () => mql.removeEventListener("change", onChange);
1333
+ touchMql.addEventListener("change", onChange);
1334
+ setIsMobile(checkIsMobile());
1335
+ return () => {
1336
+ mql.removeEventListener("change", onChange);
1337
+ touchMql.removeEventListener("change", onChange);
1338
+ };
1327
1339
  }, []);
1328
1340
  return !!isMobile;
1329
1341
  }
@@ -1942,21 +1954,28 @@ var CommandDialogBase = ({ children, open, ...props }) => {
1942
1954
  "command-dialog"
1943
1955
  ) }) }) });
1944
1956
  };
1945
- var CommandInputBase = React33__namespace.forwardRef(({ className, testid: dataTestId = "command-input", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center border-b px-3 border-border", "cmdk-input-wrapper": "", children: [
1946
- /* @__PURE__ */ jsxRuntime.jsx(react.MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 text-primary" }),
1947
- /* @__PURE__ */ jsxRuntime.jsx(
1948
- cmdk.Command.Input,
1949
- {
1950
- ref,
1951
- className: cn(
1952
- "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none text-primary placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
1953
- className
1954
- ),
1955
- "data-testid": dataTestId,
1956
- ...props
1957
- }
1958
- )
1959
- ] }));
1957
+ var CommandInputBase = React33__namespace.forwardRef(({ className, testid: dataTestId = "command-input", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
1958
+ "div",
1959
+ {
1960
+ className: "flex items-center border-b px-3 border-border",
1961
+ "cmdk-input-wrapper": "",
1962
+ children: [
1963
+ /* @__PURE__ */ jsxRuntime.jsx(react.MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 text-primary" }),
1964
+ /* @__PURE__ */ jsxRuntime.jsx(
1965
+ cmdk.Command.Input,
1966
+ {
1967
+ ref,
1968
+ className: cn(
1969
+ "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none text-primary placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
1970
+ className
1971
+ ),
1972
+ "data-testid": dataTestId,
1973
+ ...props
1974
+ }
1975
+ )
1976
+ ]
1977
+ }
1978
+ ));
1960
1979
  CommandInputBase.displayName = cmdk.Command.Input.displayName;
1961
1980
  var CommandListBase = React33__namespace.forwardRef(({ className, testid: dataTestId = "command-list", ...props }, ref) => {
1962
1981
  const listRef = React33__namespace.useRef(null);
@@ -1964,11 +1983,45 @@ var CommandListBase = React33__namespace.forwardRef(({ className, testid: dataTe
1964
1983
  const element = listRef.current;
1965
1984
  if (!element) return;
1966
1985
  const handleWheel = (e) => {
1986
+ const target = e.currentTarget;
1987
+ const { scrollTop, scrollHeight, clientHeight } = target;
1988
+ const isScrollingDown = e.deltaY > 0;
1989
+ const isScrollingUp = e.deltaY < 0;
1990
+ const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
1991
+ const isAtTop = scrollTop <= 1;
1992
+ if (isScrollingDown && !isAtBottom || isScrollingUp && !isAtTop) {
1993
+ e.stopPropagation();
1994
+ }
1995
+ };
1996
+ let touchStartY = 0;
1997
+ const handleTouchStart = (e) => {
1998
+ touchStartY = e.touches[0].clientY;
1967
1999
  e.stopPropagation();
1968
2000
  };
2001
+ const handleTouchMove = (e) => {
2002
+ const target = e.currentTarget;
2003
+ const { scrollTop, scrollHeight, clientHeight } = target;
2004
+ const touchCurrentY = e.touches[0].clientY;
2005
+ const touchDeltaY = touchStartY - touchCurrentY;
2006
+ const isScrollingDown = touchDeltaY > 0;
2007
+ const isScrollingUp = touchDeltaY < 0;
2008
+ const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
2009
+ const isAtTop = scrollTop <= 1;
2010
+ if (isScrollingDown && !isAtBottom || isScrollingUp && !isAtTop) {
2011
+ e.stopPropagation();
2012
+ } else if (isScrollingDown && isAtBottom || isScrollingUp && isAtTop) {
2013
+ e.preventDefault();
2014
+ }
2015
+ };
1969
2016
  element.addEventListener("wheel", handleWheel, { passive: false });
2017
+ element.addEventListener("touchstart", handleTouchStart, {
2018
+ passive: false
2019
+ });
2020
+ element.addEventListener("touchmove", handleTouchMove, { passive: false });
1970
2021
  return () => {
1971
2022
  element.removeEventListener("wheel", handleWheel);
2023
+ element.removeEventListener("touchmove", handleTouchMove);
2024
+ element.removeEventListener("touchstart", handleTouchStart);
1972
2025
  };
1973
2026
  }, []);
1974
2027
  const combinedRef = React33__namespace.useCallback(
@@ -1993,7 +2046,13 @@ var CommandListBase = React33__namespace.forwardRef(({ className, testid: dataTe
1993
2046
  "data-testid": dataTestId,
1994
2047
  style: {
1995
2048
  overscrollBehavior: "contain",
1996
- WebkitOverflowScrolling: "touch"
2049
+ WebkitOverflowScrolling: "touch",
2050
+ touchAction: "pan-y",
2051
+ scrollbarWidth: "thin",
2052
+ scrollbarColor: "hsl(var(--muted)) transparent",
2053
+ overflowY: "auto",
2054
+ willChange: "scroll-position",
2055
+ transform: "translateZ(0)"
1997
2056
  },
1998
2057
  ...props
1999
2058
  }
@@ -2071,6 +2130,7 @@ var PopoverContentBase = React33__namespace.forwardRef(
2071
2130
  align = "center",
2072
2131
  sideOffset = 4,
2073
2132
  testid: dataTestId = "popover-content",
2133
+ style,
2074
2134
  ...props
2075
2135
  }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
2076
2136
  PopoverPrimitive__namespace.Content,
@@ -2079,10 +2139,20 @@ var PopoverContentBase = React33__namespace.forwardRef(
2079
2139
  align,
2080
2140
  sideOffset,
2081
2141
  className: cn(
2082
- "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
2142
+ "z-[100] w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
2083
2143
  className
2084
2144
  ),
2085
2145
  "data-testid": dataTestId,
2146
+ style: {
2147
+ ...style,
2148
+ WebkitOverflowScrolling: "touch",
2149
+ overscrollBehavior: "contain",
2150
+ pointerEvents: "auto"
2151
+ },
2152
+ onWheel: (e) => {
2153
+ e.stopPropagation();
2154
+ props.onWheel?.(e);
2155
+ },
2086
2156
  onInteractOutside: (event) => {
2087
2157
  props.onInteractOutside?.(event);
2088
2158
  if (event.defaultPrevented) return;
@@ -2139,7 +2209,6 @@ function ComboboxBase({
2139
2209
  hideClear = false
2140
2210
  }) {
2141
2211
  const [open, setOpen] = React33.useState(false);
2142
- const isMobile = useIsMobile();
2143
2212
  return /* @__PURE__ */ jsxRuntime.jsxs(
2144
2213
  "div",
2145
2214
  {
@@ -2151,7 +2220,7 @@ function ComboboxBase({
2151
2220
  {
2152
2221
  open,
2153
2222
  onOpenChange: (v) => !disabled && setOpen(v),
2154
- modal: isMobile,
2223
+ modal: false,
2155
2224
  children: [
2156
2225
  /* @__PURE__ */ jsxRuntime.jsx(
2157
2226
  PopoverTriggerBase,
@@ -2883,7 +2952,7 @@ var SelectContentBase = React33__namespace.forwardRef(
2883
2952
  {
2884
2953
  ref,
2885
2954
  className: cn(
2886
- "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
2955
+ "relative z-50 max-h-96 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
2887
2956
  className
2888
2957
  ),
2889
2958
  position,
@@ -5424,14 +5493,29 @@ var TableCaptionBase = React33__namespace.forwardRef(({ className, ...props }, r
5424
5493
  }
5425
5494
  ));
5426
5495
  TableCaptionBase.displayName = "TableCaptionBase";
5427
- var TabsBase = TabsPrimitive__namespace.Root;
5496
+ var TabsBase = React33__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5497
+ TabsPrimitive__namespace.Root,
5498
+ {
5499
+ ref,
5500
+ className: cn("w-full", className),
5501
+ ...props
5502
+ }
5503
+ ));
5504
+ TabsBase.displayName = TabsPrimitive__namespace.Root.displayName;
5428
5505
  var TabsListBase = React33__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5429
5506
  TabsPrimitive__namespace.List,
5430
5507
  {
5431
5508
  ref,
5432
5509
  className: cn(
5433
5510
  "relative flex w-full items-center justify-start gap-2 border-b border-border",
5434
- "bg-transparent",
5511
+ "bg-transparent overflow-x-auto",
5512
+ "scrollbar-thin scrollbar-thumb-muted-foreground/30 scrollbar-track-transparent",
5513
+ "hover:scrollbar-thumb-muted-foreground/50",
5514
+ "[&::-webkit-scrollbar]:h-1.5",
5515
+ "[&::-webkit-scrollbar-track]:bg-transparent",
5516
+ "[&::-webkit-scrollbar-thumb]:bg-muted-foreground/30",
5517
+ "[&::-webkit-scrollbar-thumb]:rounded-full",
5518
+ "hover:[&::-webkit-scrollbar-thumb]:bg-muted-foreground/50",
5435
5519
  className
5436
5520
  ),
5437
5521
  ...props
@@ -7764,13 +7848,11 @@ function ScrollColumn({
7764
7848
  } = useScrollColumn({ value, onChange, max, step });
7765
7849
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
7766
7850
  /* @__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" }),
7851
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative w-20"), children: [
7770
7852
  /* @__PURE__ */ jsxRuntime.jsx(
7771
7853
  "div",
7772
7854
  {
7773
- className: "absolute left-0 right-0 pointer-events-none bg-muted/50 backdrop-blur-sm rounded-md border border-border",
7855
+ className: "absolute left-0 right-0 pointer-events-none bg-muted/50 rounded-md border border-border",
7774
7856
  style: {
7775
7857
  top: `${centerIndex * itemHeight}px`,
7776
7858
  height: `${itemHeight}px`
@@ -8154,7 +8236,7 @@ function DateTimePicker({
8154
8236
  }
8155
8237
  ),
8156
8238
  /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage_default, { error }),
8157
- /* @__PURE__ */ jsxRuntime.jsx(DialogContentBase, { className: "p-0 max-h-[65vh] w-[calc(100vw-24px)] sm:w-[calc(100vw-32px)] overflow-hidden flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-y-auto flex-1", children: renderPickerContent() }) })
8239
+ /* @__PURE__ */ jsxRuntime.jsx(DialogContentBase, { className: "p-0 max-h-[95vh] w-3/6 overflow-hidden flex flex-col", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-y-auto flex-1", children: renderPickerContent() }) })
8158
8240
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(PopoverBase, { open, onOpenChange: setOpen, children: [
8159
8241
  /* @__PURE__ */ jsxRuntime.jsx(
8160
8242
  PopoverTriggerBase,
@@ -10140,8 +10222,8 @@ function EventAgenda({
10140
10222
  setView(v);
10141
10223
  },
10142
10224
  items: selectItems,
10143
- className: "gap-2 px-3 py-1.5 max-[479px]:h-8",
10144
10225
  placeholder: viewLabel(view),
10226
+ className: "min-w-24",
10145
10227
  hideClear: true
10146
10228
  }
10147
10229
  ) })
@@ -10149,8 +10231,7 @@ function EventAgenda({
10149
10231
  /* @__PURE__ */ jsxRuntime.jsxs(
10150
10232
  "div",
10151
10233
  {
10152
- className: "flex flex-1 flex-col transition-all duration-200 ease-in-out",
10153
- "aria-live": "polite",
10234
+ className: "flex flex-col transition-all duration-200 ease-in-out",
10154
10235
  children: [
10155
10236
  view === "month" && /* @__PURE__ */ jsxRuntime.jsx(
10156
10237
  MonthViewAgenda,
@@ -14158,29 +14239,62 @@ var adaptDataForTooltip = (data, xAxisKey) => {
14158
14239
  };
14159
14240
  var createValueFormatter = (customFormatter, formatBR) => {
14160
14241
  const nf = new Intl.NumberFormat("pt-BR", {
14161
- minimumFractionDigits: 2,
14162
- maximumFractionDigits: 2
14242
+ minimumFractionDigits: 0,
14243
+ maximumFractionDigits: 0
14163
14244
  });
14245
+ const prefixFormats = ["R$", "$", "\u20AC", "\xA3"];
14246
+ const suffixFormats = ["%", "kg", "km", "m", "L", "un", "t", "h", "min", "s"];
14247
+ const getFormattedValue = (baseValue, format17) => {
14248
+ const trimmedFormat = format17.trim();
14249
+ if (prefixFormats.includes(trimmedFormat)) {
14250
+ return `${trimmedFormat} ${baseValue}`;
14251
+ }
14252
+ if (suffixFormats.includes(trimmedFormat)) {
14253
+ return `${baseValue}${trimmedFormat}`;
14254
+ }
14255
+ return `${baseValue} ${trimmedFormat}`;
14256
+ };
14164
14257
  if (customFormatter) {
14165
- if (formatBR) {
14166
- const wrapped = (props) => {
14167
- const { value, formattedValue } = props;
14258
+ if (typeof customFormatter === "object" && !Array.isArray(customFormatter)) {
14259
+ const formatterMap = customFormatter;
14260
+ return (props) => {
14261
+ const {
14262
+ value,
14263
+ formattedValue,
14264
+ dataKey: propsDataKey
14265
+ } = props;
14168
14266
  let num = NaN;
14169
14267
  if (typeof value === "number") num = value;
14170
14268
  else if (typeof value === "string" && value.trim() !== "") {
14171
14269
  const parsed = Number(value);
14172
14270
  num = Number.isNaN(parsed) ? NaN : parsed;
14173
14271
  }
14174
- const brFormatted = !Number.isNaN(num) ? nf.format(num) : String(formattedValue ?? value ?? "");
14175
- return customFormatter({
14176
- ...props,
14177
- formattedValue: brFormatted,
14178
- value: void 0
14179
- });
14272
+ const baseFormatted = formatBR && !Number.isNaN(num) ? nf.format(num) : String(formattedValue ?? value ?? "");
14273
+ const format17 = propsDataKey && formatterMap[propsDataKey] ? formatterMap[propsDataKey] : "";
14274
+ return format17 ? getFormattedValue(baseFormatted, format17) : baseFormatted;
14180
14275
  };
14181
- return wrapped;
14182
14276
  }
14183
- return customFormatter;
14277
+ if (typeof customFormatter === "function") {
14278
+ if (formatBR) {
14279
+ const wrapped = (props) => {
14280
+ const { value, formattedValue } = props;
14281
+ let num = NaN;
14282
+ if (typeof value === "number") num = value;
14283
+ else if (typeof value === "string" && value.trim() !== "") {
14284
+ const parsed = Number(value);
14285
+ num = Number.isNaN(parsed) ? NaN : parsed;
14286
+ }
14287
+ const brFormatted = !Number.isNaN(num) ? nf.format(num) : String(formattedValue ?? value ?? "");
14288
+ return customFormatter({
14289
+ ...props,
14290
+ formattedValue: brFormatted,
14291
+ value: void 0
14292
+ });
14293
+ };
14294
+ return wrapped;
14295
+ }
14296
+ return customFormatter;
14297
+ }
14184
14298
  }
14185
14299
  if (!formatBR) return void 0;
14186
14300
  const builtIn = (props) => {
@@ -14198,8 +14312,8 @@ var createValueFormatter = (customFormatter, formatBR) => {
14198
14312
  };
14199
14313
  var createYTickFormatter = (finalValueFormatter) => {
14200
14314
  const nf = new Intl.NumberFormat("pt-BR", {
14201
- minimumFractionDigits: 2,
14202
- maximumFractionDigits: 2
14315
+ minimumFractionDigits: 0,
14316
+ maximumFractionDigits: 0
14203
14317
  });
14204
14318
  const stripCurrency = (s) => String(s).replace(/^\s*R\$\s?/, "");
14205
14319
  if (finalValueFormatter) {
@@ -15709,7 +15823,7 @@ var Brush = ({
15709
15823
  xAxisKey,
15710
15824
  seriesOrder,
15711
15825
  finalColors,
15712
- brushHeight = 80,
15826
+ brushHeight = 40,
15713
15827
  brushColor,
15714
15828
  miniChartOpacity = 0.3
15715
15829
  }) => {
@@ -15933,16 +16047,76 @@ var ChartTotalLegend = ({ items }) => {
15933
16047
  ] }, index)) });
15934
16048
  };
15935
16049
  var ChartTotalLegend_default = ChartTotalLegend;
16050
+ var formatFieldName2 = (key) => {
16051
+ return key.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).trim();
16052
+ };
16053
+ var HorizontalLegend = ({
16054
+ allKeys,
16055
+ mapperConfig,
16056
+ finalColors,
16057
+ labelMap,
16058
+ legendUppercase = false,
16059
+ orderBy,
16060
+ maxPeriodLabel,
16061
+ minPeriodLabel,
16062
+ className
16063
+ }) => {
16064
+ const formatLegendLabel = (key) => {
16065
+ const label = mapperConfig[key]?.label ?? labelMap?.[key] ?? formatFieldName2(key);
16066
+ return legendUppercase ? label.toUpperCase() : label;
16067
+ };
16068
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-3 md:gap-4 flex-wrap", children: [
16069
+ allKeys.map((key) => {
16070
+ const displayLabel = formatLegendLabel(key);
16071
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 sm:gap-2", children: [
16072
+ /* @__PURE__ */ jsxRuntime.jsx(
16073
+ "div",
16074
+ {
16075
+ className: "w-2.5 h-2.5 sm:w-3 sm:h-3 rounded-sm flex-shrink-0",
16076
+ style: { backgroundColor: finalColors[key] }
16077
+ }
16078
+ ),
16079
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-sm tracking-[0] break-words", children: displayLabel })
16080
+ ] }, key);
16081
+ }),
16082
+ orderBy && maxPeriodLabel && minPeriodLabel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-3 md:gap-4 w-full sm:w-auto justify-center mt-2 sm:mt-0 sm:ml-3 sm:pl-3 md:ml-4 md:pl-4 sm:border-l border-border", children: [
16083
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 sm:gap-1.5", children: [
16084
+ /* @__PURE__ */ jsxRuntime.jsx(
16085
+ react.FunnelSimpleIcon,
16086
+ {
16087
+ className: "w-3 h-3 sm:w-4 sm:h-4 text-green-600 flex-shrink-0",
16088
+ weight: "bold"
16089
+ }
16090
+ ),
16091
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-sm tracking-[0] font-medium truncate max-w-[120px] sm:max-w-none", children: maxPeriodLabel })
16092
+ ] }),
16093
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 sm:gap-1.5", children: [
16094
+ /* @__PURE__ */ jsxRuntime.jsx(
16095
+ react.FunnelSimpleIcon,
16096
+ {
16097
+ className: "w-3 h-3 sm:w-4 sm:h-4 text-red-600 rotate-180 flex-shrink-0",
16098
+ weight: "bold"
16099
+ }
16100
+ ),
16101
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs sm:text-sm tracking-[0] font-medium truncate max-w-[120px] sm:max-w-none", children: minPeriodLabel })
16102
+ ] })
16103
+ ] })
16104
+ ] }) });
16105
+ };
16106
+ var HorizontalLegend_default = HorizontalLegend;
15936
16107
  var formatCompactNumber = (value) => {
15937
16108
  const isNegative = value < 0;
15938
16109
  const absValue = Math.abs(value);
15939
16110
  let formatted;
15940
16111
  if (absValue >= 1e9) {
15941
- formatted = (absValue / 1e9).toFixed(1).replace(/\.0$/, "") + "B";
16112
+ const billions = absValue / 1e9;
16113
+ formatted = (billions % 1 === 0 ? billions.toFixed(0) : billions.toFixed(1)) + "B";
15942
16114
  } else if (absValue >= 1e6) {
15943
- formatted = (absValue / 1e6).toFixed(1).replace(/\.0$/, "") + "M";
16115
+ const millions = absValue / 1e6;
16116
+ formatted = (millions % 1 === 0 ? millions.toFixed(0) : millions.toFixed(1)) + "M";
15944
16117
  } else if (absValue >= 1e3) {
15945
- formatted = (absValue / 1e3).toFixed(1).replace(/\.0$/, "") + " mil";
16118
+ const thousands = absValue / 1e3;
16119
+ formatted = (thousands % 1 === 0 ? thousands.toFixed(0) : thousands.toFixed(1)) + " mil";
15946
16120
  } else {
15947
16121
  try {
15948
16122
  const nf = new Intl.NumberFormat("pt-BR", {
@@ -16669,6 +16843,42 @@ function useTimeSeriesRange({
16669
16843
  handleMouseDown
16670
16844
  };
16671
16845
  }
16846
+ var useChartMinMax = ({
16847
+ processedData,
16848
+ orderBy,
16849
+ xAxisDataKey,
16850
+ categoryFormatter
16851
+ }) => {
16852
+ return React33.useMemo(() => {
16853
+ if (!processedData || processedData.length === 0 || !orderBy) {
16854
+ return {
16855
+ maxPeriodLabel: "",
16856
+ minPeriodLabel: ""
16857
+ };
16858
+ }
16859
+ let maxValue = -Infinity;
16860
+ let minValue = Infinity;
16861
+ let maxPeriodLabel = "";
16862
+ let minPeriodLabel = "";
16863
+ processedData.forEach((item) => {
16864
+ const value = Number(item[orderBy]) || 0;
16865
+ const periodName = String(item[xAxisDataKey] || "N/A");
16866
+ const formattedPeriod = categoryFormatter ? categoryFormatter(periodName) : periodName;
16867
+ if (value > maxValue) {
16868
+ maxValue = value;
16869
+ maxPeriodLabel = formattedPeriod;
16870
+ }
16871
+ if (value < minValue) {
16872
+ minValue = value;
16873
+ minPeriodLabel = formattedPeriod;
16874
+ }
16875
+ });
16876
+ return {
16877
+ maxPeriodLabel,
16878
+ minPeriodLabel
16879
+ };
16880
+ }, [processedData, orderBy, xAxisDataKey, categoryFormatter]);
16881
+ };
16672
16882
  var filtersOrder = (mapperConfig, series) => {
16673
16883
  const seriesOrder = [];
16674
16884
  if (series) {
@@ -16741,7 +16951,7 @@ var fnSmartConfig = ({ xAxis, data, labelMap }) => {
16741
16951
  return { xAxisConfig, mapperConfig };
16742
16952
  };
16743
16953
  var fnConfigRightKeys = (biaxialConfigNormalized, yTickFormatter, finalColors) => {
16744
- const decimals = typeof biaxialConfigNormalized?.decimals === "number" ? Math.max(0, Math.floor(biaxialConfigNormalized.decimals)) : 2;
16954
+ const decimals = typeof biaxialConfigNormalized?.decimals === "number" ? Math.max(0, Math.floor(biaxialConfigNormalized.decimals)) : 1;
16745
16955
  const rightTickFormatter = (v) => {
16746
16956
  if (biaxialConfigNormalized?.percentage) {
16747
16957
  const num = Number(String(v));
@@ -16791,6 +17001,11 @@ var fnContentLabelList = (p) => {
16791
17001
  const needsOutside = barHeight > 0 && barHeight < smallThreshold || barWidth > 0 && barWidth < smallThreshold;
16792
17002
  return needsOutside ? null : true;
16793
17003
  };
17004
+
17005
+ // src/utils/calcDivision.ts
17006
+ var calcDivision = (dividend, divisor) => {
17007
+ return dividend / divisor;
17008
+ };
16794
17009
  var DEFAULT_COLORS2 = ["#55af7d", "#8e68ff", "#2273e1"];
16795
17010
  var Chart = ({
16796
17011
  data,
@@ -16827,7 +17042,9 @@ var Chart = ({
16827
17042
  isLoading = false,
16828
17043
  timeSeries,
16829
17044
  timeSeriesLegend,
16830
- customLegend
17045
+ customLegend,
17046
+ horizontal = false,
17047
+ orderBy
16831
17048
  }) => {
16832
17049
  const { xAxisConfig, mapperConfig } = React33.useMemo(() => {
16833
17050
  return fnSmartConfig({ xAxis, data, labelMap });
@@ -16863,16 +17080,38 @@ var Chart = ({
16863
17080
  defaultEndIndex: timeSeriesConfig?.end,
16864
17081
  onRangeChange: timeSeriesConfig?.onRangeChange
16865
17082
  });
17083
+ const { maxPeriodLabel, minPeriodLabel } = useChartMinMax({
17084
+ processedData: data,
17085
+ orderBy,
17086
+ xAxisDataKey: xAxisConfig.dataKey,
17087
+ categoryFormatter
17088
+ });
16866
17089
  const processedData = React33.useMemo(() => {
16867
17090
  const mapped = data.map((item) => ({
16868
17091
  ...item,
16869
17092
  name: String(item[xAxisConfig.dataKey] || "N/A")
16870
17093
  }));
17094
+ let result = mapped;
16871
17095
  if (timeSeriesConfig) {
16872
- return mapped.slice(startIndex, endIndex + 1);
17096
+ result = mapped.slice(startIndex, endIndex + 1);
17097
+ }
17098
+ if (orderBy && horizontal) {
17099
+ result = [...result].sort((a, b) => {
17100
+ const valueA = Number(a[orderBy]) || 0;
17101
+ const valueB = Number(b[orderBy]) || 0;
17102
+ return valueB - valueA;
17103
+ });
16873
17104
  }
16874
- return mapped;
16875
- }, [data, xAxisConfig.dataKey, timeSeriesConfig, startIndex, endIndex]);
17105
+ return result;
17106
+ }, [
17107
+ data,
17108
+ xAxisConfig.dataKey,
17109
+ timeSeriesConfig,
17110
+ startIndex,
17111
+ endIndex,
17112
+ orderBy,
17113
+ horizontal
17114
+ ]);
16876
17115
  const seriesOrder = filtersOrder(mapperConfig, series);
16877
17116
  const allKeys = seriesOrder.map((s) => s.key).filter(Boolean);
16878
17117
  const finalColors = React33.useMemo(
@@ -17038,7 +17277,10 @@ var Chart = ({
17038
17277
  "div",
17039
17278
  {
17040
17279
  ref: wrapperRef,
17041
- className: cn("w-full overflow-hidden min-w-0 rounded-lg border-border", className),
17280
+ className: cn(
17281
+ "w-full overflow-hidden min-w-0 rounded-lg border-border",
17282
+ className
17283
+ ),
17042
17284
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-card relative w-full max-w-full min-w-0 py-1", children: [
17043
17285
  title && /* @__PURE__ */ jsxRuntime.jsx(
17044
17286
  "div",
@@ -17135,303 +17377,416 @@ var Chart = ({
17135
17377
  )
17136
17378
  }
17137
17379
  ),
17138
- /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height, children: /* @__PURE__ */ jsxRuntime.jsxs(
17139
- recharts.ComposedChart,
17380
+ showLegend && horizontal && /* @__PURE__ */ jsxRuntime.jsx(
17381
+ HorizontalLegend_default,
17140
17382
  {
17141
- data: processedData,
17142
- height,
17143
- margin: {
17144
- top: 10,
17145
- right: finalChartRightMargin,
17146
- left: finalChartLeftMargin,
17147
- bottom: 10
17383
+ allKeys,
17384
+ mapperConfig,
17385
+ finalColors,
17386
+ labelMap,
17387
+ legendUppercase,
17388
+ orderBy,
17389
+ maxPeriodLabel,
17390
+ minPeriodLabel,
17391
+ className: cn(HORIZONTAL_PADDING_CLASS)
17392
+ }
17393
+ ),
17394
+ /* @__PURE__ */ jsxRuntime.jsx(
17395
+ "div",
17396
+ {
17397
+ className: cn(
17398
+ horizontal && "overflow-y-auto overflow-x-hidden px-6",
17399
+ horizontal && "scrollbar-thin scrollbar-thumb-muted scrollbar-track-transparent"
17400
+ ),
17401
+ style: {
17402
+ maxHeight: horizontal ? height : void 0
17148
17403
  },
17149
- onClick: handleChartClick,
17150
- children: [
17151
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: seriesOrder.filter((s) => s.type === "area").map((s) => {
17152
- const key = s.key;
17153
- const color = finalColors[key];
17154
- return /* @__PURE__ */ jsxRuntime.jsxs(
17155
- "linearGradient",
17404
+ children: /* @__PURE__ */ jsxRuntime.jsx(
17405
+ recharts.ResponsiveContainer,
17406
+ {
17407
+ width: "100%",
17408
+ height: horizontal ? Math.max(height, processedData.length * 50) : height,
17409
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
17410
+ recharts.ComposedChart,
17156
17411
  {
17157
- id: `gradient-${key}`,
17158
- x1: "0",
17159
- y1: "0",
17160
- x2: "0",
17161
- y2: "0.8",
17412
+ data: processedData,
17413
+ height: horizontal ? Math.max(height, processedData.length * 50) : height,
17414
+ layout: horizontal ? "vertical" : "horizontal",
17415
+ margin: {
17416
+ top: 10,
17417
+ right: finalChartRightMargin,
17418
+ left: finalChartLeftMargin,
17419
+ bottom: 10
17420
+ },
17421
+ onClick: handleChartClick,
17162
17422
  children: [
17163
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.8 }),
17164
- /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "90%", stopColor: color, stopOpacity: 0.1 })
17165
- ]
17166
- },
17167
- `gradient-${key}`
17168
- );
17169
- }) }),
17170
- showGrid && /* @__PURE__ */ jsxRuntime.jsx(
17171
- recharts.CartesianGrid,
17172
- {
17173
- strokeDasharray: "3 3",
17174
- stroke: gridColor || "hsl(var(--muted-foreground))",
17175
- opacity: 0.5
17176
- }
17177
- ),
17178
- /* @__PURE__ */ jsxRuntime.jsx(
17179
- recharts.XAxis,
17180
- {
17181
- dataKey: xAxisConfig.dataKey,
17182
- stroke: "hsl(var(--muted-foreground))",
17183
- fontSize: 12,
17184
- tickLine: false,
17185
- axisLine: false,
17186
- tickFormatter: (value) => {
17187
- if (categoryFormatter)
17188
- return categoryFormatter(value);
17189
- if (xAxisConfig.valueFormatter)
17190
- return xAxisConfig.valueFormatter(value);
17191
- return String(value ?? "");
17192
- },
17193
- label: xAxisLabel ? {
17194
- value: xAxisLabel,
17195
- position: "insideBottomRight",
17196
- offset: -5,
17197
- style: {
17198
- fontSize: 12,
17199
- fill: "hsl(var(--muted-foreground))",
17200
- fontWeight: 500
17201
- }
17202
- } : void 0
17203
- }
17204
- ),
17205
- /* @__PURE__ */ jsxRuntime.jsx(
17206
- recharts.YAxis,
17207
- {
17208
- yAxisId: "left",
17209
- width: yAxisTickWidth,
17210
- stroke: "hsl(var(--muted-foreground))",
17211
- fontSize: 12,
17212
- tickLine: false,
17213
- axisLine: false,
17214
- tickFormatter: yTickFormatter,
17215
- domain: [Math.min(minLeftDataValue, 0), niceMaxLeft],
17216
- tickCount: 6,
17217
- label: yAxisLabel ? {
17218
- value: yAxisLabel,
17219
- angle: -90,
17220
- position: "left",
17221
- dx: leftYAxisLabelDx,
17222
- style: {
17223
- fontSize: 12,
17224
- fill: "hsl(var(--muted-foreground))",
17225
- fontWeight: 500,
17226
- textAnchor: "middle"
17227
- }
17228
- } : void 0
17229
- }
17230
- ),
17231
- minLeftDataValue < 0 && /* @__PURE__ */ jsxRuntime.jsx(
17232
- recharts.ReferenceLine,
17233
- {
17234
- y: 0,
17235
- yAxisId: "left",
17236
- stroke: "hsl(var(--muted-foreground))",
17237
- strokeWidth: 1,
17238
- strokeDasharray: "4 4"
17239
- }
17240
- ),
17241
- rightKeys.length > 0 && (() => {
17242
- const { rightAxisColor, rightTickFormatter } = fnConfigRightKeys(biaxialConfigNormalized, yTickFormatter, finalColors);
17243
- return /* @__PURE__ */ jsxRuntime.jsx(
17244
- recharts.YAxis,
17245
- {
17246
- yAxisId: "right",
17247
- width: finalChartRightMargin,
17248
- orientation: "right",
17249
- stroke: "hsl(var(--muted-foreground))",
17250
- fontSize: 12,
17251
- tickLine: false,
17252
- axisLine: false,
17253
- tick: { fill: rightAxisColor },
17254
- tickFormatter: rightTickFormatter,
17255
- domain: [Math.min(minRightDataValue, 0), niceMaxRight],
17256
- tickCount: 6,
17257
- label: biaxialConfigNormalized?.label ? {
17258
- value: biaxialConfigNormalized.label,
17259
- angle: -90,
17260
- position: "right",
17261
- dx: rightYAxisLabelDx,
17262
- style: {
17263
- fontSize: 12,
17264
- fill: "hsl(var(--muted-foreground))",
17265
- fontWeight: 500,
17266
- textAnchor: "middle"
17267
- }
17268
- } : void 0
17269
- }
17270
- );
17271
- })(),
17272
- showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
17273
- recharts.Tooltip,
17274
- {
17275
- content: showTooltipTotal ? /* @__PURE__ */ jsxRuntime.jsx(
17276
- TooltipWithTotal_default,
17277
- {
17278
- finalColors,
17279
- valueFormatter: finalValueFormatter,
17280
- categoryFormatter,
17281
- periodLabel
17282
- }
17283
- ) : /* @__PURE__ */ jsxRuntime.jsx(
17284
- TooltipSimple_default,
17285
- {
17286
- finalColors,
17287
- valueFormatter: finalValueFormatter,
17288
- categoryFormatter,
17289
- periodLabel
17290
- }
17291
- ),
17292
- cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
17293
- }
17294
- ),
17295
- showLegend && /* @__PURE__ */ jsxRuntime.jsx(
17296
- recharts.Legend,
17297
- {
17298
- iconSize: 12,
17299
- formatter: (value) => {
17300
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tracking-[0]", children: fnFormatterValueLegend(
17301
- value,
17302
- mapperConfig,
17303
- labelMap,
17304
- legendUppercase
17305
- ) });
17306
- }
17307
- }
17308
- ),
17309
- seriesOrder.map((s) => {
17310
- if (showOnlyHighlighted && !highlightedSeries.has(s.key))
17311
- return null;
17312
- const { label, color, key } = fnBuildConfigData(
17313
- s,
17314
- mapperConfig,
17315
- labelMap,
17316
- finalColors,
17317
- rightKeys,
17318
- biaxialConfigNormalized
17319
- );
17320
- if (s.type === "bar") {
17321
- return /* @__PURE__ */ jsxRuntime.jsx(
17322
- recharts.Bar,
17323
- {
17324
- dataKey: key,
17325
- yAxisId: rightKeys.includes(key) ? "right" : "left",
17326
- name: label,
17327
- fill: color,
17328
- radius: [4, 4, 0, 0],
17329
- onClick: handleBarClick,
17330
- className: "cursor-pointer",
17331
- style: { opacity: getSeriesOpacity(key) },
17332
- activeBar: /* @__PURE__ */ jsxRuntime.jsx(
17333
- recharts.Rectangle,
17423
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: seriesOrder.filter((s) => s.type === "area").map((s) => {
17424
+ const key = s.key;
17425
+ const color = finalColors[key];
17426
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17427
+ "linearGradient",
17428
+ {
17429
+ id: `gradient-${key}`,
17430
+ x1: "0",
17431
+ y1: "0",
17432
+ x2: "0",
17433
+ y2: "0.8",
17434
+ children: [
17435
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: color, stopOpacity: 0.8 }),
17436
+ /* @__PURE__ */ jsxRuntime.jsx(
17437
+ "stop",
17438
+ {
17439
+ offset: "90%",
17440
+ stopColor: color,
17441
+ stopOpacity: 0.1
17442
+ }
17443
+ )
17444
+ ]
17445
+ },
17446
+ `gradient-${key}`
17447
+ );
17448
+ }) }),
17449
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(
17450
+ recharts.CartesianGrid,
17334
17451
  {
17335
- fill: color,
17336
- stroke: color,
17337
- strokeWidth: 2,
17338
- opacity: 0.8
17452
+ strokeDasharray: "3 3",
17453
+ stroke: gridColor || "hsl(var(--muted-foreground))",
17454
+ opacity: 0.5
17339
17455
  }
17340
17456
  ),
17341
- children: showLabels && labelsVisibility.bar !== false && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsxRuntime.jsx(
17342
- recharts.LabelList,
17457
+ horizontal ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17458
+ /* @__PURE__ */ jsxRuntime.jsx(
17459
+ recharts.XAxis,
17460
+ {
17461
+ type: "number",
17462
+ orientation: "top",
17463
+ stroke: "hsl(var(--muted-foreground))",
17464
+ fontSize: 12,
17465
+ tickLine: false,
17466
+ axisLine: false,
17467
+ tickFormatter: yTickFormatter,
17468
+ domain: [Math.min(minLeftDataValue, 0), niceMaxLeft],
17469
+ tickCount: 6,
17470
+ label: yAxisLabel ? {
17471
+ value: yAxisLabel,
17472
+ position: "insideTopRight",
17473
+ offset: -5,
17474
+ style: {
17475
+ fontSize: 12,
17476
+ fill: "hsl(var(--muted-foreground))",
17477
+ fontWeight: 500
17478
+ }
17479
+ } : void 0
17480
+ }
17481
+ ),
17482
+ /* @__PURE__ */ jsxRuntime.jsx(
17483
+ recharts.YAxis,
17484
+ {
17485
+ type: "category",
17486
+ dataKey: xAxisConfig.dataKey,
17487
+ yAxisId: "left",
17488
+ width: yAxisTickWidth,
17489
+ stroke: "hsl(var(--muted-foreground))",
17490
+ fontSize: 12,
17491
+ tickLine: false,
17492
+ axisLine: false,
17493
+ tickFormatter: (value) => {
17494
+ if (categoryFormatter)
17495
+ return categoryFormatter(value);
17496
+ if (xAxisConfig.valueFormatter)
17497
+ return xAxisConfig.valueFormatter(
17498
+ value
17499
+ );
17500
+ return String(value ?? "");
17501
+ },
17502
+ label: xAxisLabel ? {
17503
+ value: xAxisLabel,
17504
+ angle: -90,
17505
+ position: "insideTop",
17506
+ dx: leftYAxisLabelDx,
17507
+ style: {
17508
+ fontSize: 12,
17509
+ fill: "hsl(var(--muted-foreground))",
17510
+ fontWeight: 500,
17511
+ textAnchor: "middle"
17512
+ }
17513
+ } : void 0
17514
+ }
17515
+ )
17516
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17517
+ /* @__PURE__ */ jsxRuntime.jsx(
17518
+ recharts.XAxis,
17519
+ {
17520
+ dataKey: xAxisConfig.dataKey,
17521
+ stroke: "hsl(var(--muted-foreground))",
17522
+ fontSize: 12,
17523
+ tickLine: false,
17524
+ axisLine: false,
17525
+ tickFormatter: (value) => {
17526
+ if (categoryFormatter)
17527
+ return categoryFormatter(value);
17528
+ if (xAxisConfig.valueFormatter)
17529
+ return xAxisConfig.valueFormatter(
17530
+ value
17531
+ );
17532
+ return String(value ?? "");
17533
+ },
17534
+ label: xAxisLabel ? {
17535
+ value: xAxisLabel,
17536
+ position: "insideBottomRight",
17537
+ offset: -5,
17538
+ style: {
17539
+ fontSize: 12,
17540
+ fill: "hsl(var(--muted-foreground))",
17541
+ fontWeight: 500
17542
+ }
17543
+ } : void 0
17544
+ }
17545
+ ),
17546
+ /* @__PURE__ */ jsxRuntime.jsx(
17547
+ recharts.YAxis,
17548
+ {
17549
+ yAxisId: "left",
17550
+ width: yAxisTickWidth,
17551
+ stroke: "hsl(var(--muted-foreground))",
17552
+ fontSize: 12,
17553
+ tickLine: false,
17554
+ axisLine: false,
17555
+ tickFormatter: yTickFormatter,
17556
+ domain: [Math.min(minLeftDataValue, 0), niceMaxLeft],
17557
+ tickCount: 6,
17558
+ label: yAxisLabel ? {
17559
+ value: yAxisLabel,
17560
+ angle: -90,
17561
+ position: "left",
17562
+ dx: leftYAxisLabelDx,
17563
+ style: {
17564
+ fontSize: 12,
17565
+ fill: "hsl(var(--muted-foreground))",
17566
+ fontWeight: 500,
17567
+ textAnchor: "middle"
17568
+ }
17569
+ } : void 0
17570
+ }
17571
+ )
17572
+ ] }),
17573
+ minLeftDataValue < 0 && /* @__PURE__ */ jsxRuntime.jsx(
17574
+ recharts.ReferenceLine,
17343
17575
  {
17344
- dataKey: key,
17345
- content: (props) => {
17346
- if (!fnContentLabelList(props))
17347
- return null;
17348
- const inside = renderInsideBarLabel(
17349
- color,
17350
- finalValueFormatter
17351
- );
17352
- return inside(props);
17353
- },
17354
- offset: 0
17576
+ y: 0,
17577
+ yAxisId: "left",
17578
+ stroke: "hsl(var(--muted-foreground))",
17579
+ strokeWidth: 1,
17580
+ strokeDasharray: "4 4"
17355
17581
  }
17356
- ) : null
17357
- },
17358
- `bar-${key}`
17359
- );
17360
- }
17361
- if (s.type === "line") {
17362
- return /* @__PURE__ */ jsxRuntime.jsx(
17363
- recharts.Line,
17364
- {
17365
- dataKey: key,
17366
- yAxisId: rightKeys.includes(key) ? "right" : "left",
17367
- name: label,
17368
- stroke: color,
17369
- strokeWidth: 2,
17370
- dot: { r: 3 },
17371
- activeDot: { r: 6 },
17372
- onClick: handleSeriesClick,
17373
- className: "cursor-pointer pointer-events-auto",
17374
- style: { opacity: getSeriesOpacity(key) },
17375
- children: showLabels && labelsVisibility.line !== false && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsxRuntime.jsx(
17376
- recharts.LabelList,
17582
+ ),
17583
+ rightKeys.length > 0 && (() => {
17584
+ const { rightAxisColor, rightTickFormatter } = fnConfigRightKeys(
17585
+ biaxialConfigNormalized,
17586
+ yTickFormatter,
17587
+ finalColors
17588
+ );
17589
+ return /* @__PURE__ */ jsxRuntime.jsx(
17590
+ recharts.YAxis,
17591
+ {
17592
+ yAxisId: "right",
17593
+ width: finalChartRightMargin,
17594
+ orientation: "right",
17595
+ stroke: "hsl(var(--muted-foreground))",
17596
+ fontSize: 12,
17597
+ tickLine: false,
17598
+ axisLine: false,
17599
+ tick: { fill: rightAxisColor },
17600
+ tickFormatter: rightTickFormatter,
17601
+ domain: [Math.min(minRightDataValue, 0), niceMaxRight],
17602
+ tickCount: 6,
17603
+ label: biaxialConfigNormalized?.label ? {
17604
+ value: biaxialConfigNormalized.label,
17605
+ angle: -90,
17606
+ position: "right",
17607
+ dx: rightYAxisLabelDx,
17608
+ style: {
17609
+ fontSize: 12,
17610
+ fill: "hsl(var(--muted-foreground))",
17611
+ fontWeight: 500,
17612
+ textAnchor: "middle"
17613
+ }
17614
+ } : void 0
17615
+ }
17616
+ );
17617
+ })(),
17618
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
17619
+ recharts.Tooltip,
17377
17620
  {
17378
- dataKey: key,
17379
- position: "top",
17380
- content: pillLabelRenderer_default(
17381
- color,
17382
- "filled",
17383
- finalValueFormatter
17621
+ content: showTooltipTotal ? /* @__PURE__ */ jsxRuntime.jsx(
17622
+ TooltipWithTotal_default,
17623
+ {
17624
+ finalColors,
17625
+ valueFormatter: finalValueFormatter,
17626
+ categoryFormatter,
17627
+ periodLabel
17628
+ }
17629
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
17630
+ TooltipSimple_default,
17631
+ {
17632
+ finalColors,
17633
+ valueFormatter: finalValueFormatter,
17634
+ categoryFormatter,
17635
+ periodLabel
17636
+ }
17384
17637
  ),
17385
- offset: 14
17638
+ cursor: { fill: "hsl(var(--muted))", opacity: 0.1 }
17386
17639
  }
17387
- ) : null
17388
- },
17389
- `line-${key}`
17390
- );
17391
- }
17392
- if (s.type === "area") {
17393
- return /* @__PURE__ */ jsxRuntime.jsx(
17394
- recharts.Area,
17395
- {
17396
- type: "monotone",
17397
- dataKey: key,
17398
- yAxisId: rightKeys.includes(key) ? "right" : "left",
17399
- name: label,
17400
- stroke: color,
17401
- fill: `url(#gradient-${key})`,
17402
- fillOpacity: 1,
17403
- strokeWidth: 2,
17404
- onClick: handleSeriesClick,
17405
- className: "cursor-pointer pointer-events-auto",
17406
- style: { opacity: getSeriesOpacity(key) },
17407
- activeDot: {
17408
- r: 6,
17409
- fill: color,
17410
- stroke: "hsl(var(--background))",
17411
- strokeWidth: 2
17412
- },
17413
- children: showLabels && labelsVisibility.area !== false && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsxRuntime.jsx(
17414
- recharts.LabelList,
17640
+ ),
17641
+ showLegend && !horizontal && /* @__PURE__ */ jsxRuntime.jsx(
17642
+ recharts.Legend,
17415
17643
  {
17416
- dataKey: key,
17417
- position: "top",
17418
- content: pillLabelRenderer_default(
17419
- color,
17420
- "soft",
17421
- finalValueFormatter
17422
- ),
17423
- offset: 12
17644
+ iconSize: 12,
17645
+ formatter: (value) => {
17646
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tracking-[0] rounded-sm", children: fnFormatterValueLegend(
17647
+ value,
17648
+ mapperConfig,
17649
+ labelMap,
17650
+ legendUppercase
17651
+ ) });
17652
+ }
17424
17653
  }
17425
- ) : null
17426
- },
17427
- `area-${key}`
17428
- );
17429
- }
17430
- return null;
17431
- })
17432
- ]
17654
+ ),
17655
+ seriesOrder.map((s) => {
17656
+ if (showOnlyHighlighted && !highlightedSeries.has(s.key))
17657
+ return null;
17658
+ const { label, color, key } = fnBuildConfigData(
17659
+ s,
17660
+ mapperConfig,
17661
+ labelMap,
17662
+ finalColors,
17663
+ rightKeys,
17664
+ biaxialConfigNormalized
17665
+ );
17666
+ if (s.type === "bar") {
17667
+ return /* @__PURE__ */ jsxRuntime.jsx(
17668
+ recharts.Bar,
17669
+ {
17670
+ dataKey: key,
17671
+ yAxisId: rightKeys.includes(key) ? "right" : "left",
17672
+ name: label,
17673
+ fill: color,
17674
+ radius: horizontal ? [0, 4, 4, 0] : [4, 4, 0, 0],
17675
+ onClick: handleBarClick,
17676
+ className: "cursor-pointer",
17677
+ style: { opacity: getSeriesOpacity(key) },
17678
+ activeBar: /* @__PURE__ */ jsxRuntime.jsx(
17679
+ recharts.Rectangle,
17680
+ {
17681
+ fill: color,
17682
+ stroke: color,
17683
+ strokeWidth: 2,
17684
+ opacity: 0.8
17685
+ }
17686
+ ),
17687
+ children: showLabels && labelsVisibility.bar !== false && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsxRuntime.jsx(
17688
+ recharts.LabelList,
17689
+ {
17690
+ dataKey: key,
17691
+ content: (props) => {
17692
+ if (!fnContentLabelList(props)) return null;
17693
+ const inside = renderInsideBarLabel(
17694
+ color,
17695
+ finalValueFormatter
17696
+ );
17697
+ return inside(props);
17698
+ },
17699
+ offset: 0
17700
+ }
17701
+ ) : null
17702
+ },
17703
+ `bar-${key}`
17704
+ );
17705
+ }
17706
+ if (s.type === "line") {
17707
+ const lineFormatter = (props) => {
17708
+ const numValue = typeof props.value === "number" ? props.value : typeof props.value === "string" ? parseFloat(props.value) : 0;
17709
+ const percentage = calcDivision(numValue, 100);
17710
+ const formattedPercentage = typeof percentage === "number" ? percentage.toFixed(1).replace(".", ",") : String(percentage).replace(".", ",");
17711
+ return `${formattedPercentage}%`;
17712
+ };
17713
+ return /* @__PURE__ */ jsxRuntime.jsx(
17714
+ recharts.Line,
17715
+ {
17716
+ dataKey: key,
17717
+ yAxisId: rightKeys.includes(key) ? "right" : "left",
17718
+ name: label,
17719
+ stroke: color,
17720
+ strokeWidth: 2,
17721
+ dot: { r: 3 },
17722
+ activeDot: { r: 6 },
17723
+ onClick: handleSeriesClick,
17724
+ className: "cursor-pointer pointer-events-auto",
17725
+ style: { opacity: getSeriesOpacity(key) },
17726
+ children: showLabels && labelsVisibility.line !== false && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsxRuntime.jsx(
17727
+ recharts.LabelList,
17728
+ {
17729
+ dataKey: key,
17730
+ position: "top",
17731
+ content: pillLabelRenderer_default(
17732
+ color,
17733
+ "filled",
17734
+ lineFormatter
17735
+ ),
17736
+ offset: 14
17737
+ }
17738
+ ) : null
17739
+ },
17740
+ `line-${key}`
17741
+ );
17742
+ }
17743
+ if (s.type === "area") {
17744
+ return /* @__PURE__ */ jsxRuntime.jsx(
17745
+ recharts.Area,
17746
+ {
17747
+ type: "monotone",
17748
+ dataKey: key,
17749
+ yAxisId: rightKeys.includes(key) ? "right" : "left",
17750
+ name: label,
17751
+ stroke: color,
17752
+ fill: `url(#gradient-${key})`,
17753
+ fillOpacity: 1,
17754
+ strokeWidth: 2,
17755
+ onClick: handleSeriesClick,
17756
+ className: "cursor-pointer pointer-events-auto",
17757
+ style: { opacity: getSeriesOpacity(key) },
17758
+ activeDot: {
17759
+ r: 6,
17760
+ fill: color,
17761
+ stroke: "hsl(var(--background))",
17762
+ strokeWidth: 2
17763
+ },
17764
+ children: showLabels && labelsVisibility.area !== false && highlightedSeries.size === 0 || highlightedSeries.has(key) ? /* @__PURE__ */ jsxRuntime.jsx(
17765
+ recharts.LabelList,
17766
+ {
17767
+ dataKey: key,
17768
+ position: "top",
17769
+ content: pillLabelRenderer_default(
17770
+ color,
17771
+ "soft",
17772
+ finalValueFormatter
17773
+ ),
17774
+ offset: 12
17775
+ }
17776
+ ) : null
17777
+ },
17778
+ `area-${key}`
17779
+ );
17780
+ }
17781
+ return null;
17782
+ })
17783
+ ]
17784
+ }
17785
+ )
17786
+ }
17787
+ )
17433
17788
  }
17434
- ) }),
17789
+ ),
17435
17790
  enableDraggableTooltips && activeTooltips.map((tooltip) => /* @__PURE__ */ jsxRuntime.jsx(
17436
17791
  DraggableTooltip_default,
17437
17792
  {
@@ -18009,6 +18364,7 @@ exports.FileUploader = FileUploader;
18009
18364
  exports.FilterButton = FilterButton;
18010
18365
  exports.HideButton = HideButton;
18011
18366
  exports.Highlights = Highlights_default;
18367
+ exports.HorizontalLegend = HorizontalLegend_default;
18012
18368
  exports.HoverCardBase = HoverCardBase;
18013
18369
  exports.HoverCardContentBase = HoverCardContentBase;
18014
18370
  exports.HoverCardTriggerBase = HoverCardTriggerBase;
@@ -18234,6 +18590,7 @@ exports.useCalendarDndAgenda = useCalendarDndAgenda;
18234
18590
  exports.useChartClick = useChartClick;
18235
18591
  exports.useChartDimensions = useChartDimensions;
18236
18592
  exports.useChartHighlights = useChartHighlights;
18593
+ exports.useChartMinMax = useChartMinMax;
18237
18594
  exports.useChartTooltips = useChartTooltips;
18238
18595
  exports.useCurrentTimeIndicator = useCurrentTimeIndicator;
18239
18596
  exports.useCurrentTimeIndicatorAgenda = useCurrentTimeIndicatorAgenda;