@trackunit/react-components 1.17.5 → 1.17.7

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
@@ -1289,15 +1289,15 @@ const useViewportBreakpoints = (options = {}) => {
1289
1289
 
1290
1290
  const cvaBreadcrumb = cssClassVarianceUtilities.cvaMerge(["my-4", "flex", "place-items-center"]);
1291
1291
  const cvaBreadcrumbItem = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"]);
1292
- const cvaBreadcrumbForLargeScreen = cssClassVarianceUtilities.cvaMerge(["flex", "flex-nowrap"]);
1293
- const cvaBreadcrumbForMediumScreen = cssClassVarianceUtilities.cvaMerge(["flex"], {
1292
+ const cvaBreadcrumbForLargeScreen = cssClassVarianceUtilities.cvaMerge(["flex", "flex-nowrap", "items-center"]);
1293
+ const cvaBreadcrumbForMediumScreen = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"], {
1294
1294
  variants: {
1295
1295
  expanded: {
1296
1296
  true: "flex-wrap",
1297
1297
  false: "flex-nowrap",
1298
1298
  },
1299
- defaultVariants: { expanded: false },
1300
1299
  },
1300
+ defaultVariants: { expanded: false },
1301
1301
  });
1302
1302
 
1303
1303
  /**
@@ -1322,7 +1322,7 @@ const BreadcrumbForMediumScreen = ({ "data-testid": dataTestId, breadcrumbItems,
1322
1322
  const [expanded, setExpanded] = react.useState(false);
1323
1323
  const getReducedArray = react.useCallback(() => {
1324
1324
  let reducedArrayElements = [];
1325
- const collapsibleButton = (jsxRuntime.jsxs("div", { className: cvaBreadcrumbItem(), children: [jsxRuntime.jsx(IconButton, { "data-testid": `collapsibleButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal", size: "small" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx(Icon, { color: "neutral", name: "Slash", size: "small" })] }));
1325
+ const collapsibleButton = (jsxRuntime.jsxs("div", { className: cvaBreadcrumbItem(), children: [jsxRuntime.jsx(IconButton, { "data-testid": `collapsibleButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx(Icon, { className: "text-neutral-300", name: "Slash", size: "small" })] }));
1326
1326
  const firstBreadcrumbItem = breadcrumbItems[0];
1327
1327
  if (firstBreadcrumbItem && breadcrumbItems.length > 3) {
1328
1328
  const lastTwoBreadcrumbItem = breadcrumbItems.slice(-2);
@@ -1349,9 +1349,9 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1349
1349
  const breadCrumbItemsToJSX = breadcrumbItems.map((item, index, array) => {
1350
1350
  const isLast = index === array.length - 1;
1351
1351
  if (!isLast) {
1352
- return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(Button, { asChild: true, size: "small", variant: "ghost-neutral", children: jsxRuntime.jsx(reactRouter.Link, { to: item.to, children: item.label }) }), jsxRuntime.jsx(Icon, { className: "text-neutral-300", name: "Slash", size: "small" })] }, index));
1352
+ return (jsxRuntime.jsxs("div", { className: "flex items-center", children: [jsxRuntime.jsx(Button, { asChild: true, size: "small", variant: "ghost-neutral", children: jsxRuntime.jsx(reactRouter.Link, { to: item.to, children: item.label }) }), jsxRuntime.jsx(Icon, { className: "text-neutral-300", name: "Slash", size: "small" })] }, index));
1353
1353
  }
1354
- return (jsxRuntime.jsx(Text, { className: "text-nowrap", size: "small", children: item.label }, index));
1354
+ return (jsxRuntime.jsx(Text, { className: "text-nowrap pl-2 font-medium", size: "small", children: item.label }, index));
1355
1355
  });
1356
1356
  return breadCrumbItemsToJSX;
1357
1357
  };
@@ -1359,6 +1359,9 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1359
1359
  /**
1360
1360
  * The breadcrumb component shows a user's location in a website or application. Breadcrumbs are particularly useful when a large amount of content is organized in a hierarchical manner. They streamline navigation, minimize the steps required to revisit previous pages, and offer contextual insights to the users.
1361
1361
  *
1362
+ * All items except the last are rendered as clickable links. The last item is rendered as plain text representing the current page.
1363
+ * The component automatically adapts to the screen size: on large screens all items are visible, on medium screens middle items collapse behind an ellipsis button, and on small screens only the current page is shown.
1364
+ *
1362
1365
  * ### When to use
1363
1366
  * Use breadcrumbs when deep navigation is available, on apps or pages where users might dive into content and could benefit from a quick way to return to higher levels. Breadcrumbs display the current screen as the final item in the list to make it clear where the user is.
1364
1367
  *
@@ -1381,7 +1384,7 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1381
1384
  * { label: "Assets", to: "/fleet/assets" },
1382
1385
  * { label: "Excavator 001", to: "/fleet/assets/123" },
1383
1386
  * ]}
1384
- * back={() => navigate({ to: "/fleet/assets" })}
1387
+ * onClickBack={() => navigate({ to: "/fleet/assets" })}
1385
1388
  * />
1386
1389
  * );
1387
1390
  * };
@@ -4086,7 +4089,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4086
4089
  * import { Tooltip, IconButton, Icon } from "@trackunit/react-components";
4087
4090
  *
4088
4091
  * const SettingsButton = () => (
4089
- * <Tooltip label="Open settings" placement="bottom">
4092
+ * <Tooltip asChild={false} label="Open settings" placement="bottom">
4090
4093
  * <IconButton
4091
4094
  * icon={<Icon name="Cog6Tooth" size="small" />}
4092
4095
  * variant="ghost-neutral"
@@ -4102,7 +4105,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4102
4105
  * const FieldWithHelp = () => (
4103
4106
  * <div className="flex items-center gap-2">
4104
4107
  * <span>Utilization Rate</span>
4105
- * <Tooltip
4108
+ * <Tooltip asChild={false}
4106
4109
  * label="The percentage of time the asset was actively in use during the selected period"
4107
4110
  * placement="right"
4108
4111
  * mode="light"
@@ -4113,7 +4116,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4113
4116
  * @param {TooltipProps} props - The props for the Tooltip component
4114
4117
  * @returns {ReactElement} Tooltip component
4115
4118
  */
4116
- const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, className, label, placement = "auto", mode = "dark", iconProps, id, style, }) => {
4119
+ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, className, label, placement = "auto", mode = "dark", iconProps, id, style, asChild = true, }) => {
4117
4120
  const [isOpen, setIsOpen] = react.useState(false);
4118
4121
  const arrowRef = react.useRef(null);
4119
4122
  const { refs, floatingStyles, context } = react$1.useFloating({
@@ -4133,7 +4136,12 @@ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, classN
4133
4136
  const { isMounted } = react$1.useTransitionStatus(context);
4134
4137
  // Please don't try to move this into the component body directly
4135
4138
  // I tried and it caused infinite re-renders some places (for whatever reason)
4136
- const wrappedChildren = react.useMemo(() => (jsxRuntime.jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children })), [children, className, dataTestId]);
4139
+ const wrappedChildren = react.useMemo(() => {
4140
+ if (asChild) {
4141
+ return (jsxRuntime.jsx(reactSlot.Slot, { className: className, "data-testid": dataTestId ? `${dataTestId}-child` : undefined, children: children }));
4142
+ }
4143
+ return (jsxRuntime.jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children }));
4144
+ }, [asChild, children, className, dataTestId]);
4137
4145
  const openTooltip = react.useCallback(() => {
4138
4146
  if (disabled) {
4139
4147
  return;
@@ -4305,7 +4313,7 @@ const cvaIndicatorIconBackground = cssClassVarianceUtilities.cvaMerge(["rounded-
4305
4313
  * @returns {ReactElement} Indicator component
4306
4314
  */
4307
4315
  const Indicator = ({ "data-testid": dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false, size = "medium", weight = "normal", className, ...rest }) => {
4308
- return (jsxRuntime.jsx(Tooltip, { className: className, disabled: withLabel, label: label, placement: "bottom", children: jsxRuntime.jsxs("div", { "aria-label": label, className: cvaIndicator(), "data-testid": dataTestId, ...rest, children: [jsxRuntime.jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping ? (jsxRuntime.jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })) : null, icon] }), label && withLabel ? (jsxRuntime.jsx("div", { className: cvaIndicatorLabel({ size, weight, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: label })) : null] }) }));
4316
+ return (jsxRuntime.jsx(Tooltip, { asChild: false, className: className, disabled: withLabel, label: label, placement: "bottom", children: jsxRuntime.jsxs("div", { "aria-label": label, className: cvaIndicator(), "data-testid": dataTestId, ...rest, children: [jsxRuntime.jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping ? (jsxRuntime.jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })) : null, icon] }), label && withLabel ? (jsxRuntime.jsx("div", { className: cvaIndicatorLabel({ size, weight, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: label })) : null] }) }));
4309
4317
  };
4310
4318
 
4311
4319
  /**
@@ -4439,7 +4447,7 @@ const cvaKPITrendPercentage = cssClassVarianceUtilities.cvaMerge([""], {
4439
4447
  */
4440
4448
  const KPI = ({ title, value, unit, className, "data-testid": dataTestId, tooltipLabel, variant = "default", style, ...rest }) => {
4441
4449
  const isSmallVariant = variant === "small";
4442
- return (jsxRuntime.jsx(Tooltip, { className: "min-w-8 shrink-0", "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, disabled: tooltipLabel === undefined || tooltipLabel === "", label: tooltipLabel, placement: "bottom", children: jsxRuntime.jsxs("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId, style: style, ...rest, children: [jsxRuntime.jsx(Text, { className: tailwindMerge.twMerge("truncate", "whitespace-nowrap"), "data-testid": dataTestId ? `${dataTestId}-title` : undefined, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("truncate", "whitespace-nowrap"), children: jsxRuntime.jsxs(Text, { className: "truncate whitespace-nowrap text-lg font-medium", "data-testid": dataTestId ? `${dataTestId}-value` : undefined, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: [value, " ", unit] }) })] }) }));
4450
+ return (jsxRuntime.jsx(Tooltip, { asChild: false, className: "min-w-8 shrink-0", "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, disabled: tooltipLabel === undefined || tooltipLabel === "", label: tooltipLabel, placement: "bottom", children: jsxRuntime.jsxs("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId, style: style, ...rest, children: [jsxRuntime.jsx(Text, { className: tailwindMerge.twMerge("truncate", "whitespace-nowrap"), "data-testid": dataTestId ? `${dataTestId}-title` : undefined, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("truncate", "whitespace-nowrap"), children: jsxRuntime.jsxs(Text, { className: "truncate whitespace-nowrap text-lg font-medium", "data-testid": dataTestId ? `${dataTestId}-value` : undefined, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: [value, " ", unit] }) })] }) }));
4443
4451
  };
4444
4452
 
4445
4453
  /**
@@ -5701,7 +5709,7 @@ const cvaNoticeIcon = cssClassVarianceUtilities.cvaMerge(["rounded-full", "items
5701
5709
  * @returns {ReactElement} Notice component
5702
5710
  */
5703
5711
  const Notice = ({ "data-testid": dataTestId, iconName = undefined, iconSize = "medium", iconColor = undefined, label, color = "neutral", withLabel = true, className, tooltipLabel = label, withTooltip = false, size = "medium", ...rest }) => {
5704
- return (jsxRuntime.jsx(Tooltip, { className: className, disabled: withTooltip === false, label: tooltipLabel, placement: "bottom", children: jsxRuntime.jsxs("div", { "aria-label": label, className: cvaNotice(), "data-testid": dataTestId, ...rest, children: [sharedUtils.nonNullable(iconName) ? (jsxRuntime.jsx("div", { className: cvaNoticeIcon({ color: iconColor || color }), "data-testid": dataTestId ? `${dataTestId}-icon` : "notice-icon", children: jsxRuntime.jsx(Icon, { name: iconName, size: iconSize }) })) : null, label && withLabel ? (jsxRuntime.jsx("div", { className: cvaNoticeLabel({ color, size }), "data-testid": dataTestId ? `${dataTestId}-label` : "notice-label", children: label })) : null] }) }));
5712
+ return (jsxRuntime.jsx(Tooltip, { asChild: false, className: className, disabled: withTooltip === false, label: tooltipLabel, placement: "bottom", children: jsxRuntime.jsxs("div", { "aria-label": label, className: cvaNotice(), "data-testid": dataTestId, ...rest, children: [sharedUtils.nonNullable(iconName) ? (jsxRuntime.jsx("div", { className: cvaNoticeIcon({ color: iconColor || color }), "data-testid": dataTestId ? `${dataTestId}-icon` : "notice-icon", children: jsxRuntime.jsx(Icon, { name: iconName, size: iconSize }) })) : null, label && withLabel ? (jsxRuntime.jsx("div", { className: cvaNoticeLabel({ color, size }), "data-testid": dataTestId ? `${dataTestId}-label` : "notice-label", children: label })) : null] }) }));
5705
5713
  };
5706
5714
 
5707
5715
  const cvaPage = cssClassVarianceUtilities.cvaMerge(["grid", "h-full"], {
@@ -5918,7 +5926,7 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
5918
5926
  externalOnClick?.();
5919
5927
  }, prefix: prefixIconName ? jsxRuntime.jsx(Icon, { name: prefixIconName, size: "small" }) : undefined, size: "small", variant: variant, children: actionText }));
5920
5928
  // Wrap `content` with Tooltip
5921
- const wrappedWithTooltip = tooltipLabel ? (jsxRuntime.jsx(Tooltip, { className: "block", label: tooltipLabel, children: content })) : (content);
5929
+ const wrappedWithTooltip = tooltipLabel ? (jsxRuntime.jsx(Tooltip, { asChild: false, className: "block", label: tooltipLabel, children: content })) : (content);
5922
5930
  // Finally, wrap with Link if `to` is provided
5923
5931
  return to !== undefined && to !== "" ? (jsxRuntime.jsx(reactRouter.Link, { target: target, to: to, children: wrappedWithTooltip })) : (wrappedWithTooltip);
5924
5932
  }
@@ -6036,7 +6044,7 @@ const cvaPageHeaderHeading = cssClassVarianceUtilities.cvaMerge(["text-neutral-9
6036
6044
  */
6037
6045
  const PageHeaderTitle = ({ title, "data-testid": dataTestId, className, }) => {
6038
6046
  const { ref, isTextTruncated } = useIsTextTruncated();
6039
- return (jsxRuntime.jsx("div", { className: "flex flex-row items-center", children: jsxRuntime.jsx(Tooltip, { className: "grid min-w-16", disabled: !isTextTruncated, label: title, placement: "top", children: jsxRuntime.jsx("h1", { className: cvaPageHeaderHeading({ className }), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, ref: ref, children: title }) }) }));
6047
+ return (jsxRuntime.jsx("div", { className: "flex flex-row items-center", children: jsxRuntime.jsx(Tooltip, { asChild: false, className: "grid min-w-16", disabled: !isTextTruncated, label: title, placement: "top", children: jsxRuntime.jsx("h1", { className: cvaPageHeaderHeading({ className }), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, ref: ref, children: title }) }) }));
6040
6048
  };
6041
6049
 
6042
6050
  /**
@@ -6094,18 +6102,18 @@ const PageHeader = ({ className, "data-testid": dataTestId, showLoading = false,
6094
6102
  return null;
6095
6103
  }
6096
6104
  // If the user passes a string, we render the string as a tag with props provided.
6097
- return (jsxRuntime.jsx("div", { className: "ml-auto flex flex-row gap-2", children: jsxRuntime.jsx(Tooltip, { "data-testid": "page-header-tag-tooltip", disabled: tagTooltipLabel === undefined || tagTooltipLabel === "", label: tagTooltipLabel, placement: "top", children: jsxRuntime.jsx(Tag, { color: tagColor, "data-testid": "page-header-tag", children: tagLabel }) }) }));
6105
+ return (jsxRuntime.jsx("div", { className: "ml-auto flex flex-row gap-2", children: jsxRuntime.jsx(Tooltip, { asChild: false, "data-testid": "page-header-tag-tooltip", disabled: tagTooltipLabel === undefined || tagTooltipLabel === "", label: tagTooltipLabel, placement: "top", children: jsxRuntime.jsx(Tag, { color: tagColor, "data-testid": "page-header-tag", children: tagLabel }) }) }));
6098
6106
  }, [showLoading, tagColor, tagLabel, tagTooltipLabel]);
6099
6107
  return (jsxRuntime.jsxs("div", { className: cvaPageHeaderContainer({
6100
6108
  className,
6101
6109
  withBorder: tabsList === undefined,
6102
- }), "data-testid": dataTestId, children: [jsxRuntime.jsxs("div", { className: cvaPageHeader(), children: [backTo ? (jsxRuntime.jsx(reactRouter.Link, { to: backTo, children: jsxRuntime.jsx(Button, { className: "mr-4 bg-black/5 hover:bg-black/10", prefix: jsxRuntime.jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "small", square: true, variant: "ghost-neutral" }) })) : undefined, typeof title === "string" ? jsxRuntime.jsx(PageHeaderTitle, { "data-testid": dataTestId, title: title }) : title, tagRenderer || (description !== null && description !== undefined) ? (jsxRuntime.jsxs("div", { className: "mx-2 flex items-center gap-2", children: [description !== null && description !== undefined && !showLoading ? (jsxRuntime.jsx(Tooltip, { "data-testid": dataTestId ? `${dataTestId}-description-tooltip` : undefined, iconProps: {
6110
+ }), "data-testid": dataTestId, children: [jsxRuntime.jsxs("div", { className: cvaPageHeader(), children: [backTo ? (jsxRuntime.jsx(reactRouter.Link, { to: backTo, children: jsxRuntime.jsx(Button, { className: "mr-4 bg-black/5 hover:bg-black/10", prefix: jsxRuntime.jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "small", square: true, variant: "ghost-neutral" }) })) : undefined, typeof title === "string" ? jsxRuntime.jsx(PageHeaderTitle, { "data-testid": dataTestId, title: title }) : title, tagRenderer || (description !== null && description !== undefined) ? (jsxRuntime.jsxs("div", { className: "mx-2 flex items-center gap-2", children: [description !== null && description !== undefined && !showLoading ? (jsxRuntime.jsx(Tooltip, { asChild: false, "data-testid": dataTestId ? `${dataTestId}-description-tooltip` : undefined, iconProps: {
6103
6111
  name: descriptionIcon,
6104
6112
  "data-testid": "page-header-description-icon",
6105
6113
  }, label: description, placement: "bottom" })) : undefined, tagRenderer] })) : null, jsxRuntime.jsxs("div", { className: "ml-auto flex gap-2", children: [discriminatedProps.accessoryType === "kpi-metrics" ? (jsxRuntime.jsx(PageHeaderKpiMetrics, { kpiMetrics: discriminatedProps.kpiMetrics })) : null, discriminatedProps.accessoryType === "actions" ? (Array.isArray(discriminatedProps.secondaryActions) ? (jsxRuntime.jsx(PageHeaderSecondaryActions, { actions: discriminatedProps.secondaryActions, groupActions: discriminatedProps.groupSecondaryActions ?? false, hasPrimaryAction: !!discriminatedProps.primaryAction })) : discriminatedProps.secondaryActions !== null && discriminatedProps.secondaryActions !== undefined ? (discriminatedProps.secondaryActions) : null) : null, discriminatedProps.accessoryType === "actions" &&
6106
6114
  discriminatedProps.primaryAction !== undefined &&
6107
6115
  (discriminatedProps.primaryAction.hidden === false ||
6108
- discriminatedProps.primaryAction.hidden === undefined) ? (jsxRuntime.jsx(Tooltip, { disabled: discriminatedProps.primaryAction.tooltipLabel === undefined ||
6116
+ discriminatedProps.primaryAction.hidden === undefined) ? (jsxRuntime.jsx(Tooltip, { asChild: false, disabled: discriminatedProps.primaryAction.tooltipLabel === undefined ||
6109
6117
  discriminatedProps.primaryAction.tooltipLabel === "", label: discriminatedProps.primaryAction.tooltipLabel, children: jsxRuntime.jsx(Button, { "data-testid": discriminatedProps.primaryAction["data-testid"], disabled: discriminatedProps.primaryAction.disabled, loading: discriminatedProps.primaryAction.loading, onClick: () => discriminatedProps.primaryAction?.actionCallback?.(), prefix: discriminatedProps.primaryAction.prefixIconName !== undefined ? (jsxRuntime.jsx(Icon, { name: discriminatedProps.primaryAction.prefixIconName, size: "small" })) : undefined, size: "small", variant: discriminatedProps.primaryAction.variant, children: discriminatedProps.primaryAction.actionText }) })) : null] })] }), tabsList] }));
6110
6118
  };
6111
6119
 
@@ -6953,11 +6961,11 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
6953
6961
  }, ref: el => (buttonRefs.current[index] = el), selected: selected === item.id, size: size, text: item.text, title: item.title, tooltip: item.tooltip }, item.id))) }));
6954
6962
  };
6955
6963
  const ToggleItem = ({ title, onClick, disabled, isIconOnly, iconName = undefined, size, className, selected, text, tooltip, "data-testid": dataTestId, ref, }) => {
6956
- return isIconOnly ? (jsxRuntime.jsx(Tooltip, { label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsxRuntime.jsx(ToggleButton, { className: cvaToggleItem({
6964
+ return isIconOnly ? (jsxRuntime.jsx(Tooltip, { asChild: false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsxRuntime.jsx(ToggleButton, { className: cvaToggleItem({
6957
6965
  className,
6958
6966
  selected,
6959
6967
  disabled,
6960
- }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsxRuntime.jsx(Icon, { className: cvaToggleItemContent({ selected, disabled }), name: iconName, size: size === "large" ? "medium" : "small" })) : null, isIconOnly: isIconOnly, onClick: onClick, ref: ref, size: size, title: title }) })) : (jsxRuntime.jsx(Tooltip, { disabled: !tooltip?.content && text?.truncate === false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsxRuntime.jsx(ToggleButton, { className: cvaToggleItem({
6968
+ }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsxRuntime.jsx(Icon, { className: cvaToggleItemContent({ selected, disabled }), name: iconName, size: size === "large" ? "medium" : "small" })) : null, isIconOnly: isIconOnly, onClick: onClick, ref: ref, size: size, title: title }) })) : (jsxRuntime.jsx(Tooltip, { asChild: false, disabled: !tooltip?.content && text?.truncate === false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsxRuntime.jsx(ToggleButton, { className: cvaToggleItem({
6961
6969
  className,
6962
6970
  selected,
6963
6971
  disabled,
package/index.esm.js CHANGED
@@ -1287,15 +1287,15 @@ const useViewportBreakpoints = (options = {}) => {
1287
1287
 
1288
1288
  const cvaBreadcrumb = cvaMerge(["my-4", "flex", "place-items-center"]);
1289
1289
  const cvaBreadcrumbItem = cvaMerge(["flex", "items-center"]);
1290
- const cvaBreadcrumbForLargeScreen = cvaMerge(["flex", "flex-nowrap"]);
1291
- const cvaBreadcrumbForMediumScreen = cvaMerge(["flex"], {
1290
+ const cvaBreadcrumbForLargeScreen = cvaMerge(["flex", "flex-nowrap", "items-center"]);
1291
+ const cvaBreadcrumbForMediumScreen = cvaMerge(["flex", "items-center"], {
1292
1292
  variants: {
1293
1293
  expanded: {
1294
1294
  true: "flex-wrap",
1295
1295
  false: "flex-nowrap",
1296
1296
  },
1297
- defaultVariants: { expanded: false },
1298
1297
  },
1298
+ defaultVariants: { expanded: false },
1299
1299
  });
1300
1300
 
1301
1301
  /**
@@ -1320,7 +1320,7 @@ const BreadcrumbForMediumScreen = ({ "data-testid": dataTestId, breadcrumbItems,
1320
1320
  const [expanded, setExpanded] = useState(false);
1321
1321
  const getReducedArray = useCallback(() => {
1322
1322
  let reducedArrayElements = [];
1323
- const collapsibleButton = (jsxs("div", { className: cvaBreadcrumbItem(), children: [jsx(IconButton, { "data-testid": `collapsibleButton-${dataTestId}`, icon: jsx(Icon, { name: "EllipsisHorizontal", size: "small" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsx(Icon, { color: "neutral", name: "Slash", size: "small" })] }));
1323
+ const collapsibleButton = (jsxs("div", { className: cvaBreadcrumbItem(), children: [jsx(IconButton, { "data-testid": `collapsibleButton-${dataTestId}`, icon: jsx(Icon, { name: "EllipsisHorizontal" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsx(Icon, { className: "text-neutral-300", name: "Slash", size: "small" })] }));
1324
1324
  const firstBreadcrumbItem = breadcrumbItems[0];
1325
1325
  if (firstBreadcrumbItem && breadcrumbItems.length > 3) {
1326
1326
  const lastTwoBreadcrumbItem = breadcrumbItems.slice(-2);
@@ -1347,9 +1347,9 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1347
1347
  const breadCrumbItemsToJSX = breadcrumbItems.map((item, index, array) => {
1348
1348
  const isLast = index === array.length - 1;
1349
1349
  if (!isLast) {
1350
- return (jsxs("div", { children: [jsx(Button, { asChild: true, size: "small", variant: "ghost-neutral", children: jsx(Link, { to: item.to, children: item.label }) }), jsx(Icon, { className: "text-neutral-300", name: "Slash", size: "small" })] }, index));
1350
+ return (jsxs("div", { className: "flex items-center", children: [jsx(Button, { asChild: true, size: "small", variant: "ghost-neutral", children: jsx(Link, { to: item.to, children: item.label }) }), jsx(Icon, { className: "text-neutral-300", name: "Slash", size: "small" })] }, index));
1351
1351
  }
1352
- return (jsx(Text, { className: "text-nowrap", size: "small", children: item.label }, index));
1352
+ return (jsx(Text, { className: "text-nowrap pl-2 font-medium", size: "small", children: item.label }, index));
1353
1353
  });
1354
1354
  return breadCrumbItemsToJSX;
1355
1355
  };
@@ -1357,6 +1357,9 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1357
1357
  /**
1358
1358
  * The breadcrumb component shows a user's location in a website or application. Breadcrumbs are particularly useful when a large amount of content is organized in a hierarchical manner. They streamline navigation, minimize the steps required to revisit previous pages, and offer contextual insights to the users.
1359
1359
  *
1360
+ * All items except the last are rendered as clickable links. The last item is rendered as plain text representing the current page.
1361
+ * The component automatically adapts to the screen size: on large screens all items are visible, on medium screens middle items collapse behind an ellipsis button, and on small screens only the current page is shown.
1362
+ *
1360
1363
  * ### When to use
1361
1364
  * Use breadcrumbs when deep navigation is available, on apps or pages where users might dive into content and could benefit from a quick way to return to higher levels. Breadcrumbs display the current screen as the final item in the list to make it clear where the user is.
1362
1365
  *
@@ -1379,7 +1382,7 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
1379
1382
  * { label: "Assets", to: "/fleet/assets" },
1380
1383
  * { label: "Excavator 001", to: "/fleet/assets/123" },
1381
1384
  * ]}
1382
- * back={() => navigate({ to: "/fleet/assets" })}
1385
+ * onClickBack={() => navigate({ to: "/fleet/assets" })}
1383
1386
  * />
1384
1387
  * );
1385
1388
  * };
@@ -4084,7 +4087,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4084
4087
  * import { Tooltip, IconButton, Icon } from "@trackunit/react-components";
4085
4088
  *
4086
4089
  * const SettingsButton = () => (
4087
- * <Tooltip label="Open settings" placement="bottom">
4090
+ * <Tooltip asChild={false} label="Open settings" placement="bottom">
4088
4091
  * <IconButton
4089
4092
  * icon={<Icon name="Cog6Tooth" size="small" />}
4090
4093
  * variant="ghost-neutral"
@@ -4100,7 +4103,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4100
4103
  * const FieldWithHelp = () => (
4101
4104
  * <div className="flex items-center gap-2">
4102
4105
  * <span>Utilization Rate</span>
4103
- * <Tooltip
4106
+ * <Tooltip asChild={false}
4104
4107
  * label="The percentage of time the asset was actively in use during the selected period"
4105
4108
  * placement="right"
4106
4109
  * mode="light"
@@ -4111,7 +4114,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
4111
4114
  * @param {TooltipProps} props - The props for the Tooltip component
4112
4115
  * @returns {ReactElement} Tooltip component
4113
4116
  */
4114
- const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, className, label, placement = "auto", mode = "dark", iconProps, id, style, }) => {
4117
+ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, className, label, placement = "auto", mode = "dark", iconProps, id, style, asChild = true, }) => {
4115
4118
  const [isOpen, setIsOpen] = useState(false);
4116
4119
  const arrowRef = useRef(null);
4117
4120
  const { refs, floatingStyles, context } = useFloating({
@@ -4131,7 +4134,12 @@ const Tooltip = ({ children, "data-testid": dataTestId, disabled = false, classN
4131
4134
  const { isMounted } = useTransitionStatus(context);
4132
4135
  // Please don't try to move this into the component body directly
4133
4136
  // I tried and it caused infinite re-renders some places (for whatever reason)
4134
- const wrappedChildren = useMemo(() => (jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children })), [children, className, dataTestId]);
4137
+ const wrappedChildren = useMemo(() => {
4138
+ if (asChild) {
4139
+ return (jsx(Slot, { className: className, "data-testid": dataTestId ? `${dataTestId}-child` : undefined, children: children }));
4140
+ }
4141
+ return (jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children }));
4142
+ }, [asChild, children, className, dataTestId]);
4135
4143
  const openTooltip = useCallback(() => {
4136
4144
  if (disabled) {
4137
4145
  return;
@@ -4303,7 +4311,7 @@ const cvaIndicatorIconBackground = cvaMerge(["rounded-full", "items-center", "ju
4303
4311
  * @returns {ReactElement} Indicator component
4304
4312
  */
4305
4313
  const Indicator = ({ "data-testid": dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false, size = "medium", weight = "normal", className, ...rest }) => {
4306
- return (jsx(Tooltip, { className: className, disabled: withLabel, label: label, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaIndicator(), "data-testid": dataTestId, ...rest, children: [jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping ? (jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })) : null, icon] }), label && withLabel ? (jsx("div", { className: cvaIndicatorLabel({ size, weight, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: label })) : null] }) }));
4314
+ return (jsx(Tooltip, { asChild: false, className: className, disabled: withLabel, label: label, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaIndicator(), "data-testid": dataTestId, ...rest, children: [jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping ? (jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })) : null, icon] }), label && withLabel ? (jsx("div", { className: cvaIndicatorLabel({ size, weight, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: label })) : null] }) }));
4307
4315
  };
4308
4316
 
4309
4317
  /**
@@ -4437,7 +4445,7 @@ const cvaKPITrendPercentage = cvaMerge([""], {
4437
4445
  */
4438
4446
  const KPI = ({ title, value, unit, className, "data-testid": dataTestId, tooltipLabel, variant = "default", style, ...rest }) => {
4439
4447
  const isSmallVariant = variant === "small";
4440
- return (jsx(Tooltip, { className: "min-w-8 shrink-0", "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, disabled: tooltipLabel === undefined || tooltipLabel === "", label: tooltipLabel, placement: "bottom", children: jsxs("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId, style: style, ...rest, children: [jsx(Text, { className: twMerge("truncate", "whitespace-nowrap"), "data-testid": dataTestId ? `${dataTestId}-title` : undefined, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsx("div", { className: twMerge("truncate", "whitespace-nowrap"), children: jsxs(Text, { className: "truncate whitespace-nowrap text-lg font-medium", "data-testid": dataTestId ? `${dataTestId}-value` : undefined, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: [value, " ", unit] }) })] }) }));
4448
+ return (jsx(Tooltip, { asChild: false, className: "min-w-8 shrink-0", "data-testid": dataTestId ? `${dataTestId}-tooltip` : undefined, disabled: tooltipLabel === undefined || tooltipLabel === "", label: tooltipLabel, placement: "bottom", children: jsxs("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId, style: style, ...rest, children: [jsx(Text, { className: twMerge("truncate", "whitespace-nowrap"), "data-testid": dataTestId ? `${dataTestId}-title` : undefined, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsx("div", { className: twMerge("truncate", "whitespace-nowrap"), children: jsxs(Text, { className: "truncate whitespace-nowrap text-lg font-medium", "data-testid": dataTestId ? `${dataTestId}-value` : undefined, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: [value, " ", unit] }) })] }) }));
4441
4449
  };
4442
4450
 
4443
4451
  /**
@@ -5699,7 +5707,7 @@ const cvaNoticeIcon = cvaMerge(["rounded-full", "items-center", "justify-center"
5699
5707
  * @returns {ReactElement} Notice component
5700
5708
  */
5701
5709
  const Notice = ({ "data-testid": dataTestId, iconName = undefined, iconSize = "medium", iconColor = undefined, label, color = "neutral", withLabel = true, className, tooltipLabel = label, withTooltip = false, size = "medium", ...rest }) => {
5702
- return (jsx(Tooltip, { className: className, disabled: withTooltip === false, label: tooltipLabel, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaNotice(), "data-testid": dataTestId, ...rest, children: [nonNullable(iconName) ? (jsx("div", { className: cvaNoticeIcon({ color: iconColor || color }), "data-testid": dataTestId ? `${dataTestId}-icon` : "notice-icon", children: jsx(Icon, { name: iconName, size: iconSize }) })) : null, label && withLabel ? (jsx("div", { className: cvaNoticeLabel({ color, size }), "data-testid": dataTestId ? `${dataTestId}-label` : "notice-label", children: label })) : null] }) }));
5710
+ return (jsx(Tooltip, { asChild: false, className: className, disabled: withTooltip === false, label: tooltipLabel, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaNotice(), "data-testid": dataTestId, ...rest, children: [nonNullable(iconName) ? (jsx("div", { className: cvaNoticeIcon({ color: iconColor || color }), "data-testid": dataTestId ? `${dataTestId}-icon` : "notice-icon", children: jsx(Icon, { name: iconName, size: iconSize }) })) : null, label && withLabel ? (jsx("div", { className: cvaNoticeLabel({ color, size }), "data-testid": dataTestId ? `${dataTestId}-label` : "notice-label", children: label })) : null] }) }));
5703
5711
  };
5704
5712
 
5705
5713
  const cvaPage = cvaMerge(["grid", "h-full"], {
@@ -5916,7 +5924,7 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
5916
5924
  externalOnClick?.();
5917
5925
  }, prefix: prefixIconName ? jsx(Icon, { name: prefixIconName, size: "small" }) : undefined, size: "small", variant: variant, children: actionText }));
5918
5926
  // Wrap `content` with Tooltip
5919
- const wrappedWithTooltip = tooltipLabel ? (jsx(Tooltip, { className: "block", label: tooltipLabel, children: content })) : (content);
5927
+ const wrappedWithTooltip = tooltipLabel ? (jsx(Tooltip, { asChild: false, className: "block", label: tooltipLabel, children: content })) : (content);
5920
5928
  // Finally, wrap with Link if `to` is provided
5921
5929
  return to !== undefined && to !== "" ? (jsx(Link, { target: target, to: to, children: wrappedWithTooltip })) : (wrappedWithTooltip);
5922
5930
  }
@@ -6034,7 +6042,7 @@ const cvaPageHeaderHeading = cvaMerge(["text-neutral-900", "text-xl", "font-semi
6034
6042
  */
6035
6043
  const PageHeaderTitle = ({ title, "data-testid": dataTestId, className, }) => {
6036
6044
  const { ref, isTextTruncated } = useIsTextTruncated();
6037
- return (jsx("div", { className: "flex flex-row items-center", children: jsx(Tooltip, { className: "grid min-w-16", disabled: !isTextTruncated, label: title, placement: "top", children: jsx("h1", { className: cvaPageHeaderHeading({ className }), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, ref: ref, children: title }) }) }));
6045
+ return (jsx("div", { className: "flex flex-row items-center", children: jsx(Tooltip, { asChild: false, className: "grid min-w-16", disabled: !isTextTruncated, label: title, placement: "top", children: jsx("h1", { className: cvaPageHeaderHeading({ className }), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, ref: ref, children: title }) }) }));
6038
6046
  };
6039
6047
 
6040
6048
  /**
@@ -6092,18 +6100,18 @@ const PageHeader = ({ className, "data-testid": dataTestId, showLoading = false,
6092
6100
  return null;
6093
6101
  }
6094
6102
  // If the user passes a string, we render the string as a tag with props provided.
6095
- return (jsx("div", { className: "ml-auto flex flex-row gap-2", children: jsx(Tooltip, { "data-testid": "page-header-tag-tooltip", disabled: tagTooltipLabel === undefined || tagTooltipLabel === "", label: tagTooltipLabel, placement: "top", children: jsx(Tag, { color: tagColor, "data-testid": "page-header-tag", children: tagLabel }) }) }));
6103
+ return (jsx("div", { className: "ml-auto flex flex-row gap-2", children: jsx(Tooltip, { asChild: false, "data-testid": "page-header-tag-tooltip", disabled: tagTooltipLabel === undefined || tagTooltipLabel === "", label: tagTooltipLabel, placement: "top", children: jsx(Tag, { color: tagColor, "data-testid": "page-header-tag", children: tagLabel }) }) }));
6096
6104
  }, [showLoading, tagColor, tagLabel, tagTooltipLabel]);
6097
6105
  return (jsxs("div", { className: cvaPageHeaderContainer({
6098
6106
  className,
6099
6107
  withBorder: tabsList === undefined,
6100
- }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaPageHeader(), children: [backTo ? (jsx(Link, { to: backTo, children: jsx(Button, { className: "mr-4 bg-black/5 hover:bg-black/10", prefix: jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "small", square: true, variant: "ghost-neutral" }) })) : undefined, typeof title === "string" ? jsx(PageHeaderTitle, { "data-testid": dataTestId, title: title }) : title, tagRenderer || (description !== null && description !== undefined) ? (jsxs("div", { className: "mx-2 flex items-center gap-2", children: [description !== null && description !== undefined && !showLoading ? (jsx(Tooltip, { "data-testid": dataTestId ? `${dataTestId}-description-tooltip` : undefined, iconProps: {
6108
+ }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaPageHeader(), children: [backTo ? (jsx(Link, { to: backTo, children: jsx(Button, { className: "mr-4 bg-black/5 hover:bg-black/10", prefix: jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "small", square: true, variant: "ghost-neutral" }) })) : undefined, typeof title === "string" ? jsx(PageHeaderTitle, { "data-testid": dataTestId, title: title }) : title, tagRenderer || (description !== null && description !== undefined) ? (jsxs("div", { className: "mx-2 flex items-center gap-2", children: [description !== null && description !== undefined && !showLoading ? (jsx(Tooltip, { asChild: false, "data-testid": dataTestId ? `${dataTestId}-description-tooltip` : undefined, iconProps: {
6101
6109
  name: descriptionIcon,
6102
6110
  "data-testid": "page-header-description-icon",
6103
6111
  }, label: description, placement: "bottom" })) : undefined, tagRenderer] })) : null, jsxs("div", { className: "ml-auto flex gap-2", children: [discriminatedProps.accessoryType === "kpi-metrics" ? (jsx(PageHeaderKpiMetrics, { kpiMetrics: discriminatedProps.kpiMetrics })) : null, discriminatedProps.accessoryType === "actions" ? (Array.isArray(discriminatedProps.secondaryActions) ? (jsx(PageHeaderSecondaryActions, { actions: discriminatedProps.secondaryActions, groupActions: discriminatedProps.groupSecondaryActions ?? false, hasPrimaryAction: !!discriminatedProps.primaryAction })) : discriminatedProps.secondaryActions !== null && discriminatedProps.secondaryActions !== undefined ? (discriminatedProps.secondaryActions) : null) : null, discriminatedProps.accessoryType === "actions" &&
6104
6112
  discriminatedProps.primaryAction !== undefined &&
6105
6113
  (discriminatedProps.primaryAction.hidden === false ||
6106
- discriminatedProps.primaryAction.hidden === undefined) ? (jsx(Tooltip, { disabled: discriminatedProps.primaryAction.tooltipLabel === undefined ||
6114
+ discriminatedProps.primaryAction.hidden === undefined) ? (jsx(Tooltip, { asChild: false, disabled: discriminatedProps.primaryAction.tooltipLabel === undefined ||
6107
6115
  discriminatedProps.primaryAction.tooltipLabel === "", label: discriminatedProps.primaryAction.tooltipLabel, children: jsx(Button, { "data-testid": discriminatedProps.primaryAction["data-testid"], disabled: discriminatedProps.primaryAction.disabled, loading: discriminatedProps.primaryAction.loading, onClick: () => discriminatedProps.primaryAction?.actionCallback?.(), prefix: discriminatedProps.primaryAction.prefixIconName !== undefined ? (jsx(Icon, { name: discriminatedProps.primaryAction.prefixIconName, size: "small" })) : undefined, size: "small", variant: discriminatedProps.primaryAction.variant, children: discriminatedProps.primaryAction.actionText }) })) : null] })] }), tabsList] }));
6108
6116
  };
6109
6117
 
@@ -6951,11 +6959,11 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
6951
6959
  }, ref: el => (buttonRefs.current[index] = el), selected: selected === item.id, size: size, text: item.text, title: item.title, tooltip: item.tooltip }, item.id))) }));
6952
6960
  };
6953
6961
  const ToggleItem = ({ title, onClick, disabled, isIconOnly, iconName = undefined, size, className, selected, text, tooltip, "data-testid": dataTestId, ref, }) => {
6954
- return isIconOnly ? (jsx(Tooltip, { label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(ToggleButton, { className: cvaToggleItem({
6962
+ return isIconOnly ? (jsx(Tooltip, { asChild: false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(ToggleButton, { className: cvaToggleItem({
6955
6963
  className,
6956
6964
  selected,
6957
6965
  disabled,
6958
- }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsx(Icon, { className: cvaToggleItemContent({ selected, disabled }), name: iconName, size: size === "large" ? "medium" : "small" })) : null, isIconOnly: isIconOnly, onClick: onClick, ref: ref, size: size, title: title }) })) : (jsx(Tooltip, { disabled: !tooltip?.content && text?.truncate === false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(ToggleButton, { className: cvaToggleItem({
6966
+ }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsx(Icon, { className: cvaToggleItemContent({ selected, disabled }), name: iconName, size: size === "large" ? "medium" : "small" })) : null, isIconOnly: isIconOnly, onClick: onClick, ref: ref, size: size, title: title }) })) : (jsx(Tooltip, { asChild: false, disabled: !tooltip?.content && text?.truncate === false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(ToggleButton, { className: cvaToggleItem({
6959
6967
  className,
6960
6968
  selected,
6961
6969
  disabled,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.17.5",
3
+ "version": "1.17.7",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -14,10 +14,10 @@
14
14
  "@floating-ui/react": "^0.26.25",
15
15
  "string-ts": "^2.0.0",
16
16
  "tailwind-merge": "^2.0.0",
17
- "@trackunit/ui-design-tokens": "1.11.34",
18
- "@trackunit/css-class-variance-utilities": "1.11.34",
19
- "@trackunit/shared-utils": "1.13.34",
20
- "@trackunit/ui-icons": "1.11.33",
17
+ "@trackunit/ui-design-tokens": "1.11.36",
18
+ "@trackunit/css-class-variance-utilities": "1.11.36",
19
+ "@trackunit/shared-utils": "1.13.36",
20
+ "@trackunit/ui-icons": "1.11.35",
21
21
  "@tanstack/react-router": "1.114.29",
22
22
  "es-toolkit": "^1.39.10",
23
23
  "@tanstack/react-virtual": "3.13.12",
@@ -3,6 +3,9 @@ import { BreadcrumbContainerProps, BreadcrumbProps } from "./utils/types";
3
3
  /**
4
4
  * The breadcrumb component shows a user's location in a website or application. Breadcrumbs are particularly useful when a large amount of content is organized in a hierarchical manner. They streamline navigation, minimize the steps required to revisit previous pages, and offer contextual insights to the users.
5
5
  *
6
+ * All items except the last are rendered as clickable links. The last item is rendered as plain text representing the current page.
7
+ * The component automatically adapts to the screen size: on large screens all items are visible, on medium screens middle items collapse behind an ellipsis button, and on small screens only the current page is shown.
8
+ *
6
9
  * ### When to use
7
10
  * Use breadcrumbs when deep navigation is available, on apps or pages where users might dive into content and could benefit from a quick way to return to higher levels. Breadcrumbs display the current screen as the final item in the list to make it clear where the user is.
8
11
  *
@@ -25,7 +28,7 @@ import { BreadcrumbContainerProps, BreadcrumbProps } from "./utils/types";
25
28
  * { label: "Assets", to: "/fleet/assets" },
26
29
  * { label: "Excavator 001", to: "/fleet/assets/123" },
27
30
  * ]}
28
- * back={() => navigate({ to: "/fleet/assets" })}
31
+ * onClickBack={() => navigate({ to: "/fleet/assets" })}
29
32
  * />
30
33
  * );
31
34
  * };
@@ -3,5 +3,4 @@ export declare const cvaBreadcrumbItem: (props?: import("class-variance-authorit
3
3
  export declare const cvaBreadcrumbForLargeScreen: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
4
4
  export declare const cvaBreadcrumbForMediumScreen: (props?: ({
5
5
  expanded?: boolean | null | undefined;
6
- defaultVariants?: "expanded" | null | undefined;
7
6
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
@@ -1,11 +1,20 @@
1
1
  import { MouseEventHandler, ReactElement } from "react";
2
2
  import { CommonProps } from "../../../common/CommonProps";
3
3
  export interface BreadcrumbItemProps {
4
+ /** The display text for this breadcrumb item. */
4
5
  label: string;
6
+ /** The route path this breadcrumb item links to. */
5
7
  to: string;
6
8
  }
7
9
  export interface BreadcrumbProps extends CommonProps {
10
+ /**
11
+ * The ordered list of breadcrumb items representing the navigation hierarchy.
12
+ * The last item is rendered as plain text (the current page), all preceding items are rendered as clickable links.
13
+ */
8
14
  breadcrumbItems: Array<BreadcrumbItemProps>;
15
+ /**
16
+ * Click handler for the back arrow button. Typically navigates to the previous breadcrumb item (second-to-last in the list).
17
+ */
9
18
  onClickBack: MouseEventHandler<HTMLButtonElement>;
10
19
  }
11
20
  export interface BreadcrumbContainerProps extends CommonProps {
@@ -33,6 +33,15 @@ export interface TooltipProps extends CommonProps, Styleable {
33
33
  * Ihe id of the html element
34
34
  */
35
35
  id?: string;
36
+ /**
37
+ * Specifies whether the current component or element should be rendered as a child element.
38
+ * When set to `true`, the behavior or structure of the component may adapt to fit within
39
+ * a parent context, altering its default rendering logic. Typically used in scenarios
40
+ * where nesting or parent-child relationships are relevant.
41
+ *
42
+ * @deprecated - Do not use this prop. It will be removed in a future release.
43
+ */
44
+ asChild?: boolean;
36
45
  }
37
46
  /**
38
47
  * Tooltips display additional information upon hover. The information included should be contextual, helpful, and nonessential while providing that extra ability to communicate and give clarity to a user.
@@ -48,7 +57,7 @@ export interface TooltipProps extends CommonProps, Styleable {
48
57
  * import { Tooltip, IconButton, Icon } from "@trackunit/react-components";
49
58
  *
50
59
  * const SettingsButton = () => (
51
- * <Tooltip label="Open settings" placement="bottom">
60
+ * <Tooltip asChild={false} label="Open settings" placement="bottom">
52
61
  * <IconButton
53
62
  * icon={<Icon name="Cog6Tooth" size="small" />}
54
63
  * variant="ghost-neutral"
@@ -64,7 +73,7 @@ export interface TooltipProps extends CommonProps, Styleable {
64
73
  * const FieldWithHelp = () => (
65
74
  * <div className="flex items-center gap-2">
66
75
  * <span>Utilization Rate</span>
67
- * <Tooltip
76
+ * <Tooltip asChild={false}
68
77
  * label="The percentage of time the asset was actively in use during the selected period"
69
78
  * placement="right"
70
79
  * mode="light"
@@ -75,4 +84,4 @@ export interface TooltipProps extends CommonProps, Styleable {
75
84
  * @param {TooltipProps} props - The props for the Tooltip component
76
85
  * @returns {ReactElement} Tooltip component
77
86
  */
78
- export declare const Tooltip: ({ children, "data-testid": dataTestId, disabled, className, label, placement, mode, iconProps, id, style, }: TooltipProps) => ReactElement;
87
+ export declare const Tooltip: ({ children, "data-testid": dataTestId, disabled, className, label, placement, mode, iconProps, id, style, asChild, }: TooltipProps) => ReactElement;