@trackunit/react-components 0.5.38 → 0.5.40

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/index.cjs.js CHANGED
@@ -458,7 +458,7 @@ const cvaButton = cssClassVarianceUtilities.cvaMerge([
458
458
  "cursor-pointer",
459
459
  "flex-none",
460
460
  "component-button-border",
461
- "component-button-padding", //TODO: Is overwritten by size which messes with marketing theme
461
+ "component-button-padding",
462
462
  "component-button-height",
463
463
  "disabled:cursor-not-allowed",
464
464
  "font-medium",
@@ -653,11 +653,21 @@ const cvaButtonPrefixSuffix = cssClassVarianceUtilities.cvaMerge(["flex", "items
653
653
  variant: {
654
654
  primary: [],
655
655
  "primary-danger": [],
656
- secondary: ["text-secondary-400", "group-focus:text-secondary-400", "group-hover:text-secondary-500", "group-active:text-secondary-600"],
656
+ secondary: [
657
+ "text-secondary-400",
658
+ "group-focus:text-secondary-400",
659
+ "group-hover:text-secondary-500",
660
+ "group-active:text-secondary-600",
661
+ ],
657
662
  "secondary-danger": [],
658
663
  ghost: [],
659
- "ghost-neutral": ["text-secondary-400", "group-focus:text-secondary-400", "group-hover:text-secondary-500", "group-active:text-secondary-600"],
660
- }
664
+ "ghost-neutral": [
665
+ "text-secondary-400",
666
+ "group-focus:text-secondary-400",
667
+ "group-hover:text-secondary-500",
668
+ "group-active:text-secondary-600",
669
+ ],
670
+ },
661
671
  },
662
672
  defaultVariants: {
663
673
  size: "medium",
@@ -1281,7 +1291,7 @@ const getWindowSize = () => {
1281
1291
  width: window.innerWidth,
1282
1292
  };
1283
1293
  }
1284
- catch (err) {
1294
+ catch (error) {
1285
1295
  return {
1286
1296
  height: 0,
1287
1297
  width: 0,
@@ -1928,7 +1938,6 @@ const SkeletonLines = React.memo(({ margin = "10px 0", lines = 1, height, width
1928
1938
  for (let i = 0; i < lines; i++) {
1929
1939
  skeletonLines.push(jsxRuntime.jsx("div", { className: cvaSkeletonLine({ className }), "data-testid": dataTestId ? `${dataTestId}-${i}` : `skeleton-lines-${i}`, "data-type": "loading-skeleton-line", style: { height: getHeight(i), width: getWidth(i), margin: lines > 1 && i >= 1 ? margin : "" }, children: lines > 1 && jsxRuntime.jsx(jsxRuntime.Fragment, { children: "\u00A0" }) }, i));
1930
1940
  }
1931
- // eslint-disable-next-line react/jsx-no-useless-fragment
1932
1941
  return jsxRuntime.jsx(jsxRuntime.Fragment, { children: skeletonLines });
1933
1942
  });
1934
1943
  SkeletonLines.displayName = "SkeletonLines";
@@ -3722,7 +3731,7 @@ const cvaKPICardContainer = cssClassVarianceUtilities.cvaMerge(["inline-flex"],
3722
3731
  isClickable: false,
3723
3732
  },
3724
3733
  });
3725
- const cvaKPICard = cssClassVarianceUtilities.cvaMerge(["w-full", "bg-white", "pl-6", "pr-8", "py-4", "flex", "flex-row", "items-center", "gap-3"], {
3734
+ const cvaKPICard = cssClassVarianceUtilities.cvaMerge(["w-full", "bg-white", "px-4", "py-2", "flex", "flex-row", "items-center", "gap-1"], {
3726
3735
  variants: {
3727
3736
  isClickable: {
3728
3737
  true: ["hover:bg-slate-50", "component-card-border"],
@@ -3732,38 +3741,61 @@ const cvaKPICard = cssClassVarianceUtilities.cvaMerge(["w-full", "bg-white", "pl
3732
3741
  true: ["bg-primary-50", "border-primary-600"],
3733
3742
  false: [],
3734
3743
  },
3744
+ variant: {
3745
+ small: ["px-3"],
3746
+ default: ["min-w-40"],
3747
+ },
3735
3748
  },
3736
3749
  defaultVariants: {
3737
3750
  isClickable: false,
3738
3751
  isActive: false,
3752
+ variant: "default",
3753
+ },
3754
+ });
3755
+ const cvaKPICardTrendPercentage = cssClassVarianceUtilities.cvaMerge([""], {
3756
+ variants: {
3757
+ color: {
3758
+ success: ["text-success-500"],
3759
+ danger: ["text-danger-500"],
3760
+ neutral: ["text-neutral-500"],
3761
+ },
3762
+ },
3763
+ defaultVariants: {
3764
+ color: "success",
3739
3765
  },
3740
3766
  });
3741
- const cvaKPICardIconContainer = cssClassVarianceUtilities.cvaMerge(["w-7", "h-7", "flex", "justify-center", "items-center", "rounded"], {
3767
+ const cvaKPICardValueContainer = cssClassVarianceUtilities.cvaMerge([], {
3742
3768
  variants: {
3743
- backgroundColor: {
3744
- info: "bg-primary-500",
3745
- success: "bg-secondary-500",
3746
- warning: "bg-yellow-500",
3747
- danger: "bg-red-500",
3769
+ isDefaultAndHasTrendValue: {
3770
+ true: [],
3771
+ false: ["flex", "flex-row", "items-center", "gap-1"],
3748
3772
  },
3749
3773
  },
3750
3774
  defaultVariants: {
3751
- backgroundColor: "info",
3775
+ isDefaultAndHasTrendValue: true,
3752
3776
  },
3753
3777
  });
3754
3778
 
3755
- const LoadingContent = () => (jsxRuntime.jsxs("div", { className: "flex flex-row items-center gap-3", "data-testid": "kpi-card-loading-content", children: [jsxRuntime.jsx("div", { children: jsxRuntime.jsx(SkeletonLines, { height: 28, lines: 1, width: 28 }) }), jsxRuntime.jsx("div", { className: "w-full", children: jsxRuntime.jsx(SkeletonLines, { height: [18, 20], lines: 2, margin: "3px 0", width: [50, 100] }) })] }));
3779
+ const LoadingContent = () => (jsxRuntime.jsx("div", { className: "flex flex-row items-center gap-3", "data-testid": "kpi-card-loading-content", children: jsxRuntime.jsx("div", { className: "w-full", children: jsxRuntime.jsx(SkeletonLines, { height: [18, 20], lines: 2, margin: "3px 0", width: [50, 100] }) }) }));
3756
3780
  /**
3757
3781
  * The KPICard component is used to display KPIs.
3758
3782
  *
3759
3783
  * @param {KPICardProps} props - The props for the KPICard component
3760
3784
  * @returns {JSX.Element} KPICard component
3761
3785
  */
3762
- const KPICard = ({ asChild = false, title, value, loading, unit, iconName, iconBackgroundColor, className, dataTestId, tooltipLabel, isActive, onClick, ...rest }) => {
3786
+ const KPICard = ({ asChild = false, title, value, loading, unit, className, dataTestId, tooltipLabel, isActive, variant = "default", trend, onClick, ...rest }) => {
3763
3787
  const Comp = asChild ? reactSlot.Slot : "div";
3764
- const CardContent = () => {
3765
- return (jsxRuntime.jsx(Card, { className: cvaKPICard({ isClickable: Boolean((onClick || asChild) && !loading), isActive }), children: loading ? (jsxRuntime.jsx(LoadingContent, {})) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [iconName ? (jsxRuntime.jsx("div", { className: cvaKPICardIconContainer({ backgroundColor: iconBackgroundColor }), "data-testid": `${dataTestId}-icon-container`, children: jsxRuntime.jsx(Icon, { color: "white", dataTestId: `${dataTestId}-icon`, name: iconName, size: "medium" }) })) : null, jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(Text, { dataTestId: `${dataTestId}-title`, subtle: true, weight: "bold", children: title }), jsxRuntime.jsxs(Text, { dataTestId: `${dataTestId}-value`, size: "large", weight: "bold", children: [value, " ", unit] })] })] })) }));
3788
+ const isSmallVariant = variant === "small";
3789
+ const TrendIndicator = () => {
3790
+ var _a, _b;
3791
+ if (!trend) {
3792
+ return null;
3793
+ }
3794
+ return (jsxRuntime.jsxs("div", { className: "flex flex-row items-center gap-1", "data-testid": "trend-indicator", children: [!isSmallVariant && trend.value ? (jsxRuntime.jsxs(Text, { dataTestId: "trend-value", size: "small", weight: "normal", children: [trend.value, " ", unit] })) : null, ((_a = trend.variant) === null || _a === void 0 ? void 0 : _a.icon) ? jsxRuntime.jsx(Icon, { color: trend.variant.color, name: trend.variant.icon, size: "small" }) : null, trend.percentage ? (jsxRuntime.jsxs(Text, { className: cvaKPICardTrendPercentage({ color: (_b = trend.variant) === null || _b === void 0 ? void 0 : _b.color }), size: "small", weight: "bold", children: [trend.percentage, "%"] })) : null] }));
3766
3795
  };
3796
+ const CardContent = () => (jsxRuntime.jsx(Card, { className: cvaKPICard({ isClickable: Boolean((onClick || asChild) && !loading), isActive, variant }), children: loading ? (jsxRuntime.jsx(LoadingContent, {})) : (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(Text, { dataTestId: `${dataTestId}-title`, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsxRuntime.jsx(Text, { className: isSmallVariant ? "mt-0.5" : "", dataTestId: `${dataTestId}-value`, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: jsxRuntime.jsxs("div", { className: cvaKPICardValueContainer({
3797
+ isDefaultAndHasTrendValue: Boolean((trend === null || trend === void 0 ? void 0 : trend.value) && !isSmallVariant),
3798
+ }), children: [jsxRuntime.jsxs("span", { children: [value, " ", unit] }), jsxRuntime.jsx(TrendIndicator, {})] }) })] })) }));
3767
3799
  return (jsxRuntime.jsxs(Comp, { className: cvaKPICardContainer({ className, isClickable: Boolean(asChild || onClick) }), "data-testid": `${dataTestId}-comp`, onClick: onClick, ...rest, children: [tooltipLabel ? (jsxRuntime.jsx(Tooltip, { className: "w-full", label: tooltipLabel, placement: "bottom", children: jsxRuntime.jsx(CardContent, {}) })) : (jsxRuntime.jsx(CardContent, {})), !loading && jsxRuntime.jsx(reactSlot.Slottable, { children: rest.children })] }));
3768
3800
  };
3769
3801
 
@@ -4296,6 +4328,7 @@ const Polygon = ({ points, size, color = "black", opaque = true, className, data
4296
4328
  const normalize = ({ value, min, max, size }) => ((value - min) / (max - min)) * size;
4297
4329
 
4298
4330
  function useConfirmExit(confirmExit, when = true) {
4331
+ // eslint-disable-next-line sonarjs/deprecation
4299
4332
  reactRouter.useBlocker(confirmExit, when);
4300
4333
  }
4301
4334
  /**
@@ -4398,7 +4431,7 @@ const cvaSidebarChildContainer = cssClassVarianceUtilities.cvaMerge(["apply", "f
4398
4431
  */
4399
4432
  const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id", children, }) => {
4400
4433
  const [itemOverflowMap, setItemOverflowMap] = React.useState({});
4401
- const overflowContainerRef = React.useRef(null); // TODO: Handle other elements than div
4434
+ const overflowContainerRef = React.useRef(null);
4402
4435
  const observerRef = React.useRef(null);
4403
4436
  const handleIntersection = React.useCallback(entries => {
4404
4437
  const updatedEntries = {};
@@ -4608,6 +4641,7 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
4608
4641
  * Individual ToggleItem to create custom ToggleGroups
4609
4642
  */
4610
4643
  const ToggleItem = ({ title, onClick, disabled = false, isIconOnly = false, iconName, size, className, selected = false, text, tooltip, dataTestId, }) => {
4644
+ // eslint-disable-next-line sonarjs/no-selector-parameter
4611
4645
  return isIconOnly ? (jsxRuntime.jsx(Tooltip, { label: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.content) || title, placement: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.placement) || "top", children: jsxRuntime.jsx(IconButton, { className: cvaToggleItem({ className, selected }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsxRuntime.jsx(Icon, { className: selected ? "text-slate-600" : "text-slate-400", name: iconName, size: "small" })) : null, onClick: onClick, size: size, title: iconName, variant: "secondary" }) })) : (jsxRuntime.jsx(Tooltip, { disabled: !(text === null || text === void 0 ? void 0 : text.truncate) && (tooltip === null || tooltip === void 0 ? void 0 : tooltip.content) === undefined, label: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.content) || title, placement: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.placement) || "top", children: jsxRuntime.jsx(Button, { className: cvaToggleItem({ className, selected }), "data-testid": dataTestId, disabled: disabled, onClick: onClick, prefix: iconName ? (jsxRuntime.jsx(Icon, { className: selected ? "text-slate-600" : "text-slate-400", name: iconName, size: "small" })) : null, size: size, variant: "secondary", children: jsxRuntime.jsx("span", { className: cvaToggleItemText({ disabledAndSelected: disabled && selected, maxWidth: text === null || text === void 0 ? void 0 : text.maxWidth }), children: title }) }) }));
4612
4646
  };
4613
4647
 
package/index.esm.js CHANGED
@@ -438,7 +438,7 @@ const cvaButton = cvaMerge([
438
438
  "cursor-pointer",
439
439
  "flex-none",
440
440
  "component-button-border",
441
- "component-button-padding", //TODO: Is overwritten by size which messes with marketing theme
441
+ "component-button-padding",
442
442
  "component-button-height",
443
443
  "disabled:cursor-not-allowed",
444
444
  "font-medium",
@@ -633,11 +633,21 @@ const cvaButtonPrefixSuffix = cvaMerge(["flex", "items-center"], {
633
633
  variant: {
634
634
  primary: [],
635
635
  "primary-danger": [],
636
- secondary: ["text-secondary-400", "group-focus:text-secondary-400", "group-hover:text-secondary-500", "group-active:text-secondary-600"],
636
+ secondary: [
637
+ "text-secondary-400",
638
+ "group-focus:text-secondary-400",
639
+ "group-hover:text-secondary-500",
640
+ "group-active:text-secondary-600",
641
+ ],
637
642
  "secondary-danger": [],
638
643
  ghost: [],
639
- "ghost-neutral": ["text-secondary-400", "group-focus:text-secondary-400", "group-hover:text-secondary-500", "group-active:text-secondary-600"],
640
- }
644
+ "ghost-neutral": [
645
+ "text-secondary-400",
646
+ "group-focus:text-secondary-400",
647
+ "group-hover:text-secondary-500",
648
+ "group-active:text-secondary-600",
649
+ ],
650
+ },
641
651
  },
642
652
  defaultVariants: {
643
653
  size: "medium",
@@ -1261,7 +1271,7 @@ const getWindowSize = () => {
1261
1271
  width: window.innerWidth,
1262
1272
  };
1263
1273
  }
1264
- catch (err) {
1274
+ catch (error) {
1265
1275
  return {
1266
1276
  height: 0,
1267
1277
  width: 0,
@@ -1908,7 +1918,6 @@ const SkeletonLines = memo(({ margin = "10px 0", lines = 1, height, width = "100
1908
1918
  for (let i = 0; i < lines; i++) {
1909
1919
  skeletonLines.push(jsx("div", { className: cvaSkeletonLine({ className }), "data-testid": dataTestId ? `${dataTestId}-${i}` : `skeleton-lines-${i}`, "data-type": "loading-skeleton-line", style: { height: getHeight(i), width: getWidth(i), margin: lines > 1 && i >= 1 ? margin : "" }, children: lines > 1 && jsx(Fragment, { children: "\u00A0" }) }, i));
1910
1920
  }
1911
- // eslint-disable-next-line react/jsx-no-useless-fragment
1912
1921
  return jsx(Fragment, { children: skeletonLines });
1913
1922
  });
1914
1923
  SkeletonLines.displayName = "SkeletonLines";
@@ -3702,7 +3711,7 @@ const cvaKPICardContainer = cvaMerge(["inline-flex"], {
3702
3711
  isClickable: false,
3703
3712
  },
3704
3713
  });
3705
- const cvaKPICard = cvaMerge(["w-full", "bg-white", "pl-6", "pr-8", "py-4", "flex", "flex-row", "items-center", "gap-3"], {
3714
+ const cvaKPICard = cvaMerge(["w-full", "bg-white", "px-4", "py-2", "flex", "flex-row", "items-center", "gap-1"], {
3706
3715
  variants: {
3707
3716
  isClickable: {
3708
3717
  true: ["hover:bg-slate-50", "component-card-border"],
@@ -3712,38 +3721,61 @@ const cvaKPICard = cvaMerge(["w-full", "bg-white", "pl-6", "pr-8", "py-4", "flex
3712
3721
  true: ["bg-primary-50", "border-primary-600"],
3713
3722
  false: [],
3714
3723
  },
3724
+ variant: {
3725
+ small: ["px-3"],
3726
+ default: ["min-w-40"],
3727
+ },
3715
3728
  },
3716
3729
  defaultVariants: {
3717
3730
  isClickable: false,
3718
3731
  isActive: false,
3732
+ variant: "default",
3733
+ },
3734
+ });
3735
+ const cvaKPICardTrendPercentage = cvaMerge([""], {
3736
+ variants: {
3737
+ color: {
3738
+ success: ["text-success-500"],
3739
+ danger: ["text-danger-500"],
3740
+ neutral: ["text-neutral-500"],
3741
+ },
3742
+ },
3743
+ defaultVariants: {
3744
+ color: "success",
3719
3745
  },
3720
3746
  });
3721
- const cvaKPICardIconContainer = cvaMerge(["w-7", "h-7", "flex", "justify-center", "items-center", "rounded"], {
3747
+ const cvaKPICardValueContainer = cvaMerge([], {
3722
3748
  variants: {
3723
- backgroundColor: {
3724
- info: "bg-primary-500",
3725
- success: "bg-secondary-500",
3726
- warning: "bg-yellow-500",
3727
- danger: "bg-red-500",
3749
+ isDefaultAndHasTrendValue: {
3750
+ true: [],
3751
+ false: ["flex", "flex-row", "items-center", "gap-1"],
3728
3752
  },
3729
3753
  },
3730
3754
  defaultVariants: {
3731
- backgroundColor: "info",
3755
+ isDefaultAndHasTrendValue: true,
3732
3756
  },
3733
3757
  });
3734
3758
 
3735
- const LoadingContent = () => (jsxs("div", { className: "flex flex-row items-center gap-3", "data-testid": "kpi-card-loading-content", children: [jsx("div", { children: jsx(SkeletonLines, { height: 28, lines: 1, width: 28 }) }), jsx("div", { className: "w-full", children: jsx(SkeletonLines, { height: [18, 20], lines: 2, margin: "3px 0", width: [50, 100] }) })] }));
3759
+ const LoadingContent = () => (jsx("div", { className: "flex flex-row items-center gap-3", "data-testid": "kpi-card-loading-content", children: jsx("div", { className: "w-full", children: jsx(SkeletonLines, { height: [18, 20], lines: 2, margin: "3px 0", width: [50, 100] }) }) }));
3736
3760
  /**
3737
3761
  * The KPICard component is used to display KPIs.
3738
3762
  *
3739
3763
  * @param {KPICardProps} props - The props for the KPICard component
3740
3764
  * @returns {JSX.Element} KPICard component
3741
3765
  */
3742
- const KPICard = ({ asChild = false, title, value, loading, unit, iconName, iconBackgroundColor, className, dataTestId, tooltipLabel, isActive, onClick, ...rest }) => {
3766
+ const KPICard = ({ asChild = false, title, value, loading, unit, className, dataTestId, tooltipLabel, isActive, variant = "default", trend, onClick, ...rest }) => {
3743
3767
  const Comp = asChild ? Slot : "div";
3744
- const CardContent = () => {
3745
- return (jsx(Card, { className: cvaKPICard({ isClickable: Boolean((onClick || asChild) && !loading), isActive }), children: loading ? (jsx(LoadingContent, {})) : (jsxs(Fragment, { children: [iconName ? (jsx("div", { className: cvaKPICardIconContainer({ backgroundColor: iconBackgroundColor }), "data-testid": `${dataTestId}-icon-container`, children: jsx(Icon, { color: "white", dataTestId: `${dataTestId}-icon`, name: iconName, size: "medium" }) })) : null, jsxs("div", { children: [jsx(Text, { dataTestId: `${dataTestId}-title`, subtle: true, weight: "bold", children: title }), jsxs(Text, { dataTestId: `${dataTestId}-value`, size: "large", weight: "bold", children: [value, " ", unit] })] })] })) }));
3768
+ const isSmallVariant = variant === "small";
3769
+ const TrendIndicator = () => {
3770
+ var _a, _b;
3771
+ if (!trend) {
3772
+ return null;
3773
+ }
3774
+ return (jsxs("div", { className: "flex flex-row items-center gap-1", "data-testid": "trend-indicator", children: [!isSmallVariant && trend.value ? (jsxs(Text, { dataTestId: "trend-value", size: "small", weight: "normal", children: [trend.value, " ", unit] })) : null, ((_a = trend.variant) === null || _a === void 0 ? void 0 : _a.icon) ? jsx(Icon, { color: trend.variant.color, name: trend.variant.icon, size: "small" }) : null, trend.percentage ? (jsxs(Text, { className: cvaKPICardTrendPercentage({ color: (_b = trend.variant) === null || _b === void 0 ? void 0 : _b.color }), size: "small", weight: "bold", children: [trend.percentage, "%"] })) : null] }));
3746
3775
  };
3776
+ const CardContent = () => (jsx(Card, { className: cvaKPICard({ isClickable: Boolean((onClick || asChild) && !loading), isActive, variant }), children: loading ? (jsx(LoadingContent, {})) : (jsxs("div", { children: [jsx(Text, { dataTestId: `${dataTestId}-title`, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsx(Text, { className: isSmallVariant ? "mt-0.5" : "", dataTestId: `${dataTestId}-value`, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: jsxs("div", { className: cvaKPICardValueContainer({
3777
+ isDefaultAndHasTrendValue: Boolean((trend === null || trend === void 0 ? void 0 : trend.value) && !isSmallVariant),
3778
+ }), children: [jsxs("span", { children: [value, " ", unit] }), jsx(TrendIndicator, {})] }) })] })) }));
3747
3779
  return (jsxs(Comp, { className: cvaKPICardContainer({ className, isClickable: Boolean(asChild || onClick) }), "data-testid": `${dataTestId}-comp`, onClick: onClick, ...rest, children: [tooltipLabel ? (jsx(Tooltip, { className: "w-full", label: tooltipLabel, placement: "bottom", children: jsx(CardContent, {}) })) : (jsx(CardContent, {})), !loading && jsx(Slottable, { children: rest.children })] }));
3748
3780
  };
3749
3781
 
@@ -4276,6 +4308,7 @@ const Polygon = ({ points, size, color = "black", opaque = true, className, data
4276
4308
  const normalize = ({ value, min, max, size }) => ((value - min) / (max - min)) * size;
4277
4309
 
4278
4310
  function useConfirmExit(confirmExit, when = true) {
4311
+ // eslint-disable-next-line sonarjs/deprecation
4279
4312
  useBlocker(confirmExit, when);
4280
4313
  }
4281
4314
  /**
@@ -4378,7 +4411,7 @@ const cvaSidebarChildContainer = cvaMerge(["apply", "flex", "overflow-hidden", "
4378
4411
  */
4379
4412
  const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id", children, }) => {
4380
4413
  const [itemOverflowMap, setItemOverflowMap] = useState({});
4381
- const overflowContainerRef = useRef(null); // TODO: Handle other elements than div
4414
+ const overflowContainerRef = useRef(null);
4382
4415
  const observerRef = useRef(null);
4383
4416
  const handleIntersection = useCallback(entries => {
4384
4417
  const updatedEntries = {};
@@ -4588,6 +4621,7 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
4588
4621
  * Individual ToggleItem to create custom ToggleGroups
4589
4622
  */
4590
4623
  const ToggleItem = ({ title, onClick, disabled = false, isIconOnly = false, iconName, size, className, selected = false, text, tooltip, dataTestId, }) => {
4624
+ // eslint-disable-next-line sonarjs/no-selector-parameter
4591
4625
  return isIconOnly ? (jsx(Tooltip, { label: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.content) || title, placement: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.placement) || "top", children: jsx(IconButton, { className: cvaToggleItem({ className, selected }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsx(Icon, { className: selected ? "text-slate-600" : "text-slate-400", name: iconName, size: "small" })) : null, onClick: onClick, size: size, title: iconName, variant: "secondary" }) })) : (jsx(Tooltip, { disabled: !(text === null || text === void 0 ? void 0 : text.truncate) && (tooltip === null || tooltip === void 0 ? void 0 : tooltip.content) === undefined, label: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.content) || title, placement: (tooltip === null || tooltip === void 0 ? void 0 : tooltip.placement) || "top", children: jsx(Button, { className: cvaToggleItem({ className, selected }), "data-testid": dataTestId, disabled: disabled, onClick: onClick, prefix: iconName ? (jsx(Icon, { className: selected ? "text-slate-600" : "text-slate-400", name: iconName, size: "small" })) : null, size: size, variant: "secondary", children: jsx("span", { className: cvaToggleItemText({ disabledAndSelected: disabled && selected, maxWidth: text === null || text === void 0 ? void 0 : text.maxWidth }), children: title }) }) }));
4592
4626
  };
4593
4627
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "0.5.38",
3
+ "version": "0.5.40",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -1,5 +1,3 @@
1
- import { IntentColors } from "@trackunit/ui-design-tokens";
2
- import { IconName } from "@trackunit/ui-icons";
3
1
  import { ReactNode } from "react";
4
2
  import { CommonProps } from "../../common";
5
3
  export interface KPICardProps extends CommonProps {
@@ -19,14 +17,6 @@ export interface KPICardProps extends CommonProps {
19
17
  * Whether or not to show the loading state
20
18
  */
21
19
  loading?: boolean;
22
- /**
23
- * The icon to be displayed in the prefix
24
- */
25
- iconName?: IconName;
26
- /**
27
- * The icon to be displayed in the prefix
28
- */
29
- iconBackgroundColor?: IntentColors;
30
20
  /**
31
21
  * Use asChild to render the KPICard as another component
32
22
  */
@@ -49,6 +39,36 @@ export interface KPICardProps extends CommonProps {
49
39
  * Is the kpi card active
50
40
  */
51
41
  isActive?: boolean;
42
+ /**
43
+ * The size of the KPI Card
44
+ */
45
+ variant?: "small" | "default";
46
+ /**
47
+ * The trend of the KPI Card
48
+ */
49
+ trend?: {
50
+ /**
51
+ * The value of the trend
52
+ */
53
+ value?: number | string;
54
+ /**
55
+ * The percentage of the trend
56
+ */
57
+ percentage?: number | string;
58
+ /**
59
+ * The variant of the trend
60
+ */
61
+ variant?: {
62
+ /**
63
+ * The icon of the trend
64
+ */
65
+ icon?: "ArrowUp" | "ArrowDown" | "ArrowTrendingUp" | "ArrowTrendingDown";
66
+ /**
67
+ * The color of the trend
68
+ */
69
+ color?: "success" | "danger" | "neutral";
70
+ };
71
+ };
52
72
  /**
53
73
  * On kpi card click handler
54
74
  */
@@ -60,4 +80,4 @@ export interface KPICardProps extends CommonProps {
60
80
  * @param {KPICardProps} props - The props for the KPICard component
61
81
  * @returns {JSX.Element} KPICard component
62
82
  */
63
- export declare const KPICard: ({ asChild, title, value, loading, unit, iconName, iconBackgroundColor, className, dataTestId, tooltipLabel, isActive, onClick, ...rest }: KPICardProps) => JSX.Element;
83
+ export declare const KPICard: ({ asChild, title, value, loading, unit, className, dataTestId, tooltipLabel, isActive, variant, trend, onClick, ...rest }: KPICardProps) => JSX.Element;
@@ -4,7 +4,11 @@ export declare const cvaKPICardContainer: (props?: ({
4
4
  export declare const cvaKPICard: (props?: ({
5
5
  isClickable?: boolean | null | undefined;
6
6
  isActive?: boolean | null | undefined;
7
+ variant?: "default" | "small" | null | undefined;
7
8
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
8
- export declare const cvaKPICardIconContainer: (props?: ({
9
- backgroundColor?: "info" | "success" | "warning" | "danger" | null | undefined;
9
+ export declare const cvaKPICardTrendPercentage: (props?: ({
10
+ color?: "success" | "danger" | "neutral" | null | undefined;
11
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
12
+ export declare const cvaKPICardValueContainer: (props?: ({
13
+ isDefaultAndHasTrendValue?: boolean | null | undefined;
10
14
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
@@ -4,7 +4,7 @@ import { cvaInteractableItem } from "../../InteractableItem/InteractableItem.var
4
4
  import { MenuItemVariant } from "./MenuItem";
5
5
  type CvaMenuItemProps = Partial<MappedOmit<VariantProps<typeof cvaInteractableItem>, "cursor">> & {
6
6
  variant?: MenuItemVariant;
7
- selected?: boolean | null | undefined;
7
+ selected: boolean | null | undefined;
8
8
  };
9
9
  /**
10
10
  * Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
@@ -0,0 +1,12 @@
1
+ import { RenderHookOptions } from "@testing-library/react";
2
+ /**
3
+ * Custom renderHook function to avoid boilerplate
4
+ *
5
+ * @template T
6
+ * @template K
7
+ * @param {(props: T) => K} callback - callback function
8
+ * @param {RenderHookOptions<T>} [options] - options
9
+ */
10
+ declare const customRenderHook: <TProps, TReturn>(callback: (props: TProps) => TReturn, options?: RenderHookOptions<TProps>) => import("@testing-library/react").RenderHookResult<TReturn, TProps>;
11
+ export * from "@testing-library/react";
12
+ export { customRenderHook as renderHook };
@@ -0,0 +1,12 @@
1
+ import { RenderOptions, RenderResult } from "@testing-library/react";
2
+ import * as React from "react";
3
+ /**
4
+ * Enhanced render with providers
5
+ *
6
+ * @param ui - The UI to render
7
+ * @param options - The options for the render
8
+ * @returns {RenderResult} The rendered UI
9
+ */
10
+ declare const customRender: (ui: React.ReactElement, options?: Omit<RenderOptions, "wrapper">) => RenderResult;
11
+ export * from "@testing-library/react";
12
+ export { customRender as render };