@trackunit/react-components 2.4.2-alpha-90b6c9b97dd.0 → 2.4.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 CHANGED
@@ -5586,6 +5586,93 @@ const KPICardSkeleton = ({ hasIcon = false, hasTrends = false, hasValueBar = fal
5586
5586
  return (jsxRuntime.jsx(Card, { className: cvaKPICard({ className }), "data-testid": dataTestId, ref: ref, style: style, ...rest, children: jsxRuntime.jsxs(CardBody, { className: cvaKPICardBody(), gap: "none", padding: "none", children: [jsxRuntime.jsxs("div", { className: cvaKPICardHeader(), children: [jsxRuntime.jsx(KPISkeleton, { className: "p-0", "data-testid": dataTestId ? `${dataTestId}-kpi` : undefined }), hasIcon ? (jsxRuntime.jsx(SkeletonBlock, { "data-testid": dataTestId ? `${dataTestId}-icon-loading` : undefined, height: 28, width: 28 })) : null] }), hasTrends ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-trend-indicator-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasValueBar ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-value-bar-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasNotice ? (jsxRuntime.jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-notice-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, children] }) }));
5587
5587
  };
5588
5588
 
5589
+ const cvaLabeledValue = cssClassVarianceUtilities.cvaMerge(["flex", "text-sm"], {
5590
+ variants: {
5591
+ orientation: {
5592
+ horizontal: ["flex-row", "items-start", "gap-6"],
5593
+ vertical: ["flex-col"],
5594
+ },
5595
+ },
5596
+ defaultVariants: {
5597
+ orientation: "horizontal",
5598
+ },
5599
+ });
5600
+ const cvaLabeledValueLabel = cssClassVarianceUtilities.cvaMerge(["font-medium", "text-neutral-500"], {
5601
+ variants: {
5602
+ orientation: {
5603
+ horizontal: ["min-w-[40%]", "max-w-[40%]"],
5604
+ vertical: ["mb-1"],
5605
+ },
5606
+ },
5607
+ defaultVariants: {
5608
+ orientation: "horizontal",
5609
+ },
5610
+ });
5611
+ const cvaLabeledValueValue = cssClassVarianceUtilities.cvaMerge(["min-w-0", "font-medium", "text-neutral-900"]);
5612
+ const cvaLabeledValueList = cssClassVarianceUtilities.cvaMerge(["flex", "flex-col", "gap-4"]);
5613
+ const cvaLabeledValueTooltip = cssClassVarianceUtilities.cvaMerge(["ml-1", "inline-flex", "align-sub"]);
5614
+
5615
+ /**
5616
+ * LabeledValue displays a single piece of labeled information, pairing a descriptive label with its corresponding value.
5617
+ * It provides a consistent way to present metadata, properties, or key details across cards, detail views, and side
5618
+ * panels, making information easy to scan and compare.
5619
+ *
5620
+ * ### When to use
5621
+ * Use LabeledValue to display a labelled value in a detail panel, card, or side panel. Compose several with `LabeledValueList`.
5622
+ *
5623
+ * ### When not to use
5624
+ * Do not use LabeledValue for a slash-separated inline list of metadata — use `DetailsList` instead. Do not use for tabular data with many rows and columns — use a table.
5625
+ *
5626
+ * @example Side-by-side labeled value
5627
+ * ```tsx
5628
+ * import { LabeledValue } from "@trackunit/react-components";
5629
+ *
5630
+ * const Detail = () => <LabeledValue label="Model" value="CAT 320" />;
5631
+ * ```
5632
+ * @param {LabeledValueProps} props - The props for the LabeledValue component
5633
+ * @returns {ReactElement} LabeledValue component
5634
+ */
5635
+ const LabeledValue = ({ label, labelTooltip, value, orientation = "horizontal", className, "data-testid": dataTestId, style, ref, }) => {
5636
+ const renderValue = () => {
5637
+ const valueIsEmpty = value === null || value === undefined || value === "" || typeof value === "boolean";
5638
+ if (valueIsEmpty) {
5639
+ return jsxRuntime.jsx(EmptyValue, { "data-testid": dataTestId ? `${dataTestId}-empty` : undefined });
5640
+ }
5641
+ return value;
5642
+ };
5643
+ return (jsxRuntime.jsxs("div", { className: cvaLabeledValue({ className, orientation }), "data-testid": dataTestId, ref: ref, style: style, children: [jsxRuntime.jsxs("div", { className: cvaLabeledValueLabel({ orientation }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: [jsxRuntime.jsx("span", { children: label }), labelTooltip !== undefined ? jsxRuntime.jsx("span", { className: cvaLabeledValueTooltip(), children: labelTooltip }) : null] }), jsxRuntime.jsx("div", { className: cvaLabeledValueValue(), "data-testid": dataTestId ? `${dataTestId}-value` : undefined, children: renderValue() })] }));
5644
+ };
5645
+
5646
+ /**
5647
+ * LabeledValueList renders a configurable set of side-by-side `LabeledValue`s from a data array, laid out in a responsive grid.
5648
+ * It is the data-driven counterpart to `LabeledValue`, suited to detail sections such as an asset-details or contract summary panel.
5649
+ *
5650
+ * ### When to use
5651
+ * Use LabeledValueList to render a section of labelled values from data.
5652
+ *
5653
+ * ### When not to use
5654
+ * Do not use LabeledValueList for a single pair — use `LabeledValue` directly.
5655
+ *
5656
+ * @example An asset-details section
5657
+ * ```tsx
5658
+ * import { LabeledValueList } from "@trackunit/react-components";
5659
+ *
5660
+ * const AssetDetails = () => (
5661
+ * <LabeledValueList
5662
+ * items={[
5663
+ * { label: "Model", value: "CAT 320" },
5664
+ * { label: "Serial number", value: "SN-00142" },
5665
+ * ]}
5666
+ * />
5667
+ * );
5668
+ * ```
5669
+ * @param {LabeledValueListProps} props - The props for the LabeledValueList component
5670
+ * @returns {ReactElement} LabeledValueList component
5671
+ */
5672
+ const LabeledValueList = ({ items, orientation = "horizontal", className, "data-testid": dataTestId, style, ref, }) => {
5673
+ return (jsxRuntime.jsx("div", { className: cvaLabeledValueList({ className }), "data-testid": dataTestId, ref: ref, style: style, children: items.map((item, index) => (jsxRuntime.jsx(LabeledValue, { orientation: orientation, ...item }, item["data-testid"] ?? `${item.label}-${index}`))) }));
5674
+ };
5675
+
5589
5676
  const cvaListContainer = cssClassVarianceUtilities.cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
5590
5677
  variants: {
5591
5678
  withTopSeparator: {
@@ -13386,6 +13473,8 @@ exports.KPI = KPI;
13386
13473
  exports.KPICard = KPICard;
13387
13474
  exports.KPICardSkeleton = KPICardSkeleton;
13388
13475
  exports.KPISkeleton = KPISkeleton;
13476
+ exports.LabeledValue = LabeledValue;
13477
+ exports.LabeledValueList = LabeledValueList;
13389
13478
  exports.List = List;
13390
13479
  exports.ListItem = ListItem;
13391
13480
  exports.MAX_HASH_LENGTH = MAX_HASH_LENGTH;
package/index.esm.js CHANGED
@@ -5584,6 +5584,93 @@ const KPICardSkeleton = ({ hasIcon = false, hasTrends = false, hasValueBar = fal
5584
5584
  return (jsx(Card, { className: cvaKPICard({ className }), "data-testid": dataTestId, ref: ref, style: style, ...rest, children: jsxs(CardBody, { className: cvaKPICardBody(), gap: "none", padding: "none", children: [jsxs("div", { className: cvaKPICardHeader(), children: [jsx(KPISkeleton, { className: "p-0", "data-testid": dataTestId ? `${dataTestId}-kpi` : undefined }), hasIcon ? (jsx(SkeletonBlock, { "data-testid": dataTestId ? `${dataTestId}-icon-loading` : undefined, height: 28, width: 28 })) : null] }), hasTrends ? (jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-trend-indicator-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasValueBar ? (jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-value-bar-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, hasNotice ? (jsx(SkeletonLabel, { "data-testid": dataTestId ? `${dataTestId}-notice-loading` : undefined, textSize: "text-xs", width: "100%" })) : null, children] }) }));
5585
5585
  };
5586
5586
 
5587
+ const cvaLabeledValue = cvaMerge(["flex", "text-sm"], {
5588
+ variants: {
5589
+ orientation: {
5590
+ horizontal: ["flex-row", "items-start", "gap-6"],
5591
+ vertical: ["flex-col"],
5592
+ },
5593
+ },
5594
+ defaultVariants: {
5595
+ orientation: "horizontal",
5596
+ },
5597
+ });
5598
+ const cvaLabeledValueLabel = cvaMerge(["font-medium", "text-neutral-500"], {
5599
+ variants: {
5600
+ orientation: {
5601
+ horizontal: ["min-w-[40%]", "max-w-[40%]"],
5602
+ vertical: ["mb-1"],
5603
+ },
5604
+ },
5605
+ defaultVariants: {
5606
+ orientation: "horizontal",
5607
+ },
5608
+ });
5609
+ const cvaLabeledValueValue = cvaMerge(["min-w-0", "font-medium", "text-neutral-900"]);
5610
+ const cvaLabeledValueList = cvaMerge(["flex", "flex-col", "gap-4"]);
5611
+ const cvaLabeledValueTooltip = cvaMerge(["ml-1", "inline-flex", "align-sub"]);
5612
+
5613
+ /**
5614
+ * LabeledValue displays a single piece of labeled information, pairing a descriptive label with its corresponding value.
5615
+ * It provides a consistent way to present metadata, properties, or key details across cards, detail views, and side
5616
+ * panels, making information easy to scan and compare.
5617
+ *
5618
+ * ### When to use
5619
+ * Use LabeledValue to display a labelled value in a detail panel, card, or side panel. Compose several with `LabeledValueList`.
5620
+ *
5621
+ * ### When not to use
5622
+ * Do not use LabeledValue for a slash-separated inline list of metadata — use `DetailsList` instead. Do not use for tabular data with many rows and columns — use a table.
5623
+ *
5624
+ * @example Side-by-side labeled value
5625
+ * ```tsx
5626
+ * import { LabeledValue } from "@trackunit/react-components";
5627
+ *
5628
+ * const Detail = () => <LabeledValue label="Model" value="CAT 320" />;
5629
+ * ```
5630
+ * @param {LabeledValueProps} props - The props for the LabeledValue component
5631
+ * @returns {ReactElement} LabeledValue component
5632
+ */
5633
+ const LabeledValue = ({ label, labelTooltip, value, orientation = "horizontal", className, "data-testid": dataTestId, style, ref, }) => {
5634
+ const renderValue = () => {
5635
+ const valueIsEmpty = value === null || value === undefined || value === "" || typeof value === "boolean";
5636
+ if (valueIsEmpty) {
5637
+ return jsx(EmptyValue, { "data-testid": dataTestId ? `${dataTestId}-empty` : undefined });
5638
+ }
5639
+ return value;
5640
+ };
5641
+ return (jsxs("div", { className: cvaLabeledValue({ className, orientation }), "data-testid": dataTestId, ref: ref, style: style, children: [jsxs("div", { className: cvaLabeledValueLabel({ orientation }), "data-testid": dataTestId ? `${dataTestId}-label` : undefined, children: [jsx("span", { children: label }), labelTooltip !== undefined ? jsx("span", { className: cvaLabeledValueTooltip(), children: labelTooltip }) : null] }), jsx("div", { className: cvaLabeledValueValue(), "data-testid": dataTestId ? `${dataTestId}-value` : undefined, children: renderValue() })] }));
5642
+ };
5643
+
5644
+ /**
5645
+ * LabeledValueList renders a configurable set of side-by-side `LabeledValue`s from a data array, laid out in a responsive grid.
5646
+ * It is the data-driven counterpart to `LabeledValue`, suited to detail sections such as an asset-details or contract summary panel.
5647
+ *
5648
+ * ### When to use
5649
+ * Use LabeledValueList to render a section of labelled values from data.
5650
+ *
5651
+ * ### When not to use
5652
+ * Do not use LabeledValueList for a single pair — use `LabeledValue` directly.
5653
+ *
5654
+ * @example An asset-details section
5655
+ * ```tsx
5656
+ * import { LabeledValueList } from "@trackunit/react-components";
5657
+ *
5658
+ * const AssetDetails = () => (
5659
+ * <LabeledValueList
5660
+ * items={[
5661
+ * { label: "Model", value: "CAT 320" },
5662
+ * { label: "Serial number", value: "SN-00142" },
5663
+ * ]}
5664
+ * />
5665
+ * );
5666
+ * ```
5667
+ * @param {LabeledValueListProps} props - The props for the LabeledValueList component
5668
+ * @returns {ReactElement} LabeledValueList component
5669
+ */
5670
+ const LabeledValueList = ({ items, orientation = "horizontal", className, "data-testid": dataTestId, style, ref, }) => {
5671
+ return (jsx("div", { className: cvaLabeledValueList({ className }), "data-testid": dataTestId, ref: ref, style: style, children: items.map((item, index) => (jsx(LabeledValue, { orientation: orientation, ...item }, item["data-testid"] ?? `${item.label}-${index}`))) }));
5672
+ };
5673
+
5587
5674
  const cvaListContainer = cvaMerge(["overflow-y-auto", "overflow-x-hidden", "h-full"], {
5588
5675
  variants: {
5589
5676
  withTopSeparator: {
@@ -13357,4 +13444,4 @@ const useWindowActivity = ({ onFocus, onBlur, skip = false } = { onBlur: undefin
13357
13444
  */
13358
13445
  setupLibraryTranslations();
13359
13446
 
13360
- 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_HASH_LENGTH, 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, useHashParamSync, 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 };
13447
+ 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, LabeledValue, LabeledValueList, List, ListItem, MAX_HASH_LENGTH, 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, useHashParamSync, 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,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "2.4.2-alpha-90b6c9b97dd.0",
3
+ "version": "2.4.2",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "migrations": "./migrations.json",
@@ -14,17 +14,17 @@
14
14
  "@floating-ui/react": "^0.26.25",
15
15
  "string-ts": "^2.0.0",
16
16
  "tailwind-merge": "^2.0.0",
17
- "@trackunit/ui-design-tokens": "1.13.91-alpha-90b6c9b97dd.0",
18
- "@trackunit/css-class-variance-utilities": "1.13.92-alpha-90b6c9b97dd.0",
19
- "@trackunit/shared-utils": "1.15.95-alpha-90b6c9b97dd.0",
20
- "@trackunit/ui-icons": "1.13.93-alpha-90b6c9b97dd.0",
17
+ "@trackunit/ui-design-tokens": "1.13.91",
18
+ "@trackunit/css-class-variance-utilities": "1.13.92",
19
+ "@trackunit/shared-utils": "1.15.95",
20
+ "@trackunit/ui-icons": "1.13.93",
21
21
  "es-toolkit": "^1.39.10",
22
22
  "@tanstack/react-virtual": "^3.14.3",
23
23
  "dequal": "^2.0.3",
24
24
  "fflate": "^0.8.2",
25
25
  "superjson": "^2.2.6",
26
26
  "zod": "^3.25.76",
27
- "@trackunit/i18n-library-translation": "2.2.7-alpha-90b6c9b97dd.0"
27
+ "@trackunit/i18n-library-translation": "2.2.7"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "react": "^19.0.0",
@@ -1,9 +1,9 @@
1
- import { InputHTMLAttributes, MouseEventHandler, ReactElement, ReactNode } from "react";
1
+ import { HTMLAttributes, MouseEventHandler, ReactElement, ReactNode } 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 declare const ROLE_CARD = "region";
6
- export interface CardProps extends CommonProps, Styleable, Refable<HTMLDivElement>, InputHTMLAttributes<HTMLDivElement> {
6
+ export interface CardProps extends CommonProps, Styleable, Refable<HTMLDivElement>, HTMLAttributes<HTMLDivElement> {
7
7
  /**
8
8
  * Whether the card should have full height or not.
9
9
  */
@@ -0,0 +1,45 @@
1
+ import { ReactElement, ReactNode } from "react";
2
+ import { CommonProps } from "../../common/CommonProps";
3
+ import { Refable } from "../../common/Refable";
4
+ import type { Styleable } from "../../common/Styleable";
5
+ export type LabeledValueOrientation = "horizontal" | "vertical";
6
+ export interface LabeledValueProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
7
+ /**
8
+ * The label (the "key" of the key/value pair).
9
+ */
10
+ label: string;
11
+ /**
12
+ * Optional content rendered next to the label, typically a help `Tooltip` describing the field.
13
+ */
14
+ labelTooltip?: ReactNode;
15
+ /**
16
+ * The value shown. Renders an `EmptyValue` dash when null, undefined, an empty string, or a
17
+ * boolean (booleans are not directly renderable — format them to a string before passing).
18
+ */
19
+ value?: ReactNode;
20
+ /**
21
+ * Layout of the pair. `horizontal` (default) renders label and value side-by-side; `vertical` stacks the value under the label.
22
+ */
23
+ orientation?: LabeledValueOrientation;
24
+ }
25
+ /**
26
+ * LabeledValue displays a single piece of labeled information, pairing a descriptive label with its corresponding value.
27
+ * It provides a consistent way to present metadata, properties, or key details across cards, detail views, and side
28
+ * panels, making information easy to scan and compare.
29
+ *
30
+ * ### When to use
31
+ * Use LabeledValue to display a labelled value in a detail panel, card, or side panel. Compose several with `LabeledValueList`.
32
+ *
33
+ * ### When not to use
34
+ * Do not use LabeledValue for a slash-separated inline list of metadata — use `DetailsList` instead. Do not use for tabular data with many rows and columns — use a table.
35
+ *
36
+ * @example Side-by-side labeled value
37
+ * ```tsx
38
+ * import { LabeledValue } from "@trackunit/react-components";
39
+ *
40
+ * const Detail = () => <LabeledValue label="Model" value="CAT 320" />;
41
+ * ```
42
+ * @param {LabeledValueProps} props - The props for the LabeledValue component
43
+ * @returns {ReactElement} LabeledValue component
44
+ */
45
+ export declare const LabeledValue: ({ label, labelTooltip, value, orientation, className, "data-testid": dataTestId, style, ref, }: LabeledValueProps) => ReactElement;
@@ -0,0 +1,9 @@
1
+ export declare const cvaLabeledValue: (props?: ({
2
+ orientation?: "horizontal" | "vertical" | null | undefined;
3
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
4
+ export declare const cvaLabeledValueLabel: (props?: ({
5
+ orientation?: "horizontal" | "vertical" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ export declare const cvaLabeledValueValue: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
8
+ export declare const cvaLabeledValueList: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
9
+ export declare const cvaLabeledValueTooltip: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
@@ -0,0 +1,42 @@
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 { LabeledValueOrientation, LabeledValueProps } from "./LabeledValue";
6
+ export interface LabeledValueListProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
7
+ /**
8
+ * The labeled values to render. Each item accepts the full `LabeledValue` props.
9
+ */
10
+ items: Array<LabeledValueProps>;
11
+ /**
12
+ * Layout of each pair, forwarded to every `LabeledValue` (unless the item sets its own). Defaults to `horizontal`.
13
+ */
14
+ orientation?: LabeledValueOrientation;
15
+ }
16
+ /**
17
+ * LabeledValueList renders a configurable set of side-by-side `LabeledValue`s from a data array, laid out in a responsive grid.
18
+ * It is the data-driven counterpart to `LabeledValue`, suited to detail sections such as an asset-details or contract summary panel.
19
+ *
20
+ * ### When to use
21
+ * Use LabeledValueList to render a section of labelled values from data.
22
+ *
23
+ * ### When not to use
24
+ * Do not use LabeledValueList for a single pair — use `LabeledValue` directly.
25
+ *
26
+ * @example An asset-details section
27
+ * ```tsx
28
+ * import { LabeledValueList } from "@trackunit/react-components";
29
+ *
30
+ * const AssetDetails = () => (
31
+ * <LabeledValueList
32
+ * items={[
33
+ * { label: "Model", value: "CAT 320" },
34
+ * { label: "Serial number", value: "SN-00142" },
35
+ * ]}
36
+ * />
37
+ * );
38
+ * ```
39
+ * @param {LabeledValueListProps} props - The props for the LabeledValueList component
40
+ * @returns {ReactElement} LabeledValueList component
41
+ */
42
+ export declare const LabeledValueList: ({ items, orientation, className, "data-testid": dataTestId, style, ref, }: LabeledValueListProps) => ReactElement;
package/src/index.d.ts CHANGED
@@ -44,6 +44,8 @@ export * from "./components/KPICard/components/TrendIndicator/TrendIndicator";
44
44
  export * from "./components/KPICard/components/TrendIndicators";
45
45
  export * from "./components/KPICard/KPICard";
46
46
  export * from "./components/KPICard/KPICardSkeleton";
47
+ export * from "./components/LabeledValue/LabeledValue";
48
+ export * from "./components/LabeledValue/LabeledValueList";
47
49
  export * from "./components/List/List";
48
50
  export * from "./components/List/List.variants";
49
51
  export * from "./components/List/useList";