@trackunit/react-components 1.9.21 → 1.9.24
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 +54 -50
- package/index.esm.js +54 -50
- package/package.json +6 -6
- package/src/components/Icon/Icon.d.ts +1 -13
- package/src/components/Icon/Icon.variants.d.ts +1 -1
- package/src/components/List/List.d.ts +1 -12
- package/src/components/List/useList.d.ts +20 -4
- package/src/components/ListItem/ListItem.d.ts +12 -10
- package/src/components/Tag/Tag.variants.d.ts +1 -1
package/index.cjs.js
CHANGED
|
@@ -32,7 +32,6 @@ const cvaIcon = cssClassVarianceUtilities.cvaMerge(["aspect-square", "inline-gri
|
|
|
32
32
|
variants: {
|
|
33
33
|
color: {
|
|
34
34
|
primary: "text-primary-600",
|
|
35
|
-
secondary: "text-neutral-400",
|
|
36
35
|
neutral: "text-neutral-400",
|
|
37
36
|
info: "text-info-600",
|
|
38
37
|
success: "text-success-600",
|
|
@@ -201,7 +200,6 @@ const cvaTag = cssClassVarianceUtilities.cvaMerge([
|
|
|
201
200
|
},
|
|
202
201
|
color: {
|
|
203
202
|
primary: ["bg-primary-100", "text-primary-700"],
|
|
204
|
-
secondary: ["bg-neutral-100", "text-neutral-700"],
|
|
205
203
|
neutral: ["bg-neutral-200", "text-neutral-700"],
|
|
206
204
|
black: ["bg-neutral-100", "text-neutral-700"],
|
|
207
205
|
white: ["bg-white", "text-neutral-600"],
|
|
@@ -274,7 +272,7 @@ Tag.displayName = "Tag";
|
|
|
274
272
|
* A component used to display the package name and version in the Storybook docs.
|
|
275
273
|
*/
|
|
276
274
|
const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
277
|
-
return (jsxRuntime.jsxs("div", { className: "flex gap-2", children: [jsxRuntime.jsx(Tag, { color: "
|
|
275
|
+
return (jsxRuntime.jsxs("div", { className: "flex gap-2", children: [jsxRuntime.jsx(Tag, { color: "neutral", children: packageJSON?.name }), jsxRuntime.jsxs(Tag, { color: "neutral", children: ["v", packageJSON?.version] })] }));
|
|
278
276
|
};
|
|
279
277
|
|
|
280
278
|
/**
|
|
@@ -1937,7 +1935,7 @@ const BreadcrumbForMediumScreen = ({ dataTestId, breadcrumbItems }) => {
|
|
|
1937
1935
|
const [expanded, setExpanded] = react.useState(false);
|
|
1938
1936
|
const getReducedArray = react.useCallback(() => {
|
|
1939
1937
|
let reducedArrayElements = [];
|
|
1940
|
-
const collapsibleButton = (jsxRuntime.jsxs("div", { className: cvaBreadcrumbItem(), children: [jsxRuntime.jsx(IconButton, { dataTestId: `collapsibleButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal", size: "small" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx(Icon, { color: "
|
|
1938
|
+
const collapsibleButton = (jsxRuntime.jsxs("div", { className: cvaBreadcrumbItem(), children: [jsxRuntime.jsx(IconButton, { dataTestId: `collapsibleButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal", size: "small" }), onClick: () => setExpanded(true), size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx(Icon, { color: "neutral", name: "Slash", size: "small" })] }));
|
|
1941
1939
|
const firstBreadcrumbItem = breadcrumbItems[0];
|
|
1942
1940
|
if (firstBreadcrumbItem && breadcrumbItems.length > 3) {
|
|
1943
1941
|
const lastTwoBreadcrumbItem = breadcrumbItems.slice(-2);
|
|
@@ -3426,7 +3424,31 @@ const cvaCardBodyDensityContainer = cssClassVarianceUtilities.cvaMerge(["grid",
|
|
|
3426
3424
|
},
|
|
3427
3425
|
});
|
|
3428
3426
|
|
|
3429
|
-
const
|
|
3427
|
+
const cvaListContainer = cssClassVarianceUtilities.cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
|
|
3428
|
+
variants: {
|
|
3429
|
+
withTopSeparator: {
|
|
3430
|
+
true: ["border-t", "border-neutral-200", "transition-colors duration-200 ease-in"],
|
|
3431
|
+
false: ["border-t", "border-transparent", "transition-colors duration-200 ease-in"],
|
|
3432
|
+
},
|
|
3433
|
+
},
|
|
3434
|
+
defaultVariants: {
|
|
3435
|
+
withTopSeparator: false,
|
|
3436
|
+
},
|
|
3437
|
+
});
|
|
3438
|
+
const cvaList = cssClassVarianceUtilities.cvaMerge(["relative"]);
|
|
3439
|
+
const cvaListItem$1 = cssClassVarianceUtilities.cvaMerge(["absolute", "top-0", "left-0", "w-full"], {
|
|
3440
|
+
variants: {
|
|
3441
|
+
separator: {
|
|
3442
|
+
line: ["border-b", "border-neutral-200"],
|
|
3443
|
+
none: "",
|
|
3444
|
+
},
|
|
3445
|
+
},
|
|
3446
|
+
defaultVariants: {
|
|
3447
|
+
separator: "none",
|
|
3448
|
+
},
|
|
3449
|
+
});
|
|
3450
|
+
|
|
3451
|
+
const cvaListItem = cssClassVarianceUtilities.cvaMerge(["py-3", "px-4", "min-h-14", "w-full", "flex", "justify-between", "items-center"]);
|
|
3430
3452
|
const cvaMainInformationClass = cssClassVarianceUtilities.cvaMerge(["grid", "items-center", "text-sm", "gap-2"], {
|
|
3431
3453
|
variants: {
|
|
3432
3454
|
hasThumbnail: {
|
|
@@ -3466,33 +3488,9 @@ const ListItemSkeleton = ({ hasThumbnail = DEFAULT_SKELETON_LIST_ITEM_PROPS.hasT
|
|
|
3466
3488
|
details: getResponsiveRandomWidthPercentage({ min: 25, max: 45 }),
|
|
3467
3489
|
};
|
|
3468
3490
|
});
|
|
3469
|
-
return (jsxRuntime.jsxs("div", { className: cvaListItem
|
|
3491
|
+
return (jsxRuntime.jsxs("div", { className: cvaListItem({ className: "w-full" }), children: [jsxRuntime.jsxs("div", { className: cvaMainInformationClass({ hasThumbnail, className: "w-full" }), children: [hasThumbnail ? (jsxRuntime.jsx("div", { className: cvaThumbnailContainer({ className: "bg-gray-200" }), children: jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("bg-gray-300", thumbnailShape === "circle" ? "rounded-full" : "rounded"), style: { width: 20, height: 20 } }) })) : null, jsxRuntime.jsxs("div", { className: "grid-rows-min-fr grid w-full items-center gap-1 text-sm", children: [jsxRuntime.jsx(SkeletonLines, { height: "0.875em", lines: 1, width: lineWidths.title }), hasDescription ? jsxRuntime.jsx(SkeletonLines, { height: "0.75em", lines: 1, width: lineWidths.description }) : null, hasMeta ? jsxRuntime.jsx(SkeletonLines, { height: "0.75em", lines: 1, width: lineWidths.meta }) : null] })] }), hasDetails ? (jsxRuntime.jsx("div", { className: "pl-2 text-sm", children: jsxRuntime.jsx(SkeletonLines, { height: "0.875em", lines: 1, width: lineWidths.details }) })) : null] }));
|
|
3470
3492
|
};
|
|
3471
3493
|
|
|
3472
|
-
const cvaListContainer = cssClassVarianceUtilities.cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
|
|
3473
|
-
variants: {
|
|
3474
|
-
withTopSeparator: {
|
|
3475
|
-
true: ["border-t", "border-neutral-200", "transition-colors duration-200 ease-in"],
|
|
3476
|
-
false: ["border-t", "border-transparent", "transition-colors duration-200 ease-in"],
|
|
3477
|
-
},
|
|
3478
|
-
},
|
|
3479
|
-
defaultVariants: {
|
|
3480
|
-
withTopSeparator: false,
|
|
3481
|
-
},
|
|
3482
|
-
});
|
|
3483
|
-
const cvaList = cssClassVarianceUtilities.cvaMerge(["relative"]);
|
|
3484
|
-
const cvaListItem = cssClassVarianceUtilities.cvaMerge(["absolute", "top-0", "left-0", "w-full"], {
|
|
3485
|
-
variants: {
|
|
3486
|
-
separator: {
|
|
3487
|
-
line: ["[&:not(:last-child)]:border-b", "border-neutral-200"],
|
|
3488
|
-
none: "",
|
|
3489
|
-
},
|
|
3490
|
-
},
|
|
3491
|
-
defaultVariants: {
|
|
3492
|
-
separator: "none",
|
|
3493
|
-
},
|
|
3494
|
-
});
|
|
3495
|
-
|
|
3496
3494
|
/**
|
|
3497
3495
|
*
|
|
3498
3496
|
*/
|
|
@@ -3577,9 +3575,9 @@ const ListLoadingIndicator = ({ type, hasThumbnail, thumbnailShape, hasDescripti
|
|
|
3577
3575
|
* );
|
|
3578
3576
|
* ```
|
|
3579
3577
|
*/
|
|
3580
|
-
const List = ({ children, className, dataTestId,
|
|
3578
|
+
const List = ({ children, className, dataTestId,
|
|
3581
3579
|
// UseListResult properties
|
|
3582
|
-
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, scrollOffset,
|
|
3580
|
+
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, scrollOffset, separator, topSeparatorOnScroll,
|
|
3583
3581
|
// Unused but part of UseListResult interface
|
|
3584
3582
|
getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }) => {
|
|
3585
3583
|
return (jsxRuntime.jsx("div", { className: cvaListContainer({
|
|
@@ -3588,22 +3586,18 @@ getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset:
|
|
|
3588
3586
|
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref: containerRef, children: jsxRuntime.jsx("ul", { className: cvaList(), ref: listRef, children: rows.map(row => {
|
|
3589
3587
|
// Generate list item props with separator styling
|
|
3590
3588
|
const listItemProps = getListItemProps(row, {
|
|
3591
|
-
className: cvaListItem({ separator }),
|
|
3589
|
+
className: cvaListItem$1({ separator }),
|
|
3592
3590
|
});
|
|
3593
3591
|
const key = row.virtualRow.key;
|
|
3594
3592
|
// Render loading row
|
|
3595
3593
|
if (row.type === "loader") {
|
|
3596
|
-
const loadingConfig = loadingIndicator ?? {
|
|
3597
|
-
type: "skeleton",
|
|
3598
|
-
...DEFAULT_SKELETON_LIST_ITEM_PROPS,
|
|
3599
|
-
};
|
|
3600
3594
|
// Use the total data count from useList, not visible rows (which are virtualized)
|
|
3601
3595
|
const hasHeaderRow = !!header;
|
|
3602
3596
|
const dataStartIndex = hasHeaderRow ? 1 : 0;
|
|
3603
3597
|
const totalDataRows = dataStartIndex + count;
|
|
3604
3598
|
const loaderIndex = row.virtualRow.index - totalDataRows;
|
|
3605
3599
|
const shouldShowLoader = shouldShowLoaderAtIndex(loaderIndex);
|
|
3606
|
-
return (jsxRuntime.jsx("li", { ...listItemProps, children: shouldShowLoader ? jsxRuntime.jsx(ListLoadingIndicator, { ...
|
|
3600
|
+
return (jsxRuntime.jsx("li", { ...listItemProps, children: shouldShowLoader ? jsxRuntime.jsx(ListLoadingIndicator, { ...loadingIndicator }) : null }, key));
|
|
3607
3601
|
}
|
|
3608
3602
|
// Render header row
|
|
3609
3603
|
if (row.type === "header") {
|
|
@@ -3651,10 +3645,12 @@ const DEFAULT_LOADING_INDICATOR_CONFIG = {
|
|
|
3651
3645
|
* );
|
|
3652
3646
|
* ```
|
|
3653
3647
|
*/
|
|
3654
|
-
const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAULT_LOADING_INDICATOR_CONFIG, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, }) => {
|
|
3648
|
+
const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAULT_LOADING_INDICATOR_CONFIG, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, separator = "line", topSeparatorOnScroll = false, }) => {
|
|
3655
3649
|
const containerRef = react.useRef(null);
|
|
3656
3650
|
const listRef = react.useRef(null);
|
|
3657
3651
|
const rowRefsMap = react.useRef(new Map());
|
|
3652
|
+
// Resolve loading indicator once to avoid unnecessary re-renders
|
|
3653
|
+
const resolvedLoadingIndicator = react.useMemo(() => getResolvedLoadingIndicator(loadingIndicator), [loadingIndicator]);
|
|
3658
3654
|
// Calculate total count including header
|
|
3659
3655
|
const hasHeader = Boolean(header);
|
|
3660
3656
|
const dataStartIndex = hasHeader ? 1 : 0;
|
|
@@ -3664,7 +3660,7 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3664
3660
|
const getLoadingRowsCount = react.useCallback(() => {
|
|
3665
3661
|
if (pagination?.isLoading === false)
|
|
3666
3662
|
return 0;
|
|
3667
|
-
const { type: loadingIndicatorType } =
|
|
3663
|
+
const { type: loadingIndicatorType } = resolvedLoadingIndicator;
|
|
3668
3664
|
switch (loadingIndicatorType) {
|
|
3669
3665
|
case "none":
|
|
3670
3666
|
return 0;
|
|
@@ -3673,20 +3669,20 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3673
3669
|
case "custom":
|
|
3674
3670
|
case "skeleton": {
|
|
3675
3671
|
const isInitialLoading = !pagination?.pageInfo;
|
|
3676
|
-
const initialCount =
|
|
3677
|
-
const scrollCount =
|
|
3672
|
+
const initialCount = resolvedLoadingIndicator.initialLoadingCount ?? 10;
|
|
3673
|
+
const scrollCount = resolvedLoadingIndicator.scrollLoadingCount ?? 3;
|
|
3678
3674
|
return isInitialLoading ? initialCount : scrollCount;
|
|
3679
3675
|
}
|
|
3680
3676
|
default: {
|
|
3681
3677
|
throw new Error(`${loadingIndicatorType} is not known`);
|
|
3682
3678
|
}
|
|
3683
3679
|
}
|
|
3684
|
-
}, [
|
|
3680
|
+
}, [resolvedLoadingIndicator, pagination?.isLoading, pagination?.pageInfo]);
|
|
3685
3681
|
// Helper to determine if a specific loader index should be shown
|
|
3686
3682
|
const shouldShowLoaderAtIndex = react.useCallback((loaderIndex) => {
|
|
3687
3683
|
if (pagination?.isLoading === false)
|
|
3688
3684
|
return false;
|
|
3689
|
-
const { type: loadingIndicatorType } =
|
|
3685
|
+
const { type: loadingIndicatorType } = resolvedLoadingIndicator;
|
|
3690
3686
|
let result;
|
|
3691
3687
|
switch (loadingIndicatorType) {
|
|
3692
3688
|
case "none":
|
|
@@ -3698,8 +3694,8 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3698
3694
|
case "custom":
|
|
3699
3695
|
case "skeleton": {
|
|
3700
3696
|
const isInitialLoading = !pagination?.pageInfo;
|
|
3701
|
-
const initialCount =
|
|
3702
|
-
const scrollCount =
|
|
3697
|
+
const initialCount = resolvedLoadingIndicator.initialLoadingCount ?? 10;
|
|
3698
|
+
const scrollCount = resolvedLoadingIndicator.scrollLoadingCount ?? 3;
|
|
3703
3699
|
const maxCount = isInitialLoading ? initialCount : scrollCount;
|
|
3704
3700
|
result = loaderIndex < maxCount;
|
|
3705
3701
|
break;
|
|
@@ -3709,7 +3705,7 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3709
3705
|
}
|
|
3710
3706
|
}
|
|
3711
3707
|
return result;
|
|
3712
|
-
}, [
|
|
3708
|
+
}, [resolvedLoadingIndicator, pagination?.isLoading, pagination?.pageInfo]);
|
|
3713
3709
|
const totalRowCount = react.useMemo(() => {
|
|
3714
3710
|
// Only add the exact number of loading rows we want to show
|
|
3715
3711
|
const loadingRows = pagination?.isLoading === true ? getLoadingRowsCount() : 0;
|
|
@@ -3833,11 +3829,19 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3833
3829
|
rows,
|
|
3834
3830
|
getListItemProps,
|
|
3835
3831
|
header,
|
|
3836
|
-
loadingIndicator,
|
|
3832
|
+
loadingIndicator: resolvedLoadingIndicator,
|
|
3837
3833
|
shouldShowLoaderAtIndex,
|
|
3838
3834
|
count,
|
|
3835
|
+
separator,
|
|
3836
|
+
topSeparatorOnScroll,
|
|
3839
3837
|
};
|
|
3840
3838
|
};
|
|
3839
|
+
const getResolvedLoadingIndicator = (loadingIndicator) => {
|
|
3840
|
+
if (typeof loadingIndicator === "function") {
|
|
3841
|
+
return loadingIndicator(DEFAULT_LOADING_INDICATOR_CONFIG);
|
|
3842
|
+
}
|
|
3843
|
+
return loadingIndicator;
|
|
3844
|
+
};
|
|
3841
3845
|
|
|
3842
3846
|
// Height constants (in pixels) - based on ListItem.variants.ts styling
|
|
3843
3847
|
const MIN_ITEM_HEIGHT = 56; // min-h-14 = 56px (minimum height for ListItem)
|
|
@@ -3955,7 +3959,7 @@ const cvaInteractableItem = cssClassVarianceUtilities.cvaMerge("", {
|
|
|
3955
3959
|
* @returns {Element} ListItem component
|
|
3956
3960
|
*/
|
|
3957
3961
|
const ListItem = ({ className, dataTestId, onClick, details, title, description, meta, thumbnail, thumbnailColor = "info-600", thumbnailBackground = "info-100", ...rest }) => {
|
|
3958
|
-
const baseClass = cvaListItem
|
|
3962
|
+
const baseClass = cvaListItem({ className });
|
|
3959
3963
|
const interactableItemClass = onClick ? tailwindMerge.twMerge(baseClass, cvaInteractableItem({ cursor: "pointer" })) : baseClass;
|
|
3960
3964
|
return (jsxRuntime.jsxs("li", { className: interactableItemClass, "data-testid": dataTestId, onClick: onClick, ...rest, children: [jsxRuntime.jsxs("div", { className: cvaMainInformationClass({ hasThumbnail: !!thumbnail }), children: [thumbnail ? (jsxRuntime.jsx("div", { className: cvaThumbnailContainer({
|
|
3961
3965
|
className: `text-${thumbnailColor} bg-${thumbnailBackground}`,
|
|
@@ -5229,7 +5233,7 @@ exports.cvaIndicatorPing = cvaIndicatorPing;
|
|
|
5229
5233
|
exports.cvaInteractableItem = cvaInteractableItem;
|
|
5230
5234
|
exports.cvaList = cvaList;
|
|
5231
5235
|
exports.cvaListContainer = cvaListContainer;
|
|
5232
|
-
exports.cvaListItem = cvaListItem;
|
|
5236
|
+
exports.cvaListItem = cvaListItem$1;
|
|
5233
5237
|
exports.cvaMenuItem = cvaMenuItem;
|
|
5234
5238
|
exports.cvaMenuItemLabel = cvaMenuItemLabel;
|
|
5235
5239
|
exports.cvaMenuItemPrefix = cvaMenuItemPrefix;
|
package/index.esm.js
CHANGED
|
@@ -30,7 +30,6 @@ const cvaIcon = cvaMerge(["aspect-square", "inline-grid", "relative", "shrink-0"
|
|
|
30
30
|
variants: {
|
|
31
31
|
color: {
|
|
32
32
|
primary: "text-primary-600",
|
|
33
|
-
secondary: "text-neutral-400",
|
|
34
33
|
neutral: "text-neutral-400",
|
|
35
34
|
info: "text-info-600",
|
|
36
35
|
success: "text-success-600",
|
|
@@ -199,7 +198,6 @@ const cvaTag = cvaMerge([
|
|
|
199
198
|
},
|
|
200
199
|
color: {
|
|
201
200
|
primary: ["bg-primary-100", "text-primary-700"],
|
|
202
|
-
secondary: ["bg-neutral-100", "text-neutral-700"],
|
|
203
201
|
neutral: ["bg-neutral-200", "text-neutral-700"],
|
|
204
202
|
black: ["bg-neutral-100", "text-neutral-700"],
|
|
205
203
|
white: ["bg-white", "text-neutral-600"],
|
|
@@ -272,7 +270,7 @@ Tag.displayName = "Tag";
|
|
|
272
270
|
* A component used to display the package name and version in the Storybook docs.
|
|
273
271
|
*/
|
|
274
272
|
const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
275
|
-
return (jsxs("div", { className: "flex gap-2", children: [jsx(Tag, { color: "
|
|
273
|
+
return (jsxs("div", { className: "flex gap-2", children: [jsx(Tag, { color: "neutral", children: packageJSON?.name }), jsxs(Tag, { color: "neutral", children: ["v", packageJSON?.version] })] }));
|
|
276
274
|
};
|
|
277
275
|
|
|
278
276
|
/**
|
|
@@ -1935,7 +1933,7 @@ const BreadcrumbForMediumScreen = ({ dataTestId, breadcrumbItems }) => {
|
|
|
1935
1933
|
const [expanded, setExpanded] = useState(false);
|
|
1936
1934
|
const getReducedArray = useCallback(() => {
|
|
1937
1935
|
let reducedArrayElements = [];
|
|
1938
|
-
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: "
|
|
1936
|
+
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: "neutral", name: "Slash", size: "small" })] }));
|
|
1939
1937
|
const firstBreadcrumbItem = breadcrumbItems[0];
|
|
1940
1938
|
if (firstBreadcrumbItem && breadcrumbItems.length > 3) {
|
|
1941
1939
|
const lastTwoBreadcrumbItem = breadcrumbItems.slice(-2);
|
|
@@ -3424,7 +3422,31 @@ const cvaCardBodyDensityContainer = cvaMerge(["grid", "grid-cols-[1fr_auto]"], {
|
|
|
3424
3422
|
},
|
|
3425
3423
|
});
|
|
3426
3424
|
|
|
3427
|
-
const
|
|
3425
|
+
const cvaListContainer = cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
|
|
3426
|
+
variants: {
|
|
3427
|
+
withTopSeparator: {
|
|
3428
|
+
true: ["border-t", "border-neutral-200", "transition-colors duration-200 ease-in"],
|
|
3429
|
+
false: ["border-t", "border-transparent", "transition-colors duration-200 ease-in"],
|
|
3430
|
+
},
|
|
3431
|
+
},
|
|
3432
|
+
defaultVariants: {
|
|
3433
|
+
withTopSeparator: false,
|
|
3434
|
+
},
|
|
3435
|
+
});
|
|
3436
|
+
const cvaList = cvaMerge(["relative"]);
|
|
3437
|
+
const cvaListItem$1 = cvaMerge(["absolute", "top-0", "left-0", "w-full"], {
|
|
3438
|
+
variants: {
|
|
3439
|
+
separator: {
|
|
3440
|
+
line: ["border-b", "border-neutral-200"],
|
|
3441
|
+
none: "",
|
|
3442
|
+
},
|
|
3443
|
+
},
|
|
3444
|
+
defaultVariants: {
|
|
3445
|
+
separator: "none",
|
|
3446
|
+
},
|
|
3447
|
+
});
|
|
3448
|
+
|
|
3449
|
+
const cvaListItem = cvaMerge(["py-3", "px-4", "min-h-14", "w-full", "flex", "justify-between", "items-center"]);
|
|
3428
3450
|
const cvaMainInformationClass = cvaMerge(["grid", "items-center", "text-sm", "gap-2"], {
|
|
3429
3451
|
variants: {
|
|
3430
3452
|
hasThumbnail: {
|
|
@@ -3464,33 +3486,9 @@ const ListItemSkeleton = ({ hasThumbnail = DEFAULT_SKELETON_LIST_ITEM_PROPS.hasT
|
|
|
3464
3486
|
details: getResponsiveRandomWidthPercentage({ min: 25, max: 45 }),
|
|
3465
3487
|
};
|
|
3466
3488
|
});
|
|
3467
|
-
return (jsxs("div", { className: cvaListItem
|
|
3489
|
+
return (jsxs("div", { className: cvaListItem({ className: "w-full" }), children: [jsxs("div", { className: cvaMainInformationClass({ hasThumbnail, className: "w-full" }), children: [hasThumbnail ? (jsx("div", { className: cvaThumbnailContainer({ className: "bg-gray-200" }), children: jsx("div", { className: twMerge("bg-gray-300", thumbnailShape === "circle" ? "rounded-full" : "rounded"), style: { width: 20, height: 20 } }) })) : null, jsxs("div", { className: "grid-rows-min-fr grid w-full items-center gap-1 text-sm", children: [jsx(SkeletonLines, { height: "0.875em", lines: 1, width: lineWidths.title }), hasDescription ? jsx(SkeletonLines, { height: "0.75em", lines: 1, width: lineWidths.description }) : null, hasMeta ? jsx(SkeletonLines, { height: "0.75em", lines: 1, width: lineWidths.meta }) : null] })] }), hasDetails ? (jsx("div", { className: "pl-2 text-sm", children: jsx(SkeletonLines, { height: "0.875em", lines: 1, width: lineWidths.details }) })) : null] }));
|
|
3468
3490
|
};
|
|
3469
3491
|
|
|
3470
|
-
const cvaListContainer = cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
|
|
3471
|
-
variants: {
|
|
3472
|
-
withTopSeparator: {
|
|
3473
|
-
true: ["border-t", "border-neutral-200", "transition-colors duration-200 ease-in"],
|
|
3474
|
-
false: ["border-t", "border-transparent", "transition-colors duration-200 ease-in"],
|
|
3475
|
-
},
|
|
3476
|
-
},
|
|
3477
|
-
defaultVariants: {
|
|
3478
|
-
withTopSeparator: false,
|
|
3479
|
-
},
|
|
3480
|
-
});
|
|
3481
|
-
const cvaList = cvaMerge(["relative"]);
|
|
3482
|
-
const cvaListItem = cvaMerge(["absolute", "top-0", "left-0", "w-full"], {
|
|
3483
|
-
variants: {
|
|
3484
|
-
separator: {
|
|
3485
|
-
line: ["[&:not(:last-child)]:border-b", "border-neutral-200"],
|
|
3486
|
-
none: "",
|
|
3487
|
-
},
|
|
3488
|
-
},
|
|
3489
|
-
defaultVariants: {
|
|
3490
|
-
separator: "none",
|
|
3491
|
-
},
|
|
3492
|
-
});
|
|
3493
|
-
|
|
3494
3492
|
/**
|
|
3495
3493
|
*
|
|
3496
3494
|
*/
|
|
@@ -3575,9 +3573,9 @@ const ListLoadingIndicator = ({ type, hasThumbnail, thumbnailShape, hasDescripti
|
|
|
3575
3573
|
* );
|
|
3576
3574
|
* ```
|
|
3577
3575
|
*/
|
|
3578
|
-
const List = ({ children, className, dataTestId,
|
|
3576
|
+
const List = ({ children, className, dataTestId,
|
|
3579
3577
|
// UseListResult properties
|
|
3580
|
-
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, scrollOffset,
|
|
3578
|
+
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, scrollOffset, separator, topSeparatorOnScroll,
|
|
3581
3579
|
// Unused but part of UseListResult interface
|
|
3582
3580
|
getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }) => {
|
|
3583
3581
|
return (jsx("div", { className: cvaListContainer({
|
|
@@ -3586,22 +3584,18 @@ getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset:
|
|
|
3586
3584
|
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref: containerRef, children: jsx("ul", { className: cvaList(), ref: listRef, children: rows.map(row => {
|
|
3587
3585
|
// Generate list item props with separator styling
|
|
3588
3586
|
const listItemProps = getListItemProps(row, {
|
|
3589
|
-
className: cvaListItem({ separator }),
|
|
3587
|
+
className: cvaListItem$1({ separator }),
|
|
3590
3588
|
});
|
|
3591
3589
|
const key = row.virtualRow.key;
|
|
3592
3590
|
// Render loading row
|
|
3593
3591
|
if (row.type === "loader") {
|
|
3594
|
-
const loadingConfig = loadingIndicator ?? {
|
|
3595
|
-
type: "skeleton",
|
|
3596
|
-
...DEFAULT_SKELETON_LIST_ITEM_PROPS,
|
|
3597
|
-
};
|
|
3598
3592
|
// Use the total data count from useList, not visible rows (which are virtualized)
|
|
3599
3593
|
const hasHeaderRow = !!header;
|
|
3600
3594
|
const dataStartIndex = hasHeaderRow ? 1 : 0;
|
|
3601
3595
|
const totalDataRows = dataStartIndex + count;
|
|
3602
3596
|
const loaderIndex = row.virtualRow.index - totalDataRows;
|
|
3603
3597
|
const shouldShowLoader = shouldShowLoaderAtIndex(loaderIndex);
|
|
3604
|
-
return (jsx("li", { ...listItemProps, children: shouldShowLoader ? jsx(ListLoadingIndicator, { ...
|
|
3598
|
+
return (jsx("li", { ...listItemProps, children: shouldShowLoader ? jsx(ListLoadingIndicator, { ...loadingIndicator }) : null }, key));
|
|
3605
3599
|
}
|
|
3606
3600
|
// Render header row
|
|
3607
3601
|
if (row.type === "header") {
|
|
@@ -3649,10 +3643,12 @@ const DEFAULT_LOADING_INDICATOR_CONFIG = {
|
|
|
3649
3643
|
* );
|
|
3650
3644
|
* ```
|
|
3651
3645
|
*/
|
|
3652
|
-
const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAULT_LOADING_INDICATOR_CONFIG, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, }) => {
|
|
3646
|
+
const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAULT_LOADING_INDICATOR_CONFIG, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, separator = "line", topSeparatorOnScroll = false, }) => {
|
|
3653
3647
|
const containerRef = useRef(null);
|
|
3654
3648
|
const listRef = useRef(null);
|
|
3655
3649
|
const rowRefsMap = useRef(new Map());
|
|
3650
|
+
// Resolve loading indicator once to avoid unnecessary re-renders
|
|
3651
|
+
const resolvedLoadingIndicator = useMemo(() => getResolvedLoadingIndicator(loadingIndicator), [loadingIndicator]);
|
|
3656
3652
|
// Calculate total count including header
|
|
3657
3653
|
const hasHeader = Boolean(header);
|
|
3658
3654
|
const dataStartIndex = hasHeader ? 1 : 0;
|
|
@@ -3662,7 +3658,7 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3662
3658
|
const getLoadingRowsCount = useCallback(() => {
|
|
3663
3659
|
if (pagination?.isLoading === false)
|
|
3664
3660
|
return 0;
|
|
3665
|
-
const { type: loadingIndicatorType } =
|
|
3661
|
+
const { type: loadingIndicatorType } = resolvedLoadingIndicator;
|
|
3666
3662
|
switch (loadingIndicatorType) {
|
|
3667
3663
|
case "none":
|
|
3668
3664
|
return 0;
|
|
@@ -3671,20 +3667,20 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3671
3667
|
case "custom":
|
|
3672
3668
|
case "skeleton": {
|
|
3673
3669
|
const isInitialLoading = !pagination?.pageInfo;
|
|
3674
|
-
const initialCount =
|
|
3675
|
-
const scrollCount =
|
|
3670
|
+
const initialCount = resolvedLoadingIndicator.initialLoadingCount ?? 10;
|
|
3671
|
+
const scrollCount = resolvedLoadingIndicator.scrollLoadingCount ?? 3;
|
|
3676
3672
|
return isInitialLoading ? initialCount : scrollCount;
|
|
3677
3673
|
}
|
|
3678
3674
|
default: {
|
|
3679
3675
|
throw new Error(`${loadingIndicatorType} is not known`);
|
|
3680
3676
|
}
|
|
3681
3677
|
}
|
|
3682
|
-
}, [
|
|
3678
|
+
}, [resolvedLoadingIndicator, pagination?.isLoading, pagination?.pageInfo]);
|
|
3683
3679
|
// Helper to determine if a specific loader index should be shown
|
|
3684
3680
|
const shouldShowLoaderAtIndex = useCallback((loaderIndex) => {
|
|
3685
3681
|
if (pagination?.isLoading === false)
|
|
3686
3682
|
return false;
|
|
3687
|
-
const { type: loadingIndicatorType } =
|
|
3683
|
+
const { type: loadingIndicatorType } = resolvedLoadingIndicator;
|
|
3688
3684
|
let result;
|
|
3689
3685
|
switch (loadingIndicatorType) {
|
|
3690
3686
|
case "none":
|
|
@@ -3696,8 +3692,8 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3696
3692
|
case "custom":
|
|
3697
3693
|
case "skeleton": {
|
|
3698
3694
|
const isInitialLoading = !pagination?.pageInfo;
|
|
3699
|
-
const initialCount =
|
|
3700
|
-
const scrollCount =
|
|
3695
|
+
const initialCount = resolvedLoadingIndicator.initialLoadingCount ?? 10;
|
|
3696
|
+
const scrollCount = resolvedLoadingIndicator.scrollLoadingCount ?? 3;
|
|
3701
3697
|
const maxCount = isInitialLoading ? initialCount : scrollCount;
|
|
3702
3698
|
result = loaderIndex < maxCount;
|
|
3703
3699
|
break;
|
|
@@ -3707,7 +3703,7 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3707
3703
|
}
|
|
3708
3704
|
}
|
|
3709
3705
|
return result;
|
|
3710
|
-
}, [
|
|
3706
|
+
}, [resolvedLoadingIndicator, pagination?.isLoading, pagination?.pageInfo]);
|
|
3711
3707
|
const totalRowCount = useMemo(() => {
|
|
3712
3708
|
// Only add the exact number of loading rows we want to show
|
|
3713
3709
|
const loadingRows = pagination?.isLoading === true ? getLoadingRowsCount() : 0;
|
|
@@ -3831,11 +3827,19 @@ const useList = ({ count, pagination, header, getItem, loadingIndicator = DEFAUL
|
|
|
3831
3827
|
rows,
|
|
3832
3828
|
getListItemProps,
|
|
3833
3829
|
header,
|
|
3834
|
-
loadingIndicator,
|
|
3830
|
+
loadingIndicator: resolvedLoadingIndicator,
|
|
3835
3831
|
shouldShowLoaderAtIndex,
|
|
3836
3832
|
count,
|
|
3833
|
+
separator,
|
|
3834
|
+
topSeparatorOnScroll,
|
|
3837
3835
|
};
|
|
3838
3836
|
};
|
|
3837
|
+
const getResolvedLoadingIndicator = (loadingIndicator) => {
|
|
3838
|
+
if (typeof loadingIndicator === "function") {
|
|
3839
|
+
return loadingIndicator(DEFAULT_LOADING_INDICATOR_CONFIG);
|
|
3840
|
+
}
|
|
3841
|
+
return loadingIndicator;
|
|
3842
|
+
};
|
|
3839
3843
|
|
|
3840
3844
|
// Height constants (in pixels) - based on ListItem.variants.ts styling
|
|
3841
3845
|
const MIN_ITEM_HEIGHT = 56; // min-h-14 = 56px (minimum height for ListItem)
|
|
@@ -3953,7 +3957,7 @@ const cvaInteractableItem = cvaMerge("", {
|
|
|
3953
3957
|
* @returns {Element} ListItem component
|
|
3954
3958
|
*/
|
|
3955
3959
|
const ListItem = ({ className, dataTestId, onClick, details, title, description, meta, thumbnail, thumbnailColor = "info-600", thumbnailBackground = "info-100", ...rest }) => {
|
|
3956
|
-
const baseClass = cvaListItem
|
|
3960
|
+
const baseClass = cvaListItem({ className });
|
|
3957
3961
|
const interactableItemClass = onClick ? twMerge(baseClass, cvaInteractableItem({ cursor: "pointer" })) : baseClass;
|
|
3958
3962
|
return (jsxs("li", { className: interactableItemClass, "data-testid": dataTestId, onClick: onClick, ...rest, children: [jsxs("div", { className: cvaMainInformationClass({ hasThumbnail: !!thumbnail }), children: [thumbnail ? (jsx("div", { className: cvaThumbnailContainer({
|
|
3959
3963
|
className: `text-${thumbnailColor} bg-${thumbnailBackground}`,
|
|
@@ -5147,4 +5151,4 @@ const cvaClickable = cvaMerge([
|
|
|
5147
5151
|
},
|
|
5148
5152
|
});
|
|
5149
5153
|
|
|
5150
|
-
export { ActionRenderer, Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, DetailsList, EmptyState, EmptyValue, ExternalLink, Heading, Highlight, HorizontalOverflowScroller, Icon, IconButton, Indicator, KPI, KPICard, List, ListItem, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, PageHeaderKpiMetrics, PageHeaderSecondaryActions, PageHeaderTitle, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Portal, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, ToggleGroup, Tooltip, ValueBar, ZStack, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaContainerStyles, cvaIconButton, cvaImgStyles, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaList, cvaListContainer, cvaListItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, cvaPageHeader, cvaPageHeaderContainer, cvaPageHeaderHeading, cvaToggleGroup, cvaToggleGroupWithSlidingBackground, cvaToggleItem, cvaToggleItemContent, cvaToggleItemText, cvaZStackContainer, cvaZStackItem, defaultPageSize, docs, getDevicePixelRatio, getResponsiveRandomWidthPercentage, getValueBarColorByValue, iconColorNames, iconPalette, noPagination, useClickOutside, useContainerBreakpoints, useContinuousTimeout, useDebounce, useDevicePixelRatio, useElevatedReducer, useElevatedState, useGeometry, useHover, useInfiniteScroll, useIsFirstRender, useIsFullscreen, useIsTextTruncated, useList, useListItemHeight, useModifierKey, useOverflowItems, usePopoverContext, usePrompt, useRelayPagination, useResize, useScrollDetection, useSelfUpdatingRef, useStable, useTimeout, useViewportBreakpoints, useWatch, useWindowActivity };
|
|
5154
|
+
export { ActionRenderer, Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, DetailsList, EmptyState, EmptyValue, ExternalLink, Heading, Highlight, HorizontalOverflowScroller, Icon, IconButton, Indicator, KPI, KPICard, List, ListItem, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, PageHeaderKpiMetrics, PageHeaderSecondaryActions, PageHeaderTitle, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Portal, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, ToggleGroup, Tooltip, ValueBar, ZStack, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaContainerStyles, cvaIconButton, cvaImgStyles, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaList, cvaListContainer, cvaListItem$1 as cvaListItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, cvaPageHeader, cvaPageHeaderContainer, cvaPageHeaderHeading, cvaToggleGroup, cvaToggleGroupWithSlidingBackground, cvaToggleItem, cvaToggleItemContent, cvaToggleItemText, cvaZStackContainer, cvaZStackItem, defaultPageSize, docs, getDevicePixelRatio, getResponsiveRandomWidthPercentage, getValueBarColorByValue, iconColorNames, iconPalette, noPagination, useClickOutside, useContainerBreakpoints, useContinuousTimeout, useDebounce, useDevicePixelRatio, useElevatedReducer, useElevatedState, useGeometry, useHover, useInfiniteScroll, useIsFirstRender, useIsFullscreen, useIsTextTruncated, useList, useListItemHeight, useModifierKey, useOverflowItems, usePopoverContext, usePrompt, useRelayPagination, useResize, useScrollDetection, useSelfUpdatingRef, useStable, useTimeout, useViewportBreakpoints, useWatch, useWindowActivity };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.24",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
"@floating-ui/react": "^0.26.25",
|
|
17
17
|
"string-ts": "^2.0.0",
|
|
18
18
|
"tailwind-merge": "^2.0.0",
|
|
19
|
-
"@trackunit/ui-design-tokens": "1.7.
|
|
20
|
-
"@trackunit/css-class-variance-utilities": "1.7.
|
|
21
|
-
"@trackunit/shared-utils": "1.9.
|
|
22
|
-
"@trackunit/ui-icons": "1.7.
|
|
23
|
-
"@trackunit/react-test-setup": "1.4.
|
|
19
|
+
"@trackunit/ui-design-tokens": "1.7.15",
|
|
20
|
+
"@trackunit/css-class-variance-utilities": "1.7.14",
|
|
21
|
+
"@trackunit/shared-utils": "1.9.14",
|
|
22
|
+
"@trackunit/ui-icons": "1.7.16",
|
|
23
|
+
"@trackunit/react-test-setup": "1.4.14",
|
|
24
24
|
"@tanstack/react-router": "1.114.29",
|
|
25
25
|
"es-toolkit": "^1.39.10",
|
|
26
26
|
"@tanstack/react-virtual": "3.13.12"
|
|
@@ -172,18 +172,6 @@ export declare const iconPalette: {
|
|
|
172
172
|
readonly 800: "30 64 175";
|
|
173
173
|
readonly 900: "30 58 138";
|
|
174
174
|
};
|
|
175
|
-
SECONDARY: {
|
|
176
|
-
readonly 50: "248 250 252";
|
|
177
|
-
readonly 100: "241 245 249";
|
|
178
|
-
readonly 200: "226 232 240";
|
|
179
|
-
readonly 300: "203 213 225";
|
|
180
|
-
readonly 400: "148 163 184";
|
|
181
|
-
readonly 500: "100 116 139";
|
|
182
|
-
readonly 600: "71 85 105";
|
|
183
|
-
readonly 700: "51 65 85";
|
|
184
|
-
readonly 800: "30 41 59";
|
|
185
|
-
readonly 900: "15 23 42";
|
|
186
|
-
};
|
|
187
175
|
NEUTRAL: {
|
|
188
176
|
readonly 50: "249 250 251";
|
|
189
177
|
readonly 100: "243 244 246";
|
|
@@ -251,7 +239,7 @@ export declare const iconPalette: {
|
|
|
251
239
|
readonly 900: "127 29 29";
|
|
252
240
|
};
|
|
253
241
|
};
|
|
254
|
-
export declare const iconColorNames: ("info" | "success" | "warning" | "danger" | "primary" | "
|
|
242
|
+
export declare const iconColorNames: ("info" | "success" | "warning" | "danger" | "primary" | "neutral" | "black" | "white" | "good" | "low" | "critical" | "working" | "idle" | "stopped" | "unknown" | "moving" | "active" | "excessive_usage" | "unused" | "utilized" | "heavily_utilized" | "unknown_utilization" | "site_area" | "site_classic_poi" | "site_classic_zone" | "site_depot" | "site_work_place" | "site_construction_site" | "site_unknown" | "on_rent" | "returned" | "available" | "pickup_ready" | "transfer" | "in_repair" | "other_rental_status")[];
|
|
255
243
|
type IconPropsSmall = {
|
|
256
244
|
size?: "small";
|
|
257
245
|
type?: "solid";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const cvaIcon: (props?: ({
|
|
2
|
-
color?: "default" | "primary" | "
|
|
2
|
+
color?: "default" | "primary" | "neutral" | "info" | "success" | "warning" | "danger" | "good" | "low" | "critical" | "working" | "idle" | "moving" | "active" | "excessive_usage" | "stopped" | "unknown" | "black" | "white" | "unused" | "utilized" | "heavily_utilized" | "unknown_utilization" | "site_area" | "site_classic_poi" | "site_classic_zone" | "site_depot" | "site_work_place" | "site_construction_site" | "site_unknown" | "on_rent" | "returned" | "available" | "pickup_ready" | "transfer" | "in_repair" | "other_rental_status" | null | undefined;
|
|
3
3
|
size?: "small" | "medium" | "large" | null | undefined;
|
|
4
4
|
fontSize?: boolean | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { VariantProps } from "@trackunit/css-class-variance-utilities";
|
|
2
1
|
import { ReactElement } from "react";
|
|
3
2
|
import { CommonProps } from "../../common/CommonProps";
|
|
4
|
-
import { cvaListItem } from "./List.variants";
|
|
5
3
|
import { UseListResult, VirtualizationListItemProps } from "./useList";
|
|
6
|
-
type Separator = NonNullable<VariantProps<typeof cvaListItem>["separator"]>;
|
|
7
4
|
export type { VirtualizationListItemProps } from "./useList";
|
|
8
5
|
export interface ListProps<TItem = unknown> extends CommonProps, UseListResult<TItem> {
|
|
9
6
|
/**
|
|
@@ -26,14 +23,6 @@ export interface ListProps<TItem = unknown> extends CommonProps, UseListResult<T
|
|
|
26
23
|
item: TItem | undefined;
|
|
27
24
|
index: number;
|
|
28
25
|
}) => ReactElement | null;
|
|
29
|
-
/**
|
|
30
|
-
* Separator style between list items.
|
|
31
|
-
*/
|
|
32
|
-
separator?: Separator;
|
|
33
|
-
/**
|
|
34
|
-
* Show a top separator when the list is scrolled.
|
|
35
|
-
*/
|
|
36
|
-
topSeparatorOnScroll?: boolean;
|
|
37
26
|
}
|
|
38
27
|
/**
|
|
39
28
|
* A performant virtualized list component with infinite scrolling support.
|
|
@@ -100,4 +89,4 @@ export interface ListProps<TItem = unknown> extends CommonProps, UseListResult<T
|
|
|
100
89
|
* );
|
|
101
90
|
* ```
|
|
102
91
|
*/
|
|
103
|
-
export declare const List: <TItem = unknown>({ children, className, dataTestId,
|
|
92
|
+
export declare const List: <TItem = unknown>({ children, className, dataTestId, containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, scrollOffset, separator, topSeparatorOnScroll, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }: ListProps<TItem>) => ReactElement;
|
|
@@ -2,6 +2,9 @@ import type { VirtualItem, Virtualizer } from "@tanstack/react-virtual";
|
|
|
2
2
|
import { ReactElement, RefObject } from "react";
|
|
3
3
|
import { RelayPagination } from "../../hooks";
|
|
4
4
|
import { ListLoadingIndicatorProps } from "./ListLoadingIndicator";
|
|
5
|
+
declare const DEFAULT_LOADING_INDICATOR_CONFIG: Extract<ListLoadingIndicatorProps, {
|
|
6
|
+
type: "skeleton";
|
|
7
|
+
}>;
|
|
5
8
|
/**
|
|
6
9
|
* Props that must be spread onto list items for proper virtualization.
|
|
7
10
|
* These handle positioning, measurement, accessibility, and interaction.
|
|
@@ -12,7 +15,7 @@ export interface VirtualizationListItemProps {
|
|
|
12
15
|
/** CSS classes for list styling and separators */
|
|
13
16
|
className: string;
|
|
14
17
|
/** Element ref for virtualization measurement and setting positioning transform styles */
|
|
15
|
-
ref
|
|
18
|
+
ref: (node: HTMLLIElement | null) => void;
|
|
16
19
|
/** Click handler for row-level interactions */
|
|
17
20
|
onClick?: () => void;
|
|
18
21
|
/** Data attribute for accessibility and debugging */
|
|
@@ -45,7 +48,7 @@ export interface UseListOptions<TItem = unknown> {
|
|
|
45
48
|
/**
|
|
46
49
|
* Loading indicator configuration for pagination loading.
|
|
47
50
|
*/
|
|
48
|
-
loadingIndicator?: ListLoadingIndicatorProps;
|
|
51
|
+
loadingIndicator?: ListLoadingIndicatorProps | ((defaultLoadingIndicator: typeof DEFAULT_LOADING_INDICATOR_CONFIG) => ListLoadingIndicatorProps);
|
|
49
52
|
/**
|
|
50
53
|
* Callback fired when a row is clicked.
|
|
51
54
|
*/
|
|
@@ -97,6 +100,14 @@ export interface UseListOptions<TItem = unknown> {
|
|
|
97
100
|
* Higher values reduce blank areas during fast scrolling but increase memory usage.
|
|
98
101
|
*/
|
|
99
102
|
overscan?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Separator style between list items.
|
|
105
|
+
*/
|
|
106
|
+
separator?: "none" | "line";
|
|
107
|
+
/**
|
|
108
|
+
* Show a top separator when the list is scrolled.
|
|
109
|
+
*/
|
|
110
|
+
topSeparatorOnScroll?: boolean;
|
|
100
111
|
}
|
|
101
112
|
export type ListRowType = "header" | "data" | "loader";
|
|
102
113
|
export type ListRow<TItem> = {
|
|
@@ -130,11 +141,15 @@ export interface UseListResult<TItem> extends Pick<Virtualizer<HTMLDivElement, H
|
|
|
130
141
|
/** Header element (if provided) */
|
|
131
142
|
readonly header?: ReactElement;
|
|
132
143
|
/** Loading indicator configuration */
|
|
133
|
-
readonly loadingIndicator
|
|
144
|
+
readonly loadingIndicator: ListLoadingIndicatorProps;
|
|
134
145
|
/** Helper to determine if a specific loader index should be shown */
|
|
135
146
|
readonly shouldShowLoaderAtIndex: (loaderIndex: number) => boolean;
|
|
136
147
|
/** Total number of data items (for consistent calculations) */
|
|
137
148
|
readonly count: number;
|
|
149
|
+
/** Separator style between list items */
|
|
150
|
+
readonly separator: "none" | "line";
|
|
151
|
+
/** Show a top separator when the list is scrolled */
|
|
152
|
+
readonly topSeparatorOnScroll: boolean;
|
|
138
153
|
}
|
|
139
154
|
/**
|
|
140
155
|
* A hook for managing virtualized list state and behavior.
|
|
@@ -168,4 +183,5 @@ export interface UseListResult<TItem> extends Pick<Virtualizer<HTMLDivElement, H
|
|
|
168
183
|
* );
|
|
169
184
|
* ```
|
|
170
185
|
*/
|
|
171
|
-
export declare const useList: <TItem = unknown>({ count, pagination, header, getItem, loadingIndicator, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, }: UseListOptions<TItem>) => UseListResult<TItem>;
|
|
186
|
+
export declare const useList: <TItem = unknown>({ count, pagination, header, getItem, loadingIndicator, onRowClick, onChange, estimateItemSize, estimateHeaderSize, overscan, separator, topSeparatorOnScroll, }: UseListOptions<TItem>) => UseListResult<TItem>;
|
|
187
|
+
export {};
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { VariantProps } from "@trackunit/css-class-variance-utilities";
|
|
2
2
|
import { MappedOmit } from "@trackunit/shared-utils";
|
|
3
3
|
import { tailwindPalette, ThemeColors } from "@trackunit/ui-design-tokens";
|
|
4
|
-
import {
|
|
4
|
+
import { MouseEventHandler, ReactElement, ReactNode, Ref } from "react";
|
|
5
5
|
import { CommonProps } from "../../common/CommonProps";
|
|
6
6
|
import { cvaListItem } from "./ListItem.variants";
|
|
7
7
|
type ThemeColorShades = `${keyof (typeof tailwindPalette)[keyof typeof tailwindPalette]}`;
|
|
8
|
-
export
|
|
8
|
+
export type ListItemVirtualizationProps = {
|
|
9
|
+
/** @internal */
|
|
10
|
+
ref?: Ref<HTMLLIElement>;
|
|
11
|
+
/** @internal */
|
|
12
|
+
tabIndex?: number;
|
|
13
|
+
/** @internal */
|
|
14
|
+
"data-index"?: number;
|
|
15
|
+
/** @internal */
|
|
16
|
+
className?: string;
|
|
17
|
+
};
|
|
18
|
+
export interface ListItemProps extends CommonProps, ListItemVirtualizationProps, MappedOmit<VariantProps<typeof cvaListItem>, "className"> {
|
|
9
19
|
/**The main text line of the ListItem */
|
|
10
20
|
title: string | ReactElement<CommonProps>;
|
|
11
21
|
/**Optional description for the ListItem. Can be used for descriptions, metadata, or other important details. */
|
|
@@ -24,14 +34,6 @@ export interface ListItemProps extends CommonProps, MappedOmit<VariantProps<type
|
|
|
24
34
|
* If asset image is chosen as thumbnail, make the thumbnailBackground "white".
|
|
25
35
|
*/
|
|
26
36
|
thumbnailBackground?: `${ThemeColors}-${ThemeColorShades}` | `${ThemeColors}`;
|
|
27
|
-
/** @internal */
|
|
28
|
-
style?: CSSProperties;
|
|
29
|
-
/** @internal */
|
|
30
|
-
ref?: Ref<HTMLLIElement>;
|
|
31
|
-
/** @internal */
|
|
32
|
-
tabIndex?: number;
|
|
33
|
-
/** @internal */
|
|
34
|
-
"data-index"?: number;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* The ListItem is designed to present a concise set of items for quick scanning and navigation. It supports multiple content types and actions, and its flexible layout allows for customization based on the type of data being shown - assets, events, users, etc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const cvaTag: (props?: ({
|
|
2
2
|
size?: "small" | "medium" | null | undefined;
|
|
3
3
|
layout?: "default" | "containsDismiss" | "containsIcon" | null | undefined;
|
|
4
|
-
color?: "primary" | "
|
|
4
|
+
color?: "primary" | "neutral" | "black" | "white" | "info" | "success" | "warning" | "danger" | "good" | "low" | "critical" | "working" | "stopped" | "idle" | "unknown" | "moving" | "active" | "excessive_usage" | null | undefined;
|
|
5
5
|
border?: "default" | "none" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
7
7
|
export declare const cvaTagText: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|