@trackunit/react-components 1.22.27 → 1.22.29
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 +35 -23
- package/index.esm.js +35 -23
- package/package.json +1 -1
- package/src/common/PackageNameStoryComponent.d.ts +5 -2
- package/src/components/Breadcrumb/Breadcrumb.d.ts +1 -1
- 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/PageHeaderSecondaryActions.d.ts +10 -3
- 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 = {
|
|
@@ -1558,15 +1558,16 @@ const Breadcrumb = ({ className, "data-testid": dataTestId, breadcrumbItems, onC
|
|
|
1558
1558
|
*
|
|
1559
1559
|
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1560
1560
|
*/
|
|
1561
|
-
const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) => {
|
|
1561
|
+
const BreadcrumbContainer = ({ className, "data-testid": dataTestId, breadcrumbItems, style, ref, }) => {
|
|
1562
1562
|
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1563
|
+
const sharedContainerProps = { className, "data-testid": dataTestId, ref, style };
|
|
1563
1564
|
if (isMediumScreen) {
|
|
1564
|
-
return jsxRuntime.jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` });
|
|
1565
|
+
return (jsxRuntime.jsx("div", { ...sharedContainerProps, children: jsxRuntime.jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` }) }));
|
|
1565
1566
|
}
|
|
1566
1567
|
if (isSmallScreen) {
|
|
1567
|
-
return jsxRuntime.jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` });
|
|
1568
|
+
return (jsxRuntime.jsx("div", { ...sharedContainerProps, children: jsxRuntime.jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` }) }));
|
|
1568
1569
|
}
|
|
1569
|
-
return jsxRuntime.jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` });
|
|
1570
|
+
return (jsxRuntime.jsx("div", { ...sharedContainerProps, children: jsxRuntime.jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` }) }));
|
|
1570
1571
|
};
|
|
1571
1572
|
|
|
1572
1573
|
/**
|
|
@@ -1592,8 +1593,8 @@ const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) =>
|
|
|
1592
1593
|
* @param {StarButtonProps} props - The props for the StarButton component
|
|
1593
1594
|
* @returns {ReactElement} StarButton component
|
|
1594
1595
|
*/
|
|
1595
|
-
const StarButton = ({ starred, onClick, ref }) => {
|
|
1596
|
-
return (jsxRuntime.jsx("div", { "data-
|
|
1596
|
+
const StarButton = ({ starred, onClick, className, "data-testid": dataTestId, style, ref, }) => {
|
|
1597
|
+
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
1598
|
};
|
|
1598
1599
|
|
|
1599
1600
|
const cvaCard = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -3685,9 +3686,10 @@ function createGrid() {
|
|
|
3685
3686
|
* }
|
|
3686
3687
|
* ```
|
|
3687
3688
|
*/
|
|
3688
|
-
function GridAreas({ slots, css, containerProps, validationRef, className, style, children, asChild = false, }) {
|
|
3689
|
+
function GridAreas({ slots, css, containerProps, validationRef, className, "data-testid": dataTestId, ref, style, children, asChild = false, }) {
|
|
3689
3690
|
const Comp = asChild ? reactSlot.Slot : "div";
|
|
3690
|
-
|
|
3691
|
+
const mergedRef = useMergeRefs([validationRef, ref]);
|
|
3692
|
+
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
3693
|
}
|
|
3692
3694
|
|
|
3693
3695
|
/**
|
|
@@ -5666,15 +5668,16 @@ const ListLoadingIndicator = ({ type, hasThumbnail, thumbnailShape, hasDescripti
|
|
|
5666
5668
|
* );
|
|
5667
5669
|
* ```
|
|
5668
5670
|
*/
|
|
5669
|
-
const List = ({ children, className, "data-testid": dataTestId, style,
|
|
5671
|
+
const List = ({ children, className, "data-testid": dataTestId, style, ref,
|
|
5670
5672
|
// UseListResult properties
|
|
5671
5673
|
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, separator, topSeparatorOnScroll, isAtTop, contentFillsContainer,
|
|
5672
5674
|
// Unused but part of UseListResult interface (can be used from parent)
|
|
5673
5675
|
scrollOffset: _scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }) => {
|
|
5676
|
+
const mergedContainerRef = useMergeRefs([containerRef, ref]);
|
|
5674
5677
|
return (jsxRuntime.jsx("div", { className: cvaListContainer({
|
|
5675
5678
|
withTopSeparator: topSeparatorOnScroll && !isAtTop,
|
|
5676
5679
|
className,
|
|
5677
|
-
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref:
|
|
5680
|
+
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref: mergedContainerRef, style: style, children: jsxRuntime.jsx("ul", { className: cvaList(), ref: listRef, children: rows.map(row => {
|
|
5678
5681
|
// Generate list item props with clean separator styling
|
|
5679
5682
|
const listItemProps = getListItemProps(row, {
|
|
5680
5683
|
className: cvaListItem$1({
|
|
@@ -6216,8 +6219,8 @@ const cvaMenuListItem = cssClassVarianceUtilities.cvaMerge("max-w-full");
|
|
|
6216
6219
|
* ```
|
|
6217
6220
|
* @returns {ReactElement} MenuDivider component
|
|
6218
6221
|
*/
|
|
6219
|
-
const MenuDivider = ({ style }) => {
|
|
6220
|
-
return jsxRuntime.jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider", style: style });
|
|
6222
|
+
const MenuDivider = ({ className, style, "data-testid": dataTestId, ref }) => {
|
|
6223
|
+
return (jsxRuntime.jsx("div", { className: cvaMenuListDivider({ className }), "data-testid": dataTestId ?? "menu-divider", ref: ref, style: style }));
|
|
6221
6224
|
};
|
|
6222
6225
|
|
|
6223
6226
|
/**
|
|
@@ -6890,9 +6893,13 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
6890
6893
|
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
6891
6894
|
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
6892
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
|
|
6893
6900
|
* @returns {ReactElement | null} PageHeaderSecondaryActions component
|
|
6894
6901
|
*/
|
|
6895
|
-
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, }) => {
|
|
6902
|
+
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, className, "data-testid": dataTestId, style, ref, }) => {
|
|
6896
6903
|
const enabledActions = react.useMemo(() => actions.filter(action => action.hidden === false || action.hidden === undefined), [actions]);
|
|
6897
6904
|
// If there are no enabled actions, don't render anything
|
|
6898
6905
|
if (enabledActions.length === 0) {
|
|
@@ -6909,10 +6916,10 @@ const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupAc
|
|
|
6909
6916
|
return [danger, [...others, action]];
|
|
6910
6917
|
}
|
|
6911
6918
|
}, [[], []]);
|
|
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}`)))] })) }));
|
|
6919
|
+
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
6920
|
}
|
|
6914
6921
|
// Otherwise, render them inline as buttons
|
|
6915
|
-
return (jsxRuntime.jsx("div", { className: "flex flex-row items-center gap-2", children: enabledActions
|
|
6922
|
+
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
6923
|
.toSorted((a, b) => {
|
|
6917
6924
|
if (a.variant === "secondary" && b.variant === "secondary-danger") {
|
|
6918
6925
|
return 1;
|
|
@@ -9900,6 +9907,10 @@ const cvaTab = cssClassVarianceUtilities.cvaMerge([
|
|
|
9900
9907
|
* ### When not to use
|
|
9901
9908
|
* Do not use Tab outside of a `TabList`/`Tabs` context. For standalone buttons, use `Button`.
|
|
9902
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
|
+
*
|
|
9903
9914
|
* @example Tab with icon and badge suffix
|
|
9904
9915
|
* ```tsx
|
|
9905
9916
|
* import { Tabs, TabList, Tab, TabContent, Badge } from "@trackunit/react-components";
|
|
@@ -9922,14 +9933,15 @@ const cvaTab = cssClassVarianceUtilities.cvaMerge([
|
|
|
9922
9933
|
*/
|
|
9923
9934
|
const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid": dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ref, ...rest }) => {
|
|
9924
9935
|
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
|
|
9936
|
+
const sharedProps = {
|
|
9926
9937
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
9927
9938
|
...rest,
|
|
9928
9939
|
};
|
|
9929
9940
|
return (jsxRuntime.jsx(reactTabs.Trigger, { asChild: true, ref: ref, value: value, children: asChild && typeof children !== "string" ? (react.cloneElement(children, {
|
|
9930
|
-
...
|
|
9941
|
+
...sharedProps,
|
|
9942
|
+
"data-testid": children.props["data-testid"] ?? dataTestId,
|
|
9931
9943
|
children: renderContent(),
|
|
9932
|
-
})) : (jsxRuntime.jsx("button", { ...
|
|
9944
|
+
})) : (jsxRuntime.jsx("button", { ...sharedProps, "data-testid": dataTestId, children: renderContent() })) }));
|
|
9933
9945
|
};
|
|
9934
9946
|
|
|
9935
9947
|
/**
|
|
@@ -10373,13 +10385,13 @@ const getValueTextVariant = (size, sum, segments, total) => {
|
|
|
10373
10385
|
* SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
|
|
10374
10386
|
* Supports optional tooltips per segment, showing value and optionally a label.
|
|
10375
10387
|
*/
|
|
10376
|
-
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, }) => {
|
|
10377
10389
|
const computedSegments = computeSegments(segments, total);
|
|
10378
10390
|
const sum = total > 0 ? computeSum(segments) : 0;
|
|
10379
10391
|
const valueText = formatValue(displayValue ?? sum, unit);
|
|
10380
10392
|
const canShowValue = showValue && size !== "extraSmall";
|
|
10381
10393
|
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) => {
|
|
10394
|
+
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
10395
|
const tooltipLabel = segment.label
|
|
10384
10396
|
? `${segment.label}: ${formatValue(segment.value, tooltipUnit ?? unit)}`
|
|
10385
10397
|
: formatValue(segment.value, tooltipUnit ?? unit);
|
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 = {
|
|
@@ -1556,15 +1556,16 @@ const Breadcrumb = ({ className, "data-testid": dataTestId, breadcrumbItems, onC
|
|
|
1556
1556
|
*
|
|
1557
1557
|
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1558
1558
|
*/
|
|
1559
|
-
const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) => {
|
|
1559
|
+
const BreadcrumbContainer = ({ className, "data-testid": dataTestId, breadcrumbItems, style, ref, }) => {
|
|
1560
1560
|
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1561
|
+
const sharedContainerProps = { className, "data-testid": dataTestId, ref, style };
|
|
1561
1562
|
if (isMediumScreen) {
|
|
1562
|
-
return jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` });
|
|
1563
|
+
return (jsx("div", { ...sharedContainerProps, children: jsx(BreadcrumbForMediumScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `mediumScreen-${dataTestId}` }) }));
|
|
1563
1564
|
}
|
|
1564
1565
|
if (isSmallScreen) {
|
|
1565
|
-
return jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` });
|
|
1566
|
+
return (jsx("div", { ...sharedContainerProps, children: jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `smallScreen-${dataTestId}` }) }));
|
|
1566
1567
|
}
|
|
1567
|
-
return jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` });
|
|
1568
|
+
return (jsx("div", { ...sharedContainerProps, children: jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, "data-testid": `largeScreen-${dataTestId}` }) }));
|
|
1568
1569
|
};
|
|
1569
1570
|
|
|
1570
1571
|
/**
|
|
@@ -1590,8 +1591,8 @@ const BreadcrumbContainer = ({ "data-testid": dataTestId, breadcrumbItems, }) =>
|
|
|
1590
1591
|
* @param {StarButtonProps} props - The props for the StarButton component
|
|
1591
1592
|
* @returns {ReactElement} StarButton component
|
|
1592
1593
|
*/
|
|
1593
|
-
const StarButton = ({ starred, onClick, ref }) => {
|
|
1594
|
-
return (jsx("div", { "data-
|
|
1594
|
+
const StarButton = ({ starred, onClick, className, "data-testid": dataTestId, style, ref, }) => {
|
|
1595
|
+
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
1596
|
};
|
|
1596
1597
|
|
|
1597
1598
|
const cvaCard = cvaMerge([
|
|
@@ -3683,9 +3684,10 @@ function createGrid() {
|
|
|
3683
3684
|
* }
|
|
3684
3685
|
* ```
|
|
3685
3686
|
*/
|
|
3686
|
-
function GridAreas({ slots, css, containerProps, validationRef, className, style, children, asChild = false, }) {
|
|
3687
|
+
function GridAreas({ slots, css, containerProps, validationRef, className, "data-testid": dataTestId, ref, style, children, asChild = false, }) {
|
|
3687
3688
|
const Comp = asChild ? Slot : "div";
|
|
3688
|
-
|
|
3689
|
+
const mergedRef = useMergeRefs([validationRef, ref]);
|
|
3690
|
+
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
3691
|
}
|
|
3690
3692
|
|
|
3691
3693
|
/**
|
|
@@ -5664,15 +5666,16 @@ const ListLoadingIndicator = ({ type, hasThumbnail, thumbnailShape, hasDescripti
|
|
|
5664
5666
|
* );
|
|
5665
5667
|
* ```
|
|
5666
5668
|
*/
|
|
5667
|
-
const List = ({ children, className, "data-testid": dataTestId, style,
|
|
5669
|
+
const List = ({ children, className, "data-testid": dataTestId, style, ref,
|
|
5668
5670
|
// UseListResult properties
|
|
5669
5671
|
containerRef, listRef, rows, getListItemProps, header, loadingIndicator, shouldShowLoaderAtIndex, count, isScrolling, separator, topSeparatorOnScroll, isAtTop, contentFillsContainer,
|
|
5670
5672
|
// Unused but part of UseListResult interface (can be used from parent)
|
|
5671
5673
|
scrollOffset: _scrollOffset, getTotalSize: _getTotalSize, getVirtualItems: _getVirtualItems, scrollToOffset: _scrollToOffset, scrollToIndex: _scrollToIndex, measure: _measure, }) => {
|
|
5674
|
+
const mergedContainerRef = useMergeRefs([containerRef, ref]);
|
|
5672
5675
|
return (jsx("div", { className: cvaListContainer({
|
|
5673
5676
|
withTopSeparator: topSeparatorOnScroll && !isAtTop,
|
|
5674
5677
|
className,
|
|
5675
|
-
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref:
|
|
5678
|
+
}), "data-is-scrolling": isScrolling, "data-testid": dataTestId, ref: mergedContainerRef, style: style, children: jsx("ul", { className: cvaList(), ref: listRef, children: rows.map(row => {
|
|
5676
5679
|
// Generate list item props with clean separator styling
|
|
5677
5680
|
const listItemProps = getListItemProps(row, {
|
|
5678
5681
|
className: cvaListItem$1({
|
|
@@ -6214,8 +6217,8 @@ const cvaMenuListItem = cvaMerge("max-w-full");
|
|
|
6214
6217
|
* ```
|
|
6215
6218
|
* @returns {ReactElement} MenuDivider component
|
|
6216
6219
|
*/
|
|
6217
|
-
const MenuDivider = ({ style }) => {
|
|
6218
|
-
return jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider", style: style });
|
|
6220
|
+
const MenuDivider = ({ className, style, "data-testid": dataTestId, ref }) => {
|
|
6221
|
+
return (jsx("div", { className: cvaMenuListDivider({ className }), "data-testid": dataTestId ?? "menu-divider", ref: ref, style: style }));
|
|
6219
6222
|
};
|
|
6220
6223
|
|
|
6221
6224
|
/**
|
|
@@ -6888,9 +6891,13 @@ function ActionRenderer({ action, isMenuItem = false, externalOnClick }) {
|
|
|
6888
6891
|
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
6889
6892
|
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
6890
6893
|
* @param {boolean} [props.groupActions] - Whether to group actions in a More Menu regardless of action count
|
|
6894
|
+
* @param {string} [props.className] - A custom class name for the action container
|
|
6895
|
+
* @param {string} [props."data-testid"] - An ID used to locate the container in tests
|
|
6896
|
+
* @param {object} [props.style] - Inline styles for the action container
|
|
6897
|
+
* @param {unknown} [props.ref] - Ref for the action container element
|
|
6891
6898
|
* @returns {ReactElement | null} PageHeaderSecondaryActions component
|
|
6892
6899
|
*/
|
|
6893
|
-
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, }) => {
|
|
6900
|
+
const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupActions = false, className, "data-testid": dataTestId, style, ref, }) => {
|
|
6894
6901
|
const enabledActions = useMemo(() => actions.filter(action => action.hidden === false || action.hidden === undefined), [actions]);
|
|
6895
6902
|
// If there are no enabled actions, don't render anything
|
|
6896
6903
|
if (enabledActions.length === 0) {
|
|
@@ -6907,10 +6914,10 @@ const PageHeaderSecondaryActions = ({ actions, hasPrimaryAction = false, groupAc
|
|
|
6907
6914
|
return [danger, [...others, action]];
|
|
6908
6915
|
}
|
|
6909
6916
|
}, [[], []]);
|
|
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}`)))] })) }));
|
|
6917
|
+
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
6918
|
}
|
|
6912
6919
|
// Otherwise, render them inline as buttons
|
|
6913
|
-
return (jsx("div", { className: "flex flex-row items-center gap-2", children: enabledActions
|
|
6920
|
+
return (jsx("div", { className: twMerge("flex flex-row items-center gap-2", className), "data-testid": dataTestId, ref: ref, style: style, children: enabledActions
|
|
6914
6921
|
.toSorted((a, b) => {
|
|
6915
6922
|
if (a.variant === "secondary" && b.variant === "secondary-danger") {
|
|
6916
6923
|
return 1;
|
|
@@ -9898,6 +9905,10 @@ const cvaTab = cvaMerge([
|
|
|
9898
9905
|
* ### When not to use
|
|
9899
9906
|
* Do not use Tab outside of a `TabList`/`Tabs` context. For standalone buttons, use `Button`.
|
|
9900
9907
|
*
|
|
9908
|
+
* ### `data-testid` and `asChild`
|
|
9909
|
+
* `data-testid` is applied to the rendered element. When `asChild` is used and the child already
|
|
9910
|
+
* defines its own `data-testid`, the child's value wins so consumers can label the actual DOM node.
|
|
9911
|
+
*
|
|
9901
9912
|
* @example Tab with icon and badge suffix
|
|
9902
9913
|
* ```tsx
|
|
9903
9914
|
* import { Tabs, TabList, Tab, TabContent, Badge } from "@trackunit/react-components";
|
|
@@ -9920,14 +9931,15 @@ const cvaTab = cvaMerge([
|
|
|
9920
9931
|
*/
|
|
9921
9932
|
const Tab = ({ value, isFullWidth = false, iconName = undefined, "data-testid": dataTestId, className, children, suffix, asChild = false, appendTabStylesToChildIfAsChild = true, ref, ...rest }) => {
|
|
9922
9933
|
const renderContent = () => (jsxs(Fragment, { children: [iconName !== undefined ? jsx(Icon, { name: iconName, size: "small" }) : null, isValidElement(children) ? children.props.children : children, suffix] }));
|
|
9923
|
-
const
|
|
9934
|
+
const sharedProps = {
|
|
9924
9935
|
className: appendTabStylesToChildIfAsChild ? cvaTab({ className, isFullWidth }) : className,
|
|
9925
9936
|
...rest,
|
|
9926
9937
|
};
|
|
9927
9938
|
return (jsx(Trigger, { asChild: true, ref: ref, value: value, children: asChild && typeof children !== "string" ? (cloneElement(children, {
|
|
9928
|
-
...
|
|
9939
|
+
...sharedProps,
|
|
9940
|
+
"data-testid": children.props["data-testid"] ?? dataTestId,
|
|
9929
9941
|
children: renderContent(),
|
|
9930
|
-
})) : (jsx("button", { ...
|
|
9942
|
+
})) : (jsx("button", { ...sharedProps, "data-testid": dataTestId, children: renderContent() })) }));
|
|
9931
9943
|
};
|
|
9932
9944
|
|
|
9933
9945
|
/**
|
|
@@ -10371,13 +10383,13 @@ const getValueTextVariant = (size, sum, segments, total) => {
|
|
|
10371
10383
|
* SegmentedValueBar displays multiple colored segments on a bar to visualize values relative to a total.
|
|
10372
10384
|
* Supports optional tooltips per segment, showing value and optionally a label.
|
|
10373
10385
|
*/
|
|
10374
|
-
const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, style, }) => {
|
|
10386
|
+
const SegmentedValueBar = ({ segments, total, size = "small", showValue = false, displayValue, unit, valueColor, showTooltip = false, tooltipUnit, valueWidth, className, "data-testid": dataTestId, ref, style, }) => {
|
|
10375
10387
|
const computedSegments = computeSegments(segments, total);
|
|
10376
10388
|
const sum = total > 0 ? computeSum(segments) : 0;
|
|
10377
10389
|
const valueText = formatValue(displayValue ?? sum, unit);
|
|
10378
10390
|
const canShowValue = showValue && size !== "extraSmall";
|
|
10379
10391
|
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) => {
|
|
10392
|
+
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
10393
|
const tooltipLabel = segment.label
|
|
10382
10394
|
? `${segment.label}: ${formatValue(segment.value, tooltipUnit ?? unit)}`
|
|
10383
10395
|
: formatValue(segment.value, tooltipUnit ?? unit);
|
package/package.json
CHANGED
|
@@ -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 {};
|
|
@@ -42,4 +42,4 @@ export declare const Breadcrumb: ({ className, "data-testid": dataTestId, breadc
|
|
|
42
42
|
*
|
|
43
43
|
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
44
44
|
*/
|
|
45
|
-
export declare const BreadcrumbContainer: ({ "data-testid": dataTestId, breadcrumbItems, }: BreadcrumbContainerProps) => ReactElement;
|
|
45
|
+
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;
|
|
@@ -1,11 +1,14 @@
|
|
|
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 = {
|
|
11
|
+
type ActionRendererProps = CommonProps & Styleable & Refable & {
|
|
9
12
|
action: PageHeaderSecondaryActionType;
|
|
10
13
|
/**
|
|
11
14
|
* Indicates if we should render a MenuItem or Button.
|
|
@@ -32,7 +35,11 @@ export declare function ActionRenderer({ action, isMenuItem, externalOnClick }:
|
|
|
32
35
|
* @param {Array<PageHeaderSecondaryActionType>} props.actions - The secondary actions to render
|
|
33
36
|
* @param {boolean} [props.hasPrimaryAction] - Whether there is a primary action present
|
|
34
37
|
* @param {boolean} [props.groupActions] - Whether to group actions in a More Menu regardless of action count
|
|
38
|
+
* @param {string} [props.className] - A custom class name for the action container
|
|
39
|
+
* @param {string} [props."data-testid"] - An ID used to locate the container in tests
|
|
40
|
+
* @param {object} [props.style] - Inline styles for the action container
|
|
41
|
+
* @param {unknown} [props.ref] - Ref for the action container element
|
|
35
42
|
* @returns {ReactElement | null} PageHeaderSecondaryActions component
|
|
36
43
|
*/
|
|
37
|
-
export declare const PageHeaderSecondaryActions: ({ actions, hasPrimaryAction, groupActions, }: PageHeaderSecondaryActionsProps) => ReactElement | null;
|
|
44
|
+
export declare const PageHeaderSecondaryActions: ({ actions, hasPrimaryAction, groupActions, className, "data-testid": dataTestId, style, ref, }: PageHeaderSecondaryActionsProps) => ReactElement | null;
|
|
38
45
|
export {};
|
|
@@ -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 {};
|