@trackunit/react-components 1.8.21 → 1.8.23
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 -124
- package/index.esm.js +182 -124
- package/package.json +7 -7
- package/src/common/PackageNameStoryComponent.d.ts +2 -1
- package/src/components/Alert/Alert.d.ts +2 -2
- package/src/components/Badge/Badge.d.ts +2 -1
- package/src/components/Breadcrumb/Breadcrumb.d.ts +3 -2
- package/src/components/Breadcrumb/BreadcrumbForLargeScreen.d.ts +2 -1
- package/src/components/Breadcrumb/BreadcrumbForMediumScreen.d.ts +2 -1
- package/src/components/Breadcrumb/BreadcrumbForSmallScreen.d.ts +2 -1
- package/src/components/Breadcrumb/BreadcrumbItem.d.ts +2 -1
- package/src/components/Card/Card.d.ts +2 -2
- package/src/components/Card/CardBody.d.ts +2 -2
- package/src/components/Card/CardFooter.d.ts +2 -2
- package/src/components/Card/CardHeader.d.ts +3 -3
- package/src/components/Collapse/Collapse.d.ts +2 -2
- package/src/components/CompletionStatusIndicator/CompletionStatusIndicator.d.ts +2 -1
- package/src/components/CopyableText/CopyableText.d.ts +2 -1
- package/src/components/EmptyState/EmptyState.d.ts +2 -1
- package/src/components/Highlight/Highlight.d.ts +2 -2
- package/src/components/Icon/Icon.d.ts +2 -2
- package/src/components/InteractableItem/InteractableItem.variants.d.ts +2 -2
- package/src/components/KPICard/KPICard.d.ts +1 -1
- package/src/components/Menu/MenuDivider/MenuDivider.d.ts +2 -1
- package/src/components/Menu/MenuItem/MenuItem.d.ts +2 -2
- package/src/components/Menu/MenuItem/MenuItem.variants.d.ts +3 -2
- package/src/components/Menu/MoreMenu/MoreMenu.d.ts +2 -2
- package/src/components/Page/Page.d.ts +2 -2
- package/src/components/Page/PageContent.d.ts +2 -2
- package/src/components/PageHeader/components/PageHeaderKpiMetrics.d.ts +9 -1
- package/src/components/PageHeader/components/PageHeaderSecondaryActions.d.ts +17 -2
- package/src/components/PageHeader/components/PageHeaderTitle.d.ts +10 -1
- package/src/components/Pagination/Pagination.d.ts +2 -1
- package/src/components/Polygon/Polygon.d.ts +2 -1
- package/src/components/Popover/PopoverContent.d.ts +2 -2
- package/src/components/Popover/PopoverTitle.d.ts +2 -2
- package/src/components/Popover/PopoverTrigger.d.ts +2 -2
- package/src/components/Portal/Portal.d.ts +2 -1
- package/src/components/Sidebar/Sidebar.d.ts +1 -1
- package/src/components/Sidebar/useOverflowItems.d.ts +1 -1
- package/src/components/SkeletonLines/SkeletonLines.d.ts +2 -1
- package/src/components/Spacer/Spacer.d.ts +2 -1
- package/src/components/Spinner/Spinner.d.ts +2 -1
- package/src/components/Tabs/Tab.d.ts +1 -1
- package/src/components/Tabs/TabContent.d.ts +2 -2
- package/src/components/Tabs/TabList.d.ts +1 -1
- package/src/components/Tabs/Tabs.d.ts +2 -2
- package/src/components/Tag/Tag.d.ts +2 -2
- package/src/components/ToggleGroup/ToggleGroup.d.ts +3 -3
- package/src/components/ValueBar/ValueBar.d.ts +2 -1
- package/src/components/VirtualizedList/VirtualizedList.d.ts +1 -1
- package/src/components/ZStack/ZStack.d.ts +2 -2
- package/src/components/buttons/Button/Button.d.ts +2 -2
- package/src/components/buttons/IconButton/IconButton.d.ts +4 -3
- package/src/components/buttons/StarButton/StarButton.d.ts +2 -2
- package/src/hooks/useContinuousTimeout.d.ts +1 -1
- package/src/hooks/useSelfUpdatingRef.d.ts +1 -1
package/index.esm.js
CHANGED
|
@@ -133,33 +133,29 @@ const isSafari = () => {
|
|
|
133
133
|
* @param {IconProps} props - The props for the Icon component
|
|
134
134
|
* @returns {ReactElement} Icon component
|
|
135
135
|
*/
|
|
136
|
-
const Icon = ({ name, size = "medium", className, dataTestId, color, onClick, type, style, forwardedRef, ariaLabel, fontSize, ariaLabelledBy, ariaDescribedBy, ariaHidden, }) => {
|
|
136
|
+
const Icon = ({ name, size = "medium", className, dataTestId, color = undefined, onClick, type = size === "large" ? "outline" : "solid", style, forwardedRef, ariaLabel, fontSize = false, ariaLabelledBy, ariaDescribedBy, ariaHidden, }) => {
|
|
137
137
|
const useTagRef = useRef(null);
|
|
138
138
|
const ICON_CONTAINER_ID = uuidv4();
|
|
139
139
|
const correctIconType = useMemo(() => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return "solid";
|
|
140
|
+
switch (size) {
|
|
141
|
+
case "small":
|
|
142
|
+
return "micro";
|
|
143
|
+
case "medium":
|
|
144
|
+
return "mini";
|
|
145
|
+
default:
|
|
146
|
+
return type === "solid" ? "solid" : "outline";
|
|
148
147
|
}
|
|
149
|
-
return "outline";
|
|
150
148
|
}, [type, size]);
|
|
151
149
|
const correctViewBox = useMemo(() => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
return "0 0 24 24";
|
|
150
|
+
switch (size) {
|
|
151
|
+
case "small":
|
|
152
|
+
return "0 0 16 16";
|
|
153
|
+
case "medium":
|
|
154
|
+
return "0 0 20 20";
|
|
155
|
+
default:
|
|
156
|
+
return "0 0 24 24";
|
|
160
157
|
}
|
|
161
|
-
|
|
162
|
-
}, [size, type]);
|
|
158
|
+
}, [size]);
|
|
163
159
|
const iconName = iconNames[name];
|
|
164
160
|
const href = useMemo(() => ({
|
|
165
161
|
solid: `${IconSpriteSolid}#${iconName}`,
|
|
@@ -258,15 +254,15 @@ const Tag = ({ className, dataTestId, children, size = "medium", onClose, color
|
|
|
258
254
|
return false;
|
|
259
255
|
}, [color]);
|
|
260
256
|
const layout = useMemo(() => {
|
|
261
|
-
if (onClose && isSupportedDismissColor) {
|
|
257
|
+
if (onClose !== undefined && isSupportedDismissColor) {
|
|
262
258
|
return "containsDismiss";
|
|
263
259
|
}
|
|
264
|
-
if (icon) {
|
|
260
|
+
if (icon !== null && icon !== undefined) {
|
|
265
261
|
return "containsIcon";
|
|
266
262
|
}
|
|
267
263
|
return "default";
|
|
268
264
|
}, [onClose, icon, isSupportedDismissColor]);
|
|
269
|
-
return (jsxs("div", { className: cvaTag({ className, size, color, layout, border: color === "white" ? "default" : "none" }), "data-testid": dataTestId, onMouseEnter: onMouseEnter, ref: ref, children: [icon && size === "medium" ? jsx("div", { className: cvaTagIconContainer(), children: icon }) : null, jsx("span", { className: cvaTagText(), children: children }), Boolean(onClose) && isSupportedDismissColor && size === "medium" && !disabled ? (
|
|
265
|
+
return (jsxs("div", { className: cvaTag({ className, size, color, layout, border: color === "white" ? "default" : "none" }), "data-testid": dataTestId, onMouseEnter: onMouseEnter, ref: ref, children: [icon !== null && icon !== undefined && size === "medium" ? (jsx("div", { className: cvaTagIconContainer(), children: icon })) : null, jsx("span", { className: cvaTagText(), children: children }), Boolean(onClose) && isSupportedDismissColor && size === "medium" && !disabled ? (
|
|
270
266
|
// a fix for multiselect deselecting tags working together with fade out animation
|
|
271
267
|
jsx("div", { className: cvaTagIconContainer(), onMouseDown: onClose, children: jsx(Icon, { className: cvaTagIcon(), dataTestId: dataTestId + "Icon", name: "XCircle", size: "small", style: { WebkitTransition: "-webkit-transform 0.150s" }, type: "solid" }) })) : null] }));
|
|
272
268
|
};
|
|
@@ -748,7 +744,7 @@ const cvaIconButton = cvaMerge([], {
|
|
|
748
744
|
* @param {ButtonProps} props - The props for the Button component
|
|
749
745
|
* @returns {ReactElement} Button component
|
|
750
746
|
*/
|
|
751
|
-
const Button = ({ onClick, children, loading, disabled, className, fullWidth = false, prefix, suffix, variant = "primary", type = "button", size = "medium", square = false, dataTestId, title, role, tabIndex, asChild = false, circular, ref, ...rest }) => {
|
|
747
|
+
const Button = ({ onClick, children, loading = false, disabled = false, className, fullWidth = false, prefix, suffix, variant = "primary", type = "button", size = "medium", square = false, dataTestId, title, role, tabIndex, asChild = false, circular = false, ref, ...rest }) => {
|
|
752
748
|
const Comp = asChild ? Slot : "button";
|
|
753
749
|
const sharedCompProps = {
|
|
754
750
|
ref,
|
|
@@ -766,7 +762,7 @@ const Button = ({ onClick, children, loading, disabled, className, fullWidth = f
|
|
|
766
762
|
disabled: disabled || loading,
|
|
767
763
|
type,
|
|
768
764
|
};
|
|
769
|
-
return (jsxs(Comp, { ...sharedCompProps, ...(asChild ? {} : buttonSpecificProps), children: [loading ? (jsx(Spinner, { centering: "vertically", className: cvaButtonSpinner({ variant }), containerClassName: cvaButtonSpinnerContainer(), size: "small" })) : null, prefix && !loading ? jsx("div", { className: cvaButtonPrefixSuffix({ size, variant }), children: prefix }) : null, jsx(Slottable, { children: children }), suffix && !loading ? jsx("div", { className: cvaButtonPrefixSuffix({ size, variant }), children: suffix }) : null] }));
|
|
765
|
+
return (jsxs(Comp, { ...sharedCompProps, ...(asChild ? {} : buttonSpecificProps), children: [loading ? (jsx(Spinner, { centering: "vertically", className: cvaButtonSpinner({ variant }), containerClassName: cvaButtonSpinnerContainer(), size: "small" })) : null, prefix !== null && prefix !== undefined && !loading ? (jsx("div", { className: cvaButtonPrefixSuffix({ size, variant }), children: prefix })) : null, jsx(Slottable, { children: children }), suffix !== null && suffix !== undefined && !loading ? (jsx("div", { className: cvaButtonPrefixSuffix({ size, variant }), children: suffix })) : null] }));
|
|
770
766
|
};
|
|
771
767
|
Button.displayName = "Button";
|
|
772
768
|
|
|
@@ -776,10 +772,8 @@ Button.displayName = "Button";
|
|
|
776
772
|
/**
|
|
777
773
|
*
|
|
778
774
|
*/
|
|
779
|
-
const IconButton = ({ icon, size = "medium", square = true, loading, disabled, className, ref, ...rest }) => {
|
|
780
|
-
return (jsx(Button, { className: cvaIconButton({ size: size, className }), disabled: disabled || loading, loading: loading,
|
|
781
|
-
// eslint-disable-next-line local-rules/design-guideline-button-icon-size-match
|
|
782
|
-
prefix: !loading ? icon : undefined, ref: ref, size: size, square: square, ...rest }));
|
|
775
|
+
const IconButton = ({ icon, size = "medium", square = true, loading = false, disabled = false, className, ref, ...rest }) => {
|
|
776
|
+
return (jsx(Button, { className: cvaIconButton({ size: size, className }), disabled: disabled || loading, loading: loading, prefix: !loading ? icon : undefined, ref: ref, size: size, square: square, ...rest }));
|
|
783
777
|
};
|
|
784
778
|
IconButton.displayName = "IconButton";
|
|
785
779
|
|
|
@@ -883,7 +877,7 @@ const cvaAlertIconContainer = cvaMerge(["shrink-0", "grid", "w-min", "flex"], {
|
|
|
883
877
|
* @param {AlertProps} props - The props for the Alert component
|
|
884
878
|
* @returns {ReactElement} Alert component
|
|
885
879
|
*/
|
|
886
|
-
const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClose, dataTestId, autoScroll, actionsInline = false, }) => {
|
|
880
|
+
const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClose, dataTestId, autoScroll = false, actionsInline = false, }) => {
|
|
887
881
|
const ref = useRef(null);
|
|
888
882
|
const { isTextWrapping, ref: titleRef } = useIsTextWrapping();
|
|
889
883
|
useEffect(() => {
|
|
@@ -892,7 +886,19 @@ const Alert = ({ color = "info", title, className, children, primaryAction, seco
|
|
|
892
886
|
ref.current?.scrollIntoView?.();
|
|
893
887
|
}
|
|
894
888
|
}, [ref, autoScroll]);
|
|
895
|
-
return (jsxs("div", { className: cvaAlert({ color, actionsInline, className }), "data-testid": dataTestId, ref: ref, role: "alert", children: [jsxs("div", { className: cvaAlertContentContainer({
|
|
889
|
+
return (jsxs("div", { className: cvaAlert({ color, actionsInline, className }), "data-testid": dataTestId, ref: ref, role: "alert", children: [jsxs("div", { className: cvaAlertContentContainer({
|
|
890
|
+
inline: !isTextWrapping && (children === null || children === undefined),
|
|
891
|
+
actionsInline,
|
|
892
|
+
}), children: [jsx("div", { className: cvaAlertIconContainer({
|
|
893
|
+
inline: !isTextWrapping && (children === null || children === undefined),
|
|
894
|
+
actionsInline,
|
|
895
|
+
}), children: jsx(Icon, { color: color, name: getIconName(color) }) }), jsxs("div", { className: cvaContent(), children: [title ? (jsx(Text, { dataTestId: `${dataTestId}-title`, ref: titleRef, weight: "bold", children: title })) : null, children !== null && children !== undefined ? (jsx(Text, { type: typeof children === "string" || typeof children === "number" ? "p" : "span", weight: "normal", children: children })) : null] }), onClose !== undefined && !actionsInline ? (jsx("div", { className: cvaAlertCloseButtonContainer({
|
|
896
|
+
inline: !isTextWrapping && (children === null || children === undefined),
|
|
897
|
+
actionsInline,
|
|
898
|
+
}), children: jsx(IconButton, { className: "!h-5 !min-h-0 !w-5 !p-0", icon: jsx(Icon, { name: "XMark", size: "small" }), onClick: onClose, size: "small", title: "Close Alert", variant: "ghost-neutral" }) })) : null] }), primaryAction !== undefined || secondaryAction !== undefined ? (jsxs("div", { className: cvaAlertActionsContainer({ actionsInline }), children: [secondaryAction !== undefined ? (jsx(Button, { loading: secondaryAction.loading, onClick: secondaryAction.onClick, size: "small", variant: "ghost-neutral", children: secondaryAction.label })) : null, primaryAction !== undefined ? (jsx(Button, { loading: primaryAction.loading, onClick: primaryAction.onClick, size: "small", variant: color === "danger" ? "primary-danger" : "primary", children: primaryAction.label })) : null] })) : null, onClose !== undefined && actionsInline ? (jsx("div", { className: cvaAlertCloseButtonContainer({
|
|
899
|
+
inline: !isTextWrapping && (children === null || children === undefined),
|
|
900
|
+
actionsInline,
|
|
901
|
+
}), children: jsx(IconButton, { className: "!h-5 !min-h-0 !w-5 !p-0", icon: jsx(Icon, { name: "XMark", size: "small" }), onClick: onClose, size: "small", title: "Close Alert", variant: "ghost-neutral" }) })) : null] }));
|
|
896
902
|
};
|
|
897
903
|
const getIconName = (color) => {
|
|
898
904
|
switch (color) {
|
|
@@ -966,7 +972,11 @@ const Badge = ({ color = "primary", compact = false, className, count, max, hide
|
|
|
966
972
|
if (hideZero && count === 0) {
|
|
967
973
|
return null;
|
|
968
974
|
}
|
|
969
|
-
const displayedCount = count &&
|
|
975
|
+
const displayedCount = count !== undefined && count !== 0 && !Number.isNaN(count) && max !== undefined && max !== 0 && !Number.isNaN(max)
|
|
976
|
+
? count > max
|
|
977
|
+
? `${max}+`
|
|
978
|
+
: count
|
|
979
|
+
: count;
|
|
970
980
|
const isSingleChar = displayedCount?.toString().length === 1;
|
|
971
981
|
return (jsx("span", { className: cvaBadge({ color, className, compact, isSingleChar }), "data-testid": dataTestId, children: compact ? null : displayedCount }));
|
|
972
982
|
};
|
|
@@ -1202,10 +1212,10 @@ const useDebounce = (value, delay = 500, direction, onBounce) => {
|
|
|
1202
1212
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1203
1213
|
useEffect(() => {
|
|
1204
1214
|
let handler;
|
|
1205
|
-
if ((direction === "in" && !debouncedValue && value) ||
|
|
1206
|
-
(direction === "out" && debouncedValue && !value) ||
|
|
1215
|
+
if ((direction === "in" && !Boolean(debouncedValue) && Boolean(value)) ||
|
|
1216
|
+
(direction === "out" && Boolean(debouncedValue) && !Boolean(value)) ||
|
|
1207
1217
|
direction === "both" ||
|
|
1208
|
-
|
|
1218
|
+
direction === undefined) {
|
|
1209
1219
|
handler = setTimeout(() => {
|
|
1210
1220
|
setDebouncedValue(value);
|
|
1211
1221
|
onBounce?.(value);
|
|
@@ -1426,7 +1436,7 @@ const useIsTextTruncated = (text) => {
|
|
|
1426
1436
|
}, [updateTextVisibility]);
|
|
1427
1437
|
// Re-check whenever text changes
|
|
1428
1438
|
useEffect(() => {
|
|
1429
|
-
if (
|
|
1439
|
+
if (text === undefined || text === "") {
|
|
1430
1440
|
return;
|
|
1431
1441
|
}
|
|
1432
1442
|
updateTextVisibility();
|
|
@@ -1586,7 +1596,13 @@ const useSelfUpdatingRef = (initialState) => {
|
|
|
1586
1596
|
* }
|
|
1587
1597
|
*/
|
|
1588
1598
|
const useViewportBreakpoints = () => {
|
|
1589
|
-
const [viewportSize, setViewportSize] = useState(() =>
|
|
1599
|
+
const [viewportSize, setViewportSize] = useState(() => {
|
|
1600
|
+
const newViewportSize = objectEntries(themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => ({
|
|
1601
|
+
...acc,
|
|
1602
|
+
[breakpointPropsMap[size]]: window.matchMedia(`(min-width: ${minWidth}px)`).matches,
|
|
1603
|
+
}), { ...defaultBreakpointState });
|
|
1604
|
+
return newViewportSize;
|
|
1605
|
+
});
|
|
1590
1606
|
const updateViewportSize = useCallback(() => {
|
|
1591
1607
|
const newViewportSize = objectEntries(themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => ({
|
|
1592
1608
|
...acc,
|
|
@@ -1626,7 +1642,11 @@ const useWatch = ({ value, onChange, immediate = false, isEqual }) => {
|
|
|
1626
1642
|
const prevValue = useRef(UNINITIALIZED);
|
|
1627
1643
|
useEffect(() => {
|
|
1628
1644
|
const prev = prevValue.current;
|
|
1629
|
-
const hasChanged = prev === UNINITIALIZED
|
|
1645
|
+
const hasChanged = prev === UNINITIALIZED
|
|
1646
|
+
? false
|
|
1647
|
+
: isEqual !== undefined
|
|
1648
|
+
? !isEqual(value, prev)
|
|
1649
|
+
: JSON.stringify(value) !== JSON.stringify(prev);
|
|
1630
1650
|
if (immediate && prev === UNINITIALIZED) {
|
|
1631
1651
|
onChange(value, null);
|
|
1632
1652
|
}
|
|
@@ -1886,7 +1906,7 @@ const Card = ({ children, onClick, fullHeight = false, onMouseEnter, onMouseLeav
|
|
|
1886
1906
|
* @param {CardBodyProps} props - The props for the CardBody component
|
|
1887
1907
|
* @returns {ReactElement} CardBody component
|
|
1888
1908
|
*/
|
|
1889
|
-
const CardBody = ({ density = "auto", children, dataTestId, className, direction, disableGap, id, }) => {
|
|
1909
|
+
const CardBody = ({ density = "auto", children, dataTestId, className, direction = "column", disableGap = false, id, }) => {
|
|
1890
1910
|
return (jsx("div", { className: cvaCardBodyDensityContainer$1({ density, disableGap, className, direction }), "data-testid": dataTestId, id: id, children: children }));
|
|
1891
1911
|
};
|
|
1892
1912
|
|
|
@@ -1898,7 +1918,7 @@ const CardBody = ({ density = "auto", children, dataTestId, className, direction
|
|
|
1898
1918
|
* @param {CardFooterProps} props - The props for the CardFooter component
|
|
1899
1919
|
* @returns {ReactElement} CardFooter component
|
|
1900
1920
|
*/
|
|
1901
|
-
const CardFooter = ({ dataTestId, className, children, density, hideSeparator = false }) => {
|
|
1921
|
+
const CardFooter = ({ dataTestId, className, children, density = "auto", hideSeparator = false, }) => {
|
|
1902
1922
|
return (jsx("div", { className: cvaCardFooterDensityContainer({
|
|
1903
1923
|
density,
|
|
1904
1924
|
border: hideSeparator ? "borderless" : "default",
|
|
@@ -1963,12 +1983,12 @@ const Heading = ({ variant = "primary", inverted = false, subtle = false, classN
|
|
|
1963
1983
|
* @param {CardHeaderProps} props - The props for the CardHeader component
|
|
1964
1984
|
* @returns {ReactElement} CardHeader component
|
|
1965
1985
|
*/
|
|
1966
|
-
const CardHeader = ({ heading, headingVariant = "secondary", subHeading, onClose, dataTestId, className, children, accessories, actions, density, hideSeparator = false, }) => {
|
|
1986
|
+
const CardHeader = ({ heading, headingVariant = "secondary", subHeading, onClose, dataTestId, className, children, accessories, actions, density = "auto", hideSeparator = false, }) => {
|
|
1967
1987
|
return (jsx("div", { className: cvaCardHeaderDensityContainer({
|
|
1968
1988
|
density,
|
|
1969
1989
|
border: hideSeparator ? "borderless" : "default",
|
|
1970
1990
|
className,
|
|
1971
|
-
}), "data-testid": dataTestId, children: jsxs("div", { className: cvaCardHeader(), children: [jsxs("div", { children: [jsxs("div", { className: cvaCardHeaderHeadingContainer(), children: [jsx(Heading, { className: "self-center", variant: headingVariant, children: heading }), accessories] }), subHeading ? (jsx(Heading, { subtle: true, variant: "subtitle", children: subHeading })) : null, children] }), jsxs("div", { className: "flex place-items-center gap-x-2 gap-y-1", children: [actions, onClose ? (jsx(IconButton, { className: "!h-min", dataTestId: "card-header-close-button", icon: jsx(Icon, { name: "XMark", size: "small" }), onClick: onClose, variant: "ghost-neutral" })) : null] })] }) }));
|
|
1991
|
+
}), "data-testid": dataTestId, children: jsxs("div", { className: cvaCardHeader(), children: [jsxs("div", { children: [jsxs("div", { className: cvaCardHeaderHeadingContainer(), children: [jsx(Heading, { className: "self-center", variant: headingVariant, children: heading }), accessories] }), subHeading !== null && subHeading !== undefined ? (jsx(Heading, { subtle: true, variant: "subtitle", children: subHeading })) : null, children] }), jsxs("div", { className: "flex place-items-center gap-x-2 gap-y-1", children: [actions, onClose ? (jsx(IconButton, { className: "!h-min", dataTestId: "card-header-close-button", icon: jsx(Icon, { name: "XMark", size: "small" }), onClick: onClose, variant: "ghost-neutral" })) : null] })] }) }));
|
|
1972
1992
|
};
|
|
1973
1993
|
|
|
1974
1994
|
const cvaCollapse = cvaMerge([
|
|
@@ -2054,9 +2074,9 @@ const Collapse = ({ id, initialExpanded = false, onToggle, label, children, clas
|
|
|
2054
2074
|
}
|
|
2055
2075
|
setExpanded(!expanded);
|
|
2056
2076
|
}, [expanded, onToggle]);
|
|
2057
|
-
return (jsxs("div", { className: cvaCollapse({ className }), "data-testid": dataTestId, children: [jsx("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, className: headerClassName }), onClick: handleClick, role: "button", children: jsxs("div", { className: cvaCollapseLabelContainer(), children: [jsx(Text, { id: LABEL_ID, type: "span", weight: "bold", children: label }), jsxs("div", { className: "flex items-center gap-2", children: [headerAddon ? headerAddon : null, jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronUp", size: "medium" })] })] }) }), jsx(Collapsible, { expanded: expanded, extraPadding: extraPadding, id: id, children: expanded || animate ? children : null })] }));
|
|
2077
|
+
return (jsxs("div", { className: cvaCollapse({ className }), "data-testid": dataTestId, children: [jsx("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, className: headerClassName }), onClick: handleClick, role: "button", children: jsxs("div", { className: cvaCollapseLabelContainer(), children: [jsx(Text, { id: LABEL_ID, type: "span", weight: "bold", children: label }), jsxs("div", { className: "flex items-center gap-2", children: [headerAddon !== null && headerAddon !== undefined ? headerAddon : null, jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronUp", size: "medium" })] })] }) }), jsx(Collapsible, { expanded: expanded, extraPadding: extraPadding, id: id, children: expanded || animate ? children : null })] }));
|
|
2058
2078
|
};
|
|
2059
|
-
const Collapsible = ({ children, expanded, id, extraPadding }) => {
|
|
2079
|
+
const Collapsible = ({ children, expanded, id, extraPadding = true }) => {
|
|
2060
2080
|
const ref = useRef(null);
|
|
2061
2081
|
const { height } = useGeometry(ref);
|
|
2062
2082
|
return (jsx("div", { className: cvaCollapseAnimated({ expanded }), id: id, style: { height: expanded ? height : "0" }, children: jsx("div", { ref: ref, children: jsx("div", { className: cvaCollapsible({ extraPadding }), children: children }) }) }));
|
|
@@ -2075,7 +2095,7 @@ const Collapsible = ({ children, expanded, id, extraPadding }) => {
|
|
|
2075
2095
|
* @param {boolean} props.warning - Indicates if the process has a warning.
|
|
2076
2096
|
* @param {boolean} props.success - Indicates if the process was successful.
|
|
2077
2097
|
*/
|
|
2078
|
-
const CompletionStatusIndicator = ({ loading, error, success, ...rest }) => {
|
|
2098
|
+
const CompletionStatusIndicator = ({ loading = false, error, success, ...rest }) => {
|
|
2079
2099
|
if (loading) {
|
|
2080
2100
|
return jsx(Spinner, { className: "h-[22px] w-[22px]", containerClassName: "w-min", ...rest });
|
|
2081
2101
|
}
|
|
@@ -2169,17 +2189,17 @@ const cvaSkeletonLine = cvaMerge([
|
|
|
2169
2189
|
/**
|
|
2170
2190
|
* Display placeholder lines before the data gets loaded to reduce load-time frustration.
|
|
2171
2191
|
*/
|
|
2172
|
-
const SkeletonLines = memo(({ margin = "10px 0", lines = 1, height, width = "100%", className, dataTestId }) => {
|
|
2192
|
+
const SkeletonLines = memo(({ margin = "10px 0", lines = 1, height, width = "100%", className, dataTestId, }) => {
|
|
2173
2193
|
const skeletonLines = [];
|
|
2174
2194
|
const getWidth = (index) => {
|
|
2175
|
-
if (width
|
|
2176
|
-
return width[index]
|
|
2195
|
+
if (Array.isArray(width)) {
|
|
2196
|
+
return width[index] ?? "100%";
|
|
2177
2197
|
}
|
|
2178
2198
|
return width;
|
|
2179
2199
|
};
|
|
2180
2200
|
const getHeight = (index) => {
|
|
2181
|
-
if (height
|
|
2182
|
-
return height[index]
|
|
2201
|
+
if (Array.isArray(height)) {
|
|
2202
|
+
return height[index] ?? "auto";
|
|
2183
2203
|
}
|
|
2184
2204
|
return height;
|
|
2185
2205
|
};
|
|
@@ -2263,7 +2283,7 @@ WorkerWithSignSVG.displayName = "WorkerWithSignSVG";
|
|
|
2263
2283
|
* - For guidance purposes (e.g., onboarding, adjusting filters, exploring alternative approaches).
|
|
2264
2284
|
* - In celebratory instances (e.g., no new notifications, services up to date).
|
|
2265
2285
|
*/
|
|
2266
|
-
const EmptyState = ({ description, altText, image = "SEARCH_DOCUMENT", customImageSrc, loading, dataTestId, className, primaryAction, secondaryAction, additionalHelpAction, }) => {
|
|
2286
|
+
const EmptyState = ({ description, altText, image = "SEARCH_DOCUMENT", customImageSrc, loading = false, dataTestId, className, primaryAction, secondaryAction, additionalHelpAction, }) => {
|
|
2267
2287
|
const ImageSource = useMemo(() => {
|
|
2268
2288
|
switch (image) {
|
|
2269
2289
|
case "WORKER_WITH_SIGN":
|
|
@@ -2281,7 +2301,7 @@ const EmptyState = ({ description, altText, image = "SEARCH_DOCUMENT", customIma
|
|
|
2281
2301
|
return SearchDocumentSVG;
|
|
2282
2302
|
}
|
|
2283
2303
|
}, [image]);
|
|
2284
|
-
return (jsx("div", { className: cvaContainerStyles({ className }), "data-testid": dataTestId ?? "empty-state", children: loading ? (jsxs(Fragment, { children: [jsx(Spinner, { centering: "centered", dataTestId: "spinner" }), jsx(SkeletonLines, { dataTestId: "skeleton-lines", width: 50 })] })) : (jsxs(Fragment, { children: [customImageSrc ? (typeof customImageSrc === "string" ? (jsx("img", { alt: altText, className: cvaImgStyles(), height: 200, src: customImageSrc, width: 200 })) : (customImageSrc)) : (typeof ImageSource !== "undefined" && (jsx(ImageSource, { "data-testid": "empty-state-image", height: 200, width: 200 }, image))), description ? (jsx(Text, { align: "center", size: "large", children: description })) : null, jsxs("div", { className: "mt-4 grid gap-3", children: [jsxs("div", { className: "flex gap-3", children: [secondaryAction ? (jsx(Button, { dataTestId: "empty-state-secondary-button", disabled: secondaryAction.disabled, onClick: secondaryAction.onClick, variant: "secondary", children: secondaryAction.to ? (jsx(Link, { params: secondaryAction.to.parameters, to: secondaryAction.to.pathname, children: secondaryAction.title })) : (secondaryAction.title) })) : null, primaryAction ? (jsx(Button, { dataTestId: "empty-state-primary-button", disabled: primaryAction.disabled, onClick: primaryAction.onClick, children: primaryAction.to ? (jsx(Link, { params: primaryAction.to.parameters, to: primaryAction.to.pathname, children: primaryAction.title })) : (primaryAction.title) })) : null] }), additionalHelpAction?.to ? (jsx(Button, { asChild: true, dataTestId: "empty-state-additional-button", disabled: additionalHelpAction.disabled, onClick: additionalHelpAction.onClick, suffix: jsx(Icon, { name: "ArrowTopRightOnSquare", size: "small" }), variant: "ghost", children: jsx(Link, { params: additionalHelpAction.to.parameters, target: additionalHelpAction.to.target, to: additionalHelpAction.to.pathname, children: additionalHelpAction.title }) })) : null] })] })) }));
|
|
2304
|
+
return (jsx("div", { className: cvaContainerStyles({ className }), "data-testid": dataTestId ?? "empty-state", children: loading ? (jsxs(Fragment, { children: [jsx(Spinner, { centering: "centered", dataTestId: "spinner" }), jsx(SkeletonLines, { dataTestId: "skeleton-lines", width: 50 })] })) : (jsxs(Fragment, { children: [customImageSrc !== null && customImageSrc !== undefined ? (typeof customImageSrc === "string" ? (jsx("img", { alt: altText, className: cvaImgStyles(), height: 200, src: customImageSrc, width: 200 })) : (customImageSrc)) : (typeof ImageSource !== "undefined" && (jsx(ImageSource, { "data-testid": "empty-state-image", height: 200, width: 200 }, image))), description !== undefined && description !== "" ? (jsx(Text, { align: "center", size: "large", children: description })) : null, jsxs("div", { className: "mt-4 grid gap-3", children: [jsxs("div", { className: "flex gap-3", children: [secondaryAction ? (jsx(Button, { dataTestId: "empty-state-secondary-button", disabled: secondaryAction.disabled, onClick: secondaryAction.onClick, variant: "secondary", children: secondaryAction.to ? (jsx(Link, { params: secondaryAction.to.parameters, to: secondaryAction.to.pathname, children: secondaryAction.title })) : (secondaryAction.title) })) : null, primaryAction ? (jsx(Button, { dataTestId: "empty-state-primary-button", disabled: primaryAction.disabled, onClick: primaryAction.onClick, children: primaryAction.to ? (jsx(Link, { params: primaryAction.to.parameters, to: primaryAction.to.pathname, children: primaryAction.title })) : (primaryAction.title) })) : null] }), additionalHelpAction?.to ? (jsx(Button, { asChild: true, dataTestId: "empty-state-additional-button", disabled: additionalHelpAction.disabled, onClick: additionalHelpAction.onClick, suffix: jsx(Icon, { name: "ArrowTopRightOnSquare", size: "small" }), variant: "ghost", children: jsx(Link, { params: additionalHelpAction.to.parameters, target: additionalHelpAction.to.target, to: additionalHelpAction.to.pathname, children: additionalHelpAction.title }) })) : null] })] })) }));
|
|
2285
2305
|
};
|
|
2286
2306
|
|
|
2287
2307
|
const cvaEmptyValue = cvaMerge(["text-neutral-400"]);
|
|
@@ -2632,7 +2652,7 @@ const cvaPopoverTitleText = cvaMerge(["flex-1", "text-neutral-500"]);
|
|
|
2632
2652
|
const PopoverContent = function PopoverContent({ className, dataTestId, children, portalId, ref: propRef, ...props }) {
|
|
2633
2653
|
const { context: floatingContext, customProps, ...context } = usePopoverContext();
|
|
2634
2654
|
const ref = useMergeRefs([context.refs.setFloating, propRef]);
|
|
2635
|
-
return (jsx(Portal, { id: portalId, children: context.isOpen ? (jsx(FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: true, modal: context.isModal, order: ["reference", "content"], returnFocus: true, children: jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className ?? customProps.className }), "data-testid": dataTestId ?? customProps.dataTestId ?? "popover-content", ref: ref, style: {
|
|
2655
|
+
return (jsx(Portal, { id: portalId, children: context.isOpen === true ? (jsx(FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: true, modal: context.isModal, order: ["reference", "content"], returnFocus: true, children: jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className ?? customProps.className }), "data-testid": dataTestId ?? customProps.dataTestId ?? "popover-content", ref: ref, style: {
|
|
2636
2656
|
position: context.strategy,
|
|
2637
2657
|
top: context.y,
|
|
2638
2658
|
left: context.x,
|
|
@@ -2647,7 +2667,7 @@ const PopoverContent = function PopoverContent({ className, dataTestId, children
|
|
|
2647
2667
|
* @param {PopoverTitleProps} props - The props for the PopoverTitle component
|
|
2648
2668
|
* @returns {ReactElement} PopoverTitle component
|
|
2649
2669
|
*/
|
|
2650
|
-
const PopoverTitle = ({ children, action, divider = false, className, dataTestId }) => {
|
|
2670
|
+
const PopoverTitle = ({ children, action, divider = false, className, dataTestId, }) => {
|
|
2651
2671
|
return (jsxs("div", { className: cvaPopoverTitleContainer({ divider, className }), "data-testid": dataTestId, children: [jsx(Text, { className: cvaPopoverTitleText(), size: "small", subtle: true, type: "div", uppercase: true, weight: "bold", children: children }), action] }));
|
|
2652
2672
|
};
|
|
2653
2673
|
|
|
@@ -2657,7 +2677,7 @@ const PopoverTitle = ({ children, action, divider = false, className, dataTestId
|
|
|
2657
2677
|
* @param {PopoverTriggerProps} props - The props for the PopoverTrigger component
|
|
2658
2678
|
* @returns {ReactElement} PopoverTrigger component
|
|
2659
2679
|
*/
|
|
2660
|
-
const PopoverTrigger = function PopoverTrigger({ children, renderButton, ref: propRef, ...props }) {
|
|
2680
|
+
const PopoverTrigger = function PopoverTrigger({ children, renderButton = false, ref: propRef, ...props }) {
|
|
2661
2681
|
const context = usePopoverContext();
|
|
2662
2682
|
const ref = useMergeRefs([context.refs.setReference, propRef]);
|
|
2663
2683
|
if (!renderButton && isValidElement(children)) {
|
|
@@ -2665,10 +2685,10 @@ const PopoverTrigger = function PopoverTrigger({ children, renderButton, ref: pr
|
|
|
2665
2685
|
ref,
|
|
2666
2686
|
...props,
|
|
2667
2687
|
...children.props,
|
|
2668
|
-
"data-state": context.isOpen ? "open" : "closed",
|
|
2688
|
+
"data-state": context.isOpen === true ? "open" : "closed",
|
|
2669
2689
|
}));
|
|
2670
2690
|
}
|
|
2671
|
-
return (jsx(Button, { "data-state": context.isOpen ? "open" : "closed", ref: ref, type: "button", ...context.getReferenceProps(props), children: children }));
|
|
2691
|
+
return (jsx(Button, { "data-state": context.isOpen === true ? "open" : "closed", ref: ref, type: "button", ...context.getReferenceProps(props), children: children }));
|
|
2672
2692
|
};
|
|
2673
2693
|
|
|
2674
2694
|
const cvaTooltipContainer = cvaMerge(["flex", "leading-5"]);
|
|
@@ -2744,7 +2764,7 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
|
|
|
2744
2764
|
* @param {TooltipProps} props - The props for the Tooltip component
|
|
2745
2765
|
* @returns {ReactElement} Tooltip component
|
|
2746
2766
|
*/
|
|
2747
|
-
const Tooltip = ({ children, dataTestId, disabled, className, label, placement = "auto", mode = "dark", iconProps, id, }) => {
|
|
2767
|
+
const Tooltip = ({ children, dataTestId, disabled = false, className, label, placement = "auto", mode = "dark", iconProps, id, }) => {
|
|
2748
2768
|
const [isOpen, setIsOpen] = useState(false);
|
|
2749
2769
|
const arrowRef = useRef(null);
|
|
2750
2770
|
const { refs, floatingStyles, context } = useFloating({
|
|
@@ -2764,7 +2784,7 @@ const Tooltip = ({ children, dataTestId, disabled, className, label, placement =
|
|
|
2764
2784
|
const { isMounted } = useTransitionStatus(context);
|
|
2765
2785
|
// Please don't try to move this into the component body directly
|
|
2766
2786
|
// I tried and it caused infinite re-renders some places (for whatever reason)
|
|
2767
|
-
const wrappedChildren = (jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children }));
|
|
2787
|
+
const wrappedChildren = useMemo(() => (jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children })), [children, className, dataTestId]);
|
|
2768
2788
|
const openTooltip = useCallback(() => {
|
|
2769
2789
|
if (disabled) {
|
|
2770
2790
|
return;
|
|
@@ -2910,8 +2930,8 @@ const cvaIndicatorIconBackground = cvaMerge(["rounded-full", "items-center", "ju
|
|
|
2910
2930
|
* @param {IndicatorProps} props - The props for the Indicator component
|
|
2911
2931
|
* @returns {ReactElement} Indicator component
|
|
2912
2932
|
*/
|
|
2913
|
-
const Indicator = ({ dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false, size, weight, className, ...rest }) => {
|
|
2914
|
-
return (jsx(Tooltip, { className: className, disabled: withLabel, label: label, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaIndicator(), "data-testid": dataTestId, ...rest, children: [jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping ? (jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })) : null, icon] }), label
|
|
2933
|
+
const Indicator = ({ dataTestId, icon, label, color = "unknown", withBackground = true, withLabel = true, ping = false, size = "medium", weight = "normal", className, ...rest }) => {
|
|
2934
|
+
return (jsx(Tooltip, { className: className, disabled: withLabel, label: label, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaIndicator(), "data-testid": dataTestId, ...rest, children: [jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping ? (jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })) : null, icon] }), label && withLabel ? (jsx("div", { className: cvaIndicatorLabel({ size, weight, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: label })) : null] }) }));
|
|
2915
2935
|
};
|
|
2916
2936
|
|
|
2917
2937
|
const cvaKPI = cvaMerge(["w-full", "px-4", "py-2", "flex", "flex-col"], {
|
|
@@ -2971,10 +2991,10 @@ const LoadingContent$1 = () => (jsx("div", { className: "flex h-11 flex-row item
|
|
|
2971
2991
|
* @param {KPIProps} props - The props for the KPI component
|
|
2972
2992
|
* @returns {ReactElement} KPI component
|
|
2973
2993
|
*/
|
|
2974
|
-
const KPI = ({ title, value, loading, unit, className, dataTestId, tooltipLabel, variant = "default", trend, ...rest }) => {
|
|
2994
|
+
const KPI = ({ title, value, loading = false, unit, className, dataTestId, tooltipLabel, variant = "default", trend, ...rest }) => {
|
|
2975
2995
|
const isSmallVariant = variant === "small";
|
|
2976
|
-
return (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, disabled:
|
|
2977
|
-
isDefaultAndHasTrendValue: Boolean(trend
|
|
2996
|
+
return (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, disabled: tooltipLabel === undefined || tooltipLabel === "", label: tooltipLabel, placement: "bottom", children: jsx("div", { className: cvaKPI({ variant, className }), "data-testid": dataTestId ? `${dataTestId}` : undefined, ...rest, children: loading ? (jsx(LoadingContent$1, {})) : (jsxs(Fragment, { children: [jsx("div", { className: cvaKPIHeader(), children: jsx(Text, { className: cvaKPITitleText(), dataTestId: dataTestId ? `${dataTestId}-title` : undefined, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }) }), jsx(Text, { className: cvaKPIvalueText({ variant }), dataTestId: dataTestId ? `${dataTestId}-value` : undefined, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: jsxs("div", { className: cvaKPIValueContainer({
|
|
2997
|
+
isDefaultAndHasTrendValue: Boolean(trend !== undefined && trend.value !== undefined && !isSmallVariant),
|
|
2978
2998
|
className,
|
|
2979
2999
|
}), children: [jsxs("span", { className: cvaKPIvalueText({ variant }), children: [value, " ", unit] }), jsx(TrendIndicator, { isSmallVariant: isSmallVariant, trend: trend, unit: unit })] }) })] })) }) }));
|
|
2980
3000
|
};
|
|
@@ -2982,7 +3002,7 @@ const TrendIndicator = ({ trend, unit, isSmallVariant }) => {
|
|
|
2982
3002
|
if (!trend) {
|
|
2983
3003
|
return null;
|
|
2984
3004
|
}
|
|
2985
|
-
return (jsxs("div", { className: "flex flex-row items-center gap-1", "data-testid": "trend-indicator", children: [!isSmallVariant && trend.value ? (jsxs(Text, { dataTestId: "trend-value", size: "small", weight: "normal", children: [trend.value, " ", unit] })) : null, trend.variant
|
|
3005
|
+
return (jsxs("div", { className: "flex flex-row items-center gap-1", "data-testid": "trend-indicator", children: [!isSmallVariant && trend.value !== undefined ? (jsxs(Text, { dataTestId: "trend-value", size: "small", weight: "normal", children: [trend.value, " ", unit] })) : null, trend.variant !== undefined && trend.variant.icon !== undefined ? (jsx(Icon, { color: trend.variant.color, name: trend.variant.icon, size: "small" })) : null, trend.percentage !== undefined ? (jsxs(Text, { className: cvaKPITrendPercentage({ color: trend.variant?.color }), size: "small", weight: "bold", children: [trend.percentage, "%"] })) : null] }));
|
|
2986
3006
|
};
|
|
2987
3007
|
|
|
2988
3008
|
const cvaKPICard = cvaMerge([
|
|
@@ -3027,14 +3047,14 @@ const cvaKPIIconContainer = cvaMerge(["flex", "items-center", "justify-center",
|
|
|
3027
3047
|
* @param {KPICardProps} props - The props for the KPICard component
|
|
3028
3048
|
* @returns {ReactElement} KPICard component
|
|
3029
3049
|
*/
|
|
3030
|
-
const KPICard = ({ isActive, onClick, className, dataTestId, children, iconName, iconColor, ...rest }) => {
|
|
3031
|
-
const isClickable = Boolean(onClick &&
|
|
3050
|
+
const KPICard = ({ isActive = false, onClick, className, dataTestId, children, iconName = undefined, iconColor = "info", loading = false, ...rest }) => {
|
|
3051
|
+
const isClickable = Boolean(onClick !== undefined && loading !== true);
|
|
3032
3052
|
return (jsx(Card, { className: cvaKPICard({
|
|
3033
3053
|
isClickable,
|
|
3034
3054
|
isActive,
|
|
3035
3055
|
minHeight: rest.trend ? "withTrends" : "default",
|
|
3036
3056
|
className,
|
|
3037
|
-
}), "data-testid": dataTestId ? dataTestId : undefined, onClick: onClick, children: jsxs(CardBody, { className: cvaCardBodyDensityContainer({ iconName: Boolean(iconName) }), density: "none", children: [jsx(KPI, { ...rest, className: twMerge(iconName ? "gap-2" : "", "p-0"), dataTestId: dataTestId ? `${dataTestId}-kpi` : undefined }), iconName ? (jsx("div", { className: cvaKPIIconContainer({ iconColor
|
|
3057
|
+
}), "data-testid": dataTestId ? dataTestId : undefined, onClick: onClick, children: jsxs(CardBody, { className: cvaCardBodyDensityContainer({ iconName: Boolean(iconName) }), density: "none", children: [jsx(KPI, { ...rest, className: twMerge(iconName ? "gap-2" : "", "p-0"), dataTestId: dataTestId ? `${dataTestId}-kpi` : undefined, loading: loading }), iconName ? (jsx("div", { className: cvaKPIIconContainer({ iconColor }), children: jsx(Icon, { name: iconName, size: "small", type: "solid" }) })) : null, children] }) }));
|
|
3038
3058
|
};
|
|
3039
3059
|
const cvaCardBodyDensityContainer = cvaMerge(["grid", "grid-cols-[1fr_auto]"], {
|
|
3040
3060
|
variants: {
|
|
@@ -3070,9 +3090,9 @@ const cvaInteractableItem = cvaMerge("", {
|
|
|
3070
3090
|
default: "cursor-default",
|
|
3071
3091
|
"not-allowed": "cursor-not-allowed",
|
|
3072
3092
|
},
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3093
|
+
selection: {
|
|
3094
|
+
selected: ["bg-primary-50", "hover:bg-primary-50", "focus-within:bg-primary-50"],
|
|
3095
|
+
unselected: "",
|
|
3076
3096
|
auto: [
|
|
3077
3097
|
"hover:bg-neutral-100",
|
|
3078
3098
|
"has-[:checked]:bg-primary-50",
|
|
@@ -3085,24 +3105,24 @@ const cvaInteractableItem = cvaMerge("", {
|
|
|
3085
3105
|
true: ["pointer-events-none", "!bg-neutral-100", "!cursor-not-allowed"],
|
|
3086
3106
|
false: "", // use compoundVariants instead
|
|
3087
3107
|
},
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3108
|
+
focus: {
|
|
3109
|
+
focused: ["bg-neutral-600/5"],
|
|
3110
|
+
unfocused: "",
|
|
3091
3111
|
auto: "[&:has(:focus-visible)]:outline-native",
|
|
3092
3112
|
},
|
|
3093
3113
|
},
|
|
3094
3114
|
compoundVariants: [
|
|
3095
3115
|
{
|
|
3096
3116
|
disabled: false,
|
|
3097
|
-
|
|
3117
|
+
selection: "unselected",
|
|
3098
3118
|
className: ["hover:bg-neutral-600/5", "focus-within:bg-neutral-600/5"],
|
|
3099
3119
|
},
|
|
3100
3120
|
],
|
|
3101
3121
|
defaultVariants: {
|
|
3102
3122
|
cursor: "auto",
|
|
3103
|
-
|
|
3123
|
+
selection: "auto",
|
|
3104
3124
|
disabled: false,
|
|
3105
|
-
|
|
3125
|
+
focus: "auto",
|
|
3106
3126
|
},
|
|
3107
3127
|
});
|
|
3108
3128
|
|
|
@@ -3139,7 +3159,7 @@ const ListItem = ({ className, dataTestId, onClick, details, title, description,
|
|
|
3139
3159
|
}), children: thumbnail })) : null, jsxs("div", { className: "grid-rows-min-fr grid items-center text-sm", children: [jsx("div", { className: "gap-responsive-space-sm flex w-full min-w-0 items-center text-sm", children: typeof title === "string" ? (jsx(Text, { className: "truncate", dataTestId: dataTestId ? `${dataTestId}-title` : undefined, weight: "bold", children: title })) : (cloneElement(title, {
|
|
3140
3160
|
className: twMerge(title.props.className, "neutral-900 text-sm font-medium truncate"),
|
|
3141
3161
|
dataTestId: !title.props.dataTestId && dataTestId ? `${dataTestId}-title` : undefined,
|
|
3142
|
-
})) }), description ? (jsx("div", { className: "gap-responsive-space-sm flex w-full min-w-0 items-center", children: typeof description === "string" ? (jsx(Text, { className: "truncate text-xs text-neutral-500", dataTestId: dataTestId ? `${dataTestId}-description` : undefined, weight: "bold", children: description })) : (cloneElement(description, {
|
|
3162
|
+
})) }), description !== undefined && description !== "" ? (jsx("div", { className: "gap-responsive-space-sm flex w-full min-w-0 items-center", children: typeof description === "string" ? (jsx(Text, { className: "truncate text-xs text-neutral-500", dataTestId: dataTestId ? `${dataTestId}-description` : undefined, weight: "bold", children: description })) : (cloneElement(description, {
|
|
3143
3163
|
className: twMerge(description.props.className, "text-neutral-500 text-xs font-medium truncate"),
|
|
3144
3164
|
dataTestId: !description.props.dataTestId && dataTestId ? `${dataTestId}-description` : undefined,
|
|
3145
3165
|
})) })) : null, meta ? (jsx("div", { className: "gap-responsive-space-sm flex w-full min-w-0 items-center pt-0.5", children: jsx(Text, { className: "truncate text-xs text-neutral-400", dataTestId: dataTestId ? `${dataTestId}-meta` : undefined, weight: "bold", children: meta }) })) : null] })] }), jsxs("div", { className: "flex items-center gap-0.5 pl-2", children: [details, onClick ? jsx(Icon, { color: "neutral", name: "ChevronRight", size: "medium" }) : null] })] }));
|
|
@@ -3181,7 +3201,12 @@ const MenuDivider = () => {
|
|
|
3181
3201
|
*/
|
|
3182
3202
|
const cvaMenuItem = (props) => {
|
|
3183
3203
|
const { selected, disabled, focused, className, variant, fieldSize } = props ?? {};
|
|
3184
|
-
return twMerge(cvaMenuItemStyle({ variant, selected, disabled, fieldSize }), cvaInteractableItem({
|
|
3204
|
+
return twMerge(cvaMenuItemStyle({ variant, selected, disabled, fieldSize }), cvaInteractableItem({
|
|
3205
|
+
selection: selected === true ? "selected" : "unselected",
|
|
3206
|
+
disabled,
|
|
3207
|
+
cursor: "pointer",
|
|
3208
|
+
focus: focused === true ? "focused" : "unfocused",
|
|
3209
|
+
}), className);
|
|
3185
3210
|
};
|
|
3186
3211
|
const cvaMenuItemStyle = cvaMerge(["py-2", "px-2", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded", "text-sm"], {
|
|
3187
3212
|
variants: {
|
|
@@ -3294,10 +3319,10 @@ const cvaMenuItemSuffix = cvaMerge(["text-secondary-400", "text-sm", "flex", "it
|
|
|
3294
3319
|
* @param {MenuItemProps} props - The props for the MenuItem component
|
|
3295
3320
|
* @returns {ReactElement} MenuItem component
|
|
3296
3321
|
*/
|
|
3297
|
-
const MenuItem = ({ className, dataTestId, label, children, selected, focused, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, optionLabelDescription, optionPrefix, fieldSize = "medium", variant = "primary", }) => {
|
|
3322
|
+
const MenuItem = ({ className, dataTestId, label, children, selected = false, focused = false, prefix, suffix, disabled = false, onClick, stopPropagation = true, id, tabIndex, optionLabelDescription, optionPrefix, fieldSize = "medium", variant = "primary", }) => {
|
|
3298
3323
|
/* Handle tab navigation */
|
|
3299
3324
|
const handleKeyDown = (e) => {
|
|
3300
|
-
if (e.key === "Enter" && onClick &&
|
|
3325
|
+
if (e.key === "Enter" && onClick !== undefined && disabled !== true) {
|
|
3301
3326
|
if (stopPropagation) {
|
|
3302
3327
|
e.stopPropagation();
|
|
3303
3328
|
}
|
|
@@ -3317,7 +3342,7 @@ const MenuItem = ({ className, dataTestId, label, children, selected, focused, p
|
|
|
3317
3342
|
e.stopPropagation();
|
|
3318
3343
|
}
|
|
3319
3344
|
onClick?.(e);
|
|
3320
|
-
}, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : (tabIndex ?? 0), children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : "menu-item-prefix", children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsxs("div", { className: cvaMenuItemLabel({ variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-label` : "menu-item-label", children: [optionPrefix ? optionPrefix : null, children ?? label, optionLabelDescription ? jsxs("span", { className: "text-secondary-400 ml-1", children: ["(", optionLabelDescription, ")"] }) : null] })), suffix ? (jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
|
|
3345
|
+
}, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : (tabIndex ?? 0), children: [prefix !== null && prefix !== undefined ? (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) : (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 !== "" ? (jsxs("span", { className: "text-secondary-400 ml-1", children: ["(", optionLabelDescription, ")"] })) : null] })), suffix !== null && suffix !== undefined ? (jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
|
|
3321
3346
|
};
|
|
3322
3347
|
|
|
3323
3348
|
/**
|
|
@@ -3335,16 +3360,13 @@ const MenuList = ({ dataTestId, className, children, withStickyHeader = false, i
|
|
|
3335
3360
|
const childrenArr = Children.toArray(children);
|
|
3336
3361
|
const [internalSelectedItems, setInternalSelectedItems] = useState(controlledSelectedItems ?? []);
|
|
3337
3362
|
const selectedItems = controlledSelectedItems ?? internalSelectedItems;
|
|
3338
|
-
const handleItemClick = useCallback((id
|
|
3339
|
-
if (disabled) {
|
|
3340
|
-
return;
|
|
3341
|
-
}
|
|
3363
|
+
const handleItemClick = useCallback((id) => {
|
|
3342
3364
|
const newSelectedItems = isMulti
|
|
3343
3365
|
? selectedItems.includes(id)
|
|
3344
3366
|
? selectedItems.filter(item => item !== id)
|
|
3345
3367
|
: [...selectedItems, id]
|
|
3346
3368
|
: [id];
|
|
3347
|
-
if (onSelectionChange) {
|
|
3369
|
+
if (onSelectionChange !== undefined) {
|
|
3348
3370
|
onSelectionChange(newSelectedItems);
|
|
3349
3371
|
}
|
|
3350
3372
|
else {
|
|
@@ -3353,13 +3375,15 @@ const MenuList = ({ dataTestId, className, children, withStickyHeader = false, i
|
|
|
3353
3375
|
}, [isMulti, selectedItems, onSelectionChange]);
|
|
3354
3376
|
return (jsx("div", { className: cvaMenuList({ stickyHeader: withStickyHeader, className }), "data-testid": dataTestId ? `${dataTestId}-menu-list` : "menu-list", onClick: args.onClick, role: "list", tabIndex: 0, children: childrenArr.map((menuItem, index) => {
|
|
3355
3377
|
if (isValidElement(menuItem)) {
|
|
3356
|
-
const isSelected = selectedItems.includes(menuItem.props.id ?? `${index}`) || menuItem.props.selected;
|
|
3378
|
+
const isSelected = (selectedItems.includes(menuItem.props.id ?? `${index}`) || menuItem.props.selected) ?? false;
|
|
3357
3379
|
return cloneElement(menuItem, {
|
|
3358
3380
|
...menuItem.props,
|
|
3359
3381
|
key: index,
|
|
3360
3382
|
onClick: (event) => {
|
|
3361
3383
|
menuItem.props.onClick?.(event);
|
|
3362
|
-
|
|
3384
|
+
if (menuItem.props.disabled !== true) {
|
|
3385
|
+
handleItemClick(menuItem.props.id ?? `${index}`);
|
|
3386
|
+
}
|
|
3363
3387
|
},
|
|
3364
3388
|
className: isMulti && isSelected
|
|
3365
3389
|
? cvaMenuListMultiSelect({ className: menuItem.props.className })
|
|
@@ -3441,7 +3465,7 @@ const cvaNoticeIcon = cvaMerge(["rounded-full", "items-center", "justify-center"
|
|
|
3441
3465
|
* @returns {ReactElement} Notice component
|
|
3442
3466
|
*/
|
|
3443
3467
|
const Notice = ({ dataTestId, icon, label, color = "neutral", withLabel = true, className, tooltipLabel = label, withTooltip = false, size = "medium", ...rest }) => {
|
|
3444
|
-
return (jsx(Tooltip, { className: className, disabled:
|
|
3468
|
+
return (jsx(Tooltip, { className: className, disabled: withTooltip === false, label: tooltipLabel, placement: "bottom", children: jsxs("div", { "aria-label": label, className: cvaNotice(), "data-testid": dataTestId, ...rest, children: [jsx("div", { className: cvaNoticeIcon({ color }), "data-testid": dataTestId ? `${dataTestId}-icon` : "notice-icon", children: icon }), label && withLabel ? (jsx("div", { className: cvaNoticeLabel({ color, size }), "data-testid": dataTestId ? `${dataTestId}-label` : "notice-label", children: label })) : null] }) }));
|
|
3445
3469
|
};
|
|
3446
3470
|
|
|
3447
3471
|
const cvaPage = cvaMerge(["grid", "h-full"], {
|
|
@@ -3474,7 +3498,7 @@ const cvaPageContent = cvaMerge(["overflow-auto", "page-content", "grid", "gap-r
|
|
|
3474
3498
|
* Renders the page component. Adds padding and layout to the page.
|
|
3475
3499
|
*/
|
|
3476
3500
|
const Page = ({ layout, className, children, dataTestId }) => {
|
|
3477
|
-
return (jsx("div", { className: cvaPage({ className, layout }), "data-testid": dataTestId
|
|
3501
|
+
return (jsx("div", { className: cvaPage({ className, layout }), "data-testid": dataTestId ? dataTestId : "page", children: children }));
|
|
3478
3502
|
};
|
|
3479
3503
|
|
|
3480
3504
|
/**
|
|
@@ -3489,17 +3513,30 @@ const PageContent = ({ className, children, dataTestId, layout }) => {
|
|
|
3489
3513
|
};
|
|
3490
3514
|
|
|
3491
3515
|
const LoadingContent = () => (jsx("div", { className: "flex flex-row items-center gap-3", "data-testid": "kpi-card-loading-content", children: jsx("div", { className: "w-full", children: jsx(SkeletonLines, { height: [16, 25], lines: 2, margin: "3px 0 0 0", width: [75, 50] }) }) }));
|
|
3516
|
+
/**
|
|
3517
|
+
* The PageHeaderKpiMetrics component is used to render the KPI metrics in the PageHeader component.
|
|
3518
|
+
*
|
|
3519
|
+
* @param {object} props - The props for the PageHeaderKpiMetrics component
|
|
3520
|
+
* @param {Array<PageHeaderKpiMetricsType>} props.kpiMetrics - The KPI metrics to render
|
|
3521
|
+
* @returns {ReactElement} PageHeaderKpiMetrics component
|
|
3522
|
+
*/
|
|
3492
3523
|
const PageHeaderKpiMetrics = ({ kpiMetrics }) => {
|
|
3493
3524
|
return (jsx("div", { className: "hidden items-center gap-4 md:flex", children: kpiMetrics
|
|
3494
|
-
.filter(kpi =>
|
|
3525
|
+
.filter(kpi => kpi.hidden === false || kpi.hidden === undefined)
|
|
3495
3526
|
.map((kpi, index) => {
|
|
3496
|
-
if (kpi.loading) {
|
|
3527
|
+
if (kpi.loading === true) {
|
|
3497
3528
|
return jsx(LoadingContent, {}, `${kpi}-${index}`);
|
|
3498
3529
|
}
|
|
3499
3530
|
return (jsxs("div", { className: "flex flex-col text-nowrap text-left", children: [jsx("span", { className: "text-xs text-slate-500", children: kpi.header }), jsxs("div", { className: "flex flex-row items-center gap-1", children: [jsx("span", { className: "text-lg font-medium text-slate-900", children: kpi.value }), kpi.unit ? jsx("span", { className: "text-xs text-slate-900", children: kpi.unit }) : null] })] }, `${kpi}-${index}`));
|
|
3500
3531
|
}) }));
|
|
3501
3532
|
};
|
|
3502
3533
|
|
|
3534
|
+
/**
|
|
3535
|
+
* The ActionRenderer component is used to render the action in the PageHeaderSecondaryActions component.
|
|
3536
|
+
*
|
|
3537
|
+
* @param {ActionRendererProps} props - The props for the ActionRenderer component
|
|
3538
|
+
* @returns {ReactElement} ActionRenderer component
|
|
3539
|
+
*/
|
|
3503
3540
|
function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
3504
3541
|
const { to, tooltipLabel, prefixIconName, disabled, actionText, actionCallback, dataTestId, target, variant } = action;
|
|
3505
3542
|
// This component handles all the "wrapping" logic for Link/Tooltip
|
|
@@ -3514,10 +3551,18 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
3514
3551
|
// Wrap `content` with Tooltip
|
|
3515
3552
|
const wrappedWithTooltip = tooltipLabel ? (jsx(Tooltip, { className: "block", label: tooltipLabel, children: content })) : (content);
|
|
3516
3553
|
// Finally, wrap with Link if `to` is provided
|
|
3517
|
-
return to ? (jsx(Link, { target: target, to: to, children: wrappedWithTooltip })) : (wrappedWithTooltip);
|
|
3554
|
+
return to !== undefined && to !== "" ? (jsx(Link, { target: target, to: to, children: wrappedWithTooltip })) : (wrappedWithTooltip);
|
|
3518
3555
|
}
|
|
3519
|
-
|
|
3520
|
-
|
|
3556
|
+
/**
|
|
3557
|
+
* The PageHeaderSecondaryActions component is used to render the secondary actions in the PageHeader component.
|
|
3558
|
+
*
|
|
3559
|
+
* @param {object} props - The props for the PageHeaderSecondaryActions component
|
|
3560
|
+
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
3561
|
+
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
3562
|
+
* @returns {ReactElement} PageHeaderSecondaryActions component
|
|
3563
|
+
*/
|
|
3564
|
+
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, }) => {
|
|
3565
|
+
const enabledActions = useMemo(() => actions.filter(action => action.hidden === false || action.hidden === undefined), [actions]);
|
|
3521
3566
|
// If we need to render a "More Menu" because we have too many actions:
|
|
3522
3567
|
if (enabledActions.length > 2 || (hasPrimaryAction && enabledActions.length > 1)) {
|
|
3523
3568
|
// Separate them into danger vs. other
|
|
@@ -3529,7 +3574,7 @@ const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction, }) => {
|
|
|
3529
3574
|
return [danger, [...others, action]];
|
|
3530
3575
|
}
|
|
3531
3576
|
}, [[], []]);
|
|
3532
|
-
return (jsx(MoreMenu, { dataTestId: "secondary-actions-more-menu", iconButtonProps: { size: "small", variant: "secondary" }, children: close => (jsxs(MenuList, { className: "min-w-[160px]", children: [otherActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`))), dangerActions.length ? jsx(MenuDivider, {}) : null, dangerActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`)))] })) }));
|
|
3577
|
+
return (jsx(MoreMenu, { dataTestId: "secondary-actions-more-menu", iconButtonProps: { size: "small", variant: "secondary" }, children: close => (jsxs(MenuList, { className: "min-w-[160px]", children: [otherActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`))), dangerActions.length > 0 ? jsx(MenuDivider, {}) : null, dangerActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`)))] })) }));
|
|
3533
3578
|
}
|
|
3534
3579
|
// Otherwise, render them inline as buttons
|
|
3535
3580
|
return (jsx("div", { className: "flex flex-row items-center gap-2", children: enabledActions
|
|
@@ -3556,6 +3601,14 @@ const cvaPageHeaderContainer = cvaMerge(["bg-white", "tu-page-header"], {
|
|
|
3556
3601
|
const cvaPageHeader = cvaMerge(["box-border", "py-4", "px-6", "flex", "items-center", "gap-y-1"]);
|
|
3557
3602
|
const cvaPageHeaderHeading = cvaMerge(["text-slate-900", "text-xl", "font-semibold", "truncate"]);
|
|
3558
3603
|
|
|
3604
|
+
/**
|
|
3605
|
+
* The PageHeaderTitle component is used to display the title of the page header.
|
|
3606
|
+
*
|
|
3607
|
+
* @param {object} props - The props for the PageHeaderTitle component
|
|
3608
|
+
* @param {string} props.title - The title of the page header
|
|
3609
|
+
* @param {string} [props.dataTestId] - The data test id of the page header title
|
|
3610
|
+
* @returns {ReactElement} PageHeaderTitle component
|
|
3611
|
+
*/
|
|
3559
3612
|
const PageHeaderTitle = ({ title, dataTestId }) => {
|
|
3560
3613
|
const { ref, isTextTruncated } = useIsTextTruncated();
|
|
3561
3614
|
return (jsx("div", { className: "flex flex-row items-center", children: jsx(Tooltip, { className: "grid min-w-16", disabled: !isTextTruncated, label: title, placement: "top", children: jsx("h1", { className: cvaPageHeaderHeading(), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, ref: ref, children: title }) }) }));
|
|
@@ -3571,21 +3624,21 @@ const PageHeaderTitle = ({ title, dataTestId }) => {
|
|
|
3571
3624
|
* @param {PageHeaderProps} props - The props for the PageHeader component
|
|
3572
3625
|
* @returns {ReactElement} PageHeader component
|
|
3573
3626
|
*/
|
|
3574
|
-
const PageHeader = ({ className, dataTestId, secondaryActions, showLoading, description, title, tagLabel, backTo, tagColor, tabsList, descriptionIcon, kpiMetrics, tagTooltipLabel, primaryAction, }) => {
|
|
3627
|
+
const PageHeader = ({ className, dataTestId, secondaryActions, showLoading = false, description, title, tagLabel, backTo, tagColor, tabsList, descriptionIcon = "QuestionMarkCircle", kpiMetrics, tagTooltipLabel, primaryAction, }) => {
|
|
3575
3628
|
const tagRenderer = useMemo(() => {
|
|
3576
|
-
if (
|
|
3629
|
+
if (tagLabel === undefined || tagLabel === "" || showLoading) {
|
|
3577
3630
|
return null;
|
|
3578
3631
|
}
|
|
3579
3632
|
// If the user passes a string, we render the string as a tag with props provided.
|
|
3580
|
-
return (jsx("div", { className: "ml-auto flex flex-row gap-2", children: jsx(Tooltip, { dataTestId: "page-header-tag-tooltip", disabled:
|
|
3633
|
+
return (jsx("div", { className: "ml-auto flex flex-row gap-2", children: jsx(Tooltip, { dataTestId: "page-header-tag-tooltip", disabled: tagTooltipLabel === undefined || tagTooltipLabel === "", label: tagTooltipLabel, placement: "top", children: jsx(Tag, { color: tagColor, dataTestId: "page-header-tag", children: tagLabel }) }) }));
|
|
3581
3634
|
}, [showLoading, tagColor, tagLabel, tagTooltipLabel]);
|
|
3582
3635
|
return (jsxs("div", { className: cvaPageHeaderContainer({
|
|
3583
3636
|
className,
|
|
3584
|
-
withBorder:
|
|
3585
|
-
}), "data-testid": dataTestId, children: [jsxs("div", { className: cvaPageHeader(), children: [backTo ? (jsx(Link, { to: backTo, children: jsx(Button, { className: "mr-4 bg-black/5 hover:bg-black/10", prefix: jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "medium", square: true, variant: "ghost-neutral" }) })) : undefined, typeof title === "string" ? jsx(PageHeaderTitle, { dataTestId: dataTestId, title: title }) : title, tagRenderer || description ? (jsxs("div", { className: "mx-2 flex items-center gap-2", children: [description && !showLoading ? (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-description-tooltip` : undefined, iconProps: {
|
|
3586
|
-
name: descriptionIcon
|
|
3637
|
+
withBorder: tabsList === undefined,
|
|
3638
|
+
}), "data-testid": dataTestId, children: [jsxs("div", { className: cvaPageHeader(), children: [backTo ? (jsx(Link, { to: backTo, children: jsx(Button, { className: "mr-4 bg-black/5 hover:bg-black/10", prefix: jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "medium", square: true, variant: "ghost-neutral" }) })) : undefined, typeof title === "string" ? jsx(PageHeaderTitle, { dataTestId: dataTestId, title: title }) : title, tagRenderer || (description !== null && description !== undefined) ? (jsxs("div", { className: "mx-2 flex items-center gap-2", children: [description !== null && description !== undefined && !showLoading ? (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-description-tooltip` : undefined, iconProps: {
|
|
3639
|
+
name: descriptionIcon,
|
|
3587
3640
|
dataTestId: "page-header-description-icon",
|
|
3588
|
-
}, label: description, placement: "bottom" })) : undefined, tagRenderer] })) : null, jsxs("div", { className: "ml-auto flex gap-2", children: [kpiMetrics ? jsx(PageHeaderKpiMetrics, { kpiMetrics: kpiMetrics }) : null, Array.isArray(secondaryActions) ? (jsx(PageHeaderSecondaryActions, { actions: secondaryActions, hasPrimaryAction: !!primaryAction })) : secondaryActions ? (secondaryActions) : null, primaryAction &&
|
|
3641
|
+
}, label: description, placement: "bottom" })) : undefined, tagRenderer] })) : null, jsxs("div", { className: "ml-auto flex gap-2", children: [kpiMetrics ? jsx(PageHeaderKpiMetrics, { kpiMetrics: kpiMetrics }) : null, Array.isArray(secondaryActions) ? (jsx(PageHeaderSecondaryActions, { actions: secondaryActions, hasPrimaryAction: !!primaryAction })) : secondaryActions !== null && secondaryActions !== undefined ? (secondaryActions) : null, primaryAction !== undefined && (primaryAction.hidden === false || primaryAction.hidden === undefined) ? (jsx(Tooltip, { disabled: primaryAction.tooltipLabel === undefined || primaryAction.tooltipLabel === "", label: primaryAction.tooltipLabel, children: jsx(Button, { dataTestId: primaryAction.dataTestId, disabled: primaryAction.disabled, loading: primaryAction.loading, onClick: () => primaryAction.actionCallback?.(), prefix: primaryAction.prefixIconName !== undefined ? (jsx(Icon, { name: primaryAction.prefixIconName, size: "small" })) : undefined, size: "medium", variant: primaryAction.variant, children: primaryAction.actionText }) })) : null] })] }), tabsList] }));
|
|
3589
3642
|
};
|
|
3590
3643
|
|
|
3591
3644
|
const cvaPagination = cvaMerge(["flex", "items-center", "gap-1"]);
|
|
@@ -3597,7 +3650,7 @@ const cvaPaginationText = cvaMerge("whitespace-nowrap");
|
|
|
3597
3650
|
* @param {PaginationProps} props - The props for the Pagination component
|
|
3598
3651
|
* @returns {ReactElement} Pagination component
|
|
3599
3652
|
*/
|
|
3600
|
-
const Pagination = ({ previousPage, nextPage, canPreviousPage, canNextPage, pageCount, pageIndex, loading, className, dataTestId, getTranslatedCount, onPageChange, cursorBase, }) => {
|
|
3653
|
+
const Pagination = ({ previousPage, nextPage, canPreviousPage = false, canNextPage = false, pageCount, pageIndex, loading = false, className, dataTestId, getTranslatedCount, onPageChange, cursorBase = false, }) => {
|
|
3601
3654
|
const [page, setPage] = useState(pageIndex);
|
|
3602
3655
|
const [currentPage, setCurrentPage] = useState(String(pageIndex !== undefined ? pageIndex + 1 : 1));
|
|
3603
3656
|
if (!loading && pageCount === undefined) {
|
|
@@ -3646,7 +3699,7 @@ const STROKE_WIDTH_THRESHOLD = 32;
|
|
|
3646
3699
|
* @param { PolygonProps} props - The props for the Polygon component
|
|
3647
3700
|
* @returns {ReactElement} Polygon component
|
|
3648
3701
|
*/
|
|
3649
|
-
const Polygon = ({ points, size, color = "black", opaque = true, className, dataTestId }) => {
|
|
3702
|
+
const Polygon = ({ points, size, color = "black", opaque = true, className, dataTestId, }) => {
|
|
3650
3703
|
// Calculate the bounds of the points
|
|
3651
3704
|
const minX = Math.min(...points.map(coord => coord[0]));
|
|
3652
3705
|
const maxX = Math.max(...points.map(coord => coord[0]));
|
|
@@ -3749,7 +3802,7 @@ const Spacer = ({ size = "medium", border = false, dataTestId, className }) => {
|
|
|
3749
3802
|
* @returns {ReactElement} SectionHeader component
|
|
3750
3803
|
*/
|
|
3751
3804
|
const SectionHeader = ({ title, subtitle, dataTestId, addons }) => {
|
|
3752
|
-
return (jsxs("div", { className: "flex flex-col", children: [jsx(HelmetProvider, { children: jsx(Helmet, { title: title }) }), jsxs("div", { className: "mb-2 flex flex-row gap-2", children: [jsxs("div", { className: "flex grow flex-col gap-2", children: [jsx(Heading, { dataTestId: dataTestId, variant: "secondary", children: title }), subtitle ? (jsx(Heading, { subtle: true, variant: "subtitle", children: subtitle })) : null] }), addons ? jsx("div", { className: "flex gap-2", children: addons }) : null] }), jsx(Spacer, { size: "small" })] }));
|
|
3805
|
+
return (jsxs("div", { className: "flex flex-col", children: [jsx(HelmetProvider, { children: jsx(Helmet, { title: title }) }), jsxs("div", { className: "mb-2 flex flex-row gap-2", children: [jsxs("div", { className: "flex grow flex-col gap-2", children: [jsx(Heading, { dataTestId: dataTestId, variant: "secondary", children: title }), subtitle ? (jsx(Heading, { subtle: true, variant: "subtitle", children: subtitle })) : null] }), addons !== null && addons !== undefined ? jsx("div", { className: "flex gap-2", children: addons }) : null] }), jsx(Spacer, { size: "small" })] }));
|
|
3753
3806
|
};
|
|
3754
3807
|
|
|
3755
3808
|
const cvaSidebar = cvaMerge(["apply", "grid", "grid-cols-fr-min", "items-center"]);
|
|
@@ -3783,7 +3836,7 @@ const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id"
|
|
|
3783
3836
|
entries.forEach(entry => {
|
|
3784
3837
|
// @ts-expect-error - suppressImplicitAnyIndexErrors
|
|
3785
3838
|
const targetElementId = entry.target[childUniqueIdentifierAttribute];
|
|
3786
|
-
if (targetElementId) {
|
|
3839
|
+
if (targetElementId !== null && targetElementId !== undefined) {
|
|
3787
3840
|
updatedEntries[targetElementId] = entry.isIntersecting ? false : true;
|
|
3788
3841
|
}
|
|
3789
3842
|
});
|
|
@@ -3839,19 +3892,19 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
|
|
|
3839
3892
|
});
|
|
3840
3893
|
const overflowItemCount = objectValues(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
|
|
3841
3894
|
const itemVisibilityClassName = (id) => {
|
|
3842
|
-
if (itemOverflowMap[id]) {
|
|
3895
|
+
if (itemOverflowMap[id] === true) {
|
|
3843
3896
|
return "invisible";
|
|
3844
3897
|
}
|
|
3845
3898
|
return "visible";
|
|
3846
3899
|
};
|
|
3847
|
-
return (jsxs("div", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [jsx("div", { className: cvaSidebarChildContainer({ breakpoint, className: childContainerClassName }), "data-testid":
|
|
3900
|
+
return (jsxs("div", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [jsx("div", { className: cvaSidebarChildContainer({ breakpoint, className: childContainerClassName }), "data-testid": `${dataTestId}-child-container`, ref: overflowContainerRef, children: Children.map(children, child => {
|
|
3848
3901
|
return cloneElement(child, {
|
|
3849
3902
|
className: twMerge(child.props.className, itemVisibilityClassName(child.props.id)),
|
|
3850
3903
|
});
|
|
3851
3904
|
}) }), overflowItemCount > 0 ? (jsx(MoreMenu, { iconButtonProps: {
|
|
3852
3905
|
variant: "ghost-neutral",
|
|
3853
|
-
}, ...moreMenuProps, className: moreMenuProps?.className, dataTestId:
|
|
3854
|
-
return itemOverflowMap[child.props.id]
|
|
3906
|
+
}, ...moreMenuProps, className: moreMenuProps?.className, dataTestId: `${dataTestId}-more-menu`, children: close => (jsx(MenuList, { ...menuListProps, dataTestId: dataTestId, children: Children.map(children, child => {
|
|
3907
|
+
return itemOverflowMap[child.props.id] === true
|
|
3855
3908
|
? cloneElement(child, {
|
|
3856
3909
|
onClick: () => {
|
|
3857
3910
|
child.props.onClick?.();
|
|
@@ -3914,8 +3967,8 @@ const cvaTab = cvaMerge([
|
|
|
3914
3967
|
* Wrapper for radix tab component.
|
|
3915
3968
|
* We add a custom implementation of the asChild prop to make it easy to make the child element look like other tabs.
|
|
3916
3969
|
*/
|
|
3917
|
-
const Tab = ({ value, isFullWidth = false, iconName, dataTestId, className, children, suffix, asChild, appendTabStylesToChildIfAsChild = true, ...rest }) => {
|
|
3918
|
-
const renderContent = () => (jsxs(Fragment, { children: [iconName ? jsx(Icon, { name: iconName, size: "small" }) : null, isValidElement(children) ? children.props.children : children, suffix] }));
|
|
3970
|
+
const Tab = ({ value, isFullWidth = false, iconName = undefined, dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ...rest }) => {
|
|
3971
|
+
const renderContent = () => (jsxs(Fragment, { children: [iconName !== undefined ? jsx(Icon, { name: iconName, size: "small" }) : null, isValidElement(children) ? children.props.children : children, suffix] }));
|
|
3919
3972
|
const commonProps = {
|
|
3920
3973
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
3921
3974
|
...rest,
|
|
@@ -4075,8 +4128,8 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
|
|
|
4075
4128
|
const containerPadding = 2; // p-0.5 = 2px
|
|
4076
4129
|
const gap = 4;
|
|
4077
4130
|
const slidingLeft = containerPadding +
|
|
4078
|
-
buttonRefs.current.slice(0, validIndex).reduce((sum, ref) => sum + (ref?.offsetWidth
|
|
4079
|
-
const slidingWidth = buttonRefs.current[validIndex]?.offsetWidth
|
|
4131
|
+
buttonRefs.current.slice(0, validIndex).reduce((sum, ref) => sum + (ref?.offsetWidth ?? 0) + gap, 0);
|
|
4132
|
+
const slidingWidth = buttonRefs.current[validIndex]?.offsetWidth ?? 0;
|
|
4080
4133
|
useEffect(() => {
|
|
4081
4134
|
setIsMounted(true);
|
|
4082
4135
|
}, []);
|
|
@@ -4096,7 +4149,7 @@ const ToggleItem = ({ title, onClick, disabled, isIconOnly, iconName, size, clas
|
|
|
4096
4149
|
className,
|
|
4097
4150
|
selected,
|
|
4098
4151
|
disabled,
|
|
4099
|
-
}), dataTestId: dataTestId, disabled: disabled, icon: iconName ? (jsx(Icon, { className: cvaToggleItemContent({ selected, disabled }), name: iconName, size: size === "large" ? "medium" : "small" })) : null, isIconOnly: isIconOnly, onClick: onClick, ref: ref, size: size, title: title }) })) : (jsx(Tooltip, { disabled: !tooltip?.content &&
|
|
4152
|
+
}), dataTestId: dataTestId, disabled: disabled, icon: iconName ? (jsx(Icon, { className: cvaToggleItemContent({ selected, disabled }), name: iconName, size: size === "large" ? "medium" : "small" })) : null, isIconOnly: isIconOnly, onClick: onClick, ref: ref, size: size, title: title }) })) : (jsx(Tooltip, { disabled: !tooltip?.content && text?.truncate === false, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(ToggleButton, { className: cvaToggleItem({
|
|
4100
4153
|
className,
|
|
4101
4154
|
selected,
|
|
4102
4155
|
disabled,
|
|
@@ -4162,7 +4215,7 @@ const cvaValueBarText = cvaMerge(["whitespace-nowrap"], {
|
|
|
4162
4215
|
*/
|
|
4163
4216
|
const getScore = (value, min, max, zeroScoreAllowed) => {
|
|
4164
4217
|
if (value <= min) {
|
|
4165
|
-
if (zeroScoreAllowed) {
|
|
4218
|
+
if (zeroScoreAllowed === true) {
|
|
4166
4219
|
return 0;
|
|
4167
4220
|
}
|
|
4168
4221
|
return 0.01; // always render at least some small fragment
|
|
@@ -4195,10 +4248,10 @@ const getDefaultFillColor = (score) => {
|
|
|
4195
4248
|
* @returns {string} color value
|
|
4196
4249
|
*/
|
|
4197
4250
|
const getFillColor = (score, levelColors) => {
|
|
4198
|
-
if (levelColors.low && score < (levelColors.low.level
|
|
4251
|
+
if (levelColors.low !== undefined && score < (levelColors.low.level !== undefined ? levelColors.low.level : 0)) {
|
|
4199
4252
|
return levelColors.low.color;
|
|
4200
4253
|
}
|
|
4201
|
-
if (levelColors.high && score >= (levelColors.high.level
|
|
4254
|
+
if (levelColors.high !== undefined && score >= (levelColors.high.level !== undefined ? levelColors.high.level : 0)) {
|
|
4202
4255
|
return levelColors.high.color;
|
|
4203
4256
|
}
|
|
4204
4257
|
return levelColors.medium?.color ?? color("WARNING", 300);
|
|
@@ -4223,7 +4276,7 @@ const getValueBarColorByValue = (value, min, max, levelColors) => {
|
|
|
4223
4276
|
* @param {ValueBarProps} props - The props for the ValueBar component
|
|
4224
4277
|
* @returns {ReactElement} ValueBar component
|
|
4225
4278
|
*/
|
|
4226
|
-
const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors, valueColor, showValue, className, dataTestId, zeroScoreAllowed, }) => {
|
|
4279
|
+
const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors, valueColor, showValue = false, className, dataTestId, zeroScoreAllowed = false, }) => {
|
|
4227
4280
|
const score = getScore(value, min, max, zeroScoreAllowed);
|
|
4228
4281
|
const barFillColor = levelColors ? getFillColor(score, levelColors) : getDefaultFillColor(score);
|
|
4229
4282
|
const valueText = `${Number(value.toFixed(1))}${nonNullable(unit) ? unit : ""}`;
|
|
@@ -4286,7 +4339,12 @@ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, classNam
|
|
|
4286
4339
|
return {
|
|
4287
4340
|
pagination: pagination || noPagination,
|
|
4288
4341
|
containerRef: { current: scrollParent },
|
|
4289
|
-
rowSize: pagination
|
|
4342
|
+
rowSize: pagination !== undefined &&
|
|
4343
|
+
pagination.pageInfo !== undefined &&
|
|
4344
|
+
pagination.pageInfo.hasNextPage === true &&
|
|
4345
|
+
pagination.isLoading === true
|
|
4346
|
+
? count + 1
|
|
4347
|
+
: count,
|
|
4290
4348
|
rowHeight,
|
|
4291
4349
|
};
|
|
4292
4350
|
}, [pagination, scrollParent, count, rowHeight]);
|
|
@@ -4305,9 +4363,9 @@ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, classNam
|
|
|
4305
4363
|
}, [scrollParent, fetchMoreOnBottomReached]);
|
|
4306
4364
|
return (jsx("div", { className: cvaVirtualizedListContainer({ parentControlledScrollable, className }), "data-testid": dataTestId, ref: containerRef, children: jsx("ul", { className: cvaVirtualizedList(), ref: listRef, style: { height: `${getTotalSize()}px`, outline: "none" }, children: getVirtualItems().map(virtualRow => {
|
|
4307
4365
|
const isLoaderRow = virtualRow.index > count - 1;
|
|
4308
|
-
return (jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
|
|
4366
|
+
return (jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick !== undefined ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
|
|
4309
4367
|
transform: `translateY(${virtualRow.start}px)`,
|
|
4310
|
-
}, tabIndex: -1, children: isLoaderRow ? (pagination?.isLoading ? (jsxs(Fragment, { children: [loadingIndicator === "spinner" && jsx(Spinner, { centering: "horizontally", containerClassName: "p-4" }), loadingIndicator === "skeletonLines" && (jsx(SkeletonLines, { height: skeletonLinesHeight, lines: 3, width: "full" }))] })) : null) : (children(virtualRow.index)) }, virtualRow.key));
|
|
4368
|
+
}, tabIndex: -1, children: isLoaderRow ? (pagination?.isLoading === true ? (jsxs(Fragment, { children: [loadingIndicator === "spinner" && jsx(Spinner, { centering: "horizontally", containerClassName: "p-4" }), loadingIndicator === "skeletonLines" && (jsx(SkeletonLines, { height: skeletonLinesHeight, lines: 3, width: "full" }))] })) : null) : (children(virtualRow.index)) }, virtualRow.key));
|
|
4311
4369
|
}) }) }));
|
|
4312
4370
|
};
|
|
4313
4371
|
|