@trackunit/react-components 1.22.27 → 1.23.2
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 +61 -49
- package/index.esm.js +62 -48
- package/package.json +6 -5
- package/src/common/PackageNameStoryComponent.d.ts +5 -2
- package/src/components/Breadcrumb/Breadcrumb.d.ts +1 -7
- package/src/components/Breadcrumb/BreadcrumbContainer.d.ts +8 -0
- package/src/components/Breadcrumb/utils/types.d.ts +2 -2
- package/src/components/GridAreas/GridAreas.d.ts +4 -2
- package/src/components/Highlight/Highlight.d.ts +4 -7
- package/src/components/List/List.d.ts +3 -2
- package/src/components/ListItem/ListItem.d.ts +4 -5
- package/src/components/Menu/MenuDivider/MenuDivider.d.ts +4 -2
- package/src/components/PageHeader/components/ActionRenderer.d.ts +25 -0
- package/src/components/PageHeader/components/PageHeaderSecondaryActions.d.ts +9 -23
- package/src/components/Portal/Portal.d.ts +5 -2
- package/src/components/Sheet/sheet-types.d.ts +4 -7
- package/src/components/Tabs/Tab.d.ts +8 -7
- package/src/components/Tabs/TabContent.d.ts +3 -1
- package/src/components/Tabs/TabList.d.ts +3 -9
- package/src/components/Tabs/Tabs.d.ts +3 -9
- package/src/components/Tag/Tag.d.ts +4 -7
- package/src/components/ValueBar/SegmentedValueBar.d.ts +3 -2
- package/src/components/buttons/Button/Button.d.ts +3 -6
- package/src/components/buttons/IconButton/IconButton.d.ts +3 -6
- package/src/components/buttons/StarButton/StarButton.d.ts +4 -2
package/index.cjs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var tailwindMerge = require('tailwind-merge');
|
|
4
5
|
var sharedUtils = require('@trackunit/shared-utils');
|
|
5
6
|
var react = require('react');
|
|
6
7
|
var uiDesignTokens = require('@trackunit/ui-design-tokens');
|
|
@@ -15,7 +16,6 @@ var reactSlot = require('@radix-ui/react-slot');
|
|
|
15
16
|
var reactRouter = require('@tanstack/react-router');
|
|
16
17
|
var esToolkit = require('es-toolkit');
|
|
17
18
|
var react$1 = require('@floating-ui/react');
|
|
18
|
-
var tailwindMerge = require('tailwind-merge');
|
|
19
19
|
var reactVirtual = require('@tanstack/react-virtual');
|
|
20
20
|
var reactHelmetAsync = require('react-helmet-async');
|
|
21
21
|
var reactTabs = require('@radix-ui/react-tabs');
|
|
@@ -359,7 +359,7 @@ const buildLibraryHref = (slug) => {
|
|
|
359
359
|
* A component used to display the package name and version in the Storybook docs.
|
|
360
360
|
* The package-name tag links to the matching section on the "Libraries" overview page.
|
|
361
361
|
*/
|
|
362
|
-
const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
362
|
+
const PackageNameStoryComponent = ({ packageJSON, className, "data-testid": dataTestId, style, ref, }) => {
|
|
363
363
|
const name = packageJSON?.name;
|
|
364
364
|
const slug = name ? toLibrarySlug(name) : undefined;
|
|
365
365
|
const href = slug ? buildLibraryHref(slug) : undefined;
|
|
@@ -373,7 +373,7 @@ const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
|
373
373
|
if (top)
|
|
374
374
|
top.location.href = href;
|
|
375
375
|
};
|
|
376
|
-
return (jsxRuntime.jsxs("div", { className: "flex gap-2", children: [href ? (jsxRuntime.jsx("a", { "aria-label": `Learn more about ${name}`, className: "no-underline", href: href, onClick: onClick, target: "_top", title: `Learn more about ${name}`, children: jsxRuntime.jsx(Tag, { color: "neutral", children: name }) })) : (jsxRuntime.jsx(Tag, { color: "neutral", children: name })), packageJSON?.version ? jsxRuntime.jsxs(Tag, { color: "neutral", children: ["v", packageJSON.version] }) : null] }));
|
|
376
|
+
return (jsxRuntime.jsxs("div", { className: tailwindMerge.twMerge("flex gap-2", className), "data-testid": dataTestId, ref: ref, style: style, children: [href ? (jsxRuntime.jsx("a", { "aria-label": `Learn more about ${name}`, className: "no-underline", href: href, onClick: onClick, target: "_top", title: `Learn more about ${name}`, children: jsxRuntime.jsx(Tag, { color: "neutral", children: name }) })) : (jsxRuntime.jsx(Tag, { color: "neutral", children: name })), packageJSON?.version ? jsxRuntime.jsxs(Tag, { color: "neutral", children: ["v", packageJSON.version] }) : null] }));
|
|
377
377
|
};
|
|
378
378
|
|
|
379
379
|
const docs = {
|
|
@@ -1348,6 +1348,19 @@ const Badge = ({ color = "primary", size = "default", compact = false, className
|
|
|
1348
1348
|
return (jsxRuntime.jsx("span", { className: cvaBadge({ color, size, className, compact, isSingleChar }), "data-testid": dataTestId, ref: ref, style: style, children: compact ? null : displayedCount }));
|
|
1349
1349
|
};
|
|
1350
1350
|
|
|
1351
|
+
const cvaBreadcrumb = cssClassVarianceUtilities.cvaMerge(["my-4", "flex", "place-items-center"]);
|
|
1352
|
+
const cvaBreadcrumbItem = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"]);
|
|
1353
|
+
const cvaBreadcrumbForLargeScreen = cssClassVarianceUtilities.cvaMerge(["flex", "flex-nowrap", "items-center"]);
|
|
1354
|
+
const cvaBreadcrumbForMediumScreen = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"], {
|
|
1355
|
+
variants: {
|
|
1356
|
+
expanded: {
|
|
1357
|
+
true: "flex-wrap",
|
|
1358
|
+
false: "flex-nowrap",
|
|
1359
|
+
},
|
|
1360
|
+
},
|
|
1361
|
+
defaultVariants: { expanded: false },
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1351
1364
|
/**
|
|
1352
1365
|
* Maps size keys to their corresponding state property names.
|
|
1353
1366
|
*/
|
|
@@ -1445,19 +1458,6 @@ const useViewportBreakpoints = (options = {}) => {
|
|
|
1445
1458
|
return viewportSize;
|
|
1446
1459
|
};
|
|
1447
1460
|
|
|
1448
|
-
const cvaBreadcrumb = cssClassVarianceUtilities.cvaMerge(["my-4", "flex", "place-items-center"]);
|
|
1449
|
-
const cvaBreadcrumbItem = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"]);
|
|
1450
|
-
const cvaBreadcrumbForLargeScreen = cssClassVarianceUtilities.cvaMerge(["flex", "flex-nowrap", "items-center"]);
|
|
1451
|
-
const cvaBreadcrumbForMediumScreen = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"], {
|
|
1452
|
-
variants: {
|
|
1453
|
-
expanded: {
|
|
1454
|
-
true: "flex-wrap",
|
|
1455
|
-
false: "flex-nowrap",
|
|
1456
|
-
},
|
|
1457
|
-
},
|
|
1458
|
-
defaultVariants: { expanded: false },
|
|
1459
|
-
});
|
|
1460
|
-
|
|
1461
1461
|
/**
|
|
1462
1462
|
* BreadcrumbItem is a helper component that renders the individual breadcrumb item.
|
|
1463
1463
|
*/
|
|
@@ -1500,6 +1500,23 @@ const BreadcrumbForSmallScreen = ({ "data-testid": dataTestId, breadcrumbItems,
|
|
|
1500
1500
|
return (jsxRuntime.jsx("div", { className: className, "data-testid": dataTestId, style: style, children: lastBreadcrumbItem.map((item, index) => (jsxRuntime.jsx(BreadcrumbItem, { "data-testid": `breadcrumbItem-${dataTestId}`, item: item }, `breadcrumbItem-${index}`))) }));
|
|
1501
1501
|
};
|
|
1502
1502
|
|
|
1503
|
+
/**
|
|
1504
|
+
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
1505
|
+
*
|
|
1506
|
+
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1507
|
+
*/
|
|
1508
|
+
const BreadcrumbContainer = ({ className, "data-testid": dataTestId, breadcrumbItems, style, ref, }) => {
|
|
1509
|
+
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1510
|
+
const sharedContainerProps = { className, "data-testid": dataTestId, ref, style };
|
|
1511
|
+
if (isMediumScreen) {
|
|
1512
|
+
return (jsxRuntime.jsx("div", { ...sharedContainerProps, children: jsxRuntime.jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` }) }));
|
|
1513
|
+
}
|
|
1514
|
+
if (isSmallScreen) {
|
|
1515
|
+
return (jsxRuntime.jsx("div", { ...sharedContainerProps, children: jsxRuntime.jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` }) }));
|
|
1516
|
+
}
|
|
1517
|
+
return (jsxRuntime.jsx("div", { ...sharedContainerProps, children: jsxRuntime.jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` }) }));
|
|
1518
|
+
};
|
|
1519
|
+
|
|
1503
1520
|
/**
|
|
1504
1521
|
* useBreadcrumbItemsToRender is a custom hook that takes an array of BreadcrumbItemProps and returns an array of React.ReactElement
|
|
1505
1522
|
*/
|
|
@@ -1553,21 +1570,6 @@ const Breadcrumb = ({ className, "data-testid": dataTestId, breadcrumbItems, onC
|
|
|
1553
1570
|
const breadCrumbItemsToJSX = useBreadcrumbItemsToRender(breadcrumbItems);
|
|
1554
1571
|
return (jsxRuntime.jsxs("div", { className: cvaBreadcrumb({ className }), "data-testid": dataTestId, ref: ref, style: style, children: [jsxRuntime.jsx(IconButton, { "data-testid": `backButton-${dataTestId}`, icon: jsxRuntime.jsx(Icon, { name: "ArrowLeft", size: "small" }), onClick: onClickBack, size: "small", variant: "ghost-neutral" }), jsxRuntime.jsx("div", { children: jsxRuntime.jsx(BreadcrumbContainer, { breadcrumbItems: breadCrumbItemsToJSX, "data-testid": dataTestId }) })] }));
|
|
1555
1572
|
};
|
|
1556
|
-
/**
|
|
1557
|
-
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
1558
|
-
*
|
|
1559
|
-
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1560
|
-
*/
|
|
1561
|
-
const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) => {
|
|
1562
|
-
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1563
|
-
if (isMediumScreen) {
|
|
1564
|
-
return jsxRuntime.jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` });
|
|
1565
|
-
}
|
|
1566
|
-
if (isSmallScreen) {
|
|
1567
|
-
return jsxRuntime.jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` });
|
|
1568
|
-
}
|
|
1569
|
-
return jsxRuntime.jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` });
|
|
1570
|
-
};
|
|
1571
1573
|
|
|
1572
1574
|
/**
|
|
1573
1575
|
* StarButton renders a clickable star icon for toggling favorite/starred state.
|
|
@@ -1592,8 +1594,8 @@ const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) =>
|
|
|
1592
1594
|
* @param {StarButtonProps} props - The props for the StarButton component
|
|
1593
1595
|
* @returns {ReactElement} StarButton component
|
|
1594
1596
|
*/
|
|
1595
|
-
const StarButton = ({ starred, onClick, ref }) => {
|
|
1596
|
-
return (jsxRuntime.jsx("div", { "data-
|
|
1597
|
+
const StarButton = ({ starred, onClick, className, "data-testid": dataTestId, style, ref, }) => {
|
|
1598
|
+
return (jsxRuntime.jsx("div", { className: className, "data-testid": dataTestId ?? "starred-filter", onClick: onClick, ref: ref, style: style, children: jsxRuntime.jsx(Icon, { color: starred ? "primary" : "neutral", name: "Star", size: "medium" }) }));
|
|
1597
1599
|
};
|
|
1598
1600
|
|
|
1599
1601
|
const cvaCard = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -3685,9 +3687,10 @@ function createGrid() {
|
|
|
3685
3687
|
* }
|
|
3686
3688
|
* ```
|
|
3687
3689
|
*/
|
|
3688
|
-
function GridAreas({ slots, css, containerProps, validationRef, className, style, children, asChild = false, }) {
|
|
3690
|
+
function GridAreas({ slots, css, containerProps, validationRef, className, "data-testid": dataTestId, ref, style, children, asChild = false, }) {
|
|
3689
3691
|
const Comp = asChild ? reactSlot.Slot : "div";
|
|
3690
|
-
|
|
3692
|
+
const mergedRef = useMergeRefs([validationRef, ref]);
|
|
3693
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("style", { children: css }), jsxRuntime.jsx(Comp, { ...containerProps, className: tailwindMerge.twMerge("@container grid", className), "data-testid": dataTestId, ref: mergedRef, style: style, children: children(slots) })] }));
|
|
3691
3694
|
}
|
|
3692
3695
|
|
|
3693
3696
|
/**
|
|
@@ -5666,15 +5669,16 @@ const ListLoadingIndicator = ({ type, hasThumbnail, thumbnailShape, hasDescripti
|
|
|
5666
5669
|
* );
|
|
5667
5670
|
* ```
|
|
5668
5671
|
*/
|
|
5669
|
-
const List = ({ children, className, "data-testid": dataTestId, style,
|
|
5672
|
+
const List = ({ children, className, "data-testid": dataTestId, style, ref,
|
|
5670
5673
|
// UseListResult properties
|
|
5671
5674
|
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, separator, topSeparatorOnScroll, isAtTop, contentFillsContainer,
|
|
5672
5675
|
// Unused but part of UseListResult interface (can be used from parent)
|
|
5673
5676
|
scrollOffset: _scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }) => {
|
|
5677
|
+
const mergedContainerRef = useMergeRefs([containerRef, ref]);
|
|
5674
5678
|
return (jsxRuntime.jsx("div", { className: cvaListContainer({
|
|
5675
5679
|
withTopSeparator: topSeparatorOnScroll && !isAtTop,
|
|
5676
5680
|
className,
|
|
5677
|
-
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref:
|
|
5681
|
+
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref: mergedContainerRef, style: style, children: jsxRuntime.jsx("ul", { className: cvaList(), ref: listRef, children: rows.map(row => {
|
|
5678
5682
|
// Generate list item props with clean separator styling
|
|
5679
5683
|
const listItemProps = getListItemProps(row, {
|
|
5680
5684
|
className: cvaListItem$1({
|
|
@@ -6216,8 +6220,8 @@ const cvaMenuListItem = cssClassVarianceUtilities.cvaMerge("max-w-full");
|
|
|
6216
6220
|
* ```
|
|
6217
6221
|
* @returns {ReactElement} MenuDivider component
|
|
6218
6222
|
*/
|
|
6219
|
-
const MenuDivider = ({ style }) => {
|
|
6220
|
-
return jsxRuntime.jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider", style: style });
|
|
6223
|
+
const MenuDivider = ({ className, style, "data-testid": dataTestId, ref }) => {
|
|
6224
|
+
return (jsxRuntime.jsx("div", { className: cvaMenuListDivider({ className }), "data-testid": dataTestId ?? "menu-divider", ref: ref, style: style }));
|
|
6221
6225
|
};
|
|
6222
6226
|
|
|
6223
6227
|
/**
|
|
@@ -6883,6 +6887,7 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
6883
6887
|
// Finally, wrap with Link if `to` is provided
|
|
6884
6888
|
return to !== undefined && to !== "" ? (jsxRuntime.jsx(reactRouter.Link, { target: target, to: to, children: wrappedWithTooltip })) : (wrappedWithTooltip);
|
|
6885
6889
|
}
|
|
6890
|
+
|
|
6886
6891
|
/**
|
|
6887
6892
|
* The PageHeaderSecondaryActions component is used to render the secondary actions in the PageHeader component.
|
|
6888
6893
|
*
|
|
@@ -6890,9 +6895,13 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
6890
6895
|
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
6891
6896
|
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
6892
6897
|
* @param {boolean} [props.groupActions] - Whether to group actions in a More Menu regardless of action count
|
|
6898
|
+
* @param {string} [props.className] - A custom class name for the action container
|
|
6899
|
+
* @param {string} [props."data-testid"] - An ID used to locate the container in tests
|
|
6900
|
+
* @param {object} [props.style] - Inline styles for the action container
|
|
6901
|
+
* @param {unknown} [props.ref] - Ref for the action container element
|
|
6893
6902
|
* @returns {ReactElement | null} PageHeaderSecondaryActions component
|
|
6894
6903
|
*/
|
|
6895
|
-
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, }) => {
|
|
6904
|
+
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, className, "data-testid": dataTestId, style, ref, }) => {
|
|
6896
6905
|
const enabledActions = react.useMemo(() => actions.filter(action => action.hidden === false || action.hidden === undefined), [actions]);
|
|
6897
6906
|
// If there are no enabled actions, don't render anything
|
|
6898
6907
|
if (enabledActions.length === 0) {
|
|
@@ -6909,10 +6918,10 @@ const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupAc
|
|
|
6909
6918
|
return [danger, [...others, action]];
|
|
6910
6919
|
}
|
|
6911
6920
|
}, [[], []]);
|
|
6912
|
-
return (jsxRuntime.jsx(MoreMenu, { "data-testid": "secondary-actions-more-menu", iconButtonProps: { size: "small", variant: "secondary" }, children: close => (jsxRuntime.jsxs(MenuList, { className: "min-w-[160px]", children: [otherActions.map((action, index) => (jsxRuntime.jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`))), dangerActions.length > 0 ? jsxRuntime.jsx(MenuDivider, {}) : null, dangerActions.map((action, index) => (jsxRuntime.jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`)))] })) }));
|
|
6921
|
+
return (jsxRuntime.jsx("div", { className: className, "data-testid": dataTestId, ref: ref, style: style, children: jsxRuntime.jsx(MoreMenu, { "data-testid": "secondary-actions-more-menu", iconButtonProps: { size: "small", variant: "secondary" }, children: close => (jsxRuntime.jsxs(MenuList, { className: "min-w-[160px]", children: [otherActions.map((action, index) => (jsxRuntime.jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`))), dangerActions.length > 0 ? jsxRuntime.jsx(MenuDivider, {}) : null, dangerActions.map((action, index) => (jsxRuntime.jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`)))] })) }) }));
|
|
6913
6922
|
}
|
|
6914
6923
|
// Otherwise, render them inline as buttons
|
|
6915
|
-
return (jsxRuntime.jsx("div", { className: "flex flex-row items-center gap-2", children: enabledActions
|
|
6924
|
+
return (jsxRuntime.jsx("div", { className: tailwindMerge.twMerge("flex flex-row items-center gap-2", className), "data-testid": dataTestId, ref: ref, style: style, children: enabledActions
|
|
6916
6925
|
.toSorted((a, b) => {
|
|
6917
6926
|
if (a.variant === "secondary" && b.variant === "secondary-danger") {
|
|
6918
6927
|
return 1;
|
|
@@ -9900,6 +9909,10 @@ const cvaTab = cssClassVarianceUtilities.cvaMerge([
|
|
|
9900
9909
|
* ### When not to use
|
|
9901
9910
|
* Do not use Tab outside of a `TabList`/`Tabs` context. For standalone buttons, use `Button`.
|
|
9902
9911
|
*
|
|
9912
|
+
* ### `data-testid` and `asChild`
|
|
9913
|
+
* `data-testid` is applied to the rendered element. When `asChild` is used and the child already
|
|
9914
|
+
* defines its own `data-testid`, the child's value wins so consumers can label the actual DOM node.
|
|
9915
|
+
*
|
|
9903
9916
|
* @example Tab with icon and badge suffix
|
|
9904
9917
|
* ```tsx
|
|
9905
9918
|
* import { Tabs, TabList, Tab, TabContent, Badge } from "@trackunit/react-components";
|
|
@@ -9922,14 +9935,15 @@ const cvaTab = cssClassVarianceUtilities.cvaMerge([
|
|
|
9922
9935
|
*/
|
|
9923
9936
|
const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid": dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ref, ...rest }) => {
|
|
9924
9937
|
const renderContent = () => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [iconName !== undefined ? jsxRuntime.jsx(Icon, { name: iconName, size: "small" }) : null, react.isValidElement(children) ? children.props.children : children, suffix] }));
|
|
9925
|
-
const
|
|
9938
|
+
const sharedProps = {
|
|
9926
9939
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
9927
9940
|
...rest,
|
|
9928
9941
|
};
|
|
9929
9942
|
return (jsxRuntime.jsx(reactTabs.Trigger, { asChild: true, ref: ref, value: value, children: asChild && typeof children !== "string" ? (react.cloneElement(children, {
|
|
9930
|
-
...
|
|
9943
|
+
...sharedProps,
|
|
9944
|
+
"data-testid": children.props["data-testid"] ?? dataTestId,
|
|
9931
9945
|
children: renderContent(),
|
|
9932
|
-
})) : (jsxRuntime.jsx("button", { ...
|
|
9946
|
+
})) : (jsxRuntime.jsx("button", { ...sharedProps, "data-testid": dataTestId, children: renderContent() })) }));
|
|
9933
9947
|
};
|
|
9934
9948
|
|
|
9935
9949
|
/**
|
|
@@ -10373,13 +10387,13 @@ const getValueTextVariant = (size, sum, segments, total) => {
|
|
|
10373
10387
|
* SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
|
|
10374
10388
|
* Supports optional tooltips per segment, showing value and optionally a label.
|
|
10375
10389
|
*/
|
|
10376
|
-
const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, style, }) => {
|
|
10390
|
+
const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, ref, style, }) => {
|
|
10377
10391
|
const computedSegments = computeSegments(segments, total);
|
|
10378
10392
|
const sum = total > 0 ? computeSum(segments) : 0;
|
|
10379
10393
|
const valueText = formatValue(displayValue ?? sum, unit);
|
|
10380
10394
|
const canShowValue = showValue && size !== "extraSmall";
|
|
10381
10395
|
const valueTextClassName = cvaSegmentedValueBarText({ size: getValueTextVariant(size, sum, segments, total) });
|
|
10382
|
-
return (jsxRuntime.jsxs("span", { className: valueBarContainerClassName, "data-testid": dataTestId, style: style, children: [jsxRuntime.jsx("div", { "aria-label": valueText, className: cvaSegmentedValueBar({ className, size }), "data-testid": dataTestId ? `${dataTestId}-track` : undefined, children: computedSegments.map((segment, index) => {
|
|
10396
|
+
return (jsxRuntime.jsxs("span", { className: valueBarContainerClassName, "data-testid": dataTestId, ref: ref, style: style, children: [jsxRuntime.jsx("div", { "aria-label": valueText, className: cvaSegmentedValueBar({ className, size }), "data-testid": dataTestId ? `${dataTestId}-track` : undefined, children: computedSegments.map((segment, index) => {
|
|
10383
10397
|
const tooltipLabel = segment.label
|
|
10384
10398
|
? `${segment.label}: ${formatValue(segment.value, tooltipUnit ?? unit)}`
|
|
10385
10399
|
: formatValue(segment.value, tooltipUnit ?? unit);
|
|
@@ -12476,11 +12490,9 @@ const useWindowActivity = ({ onFocus, onBlur, skip = false } = { onBlur: undefin
|
|
|
12476
12490
|
return react.useMemo(() => ({ focused }), [focused]);
|
|
12477
12491
|
};
|
|
12478
12492
|
|
|
12479
|
-
exports.ActionRenderer = ActionRenderer;
|
|
12480
12493
|
exports.Alert = Alert;
|
|
12481
12494
|
exports.Badge = Badge;
|
|
12482
12495
|
exports.Breadcrumb = Breadcrumb;
|
|
12483
|
-
exports.BreadcrumbContainer = BreadcrumbContainer;
|
|
12484
12496
|
exports.Button = Button;
|
|
12485
12497
|
exports.Card = Card;
|
|
12486
12498
|
exports.CardBody = CardBody;
|
package/index.esm.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
2
3
|
import { objectKeys, uuidv4, parseTailwindArbitraryValue, objectEntries, nonNullable, objectValues, filterByMultiple } from '@trackunit/shared-utils';
|
|
3
4
|
import { useRef, useMemo, useEffect, useState, useLayoutEffect, useCallback, createElement, createContext, useContext, isValidElement, cloneElement, Fragment as Fragment$1, memo, forwardRef, useId, useReducer, Children } from 'react';
|
|
4
5
|
import { rentalStatusPalette, sitesPalette, utilizationPalette, activityPalette, criticalityPalette, generalPalette, intentPalette, themeScreenSizeAsNumber, themeContainerSize, color } from '@trackunit/ui-design-tokens';
|
|
@@ -13,7 +14,6 @@ import { Slot, Slottable } from '@radix-ui/react-slot';
|
|
|
13
14
|
import { Link, useBlocker, useNavigate, useLocation, useRouter, useSearch } from '@tanstack/react-router';
|
|
14
15
|
import { isEqual, omit } from 'es-toolkit';
|
|
15
16
|
import { useFloating, offset, flip, shift, size, autoUpdate, useClick, useDismiss, useHover as useHover$1, safePolygon, useRole, useInteractions, FloatingPortal, useMergeRefs as useMergeRefs$1, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
|
|
16
|
-
import { twMerge } from 'tailwind-merge';
|
|
17
17
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
18
18
|
import { HelmetProvider, Helmet } from 'react-helmet-async';
|
|
19
19
|
import { Trigger, Content as Content$1, List as List$1, Root } from '@radix-ui/react-tabs';
|
|
@@ -357,7 +357,7 @@ const buildLibraryHref = (slug) => {
|
|
|
357
357
|
* A component used to display the package name and version in the Storybook docs.
|
|
358
358
|
* The package-name tag links to the matching section on the "Libraries" overview page.
|
|
359
359
|
*/
|
|
360
|
-
const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
360
|
+
const PackageNameStoryComponent = ({ packageJSON, className, "data-testid": dataTestId, style, ref, }) => {
|
|
361
361
|
const name = packageJSON?.name;
|
|
362
362
|
const slug = name ? toLibrarySlug(name) : undefined;
|
|
363
363
|
const href = slug ? buildLibraryHref(slug) : undefined;
|
|
@@ -371,7 +371,7 @@ const PackageNameStoryComponent = ({ packageJSON }) => {
|
|
|
371
371
|
if (top)
|
|
372
372
|
top.location.href = href;
|
|
373
373
|
};
|
|
374
|
-
return (jsxs("div", { className: "flex gap-2", children: [href ? (jsx("a", { "aria-label": `Learn more about ${name}`, className: "no-underline", href: href, onClick: onClick, target: "_top", title: `Learn more about ${name}`, children: jsx(Tag, { color: "neutral", children: name }) })) : (jsx(Tag, { color: "neutral", children: name })), packageJSON?.version ? jsxs(Tag, { color: "neutral", children: ["v", packageJSON.version] }) : null] }));
|
|
374
|
+
return (jsxs("div", { className: twMerge("flex gap-2", className), "data-testid": dataTestId, ref: ref, style: style, children: [href ? (jsx("a", { "aria-label": `Learn more about ${name}`, className: "no-underline", href: href, onClick: onClick, target: "_top", title: `Learn more about ${name}`, children: jsx(Tag, { color: "neutral", children: name }) })) : (jsx(Tag, { color: "neutral", children: name })), packageJSON?.version ? jsxs(Tag, { color: "neutral", children: ["v", packageJSON.version] }) : null] }));
|
|
375
375
|
};
|
|
376
376
|
|
|
377
377
|
const docs = {
|
|
@@ -1346,6 +1346,19 @@ const Badge = ({ color = "primary", size = "default", compact = false, className
|
|
|
1346
1346
|
return (jsx("span", { className: cvaBadge({ color, size, className, compact, isSingleChar }), "data-testid": dataTestId, ref: ref, style: style, children: compact ? null : displayedCount }));
|
|
1347
1347
|
};
|
|
1348
1348
|
|
|
1349
|
+
const cvaBreadcrumb = cvaMerge(["my-4", "flex", "place-items-center"]);
|
|
1350
|
+
const cvaBreadcrumbItem = cvaMerge(["flex", "items-center"]);
|
|
1351
|
+
const cvaBreadcrumbForLargeScreen = cvaMerge(["flex", "flex-nowrap", "items-center"]);
|
|
1352
|
+
const cvaBreadcrumbForMediumScreen = cvaMerge(["flex", "items-center"], {
|
|
1353
|
+
variants: {
|
|
1354
|
+
expanded: {
|
|
1355
|
+
true: "flex-wrap",
|
|
1356
|
+
false: "flex-nowrap",
|
|
1357
|
+
},
|
|
1358
|
+
},
|
|
1359
|
+
defaultVariants: { expanded: false },
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1349
1362
|
/**
|
|
1350
1363
|
* Maps size keys to their corresponding state property names.
|
|
1351
1364
|
*/
|
|
@@ -1443,19 +1456,6 @@ const useViewportBreakpoints = (options = {}) => {
|
|
|
1443
1456
|
return viewportSize;
|
|
1444
1457
|
};
|
|
1445
1458
|
|
|
1446
|
-
const cvaBreadcrumb = cvaMerge(["my-4", "flex", "place-items-center"]);
|
|
1447
|
-
const cvaBreadcrumbItem = cvaMerge(["flex", "items-center"]);
|
|
1448
|
-
const cvaBreadcrumbForLargeScreen = cvaMerge(["flex", "flex-nowrap", "items-center"]);
|
|
1449
|
-
const cvaBreadcrumbForMediumScreen = cvaMerge(["flex", "items-center"], {
|
|
1450
|
-
variants: {
|
|
1451
|
-
expanded: {
|
|
1452
|
-
true: "flex-wrap",
|
|
1453
|
-
false: "flex-nowrap",
|
|
1454
|
-
},
|
|
1455
|
-
},
|
|
1456
|
-
defaultVariants: { expanded: false },
|
|
1457
|
-
});
|
|
1458
|
-
|
|
1459
1459
|
/**
|
|
1460
1460
|
* BreadcrumbItem is a helper component that renders the individual breadcrumb item.
|
|
1461
1461
|
*/
|
|
@@ -1498,6 +1498,23 @@ const BreadcrumbForSmallScreen = ({ "data-testid": dataTestId, breadcrumbItems,
|
|
|
1498
1498
|
return (jsx("div", { className: className, "data-testid": dataTestId, style: style, children: lastBreadcrumbItem.map((item, index) => (jsx(BreadcrumbItem, { "data-testid": `breadcrumbItem-${dataTestId}`, item: item }, `breadcrumbItem-${index}`))) }));
|
|
1499
1499
|
};
|
|
1500
1500
|
|
|
1501
|
+
/**
|
|
1502
|
+
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
1503
|
+
*
|
|
1504
|
+
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1505
|
+
*/
|
|
1506
|
+
const BreadcrumbContainer = ({ className, "data-testid": dataTestId, breadcrumbItems, style, ref, }) => {
|
|
1507
|
+
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1508
|
+
const sharedContainerProps = { className, "data-testid": dataTestId, ref, style };
|
|
1509
|
+
if (isMediumScreen) {
|
|
1510
|
+
return (jsx("div", { ...sharedContainerProps, children: jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` }) }));
|
|
1511
|
+
}
|
|
1512
|
+
if (isSmallScreen) {
|
|
1513
|
+
return (jsx("div", { ...sharedContainerProps, children: jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` }) }));
|
|
1514
|
+
}
|
|
1515
|
+
return (jsx("div", { ...sharedContainerProps, children: jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` }) }));
|
|
1516
|
+
};
|
|
1517
|
+
|
|
1501
1518
|
/**
|
|
1502
1519
|
* useBreadcrumbItemsToRender is a custom hook that takes an array of BreadcrumbItemProps and returns an array of React.ReactElement
|
|
1503
1520
|
*/
|
|
@@ -1551,21 +1568,6 @@ const Breadcrumb = ({ className, "data-testid": dataTestId, breadcrumbItems, onC
|
|
|
1551
1568
|
const breadCrumbItemsToJSX = useBreadcrumbItemsToRender(breadcrumbItems);
|
|
1552
1569
|
return (jsxs("div", { className: cvaBreadcrumb({ className }), "data-testid": dataTestId, ref: ref, style: style, children: [jsx(IconButton, { "data-testid": `backButton-${dataTestId}`, icon: jsx(Icon, { name: "ArrowLeft", size: "small" }), onClick: onClickBack, size: "small", variant: "ghost-neutral" }), jsx("div", { children: jsx(BreadcrumbContainer, { breadcrumbItems: breadCrumbItemsToJSX, "data-testid": dataTestId }) })] }));
|
|
1553
1570
|
};
|
|
1554
|
-
/**
|
|
1555
|
-
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
1556
|
-
*
|
|
1557
|
-
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1558
|
-
*/
|
|
1559
|
-
const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) => {
|
|
1560
|
-
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1561
|
-
if (isMediumScreen) {
|
|
1562
|
-
return jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` });
|
|
1563
|
-
}
|
|
1564
|
-
if (isSmallScreen) {
|
|
1565
|
-
return jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` });
|
|
1566
|
-
}
|
|
1567
|
-
return jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` });
|
|
1568
|
-
};
|
|
1569
1571
|
|
|
1570
1572
|
/**
|
|
1571
1573
|
* StarButton renders a clickable star icon for toggling favorite/starred state.
|
|
@@ -1590,8 +1592,8 @@ const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) =>
|
|
|
1590
1592
|
* @param {StarButtonProps} props - The props for the StarButton component
|
|
1591
1593
|
* @returns {ReactElement} StarButton component
|
|
1592
1594
|
*/
|
|
1593
|
-
const StarButton = ({ starred, onClick, ref }) => {
|
|
1594
|
-
return (jsx("div", { "data-
|
|
1595
|
+
const StarButton = ({ starred, onClick, className, "data-testid": dataTestId, style, ref, }) => {
|
|
1596
|
+
return (jsx("div", { className: className, "data-testid": dataTestId ?? "starred-filter", onClick: onClick, ref: ref, style: style, children: jsx(Icon, { color: starred ? "primary" : "neutral", name: "Star", size: "medium" }) }));
|
|
1595
1597
|
};
|
|
1596
1598
|
|
|
1597
1599
|
const cvaCard = cvaMerge([
|
|
@@ -3683,9 +3685,10 @@ function createGrid() {
|
|
|
3683
3685
|
* }
|
|
3684
3686
|
* ```
|
|
3685
3687
|
*/
|
|
3686
|
-
function GridAreas({ slots, css, containerProps, validationRef, className, style, children, asChild = false, }) {
|
|
3688
|
+
function GridAreas({ slots, css, containerProps, validationRef, className, "data-testid": dataTestId, ref, style, children, asChild = false, }) {
|
|
3687
3689
|
const Comp = asChild ? Slot : "div";
|
|
3688
|
-
|
|
3690
|
+
const mergedRef = useMergeRefs([validationRef, ref]);
|
|
3691
|
+
return (jsxs(Fragment, { children: [jsx("style", { children: css }), jsx(Comp, { ...containerProps, className: twMerge("@container grid", className), "data-testid": dataTestId, ref: mergedRef, style: style, children: children(slots) })] }));
|
|
3689
3692
|
}
|
|
3690
3693
|
|
|
3691
3694
|
/**
|
|
@@ -5664,15 +5667,16 @@ const ListLoadingIndicator = ({ type, hasThumbnail, thumbnailShape, hasDescripti
|
|
|
5664
5667
|
* );
|
|
5665
5668
|
* ```
|
|
5666
5669
|
*/
|
|
5667
|
-
const List = ({ children, className, "data-testid": dataTestId, style,
|
|
5670
|
+
const List = ({ children, className, "data-testid": dataTestId, style, ref,
|
|
5668
5671
|
// UseListResult properties
|
|
5669
5672
|
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, separator, topSeparatorOnScroll, isAtTop, contentFillsContainer,
|
|
5670
5673
|
// Unused but part of UseListResult interface (can be used from parent)
|
|
5671
5674
|
scrollOffset: _scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }) => {
|
|
5675
|
+
const mergedContainerRef = useMergeRefs([containerRef, ref]);
|
|
5672
5676
|
return (jsx("div", { className: cvaListContainer({
|
|
5673
5677
|
withTopSeparator: topSeparatorOnScroll && !isAtTop,
|
|
5674
5678
|
className,
|
|
5675
|
-
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref:
|
|
5679
|
+
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref: mergedContainerRef, style: style, children: jsx("ul", { className: cvaList(), ref: listRef, children: rows.map(row => {
|
|
5676
5680
|
// Generate list item props with clean separator styling
|
|
5677
5681
|
const listItemProps = getListItemProps(row, {
|
|
5678
5682
|
className: cvaListItem$1({
|
|
@@ -6214,8 +6218,8 @@ const cvaMenuListItem = cvaMerge("max-w-full");
|
|
|
6214
6218
|
* ```
|
|
6215
6219
|
* @returns {ReactElement} MenuDivider component
|
|
6216
6220
|
*/
|
|
6217
|
-
const MenuDivider = ({ style }) => {
|
|
6218
|
-
return jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider", style: style });
|
|
6221
|
+
const MenuDivider = ({ className, style, "data-testid": dataTestId, ref }) => {
|
|
6222
|
+
return (jsx("div", { className: cvaMenuListDivider({ className }), "data-testid": dataTestId ?? "menu-divider", ref: ref, style: style }));
|
|
6219
6223
|
};
|
|
6220
6224
|
|
|
6221
6225
|
/**
|
|
@@ -6881,6 +6885,7 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
6881
6885
|
// Finally, wrap with Link if `to` is provided
|
|
6882
6886
|
return to !== undefined && to !== "" ? (jsx(Link, { target: target, to: to, children: wrappedWithTooltip })) : (wrappedWithTooltip);
|
|
6883
6887
|
}
|
|
6888
|
+
|
|
6884
6889
|
/**
|
|
6885
6890
|
* The PageHeaderSecondaryActions component is used to render the secondary actions in the PageHeader component.
|
|
6886
6891
|
*
|
|
@@ -6888,9 +6893,13 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
6888
6893
|
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
6889
6894
|
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
6890
6895
|
* @param {boolean} [props.groupActions] - Whether to group actions in a More Menu regardless of action count
|
|
6896
|
+
* @param {string} [props.className] - A custom class name for the action container
|
|
6897
|
+
* @param {string} [props."data-testid"] - An ID used to locate the container in tests
|
|
6898
|
+
* @param {object} [props.style] - Inline styles for the action container
|
|
6899
|
+
* @param {unknown} [props.ref] - Ref for the action container element
|
|
6891
6900
|
* @returns {ReactElement | null} PageHeaderSecondaryActions component
|
|
6892
6901
|
*/
|
|
6893
|
-
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, }) => {
|
|
6902
|
+
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, className, "data-testid": dataTestId, style, ref, }) => {
|
|
6894
6903
|
const enabledActions = useMemo(() => actions.filter(action => action.hidden === false || action.hidden === undefined), [actions]);
|
|
6895
6904
|
// If there are no enabled actions, don't render anything
|
|
6896
6905
|
if (enabledActions.length === 0) {
|
|
@@ -6907,10 +6916,10 @@ const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupAc
|
|
|
6907
6916
|
return [danger, [...others, action]];
|
|
6908
6917
|
}
|
|
6909
6918
|
}, [[], []]);
|
|
6910
|
-
return (jsx(MoreMenu, { "data-testid": "secondary-actions-more-menu", iconButtonProps: { size: "small", variant: "secondary" }, children: close => (jsxs(MenuList, { className: "min-w-[160px]", children: [otherActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`))), dangerActions.length > 0 ? jsx(MenuDivider, {}) : null, dangerActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`)))] })) }));
|
|
6919
|
+
return (jsx("div", { className: className, "data-testid": dataTestId, ref: ref, style: style, children: jsx(MoreMenu, { "data-testid": "secondary-actions-more-menu", iconButtonProps: { size: "small", variant: "secondary" }, children: close => (jsxs(MenuList, { className: "min-w-[160px]", children: [otherActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`))), dangerActions.length > 0 ? jsx(MenuDivider, {}) : null, dangerActions.map((action, index) => (jsx(ActionRenderer, { action: action, externalOnClick: close, isMenuItem: true }, `${action.actionText}-${index}`)))] })) }) }));
|
|
6911
6920
|
}
|
|
6912
6921
|
// Otherwise, render them inline as buttons
|
|
6913
|
-
return (jsx("div", { className: "flex flex-row items-center gap-2", children: enabledActions
|
|
6922
|
+
return (jsx("div", { className: twMerge("flex flex-row items-center gap-2", className), "data-testid": dataTestId, ref: ref, style: style, children: enabledActions
|
|
6914
6923
|
.toSorted((a, b) => {
|
|
6915
6924
|
if (a.variant === "secondary" && b.variant === "secondary-danger") {
|
|
6916
6925
|
return 1;
|
|
@@ -9898,6 +9907,10 @@ const cvaTab = cvaMerge([
|
|
|
9898
9907
|
* ### When not to use
|
|
9899
9908
|
* Do not use Tab outside of a `TabList`/`Tabs` context. For standalone buttons, use `Button`.
|
|
9900
9909
|
*
|
|
9910
|
+
* ### `data-testid` and `asChild`
|
|
9911
|
+
* `data-testid` is applied to the rendered element. When `asChild` is used and the child already
|
|
9912
|
+
* defines its own `data-testid`, the child's value wins so consumers can label the actual DOM node.
|
|
9913
|
+
*
|
|
9901
9914
|
* @example Tab with icon and badge suffix
|
|
9902
9915
|
* ```tsx
|
|
9903
9916
|
* import { Tabs, TabList, Tab, TabContent, Badge } from "@trackunit/react-components";
|
|
@@ -9920,14 +9933,15 @@ const cvaTab = cvaMerge([
|
|
|
9920
9933
|
*/
|
|
9921
9934
|
const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid": dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ref, ...rest }) => {
|
|
9922
9935
|
const renderContent = () => (jsxs(Fragment, { children: [iconName !== undefined ? jsx(Icon, { name: iconName, size: "small" }) : null, isValidElement(children) ? children.props.children : children, suffix] }));
|
|
9923
|
-
const
|
|
9936
|
+
const sharedProps = {
|
|
9924
9937
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
9925
9938
|
...rest,
|
|
9926
9939
|
};
|
|
9927
9940
|
return (jsx(Trigger, { asChild: true, ref: ref, value: value, children: asChild && typeof children !== "string" ? (cloneElement(children, {
|
|
9928
|
-
...
|
|
9941
|
+
...sharedProps,
|
|
9942
|
+
"data-testid": children.props["data-testid"] ?? dataTestId,
|
|
9929
9943
|
children: renderContent(),
|
|
9930
|
-
})) : (jsx("button", { ...
|
|
9944
|
+
})) : (jsx("button", { ...sharedProps, "data-testid": dataTestId, children: renderContent() })) }));
|
|
9931
9945
|
};
|
|
9932
9946
|
|
|
9933
9947
|
/**
|
|
@@ -10371,13 +10385,13 @@ const getValueTextVariant = (size, sum, segments, total) => {
|
|
|
10371
10385
|
* SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
|
|
10372
10386
|
* Supports optional tooltips per segment, showing value and optionally a label.
|
|
10373
10387
|
*/
|
|
10374
|
-
const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, style, }) => {
|
|
10388
|
+
const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, ref, style, }) => {
|
|
10375
10389
|
const computedSegments = computeSegments(segments, total);
|
|
10376
10390
|
const sum = total > 0 ? computeSum(segments) : 0;
|
|
10377
10391
|
const valueText = formatValue(displayValue ?? sum, unit);
|
|
10378
10392
|
const canShowValue = showValue && size !== "extraSmall";
|
|
10379
10393
|
const valueTextClassName = cvaSegmentedValueBarText({ size: getValueTextVariant(size, sum, segments, total) });
|
|
10380
|
-
return (jsxs("span", { className: valueBarContainerClassName, "data-testid": dataTestId, style: style, children: [jsx("div", { "aria-label": valueText, className: cvaSegmentedValueBar({ className, size }), "data-testid": dataTestId ? `${dataTestId}-track` : undefined, children: computedSegments.map((segment, index) => {
|
|
10394
|
+
return (jsxs("span", { className: valueBarContainerClassName, "data-testid": dataTestId, ref: ref, style: style, children: [jsx("div", { "aria-label": valueText, className: cvaSegmentedValueBar({ className, size }), "data-testid": dataTestId ? `${dataTestId}-track` : undefined, children: computedSegments.map((segment, index) => {
|
|
10381
10395
|
const tooltipLabel = segment.label
|
|
10382
10396
|
? `${segment.label}: ${formatValue(segment.value, tooltipUnit ?? unit)}`
|
|
10383
10397
|
: formatValue(segment.value, tooltipUnit ?? unit);
|
|
@@ -12474,4 +12488,4 @@ const useWindowActivity = ({ onFocus, onBlur, skip = false } = { onBlur: undefin
|
|
|
12474
12488
|
return useMemo(() => ({ focused }), [focused]);
|
|
12475
12489
|
};
|
|
12476
12490
|
|
|
12477
|
-
export {
|
|
12491
|
+
export { Alert, Badge, Breadcrumb, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, DEFAULT_SKELETON_PREFERENCE_CARD_PROPS, DetailsList, EmptyState, EmptyValue, ExternalLink, GridAreas, Heading, Highlight, HorizontalOverflowScroller, Icon, IconButton, Indicator, KPI, KPICard, KPICardSkeleton, KPISkeleton, List, ListItem, MAX_URL_LENGTH, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, PageHeaderKpiMetrics, PageHeaderSecondaryActions, PageHeaderTitle, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Portal, PreferenceCard, PreferenceCardSkeleton, Prompt, ROLE_CARD, SHEET_TRANSITION_DURATION, SHEET_TRANSITION_DURATION_MS, SHEET_TRANSITION_EASING, SectionHeader, SegmentedValueBar, Sheet, Sidebar, SkeletonBlock, SkeletonLabel, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, ToggleGroup, Tooltip, TrendIndicator, TrendIndicators, ValueBar, ZStack, createGrid, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaContainerStyles, cvaContentContainer, cvaContentWrapper, cvaDescriptionCard, cvaIconBackground, cvaIconButton, cvaImgStyles, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInputContainer, cvaInteractableItem, cvaList, cvaListContainer, cvaListItem$1 as cvaListItem, cvaMenu, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, cvaMenuList, cvaMenuListDivider, cvaMenuListItem, cvaMenuListMultiSelect, cvaPageHeader, cvaPageHeaderContainer, cvaPageHeaderHeading, cvaPreferenceCard, cvaTitleCard, cvaToggleGroup, cvaToggleGroupWithSlidingBackground, cvaToggleItem, cvaToggleItemContent, cvaToggleItemText, cvaZStackContainer, cvaZStackItem, defaultPageSize, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, noPagination, preferenceCardGrid, storageSerializer, useBidirectionalScroll, useClickOutside, useContainerBreakpoints, useContinuousTimeout, useCopyToClipboard, useCursorUrlSync, useCustomEncoding, useDebounce, useDevicePixelRatio, useElevatedReducer, useElevatedState, useGridAreas, useHover, useInfiniteScroll, useIsFirstRender, useIsFullscreen, useIsTextTruncated, useKeyboardShortcut, useList, useListItemHeight, useLocalStorage, useLocalStorageReducer, useMeasure, useMergeRefs, useModifierKey, useOverflowBorder, useOverflowItems, usePersistedState, usePopoverContext, usePrevious, usePrompt, useRandomCSSLengths, useRelayPagination, useResize, useScrollBlock, useScrollDetection, useSearchParamSync, useSelfUpdatingRef, useSessionStorage, useSessionStorageReducer, useSheet, useSheetSnap, useStorageKey, useTextSearch, useTimeout, useViewportBreakpoints, useWatch, useWindowActivity };
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.23.2",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
|
+
"migrations": "./migrations.json",
|
|
6
7
|
"engines": {
|
|
7
8
|
"node": ">=24.x"
|
|
8
9
|
},
|
|
@@ -13,10 +14,10 @@
|
|
|
13
14
|
"@floating-ui/react": "^0.26.25",
|
|
14
15
|
"string-ts": "^2.0.0",
|
|
15
16
|
"tailwind-merge": "^2.0.0",
|
|
16
|
-
"@trackunit/ui-design-tokens": "1.
|
|
17
|
-
"@trackunit/css-class-variance-utilities": "1.
|
|
18
|
-
"@trackunit/shared-utils": "1.
|
|
19
|
-
"@trackunit/ui-icons": "1.
|
|
17
|
+
"@trackunit/ui-design-tokens": "1.12.1",
|
|
18
|
+
"@trackunit/css-class-variance-utilities": "1.12.1",
|
|
19
|
+
"@trackunit/shared-utils": "1.14.1",
|
|
20
|
+
"@trackunit/ui-icons": "1.12.2",
|
|
20
21
|
"es-toolkit": "^1.39.10",
|
|
21
22
|
"@tanstack/react-virtual": "3.13.12",
|
|
22
23
|
"dequal": "^2.0.3",
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
-
|
|
2
|
+
import { CommonProps } from "./CommonProps";
|
|
3
|
+
import { Refable } from "./Refable";
|
|
4
|
+
import type { Styleable } from "./Styleable";
|
|
5
|
+
interface PackageNameStoryComponentProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
3
6
|
packageJSON?: {
|
|
4
7
|
name?: string;
|
|
5
8
|
version?: string;
|
|
@@ -9,5 +12,5 @@ interface PackageNameStoryComponentProps {
|
|
|
9
12
|
* A component used to display the package name and version in the Storybook docs.
|
|
10
13
|
* The package-name tag links to the matching section on the "Libraries" overview page.
|
|
11
14
|
*/
|
|
12
|
-
export declare const PackageNameStoryComponent: ({ packageJSON }: PackageNameStoryComponentProps) => ReactElement;
|
|
15
|
+
export declare const PackageNameStoryComponent: ({ packageJSON, className, "data-testid": dataTestId, style, ref, }: PackageNameStoryComponentProps) => ReactElement;
|
|
13
16
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { BreadcrumbProps } from "./utils/types";
|
|
3
3
|
/**
|
|
4
4
|
* The breadcrumb component shows a user's location in a website or application. Breadcrumbs are particularly useful when a large amount of content is organized in a hierarchical manner. They streamline navigation, minimize the steps required to revisit previous pages, and offer contextual insights to the users.
|
|
5
5
|
*
|
|
@@ -37,9 +37,3 @@ import { BreadcrumbContainerProps, BreadcrumbProps } from "./utils/types";
|
|
|
37
37
|
* @returns {ReactElement} Breadcrumb component
|
|
38
38
|
*/
|
|
39
39
|
export declare const Breadcrumb: ({ className, "data-testid": dataTestId, breadcrumbItems, onClickBack, style, ref, }: BreadcrumbProps) => ReactElement;
|
|
40
|
-
/**
|
|
41
|
-
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
42
|
-
*
|
|
43
|
-
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
44
|
-
*/
|
|
45
|
-
export declare const BreadcrumbContainer: ({ "data-testid": dataTestId, breadcrumbItems, }: BreadcrumbContainerProps) => ReactElement;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { BreadcrumbContainerProps } from "./utils/types";
|
|
3
|
+
/**
|
|
4
|
+
* BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
|
|
5
|
+
*
|
|
6
|
+
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
7
|
+
*/
|
|
8
|
+
export declare const BreadcrumbContainer: ({ className, "data-testid": dataTestId, breadcrumbItems, style, ref, }: BreadcrumbContainerProps) => ReactElement;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MouseEventHandler, ReactElement } from "react";
|
|
2
2
|
import { CommonProps } from "../../../common/CommonProps";
|
|
3
|
-
import type { Styleable } from "../../../common/Styleable";
|
|
4
3
|
import { Refable } from "../../../common/Refable";
|
|
4
|
+
import type { Styleable } from "../../../common/Styleable";
|
|
5
5
|
export interface BreadcrumbItemProps {
|
|
6
6
|
/** The display text for this breadcrumb item. */
|
|
7
7
|
label: string;
|
|
@@ -19,7 +19,7 @@ export interface BreadcrumbProps extends CommonProps, Styleable, Refable<HTMLDiv
|
|
|
19
19
|
*/
|
|
20
20
|
onClickBack: MouseEventHandler<HTMLButtonElement>;
|
|
21
21
|
}
|
|
22
|
-
export interface BreadcrumbContainerProps extends CommonProps, Styleable {
|
|
22
|
+
export interface BreadcrumbContainerProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
23
23
|
breadcrumbItems: Array<ReactElement<BreadcrumbItemProps>>;
|
|
24
24
|
}
|
|
25
25
|
export interface BreadcrumbItemRenderProps extends CommonProps, Styleable {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
3
|
+
import { Refable } from "../../common/Refable";
|
|
2
4
|
import type { Styleable } from "../../common/Styleable";
|
|
3
5
|
import { GridAreasResult, SlotProps } from "./types";
|
|
4
6
|
/**
|
|
@@ -6,7 +8,7 @@ import { GridAreasResult, SlotProps } from "./types";
|
|
|
6
8
|
*
|
|
7
9
|
* Spread the result from useGridAreas() onto this component.
|
|
8
10
|
*/
|
|
9
|
-
export type GridAreasProps<TAreaName extends string> = GridAreasResult<TAreaName> & Styleable & {
|
|
11
|
+
export type GridAreasProps<TAreaName extends string> = GridAreasResult<TAreaName> & CommonProps & Styleable & Refable<HTMLElement> & {
|
|
10
12
|
/** Additional CSS classes to apply to the grid container */
|
|
11
13
|
className?: string;
|
|
12
14
|
/** Render prop that receives the slots object */
|
|
@@ -93,4 +95,4 @@ export type GridAreasProps<TAreaName extends string> = GridAreasResult<TAreaName
|
|
|
93
95
|
* }
|
|
94
96
|
* ```
|
|
95
97
|
*/
|
|
96
|
-
export declare function GridAreas<TAreaName extends string>({ slots, css, containerProps, validationRef, className, style, children, asChild, }: GridAreasProps<TAreaName>): ReactNode;
|
|
98
|
+
export declare function GridAreas<TAreaName extends string>({ slots, css, containerProps, validationRef, className, "data-testid": dataTestId, ref, style, children, asChild, }: GridAreasProps<TAreaName>): ReactNode;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ReactElement, ReactNode
|
|
1
|
+
import { ReactElement, ReactNode } from "react";
|
|
2
2
|
import { CommonProps } from "../../common/CommonProps";
|
|
3
|
-
import
|
|
3
|
+
import { Refable } from "../../common/Refable";
|
|
4
4
|
import { Size } from "../../common/Size";
|
|
5
|
+
import type { Styleable } from "../../common/Styleable";
|
|
5
6
|
export type HighlightSize = Extract<Size, "small" | "medium">;
|
|
6
|
-
export interface HighlightProps extends CommonProps, Styleable {
|
|
7
|
+
export interface HighlightProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
7
8
|
/**
|
|
8
9
|
* The size of the highlight. Allowed values: "small" (text-xs), "medium" (text-sm).
|
|
9
10
|
*/
|
|
@@ -16,10 +17,6 @@ export interface HighlightProps extends CommonProps, Styleable {
|
|
|
16
17
|
* The content of the highlight. Accepts any valid React children (text, numbers, elements).
|
|
17
18
|
*/
|
|
18
19
|
children?: ReactNode;
|
|
19
|
-
/**
|
|
20
|
-
* A ref for the component
|
|
21
|
-
*/
|
|
22
|
-
ref?: Ref<HTMLDivElement>;
|
|
23
20
|
}
|
|
24
21
|
/**
|
|
25
22
|
* Highlight draws visual attention to data values that may require user action, monitoring, or investigation.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
2
|
import { CommonProps } from "../../common/CommonProps";
|
|
3
|
+
import { Refable } from "../../common/Refable";
|
|
3
4
|
import type { Styleable } from "../../common/Styleable";
|
|
4
5
|
import { UseListResult, VirtualizationListItemProps } from "./useList";
|
|
5
6
|
export type { VirtualizationListItemProps } from "./useList";
|
|
6
|
-
export interface ListProps<TItem = unknown> extends CommonProps, Styleable, UseListResult<TItem> {
|
|
7
|
+
export interface ListProps<TItem = unknown> extends CommonProps, Styleable, Refable<HTMLDivElement>, UseListResult<TItem> {
|
|
7
8
|
/**
|
|
8
9
|
* Function that renders each list item. Must spread `listItemProps` onto your element
|
|
9
10
|
* and use the provided `key` prop for React's reconciliation.
|
|
@@ -92,4 +93,4 @@ export interface ListProps<TItem = unknown> extends CommonProps, Styleable, UseL
|
|
|
92
93
|
* );
|
|
93
94
|
* ```
|
|
94
95
|
*/
|
|
95
|
-
export declare const List: <TItem = unknown>({ children, className, "data-testid": dataTestId, style, containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, separator, topSeparatorOnScroll, isAtTop, contentFillsContainer, scrollOffset: _scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }: ListProps<TItem>) => ReactElement;
|
|
96
|
+
export declare const List: <TItem = unknown>({ children, className, "data-testid": dataTestId, style, ref, containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, separator, topSeparatorOnScroll, isAtTop, contentFillsContainer, scrollOffset: _scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }: ListProps<TItem>) => ReactElement;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { VariantProps } from "@trackunit/css-class-variance-utilities";
|
|
2
2
|
import type { MappedOmit } from "@trackunit/shared-utils";
|
|
3
3
|
import { tailwindPalette, ThemeColors } from "@trackunit/ui-design-tokens";
|
|
4
|
-
import { MouseEventHandler, ReactElement, ReactNode
|
|
4
|
+
import { MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
5
5
|
import { CommonProps } from "../../common/CommonProps";
|
|
6
|
+
import { Refable } from "../../common/Refable";
|
|
6
7
|
import type { Styleable } from "../../common/Styleable";
|
|
7
8
|
import { cvaListItem } from "./ListItem.variants";
|
|
8
9
|
type ThemeColorShades = `${keyof (typeof tailwindPalette)[keyof typeof tailwindPalette]}`;
|
|
9
|
-
export type ListItemVirtualizationProps = {
|
|
10
|
-
/** @internal */
|
|
11
|
-
ref?: Ref<HTMLLIElement>;
|
|
10
|
+
export type ListItemVirtualizationProps = Refable<HTMLLIElement> & {
|
|
12
11
|
/** @internal */
|
|
13
12
|
tabIndex?: number;
|
|
14
13
|
/** @internal */
|
|
@@ -16,7 +15,7 @@ export type ListItemVirtualizationProps = {
|
|
|
16
15
|
/** @internal */
|
|
17
16
|
className?: string;
|
|
18
17
|
};
|
|
19
|
-
export interface ListItemProps extends CommonProps, Styleable, ListItemVirtualizationProps, MappedOmit<VariantProps<typeof cvaListItem>, "className"> {
|
|
18
|
+
export interface ListItemProps extends CommonProps, Styleable, Refable<HTMLLIElement>, ListItemVirtualizationProps, MappedOmit<VariantProps<typeof cvaListItem>, "className"> {
|
|
20
19
|
/**The main text line of the ListItem */
|
|
21
20
|
title: string | ReactElement<CommonProps>;
|
|
22
21
|
/**Optional description for the ListItem. Can be used for descriptions, metadata, or other important details. */
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
+
import { CommonProps } from "../../../common/CommonProps";
|
|
3
|
+
import { Refable } from "../../../common/Refable";
|
|
2
4
|
import type { Styleable } from "../../../common/Styleable";
|
|
3
|
-
export type MenuDividerProps = Styleable
|
|
5
|
+
export type MenuDividerProps = CommonProps & Styleable & Refable<HTMLDivElement>;
|
|
4
6
|
/**
|
|
5
7
|
* MenuDivider renders a horizontal line to visually separate groups of items within a MenuList.
|
|
6
8
|
*
|
|
@@ -25,4 +27,4 @@ export type MenuDividerProps = Styleable;
|
|
|
25
27
|
* ```
|
|
26
28
|
* @returns {ReactElement} MenuDivider component
|
|
27
29
|
*/
|
|
28
|
-
export declare const MenuDivider: ({ style }: MenuDividerProps) => ReactElement;
|
|
30
|
+
export declare const MenuDivider: ({ className, style, "data-testid": dataTestId, ref }: MenuDividerProps) => ReactElement;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { CommonProps } from "../../../common/CommonProps";
|
|
3
|
+
import { Refable } from "../../../common/Refable";
|
|
4
|
+
import type { Styleable } from "../../../common/Styleable";
|
|
5
|
+
import { PageHeaderSecondaryActionType } from "../types";
|
|
6
|
+
export type ActionRendererProps = CommonProps & Styleable & Refable & {
|
|
7
|
+
action: PageHeaderSecondaryActionType;
|
|
8
|
+
/**
|
|
9
|
+
* Indicates if we should render a MenuItem or Button.
|
|
10
|
+
* If `isMenuItem` is true, we render `MenuItem`, otherwise we render `Button`.
|
|
11
|
+
*/
|
|
12
|
+
isMenuItem?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Because sometimes in a menu, you want to close the menu after clicking.
|
|
15
|
+
* If `externalOnClick` is provided, we'll call it after the action callback.
|
|
16
|
+
*/
|
|
17
|
+
externalOnClick?: () => void;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The ActionRenderer component is used to render the action in the PageHeaderSecondaryActions component.
|
|
21
|
+
*
|
|
22
|
+
* @param {ActionRendererProps} props - The props for the ActionRenderer component
|
|
23
|
+
* @returns {ReactElement} ActionRenderer component
|
|
24
|
+
*/
|
|
25
|
+
export declare function ActionRenderer({ action, isMenuItem, externalOnClick }: ActionRendererProps): ReactElement;
|
|
@@ -1,30 +1,13 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
|
+
import { CommonProps } from "../../../common/CommonProps";
|
|
3
|
+
import { Refable } from "../../../common/Refable";
|
|
4
|
+
import type { Styleable } from "../../../common/Styleable";
|
|
2
5
|
import { PageHeaderSecondaryActionType } from "../types";
|
|
3
|
-
export type PageHeaderSecondaryActionsProps = {
|
|
6
|
+
export type PageHeaderSecondaryActionsProps = CommonProps & Styleable & Refable<HTMLDivElement> & {
|
|
4
7
|
actions: Array<PageHeaderSecondaryActionType>;
|
|
5
8
|
hasPrimaryAction?: boolean;
|
|
6
9
|
groupActions?: boolean;
|
|
7
10
|
};
|
|
8
|
-
type ActionRendererProps = {
|
|
9
|
-
action: PageHeaderSecondaryActionType;
|
|
10
|
-
/**
|
|
11
|
-
* Indicates if we should render a MenuItem or Button.
|
|
12
|
-
* If `isMenuItem` is true, we render `MenuItem`, otherwise we render `Button`.
|
|
13
|
-
*/
|
|
14
|
-
isMenuItem?: boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Because sometimes in a menu, you want to close the menu after clicking.
|
|
17
|
-
* If `externalOnClick` is provided, we’ll call it after the action callback.
|
|
18
|
-
*/
|
|
19
|
-
externalOnClick?: () => void;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* The ActionRenderer component is used to render the action in the PageHeaderSecondaryActions component.
|
|
23
|
-
*
|
|
24
|
-
* @param {ActionRendererProps} props - The props for the ActionRenderer component
|
|
25
|
-
* @returns {ReactElement} ActionRenderer component
|
|
26
|
-
*/
|
|
27
|
-
export declare function ActionRenderer({ action, isMenuItem, externalOnClick }: ActionRendererProps): ReactElement;
|
|
28
11
|
/**
|
|
29
12
|
* The PageHeaderSecondaryActions component is used to render the secondary actions in the PageHeader component.
|
|
30
13
|
*
|
|
@@ -32,7 +15,10 @@ export declare function ActionRenderer({ action, isMenuItem, externalOnClick }:
|
|
|
32
15
|
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
33
16
|
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
34
17
|
* @param {boolean} [props.groupActions] - Whether to group actions in a More Menu regardless of action count
|
|
18
|
+
* @param {string} [props.className] - A custom class name for the action container
|
|
19
|
+
* @param {string} [props."data-testid"] - An ID used to locate the container in tests
|
|
20
|
+
* @param {object} [props.style] - Inline styles for the action container
|
|
21
|
+
* @param {unknown} [props.ref] - Ref for the action container element
|
|
35
22
|
* @returns {ReactElement | null} PageHeaderSecondaryActions component
|
|
36
23
|
*/
|
|
37
|
-
export declare const PageHeaderSecondaryActions: ({ actions, hasPrimaryAction, groupActions, }: PageHeaderSecondaryActionsProps) => ReactElement | null;
|
|
38
|
-
export {};
|
|
24
|
+
export declare const PageHeaderSecondaryActions: ({ actions, hasPrimaryAction, groupActions, className, "data-testid": dataTestId, style, ref, }: PageHeaderSecondaryActionsProps) => ReactElement | null;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { FloatingPortalProps } from "@floating-ui/react";
|
|
2
2
|
import { ReactElement } from "react";
|
|
3
|
-
|
|
3
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
4
|
+
import { Refable } from "../../common/Refable";
|
|
5
|
+
import type { Styleable } from "../../common/Styleable";
|
|
6
|
+
export type PortalProps = FloatingPortalProps & CommonProps & Styleable & Refable<HTMLDivElement>;
|
|
4
7
|
/**
|
|
5
8
|
* Portal renders its children into a separate DOM node, outside the normal React tree hierarchy.
|
|
6
9
|
* By default, content is portalled into a z-index-isolated `div#portal-container` in the document body.
|
|
@@ -38,4 +41,4 @@ export type PortalProps = FloatingPortalProps;
|
|
|
38
41
|
* @param {PortalProps} props - The props for the Portal component
|
|
39
42
|
* @returns {ReactElement} Portal component
|
|
40
43
|
*/
|
|
41
|
-
export declare const Portal: (props:
|
|
44
|
+
export declare const Portal: (props: PortalProps) => ReactElement;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { UseFloatingReturn } from "@floating-ui/react";
|
|
2
|
-
import type { ReactNode,
|
|
2
|
+
import type { ReactNode, RefObject } from "react";
|
|
3
|
+
import type { CommonProps } from "../../common/CommonProps";
|
|
4
|
+
import type { Refable } from "../../common/Refable";
|
|
3
5
|
import type { Styleable } from "../../common/Styleable";
|
|
4
6
|
import type { UseOverlayDismissibleProps } from "../../overlay-dismissible/types";
|
|
5
7
|
/**
|
|
@@ -146,7 +148,7 @@ export type UseSheetSnapReturn = {
|
|
|
146
148
|
* actually reads. Consumers spread the hook return (`{...sheet}`) and
|
|
147
149
|
* TypeScript allows extra properties on spread expressions.
|
|
148
150
|
*/
|
|
149
|
-
export type SheetProps = Styleable & {
|
|
151
|
+
export type SheetProps = CommonProps & Styleable & Refable<HTMLDivElement> & {
|
|
150
152
|
readonly isOpen: boolean;
|
|
151
153
|
/** Unified sheet state from useSheetSnap. */
|
|
152
154
|
readonly state: SheetState;
|
|
@@ -163,7 +165,6 @@ export type SheetProps = Styleable & {
|
|
|
163
165
|
* Sheet skips its own focus trap and dismiss — the parent owns those.
|
|
164
166
|
*/
|
|
165
167
|
readonly floatingUi?: SheetFloatingUiProps;
|
|
166
|
-
readonly ref?: Ref<HTMLDivElement>;
|
|
167
168
|
/** Horizontal positioning of the sheet. */
|
|
168
169
|
readonly anchor?: SheetAnchor;
|
|
169
170
|
/** Enable/disable drag-to-snap between levels. Default: true. */
|
|
@@ -197,10 +198,6 @@ export type SheetProps = Styleable & {
|
|
|
197
198
|
* mode shows only `persistentContent`.
|
|
198
199
|
*/
|
|
199
200
|
readonly persistentContent?: ReactNode;
|
|
200
|
-
/** Custom class name. */
|
|
201
|
-
readonly className?: string;
|
|
202
|
-
/** Test ID for the sheet. */
|
|
203
|
-
readonly "data-testid"?: string;
|
|
204
201
|
/** Sheet content. */
|
|
205
202
|
readonly children?: ReactNode;
|
|
206
203
|
/** Called after the close CSS transition completes (transitionend on transform). */
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { TabsTriggerProps } from "@radix-ui/react-tabs";
|
|
2
2
|
import { IconName } from "@trackunit/ui-icons";
|
|
3
3
|
import { ReactElement, ReactNode } from "react";
|
|
4
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
4
5
|
import { Refable } from "../../common/Refable";
|
|
5
|
-
|
|
6
|
+
import type { Styleable } from "../../common/Styleable";
|
|
7
|
+
export interface TabChildProps extends CommonProps {
|
|
6
8
|
children?: ReactNode;
|
|
7
|
-
className?: string;
|
|
8
9
|
}
|
|
9
|
-
export interface TabProps extends TabsTriggerProps, Refable<HTMLButtonElement> {
|
|
10
|
+
export interface TabProps extends TabsTriggerProps, CommonProps, Styleable, Refable<HTMLButtonElement> {
|
|
10
11
|
/**
|
|
11
12
|
* Specifies whether the tab should occupy the full width of its container.
|
|
12
13
|
*/
|
|
13
14
|
isFullWidth?: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* A data-testid attribute for testing purposes.
|
|
16
|
-
*/
|
|
17
|
-
"data-testid"?: string;
|
|
18
15
|
/**
|
|
19
16
|
* The text content of the tab.
|
|
20
17
|
*/
|
|
@@ -51,6 +48,10 @@ export interface TabProps extends TabsTriggerProps, Refable<HTMLButtonElement> {
|
|
|
51
48
|
* ### When not to use
|
|
52
49
|
* Do not use Tab outside of a `TabList`/`Tabs` context. For standalone buttons, use `Button`.
|
|
53
50
|
*
|
|
51
|
+
* ### `data-testid` and `asChild`
|
|
52
|
+
* `data-testid` is applied to the rendered element. When `asChild` is used and the child already
|
|
53
|
+
* defines its own `data-testid`, the child's value wins so consumers can label the actual DOM node.
|
|
54
|
+
*
|
|
54
55
|
* @example Tab with icon and badge suffix
|
|
55
56
|
* ```tsx
|
|
56
57
|
* import { Tabs, TabList, Tab, TabContent, Badge } from "@trackunit/react-components";
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { TabsContentProps } from "@radix-ui/react-tabs";
|
|
2
2
|
import { IconName } from "@trackunit/ui-icons";
|
|
3
3
|
import { ReactElement, ReactNode } from "react";
|
|
4
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
4
5
|
import { Refable } from "../../common/Refable";
|
|
5
|
-
|
|
6
|
+
import type { Styleable } from "../../common/Styleable";
|
|
7
|
+
export interface TabContentProps extends TabsContentProps, CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
6
8
|
/**
|
|
7
9
|
* A custom class name to be attached to the content wrapper element.
|
|
8
10
|
*/
|
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
import { TabsListProps } from "@radix-ui/react-tabs";
|
|
2
2
|
import { ReactElement } from "react";
|
|
3
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
3
4
|
import { Refable } from "../../common/Refable";
|
|
5
|
+
import type { Styleable } from "../../common/Styleable";
|
|
4
6
|
import { TabContentProps } from "./TabContent";
|
|
5
|
-
export interface TabListProps extends TabsListProps, Refable<HTMLDivElement> {
|
|
7
|
+
export interface TabListProps extends TabsListProps, CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
6
8
|
/**
|
|
7
9
|
* The child elements to be displayed within the Tabs component.
|
|
8
10
|
*/
|
|
9
11
|
children: Array<ReactElement<TabContentProps>>;
|
|
10
|
-
/**
|
|
11
|
-
* A custom class name to be attached to root element
|
|
12
|
-
*/
|
|
13
|
-
className?: string;
|
|
14
|
-
/**
|
|
15
|
-
* An ID that can be used in tests to locate the component.
|
|
16
|
-
*/
|
|
17
|
-
"data-testid"?: string;
|
|
18
12
|
/**
|
|
19
13
|
* If set to true, automatically scrolls the active tab into view when changed.
|
|
20
14
|
*
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { TabsProps as TabsRootProps } from "@radix-ui/react-tabs";
|
|
2
2
|
import { ReactElement, ReactNode } from "react";
|
|
3
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
3
4
|
import { Refable } from "../../common/Refable";
|
|
4
|
-
|
|
5
|
+
import type { Styleable } from "../../common/Styleable";
|
|
6
|
+
export interface TabsProps extends TabsRootProps, CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
5
7
|
/**
|
|
6
8
|
* If set to true, forces the content of all tabs to render even if not selected.
|
|
7
9
|
*/
|
|
@@ -14,14 +16,6 @@ export interface TabsProps extends TabsRootProps, Refable<HTMLDivElement> {
|
|
|
14
16
|
* The child elements to be displayed within the Tabs component.
|
|
15
17
|
*/
|
|
16
18
|
children: ReactNode;
|
|
17
|
-
/**
|
|
18
|
-
* A custom class name to be attached to root element
|
|
19
|
-
*/
|
|
20
|
-
className?: string;
|
|
21
|
-
/**
|
|
22
|
-
* An ID that can be used in tests to locate the component.
|
|
23
|
-
*/
|
|
24
|
-
"data-testid"?: string;
|
|
25
19
|
}
|
|
26
20
|
/**
|
|
27
21
|
* Tabs group different but related content, allowing users to navigate views without leaving the page.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ActivityColors, CriticalityColors, GeneralColors, IntentColors } from "@trackunit/ui-design-tokens";
|
|
2
|
-
import { MouseEventHandler, ReactElement, ReactNode
|
|
2
|
+
import { MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
3
3
|
import { CommonProps } from "../../common/CommonProps";
|
|
4
|
-
import
|
|
4
|
+
import { Refable } from "../../common/Refable";
|
|
5
5
|
import { Size } from "../../common/Size";
|
|
6
|
+
import type { Styleable } from "../../common/Styleable";
|
|
6
7
|
export type TagSize = Extract<Size, "small" | "medium">;
|
|
7
8
|
export type TagColors = IntentColors | GeneralColors | CriticalityColors | ActivityColors;
|
|
8
|
-
export interface TagProps extends CommonProps, Styleable {
|
|
9
|
+
export interface TagProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
9
10
|
/**
|
|
10
11
|
* The color of the tag.
|
|
11
12
|
*
|
|
@@ -31,10 +32,6 @@ export interface TagProps extends CommonProps, Styleable {
|
|
|
31
32
|
* Is the tag disabled.
|
|
32
33
|
*/
|
|
33
34
|
disabled?: boolean;
|
|
34
|
-
/**
|
|
35
|
-
* A ref for the component
|
|
36
|
-
*/
|
|
37
|
-
ref?: Ref<HTMLDivElement>;
|
|
38
35
|
/**
|
|
39
36
|
* The icon to display. Only supported for medium size.
|
|
40
37
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ReactElement } from "react";
|
|
2
2
|
import { CommonProps } from "../../common/CommonProps";
|
|
3
|
+
import { Refable } from "../../common/Refable";
|
|
3
4
|
import type { Styleable } from "../../common/Styleable";
|
|
4
5
|
import type { SegmentedValueBarSize, ValueBarSegment } from "./SegmentedValueBarTypes";
|
|
5
|
-
export interface SegmentedValueBarProps extends CommonProps, Styleable {
|
|
6
|
+
export interface SegmentedValueBarProps extends CommonProps, Styleable, Refable<HTMLSpanElement> {
|
|
6
7
|
/**
|
|
7
8
|
* Array of segments to display. Each segment has a numeric value and a color and optionally a label.
|
|
8
9
|
* Segments render in the order they are provided; the component does not sort or reorder them.
|
|
@@ -50,4 +51,4 @@ export interface SegmentedValueBarProps extends CommonProps, Styleable {
|
|
|
50
51
|
* SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
|
|
51
52
|
* Supports optional tooltips per segment, showing value and optionally a label.
|
|
52
53
|
*/
|
|
53
|
-
export declare const SegmentedValueBar: ({ segments, total, size, showValue, displayValue, unit, valueColor, showTooltip, tooltipUnit, valueWidth, className, "data-testid": dataTestId, style, }: SegmentedValueBarProps) => ReactElement;
|
|
54
|
+
export declare const SegmentedValueBar: ({ segments, total, size, showValue, displayValue, unit, valueColor, showTooltip, tooltipUnit, valueWidth, className, "data-testid": dataTestId, ref, style, }: SegmentedValueBarProps) => ReactElement;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MappedOmit } from "@trackunit/shared-utils";
|
|
2
|
-
import { ReactElement, ReactNode
|
|
2
|
+
import { ReactElement, ReactNode } from "react";
|
|
3
|
+
import { Refable } from "../../../common/Refable";
|
|
3
4
|
import { Size } from "../../../common/Size";
|
|
4
5
|
import { ButtonCommonProps, ButtonType } from "../shared/ButtonProps";
|
|
5
|
-
export interface ButtonProps extends MappedOmit<ButtonCommonProps, "size"> {
|
|
6
|
+
export interface ButtonProps extends MappedOmit<ButtonCommonProps, "size">, Refable<HTMLButtonElement> {
|
|
6
7
|
/**
|
|
7
8
|
* Child nodes. Can be used to pass in text to be displayed on the button.
|
|
8
9
|
*/
|
|
@@ -35,10 +36,6 @@ export interface ButtonProps extends MappedOmit<ButtonCommonProps, "size"> {
|
|
|
35
36
|
* The name of the button
|
|
36
37
|
*/
|
|
37
38
|
name?: string;
|
|
38
|
-
/**
|
|
39
|
-
* A ref for the component
|
|
40
|
-
*/
|
|
41
|
-
ref?: Ref<HTMLButtonElement>;
|
|
42
39
|
/**
|
|
43
40
|
* The size of the button
|
|
44
41
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { MappedOmit } from "@trackunit/shared-utils";
|
|
2
|
-
import { ComponentType, JSX, ReactElement, ReactNode
|
|
2
|
+
import { ComponentType, JSX, ReactElement, ReactNode } from "react";
|
|
3
|
+
import { Refable } from "../../../common/Refable";
|
|
3
4
|
import { Size } from "../../../common/Size";
|
|
4
5
|
import { ButtonCommonProps } from "../shared/ButtonProps";
|
|
5
|
-
export interface IconButtonProps extends MappedOmit<ButtonCommonProps, "size"> {
|
|
6
|
+
export interface IconButtonProps extends MappedOmit<ButtonCommonProps, "size">, Refable<HTMLButtonElement> {
|
|
6
7
|
/**
|
|
7
8
|
* The icon to display.
|
|
8
9
|
*/
|
|
@@ -17,10 +18,6 @@ export interface IconButtonProps extends MappedOmit<ButtonCommonProps, "size"> {
|
|
|
17
18
|
* The size of the button. Defaults to "medium".
|
|
18
19
|
*/
|
|
19
20
|
size?: Size;
|
|
20
|
-
/**
|
|
21
|
-
* A ref for the component
|
|
22
|
-
*/
|
|
23
|
-
ref?: Ref<HTMLButtonElement>;
|
|
24
21
|
}
|
|
25
22
|
/**
|
|
26
23
|
* 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.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { MouseEventHandler, ReactElement } from "react";
|
|
2
|
+
import { CommonProps } from "../../../common/CommonProps";
|
|
2
3
|
import { Refable } from "../../../common/Refable";
|
|
3
|
-
|
|
4
|
+
import type { Styleable } from "../../../common/Styleable";
|
|
5
|
+
interface StarButtonProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
|
|
4
6
|
/**
|
|
5
7
|
* Whether the item is currently starred/favorited. Controls the icon color (primary when starred, neutral when not).
|
|
6
8
|
*/
|
|
@@ -33,5 +35,5 @@ interface StarButtonProps extends Refable<HTMLDivElement> {
|
|
|
33
35
|
* @param {StarButtonProps} props - The props for the StarButton component
|
|
34
36
|
* @returns {ReactElement} StarButton component
|
|
35
37
|
*/
|
|
36
|
-
export declare const StarButton: ({ starred, onClick, ref }: StarButtonProps) => ReactElement;
|
|
38
|
+
export declare const StarButton: ({ starred, onClick, className, "data-testid": dataTestId, style, ref, }: StarButtonProps) => ReactElement;
|
|
37
39
|
export {};
|