@trackunit/react-components 1.0.12 → 1.1.0
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 +72 -84
- package/index.esm.js +81 -93
- package/package.json +2 -2
- package/src/components/Alert/Alert.d.ts +2 -2
- package/src/components/Card/Card.d.ts +6 -6
- 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 +5 -5
- package/src/components/Collapse/Collapse.d.ts +5 -5
- package/src/components/Heading/Heading.d.ts +2 -2
- package/src/components/Page/Page.d.ts +2 -2
- package/src/components/Page/PageContent.d.ts +3 -3
- package/src/components/PageHeader/PageHeader.d.ts +5 -5
- package/src/components/Popover/PopoverContent.d.ts +4 -4
- package/src/components/Popover/PopoverSizing.d.ts +1 -1
- package/src/components/Popover/PopoverTitle.d.ts +3 -3
- package/src/components/Sidebar/Sidebar.d.ts +4 -4
- package/src/components/Tag/Tag.d.ts +4 -4
- package/src/components/Text/Text.d.ts +7 -3
- package/src/components/Tooltip/Tooltip.d.ts +3 -3
- package/src/components/Widget/WidgetBody.d.ts +2 -2
- package/src/components/buttons/Button/Button.d.ts +6 -6
- package/src/components/buttons/IconButton/IconButton.d.ts +4 -4
- package/src/components/buttons/StarButton/StarButton.d.ts +2 -2
- package/src/hooks/useElevatedState.d.ts +2 -2
- package/src/test-utils/test-utils.d.ts +2 -2
package/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import
|
|
3
|
+
import { useRef, useMemo, useEffect, forwardRef, useState, createElement, useCallback, memo, createContext, useContext, isValidElement, cloneElement, Children } from 'react';
|
|
4
4
|
import { objectKeys, uuidv4, objectEntries, objectValues } from '@trackunit/shared-utils';
|
|
5
5
|
import { rentalStatusPalette, intentPalette, generalPalette, criticalityPalette, activityPalette, utilizationPalette, sitesPalette, themeScreenSizeAsNumber, color } from '@trackunit/ui-design-tokens';
|
|
6
6
|
import { iconNames } from '@trackunit/ui-icons';
|
|
@@ -253,7 +253,7 @@ const cvaTagIcon = cvaMerge(["cursor-pointer", "transition-opacity", "hover:opac
|
|
|
253
253
|
* @param {TagProps} props - The props for the tag component
|
|
254
254
|
* @returns {JSX.Element} tag component
|
|
255
255
|
*/
|
|
256
|
-
const Tag =
|
|
256
|
+
const Tag = forwardRef(({ className, dataTestId, children, size = "medium", onClose, color = "primary", disabled = false }, ref) => {
|
|
257
257
|
return (jsxs("span", { className: cvaTag({ className, size, color, layout: onClose ? "withIcon" : "default" }), "data-testid": dataTestId, ref: ref, children: [children, Boolean(onClose) && !disabled ? (
|
|
258
258
|
// a fix for multiselect deselecting tags working together with fade out animation
|
|
259
259
|
jsx("div", { className: cvaTagIconContainer(), onMouseDown: onClose, children: jsx(Icon, { className: cvaTagIcon(), dataTestId: dataTestId + "Icon", name: "XCircle", size: size, style: { WebkitTransition: "-webkit-transform 0.150s" }, type: "solid" }) })) : null] }));
|
|
@@ -264,7 +264,7 @@ Tag.displayName = "Tag";
|
|
|
264
264
|
* A component used to display the package name and version in the Storybook docs.
|
|
265
265
|
*/
|
|
266
266
|
const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
267
|
-
return (jsxs("div", { className: "flex gap-2", children: [jsx(Tag, { color: "secondary", children: packageJSON
|
|
267
|
+
return (jsxs("div", { className: "flex gap-2", children: [jsx(Tag, { color: "secondary", children: packageJSON?.name }), jsxs(Tag, { color: "secondary", children: ["v", packageJSON?.version] })] }));
|
|
268
268
|
};
|
|
269
269
|
|
|
270
270
|
/**
|
|
@@ -274,7 +274,6 @@ const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
|
274
274
|
* @returns {boolean} True if the text spans multiple lines
|
|
275
275
|
*/
|
|
276
276
|
const useIsTextWrapping = (ref) => {
|
|
277
|
-
var _a, _b;
|
|
278
277
|
const [isWrapping, setIsWrapping] = useState(false);
|
|
279
278
|
useEffect(() => {
|
|
280
279
|
if (!ref.current) {
|
|
@@ -282,7 +281,7 @@ const useIsTextWrapping = (ref) => {
|
|
|
282
281
|
return;
|
|
283
282
|
}
|
|
284
283
|
setIsWrapping(ref.current.clientHeight > ref.current.scrollHeight / 2);
|
|
285
|
-
}, [
|
|
284
|
+
}, [ref.current?.clientHeight, ref.current?.scrollHeight, ref]);
|
|
286
285
|
return isWrapping;
|
|
287
286
|
};
|
|
288
287
|
|
|
@@ -349,8 +348,8 @@ const cvaText = cvaMerge(["text-black", "m-0", "relative", "text-sm", "font-norm
|
|
|
349
348
|
* @param {TextProps} props - The props for the Text component
|
|
350
349
|
* @returns {JSX.Element} Text component
|
|
351
350
|
*/
|
|
352
|
-
const Text =
|
|
353
|
-
return
|
|
351
|
+
const Text = forwardRef(({ children, type = "p", size = "medium", align = "left", weight = "normal", underline = false, inverted = false, subtle = false, italicize = false, uppercase = false, disabled = false, className, dataTestId, ...rest }, ref) => {
|
|
352
|
+
return createElement(type, {
|
|
354
353
|
ref,
|
|
355
354
|
className: cvaText({
|
|
356
355
|
inverted,
|
|
@@ -680,7 +679,7 @@ const cvaIconButton = cvaMerge([], {
|
|
|
680
679
|
* @param {ButtonProps} props - The props for the Button component
|
|
681
680
|
* @returns {JSX.Element} Button component
|
|
682
681
|
*/
|
|
683
|
-
const Button =
|
|
682
|
+
const Button = forwardRef(({ onClick, children, loading, disabled, className, fullWidth = false, prefix, suffix, variant = "primary", type = "button", size = "medium", square = false, dataTestId, title, role, tabIndex, asChild = false, circular, ...rest }, ref) => {
|
|
684
683
|
const Comp = asChild ? Slot : "button";
|
|
685
684
|
const sharedCompProps = {
|
|
686
685
|
ref,
|
|
@@ -705,7 +704,7 @@ Button.displayName = "Button";
|
|
|
705
704
|
/**
|
|
706
705
|
* Buttons are clickable elements that are used to trigger actions. They communicate calls to action to the user and allow users to interact with pages in a variety of ways. The Icon Button is a version of the standard Button component without the text label.
|
|
707
706
|
*/
|
|
708
|
-
const IconButton =
|
|
707
|
+
const IconButton = forwardRef(({ icon, size = "medium", square = true, loading, disabled, className, ...rest }, ref) => {
|
|
709
708
|
return (jsx(Button, { className: cvaIconButton({ size: size, className }), disabled: disabled || loading, loading: loading,
|
|
710
709
|
// eslint-disable-next-line local-rules/design-guideline-button-icon-size-match
|
|
711
710
|
prefix: !loading ? icon : undefined, ref: ref, size: size, square: square, ...rest }));
|
|
@@ -755,14 +754,13 @@ const cvaAlertIconContainer = cvaMerge(["self-start", "shrink-0", "grid", "w-min
|
|
|
755
754
|
* @returns {JSX.Element} Alert component
|
|
756
755
|
*/
|
|
757
756
|
const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClose, dataTestId, autoScroll, }) => {
|
|
758
|
-
const ref =
|
|
759
|
-
const titleRef =
|
|
757
|
+
const ref = useRef(null);
|
|
758
|
+
const titleRef = useRef(null);
|
|
760
759
|
const isWrapping = useIsTextWrapping(titleRef);
|
|
761
|
-
|
|
762
|
-
var _a, _b;
|
|
760
|
+
useEffect(() => {
|
|
763
761
|
if (autoScroll) {
|
|
764
762
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
765
|
-
|
|
763
|
+
ref.current?.scrollIntoView?.();
|
|
766
764
|
}
|
|
767
765
|
}, [ref, autoScroll]);
|
|
768
766
|
return (jsxs("div", { className: cvaAlert({ color, className }), "data-testid": dataTestId, ref: ref, role: "alert", children: [jsxs("div", { className: cvaAlertContentContainer({ inline: !isWrapping && !children }), children: [jsx("div", { className: cvaAlertIconContainer(), 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 ? (jsx(Text, { type: typeof children === "string" || typeof children === "number" ? "p" : "span", weight: !title ? "bold" : "normal", children: children })) : null] }), onClose ? (jsx("div", { className: cvaAlertCloseButtonContainer(), children: jsx(IconButton, { circular: true, icon: jsx(Icon, { name: "XMark", size: "small" }), onClick: onClose, size: "small", title: "Close Alert", variant: "ghost-neutral" }) })) : null] }), primaryAction || secondaryAction ? (jsxs("div", { className: cvaAlertActionsContainer(), children: [secondaryAction ? (jsx(Button, { loading: secondaryAction.loading, onClick: secondaryAction.onClick, size: "small", variant: "ghost-neutral", children: secondaryAction.label })) : null, primaryAction ? (jsx(Button, { loading: primaryAction.loading, onClick: primaryAction.onClick, size: "small", variant: color === "danger" ? "primary-danger" : "primary", children: primaryAction.label })) : null] })) : null] }));
|
|
@@ -1028,7 +1026,7 @@ const useContinuousTimeout = ({ onTimeout, onMaxRetries, duration, maxRetries })
|
|
|
1028
1026
|
retries.current++;
|
|
1029
1027
|
}
|
|
1030
1028
|
else {
|
|
1031
|
-
onMaxRetries
|
|
1029
|
+
onMaxRetries?.();
|
|
1032
1030
|
retries.current = 0;
|
|
1033
1031
|
}
|
|
1034
1032
|
startTimeout(); // Restart the timeout if it's still running
|
|
@@ -1064,7 +1062,7 @@ const useDebounce = (value, delay = 500, direction, onBounce) => {
|
|
|
1064
1062
|
!direction) {
|
|
1065
1063
|
handler = setTimeout(() => {
|
|
1066
1064
|
setDebouncedValue(value);
|
|
1067
|
-
onBounce
|
|
1065
|
+
onBounce?.(value);
|
|
1068
1066
|
}, delay);
|
|
1069
1067
|
}
|
|
1070
1068
|
else {
|
|
@@ -1118,14 +1116,14 @@ function getDevicePixelRatio(options) {
|
|
|
1118
1116
|
|
|
1119
1117
|
/**
|
|
1120
1118
|
* Use this hook if you want to optionally elevate the state of a component.
|
|
1121
|
-
* Useful when you
|
|
1122
|
-
* from a parent
|
|
1119
|
+
* Useful when you _want_ to be able to control the state of a component
|
|
1120
|
+
* from a parent component but keep the simplicity of not _having_ to.
|
|
1123
1121
|
*
|
|
1124
1122
|
* If no custom state is provided, the fallback state will be used and it works like a normal useState hook.
|
|
1125
1123
|
*/
|
|
1126
1124
|
const useElevatedState = (initialState, customState) => {
|
|
1127
1125
|
const fallbackState = useState(initialState);
|
|
1128
|
-
return customState
|
|
1126
|
+
return customState ?? fallbackState;
|
|
1129
1127
|
};
|
|
1130
1128
|
|
|
1131
1129
|
/**
|
|
@@ -1233,7 +1231,6 @@ const useIsFullscreen = () => {
|
|
|
1233
1231
|
* @returns {boolean} True if the text is cut off.
|
|
1234
1232
|
*/
|
|
1235
1233
|
const useIsTextCutOff = (ref) => {
|
|
1236
|
-
var _a, _b;
|
|
1237
1234
|
const [isTextCutOff, setIsTextCutOff] = useState(false);
|
|
1238
1235
|
useEffect(() => {
|
|
1239
1236
|
if (!ref.current) {
|
|
@@ -1241,7 +1238,7 @@ const useIsTextCutOff = (ref) => {
|
|
|
1241
1238
|
return;
|
|
1242
1239
|
}
|
|
1243
1240
|
setIsTextCutOff(ref.current.offsetWidth < ref.current.scrollWidth);
|
|
1244
|
-
}, [
|
|
1241
|
+
}, [ref.current?.offsetWidth, ref.current?.scrollWidth, ref]);
|
|
1245
1242
|
return isTextCutOff;
|
|
1246
1243
|
};
|
|
1247
1244
|
|
|
@@ -1404,11 +1401,11 @@ const useWindowActivity = ({ onFocus, onBlur } = { onBlur: undefined, onFocus: u
|
|
|
1404
1401
|
const [focused, setFocused] = useState(hasFocus());
|
|
1405
1402
|
const onFocusInternal = useCallback(() => {
|
|
1406
1403
|
setFocused(hasFocus());
|
|
1407
|
-
onFocus
|
|
1404
|
+
onFocus?.();
|
|
1408
1405
|
}, [onFocus]);
|
|
1409
1406
|
const onBlurInternal = useCallback(() => {
|
|
1410
1407
|
setFocused(hasFocus());
|
|
1411
|
-
onBlur
|
|
1408
|
+
onBlur?.();
|
|
1412
1409
|
}, [onBlur]);
|
|
1413
1410
|
useEffect(() => {
|
|
1414
1411
|
setFocused(hasFocus()); // Focus for additional renders
|
|
@@ -1454,8 +1451,8 @@ const BreadcrumbForLargeScreen = ({ dataTestId, breadcrumbItems }) => {
|
|
|
1454
1451
|
* BreadcrumbForMediumScreen is a helper component that renders the breadcrumb items for medium screens.
|
|
1455
1452
|
*/
|
|
1456
1453
|
const BreadcrumbForMediumScreen = ({ dataTestId, breadcrumbItems }) => {
|
|
1457
|
-
const [expanded, setExpanded] =
|
|
1458
|
-
const getReducedArray =
|
|
1454
|
+
const [expanded, setExpanded] = useState(false);
|
|
1455
|
+
const getReducedArray = useCallback(() => {
|
|
1459
1456
|
let reducedArrayElements = [];
|
|
1460
1457
|
const collapsibleButton = (jsxs("div", { className: cvaBreadcrumbItem(), children: [jsx(IconButton, { dataTestId: `collapsibleButton-${dataTestId}`, icon: jsx(Icon, { name: "EllipsisHorizontal", size: "small" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsx(Icon, { color: "secondary", name: "Slash", size: "small" })] }));
|
|
1461
1458
|
const firstBreadcrumbItem = breadcrumbItems[0];
|
|
@@ -1706,7 +1703,7 @@ const Heading = ({ variant = "primary", inverted = false, subtle = false, classN
|
|
|
1706
1703
|
tertiary: "h3",
|
|
1707
1704
|
subtitle: "h4",
|
|
1708
1705
|
};
|
|
1709
|
-
return
|
|
1706
|
+
return createElement(semanticType[variant], {
|
|
1710
1707
|
...rest,
|
|
1711
1708
|
className: cvaHeading({ subtle, inverted, size: variant, className }),
|
|
1712
1709
|
"data-testid": dataTestId,
|
|
@@ -1803,8 +1800,8 @@ const cvaChevronIcon = cvaMerge(["transition-transform"], {
|
|
|
1803
1800
|
*/
|
|
1804
1801
|
const Collapse = ({ id, initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, animate = true, extraPadding = true, }) => {
|
|
1805
1802
|
const LABEL_ID = uuidv4();
|
|
1806
|
-
const [expanded, setExpanded] =
|
|
1807
|
-
const handleClick =
|
|
1803
|
+
const [expanded, setExpanded] = useState(initialExpanded);
|
|
1804
|
+
const handleClick = useCallback((e) => {
|
|
1808
1805
|
if (onToggle) {
|
|
1809
1806
|
onToggle(e, !expanded);
|
|
1810
1807
|
}
|
|
@@ -1876,8 +1873,7 @@ const cvaCopyableText = cvaMerge([
|
|
|
1876
1873
|
* @returns {JSX.Element} CopyableText component
|
|
1877
1874
|
*/
|
|
1878
1875
|
const CopyableText = ({ text, alternativeText, dataTestId, className }) => {
|
|
1879
|
-
|
|
1880
|
-
const value = (_a = alternativeText !== null && alternativeText !== void 0 ? alternativeText : text) !== null && _a !== void 0 ? _a : "";
|
|
1876
|
+
const value = alternativeText ?? text ?? "";
|
|
1881
1877
|
const [animating, setAnimating] = useState(false);
|
|
1882
1878
|
const [, copyToClipboard] = useCopyToClipboard();
|
|
1883
1879
|
const handleOnClick = () => {
|
|
@@ -3251,7 +3247,6 @@ var ForwardRef = /*#__PURE__*/forwardRef(SvgWorkerWithSign);
|
|
|
3251
3247
|
* - In celebratory instances (e.g., no new notifications, services up to date).
|
|
3252
3248
|
*/
|
|
3253
3249
|
const EmptyState = ({ description, altText, image = "SEARCH_DOCUMENT", customImageSrc, loading, dataTestId, className, primaryAction, secondaryAction, additionalHelpAction, }) => {
|
|
3254
|
-
var _a, _b, _c;
|
|
3255
3250
|
const ImageSource = useMemo(() => {
|
|
3256
3251
|
switch (image) {
|
|
3257
3252
|
case "WORKER_WITH_SIGN":
|
|
@@ -3269,7 +3264,7 @@ const EmptyState = ({ description, altText, image = "SEARCH_DOCUMENT", customIma
|
|
|
3269
3264
|
return ForwardRef$2;
|
|
3270
3265
|
}
|
|
3271
3266
|
}, [image]);
|
|
3272
|
-
return (jsx("div", { className: cvaContainerStyles({ className }), "data-testid": dataTestId
|
|
3267
|
+
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 ? (jsx("img", { alt: altText, className: cvaImgStyles(), height: 200, src: customImageSrc, width: 200 })) : (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: "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 ? (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] })] })) }));
|
|
3273
3268
|
};
|
|
3274
3269
|
|
|
3275
3270
|
const cvaEmptyValue = cvaMerge(["text-gray-400"]);
|
|
@@ -3296,7 +3291,7 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
|
|
|
3296
3291
|
return (jsx("a", { className: cvaExternalLink({ className }), "data-testid": dataTestId, href: href, onClick: onClick, rel: rel, target: target, title: title, children: children }));
|
|
3297
3292
|
};
|
|
3298
3293
|
|
|
3299
|
-
const PADDING
|
|
3294
|
+
const PADDING = 12;
|
|
3300
3295
|
/**
|
|
3301
3296
|
* Converts a width size value into a CSS dimension value for max constraints
|
|
3302
3297
|
*
|
|
@@ -3312,7 +3307,7 @@ const getMaxWidthValue = ({ value, referenceWidth, availableWidth }) => {
|
|
|
3312
3307
|
}
|
|
3313
3308
|
case undefined:
|
|
3314
3309
|
case "none": {
|
|
3315
|
-
return `${availableWidth - PADDING
|
|
3310
|
+
return `${availableWidth - PADDING * 2}px`;
|
|
3316
3311
|
}
|
|
3317
3312
|
default: {
|
|
3318
3313
|
if (typeof value === "number") {
|
|
@@ -3357,7 +3352,7 @@ const getMaxHeightValue = ({ value, availableHeight }) => {
|
|
|
3357
3352
|
switch (value) {
|
|
3358
3353
|
case undefined:
|
|
3359
3354
|
case "none": {
|
|
3360
|
-
return `${availableHeight - PADDING
|
|
3355
|
+
return `${availableHeight - PADDING * 2}px`;
|
|
3361
3356
|
}
|
|
3362
3357
|
default: {
|
|
3363
3358
|
if (typeof value === "number") {
|
|
@@ -3389,7 +3384,6 @@ const getMinHeightValue = ({ value }) => {
|
|
|
3389
3384
|
};
|
|
3390
3385
|
|
|
3391
3386
|
const DEFAULT_ACTIVATION = { click: true, hover: false, keyboardHandlers: true };
|
|
3392
|
-
const PADDING = 16;
|
|
3393
3387
|
const DEFAULT_DISMISSAL = {
|
|
3394
3388
|
enabled: true,
|
|
3395
3389
|
outsidePress: true,
|
|
@@ -3412,13 +3406,13 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
|
|
|
3412
3406
|
const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(initialOpen);
|
|
3413
3407
|
const [labelId, setLabelId] = useState();
|
|
3414
3408
|
const [descriptionId, setDescriptionId] = useState();
|
|
3415
|
-
const isOpen = controlledIsOpen
|
|
3409
|
+
const isOpen = controlledIsOpen ?? uncontrolledIsOpen;
|
|
3416
3410
|
const popoverData = useFloating({
|
|
3417
3411
|
placement,
|
|
3418
3412
|
open: isOpen,
|
|
3419
3413
|
onOpenChange: open => {
|
|
3420
3414
|
setUncontrolledIsOpen(open);
|
|
3421
|
-
onOpenStateChange
|
|
3415
|
+
onOpenStateChange?.(open);
|
|
3422
3416
|
},
|
|
3423
3417
|
whileElementsMounted: autoUpdate,
|
|
3424
3418
|
middleware: [
|
|
@@ -3548,8 +3542,7 @@ const getDefaultPortalContainer = () => {
|
|
|
3548
3542
|
* alongside other portalled elements.
|
|
3549
3543
|
*/
|
|
3550
3544
|
const Portal = (props) => {
|
|
3551
|
-
|
|
3552
|
-
return jsx(FloatingPortal, { ...props, root: (_a = props.root) !== null && _a !== void 0 ? _a : getDefaultPortalContainer() });
|
|
3545
|
+
return jsx(FloatingPortal, { ...props, root: props.root ?? getDefaultPortalContainer() });
|
|
3553
3546
|
};
|
|
3554
3547
|
|
|
3555
3548
|
const cvaPopoverContainer = cvaMerge(["component-popover-border", "z-popover", "animate-fade-in-fast"]);
|
|
@@ -3563,11 +3556,10 @@ const cvaPopoverTitleContainer = cvaMerge(["flex", "items-center", "px-2", "py-1
|
|
|
3563
3556
|
});
|
|
3564
3557
|
const cvaPopoverTitleText = cvaMerge(["flex-1", "text-neutral-500"]);
|
|
3565
3558
|
|
|
3566
|
-
const PopoverContent =
|
|
3567
|
-
var _a;
|
|
3559
|
+
const PopoverContent = forwardRef(function PopoverContent({ className, dataTestId, children, portalId, ...props }, propRef) {
|
|
3568
3560
|
const { context: floatingContext, customProps, ...context } = usePopoverContext();
|
|
3569
3561
|
const ref = useMergeRefs([context.refs.setFloating, propRef]);
|
|
3570
|
-
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
|
|
3562
|
+
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: {
|
|
3571
3563
|
position: context.strategy,
|
|
3572
3564
|
top: context.y,
|
|
3573
3565
|
left: context.x,
|
|
@@ -3678,8 +3670,8 @@ const FloatingArrowContainer = ({ arrowRef, mode = "dark", }) => {
|
|
|
3678
3670
|
* @returns {JSX.Element} Tooltip component
|
|
3679
3671
|
*/
|
|
3680
3672
|
const Tooltip = ({ children, dataTestId = "tool-tip", disabled, className, label, placement = "auto", mode = "dark", iconProps, id, }) => {
|
|
3681
|
-
const [isOpen, setIsOpen] =
|
|
3682
|
-
const arrowRef =
|
|
3673
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
3674
|
+
const arrowRef = useRef(null);
|
|
3683
3675
|
const { refs, floatingStyles, context } = useFloating({
|
|
3684
3676
|
placement: placement === "auto" ? "bottom" : placement,
|
|
3685
3677
|
open: isOpen,
|
|
@@ -3691,13 +3683,13 @@ const Tooltip = ({ children, dataTestId = "tool-tip", disabled, className, label
|
|
|
3691
3683
|
// Please don't try to move this into the component body directly
|
|
3692
3684
|
// I tried and it caused infinite re-renders some places (for whatever reason)
|
|
3693
3685
|
const wrappedChildren = (jsx("div", { className: cvaTooltipContainer({ className }), "data-testid": dataTestId ? `${dataTestId}-parent` : undefined, children: children }));
|
|
3694
|
-
const openTooltip =
|
|
3686
|
+
const openTooltip = useCallback(() => {
|
|
3695
3687
|
if (disabled) {
|
|
3696
3688
|
return;
|
|
3697
3689
|
}
|
|
3698
3690
|
setIsOpen(true);
|
|
3699
3691
|
}, [disabled]);
|
|
3700
|
-
const closeTooltip =
|
|
3692
|
+
const closeTooltip = useCallback(() => {
|
|
3701
3693
|
if (disabled) {
|
|
3702
3694
|
return;
|
|
3703
3695
|
}
|
|
@@ -3886,15 +3878,14 @@ const KPICard = ({ asChild = false, title, value, loading, unit, className, data
|
|
|
3886
3878
|
const Comp = asChild ? Slot : "div";
|
|
3887
3879
|
const isSmallVariant = variant === "small";
|
|
3888
3880
|
return (jsxs(Comp, { className: cvaKPICardContainer({ className, isClickable: Boolean(asChild || onClick) }), "data-testid": `${dataTestId}-comp`, onClick: onClick, ...rest, children: [jsx(Tooltip, { className: "w-full", disabled: !tooltipLabel, label: tooltipLabel, placement: "bottom", children: jsx(Card, { className: cvaKPICard({ isClickable: Boolean((onClick || asChild) && !loading), isActive, variant }), children: loading ? (jsx(LoadingContent, {})) : (jsxs("div", { children: [jsx(Text, { dataTestId: `${dataTestId}-title`, size: isSmallVariant ? "small" : "medium", subtle: true, weight: isSmallVariant ? "normal" : "bold", children: title }), jsx(Text, { className: isSmallVariant ? "mt-0.5" : "", dataTestId: `${dataTestId}-value`, size: isSmallVariant ? "small" : "large", type: "div", weight: isSmallVariant ? "bold" : "thick", children: jsxs("div", { className: cvaKPICardValueContainer({
|
|
3889
|
-
isDefaultAndHasTrendValue: Boolean(
|
|
3881
|
+
isDefaultAndHasTrendValue: Boolean(trend?.value && !isSmallVariant),
|
|
3890
3882
|
}), children: [jsxs("span", { children: [value, " ", unit] }), jsx(TrendIndicator, { isSmallVariant: isSmallVariant, trend: trend, unit: unit })] }) })] })) }) }), !loading && jsx(Slottable, { children: rest.children })] }));
|
|
3891
3883
|
};
|
|
3892
3884
|
const TrendIndicator = ({ trend, unit, isSmallVariant }) => {
|
|
3893
|
-
var _a, _b;
|
|
3894
3885
|
if (!trend) {
|
|
3895
3886
|
return null;
|
|
3896
3887
|
}
|
|
3897
|
-
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,
|
|
3888
|
+
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?.icon ? jsx(Icon, { color: trend.variant.color, name: trend.variant.icon, size: "small" }) : null, trend.percentage ? (jsxs(Text, { className: cvaKPICardTrendPercentage({ color: trend.variant?.color }), size: "small", weight: "bold", children: [trend.percentage, "%"] })) : null] }));
|
|
3898
3889
|
};
|
|
3899
3890
|
|
|
3900
3891
|
const cvaMenuList = cvaMerge([
|
|
@@ -3918,7 +3909,7 @@ const cvaMenuList = cvaMerge([
|
|
|
3918
3909
|
});
|
|
3919
3910
|
const cvaMenuListDivider = cvaMerge(["mx-[-4px]", "my-1", "min-h-px", "bg-slate-300"]);
|
|
3920
3911
|
const cvaMenuListMultiSelect = cvaMerge("hover:!bg-blue-200");
|
|
3921
|
-
const cvaMenuListItem = cvaMerge("max-w-
|
|
3912
|
+
const cvaMenuListItem = cvaMerge("max-w-full");
|
|
3922
3913
|
|
|
3923
3914
|
/**
|
|
3924
3915
|
* The MenuDivider component is used to separate items in a menu list.
|
|
@@ -3984,7 +3975,7 @@ const cvaInteractableItem = cvaMerge("", {
|
|
|
3984
3975
|
* The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
|
|
3985
3976
|
*/
|
|
3986
3977
|
const cvaMenuItem = (props) => {
|
|
3987
|
-
const { selected, disabled, focused, className, variant } = props
|
|
3978
|
+
const { selected, disabled, focused, className, variant } = props ?? {};
|
|
3988
3979
|
return twMerge(cvaMenuItemStyle({ variant, selected, disabled }), cvaInteractableItem({ selected, disabled, cursor: "pointer", focused }), className);
|
|
3989
3980
|
};
|
|
3990
3981
|
const cvaMenuItemStyle = cvaMerge(["py-2", "px-2", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded", "text-sm"], {
|
|
@@ -4101,8 +4092,8 @@ const MenuItem = ({ className, dataTestId, label, children, selected, prefix, su
|
|
|
4101
4092
|
variant,
|
|
4102
4093
|
}), "data-testid": dataTestId ? `${dataTestId}-menu-item` : "menu-item", id: id, onClick: e => {
|
|
4103
4094
|
stopPropagation && e.stopPropagation();
|
|
4104
|
-
onClick
|
|
4105
|
-
}, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : tabIndex
|
|
4095
|
+
onClick?.(e);
|
|
4096
|
+
}, 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: [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] }));
|
|
4106
4097
|
};
|
|
4107
4098
|
|
|
4108
4099
|
/**
|
|
@@ -4118,8 +4109,8 @@ const MenuItem = ({ className, dataTestId, label, children, selected, prefix, su
|
|
|
4118
4109
|
*/
|
|
4119
4110
|
const MenuList = ({ dataTestId, className, children, withStickyHeader = false, isMulti = false, selectedItems: controlledSelectedItems, onSelectionChange, ...args }) => {
|
|
4120
4111
|
const childrenArr = Children.toArray(children);
|
|
4121
|
-
const [internalSelectedItems, setInternalSelectedItems] = useState(controlledSelectedItems
|
|
4122
|
-
const selectedItems = controlledSelectedItems
|
|
4112
|
+
const [internalSelectedItems, setInternalSelectedItems] = useState(controlledSelectedItems ?? []);
|
|
4113
|
+
const selectedItems = controlledSelectedItems ?? internalSelectedItems;
|
|
4123
4114
|
const handleItemClick = useCallback((id, disabled) => {
|
|
4124
4115
|
if (disabled) {
|
|
4125
4116
|
return;
|
|
@@ -4137,22 +4128,22 @@ const MenuList = ({ dataTestId, className, children, withStickyHeader = false, i
|
|
|
4137
4128
|
}
|
|
4138
4129
|
}, [isMulti, selectedItems, onSelectionChange]);
|
|
4139
4130
|
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) => {
|
|
4140
|
-
var _a;
|
|
4141
4131
|
if (isValidElement(menuItem)) {
|
|
4142
|
-
const isSelected = selectedItems.includes(
|
|
4143
|
-
return
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4132
|
+
const isSelected = selectedItems.includes(menuItem.props.id ?? `${index}`) || menuItem.props.selected;
|
|
4133
|
+
return cloneElement(menuItem, {
|
|
4134
|
+
...menuItem.props,
|
|
4135
|
+
key: index,
|
|
4136
|
+
onClick: (event) => {
|
|
4137
|
+
menuItem.props.onClick?.(event);
|
|
4138
|
+
handleItemClick(menuItem.props.id ?? `${index}`, menuItem.props.disabled);
|
|
4139
|
+
},
|
|
4140
|
+
className: isMulti && isSelected
|
|
4141
|
+
? cvaMenuListMultiSelect({ className: menuItem.props.className })
|
|
4142
|
+
: cvaMenuListItem({ className: menuItem.props.className }),
|
|
4143
|
+
selected: isSelected,
|
|
4144
|
+
suffix: menuItem.props.suffix ??
|
|
4145
|
+
(isMulti && isSelected ? jsx(Icon, { className: "block text-blue-600", name: "Check", size: "medium" }) : null),
|
|
4146
|
+
});
|
|
4156
4147
|
}
|
|
4157
4148
|
return null;
|
|
4158
4149
|
}) }));
|
|
@@ -4177,7 +4168,7 @@ const MoreMenu = ({ className, dataTestId, popoverProps, iconProps = {
|
|
|
4177
4168
|
variant: "secondary",
|
|
4178
4169
|
}, customButton, customPortalId, children, }) => {
|
|
4179
4170
|
const actionMenuRef = useRef(null);
|
|
4180
|
-
return (jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId ? dataTestId : "more-menu", ref: actionMenuRef, children: jsxs(Popover, { placement: "bottom-end", ...popoverProps, children: [jsx(PopoverTrigger, { children: customButton
|
|
4171
|
+
return (jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId ? dataTestId : "more-menu", ref: actionMenuRef, children: jsxs(Popover, { placement: "bottom-end", ...popoverProps, children: [jsx(PopoverTrigger, { children: customButton ?? (jsx(IconButton, { dataTestId: "more-menu-icon", ...iconButtonProps, icon: jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) })) }), jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
|
|
4181
4172
|
};
|
|
4182
4173
|
|
|
4183
4174
|
const cvaNotice = cvaMerge(["flex", "items-center"]);
|
|
@@ -4282,7 +4273,7 @@ const Page = ({ layout, className, children, dataTestId }) => {
|
|
|
4282
4273
|
* Applies padding to content. To be used within a <Page/>
|
|
4283
4274
|
*
|
|
4284
4275
|
* @param {PageContentProps} props - The component props.
|
|
4285
|
-
* @returns {
|
|
4276
|
+
* @returns {ReactNode} - The rendered component.
|
|
4286
4277
|
*/
|
|
4287
4278
|
const PageContent = ({ className, children, dataTestId, layout }) => {
|
|
4288
4279
|
return (jsx("div", { className: cvaPageContent({ className, layout }), "data-testid": dataTestId ? dataTestId : "page-content", children: children }));
|
|
@@ -4342,7 +4333,7 @@ const PageHeader = ({ className, dataTestId, action, actionPosition, showLoading
|
|
|
4342
4333
|
withBorder: !tabsList,
|
|
4343
4334
|
}), "data-testid": dataTestId, children: [jsxs("div", { className: cvaPageHeader(), children: [jsxs("div", { className: cvaPageHeaderHeadingAccessoriesContainer({
|
|
4344
4335
|
actionPosition: actionPosition ? actionPosition : null,
|
|
4345
|
-
}), "data-testid": dataTestId ? `${dataTestId}-heading-container` : undefined, children: [jsxs("div", { className: cvaPageHeaderHeadingContainer(), children: [backTo ? (jsx(Button, { asChild: true, className: "bg-black/5 hover:bg-black/10", prefix: jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "small", square: true, variant: "ghost-neutral", children: jsx(Link, { to: backTo }) })) : undefined, jsxs("div", { className: "flex flex-col", children: [jsxs("div", { className: "flex flex-row flex-wrap items-center gap-x-4 gap-y-2", children: [jsx("h1", { className: cvaPageHeaderHeading(), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, children: title }), description && !showLoading ? (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, iconProps: { name: descriptionIcon
|
|
4336
|
+
}), "data-testid": dataTestId ? `${dataTestId}-heading-container` : undefined, children: [jsxs("div", { className: cvaPageHeaderHeadingContainer(), children: [backTo ? (jsx(Button, { asChild: true, className: "bg-black/5 hover:bg-black/10", prefix: jsx(Icon, { name: "ArrowLeft", size: "small" }), size: "small", square: true, variant: "ghost-neutral", children: jsx(Link, { to: backTo }) })) : undefined, jsxs("div", { className: "flex flex-col", children: [jsxs("div", { className: "flex flex-row flex-wrap items-center gap-x-4 gap-y-2", children: [jsx("h1", { className: cvaPageHeaderHeading(), "data-testid": dataTestId ? `${dataTestId}-heading` : undefined, children: title }), description && !showLoading ? (jsx(Tooltip, { dataTestId: dataTestId ? `${dataTestId}-tooltip` : undefined, iconProps: { name: descriptionIcon ?? "QuestionMarkCircle" }, label: description, placement: "bottom" })) : undefined, tag && !showLoading ? (jsx(Tag, { color: tagColor, dataTestId: dataTestId ? `${dataTestId}-tag` : undefined, children: tag })) : undefined] }), link ? (jsxs(Link, { className: cvaPageHeaderLink(), "data-testid": "tooltip-link", target: "_blank", to: link, children: [linkText, jsx(Icon, { name: "ArrowTopRightOnSquare", size: "small" })] })) : undefined] }), showLoading ? (jsx(Spinner, { centering: "vertically", dataTestId: dataTestId ? `${dataTestId}-spinner` : undefined })) : null] }), jsx("div", { children: action })] }), children ? jsx("div", { className: cvaPageHeaderChildContainer(), children: children }) : null] }), tabsList] }));
|
|
4346
4337
|
};
|
|
4347
4338
|
|
|
4348
4339
|
const cvaPagination = cvaMerge(["flex", "items-center", "gap-1"]);
|
|
@@ -4386,7 +4377,7 @@ const Pagination = ({ previousPage, nextPage, canPreviousPage, canNextPage, page
|
|
|
4386
4377
|
setPage(to);
|
|
4387
4378
|
setCurrentPage(String(to + 1));
|
|
4388
4379
|
}
|
|
4389
|
-
onPageChange
|
|
4380
|
+
onPageChange?.({ from, to, description });
|
|
4390
4381
|
}, [page, onPageChange, previousPage, nextPage]);
|
|
4391
4382
|
if (loading) {
|
|
4392
4383
|
return (jsx("div", { className: cvaPagination({ className }), children: jsx(SkeletonLines, { height: 16, width: 150 }) }));
|
|
@@ -4557,7 +4548,7 @@ const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id"
|
|
|
4557
4548
|
}, [handleIntersection, threshold]);
|
|
4558
4549
|
const unobserve = useCallback(() => {
|
|
4559
4550
|
const currentObserver = observerRef.current;
|
|
4560
|
-
currentObserver
|
|
4551
|
+
currentObserver?.disconnect();
|
|
4561
4552
|
observerRef.current = null;
|
|
4562
4553
|
}, []);
|
|
4563
4554
|
const initializeObserver = useCallback(() => {
|
|
@@ -4588,7 +4579,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
|
|
|
4588
4579
|
const { overflowContainerRef, itemOverflowMap } = useOverflowItems({
|
|
4589
4580
|
children,
|
|
4590
4581
|
childUniqueIdentifierAttribute: "id",
|
|
4591
|
-
threshold: overflowThreshold
|
|
4582
|
+
threshold: overflowThreshold ?? 0.8,
|
|
4592
4583
|
});
|
|
4593
4584
|
const overflowItemCount = objectValues(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
|
|
4594
4585
|
const itemVisibilityClassName = (id) => {
|
|
@@ -4597,18 +4588,17 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
|
|
|
4597
4588
|
}
|
|
4598
4589
|
return "visible";
|
|
4599
4590
|
};
|
|
4600
|
-
return (jsxs("div", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [jsx("div", { className: cvaSidebarChildContainer({ breakpoint, className: childContainerClassName }), "data-testid": dataTestId ? `${dataTestId}-child-container` : null, ref: overflowContainerRef, children:
|
|
4601
|
-
return
|
|
4591
|
+
return (jsxs("div", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [jsx("div", { className: cvaSidebarChildContainer({ breakpoint, className: childContainerClassName }), "data-testid": dataTestId ? `${dataTestId}-child-container` : null, ref: overflowContainerRef, children: Children.map(children, child => {
|
|
4592
|
+
return cloneElement(child, {
|
|
4602
4593
|
className: twMerge(child.props.className, itemVisibilityClassName(child.props.id)),
|
|
4603
4594
|
});
|
|
4604
4595
|
}) }), overflowItemCount > 0 ? (jsx(MoreMenu, { iconButtonProps: {
|
|
4605
4596
|
variant: "ghost-neutral",
|
|
4606
|
-
}, ...moreMenuProps, className: moreMenuProps
|
|
4597
|
+
}, ...moreMenuProps, className: moreMenuProps?.className, dataTestId: dataTestId ? `${dataTestId}-more-menu` : undefined, children: close => (jsx(MenuList, { ...menuListProps, dataTestId: dataTestId, children: Children.map(children, child => {
|
|
4607
4598
|
return itemOverflowMap[child.props.id]
|
|
4608
|
-
?
|
|
4599
|
+
? cloneElement(child, {
|
|
4609
4600
|
onClick: () => {
|
|
4610
|
-
|
|
4611
|
-
(_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
4601
|
+
child.props.onClick?.();
|
|
4612
4602
|
close();
|
|
4613
4603
|
},
|
|
4614
4604
|
className: "w-full",
|
|
@@ -4669,12 +4659,12 @@ const cvaTab = cvaMerge([
|
|
|
4669
4659
|
* We add a custom implementation of the asChild prop to make it easy to make the child element look like other tabs.
|
|
4670
4660
|
*/
|
|
4671
4661
|
const Tab = ({ value, isFullWidth = false, iconName, dataTestId, className, children, suffix, asChild, appendTabStylesToChildIfAsChild = true, ...rest }) => {
|
|
4672
|
-
const renderContent = () => (jsxs(Fragment, { children: [iconName ? jsx(Icon, { name: iconName, size: "small" }) : null,
|
|
4662
|
+
const renderContent = () => (jsxs(Fragment, { children: [iconName ? jsx(Icon, { name: iconName, size: "small" }) : null, isValidElement(children) ? children.props.children : children, suffix] }));
|
|
4673
4663
|
const commonProps = {
|
|
4674
4664
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
4675
4665
|
...rest,
|
|
4676
4666
|
};
|
|
4677
|
-
return (jsx(Trigger, { asChild: true, value: value, children: asChild && typeof children !== "string" ? (
|
|
4667
|
+
return (jsx(Trigger, { asChild: true, value: value, children: asChild && typeof children !== "string" ? (cloneElement(children, {
|
|
4678
4668
|
...commonProps,
|
|
4679
4669
|
children: renderContent(),
|
|
4680
4670
|
})) : (jsx("button", { ...commonProps, "data-testid": dataTestId, children: renderContent() })) }));
|
|
@@ -4732,7 +4722,7 @@ const cvaToggleItemText = cvaMerge(["text-ellipsis", "truncate", "flex-grow"], {
|
|
|
4732
4722
|
const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false, size = "medium", isIconOnly = false, className, dataTestId, }) => {
|
|
4733
4723
|
return (jsx("div", { className: cvaToggleGroup(), "data-testid": dataTestId, children: list.map((item, index) => (jsx(ToggleItem, { className: twMerge(className, index === 0 ? ["rounded-l-md", "border-l"] : "", index === list.length - 1 ? ["rounded-r-md", "border-r"] : ""), dataTestId: item.dataTestId, disabled: disabled, iconName: item.iconName, isIconOnly: isIconOnly, onClick: () => {
|
|
4734
4724
|
setSelected(item.id);
|
|
4735
|
-
onChange
|
|
4725
|
+
onChange?.(item.id);
|
|
4736
4726
|
}, selected: selected === item.id, size: size, text: item.text, title: item.title, tooltip: item.tooltip }, item.id))) }));
|
|
4737
4727
|
};
|
|
4738
4728
|
/**
|
|
@@ -4740,7 +4730,7 @@ const ToggleGroup = ({ list, selected, setSelected, onChange, disabled = false,
|
|
|
4740
4730
|
*/
|
|
4741
4731
|
const ToggleItem = ({ title, onClick, disabled = false, isIconOnly = false, iconName, size, className, selected = false, text, tooltip, dataTestId, }) => {
|
|
4742
4732
|
// eslint-disable-next-line sonarjs/no-selector-parameter
|
|
4743
|
-
return isIconOnly ? (jsx(Tooltip, { label:
|
|
4733
|
+
return isIconOnly ? (jsx(Tooltip, { label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(IconButton, { className: cvaToggleItem({ className, selected }), "data-testid": dataTestId, disabled: disabled, icon: iconName ? (jsx(Icon, { className: selected ? "text-slate-600" : "text-slate-400", name: iconName, size: "small" })) : null, onClick: onClick, size: size, title: iconName, variant: "secondary" }) })) : (jsx(Tooltip, { disabled: !text?.truncate && tooltip?.content === undefined, label: tooltip?.content || title, placement: tooltip?.placement || "top", children: jsx(Button, { className: cvaToggleItem({ className, selected }), "data-testid": dataTestId, disabled: disabled, onClick: onClick, prefix: iconName ? (jsx(Icon, { className: selected ? "text-slate-600" : "text-slate-400", name: iconName, size: "small" })) : null, size: size, variant: "secondary", children: jsx("span", { className: cvaToggleItemText({ disabledAndSelected: disabled && selected, maxWidth: text?.maxWidth }), children: title }) }) }));
|
|
4744
4734
|
};
|
|
4745
4735
|
|
|
4746
4736
|
const cvaValueBar = cvaMerge(["w-full"], {
|
|
@@ -4823,14 +4813,13 @@ const getDefaultFillColor = (score) => {
|
|
|
4823
4813
|
* @returns {string} color value
|
|
4824
4814
|
*/
|
|
4825
4815
|
const getFillColor = (score, levelColors) => {
|
|
4826
|
-
var _a, _b;
|
|
4827
4816
|
if (levelColors.low && score < (levelColors.low.level || 0)) {
|
|
4828
4817
|
return levelColors.low.color;
|
|
4829
4818
|
}
|
|
4830
4819
|
if (levelColors.high && score >= (levelColors.high.level || 0)) {
|
|
4831
4820
|
return levelColors.high.color;
|
|
4832
4821
|
}
|
|
4833
|
-
return
|
|
4822
|
+
return levelColors.medium?.color ?? color("WARNING", 300);
|
|
4834
4823
|
};
|
|
4835
4824
|
/**
|
|
4836
4825
|
* Helper function to get color used by the ValueBar
|
|
@@ -4856,7 +4845,7 @@ const ValueBar = ({ value, min = 0, max = 100, unit, size = "small", levelColors
|
|
|
4856
4845
|
const score = getScore(value, min, max, zeroScoreAllowed);
|
|
4857
4846
|
const barFillColor = levelColors ? getFillColor(score, levelColors) : getDefaultFillColor(score);
|
|
4858
4847
|
const barWidth = showValue && size === "small" ? 90 : 100;
|
|
4859
|
-
return (jsx("svg", { className: cvaValueBar({ size, className }), "data-testid": dataTestId, role: "img", children: jsxs("g", { children: [jsx("rect", { className: cvaValueBarProgress({ fill: "background", className }), "data-testid": "value-bar-svg-rect-0", rx: size === "extraSmall" ? "2" : "5", width: `${barWidth}%` }), jsx("rect", { className: cvaValueBarProgress(), "data-testid": "value-bar-svg-rect-1", fill: barFillColor, rx: size === "extraSmall" ? "2" : "5", width: `${score * barWidth}%` }), showValue && size === "large" ? (jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor
|
|
4848
|
+
return (jsx("svg", { className: cvaValueBar({ size, className }), "data-testid": dataTestId, role: "img", children: jsxs("g", { children: [jsx("rect", { className: cvaValueBarProgress({ fill: "background", className }), "data-testid": "value-bar-svg-rect-0", rx: size === "extraSmall" ? "2" : "5", width: `${barWidth}%` }), jsx("rect", { className: cvaValueBarProgress(), "data-testid": "value-bar-svg-rect-1", fill: barFillColor, rx: size === "extraSmall" ? "2" : "5", width: `${score * barWidth}%` }), showValue && size === "large" ? (jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor ?? "white", x: "12", y: "23", children: [Number(value.toFixed(1)), unit || ""] })) : null, showValue && size === "small" ? (jsxs("text", { className: cvaValueBarText({ size }), fill: valueColor ?? color("NEUTRAL", 400, "CSS"), x: `${barWidth + 2}%`, y: "11", children: [Number(value.toFixed(1)), unit || ""] })) : null] }) }));
|
|
4860
4849
|
};
|
|
4861
4850
|
|
|
4862
4851
|
const cvaVirtualizedListContainer = cvaMerge(["h-full", "overflow-auto"]);
|
|
@@ -4887,13 +4876,12 @@ const cvaVirtualizedListItem = cvaMerge(["absolute", "top-0", "left-0", "w-full"
|
|
|
4887
4876
|
* @property {skeletonLinesHeight} [skeletonLinesHeight="2rem"] - The height of the skeleton lines.
|
|
4888
4877
|
*/
|
|
4889
4878
|
const VirtualizedList = ({ count, rowHeight = 40, pagination, children, className, dataTestId, separator = "none", loadingIndicator = "spinner", skeletonLinesHeight = rowHeight + "px", onRowClick, }) => {
|
|
4890
|
-
var _a;
|
|
4891
4879
|
const containerRef = useRef(null);
|
|
4892
4880
|
const listRef = useRef(null);
|
|
4893
4881
|
const { fetchMoreOnBottomReached, getVirtualItems, getTotalSize, measureElement } = useInfiniteScroll({
|
|
4894
4882
|
pagination: pagination || noPagination,
|
|
4895
4883
|
containerRef,
|
|
4896
|
-
rowSize:
|
|
4884
|
+
rowSize: pagination?.pageInfo?.hasNextPage && pagination.isLoading ? count + 1 : count,
|
|
4897
4885
|
rowHeight,
|
|
4898
4886
|
});
|
|
4899
4887
|
return (jsx("div", { className: cvaVirtualizedListContainer({ className }), "data-testid": dataTestId,
|
|
@@ -4902,7 +4890,7 @@ const VirtualizedList = ({ count, rowHeight = 40, pagination, children, classNam
|
|
|
4902
4890
|
const isLoaderRow = virtualRow.index > count - 1;
|
|
4903
4891
|
return (jsx("li", { className: cvaVirtualizedListItem({ separator }), "data-index": virtualRow.index, onClick: onRowClick ? () => onRowClick(virtualRow.index) : undefined, ref: measureElement, style: {
|
|
4904
4892
|
transform: `translateY(${virtualRow.start}px)`,
|
|
4905
|
-
}, tabIndex: -1, children: isLoaderRow ? (
|
|
4893
|
+
}, 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));
|
|
4906
4894
|
}) }) }));
|
|
4907
4895
|
};
|
|
4908
4896
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@trackunit/ui-design-tokens": "^1.0.1",
|
|
23
23
|
"@trackunit/css-class-variance-utilities": "^1.0.1",
|
|
24
24
|
"@trackunit/shared-utils": "^1.0.3",
|
|
25
|
-
"@trackunit/ui-icons": "^1.0.
|
|
25
|
+
"@trackunit/ui-icons": "^1.0.3",
|
|
26
26
|
"@trackunit/react-table-pagination": "^1.0.1"
|
|
27
27
|
},
|
|
28
28
|
"module": "./index.esm.js",
|