@trackunit/react-components 3.1.7 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
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
+ export interface IdentityCardSkeletonProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
6
+ /**
7
+ * When true, renders an image slot with a size-matched skeleton block. The
8
+ * slot's height tracks the rendered text stack at a 14:9 aspect ratio
9
+ * (168/108, matching `AssetPageHeader`) — same measurement approach as
10
+ * the loaded `IdentityCard` so the skeleton → loaded transition doesn't
11
+ * jump.
12
+ *
13
+ * Mutually exclusive with `hasThumbnail` — `hasImage` wins if both
14
+ * are true (mirrors the loaded card's slot precedence).
15
+ *
16
+ * @default false
17
+ */
18
+ hasImage?: boolean;
19
+ /**
20
+ * When true, renders a 44×44 rounded-md skeleton badge in the thumbnail
21
+ * slot — the loading counterpart to the loaded card's `thumbnail` prop.
22
+ * Use for non-asset entities (sites, customers, users, …).
23
+ *
24
+ * Mutually exclusive with `hasImage` — `hasImage` wins if both are true.
25
+ *
26
+ * @default false
27
+ */
28
+ hasThumbnail?: boolean;
29
+ /**
30
+ * When true, renders a subtitle skeleton line under the title. Kept on by
31
+ * default so `<IdentityCardSkeleton />` with no props renders the
32
+ * canonical compact identity card shape (title + subtitle).
33
+ *
34
+ * @default true
35
+ */
36
+ hasSubtitle?: boolean;
37
+ /**
38
+ * When true, renders a status-row skeleton (two chip placeholders) under
39
+ * the identity group.
40
+ *
41
+ * @default false
42
+ */
43
+ hasStatusIndicators?: boolean;
44
+ /**
45
+ * When true, renders a right-side connectivity skeleton on the title row.
46
+ *
47
+ * @default false
48
+ */
49
+ hasConnectivity?: boolean;
50
+ /**
51
+ * When true, renders the same right-side `ChevronRight` as a clickable
52
+ * `IdentityCard` — the icon is known up front, so it is not skeletoned.
53
+ * Keeps the skeleton → loaded transition from jumping.
54
+ *
55
+ * @default false
56
+ */
57
+ hasChevron?: boolean;
58
+ }
59
+ /**
60
+ * IdentityCardSkeleton is the loading placeholder paired with
61
+ * `IdentityCard`. It renders per-slot skeleton blocks (title +
62
+ * optional subtitle / status indicators / image / thumbnail / connectivity)
63
+ * inside the same `Card` shell so the skeleton → loaded
64
+ * transition is visually stable. When `hasChevron` is on, the real
65
+ * `ChevronRight` is shown — that icon does not depend on loaded data.
66
+ *
67
+ * The slot toggles (`hasImage`, `hasThumbnail`, `hasSubtitle`,
68
+ * `hasStatusIndicators`, `hasConnectivity`, `hasChevron`) are the skeleton
69
+ * counterparts to the loaded `IdentityCard`'s slot props / `onClick` —
70
+ * flip on the slots you'll render once the data resolves.
71
+ *
72
+ * ### When to use
73
+ * Use `IdentityCardSkeleton` in place of `IdentityCard` while
74
+ * the referenced entity's data is being fetched.
75
+ *
76
+ * ### When not to use
77
+ * Do not use for generic text loading — use `SkeletonLabel` /
78
+ * `SkeletonBlock` directly. Do not use to represent partial data (some
79
+ * fields loaded, others not); render `IdentityCard` with the fields
80
+ * you have and omit the rest.
81
+ *
82
+ * @example Compact card (title + subtitle)
83
+ * ```tsx
84
+ * import { IdentityCardSkeleton } from "@trackunit/react-components";
85
+ *
86
+ * const Loading = () => <IdentityCardSkeleton />;
87
+ * ```
88
+ * @example Clickable card with image + status + connectivity
89
+ * ```tsx
90
+ * <IdentityCardSkeleton hasImage hasStatusIndicators hasConnectivity hasChevron />
91
+ * ```
92
+ * @param {IdentityCardSkeletonProps} props - The props for the IdentityCardSkeleton component
93
+ * @returns {ReactElement} IdentityCardSkeleton component
94
+ */
95
+ export declare const IdentityCardSkeleton: ({ hasImage, hasThumbnail, hasSubtitle, hasStatusIndicators, hasConnectivity, hasChevron, className, "data-testid": dataTestId, style, ref, }: IdentityCardSkeletonProps) => ReactElement;
@@ -0,0 +1,32 @@
1
+ import { type RefCallback } from "react";
2
+ export declare const IDENTITY_MIN_IMAGE_HEIGHT_PX = 44;
3
+ export declare const IDENTITY_IMAGE_ASPECT_RATIO: number;
4
+ export type IdentityImageSize = {
5
+ readonly height: number;
6
+ readonly width: number;
7
+ };
8
+ export type IdentityImageSizeResult = {
9
+ readonly imageSize: IdentityImageSize | null;
10
+ readonly textStackRef: RefCallback<HTMLDivElement>;
11
+ };
12
+ /**
13
+ * Measures the rendered text-stack height and returns matching image
14
+ * dimensions at a 14:9 (168/108) aspect ratio, clamped to the identity
15
+ * minimum so title-only identities keep a reasonable image footprint. Kept
16
+ * as a shared hook so the loaded `IdentityCard` and its `IdentityCardSkeleton`
17
+ * cannot drift out of sync — the skeleton → loaded transition would jump
18
+ * if the two measurements diverged.
19
+ *
20
+ * Measured in `useLayoutEffect` so the image slot is sized before the
21
+ * browser paints. `useMeasure` is the usual choice here, but it observes
22
+ * in `useEffect` (after paint), which would flash the unsized
23
+ * `aspect-[14/9]` fallback for a frame.
24
+ *
25
+ * Attach `textStackRef` to the text-stack container; subsequent layout
26
+ * changes (title text, subtitle wrap, status row toggling on/off)
27
+ * re-measure automatically.
28
+ *
29
+ * @param enabled - When false, the hook is inert (no measurement). Use this
30
+ * to gate on `showImage` / `hasImage`.
31
+ */
32
+ export declare const useIdentityImageSize: (enabled: boolean) => IdentityImageSizeResult;
@@ -1,8 +1,8 @@
1
1
  import { ActivityColors, CriticalityColors, GeneralColors, IntentColors, RentalStatusColors, SitesColors, UtilizationColors } from "@trackunit/ui-design-tokens";
2
- import { ReactElement } from "react";
2
+ import { ReactElement, ReactNode } from "react";
3
3
  import { CommonProps } from "../../common/CommonProps";
4
- import type { Styleable } from "../../common/Styleable";
5
4
  import { Refable } from "../../common/Refable";
5
+ import type { Styleable } from "../../common/Styleable";
6
6
  export interface IndicatorProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
7
7
  /**
8
8
  * The icon to be rendered inside the indicator component
@@ -21,9 +21,9 @@ export interface IndicatorProps extends CommonProps, Styleable, Refable<HTMLDivE
21
21
  */
22
22
  weight?: "normal" | "medium";
23
23
  /**
24
- * A text label to be displayed next to the indicator
24
+ * Content displayed next to the indicator. String labels are capitalized; custom content retains its own casing.
25
25
  */
26
- label?: string;
26
+ label?: ReactNode;
27
27
  /**
28
28
  * A boolean parameter to display or hide icon background, default value is true
29
29
  */
@@ -11,8 +11,11 @@ export declare const cvaIndicatorIcon: import("cva").CVAComponent<Omit<{
11
11
  defaultVariants: Omit<{}, never>;
12
12
  }, unknown>;
13
13
  export declare const cvaIndicatorLabel: import("cva").CVAComponent<Omit<{
14
- base: string[];
15
14
  variants: {
15
+ content: {
16
+ text: string;
17
+ custom: null;
18
+ };
16
19
  size: {
17
20
  small: string;
18
21
  medium: string;
@@ -27,12 +30,17 @@ export declare const cvaIndicatorLabel: import("cva").CVAComponent<Omit<{
27
30
  };
28
31
  };
29
32
  defaultVariants: {
33
+ content: "text";
30
34
  size: "medium";
31
35
  weight: "medium";
32
36
  background: "visible";
33
37
  };
34
38
  }, "defaultVariants"> & {
35
39
  variants: {
40
+ content: {
41
+ text: string;
42
+ custom: null;
43
+ };
36
44
  size: {
37
45
  small: string;
38
46
  medium: string;
@@ -46,12 +54,17 @@ export declare const cvaIndicatorLabel: import("cva").CVAComponent<Omit<{
46
54
  hidden: string;
47
55
  };
48
56
  };
49
- defaultVariants: Omit<{}, "size" | "weight" | "background"> & {
57
+ defaultVariants: Omit<{}, "content" | "size" | "weight" | "background"> & {
58
+ content: "text";
50
59
  size: "medium";
51
60
  weight: "medium";
52
61
  background: "visible";
53
62
  };
54
63
  }, {
64
+ content: {
65
+ text: string;
66
+ custom: null;
67
+ };
55
68
  size: {
56
69
  small: string;
57
70
  medium: string;
package/src/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export * from "./common/Size";
7
7
  export * from "./common/StorybookProps";
8
8
  export type { Styleable } from "./common/Styleable";
9
9
  export * from "./components/Alert/Alert";
10
+ export * from "./components/AssetIdentity/IdentityCard";
11
+ export * from "./components/AssetIdentity/IdentityCardSkeleton";
10
12
  export * from "./components/Badge/Badge";
11
13
  export * from "./components/Breadcrumb/Breadcrumb";
12
14
  export * from "./components/buttons/Button/Button";