@trackunit/react-components 1.17.17 → 1.17.20
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 +182 -170
- package/index.esm.js +183 -171
- package/package.json +5 -5
- package/src/common/Refable.d.ts +5 -0
- package/src/components/Alert/Alert.d.ts +3 -2
- package/src/components/Badge/Badge.d.ts +3 -2
- package/src/components/Breadcrumb/Breadcrumb.d.ts +1 -1
- package/src/components/Breadcrumb/utils/types.d.ts +2 -1
- package/src/components/Card/Card.d.ts +7 -3
- package/src/components/Card/CardBody.d.ts +3 -2
- package/src/components/Card/CardFooter.d.ts +3 -2
- package/src/components/Card/CardHeader.d.ts +3 -2
- package/src/components/Collapse/Collapse.d.ts +3 -2
- package/src/components/CopyableText/CopyableText.d.ts +3 -2
- package/src/components/DetailsList/DetailsList.d.ts +4 -2
- package/src/components/EmptyState/EmptyState.d.ts +2 -1
- package/src/components/EmptyValue/EmptyValue.d.ts +2 -1
- package/src/components/ExternalLink/ExternalLink.d.ts +3 -2
- package/src/components/Heading/Heading.d.ts +3 -2
- package/src/components/HorizontalOverflowScroller/HorizontalOverflowScroller.d.ts +4 -2
- package/src/components/Icon/Icon.d.ts +4 -9
- package/src/components/Indicator/Indicator.d.ts +3 -2
- package/src/components/KPI/KPI.d.ts +3 -2
- package/src/components/KPI/KPISkeleton.d.ts +3 -2
- package/src/components/KPICard/KPICard.d.ts +3 -2
- package/src/components/KPICard/KPICardSkeleton.d.ts +3 -2
- package/src/components/KPICard/components/TrendIndicator/TrendIndicator.d.ts +3 -2
- package/src/components/KPICard/components/TrendIndicators.d.ts +3 -2
- package/src/components/Menu/MenuItem/MenuItem.d.ts +3 -2
- package/src/components/Menu/MenuList/MenuList.d.ts +3 -2
- package/src/components/Menu/MoreMenu/MoreMenu.d.ts +3 -2
- package/src/components/Notice/Notice.d.ts +3 -2
- package/src/components/Page/Page.d.ts +3 -2
- package/src/components/Page/PageContent.d.ts +3 -2
- package/src/components/PageHeader/PageHeader.d.ts +1 -1
- package/src/components/PageHeader/components/PageHeaderKpiMetrics.d.ts +4 -2
- package/src/components/PageHeader/components/PageHeaderTitle.d.ts +4 -2
- package/src/components/PageHeader/types.d.ts +2 -1
- package/src/components/Pagination/Pagination.d.ts +3 -2
- package/src/components/Polygon/Polygon.d.ts +3 -2
- package/src/components/Popover/PopoverTitle.d.ts +3 -2
- package/src/components/PreferenceCard/PreferenceCard.d.ts +3 -2
- package/src/components/PreferenceCard/PreferenceCardSkeleton.d.ts +3 -2
- package/src/components/SectionHeader/SectionHeader.d.ts +3 -2
- package/src/components/Sidebar/Sidebar.d.ts +3 -2
- package/src/components/Skeleton/SkeletonBlock/SkeletonBlock.d.ts +2 -1
- package/src/components/Skeleton/SkeletonLabel/SkeletonLabel.d.ts +2 -1
- package/src/components/SkeletonLines/SkeletonLines.d.ts +4 -3
- package/src/components/Spacer/Spacer.d.ts +3 -2
- package/src/components/Spinner/Spinner.d.ts +3 -2
- package/src/components/Tabs/Tab.d.ts +3 -2
- package/src/components/Tabs/TabContent.d.ts +3 -2
- package/src/components/Tabs/TabList.d.ts +3 -2
- package/src/components/Tabs/Tabs.d.ts +3 -2
- package/src/components/ToggleGroup/ToggleGroup.d.ts +3 -2
- package/src/components/Tooltip/Tooltip.d.ts +1 -1
- package/src/components/ValueBar/ValueBar.d.ts +3 -2
- package/src/components/ZStack/ZStack.d.ts +3 -2
- package/src/components/buttons/StarButton/StarButton.d.ts +3 -2
- package/src/index.d.ts +1 -0
package/index.cjs.js
CHANGED
|
@@ -127,7 +127,7 @@ const isSafari = () => {
|
|
|
127
127
|
* @param {IconProps} props - The props for the Icon component
|
|
128
128
|
* @returns {ReactElement} Icon component
|
|
129
129
|
*/
|
|
130
|
-
const Icon = ({ name, size = "medium", className, "data-testid": dataTestId, color = undefined, onClick, type = size === "large" ? "outline" : "solid", style,
|
|
130
|
+
const Icon = ({ name, size = "medium", className, "data-testid": dataTestId, color = undefined, onClick, type = size === "large" ? "outline" : "solid", style, ref, ariaLabel, fontSize = false, ariaLabelledBy, ariaDescribedBy, ariaHidden, }) => {
|
|
131
131
|
const useTagRef = react.useRef(null);
|
|
132
132
|
const ICON_CONTAINER_ID = sharedUtils.uuidv4();
|
|
133
133
|
const correctIconType = react.useMemo(() => {
|
|
@@ -162,7 +162,7 @@ const Icon = ({ name, size = "medium", className, "data-testid": dataTestId, col
|
|
|
162
162
|
useTagRef.current.setAttribute("href", href[correctIconType]);
|
|
163
163
|
}
|
|
164
164
|
}, [correctIconType, href]);
|
|
165
|
-
return (jsxRuntime.jsx("span", { "aria-describedby": ariaDescribedBy, "aria-hidden": ariaHidden, "aria-label": ariaLabel ? ariaLabel : stringTs.titleCase(iconName), "aria-labelledby": ariaLabelledBy, className: cvaIcon({ color, size, fontSize, className }), "data-testid": dataTestId, id: ICON_CONTAINER_ID, onClick: onClick, ref:
|
|
165
|
+
return (jsxRuntime.jsx("span", { "aria-describedby": ariaDescribedBy, "aria-hidden": ariaHidden, "aria-label": ariaLabel ? ariaLabel : stringTs.titleCase(iconName), "aria-labelledby": ariaLabelledBy, className: cvaIcon({ color, size, fontSize, className }), "data-testid": dataTestId, id: ICON_CONTAINER_ID, onClick: onClick, ref: ref, children: jsxRuntime.jsx("svg", { "aria-labelledby": ICON_CONTAINER_ID, "data-testid": dataTestId ? `${dataTestId}-${iconName}` : iconName, role: "img", style: style, viewBox: correctViewBox, children: jsxRuntime.jsx("use", { href: href[correctIconType], ref: useTagRef }) }) }));
|
|
166
166
|
};
|
|
167
167
|
|
|
168
168
|
/**
|
|
@@ -383,6 +383,70 @@ const useIsTextWrapping = (options = {}) => {
|
|
|
383
383
|
return react.useMemo(() => ({ ref, isTextWrapping }), [isTextWrapping]);
|
|
384
384
|
};
|
|
385
385
|
|
|
386
|
+
// This hook is _heavily_ inspired by floating-ui's useMergeRefs
|
|
387
|
+
/**
|
|
388
|
+
* Merges an array of refs into a single memoized callback ref or `null`.
|
|
389
|
+
* Useful when you need to attach multiple refs to the same element,
|
|
390
|
+
* such as when composing multiple hooks that each need a ref.
|
|
391
|
+
*
|
|
392
|
+
* @template TInstance - The type of the element instance
|
|
393
|
+
* @param {ReadonlyArray<MergeableRef<TInstance> | undefined>} refs - Array of refs to merge (can be RefObjects, RefCallbacks, or undefined)
|
|
394
|
+
* @returns {null | RefCallback<TInstance>} A single ref callback that will update all provided refs, or null if all refs are null
|
|
395
|
+
* @example
|
|
396
|
+
* ```tsx
|
|
397
|
+
* const { ref: measureRef } = useMeasure();
|
|
398
|
+
* const { ref: scrollRef } = useScrollDetection();
|
|
399
|
+
* const mergedRef = useMergeRefs([measureRef, scrollRef]);
|
|
400
|
+
*
|
|
401
|
+
* return <div ref={mergedRef}>Content</div>;
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
function useMergeRefs(refs) {
|
|
405
|
+
const cleanupRef = react.useRef(undefined);
|
|
406
|
+
const refsRef = react.useRef(refs);
|
|
407
|
+
react.useEffect(() => {
|
|
408
|
+
refsRef.current = refs;
|
|
409
|
+
}, [refs]);
|
|
410
|
+
const refEffect = react.useCallback((instance) => {
|
|
411
|
+
const cleanups = refsRef.current.map(ref => {
|
|
412
|
+
if (ref === null || ref === undefined) {
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (typeof ref === "function") {
|
|
416
|
+
const refCallback = ref;
|
|
417
|
+
const refCleanup = refCallback(instance);
|
|
418
|
+
return typeof refCleanup === "function"
|
|
419
|
+
? refCleanup
|
|
420
|
+
: () => {
|
|
421
|
+
refCallback(null);
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
ref.current = instance;
|
|
425
|
+
return () => {
|
|
426
|
+
ref.current = null;
|
|
427
|
+
};
|
|
428
|
+
});
|
|
429
|
+
return () => {
|
|
430
|
+
cleanups.forEach(refCleanup => refCleanup?.());
|
|
431
|
+
};
|
|
432
|
+
}, []);
|
|
433
|
+
return react.useMemo(() => {
|
|
434
|
+
// eslint-disable-next-line react-hooks/refs
|
|
435
|
+
if (refsRef.current.every(ref => ref === null)) {
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
return (value) => {
|
|
439
|
+
if (cleanupRef.current) {
|
|
440
|
+
cleanupRef.current();
|
|
441
|
+
cleanupRef.current = undefined;
|
|
442
|
+
}
|
|
443
|
+
if (value !== null) {
|
|
444
|
+
cleanupRef.current = refEffect(value);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}, [refEffect]);
|
|
448
|
+
}
|
|
449
|
+
|
|
386
450
|
const cvaText = cssClassVarianceUtilities.cvaMerge(["text-black", "m-0", "relative", "text-sm", "font-normal"], {
|
|
387
451
|
variants: {
|
|
388
452
|
align: {
|
|
@@ -518,8 +582,8 @@ const cvaSpinnerLabel = cssClassVarianceUtilities.cvaMerge(["self-center", "text
|
|
|
518
582
|
* @param {SpinnerProps} props - The props for the Spinner component
|
|
519
583
|
* @returns {ReactElement} Spinner component
|
|
520
584
|
*/
|
|
521
|
-
const Spinner = ({ mode = "light", size = "medium", centering = "centered", className, containerClassName, "data-testid": dataTestId = "spinner", label, }) => {
|
|
522
|
-
return (jsxRuntime.jsx("div", { className: cvaSpinnerContainer({ centering, className: containerClassName }), children: jsxRuntime.jsxs("div", { className: cvaSpinnerContainerInner(), children: [jsxRuntime.jsx("div", { className: cvaSpinner({ size, mode, className }), "data-testid": dataTestId, role: "spinbutton" }), label ? jsxRuntime.jsx("span", { className: cvaSpinnerLabel(), children: label }) : null] }) }));
|
|
585
|
+
const Spinner = ({ mode = "light", size = "medium", centering = "centered", className, containerClassName, "data-testid": dataTestId = "spinner", label, ref, }) => {
|
|
586
|
+
return (jsxRuntime.jsx("div", { className: cvaSpinnerContainer({ centering, className: containerClassName }), ref: ref, children: jsxRuntime.jsxs("div", { className: cvaSpinnerContainerInner(), children: [jsxRuntime.jsx("div", { className: cvaSpinner({ size, mode, className }), "data-testid": dataTestId, role: "spinbutton" }), label ? jsxRuntime.jsx("span", { className: cvaSpinnerLabel(), children: label }) : null] }) }));
|
|
523
587
|
};
|
|
524
588
|
|
|
525
589
|
const cvaButton = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -1054,16 +1118,19 @@ const cvaAlertIconContainer = cssClassVarianceUtilities.cvaMerge(["shrink-0", "g
|
|
|
1054
1118
|
* @param {AlertProps} props - The props for the Alert component
|
|
1055
1119
|
* @returns {ReactElement} Alert component
|
|
1056
1120
|
*/
|
|
1057
|
-
const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClickClose, "data-testid": dataTestId, autoScroll = false, actionsInline = false, }) => {
|
|
1058
|
-
const
|
|
1121
|
+
const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClickClose, "data-testid": dataTestId, autoScroll = false, actionsInline = false, ref, }) => {
|
|
1122
|
+
const scrollRef = react.useRef(null);
|
|
1123
|
+
const mergedRef = useMergeRefs([scrollRef, ref]);
|
|
1059
1124
|
const { isTextWrapping, ref: titleRef } = useIsTextWrapping();
|
|
1060
1125
|
react.useEffect(() => {
|
|
1061
1126
|
if (autoScroll) {
|
|
1062
|
-
|
|
1063
|
-
|
|
1127
|
+
const element = scrollRef.current;
|
|
1128
|
+
if (element && typeof element.scrollIntoView === "function") {
|
|
1129
|
+
element.scrollIntoView();
|
|
1130
|
+
}
|
|
1064
1131
|
}
|
|
1065
|
-
}, [
|
|
1066
|
-
return (jsxRuntime.jsxs("div", { className: cvaAlert({ color, actionsInline, className }), "data-testid": dataTestId, ref:
|
|
1132
|
+
}, [autoScroll]);
|
|
1133
|
+
return (jsxRuntime.jsxs("div", { className: cvaAlert({ color, actionsInline, className }), "data-testid": dataTestId, ref: mergedRef, role: "alert", children: [jsxRuntime.jsxs("div", { className: cvaAlertContentContainer({
|
|
1067
1134
|
inline: !isTextWrapping && (children === null || children === undefined),
|
|
1068
1135
|
actionsInline,
|
|
1069
1136
|
}), children: [jsxRuntime.jsx("div", { className: cvaAlertIconContainer({
|
|
@@ -1178,7 +1245,7 @@ const cvaBadge = cssClassVarianceUtilities.cvaMerge([
|
|
|
1178
1245
|
* @param {BadgeProps} props - The props for the Badge component
|
|
1179
1246
|
* @returns {ReactElement} Badge component
|
|
1180
1247
|
*/
|
|
1181
|
-
const Badge = ({ color = "primary", size = "default", compact = false, className, count, max, hideZero = false, "data-testid": dataTestId, }) => {
|
|
1248
|
+
const Badge = ({ color = "primary", size = "default", compact = false, className, count, max, hideZero = false, "data-testid": dataTestId, ref, }) => {
|
|
1182
1249
|
if (hideZero && count === 0) {
|
|
1183
1250
|
return null;
|
|
1184
1251
|
}
|
|
@@ -1188,7 +1255,7 @@ const Badge = ({ color = "primary", size = "default", compact = false, className
|
|
|
1188
1255
|
: count
|
|
1189
1256
|
: count;
|
|
1190
1257
|
const isSingleChar = displayedCount?.toString().length === 1;
|
|
1191
|
-
return (jsxRuntime.jsx("span", { className: cvaBadge({ color, size, className, compact, isSingleChar }), "data-testid": dataTestId, children: compact ? null : displayedCount }));
|
|
1258
|
+
return (jsxRuntime.jsx("span", { className: cvaBadge({ color, size, className, compact, isSingleChar }), "data-testid": dataTestId, ref: ref, children: compact ? null : displayedCount }));
|
|
1192
1259
|
};
|
|
1193
1260
|
|
|
1194
1261
|
/**
|
|
@@ -1392,9 +1459,9 @@ const useBreadcrumbItemsToRender = (breadcrumbItems) => {
|
|
|
1392
1459
|
* @param {BreadcrumbProps} props - The props for the Breadcrumb component
|
|
1393
1460
|
* @returns {ReactElement} Breadcrumb component
|
|
1394
1461
|
*/
|
|
1395
|
-
const Breadcrumb = ({ className, "data-testid": dataTestId, breadcrumbItems, onClickBack, }) => {
|
|
1462
|
+
const Breadcrumb = ({ className, "data-testid": dataTestId, breadcrumbItems, onClickBack, ref, }) => {
|
|
1396
1463
|
const breadCrumbItemsToJSX = useBreadcrumbItemsToRender(breadcrumbItems);
|
|
1397
|
-
return (jsxRuntime.jsxs("div", { className: cvaBreadcrumb({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsx(IconButton, { "data-testid": `backButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "ArrowLeft", size: "small" }), onClick: onClickBack, size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx("div", { children: jsxRuntime.jsx(BreadcrumbContainer, { breadcrumbItems: breadCrumbItemsToJSX, "data-testid": dataTestId }) })] }));
|
|
1464
|
+
return (jsxRuntime.jsxs("div", { className: cvaBreadcrumb({ className }), "data-testid": dataTestId, ref: ref, children: [jsxRuntime.jsx(IconButton, { "data-testid": `backButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "ArrowLeft", size: "small" }), onClick: onClickBack, size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx("div", { children: jsxRuntime.jsx(BreadcrumbContainer, { breadcrumbItems: breadCrumbItemsToJSX, "data-testid": dataTestId }) })] }));
|
|
1398
1465
|
};
|
|
1399
1466
|
/**
|
|
1400
1467
|
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
@@ -1418,8 +1485,8 @@ const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) =>
|
|
|
1418
1485
|
* @param {StarButtonProps} props - The props for the StarButton component
|
|
1419
1486
|
* @returns {ReactElement} StarButton component
|
|
1420
1487
|
*/
|
|
1421
|
-
const StarButton = ({ starred, onClick }) => {
|
|
1422
|
-
return (jsxRuntime.jsx("div", { "data-test-id": "starred-filter", onClick: onClick, children: jsxRuntime.jsx(Icon, { color: starred ? "primary" : "neutral", name: "Star", size: "medium" }) }));
|
|
1488
|
+
const StarButton = ({ starred, onClick, ref }) => {
|
|
1489
|
+
return (jsxRuntime.jsx("div", { "data-test-id": "starred-filter", onClick: onClick, ref: ref, children: jsxRuntime.jsx(Icon, { color: starred ? "primary" : "neutral", name: "Star", size: "medium" }) }));
|
|
1423
1490
|
};
|
|
1424
1491
|
|
|
1425
1492
|
const cvaCard = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -1556,9 +1623,10 @@ const ROLE_CARD = "region";
|
|
|
1556
1623
|
* @param {CardProps} props - The props for the Card component
|
|
1557
1624
|
* @returns {ReactElement} Card component
|
|
1558
1625
|
*/
|
|
1559
|
-
const Card =
|
|
1626
|
+
const Card = ({ children, onClick, fullHeight = false, onMouseEnter, onMouseLeave, className, "data-testid": dataTestId, ref, ...rest }) => {
|
|
1560
1627
|
return (jsxRuntime.jsx("div", { className: cvaCard({ fullHeight, clickable: Boolean(onClick), className }), "data-card": true, "data-testid": dataTestId, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, ref: ref, role: ROLE_CARD, ...rest, children: children }));
|
|
1561
|
-
}
|
|
1628
|
+
};
|
|
1629
|
+
Card.displayName = "Card";
|
|
1562
1630
|
|
|
1563
1631
|
/**
|
|
1564
1632
|
* The CardBody component should be used to inform the user of important information.
|
|
@@ -1568,13 +1636,13 @@ const Card = react.forwardRef(function Card({ children, onClick, fullHeight = fa
|
|
|
1568
1636
|
* @param {CardBodyProps} props - The props for the CardBody component
|
|
1569
1637
|
* @returns {ReactElement} CardBody component
|
|
1570
1638
|
*/
|
|
1571
|
-
const CardBody = ({ children, "data-testid": dataTestId, className, direction = "column", gap = "default", padding = "default", id, }) => {
|
|
1639
|
+
const CardBody = ({ children, "data-testid": dataTestId, className, direction = "column", gap = "default", padding = "default", id, ref, }) => {
|
|
1572
1640
|
return (jsxRuntime.jsx("div", { className: cvaCardBodyContainer({
|
|
1573
1641
|
gap,
|
|
1574
1642
|
padding,
|
|
1575
1643
|
className,
|
|
1576
1644
|
direction,
|
|
1577
|
-
}), "data-card-body": true, "data-testid": dataTestId, id: id, children: children }));
|
|
1645
|
+
}), "data-card-body": true, "data-testid": dataTestId, id: id, ref: ref, children: children }));
|
|
1578
1646
|
};
|
|
1579
1647
|
|
|
1580
1648
|
/**
|
|
@@ -1585,12 +1653,12 @@ const CardBody = ({ children, "data-testid": dataTestId, className, direction =
|
|
|
1585
1653
|
* @param {CardFooterProps} props - The props for the CardFooter component
|
|
1586
1654
|
* @returns {ReactElement} CardFooter component
|
|
1587
1655
|
*/
|
|
1588
|
-
const CardFooter = ({ "data-testid": dataTestId, className, children, padding = "default", hideSeparator = false, }) => {
|
|
1656
|
+
const CardFooter = ({ "data-testid": dataTestId, className, children, padding = "default", hideSeparator = false, ref, }) => {
|
|
1589
1657
|
return (jsxRuntime.jsx("div", { className: cvaCardFooterContainerRoot({
|
|
1590
1658
|
border: hideSeparator ? "borderless" : "default",
|
|
1591
1659
|
padding,
|
|
1592
1660
|
className,
|
|
1593
|
-
}), "data-card-footer": true, "data-testid": dataTestId, children: jsxRuntime.jsx("div", { className: cvaCardFooterContainer(), children: children }) }));
|
|
1661
|
+
}), "data-card-footer": true, "data-testid": dataTestId, ref: ref, children: jsxRuntime.jsx("div", { className: cvaCardFooterContainer(), children: children }) }));
|
|
1594
1662
|
};
|
|
1595
1663
|
|
|
1596
1664
|
const cvaHeading = cssClassVarianceUtilities.cvaMerge(["m-0", "leading-normal", "text-black"], {
|
|
@@ -1630,7 +1698,7 @@ const cvaHeading = cssClassVarianceUtilities.cvaMerge(["m-0", "leading-normal",
|
|
|
1630
1698
|
* @param {HeadingProps} props - The props for the Heading component
|
|
1631
1699
|
* @returns {ReactElement} Heading component
|
|
1632
1700
|
*/
|
|
1633
|
-
const Heading = ({ variant = "primary", inverted = false, subtle = false, className, "data-testid": dataTestId, ...rest }) => {
|
|
1701
|
+
const Heading = ({ variant = "primary", inverted = false, subtle = false, className, "data-testid": dataTestId, ref, ...rest }) => {
|
|
1634
1702
|
const semanticType = {
|
|
1635
1703
|
primary: "h1",
|
|
1636
1704
|
secondary: "h2",
|
|
@@ -1639,6 +1707,7 @@ const Heading = ({ variant = "primary", inverted = false, subtle = false, classN
|
|
|
1639
1707
|
};
|
|
1640
1708
|
return react.createElement(semanticType[variant], {
|
|
1641
1709
|
...rest,
|
|
1710
|
+
ref,
|
|
1642
1711
|
className: cvaHeading({ subtle, inverted, size: variant, className }),
|
|
1643
1712
|
"data-testid": dataTestId,
|
|
1644
1713
|
});
|
|
@@ -1650,12 +1719,12 @@ const Heading = ({ variant = "primary", inverted = false, subtle = false, classN
|
|
|
1650
1719
|
* @param {CardHeaderProps} props - The props for the CardHeader component
|
|
1651
1720
|
* @returns {ReactElement} CardHeader component
|
|
1652
1721
|
*/
|
|
1653
|
-
const CardHeader = ({ heading, headingVariant = "secondary", subHeading, onClickClose, "data-testid": dataTestId, className, children, accessories, actions, padding = "default", hideSeparator = false, }) => {
|
|
1722
|
+
const CardHeader = ({ heading, headingVariant = "secondary", subHeading, onClickClose, "data-testid": dataTestId, className, children, accessories, actions, padding = "default", hideSeparator = false, ref, }) => {
|
|
1654
1723
|
return (jsxRuntime.jsx("div", { className: cvaCardHeaderContainer({
|
|
1655
1724
|
border: hideSeparator ? "borderless" : "default",
|
|
1656
1725
|
padding,
|
|
1657
1726
|
className,
|
|
1658
|
-
}), "data-card-header": true, "data-testid": dataTestId, children: jsxRuntime.jsxs("div", { className: cvaCardHeader(), children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: cvaCardHeaderHeadingContainer(), children: [jsxRuntime.jsx(Heading, { className: "self-center", variant: headingVariant, children: heading }), accessories] }), subHeading !== null && subHeading !== undefined ? (jsxRuntime.jsx(Heading, { subtle: true, variant: "subtitle", children: subHeading })) : null, children] }), jsxRuntime.jsxs("div", { className: "flex place-items-center gap-x-2 gap-y-1", children: [actions, onClickClose ? (jsxRuntime.jsx(IconButton, { className: "!h-min", "data-testid": "card-header-close-button", icon: jsxRuntime.jsx(Icon, { name: "XMark", size: "small" }), onClick: onClickClose, variant: "ghost-neutral" })) : null] })] }) }));
|
|
1727
|
+
}), "data-card-header": true, "data-testid": dataTestId, ref: ref, children: jsxRuntime.jsxs("div", { className: cvaCardHeader(), children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: cvaCardHeaderHeadingContainer(), children: [jsxRuntime.jsx(Heading, { className: "self-center", variant: headingVariant, children: heading }), accessories] }), subHeading !== null && subHeading !== undefined ? (jsxRuntime.jsx(Heading, { subtle: true, variant: "subtitle", children: subHeading })) : null, children] }), jsxRuntime.jsxs("div", { className: "flex place-items-center gap-x-2 gap-y-1", children: [actions, onClickClose ? (jsxRuntime.jsx(IconButton, { className: "!h-min", "data-testid": "card-header-close-button", icon: jsxRuntime.jsx(Icon, { name: "XMark", size: "small" }), onClick: onClickClose, variant: "ghost-neutral" })) : null] })] }) }));
|
|
1659
1728
|
};
|
|
1660
1729
|
|
|
1661
1730
|
const cvaClickable = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -1926,7 +1995,7 @@ const cvaChevronIcon = cssClassVarianceUtilities.cvaMerge(["transition-transform
|
|
|
1926
1995
|
* @param {CollapseProps} props - The props for the Collapse component
|
|
1927
1996
|
* @returns {ReactElement} Collapse component
|
|
1928
1997
|
*/
|
|
1929
|
-
const Collapse = ({ id, variant = "primary", initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, "data-testid": dataTestId, animate = true, extraPadding = true, }) => {
|
|
1998
|
+
const Collapse = ({ id, variant = "primary", initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, "data-testid": dataTestId, animate = true, extraPadding = true, ref, }) => {
|
|
1930
1999
|
const LABEL_ID = sharedUtils.uuidv4();
|
|
1931
2000
|
const [expanded, setExpanded] = react.useState(initialExpanded);
|
|
1932
2001
|
const handleClick = react.useCallback((e) => {
|
|
@@ -1935,7 +2004,7 @@ const Collapse = ({ id, variant = "primary", initialExpanded = false, onToggle,
|
|
|
1935
2004
|
}
|
|
1936
2005
|
setExpanded(!expanded);
|
|
1937
2006
|
}, [expanded, onToggle]);
|
|
1938
|
-
return (jsxRuntime.jsxs("div", { className: cvaCollapse({ variant: variant, className }), "data-testid": dataTestId, children: [jsxRuntime.jsx("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, variant, extraPadding, className: headerClassName }), onClick: handleClick, role: "button", children: jsxRuntime.jsxs("div", { className: cvaCollapseLabelContainer({ variant }), children: [jsxRuntime.jsx(Text, { className: cvaCollapseLabel({ variant }), id: LABEL_ID, size: variant === "secondary" ? "small" : "medium", type: "span", weight: "bold", children: label }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [headerAddon !== null && headerAddon !== undefined && variant !== "secondary" ? headerAddon : null, jsxRuntime.jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronUp", size: variant === "secondary" ? "small" : "medium" })] })] }) }), jsxRuntime.jsx(Collapsible, { expanded: expanded, extraPadding: extraPadding, id: id, variant: variant, children: expanded || animate ? children : null })] }));
|
|
2007
|
+
return (jsxRuntime.jsxs("div", { className: cvaCollapse({ variant: variant, className }), "data-testid": dataTestId, ref: ref, children: [jsxRuntime.jsx("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, variant, extraPadding, className: headerClassName }), onClick: handleClick, role: "button", children: jsxRuntime.jsxs("div", { className: cvaCollapseLabelContainer({ variant }), children: [jsxRuntime.jsx(Text, { className: cvaCollapseLabel({ variant }), id: LABEL_ID, size: variant === "secondary" ? "small" : "medium", type: "span", weight: "bold", children: label }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [headerAddon !== null && headerAddon !== undefined && variant !== "secondary" ? headerAddon : null, jsxRuntime.jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronUp", size: variant === "secondary" ? "small" : "medium" })] })] }) }), jsxRuntime.jsx(Collapsible, { expanded: expanded, extraPadding: extraPadding, id: id, variant: variant, children: expanded || animate ? children : null })] }));
|
|
1939
2008
|
};
|
|
1940
2009
|
const Collapsible = ({ children, expanded, id, variant, extraPadding }) => {
|
|
1941
2010
|
const { geometry, ref } = useMeasure();
|
|
@@ -2067,7 +2136,7 @@ const cvaCopyableText = cssClassVarianceUtilities.cvaMerge([
|
|
|
2067
2136
|
* @param {CopyableTextProps} props - The props for the CopyableText component
|
|
2068
2137
|
* @returns {ReactElement} CopyableText component
|
|
2069
2138
|
*/
|
|
2070
|
-
const CopyableText = ({ text, alternativeText, "data-testid": dataTestId, className, }) => {
|
|
2139
|
+
const CopyableText = ({ text, alternativeText, "data-testid": dataTestId, className, ref, }) => {
|
|
2071
2140
|
const value = alternativeText ?? text ?? "";
|
|
2072
2141
|
const [animating, setAnimating] = react.useState(false);
|
|
2073
2142
|
const [, copyToClipboard] = useCopyToClipboard();
|
|
@@ -2075,7 +2144,7 @@ const CopyableText = ({ text, alternativeText, "data-testid": dataTestId, classN
|
|
|
2075
2144
|
void copyToClipboard(value);
|
|
2076
2145
|
setAnimating(true);
|
|
2077
2146
|
};
|
|
2078
|
-
return (jsxRuntime.jsx("span", { className: cvaCopyableText({ animating, className }), "data-testid": dataTestId, onAnimationEnd: () => setAnimating(false), onClick: handleOnClick, title: value, children: text }));
|
|
2147
|
+
return (jsxRuntime.jsx("span", { className: cvaCopyableText({ animating, className }), "data-testid": dataTestId, onAnimationEnd: () => setAnimating(false), onClick: handleOnClick, ref: ref, title: value, children: text }));
|
|
2079
2148
|
};
|
|
2080
2149
|
|
|
2081
2150
|
const cvaDetailsList = cssClassVarianceUtilities.cvaMerge(["flex", "w-full", "min-w-0", "items-center", "truncate", "text-xs", "text-neutral-600", "font-medium", "pt-0"], {
|
|
@@ -2097,10 +2166,11 @@ const cvaDetailsListItem = cssClassVarianceUtilities.cvaMerge(["last:truncate"])
|
|
|
2097
2166
|
* @param {string[]} props.details - Values to render.
|
|
2098
2167
|
* @param {string} [props.className] - Optional CSS class for customization.
|
|
2099
2168
|
* @param {boolean} [props.hasLink=false] - Whether the parent component contains a link.
|
|
2169
|
+
* @param [props.ref] - Ref forwarded to the root element.
|
|
2100
2170
|
* @returns {ReactElement} The details list element.
|
|
2101
2171
|
*/
|
|
2102
|
-
const DetailsList = ({ details, className, hasLink = false }) => {
|
|
2103
|
-
return (jsxRuntime.jsx("div", { className: cvaDetailsList({ className, hasLink }), children: details.map((value, index, array) => (jsxRuntime.jsxs(react.Fragment, { children: [jsxRuntime.jsx("span", { className: cvaDetailsListItem({ className }), children: value }), index < array.length - 1 && (jsxRuntime.jsx("div", { className: "mx-0.5 flex items-center", children: jsxRuntime.jsx(Icon, { className: "w-4 text-neutral-300", color: "neutral", name: "Slash", size: "small" }) }))] }, index))) }));
|
|
2172
|
+
const DetailsList = ({ details, className, hasLink = false, ref }) => {
|
|
2173
|
+
return (jsxRuntime.jsx("div", { className: cvaDetailsList({ className, hasLink }), ref: ref, children: details.map((value, index, array) => (jsxRuntime.jsxs(react.Fragment, { children: [jsxRuntime.jsx("span", { className: cvaDetailsListItem({ className }), children: value }), index < array.length - 1 && (jsxRuntime.jsx("div", { className: "mx-0.5 flex items-center", children: jsxRuntime.jsx(Icon, { className: "w-4 text-neutral-300", color: "neutral", name: "Slash", size: "small" }) }))] }, index))) }));
|
|
2104
2174
|
};
|
|
2105
2175
|
|
|
2106
2176
|
const VALID_SIZE_KEYS = [
|
|
@@ -2242,10 +2312,10 @@ const cvaSkeleton = cssClassVarianceUtilities.cvaMerge([
|
|
|
2242
2312
|
* For shape-based elements (images, badges, buttons), use SkeletonBlock component instead.
|
|
2243
2313
|
*/
|
|
2244
2314
|
const SkeletonLabel = react.memo((props) => {
|
|
2245
|
-
const { width = "100%", textSize = "text-base", flexibleWidth = true, className, "data-testid": dataTestId, children, } = props;
|
|
2315
|
+
const { width = "100%", textSize = "text-base", flexibleWidth = true, className, "data-testid": dataTestId, children, ref, } = props;
|
|
2246
2316
|
const widthValue = typeof width === "number" ? `${width}px` : width;
|
|
2247
2317
|
const heightValue = getHeightValue(textSize);
|
|
2248
|
-
return (jsxRuntime.jsx("div", { "aria-label": "Loading", className: cvaSkeleton({ textSize, className }), "data-testid": dataTestId, role: "status", style: {
|
|
2318
|
+
return (jsxRuntime.jsx("div", { "aria-label": "Loading", className: cvaSkeleton({ textSize, className }), "data-testid": dataTestId, ref: ref, role: "status", style: {
|
|
2249
2319
|
width: flexibleWidth ? "100%" : widthValue,
|
|
2250
2320
|
maxWidth: flexibleWidth ? widthValue : undefined,
|
|
2251
2321
|
height: heightValue,
|
|
@@ -2435,8 +2505,8 @@ const cvaExternalLink = cssClassVarianceUtilities.cvaMerge(["underline", "decora
|
|
|
2435
2505
|
* @param {ExternalLinkProps} props - The props for the external link component
|
|
2436
2506
|
* @returns {ReactElement} External Link component
|
|
2437
2507
|
*/
|
|
2438
|
-
const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className, children = href, title = href, "data-testid": dataTestId, onClick, color = "primary", }) => {
|
|
2439
|
-
return (jsxRuntime.jsx("a", { className: cvaExternalLink({ className, color }), "data-testid": dataTestId, href: href, onClick: onClick, rel: rel, target: target, title: title, children: children }));
|
|
2508
|
+
const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className, children = href, title = href, "data-testid": dataTestId, onClick, color = "primary", ref, }) => {
|
|
2509
|
+
return (jsxRuntime.jsx("a", { className: cvaExternalLink({ className, color }), "data-testid": dataTestId, href: href, onClick: onClick, ref: ref, rel: rel, target: target, title: title, children: children }));
|
|
2440
2510
|
};
|
|
2441
2511
|
|
|
2442
2512
|
// =============================================================================
|
|
@@ -3240,70 +3310,6 @@ const Highlight = ({ className, "data-testid": dataTestId, children, size = "sma
|
|
|
3240
3310
|
};
|
|
3241
3311
|
Highlight.displayName = "Highlight";
|
|
3242
3312
|
|
|
3243
|
-
// This hook is _heavily_ inspired by floating-ui's useMergeRefs
|
|
3244
|
-
/**
|
|
3245
|
-
* Merges an array of refs into a single memoized callback ref or `null`.
|
|
3246
|
-
* Useful when you need to attach multiple refs to the same element,
|
|
3247
|
-
* such as when composing multiple hooks that each need a ref.
|
|
3248
|
-
*
|
|
3249
|
-
* @template TInstance - The type of the element instance
|
|
3250
|
-
* @param {ReadonlyArray<MergeableRef<TInstance> | undefined>} refs - Array of refs to merge (can be RefObjects, RefCallbacks, or undefined)
|
|
3251
|
-
* @returns {null | RefCallback<TInstance>} A single ref callback that will update all provided refs, or null if all refs are null
|
|
3252
|
-
* @example
|
|
3253
|
-
* ```tsx
|
|
3254
|
-
* const { ref: measureRef } = useMeasure();
|
|
3255
|
-
* const { ref: scrollRef } = useScrollDetection();
|
|
3256
|
-
* const mergedRef = useMergeRefs([measureRef, scrollRef]);
|
|
3257
|
-
*
|
|
3258
|
-
* return <div ref={mergedRef}>Content</div>;
|
|
3259
|
-
* ```
|
|
3260
|
-
*/
|
|
3261
|
-
function useMergeRefs(refs) {
|
|
3262
|
-
const cleanupRef = react.useRef(undefined);
|
|
3263
|
-
const refsRef = react.useRef(refs);
|
|
3264
|
-
react.useEffect(() => {
|
|
3265
|
-
refsRef.current = refs;
|
|
3266
|
-
}, [refs]);
|
|
3267
|
-
const refEffect = react.useCallback((instance) => {
|
|
3268
|
-
const cleanups = refsRef.current.map(ref => {
|
|
3269
|
-
if (ref === null || ref === undefined) {
|
|
3270
|
-
return;
|
|
3271
|
-
}
|
|
3272
|
-
if (typeof ref === "function") {
|
|
3273
|
-
const refCallback = ref;
|
|
3274
|
-
const refCleanup = refCallback(instance);
|
|
3275
|
-
return typeof refCleanup === "function"
|
|
3276
|
-
? refCleanup
|
|
3277
|
-
: () => {
|
|
3278
|
-
refCallback(null);
|
|
3279
|
-
};
|
|
3280
|
-
}
|
|
3281
|
-
ref.current = instance;
|
|
3282
|
-
return () => {
|
|
3283
|
-
ref.current = null;
|
|
3284
|
-
};
|
|
3285
|
-
});
|
|
3286
|
-
return () => {
|
|
3287
|
-
cleanups.forEach(refCleanup => refCleanup?.());
|
|
3288
|
-
};
|
|
3289
|
-
}, []);
|
|
3290
|
-
return react.useMemo(() => {
|
|
3291
|
-
// eslint-disable-next-line react-hooks/refs
|
|
3292
|
-
if (refsRef.current.every(ref => ref === null)) {
|
|
3293
|
-
return null;
|
|
3294
|
-
}
|
|
3295
|
-
return (value) => {
|
|
3296
|
-
if (cleanupRef.current) {
|
|
3297
|
-
cleanupRef.current();
|
|
3298
|
-
cleanupRef.current = undefined;
|
|
3299
|
-
}
|
|
3300
|
-
if (value !== null) {
|
|
3301
|
-
cleanupRef.current = refEffect(value);
|
|
3302
|
-
}
|
|
3303
|
-
};
|
|
3304
|
-
}, [refEffect]);
|
|
3305
|
-
}
|
|
3306
|
-
|
|
3307
3313
|
/**
|
|
3308
3314
|
* The useDebounce hook works like useState, but adds a delay where previous values will be ignored.
|
|
3309
3315
|
*
|
|
@@ -3565,8 +3571,8 @@ const cvaZStackItem = cssClassVarianceUtilities.cvaMerge(["col-start-1", "col-en
|
|
|
3565
3571
|
* @param { ZStackProps} props - The props for the ZStack component
|
|
3566
3572
|
* @returns {Element} ZStack component
|
|
3567
3573
|
*/
|
|
3568
|
-
const ZStack = ({ children, className, "data-testid": dataTestId }) => {
|
|
3569
|
-
return (jsxRuntime.jsx("div", { className: cvaZStackContainer({ className }), "data-testid": dataTestId, children: react.Children.map(children, (child, index) => {
|
|
3574
|
+
const ZStack = ({ children, className, "data-testid": dataTestId, ref }) => {
|
|
3575
|
+
return (jsxRuntime.jsx("div", { className: cvaZStackContainer({ className }), "data-testid": dataTestId, ref: ref, children: react.Children.map(children, (child, index) => {
|
|
3570
3576
|
if (!react.isValidElement(child)) {
|
|
3571
3577
|
return child;
|
|
3572
3578
|
}
|
|
@@ -3637,9 +3643,10 @@ const OverflowIndicator = ({ className, "data-testid": dataTestId, direction, on
|
|
|
3637
3643
|
* @param props.className - Optional CSS class name for styling
|
|
3638
3644
|
* @param props."data-testid" - Optional test ID for testing purposes
|
|
3639
3645
|
* @param props.onScrollStateChange - Optional callback fired when scroll state changes
|
|
3646
|
+
* @param [props.ref] - Ref forwarded to the root element
|
|
3640
3647
|
* @returns {ReactElement} A horizontal overflow scroller component with visual indicators
|
|
3641
3648
|
*/
|
|
3642
|
-
const HorizontalOverflowScroller = ({ className, "data-testid": dataTestId, children, onScrollStateChange, }) => {
|
|
3649
|
+
const HorizontalOverflowScroller = ({ className, "data-testid": dataTestId, children, onScrollStateChange, ref, }) => {
|
|
3643
3650
|
const childrenArray = react.Children.toArray(children);
|
|
3644
3651
|
const { geometry: containerGeometry, ref: measureRef, element } = useMeasure();
|
|
3645
3652
|
const { ref: scrollRef, isScrollable, isAtBeginning, isAtEnd, } = useScrollDetection({
|
|
@@ -3652,7 +3659,7 @@ const HorizontalOverflowScroller = ({ className, "data-testid": dataTestId, chil
|
|
|
3652
3659
|
})
|
|
3653
3660
|
: undefined,
|
|
3654
3661
|
});
|
|
3655
|
-
const mergedRef = useMergeRefs([measureRef, scrollRef]);
|
|
3662
|
+
const mergedRef = useMergeRefs([measureRef, scrollRef, ref]);
|
|
3656
3663
|
const handleScrollLeft = () => {
|
|
3657
3664
|
if (!element || containerGeometry?.width === undefined)
|
|
3658
3665
|
return;
|
|
@@ -4318,8 +4325,8 @@ const cvaIndicatorIconBackground = cssClassVarianceUtilities.cvaMerge(["rounded-
|
|
|
4318
4325
|
* @param {IndicatorProps} props - The props for the Indicator component
|
|
4319
4326
|
* @returns {ReactElement} Indicator component
|
|
4320
4327
|
*/
|
|
4321
|
-
const Indicator = ({ "data-testid": dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false, size = "medium", weight = "normal", className, ...rest }) => {
|
|
4322
|
-
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] }) }));
|
|
4328
|
+
const Indicator = ({ "data-testid": dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false, size = "medium", weight = "normal", className, ref, ...rest }) => {
|
|
4329
|
+
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, ref: ref, ...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] }) }));
|
|
4323
4330
|
};
|
|
4324
4331
|
|
|
4325
4332
|
/**
|
|
@@ -4451,20 +4458,20 @@ const cvaKPITrendPercentage = cssClassVarianceUtilities.cvaMerge([""], {
|
|
|
4451
4458
|
* @param {KPIProps} props - The props for the KPI component
|
|
4452
4459
|
* @returns {ReactElement} KPI component
|
|
4453
4460
|
*/
|
|
4454
|
-
const KPI = ({ title, value, unit, className, "data-testid": dataTestId, tooltipLabel, variant = "default", style, ...rest }) => {
|
|
4461
|
+
const KPI = ({ title, value, unit, className, "data-testid": dataTestId, tooltipLabel, variant = "default", style, ref, ...rest }) => {
|
|
4455
4462
|
const isSmallVariant = variant === "small";
|
|
4456
|
-
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] }) })] }) }));
|
|
4463
|
+
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, ref: ref, 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] }) })] }) }));
|
|
4457
4464
|
};
|
|
4458
4465
|
|
|
4459
4466
|
/**
|
|
4460
4467
|
* Skeleton loading indicator that mimics the KPI component structure.
|
|
4461
4468
|
* Uses the same layout, spacing, and visual hierarchy as KPI.
|
|
4462
4469
|
*/
|
|
4463
|
-
const KPISkeleton = ({ variant = "default", className, "data-testid": dataTestId, style, ...rest }) => {
|
|
4470
|
+
const KPISkeleton = ({ variant = "default", className, "data-testid": dataTestId, style, ref, ...rest }) => {
|
|
4464
4471
|
const isSmallVariant = variant === "small";
|
|
4465
4472
|
// Generate stable random widths once and never change them
|
|
4466
4473
|
const [titleWidth, valueWidth] = useRandomCSSLengths({ count: 2, min: 60, max: 100 });
|
|
4467
|
-
return (jsxRuntime.jsxs("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId, style: style, ...rest, children: [jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex", "items-center", "flex-row", isSmallVariant ? "h-4" : "h-5"), children: jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-title-loading` : undefined, textSize: isSmallVariant ? "text-xs" : "text-sm", width: titleWidth }) }), jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("truncate", "whitespace-nowrap", "flex h-7 flex-row items-center"), children: jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-value-loading` : undefined, textSize: isSmallVariant ? "text-xs" : "text-lg", width: valueWidth }) })] }));
|
|
4474
|
+
return (jsxRuntime.jsxs("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId, ref: ref, style: style, ...rest, children: [jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex", "items-center", "flex-row", isSmallVariant ? "h-4" : "h-5"), children: jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-title-loading` : undefined, textSize: isSmallVariant ? "text-xs" : "text-sm", width: titleWidth }) }), jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("truncate", "whitespace-nowrap", "flex h-7 flex-row items-center"), children: jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-value-loading` : undefined, textSize: isSmallVariant ? "text-xs" : "text-lg", width: valueWidth }) })] }));
|
|
4468
4475
|
};
|
|
4469
4476
|
|
|
4470
4477
|
/**
|
|
@@ -4473,8 +4480,8 @@ const KPISkeleton = ({ variant = "default", className, "data-testid": dataTestId
|
|
|
4473
4480
|
* @param {TrendIndicatorProps} props - The props for the TrendIndicator component
|
|
4474
4481
|
* @returns {ReactElement} TrendIndicator component
|
|
4475
4482
|
*/
|
|
4476
|
-
const TrendIndicator = ({ value, trend, label, icon = undefined, color = undefined, "data-testid": dataTestId, className, }) => {
|
|
4477
|
-
return (jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex flex-row items-center gap-1", className), "data-testid": dataTestId, children: [value !== undefined ? (jsxRuntime.jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-value` : undefined, size: "small", weight: "normal", children: value })) : null, jsxRuntime.jsxs("div", { className: "flex items-center", children: [icon ? (jsxRuntime.jsx(Icon, { color: color, "data-testid": dataTestId ? `${dataTestId}-icon` : undefined, name: icon, size: "small" })) : null, jsxRuntime.jsx(Text, { className: cvaKPITrendPercentage({ color }), "data-testid": dataTestId ? `${dataTestId}-trend` : undefined, size: "small", weight: "bold", children: trend })] }), jsxRuntime.jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-label` : undefined, size: "small", weight: "normal", children: label })] }));
|
|
4483
|
+
const TrendIndicator = ({ value, trend, label, icon = undefined, color = undefined, "data-testid": dataTestId, className, ref, }) => {
|
|
4484
|
+
return (jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex flex-row items-center gap-1", className), "data-testid": dataTestId, ref: ref, children: [value !== undefined ? (jsxRuntime.jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-value` : undefined, size: "small", weight: "normal", children: value })) : null, jsxRuntime.jsxs("div", { className: "flex items-center", children: [icon ? (jsxRuntime.jsx(Icon, { color: color, "data-testid": dataTestId ? `${dataTestId}-icon` : undefined, name: icon, size: "small" })) : null, jsxRuntime.jsx(Text, { className: cvaKPITrendPercentage({ color }), "data-testid": dataTestId ? `${dataTestId}-trend` : undefined, size: "small", weight: "bold", children: trend })] }), jsxRuntime.jsx(Text, { "data-testid": dataTestId ? `${dataTestId}-label` : undefined, size: "small", weight: "normal", children: label })] }));
|
|
4478
4485
|
};
|
|
4479
4486
|
|
|
4480
4487
|
/**
|
|
@@ -4483,8 +4490,8 @@ const TrendIndicator = ({ value, trend, label, icon = undefined, color = undefin
|
|
|
4483
4490
|
* @param {TrendIndicatorsProps} props - The props for the TrendIndicators component
|
|
4484
4491
|
* @returns {ReactElement} TrendIndicators component
|
|
4485
4492
|
*/
|
|
4486
|
-
const TrendIndicators = ({ trends, "data-testid": dataTestId, className, }) => {
|
|
4487
|
-
return (jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("flex flex-row items-center gap-1", className), "data-testid": dataTestId, children: trends.map((trend, index) => (jsxRuntime.jsx(TrendIndicator, { "data-testid": dataTestId ? `${dataTestId}-trend-indicator-${index}` : undefined, ...trend }, index))) }));
|
|
4493
|
+
const TrendIndicators = ({ trends, "data-testid": dataTestId, className, ref, }) => {
|
|
4494
|
+
return (jsxRuntime.jsx("span", { className: tailwindMerge.twMerge("flex flex-row items-center gap-1", className), "data-testid": dataTestId, ref: ref, children: trends.map((trend, index) => (jsxRuntime.jsx(TrendIndicator, { "data-testid": dataTestId ? `${dataTestId}-trend-indicator-${index}` : undefined, ...trend }, index))) }));
|
|
4488
4495
|
};
|
|
4489
4496
|
|
|
4490
4497
|
const cvaValueBar = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -4593,11 +4600,11 @@ const getValueBarColorByValue = (value, min, max, levelColors) => {
|
|
|
4593
4600
|
* @param {ValueBarProps} props - The props for the ValueBar component
|
|
4594
4601
|
* @returns {ReactElement} ValueBar component
|
|
4595
4602
|
*/
|
|
4596
|
-
const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors, valueColor, showValue = false, className, "data-testid": dataTestId, zeroScoreAllowed = false, }) => {
|
|
4603
|
+
const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors, valueColor, showValue = false, className, "data-testid": dataTestId, zeroScoreAllowed = false, ref, }) => {
|
|
4597
4604
|
const score = getScore(value, min, max, zeroScoreAllowed);
|
|
4598
4605
|
const barFillColor = levelColors ? getFillColor(score, levelColors) : getDefaultFillColor(score);
|
|
4599
4606
|
const valueText = `${Number(value.toFixed(1))}${sharedUtils.nonNullable(unit) ? unit : ""}`;
|
|
4600
|
-
return (jsxRuntime.jsxs("span", { className: "relative flex items-center gap-2", "data-testid": dataTestId, children: [jsxRuntime.jsx("progress", { "aria-label": valueText, className: cvaValueBar({ className, size }), max: 100, style: { color: barFillColor }, value: score * 100 }), showValue && (size === "small" || size === "large") ? (jsxRuntime.jsx(Text, { className: cvaValueBarText({ size }), "data-testid": dataTestId ? `${dataTestId}-value` : undefined, children: jsxRuntime.jsx("span", { style: valueColor ? { color: valueColor } : undefined, children: valueText }) })) : null] }));
|
|
4607
|
+
return (jsxRuntime.jsxs("span", { className: "relative flex items-center gap-2", "data-testid": dataTestId, ref: ref, children: [jsxRuntime.jsx("progress", { "aria-label": valueText, className: cvaValueBar({ className, size }), max: 100, style: { color: barFillColor }, value: score * 100 }), showValue && (size === "small" || size === "large") ? (jsxRuntime.jsx(Text, { className: cvaValueBarText({ size }), "data-testid": dataTestId ? `${dataTestId}-value` : undefined, children: jsxRuntime.jsx("span", { style: valueColor ? { color: valueColor } : undefined, children: valueText }) })) : null] }));
|
|
4601
4608
|
};
|
|
4602
4609
|
|
|
4603
4610
|
const cvaKPICard = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -4686,13 +4693,13 @@ const cvaKPIIconContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-c
|
|
|
4686
4693
|
* @param {KPICardProps} props - The props for the KPICard component
|
|
4687
4694
|
* @returns {ReactElement} KPICard component
|
|
4688
4695
|
*/
|
|
4689
|
-
const KPICard = ({ isActive = false, onClick, className, "data-testid": dataTestId, children, iconName = undefined, iconColor = "info", notice, valueBar, trends, unit, ...rest }) => {
|
|
4696
|
+
const KPICard = ({ isActive = false, onClick, className, "data-testid": dataTestId, children, iconName = undefined, iconColor = "info", notice, valueBar, trends, unit, ref, ...rest }) => {
|
|
4690
4697
|
const isClickable = Boolean(onClick !== undefined);
|
|
4691
4698
|
return (jsxRuntime.jsx(Card, { className: cvaKPICard({
|
|
4692
4699
|
isClickable,
|
|
4693
4700
|
isActive,
|
|
4694
4701
|
className,
|
|
4695
|
-
}), "data-testid": dataTestId ? dataTestId : undefined, onClick: onClick, children: jsxRuntime.jsxs(CardBody, { className: cvaKPICardBody(), gap: "none", padding: "none", children: [jsxRuntime.jsxs("div", { className: cvaKPICardHeader(), children: [jsxRuntime.jsx(KPI, { ...rest, className: "p-0", "data-testid": dataTestId ? `${dataTestId}-kpi` : undefined, unit: unit }), iconName ? (jsxRuntime.jsx("div", { className: cvaKPIIconContainer({ iconColor }), children: jsxRuntime.jsx(Icon, { name: iconName, size: "small", type: "solid" }) })) : null] }), trends !== undefined && trends.length > 0 ? (jsxRuntime.jsx(TrendIndicators, { "data-testid": dataTestId ? `${dataTestId}-trend-indicators` : undefined, trends: trends })) : null, valueBar !== undefined ? (jsxRuntime.jsx(ValueBar, { className: "h-2", "data-testid": dataTestId ? `${dataTestId}-value-bar` : undefined, ...valueBar })) : null, notice !== undefined ? (
|
|
4702
|
+
}), "data-testid": dataTestId ? dataTestId : undefined, onClick: onClick, ref: ref, children: jsxRuntime.jsxs(CardBody, { className: cvaKPICardBody(), gap: "none", padding: "none", children: [jsxRuntime.jsxs("div", { className: cvaKPICardHeader(), children: [jsxRuntime.jsx(KPI, { ...rest, className: "p-0", "data-testid": dataTestId ? `${dataTestId}-kpi` : undefined, unit: unit }), iconName ? (jsxRuntime.jsx("div", { className: cvaKPIIconContainer({ iconColor }), children: jsxRuntime.jsx(Icon, { name: iconName, size: "small", type: "solid" }) })) : null] }), trends !== undefined && trends.length > 0 ? (jsxRuntime.jsx(TrendIndicators, { "data-testid": dataTestId ? `${dataTestId}-trend-indicators` : undefined, trends: trends })) : null, valueBar !== undefined ? (jsxRuntime.jsx(ValueBar, { className: "h-2", "data-testid": dataTestId ? `${dataTestId}-value-bar` : undefined, ...valueBar })) : null, notice !== undefined ? (
|
|
4696
4703
|
// NOTE: Can't use Notice component here due to the non-flexible text styling options
|
|
4697
4704
|
jsxRuntime.jsxs("div", { className: "flex items-center gap-1 truncate", "data-testid": dataTestId ? `${dataTestId}-notice` : undefined, children: [notice.iconName ? (jsxRuntime.jsx(Icon, { color: notice.iconColor, "data-testid": dataTestId ? `${dataTestId}-notice-icon` : undefined, name: notice.iconName, size: "small" })) : null, jsxRuntime.jsx(Text, { className: "truncate text-neutral-900", "data-testid": dataTestId ? `${dataTestId}-notice-label` : undefined, size: "small", children: notice.label })] })) : null, children] }) }));
|
|
4698
4705
|
};
|
|
@@ -4707,10 +4714,10 @@ const KPICard = ({ isActive = false, onClick, className, "data-testid": dataTest
|
|
|
4707
4714
|
* For multiple text lines, use SkeletonLines component instead.
|
|
4708
4715
|
*/
|
|
4709
4716
|
const SkeletonBlock = react.memo((props) => {
|
|
4710
|
-
const { width = "100%", height = 16, flexibleWidth = false, className, "data-testid": dataTestId, children } = props;
|
|
4717
|
+
const { width = "100%", height = 16, flexibleWidth = false, className, "data-testid": dataTestId, children, ref, } = props;
|
|
4711
4718
|
const widthValue = typeof width === "number" ? `${width}px` : width;
|
|
4712
4719
|
const heightValue = typeof height === "number" ? `${height}px` : height;
|
|
4713
|
-
return (jsxRuntime.jsx("div", { "aria-label": "Loading", className: cvaSkeleton({ className }), "data-testid": dataTestId, role: "status", style: {
|
|
4720
|
+
return (jsxRuntime.jsx("div", { "aria-label": "Loading", className: cvaSkeleton({ className }), "data-testid": dataTestId, ref: ref, role: "status", style: {
|
|
4714
4721
|
width: flexibleWidth ? "100%" : widthValue,
|
|
4715
4722
|
maxWidth: flexibleWidth ? widthValue : undefined,
|
|
4716
4723
|
height: heightValue,
|
|
@@ -4722,8 +4729,8 @@ SkeletonBlock.displayName = "SkeletonBlock";
|
|
|
4722
4729
|
* Skeleton loading indicator that mimics the KPICard component structure.
|
|
4723
4730
|
* Uses the same layout, spacing, and visual hierarchy as KPICard.
|
|
4724
4731
|
*/
|
|
4725
|
-
const KPICardSkeleton = ({ hasIcon = false, hasTrends = false, hasValueBar = false, hasNotice = false, children, className, "data-testid": dataTestId, style, ...rest }) => {
|
|
4726
|
-
return (jsxRuntime.jsx(Card, { className: cvaKPICard({ className }), "data-testid": dataTestId, style: style, ...rest, children: jsxRuntime.jsxs(CardBody, { className: cvaKPICardBody(), gap: "none", padding: "none", children: [jsxRuntime.jsxs("div", { className: cvaKPICardHeader(), children: [jsxRuntime.jsx(KPISkeleton, { className: "p-0", "data-testid": dataTestId ? `${dataTestId}-kpi` : undefined }), hasIcon ? (jsxRuntime.jsx(SkeletonBlock, { "data-testid": dataTestId ? `${dataTestId}-icon-loading` : undefined, height: 28, width: 28 })) : null] }), hasTrends ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-trend-indicator-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasValueBar ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-value-bar-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasNotice ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-notice-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, children] }) }));
|
|
4732
|
+
const KPICardSkeleton = ({ hasIcon = false, hasTrends = false, hasValueBar = false, hasNotice = false, children, className, "data-testid": dataTestId, style, ref, ...rest }) => {
|
|
4733
|
+
return (jsxRuntime.jsx(Card, { className: cvaKPICard({ className }), "data-testid": dataTestId, ref: ref, style: style, ...rest, children: jsxRuntime.jsxs(CardBody, { className: cvaKPICardBody(), gap: "none", padding: "none", children: [jsxRuntime.jsxs("div", { className: cvaKPICardHeader(), children: [jsxRuntime.jsx(KPISkeleton, { className: "p-0", "data-testid": dataTestId ? `${dataTestId}-kpi` : undefined }), hasIcon ? (jsxRuntime.jsx(SkeletonBlock, { "data-testid": dataTestId ? `${dataTestId}-icon-loading` : undefined, height: 28, width: 28 })) : null] }), hasTrends ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-trend-indicator-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasValueBar ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-value-bar-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasNotice ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-notice-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, children] }) }));
|
|
4727
4734
|
};
|
|
4728
4735
|
|
|
4729
4736
|
const cvaListContainer = cssClassVarianceUtilities.cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
|
|
@@ -5525,7 +5532,7 @@ const cvaMenuItemSuffix = cssClassVarianceUtilities.cvaMerge(["text-neutral-400"
|
|
|
5525
5532
|
* @param {MenuItemProps} props - The props for the MenuItem component
|
|
5526
5533
|
* @returns {ReactElement} MenuItem component
|
|
5527
5534
|
*/
|
|
5528
|
-
const MenuItem = ({ className, "data-testid": dataTestId, label, children, selected = false, focused = false, prefix, suffix, disabled = false, onClick, stopPropagation = true, id, tabIndex, optionLabelDescription, optionPrefix, fieldSize = "medium", variant = "primary", }) => {
|
|
5535
|
+
const MenuItem = ({ className, "data-testid": dataTestId, label, children, selected = false, focused = false, prefix, suffix, disabled = false, onClick, stopPropagation = true, id, tabIndex, optionLabelDescription, optionPrefix, fieldSize = "medium", variant = "primary", ref, }) => {
|
|
5529
5536
|
/* Handle tab navigation */
|
|
5530
5537
|
const handleKeyDown = (e) => {
|
|
5531
5538
|
if (e.key === "Enter" && onClick !== undefined && disabled !== true) {
|
|
@@ -5548,7 +5555,7 @@ const MenuItem = ({ className, "data-testid": dataTestId, label, children, selec
|
|
|
5548
5555
|
e.stopPropagation();
|
|
5549
5556
|
}
|
|
5550
5557
|
onClick?.(e);
|
|
5551
|
-
}, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : (tabIndex ?? 0), children: [prefix !== null && prefix !== undefined ? (jsxRuntime.jsx("div", { className: cvaMenuItemPrefix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : "menu-item-prefix", children: prefix })) : null, children !== null && children !== undefined && typeof children !== "string" ? (children) : (jsxRuntime.jsxs("div", { className: cvaMenuItemLabel({ variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-label` : "menu-item-label", children: [optionPrefix !== null && optionPrefix !== undefined ? optionPrefix : null, children ?? label, optionLabelDescription !== undefined && optionLabelDescription !== "" ? (jsxRuntime.jsxs("span", { className: "ml-1 text-neutral-400", children: ["(", optionLabelDescription, ")"] })) : null] })), suffix !== null && suffix !== undefined ? (jsxRuntime.jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
|
|
5558
|
+
}, onKeyDown: handleKeyDown, ref: ref, role: "menuitem", tabIndex: disabled ? -1 : (tabIndex ?? 0), children: [prefix !== null && prefix !== undefined ? (jsxRuntime.jsx("div", { className: cvaMenuItemPrefix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : "menu-item-prefix", children: prefix })) : null, children !== null && children !== undefined && typeof children !== "string" ? (children) : (jsxRuntime.jsxs("div", { className: cvaMenuItemLabel({ variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-label` : "menu-item-label", children: [optionPrefix !== null && optionPrefix !== undefined ? optionPrefix : null, children ?? label, optionLabelDescription !== undefined && optionLabelDescription !== "" ? (jsxRuntime.jsxs("span", { className: "ml-1 text-neutral-400", children: ["(", optionLabelDescription, ")"] })) : null] })), suffix !== null && suffix !== undefined ? (jsxRuntime.jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
|
|
5552
5559
|
};
|
|
5553
5560
|
|
|
5554
5561
|
/**
|
|
@@ -5607,7 +5614,7 @@ const MenuItem = ({ className, "data-testid": dataTestId, label, children, selec
|
|
|
5607
5614
|
* @param {MenuListProps} props - The props for the MenuList component
|
|
5608
5615
|
* @returns {ReactElement} MenuList component
|
|
5609
5616
|
*/
|
|
5610
|
-
const MenuList = ({ "data-testid": dataTestId, className, children, isMulti = false, selectedItems: controlledSelectedItems, onSelectionChange, ...args }) => {
|
|
5617
|
+
const MenuList = ({ "data-testid": dataTestId, className, children, isMulti = false, selectedItems: controlledSelectedItems, onSelectionChange, ref, ...args }) => {
|
|
5611
5618
|
const childrenArr = react.Children.toArray(children);
|
|
5612
5619
|
const [internalSelectedItems, setInternalSelectedItems] = react.useState(controlledSelectedItems ?? []);
|
|
5613
5620
|
const selectedItems = controlledSelectedItems ?? internalSelectedItems;
|
|
@@ -5624,7 +5631,7 @@ const MenuList = ({ "data-testid": dataTestId, className, children, isMulti = fa
|
|
|
5624
5631
|
setInternalSelectedItems(newSelectedItems);
|
|
5625
5632
|
}
|
|
5626
5633
|
}, [isMulti, selectedItems, onSelectionChange]);
|
|
5627
|
-
return (jsxRuntime.jsx("div", { className: cvaMenu({ className, limitWidth: true }), "data-testid": dataTestId ? `${dataTestId}-menu-list` : "menu-list", onClick: args.onClick, role: "list", tabIndex: 0, children: jsxRuntime.jsx("div", { className: cvaMenuList(), children: childrenArr.map((menuItem, index) => {
|
|
5634
|
+
return (jsxRuntime.jsx("div", { className: cvaMenu({ className, limitWidth: true }), "data-testid": dataTestId ? `${dataTestId}-menu-list` : "menu-list", onClick: args.onClick, ref: ref, role: "list", tabIndex: 0, children: jsxRuntime.jsx("div", { className: cvaMenuList(), children: childrenArr.map((menuItem, index) => {
|
|
5628
5635
|
if (react.isValidElement(menuItem)) {
|
|
5629
5636
|
const isSelected = (selectedItems.includes(menuItem.props.id ?? `${index}`) || menuItem.props.selected) ?? false;
|
|
5630
5637
|
return react.cloneElement(menuItem, {
|
|
@@ -5664,9 +5671,10 @@ const MoreMenu = ({ className, "data-testid": dataTestId, popoverProps, iconProp
|
|
|
5664
5671
|
size: "medium",
|
|
5665
5672
|
square: true,
|
|
5666
5673
|
variant: "secondary",
|
|
5667
|
-
}, customButton, customPortalId, children, }) => {
|
|
5674
|
+
}, customButton, customPortalId, children, ref, }) => {
|
|
5668
5675
|
const actionMenuRef = react.useRef(null);
|
|
5669
|
-
|
|
5676
|
+
const mergedRef = useMergeRefs([actionMenuRef, ref]);
|
|
5677
|
+
return (jsxRuntime.jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId ? dataTestId : undefined, ref: mergedRef, children: jsxRuntime.jsxs(Popover, { placement: "bottom-end", ...popoverProps, children: [jsxRuntime.jsx(PopoverTrigger, { children: customButton ?? (jsxRuntime.jsx(IconButton, { "data-testid": "more-menu-icon", ...iconButtonProps, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) })) }), jsxRuntime.jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
|
|
5670
5678
|
};
|
|
5671
5679
|
|
|
5672
5680
|
const cvaNotice = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "gap-1"]);
|
|
@@ -5714,8 +5722,8 @@ const cvaNoticeIcon = cssClassVarianceUtilities.cvaMerge(["rounded-full", "items
|
|
|
5714
5722
|
* @param {NoticeProps} props - The props for the Notice component
|
|
5715
5723
|
* @returns {ReactElement} Notice component
|
|
5716
5724
|
*/
|
|
5717
|
-
const Notice = ({ "data-testid": dataTestId, iconName = undefined, iconSize = "medium", iconColor = undefined, label, color = "neutral", withLabel = true, className, tooltipLabel = label, withTooltip = false, size = "medium", ...rest }) => {
|
|
5718
|
-
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] }) }));
|
|
5725
|
+
const Notice = ({ "data-testid": dataTestId, iconName = undefined, iconSize = "medium", iconColor = undefined, label, color = "neutral", withLabel = true, className, tooltipLabel = label, withTooltip = false, size = "medium", ref, ...rest }) => {
|
|
5726
|
+
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, ref: ref, ...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] }) }));
|
|
5719
5727
|
};
|
|
5720
5728
|
|
|
5721
5729
|
const cvaPage = cssClassVarianceUtilities.cvaMerge(["grid", "h-full"], {
|
|
@@ -5747,8 +5755,8 @@ const cvaPageContent = cssClassVarianceUtilities.cvaMerge(["overflow-auto", "pag
|
|
|
5747
5755
|
/**
|
|
5748
5756
|
* Renders the page component. Adds padding and layout to the page.
|
|
5749
5757
|
*/
|
|
5750
|
-
const Page = ({ layout, className, children, "data-testid": dataTestId }) => {
|
|
5751
|
-
return (jsxRuntime.jsx("div", { className: cvaPage({ className, layout }), "data-testid": dataTestId ? dataTestId : "page", children: children }));
|
|
5758
|
+
const Page = ({ layout, className, children, "data-testid": dataTestId, ref }) => {
|
|
5759
|
+
return (jsxRuntime.jsx("div", { className: cvaPage({ className, layout }), "data-testid": dataTestId ? dataTestId : "page", ref: ref, children: children }));
|
|
5752
5760
|
};
|
|
5753
5761
|
|
|
5754
5762
|
/**
|
|
@@ -5758,8 +5766,8 @@ const Page = ({ layout, className, children, "data-testid": dataTestId }) => {
|
|
|
5758
5766
|
* @param {PageContentProps} props - The component props.
|
|
5759
5767
|
* @returns {ReactNode} - The rendered component.
|
|
5760
5768
|
*/
|
|
5761
|
-
const PageContent = ({ className, children, "data-testid": dataTestId, layout, }) => {
|
|
5762
|
-
return (jsxRuntime.jsx("div", { className: cvaPageContent({ className, layout }), "data-testid": dataTestId ? dataTestId : "page-content", children: children }));
|
|
5769
|
+
const PageContent = ({ className, children, "data-testid": dataTestId, layout, ref, }) => {
|
|
5770
|
+
return (jsxRuntime.jsx("div", { className: cvaPageContent({ className, layout }), "data-testid": dataTestId ? dataTestId : "page-content", ref: ref, children: children }));
|
|
5763
5771
|
};
|
|
5764
5772
|
|
|
5765
5773
|
/**
|
|
@@ -5867,7 +5875,7 @@ cssClassVarianceUtilities.cvaMerge([
|
|
|
5867
5875
|
* <SkeletonLines variant="preset" preset="title-paragraph" />
|
|
5868
5876
|
*/
|
|
5869
5877
|
const SkeletonLines = react.memo((props) => {
|
|
5870
|
-
const { className, "data-testid": dataTestId } = props;
|
|
5878
|
+
const { className, "data-testid": dataTestId, ref } = props;
|
|
5871
5879
|
// Generate line configs based on variant
|
|
5872
5880
|
let lineConfigs;
|
|
5873
5881
|
if (props.variant === "preset") {
|
|
@@ -5888,7 +5896,7 @@ const SkeletonLines = react.memo((props) => {
|
|
|
5888
5896
|
}));
|
|
5889
5897
|
}
|
|
5890
5898
|
const lineCount = lineConfigs.length;
|
|
5891
|
-
return (jsxRuntime.jsx("div", { "aria-label": `Loading ${lineCount} ${lineCount === 1 ? "item" : "items"}`, className: cvaSkeletonContainer({ className }), "data-testid": dataTestId, "data-variant": props.variant, role: "status", ...(props.variant === "preset" && { "data-preset": props.preset }), children: lineConfigs.map((config, index) => (jsxRuntime.jsx(SkeletonLabel, { className: config.className, "data-testid": dataTestId ? `${dataTestId}-${index}` : undefined, flexibleWidth: config.flexibleWidth ?? true, textSize: config.textSize ?? "text-base", width: config.width ?? "100%" }, index))) }));
|
|
5899
|
+
return (jsxRuntime.jsx("div", { "aria-label": `Loading ${lineCount} ${lineCount === 1 ? "item" : "items"}`, className: cvaSkeletonContainer({ className }), "data-testid": dataTestId, "data-variant": props.variant, ref: ref, role: "status", ...(props.variant === "preset" && { "data-preset": props.preset }), children: lineConfigs.map((config, index) => (jsxRuntime.jsx(SkeletonLabel, { className: config.className, "data-testid": dataTestId ? `${dataTestId}-${index}` : undefined, flexibleWidth: config.flexibleWidth ?? true, textSize: config.textSize ?? "text-base", width: config.width ?? "100%" }, index))) }));
|
|
5892
5900
|
});
|
|
5893
5901
|
SkeletonLines.displayName = "SkeletonLines";
|
|
5894
5902
|
|
|
@@ -5901,16 +5909,17 @@ const LoadingContent = () => (jsxRuntime.jsx("div", { className: "flex flex-row
|
|
|
5901
5909
|
*
|
|
5902
5910
|
* @param {object} props - The props for the PageHeaderKpiMetrics component
|
|
5903
5911
|
* @param {Array<PageHeaderKpiMetricsType>} props.kpiMetrics - The KPI metrics to render
|
|
5912
|
+
* @param [props.ref] - Ref forwarded to the root element
|
|
5904
5913
|
* @returns {ReactElement} PageHeaderKpiMetrics component
|
|
5905
5914
|
*/
|
|
5906
|
-
const PageHeaderKpiMetrics = ({ kpiMetrics }) => {
|
|
5907
|
-
return (jsxRuntime.jsx("div", { className: "hidden items-center gap-4 md:flex", children: kpiMetrics
|
|
5915
|
+
const PageHeaderKpiMetrics = ({ kpiMetrics, ref, }) => {
|
|
5916
|
+
return (jsxRuntime.jsx("div", { className: "hidden items-center gap-4 md:flex", ref: ref, children: kpiMetrics
|
|
5908
5917
|
.filter(kpi => kpi.hidden === false || kpi.hidden === undefined)
|
|
5909
5918
|
.map((kpi, index) => {
|
|
5910
5919
|
if (kpi.loading === true) {
|
|
5911
5920
|
return jsxRuntime.jsx(LoadingContent, {}, `${kpi}-${index}`);
|
|
5912
5921
|
}
|
|
5913
|
-
return (jsxRuntime.jsxs("div", { className: "flex flex-col text-
|
|
5922
|
+
return (jsxRuntime.jsxs("div", { className: "text-nowrap flex flex-col text-left", children: [jsxRuntime.jsx("span", { className: "text-xs text-neutral-500", children: kpi.header }), jsxRuntime.jsxs("div", { className: "flex flex-row items-center gap-1", children: [jsxRuntime.jsx("span", { className: "text-lg font-medium text-neutral-900", children: kpi.value }), kpi.unit ? jsxRuntime.jsx("span", { className: "text-xs text-neutral-900", children: kpi.unit }) : null] })] }, `${kpi}-${index}`));
|
|
5914
5923
|
}) }));
|
|
5915
5924
|
};
|
|
5916
5925
|
|
|
@@ -6046,11 +6055,12 @@ const cvaPageHeaderHeading = cssClassVarianceUtilities.cvaMerge(["text-neutral-9
|
|
|
6046
6055
|
* @param {string} props.title - The title of the page header
|
|
6047
6056
|
* @param {string} props.className - The class name of the page header title
|
|
6048
6057
|
* @param {string} [props."data-testid"] - The data test id of the page header title
|
|
6058
|
+
* @param [props.ref] - Ref forwarded to the root element
|
|
6049
6059
|
* @returns {ReactElement} PageHeaderTitle component
|
|
6050
6060
|
*/
|
|
6051
|
-
const PageHeaderTitle = ({ title, "data-testid": dataTestId, className, }) => {
|
|
6061
|
+
const PageHeaderTitle = ({ title, "data-testid": dataTestId, className, ref: forwardedRef, }) => {
|
|
6052
6062
|
const { ref, isTextTruncated } = useIsTextTruncated();
|
|
6053
|
-
return (jsxRuntime.jsx("div", { className: "flex flex-row items-center", children: jsxRuntime.jsx(Tooltip, { asChild: false, className: "
|
|
6063
|
+
return (jsxRuntime.jsx("div", { className: "flex flex-row items-center", ref: forwardedRef, children: jsxRuntime.jsx(Tooltip, { asChild: false, className: "min-w-16 grid", disabled: !isTextTruncated, label: title, placement: "top", children: jsxRuntime.jsx("h1", { className: cvaPageHeaderHeading({ className }), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, ref: ref, children: title }) }) }));
|
|
6054
6064
|
};
|
|
6055
6065
|
|
|
6056
6066
|
/**
|
|
@@ -6102,7 +6112,7 @@ const PageHeaderTitle = ({ title, "data-testid": dataTestId, className, }) => {
|
|
|
6102
6112
|
* @param {PageHeaderProps} props - The props for the PageHeader component
|
|
6103
6113
|
* @returns {ReactElement} PageHeader component
|
|
6104
6114
|
*/
|
|
6105
|
-
const PageHeader = ({ className, "data-testid": dataTestId, showLoading = false, description, title, tagLabel, backTo, tagColor, tabsList, descriptionIcon = "QuestionMarkCircle", tagTooltipLabel, ...discriminatedProps }) => {
|
|
6115
|
+
const PageHeader = ({ className, "data-testid": dataTestId, showLoading = false, description, title, tagLabel, backTo, tagColor, tabsList, descriptionIcon = "QuestionMarkCircle", tagTooltipLabel, ref, ...discriminatedProps }) => {
|
|
6106
6116
|
const tagRenderer = react.useMemo(() => {
|
|
6107
6117
|
if (tagLabel === undefined || tagLabel === "" || showLoading) {
|
|
6108
6118
|
return null;
|
|
@@ -6113,7 +6123,7 @@ const PageHeader = ({ className, "data-testid": dataTestId, showLoading = false,
|
|
|
6113
6123
|
return (jsxRuntime.jsxs("div", { className: cvaPageHeaderContainer({
|
|
6114
6124
|
className,
|
|
6115
6125
|
withBorder: tabsList === undefined,
|
|
6116
|
-
}), "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: {
|
|
6126
|
+
}), "data-testid": dataTestId, ref: ref, 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: {
|
|
6117
6127
|
name: descriptionIcon,
|
|
6118
6128
|
"data-testid": "page-header-description-icon",
|
|
6119
6129
|
}, 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" &&
|
|
@@ -6132,7 +6142,7 @@ const cvaPaginationText = cssClassVarianceUtilities.cvaMerge("whitespace-nowrap"
|
|
|
6132
6142
|
* @param {PaginationProps} props - The props for the Pagination component
|
|
6133
6143
|
* @returns {ReactElement} Pagination component
|
|
6134
6144
|
*/
|
|
6135
|
-
const Pagination = ({ previousPage, nextPage, canPreviousPage = false, canNextPage = false, pageCount, pageIndex, loading = false, className, "data-testid": dataTestId, getTranslatedCount, onPageChange, cursorBase = false, }) => {
|
|
6145
|
+
const Pagination = ({ previousPage, nextPage, canPreviousPage = false, canNextPage = false, pageCount, pageIndex, loading = false, className, "data-testid": dataTestId, getTranslatedCount, onPageChange, cursorBase = false, ref, }) => {
|
|
6136
6146
|
const [page, setPage] = react.useState(pageIndex);
|
|
6137
6147
|
const [currentPage, setCurrentPage] = react.useState(String(pageIndex !== undefined ? pageIndex + 1 : 1));
|
|
6138
6148
|
if (!loading && pageCount === undefined) {
|
|
@@ -6175,9 +6185,9 @@ const Pagination = ({ previousPage, nextPage, canPreviousPage = false, canNextPa
|
|
|
6175
6185
|
onPageChange?.({ from, to, description });
|
|
6176
6186
|
}, [page, onPageChange, previousPage, nextPage]);
|
|
6177
6187
|
if (loading) {
|
|
6178
|
-
return (jsxRuntime.jsx("div", { className: cvaPagination({ className }), children: jsxRuntime.jsx(SkeletonLabel, { textSize: "text-sm", width: 150 }) }));
|
|
6188
|
+
return (jsxRuntime.jsx("div", { className: cvaPagination({ className }), ref: ref, children: jsxRuntime.jsx(SkeletonLabel, { textSize: "text-sm", width: 150 }) }));
|
|
6179
6189
|
}
|
|
6180
|
-
return (jsxRuntime.jsxs("div", { className: cvaPagination({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsx(IconButton, { "data-testid": "prev-page", disabled: cursorBase ? !canPreviousPage || false : page !== undefined && page <= 0, icon: jsxRuntime.jsx(Icon, { name: "ChevronLeft", size: "small" }), onClick: () => handlePageChange("prev"), size: "small", variant: "ghost-neutral" }), !cursorBase && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: cvaPaginationText(), "data-testid": "current-page", children: currentPage }), jsxRuntime.jsx("div", { className: cvaPaginationText(), "data-testid": "page-count", children: pageCount !== null && pageCount !== undefined && getTranslatedCount ? getTranslatedCount(pageCount) : null })] })), jsxRuntime.jsx(IconButton, { "data-testid": "next-page", disabled: cursorBase
|
|
6190
|
+
return (jsxRuntime.jsxs("div", { className: cvaPagination({ className }), "data-testid": dataTestId, ref: ref, children: [jsxRuntime.jsx(IconButton, { "data-testid": "prev-page", disabled: cursorBase ? !canPreviousPage || false : page !== undefined && page <= 0, icon: jsxRuntime.jsx(Icon, { name: "ChevronLeft", size: "small" }), onClick: () => handlePageChange("prev"), size: "small", variant: "ghost-neutral" }), !cursorBase && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: cvaPaginationText(), "data-testid": "current-page", children: currentPage }), jsxRuntime.jsx("div", { className: cvaPaginationText(), "data-testid": "page-count", children: pageCount !== null && pageCount !== undefined && getTranslatedCount ? getTranslatedCount(pageCount) : null })] })), jsxRuntime.jsx(IconButton, { "data-testid": "next-page", disabled: cursorBase
|
|
6181
6191
|
? !canNextPage || false
|
|
6182
6192
|
: page !== undefined && pageCount !== undefined && pageCount !== null && page >= pageCount - 1, icon: jsxRuntime.jsx(Icon, { name: "ChevronRight", size: "small" }), onClick: () => handlePageChange("next"), size: "small", variant: "ghost-neutral" })] }));
|
|
6183
6193
|
};
|
|
@@ -6189,7 +6199,7 @@ const STROKE_WIDTH_THRESHOLD = 32;
|
|
|
6189
6199
|
* @param { PolygonProps} props - The props for the Polygon component
|
|
6190
6200
|
* @returns {ReactElement} Polygon component
|
|
6191
6201
|
*/
|
|
6192
|
-
const Polygon = ({ points, size, color = "black", opaque = true, className, "data-testid": dataTestId, }) => {
|
|
6202
|
+
const Polygon = ({ points, size, color = "black", opaque = true, className, "data-testid": dataTestId, ref, }) => {
|
|
6193
6203
|
// Calculate the bounds of the points
|
|
6194
6204
|
const minX = Math.min(...points.map(coord => coord[0]));
|
|
6195
6205
|
const maxX = Math.max(...points.map(coord => coord[0]));
|
|
@@ -6206,7 +6216,7 @@ const Polygon = ({ points, size, color = "black", opaque = true, className, "dat
|
|
|
6206
6216
|
size: sizeToNormalizeAgainst,
|
|
6207
6217
|
})}`)
|
|
6208
6218
|
.join(" ");
|
|
6209
|
-
return (jsxRuntime.jsx("svg", { className: className, "data-testid": dataTestId, height: size, style: { width: `${size}px`, height: `${size}px` }, viewBox: `0 0 ${size} ${size}`, width: size, xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("polygon", { points: normalizedPoints, style: {
|
|
6219
|
+
return (jsxRuntime.jsx("svg", { className: className, "data-testid": dataTestId, height: size, ref: ref, style: { width: `${size}px`, height: `${size}px` }, viewBox: `0 0 ${size} ${size}`, width: size, xmlns: "http://www.w3.org/2000/svg", children: jsxRuntime.jsx("polygon", { points: normalizedPoints, style: {
|
|
6210
6220
|
fill: color,
|
|
6211
6221
|
fillOpacity: opaque ? 0.2 : undefined,
|
|
6212
6222
|
stroke: color,
|
|
@@ -6222,8 +6232,8 @@ const normalize = ({ value, min, max, size }) => ((value - min) / (max - min)) *
|
|
|
6222
6232
|
* @param {PopoverTitleProps} props - The props for the PopoverTitle component
|
|
6223
6233
|
* @returns {ReactElement} PopoverTitle component
|
|
6224
6234
|
*/
|
|
6225
|
-
const PopoverTitle = ({ children, action, divider = false, className, "data-testid": dataTestId, }) => {
|
|
6226
|
-
return (jsxRuntime.jsxs("div", { className: cvaPopoverTitleContainer({ divider, className }), "data-testid": dataTestId, children: [jsxRuntime.jsx(Text, { className: cvaPopoverTitleText(), size: "small", subtle: true, type: "div", uppercase: true, weight: "bold", children: children }), action] }));
|
|
6235
|
+
const PopoverTitle = ({ children, action, divider = false, className, "data-testid": dataTestId, ref, }) => {
|
|
6236
|
+
return (jsxRuntime.jsxs("div", { className: cvaPopoverTitleContainer({ divider, className }), "data-testid": dataTestId, ref: ref, children: [jsxRuntime.jsx(Text, { className: cvaPopoverTitleText(), size: "small", subtle: true, type: "div", uppercase: true, weight: "bold", children: children }), action] }));
|
|
6227
6237
|
};
|
|
6228
6238
|
|
|
6229
6239
|
const cvaPreferenceCard = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -6365,8 +6375,9 @@ const preferenceCardGrid = createGrid()
|
|
|
6365
6375
|
* with various states and visual treatments.
|
|
6366
6376
|
* It is recommended to be primarily used as an input component, as it supports checkboxes, radio buttons and toggles.
|
|
6367
6377
|
*/
|
|
6368
|
-
const PreferenceCard = ({ title, description, icon, input, titleTag, cardTag, disabled = false, className, "data-testid": dataTestId, children, }) => {
|
|
6369
|
-
const { ref, geometry } = useMeasure();
|
|
6378
|
+
const PreferenceCard = ({ title, description, icon, input, titleTag, cardTag, disabled = false, className, "data-testid": dataTestId, children, ref: forwardedRef, }) => {
|
|
6379
|
+
const { ref: measureRef, geometry } = useMeasure();
|
|
6380
|
+
const ref = useMergeRefs([measureRef, forwardedRef]);
|
|
6370
6381
|
const gridAreas = useGridAreas(preferenceCardGrid);
|
|
6371
6382
|
return (jsxRuntime.jsxs("div", { className: cvaPreferenceCard({
|
|
6372
6383
|
disabled,
|
|
@@ -6415,7 +6426,7 @@ const getRandomWidth = (min, max) => {
|
|
|
6415
6426
|
* Skeleton loading indicator that mimics the PreferenceCard component structure.
|
|
6416
6427
|
* Uses the same grid layout, spacing, and visual hierarchy as PreferenceCard.
|
|
6417
6428
|
*/
|
|
6418
|
-
const PreferenceCardSkeleton = ({ hasIcon = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasIcon, hasTitleTag = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasTitleTag, hasCardTag = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasCardTag, hasInput = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasInput, }) => {
|
|
6429
|
+
const PreferenceCardSkeleton = ({ hasIcon = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasIcon, hasTitleTag = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasTitleTag, hasCardTag = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasCardTag, hasInput = DEFAULT_SKELETON_PREFERENCE_CARD_PROPS.hasInput, ref, }) => {
|
|
6419
6430
|
const gridAreas = useGridAreas(preferenceCardGrid);
|
|
6420
6431
|
// Generate stable random widths once and never change them
|
|
6421
6432
|
const lineWidths = react.useMemo(() => {
|
|
@@ -6424,7 +6435,7 @@ const PreferenceCardSkeleton = ({ hasIcon = DEFAULT_SKELETON_PREFERENCE_CARD_PRO
|
|
|
6424
6435
|
description: getRandomWidth(160, 240),
|
|
6425
6436
|
};
|
|
6426
6437
|
}, []);
|
|
6427
|
-
return (jsxRuntime.jsxs("div", { className: cvaPreferenceCard(), children: [hasInput ? (jsxRuntime.jsx("div", { className: cvaInputContainer({ itemPlacement: "center" }), children: jsxRuntime.jsx(SkeletonBlock, { height: 20, width: 20 }) })) : null, jsxRuntime.jsx("div", { className: cvaContentWrapper(), children: jsxRuntime.jsx(GridAreas, { ...gridAreas, className: cvaContentContainer({ itemPlacement: "center" }), children: slots => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasIcon ? (jsxRuntime.jsx("div", { ...slots.icon, children: jsxRuntime.jsx(SkeletonBlock, { className: cvaIconBackground({ disabled: false }), height: 32, width: 32 }) })) : null, jsxRuntime.jsxs("div", { ...slots.information, className: "min-w-0 flex-1", children: [jsxRuntime.jsx("div", { className: "grid min-w-0 grid-cols-[1fr_auto] items-center gap-2", children: jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [jsxRuntime.jsx(SkeletonLabel, { textSize: "text-sm", width: lineWidths.title }), hasTitleTag ? jsxRuntime.jsx(TagSkeleton, { size: "small" }) : null] }) }), jsxRuntime.jsx(SkeletonLabel, { textSize: "text-xs", width: lineWidths.description })] }), hasCardTag ? (jsxRuntime.jsx("div", { ...slots.cardTag, className: "justify-self-end", children: jsxRuntime.jsx(TagSkeleton, { size: "medium" }) })) : null] })) }) })] }));
|
|
6438
|
+
return (jsxRuntime.jsxs("div", { className: cvaPreferenceCard(), ref: ref, children: [hasInput ? (jsxRuntime.jsx("div", { className: cvaInputContainer({ itemPlacement: "center" }), children: jsxRuntime.jsx(SkeletonBlock, { height: 20, width: 20 }) })) : null, jsxRuntime.jsx("div", { className: cvaContentWrapper(), children: jsxRuntime.jsx(GridAreas, { ...gridAreas, className: cvaContentContainer({ itemPlacement: "center" }), children: slots => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasIcon ? (jsxRuntime.jsx("div", { ...slots.icon, children: jsxRuntime.jsx(SkeletonBlock, { className: cvaIconBackground({ disabled: false }), height: 32, width: 32 }) })) : null, jsxRuntime.jsxs("div", { ...slots.information, className: "min-w-0 flex-1", children: [jsxRuntime.jsx("div", { className: "grid min-w-0 grid-cols-[1fr_auto] items-center gap-2", children: jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [jsxRuntime.jsx(SkeletonLabel, { textSize: "text-sm", width: lineWidths.title }), hasTitleTag ? jsxRuntime.jsx(TagSkeleton, { size: "small" }) : null] }) }), jsxRuntime.jsx(SkeletonLabel, { textSize: "text-xs", width: lineWidths.description })] }), hasCardTag ? (jsxRuntime.jsx("div", { ...slots.cardTag, className: "justify-self-end", children: jsxRuntime.jsx(TagSkeleton, { size: "medium" }) })) : null] })) }) })] }));
|
|
6428
6439
|
};
|
|
6429
6440
|
/**
|
|
6430
6441
|
* Simple tag skeleton for use within PreferenceCardSkeleton.
|
|
@@ -6512,8 +6523,8 @@ const cvaSpacer = cssClassVarianceUtilities.cvaMerge([], {
|
|
|
6512
6523
|
* @param {SpacerProps} props - The props for the Spacer component
|
|
6513
6524
|
* @returns {ReactElement} Spacer component
|
|
6514
6525
|
*/
|
|
6515
|
-
const Spacer = ({ size = "medium", border = false, "data-testid": dataTestId, className, }) => {
|
|
6516
|
-
return jsxRuntime.jsx("div", { className: cvaSpacer({ className, border, size }), "data-testid": dataTestId });
|
|
6526
|
+
const Spacer = ({ size = "medium", border = false, "data-testid": dataTestId, className, ref, }) => {
|
|
6527
|
+
return jsxRuntime.jsx("div", { className: cvaSpacer({ className, border, size }), "data-testid": dataTestId, ref: ref });
|
|
6517
6528
|
};
|
|
6518
6529
|
|
|
6519
6530
|
/**
|
|
@@ -6522,8 +6533,8 @@ const Spacer = ({ size = "medium", border = false, "data-testid": dataTestId, cl
|
|
|
6522
6533
|
* @param {SectionHeaderProps} props - The props for the section header component
|
|
6523
6534
|
* @returns {ReactElement} SectionHeader component
|
|
6524
6535
|
*/
|
|
6525
|
-
const SectionHeader = ({ title, subtitle, "data-testid": dataTestId, addons, }) => {
|
|
6526
|
-
return (jsxRuntime.jsxs("div", { className: "flex flex-col", children: [jsxRuntime.jsx(reactHelmetAsync.HelmetProvider, { children: jsxRuntime.jsx(reactHelmetAsync.Helmet, { title: title }) }), jsxRuntime.jsxs("div", { className: "mb-2 flex flex-row gap-2", children: [jsxRuntime.jsxs("div", { className: "flex grow flex-col gap-2", children: [jsxRuntime.jsx(Heading, { "data-testid": dataTestId, variant: "secondary", children: title }), subtitle ? (jsxRuntime.jsx(Heading, { subtle: true, variant: "subtitle", children: subtitle })) : null] }), addons !== null && addons !== undefined ? jsxRuntime.jsx("div", { className: "flex gap-2", children: addons }) : null] }), jsxRuntime.jsx(Spacer, { size: "small" })] }));
|
|
6536
|
+
const SectionHeader = ({ title, subtitle, "data-testid": dataTestId, addons, ref, }) => {
|
|
6537
|
+
return (jsxRuntime.jsxs("div", { className: "flex flex-col", ref: ref, children: [jsxRuntime.jsx(reactHelmetAsync.HelmetProvider, { children: jsxRuntime.jsx(reactHelmetAsync.Helmet, { title: title }) }), jsxRuntime.jsxs("div", { className: "mb-2 flex flex-row gap-2", children: [jsxRuntime.jsxs("div", { className: "flex grow flex-col gap-2", children: [jsxRuntime.jsx(Heading, { "data-testid": dataTestId, variant: "secondary", children: title }), subtitle ? (jsxRuntime.jsx(Heading, { subtle: true, variant: "subtitle", children: subtitle })) : null] }), addons !== null && addons !== undefined ? jsxRuntime.jsx("div", { className: "flex gap-2", children: addons }) : null] }), jsxRuntime.jsx(Spacer, { size: "small" })] }));
|
|
6527
6538
|
};
|
|
6528
6539
|
|
|
6529
6540
|
const cvaSidebar = cssClassVarianceUtilities.cvaMerge(["apply", "grid", "grid-cols-fr-min", "items-center"]);
|
|
@@ -6626,7 +6637,7 @@ const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id"
|
|
|
6626
6637
|
* @param {SidebarProps} props - The props for the Sidebar component
|
|
6627
6638
|
* @returns {ReactElement} Sidebar component
|
|
6628
6639
|
*/
|
|
6629
|
-
const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", className, "data-testid": dataTestId = "sidebar", moreMenuProps, menuListProps, overflowThreshold, }) => {
|
|
6640
|
+
const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", className, "data-testid": dataTestId = "sidebar", moreMenuProps, menuListProps, overflowThreshold, ref, }) => {
|
|
6630
6641
|
const { overflowContainerRef, itemOverflowMap } = useOverflowItems({
|
|
6631
6642
|
children,
|
|
6632
6643
|
childUniqueIdentifierAttribute: "id",
|
|
@@ -6639,7 +6650,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
|
|
|
6639
6650
|
}
|
|
6640
6651
|
return "visible";
|
|
6641
6652
|
};
|
|
6642
|
-
return (jsxRuntime.jsxs("div", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsx("div", { className: cvaSidebarChildContainer({ breakpoint, className: childContainerClassName }), "data-testid": `${dataTestId}-child-container`, ref: overflowContainerRef, children: react.Children.map(children, child => {
|
|
6653
|
+
return (jsxRuntime.jsxs("div", { className: cvaSidebar({ className }), "data-testid": dataTestId, ref: ref, children: [jsxRuntime.jsx("div", { className: cvaSidebarChildContainer({ breakpoint, className: childContainerClassName }), "data-testid": `${dataTestId}-child-container`, ref: overflowContainerRef, children: react.Children.map(children, child => {
|
|
6643
6654
|
return react.cloneElement(child, {
|
|
6644
6655
|
className: tailwindMerge.twMerge(child.props.className, itemVisibilityClassName(child.props.id)),
|
|
6645
6656
|
});
|
|
@@ -6709,13 +6720,13 @@ const cvaTab = cssClassVarianceUtilities.cvaMerge([
|
|
|
6709
6720
|
* Wrapper for radix tab component.
|
|
6710
6721
|
* We add a custom implementation of the asChild prop to make it easy to make the child element look like other tabs.
|
|
6711
6722
|
*/
|
|
6712
|
-
const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid": dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ...rest }) => {
|
|
6723
|
+
const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid": dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ref, ...rest }) => {
|
|
6713
6724
|
const renderContent = () => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [iconName !== undefined ? jsxRuntime.jsx(Icon, { name: iconName, size: "small" }) : null, react.isValidElement(children) ? children.props.children : children, suffix] }));
|
|
6714
6725
|
const commonProps = {
|
|
6715
6726
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
6716
6727
|
...rest,
|
|
6717
6728
|
};
|
|
6718
|
-
return (jsxRuntime.jsx(reactTabs.Trigger, { asChild: true, value: value, children: asChild && typeof children !== "string" ? (react.cloneElement(children, {
|
|
6729
|
+
return (jsxRuntime.jsx(reactTabs.Trigger, { asChild: true, ref: ref, value: value, children: asChild && typeof children !== "string" ? (react.cloneElement(children, {
|
|
6719
6730
|
...commonProps,
|
|
6720
6731
|
children: renderContent(),
|
|
6721
6732
|
})) : (jsxRuntime.jsx("button", { ...commonProps, "data-testid": dataTestId, children: renderContent() })) }));
|
|
@@ -6724,15 +6735,16 @@ const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid":
|
|
|
6724
6735
|
/**
|
|
6725
6736
|
* Wrapper for radix tab content component.
|
|
6726
6737
|
*/
|
|
6727
|
-
const TabContent = ({ className, "data-testid": dataTestId, children, ...rest }) => {
|
|
6728
|
-
return (jsxRuntime.jsx(reactTabs.Content, { className: cvaTabContent({ className }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, ...rest, children: children }));
|
|
6738
|
+
const TabContent = ({ className, "data-testid": dataTestId, children, ref, ...rest }) => {
|
|
6739
|
+
return (jsxRuntime.jsx(reactTabs.Content, { className: cvaTabContent({ className }), "data-testid": dataTestId ? `${dataTestId}-content` : undefined, ref: ref, ...rest, children: children }));
|
|
6729
6740
|
};
|
|
6730
6741
|
|
|
6731
6742
|
/**
|
|
6732
6743
|
* Wrapper for radix tab list component.
|
|
6733
6744
|
*/
|
|
6734
|
-
const TabList = ({ className, "data-testid": dataTestId, children, autoScrollToActive = true, ...rest }) => {
|
|
6745
|
+
const TabList = ({ className, "data-testid": dataTestId, children, autoScrollToActive = true, ref, ...rest }) => {
|
|
6735
6746
|
const listRef = react.useRef(null);
|
|
6747
|
+
const mergedRef = useMergeRefs([listRef, ref]);
|
|
6736
6748
|
react.useEffect(() => {
|
|
6737
6749
|
const element = listRef.current;
|
|
6738
6750
|
if (!element) {
|
|
@@ -6771,7 +6783,7 @@ const TabList = ({ className, "data-testid": dataTestId, children, autoScrollToA
|
|
|
6771
6783
|
});
|
|
6772
6784
|
}
|
|
6773
6785
|
}, [autoScrollToActive]);
|
|
6774
|
-
return (jsxRuntime.jsx(reactTabs.List, { className: cvaTabList({ className }), "data-testid": dataTestId, ref:
|
|
6786
|
+
return (jsxRuntime.jsx(reactTabs.List, { className: cvaTabList({ className }), "data-testid": dataTestId, ref: mergedRef, ...rest, children: children }));
|
|
6775
6787
|
};
|
|
6776
6788
|
|
|
6777
6789
|
/**
|
|
@@ -6810,8 +6822,8 @@ const TabList = ({ className, "data-testid": dataTestId, children, autoScrollToA
|
|
|
6810
6822
|
* );
|
|
6811
6823
|
* ```
|
|
6812
6824
|
*/
|
|
6813
|
-
const Tabs = ({ children, forceRender, className, "data-testid": dataTestId, fullWidth, ...rest }) => {
|
|
6814
|
-
return (jsxRuntime.jsx(reactTabs.Root, { className: cvaTabsRoot({ className }), "data-testid": dataTestId, ...rest, children: children }));
|
|
6825
|
+
const Tabs = ({ children, forceRender, className, "data-testid": dataTestId, fullWidth, ref, ...rest }) => {
|
|
6826
|
+
return (jsxRuntime.jsx(reactTabs.Root, { className: cvaTabsRoot({ className }), "data-testid": dataTestId, ref: ref, ...rest, children: children }));
|
|
6815
6827
|
};
|
|
6816
6828
|
|
|
6817
6829
|
const cvaToggleGroup = cssClassVarianceUtilities.cvaMerge(["inline-flex", "p-0.5", "bg-neutral-200", "rounded-md", "gap-1", "relative"]);
|
|
@@ -6934,7 +6946,7 @@ const cvaToggleItemContent = cssClassVarianceUtilities.cvaMerge([], {
|
|
|
6934
6946
|
* @param {ToggleGroupProps} props - The props for the ToggleGroup component
|
|
6935
6947
|
* @returns {ReactElement} ToggleGroup component
|
|
6936
6948
|
*/
|
|
6937
|
-
const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false, size = "medium", isIconOnly = false, className, "data-testid": dataTestId, }) => {
|
|
6949
|
+
const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false, size = "medium", isIconOnly = false, className, "data-testid": dataTestId, ref, }) => {
|
|
6938
6950
|
const [isMounted, setIsMounted] = react.useState(false);
|
|
6939
6951
|
const [slidingLeft, setSlidingLeft] = react.useState(0);
|
|
6940
6952
|
const [slidingWidth, setSlidingWidth] = react.useState(0);
|
|
@@ -6950,12 +6962,12 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
|
|
|
6950
6962
|
const containerPadding = 2; // p-0.5 = 2px
|
|
6951
6963
|
const gap = 4;
|
|
6952
6964
|
const left = containerPadding +
|
|
6953
|
-
buttonRefs.current.slice(0, validIndex).reduce((sum,
|
|
6965
|
+
buttonRefs.current.slice(0, validIndex).reduce((sum, btnRef) => sum + (btnRef?.offsetWidth ?? 0) + gap, 0);
|
|
6954
6966
|
const width = buttonRefs.current[validIndex]?.offsetWidth ?? 0;
|
|
6955
6967
|
setSlidingLeft(left);
|
|
6956
6968
|
setSlidingWidth(width);
|
|
6957
6969
|
}, [validIndex]);
|
|
6958
|
-
return (jsxRuntime.jsx("div", { className: tailwindMerge.twMerge(cvaToggleGroup({ className }), cvaToggleGroupWithSlidingBackground({ isMounted })), "data-testid": dataTestId, style:
|
|
6970
|
+
return (jsxRuntime.jsx("div", { className: tailwindMerge.twMerge(cvaToggleGroup({ className }), cvaToggleGroupWithSlidingBackground({ isMounted })), "data-testid": dataTestId, ref: ref, style:
|
|
6959
6971
|
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
6960
6972
|
{
|
|
6961
6973
|
"--sliding-left": `${slidingLeft}px`,
|