@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 +29 -21
- package/index.esm.js +29 -21
- package/package.json +5 -5
- package/src/components/Breadcrumb/Breadcrumb.d.ts +4 -1
- package/src/components/Breadcrumb/Breadcrumb.variant.d.ts +0 -1
- package/src/components/Breadcrumb/utils/types.d.ts +9 -0
- package/src/components/Tooltip/Tooltip.d.ts +12 -3
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"
|
|
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
|
-
*
|
|
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(() =>
|
|
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"
|
|
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
|
-
*
|
|
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(() =>
|
|
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.
|
|
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.
|
|
18
|
-
"@trackunit/css-class-variance-utilities": "1.11.
|
|
19
|
-
"@trackunit/shared-utils": "1.13.
|
|
20
|
-
"@trackunit/ui-icons": "1.11.
|
|
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
|
-
*
|
|
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;
|