@zedtech/zedkit-ui 0.2.0 → 0.3.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.
Files changed (44) hide show
  1. package/dist/card-skeleton.d.ts +10 -0
  2. package/dist/card-skeleton.d.ts.map +1 -0
  3. package/dist/card-skeleton.js +11 -0
  4. package/dist/card-skeleton.js.map +1 -0
  5. package/dist/data-table-skeleton.d.ts +14 -0
  6. package/dist/data-table-skeleton.d.ts.map +1 -0
  7. package/dist/data-table-skeleton.js +13 -0
  8. package/dist/data-table-skeleton.js.map +1 -0
  9. package/dist/detail-panel-skeleton.d.ts +11 -0
  10. package/dist/detail-panel-skeleton.d.ts.map +1 -0
  11. package/dist/detail-panel-skeleton.js +11 -0
  12. package/dist/detail-panel-skeleton.js.map +1 -0
  13. package/dist/dialog.d.ts.map +1 -1
  14. package/dist/dialog.js +2 -2
  15. package/dist/dialog.js.map +1 -1
  16. package/dist/index.d.ts +6 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +6 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/page-header-skeleton.d.ts +12 -0
  21. package/dist/page-header-skeleton.d.ts.map +1 -0
  22. package/dist/page-header-skeleton.js +11 -0
  23. package/dist/page-header-skeleton.js.map +1 -0
  24. package/dist/skeleton.js +1 -1
  25. package/dist/skeleton.js.map +1 -1
  26. package/dist/status-label.d.ts +13 -0
  27. package/dist/status-label.d.ts.map +1 -0
  28. package/dist/status-label.js +30 -0
  29. package/dist/status-label.js.map +1 -0
  30. package/dist/updated-ago.d.ts +13 -0
  31. package/dist/updated-ago.d.ts.map +1 -0
  32. package/dist/updated-ago.js +29 -0
  33. package/dist/updated-ago.js.map +1 -0
  34. package/package.json +2 -2
  35. package/src/card-skeleton.tsx +31 -0
  36. package/src/data-table-skeleton.tsx +53 -0
  37. package/src/detail-panel-skeleton.tsx +29 -0
  38. package/src/dialog.tsx +8 -1
  39. package/src/index.ts +6 -0
  40. package/src/page-header-skeleton.tsx +39 -0
  41. package/src/skeleton.tsx +1 -1
  42. package/src/status-label.tsx +53 -0
  43. package/src/styles.css +61 -0
  44. package/src/updated-ago.tsx +38 -0
@@ -0,0 +1,10 @@
1
+ export interface CardSkeletonProps {
2
+ label?: string;
3
+ className?: string;
4
+ }
5
+ /**
6
+ * Faithful loading shape of Card: header block plus three text lines
7
+ * in the same bordered box, so content lands without shifting.
8
+ */
9
+ export declare function CardSkeleton({ label, className }: CardSkeletonProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=card-skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-skeleton.d.ts","sourceRoot":"","sources":["../src/card-skeleton.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAiB,EAAE,SAAS,EAAE,EAAE,iBAAiB,+BAkB/E"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Skeleton } from "./skeleton.js";
3
+ import { cn } from "./utils.js";
4
+ /**
5
+ * Faithful loading shape of Card: header block plus three text lines
6
+ * in the same bordered box, so content lands without shifting.
7
+ */
8
+ export function CardSkeleton({ label = "Loading", className }) {
9
+ return (_jsxs("div", { role: "status", "aria-label": label, className: cn("rounded-xl border bg-card p-6 shadow", className), children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx(Skeleton, { className: "h-5 w-1/3" }), _jsx(Skeleton, { className: "h-4 w-2/3" })] }), _jsxs("div", { className: "mt-4 space-y-2", children: [_jsx(Skeleton, { className: "h-4 w-full" }), _jsx(Skeleton, { className: "h-4 w-full" }), _jsx(Skeleton, { className: "h-4 w-4/5" })] })] }));
10
+ }
11
+ //# sourceMappingURL=card-skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-skeleton.js","sourceRoot":"","sources":["../src/card-skeleton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAOhC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,SAAS,EAAqB;IAC9E,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,SAAS,EAAE,EAAE,CAAC,sCAAsC,EAAE,SAAS,CAAC,aAEhE,eAAK,SAAS,EAAC,aAAa,aAC1B,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,EAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,EACN,eAAK,SAAS,EAAC,gBAAgB,aAC7B,KAAC,QAAQ,IAAC,SAAS,EAAC,YAAY,GAAG,EACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,YAAY,GAAG,EACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface DataTableSkeletonProps {
2
+ label?: string;
3
+ columns?: number;
4
+ rows?: number;
5
+ filter?: boolean;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * Standalone loading shape of DataTable for Suspense fallbacks: filter
10
+ * slot plus a headed table of skeleton rows. (DataTable's own inline
11
+ * loading state stays untouched inside the table body.)
12
+ */
13
+ export declare function DataTableSkeleton({ label, columns, rows, filter, className, }: DataTableSkeletonProps): import("react").JSX.Element;
14
+ //# sourceMappingURL=data-table-skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-skeleton.d.ts","sourceRoot":"","sources":["../src/data-table-skeleton.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAiB,EACjB,OAAW,EACX,IAAQ,EACR,MAAa,EACb,SAAS,GACV,EAAE,sBAAsB,+BA6BxB"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Skeleton } from "./skeleton.js";
3
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
4
+ import { cn } from "./utils.js";
5
+ /**
6
+ * Standalone loading shape of DataTable for Suspense fallbacks: filter
7
+ * slot plus a headed table of skeleton rows. (DataTable's own inline
8
+ * loading state stays untouched inside the table body.)
9
+ */
10
+ export function DataTableSkeleton({ label = "Loading", columns = 4, rows = 3, filter = true, className, }) {
11
+ return (_jsxs("div", { role: "status", "aria-label": label, className: cn("space-y-4", className), children: [filter ? _jsx(Skeleton, { className: "h-9 max-w-sm" }) : null, _jsxs(Table, { "aria-hidden": true, children: [_jsx(TableHeader, { children: _jsx(TableRow, { children: Array.from({ length: columns }, (_, index) => (_jsx(TableHead, { children: _jsx(Skeleton, { className: "h-4 w-2/3" }) }, index))) }) }), _jsx(TableBody, { children: Array.from({ length: rows }, (_, row) => (_jsx(TableRow, { children: Array.from({ length: columns }, (_, column) => (_jsx(TableCell, { children: _jsx(Skeleton, { className: "h-4 w-full" }) }, column))) }, row))) })] })] }));
12
+ }
13
+ //# sourceMappingURL=data-table-skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table-skeleton.js","sourceRoot":"","sources":["../src/data-table-skeleton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAUhC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,CAAC,EACX,IAAI,GAAG,CAAC,EACR,MAAM,GAAG,IAAI,EACb,SAAS,GACc;IACvB,OAAO,CACL,eAAK,IAAI,EAAC,QAAQ,gBAAa,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,aACxE,MAAM,CAAC,CAAC,CAAC,KAAC,QAAQ,IAAC,SAAS,EAAC,cAAc,GAAG,CAAC,CAAC,CAAC,IAAI,EAEtD,MAAC,KAAK,oCACJ,KAAC,WAAW,cACV,KAAC,QAAQ,cACN,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC7C,KAAC,SAAS,cACR,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IADpB,KAAK,CAET,CACb,CAAC,GACO,GACC,EACd,KAAC,SAAS,cACP,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CACxC,KAAC,QAAQ,cACN,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,CAC9C,KAAC,SAAS,cACR,KAAC,QAAQ,IAAC,SAAS,EAAC,YAAY,GAAG,IADrB,MAAM,CAEV,CACb,CAAC,IALW,GAAG,CAMP,CACZ,CAAC,GACQ,IACN,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface DetailPanelSkeletonProps {
2
+ label?: string;
3
+ rows?: number;
4
+ className?: string;
5
+ }
6
+ /**
7
+ * Faithful loading shape of DetailPanel: label/value skeleton pairs
8
+ * in the same divided box, so rows land without shifting.
9
+ */
10
+ export declare function DetailPanelSkeleton({ label, rows, className }: DetailPanelSkeletonProps): import("react").JSX.Element;
11
+ //# sourceMappingURL=detail-panel-skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detail-panel-skeleton.d.ts","sourceRoot":"","sources":["../src/detail-panel-skeleton.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,KAAiB,EAAE,IAAQ,EAAE,SAAS,EAAE,EAAE,wBAAwB,+BAevG"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Skeleton } from "./skeleton.js";
3
+ import { cn } from "./utils.js";
4
+ /**
5
+ * Faithful loading shape of DetailPanel: label/value skeleton pairs
6
+ * in the same divided box, so rows land without shifting.
7
+ */
8
+ export function DetailPanelSkeleton({ label = "Loading", rows = 4, className }) {
9
+ return (_jsx("div", { role: "status", "aria-label": label, className: cn("divide-y divide-border rounded-lg border", className), children: Array.from({ length: rows }, (_, index) => (_jsxs("div", { className: "grid grid-cols-3 gap-4 px-4 py-3", children: [_jsx(Skeleton, { className: "h-4 w-20" }), _jsx(Skeleton, { className: "col-span-2 h-4 w-2/3" })] }, index))) }));
10
+ }
11
+ //# sourceMappingURL=detail-panel-skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detail-panel-skeleton.js","sourceRoot":"","sources":["../src/detail-panel-skeleton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAQhC;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,GAAG,CAAC,EAAE,SAAS,EAA4B;IACtG,OAAO,CACL,cACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,SAAS,EAAE,EAAE,CAAC,0CAA0C,EAAE,SAAS,CAAC,YAEnE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1C,eAAiB,SAAS,EAAC,kCAAkC,aAC3D,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,sBAAsB,GAAG,KAFrC,KAAK,CAGT,CACP,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../src/dialog.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAI1D,QAAA,MAAM,MAAM,uCAAuB,CAAC;AACpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAC9C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAC1C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,aAAa,8JASjB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAqBjB,CAAC;AAGH,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,qBAOlF;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,qBAOlF;AAED,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,GACd,CAAC"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../src/dialog.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAI1D,QAAA,MAAM,MAAM,uCAAuB,CAAC;AACpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAC9C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAC1C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,aAAa,8JAcjB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAuBjB,CAAC;AAGH,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,qBAOlF;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,qBAOlF;AAED,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,GACd,CAAC"}
package/dist/dialog.js CHANGED
@@ -9,9 +9,9 @@ const Dialog = DialogPrimitive.Root;
9
9
  const DialogTrigger = DialogPrimitive.Trigger;
10
10
  const DialogClose = DialogPrimitive.Close;
11
11
  const DialogPortal = DialogPrimitive.Portal;
12
- const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn("fixed inset-0 z-50 bg-overlay/80", className), ...props })));
12
+ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn("fixed inset-0 z-50 bg-overlay/80", "motion-safe:data-[state=open]:animate-[zk-fade-in_var(--motion-base)_var(--ease-enter)]", "motion-safe:data-[state=closed]:animate-[zk-fade-out_var(--motion-base)_var(--ease-exit)]", className), ...props })));
13
13
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
14
- const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg", className), ...props, children: [children, _jsxs(DialogPrimitive.Close, { className: "absolute top-4 right-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [_jsx(X, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "Close" })] })] })] })));
14
+ const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg", "motion-safe:data-[state=open]:animate-[zk-zoom-in_var(--motion-base)_var(--ease-enter)]", "motion-safe:data-[state=closed]:animate-[zk-zoom-out_var(--motion-base)_var(--ease-exit)]", className), ...props, children: [children, _jsxs(DialogPrimitive.Close, { className: "absolute top-4 right-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [_jsx(X, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "Close" })] })] })] })));
15
15
  DialogContent.displayName = DialogPrimitive.Content.displayName;
16
16
  function DialogHeader({ className, ...props }) {
17
17
  return (_jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props }));
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../src/dialog.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../src/dialog.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export { LivePulse, type LivePulseProps } from "./live-pulse.js";
20
20
  export { StatusDot, type StatusDotProps, type StatusDotTone } from "./status-dot.js";
21
21
  export { ProgressBar, type ProgressBarProps } from "./progress-bar.js";
22
22
  export { Checkmark, type CheckmarkProps } from "./checkmark.js";
23
+ export { StatusLabel, type StatusLabelProps, type StatusLabelTone } from "./status-label.js";
24
+ export { UpdatedAgo, type UpdatedAgoProps } from "./updated-ago.js";
23
25
  export { OptionCards, type OptionCard, type OptionCardsProps } from "./option-cards.js";
24
26
  export { PageHeader, type PageHeaderProps } from "./page-header.js";
25
27
  export { SecretField, type SecretFieldProps } from "./secret-field.js";
@@ -34,4 +36,8 @@ export { Textarea } from "./textarea.js";
34
36
  export { Toaster } from "./sonner.js";
35
37
  export { Heading, headingVariants, Text, textVariants, type HeadingProps, type TextProps, } from "./typography.js";
36
38
  export { cn } from "./utils.js";
39
+ export { CardSkeleton, type CardSkeletonProps } from "./card-skeleton.js";
40
+ export { DataTableSkeleton, type DataTableSkeletonProps } from "./data-table-skeleton.js";
41
+ export { DetailPanelSkeleton, type DetailPanelSkeletonProps } from "./detail-panel-skeleton.js";
42
+ export { PageHeaderSkeleton, type PageHeaderSkeletonProps } from "./page-header-skeleton.js";
37
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,6 +20,8 @@ export { LivePulse } from "./live-pulse.js";
20
20
  export { StatusDot } from "./status-dot.js";
21
21
  export { ProgressBar } from "./progress-bar.js";
22
22
  export { Checkmark } from "./checkmark.js";
23
+ export { StatusLabel } from "./status-label.js";
24
+ export { UpdatedAgo } from "./updated-ago.js";
23
25
  export { OptionCards } from "./option-cards.js";
24
26
  export { PageHeader } from "./page-header.js";
25
27
  export { SecretField } from "./secret-field.js";
@@ -34,4 +36,8 @@ export { Textarea } from "./textarea.js";
34
36
  export { Toaster } from "./sonner.js";
35
37
  export { Heading, headingVariants, Text, textVariants, } from "./typography.js";
36
38
  export { cn } from "./utils.js";
39
+ export { CardSkeleton } from "./card-skeleton.js";
40
+ export { DataTableSkeleton } from "./data-table-skeleton.js";
41
+ export { DetailPanelSkeleton } from "./detail-panel-skeleton.js";
42
+ export { PageHeaderSkeleton } from "./page-header-skeleton.js";
37
43
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface PageHeaderSkeletonProps {
2
+ label?: string;
3
+ description?: boolean;
4
+ actions?: boolean;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Faithful loading shape of PageHeader: title, optional description
9
+ * and action slots. Same box, no layout shift when content lands.
10
+ */
11
+ export declare function PageHeaderSkeleton({ label, description, actions, className, }: PageHeaderSkeletonProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=page-header-skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-header-skeleton.d.ts","sourceRoot":"","sources":["../src/page-header-skeleton.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAiB,EACjB,WAAkB,EAClB,OAAc,EACd,SAAS,GACV,EAAE,uBAAuB,+BAmBzB"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Skeleton } from "./skeleton.js";
3
+ import { cn } from "./utils.js";
4
+ /**
5
+ * Faithful loading shape of PageHeader: title, optional description
6
+ * and action slots. Same box, no layout shift when content lands.
7
+ */
8
+ export function PageHeaderSkeleton({ label = "Loading", description = true, actions = true, className, }) {
9
+ return (_jsxs("div", { role: "status", "aria-label": label, className: cn("mb-6 flex flex-wrap items-start justify-between gap-4", className), children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Skeleton, { className: "h-7 w-48" }), description ? _jsx(Skeleton, { className: "h-4 w-64" }) : null] }), actions ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Skeleton, { className: "h-9 w-24" }), _jsx(Skeleton, { className: "h-9 w-24" })] })) : null] }));
10
+ }
11
+ //# sourceMappingURL=page-header-skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-header-skeleton.js","sourceRoot":"","sources":["../src/page-header-skeleton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAShC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,GAAG,SAAS,EACjB,WAAW,GAAG,IAAI,EAClB,OAAO,GAAG,IAAI,EACd,SAAS,GACe;IACxB,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,SAAS,EAAE,EAAE,CAAC,uDAAuD,EAAE,SAAS,CAAC,aAEjF,eAAK,SAAS,EAAC,WAAW,aACxB,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EAChC,WAAW,CAAC,CAAC,CAAC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,IACnD,EACL,OAAO,CAAC,CAAC,CAAC,CACT,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
package/dist/skeleton.js CHANGED
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  // Derived from shadcn/ui (skeleton) — see Provenance in packages/ui/README.md. Tolerated exception: migrated to custom code only when customization needs it.
3
3
  import { cn } from "./utils.js";
4
4
  function Skeleton({ className, ...props }) {
5
- return _jsx("div", { className: cn("animate-pulse rounded-md bg-muted", className), ...props });
5
+ return _jsx("div", { className: cn("rounded-md bg-muted motion-safe:animate-pulse", className), ...props });
6
6
  }
7
7
  export { Skeleton };
8
8
  //# sourceMappingURL=skeleton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../src/skeleton.tsx"],"names":[],"mappings":";AAAA,8JAA8J;AAC9J,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAEhC,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAwC;IAC7E,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,mCAAmC,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAC;AAC3F,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../src/skeleton.tsx"],"names":[],"mappings":";AAAA,8JAA8J;AAC9J,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAEhC,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAwC;IAC7E,OAAO,cAAK,SAAS,EAAE,EAAE,CAAC,+CAA+C,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAAC;AACvG,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ export type StatusLabelTone = "loading" | "updating" | "syncing" | "saved" | "retry" | "error" | "offline";
2
+ export interface StatusLabelProps {
3
+ tone: StatusLabelTone;
4
+ children: React.ReactNode;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Named inline status: icon + text, announced politely (`role=status`).
9
+ * Name the operation ("Saving report…", not "Loading…") so a worried
10
+ * user always knows what is happening and where.
11
+ */
12
+ export declare function StatusLabel({ tone, children, className }: StatusLabelProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=status-label.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-label.d.ts","sourceRoot":"","sources":["../src/status-label.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3G,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BAgB1E"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { WifiOff } from "lucide-react";
3
+ import { Checkmark } from "./checkmark.js";
4
+ import { StatusDot } from "./status-dot.js";
5
+ import { cn } from "./utils.js";
6
+ function ToneIcon({ tone }) {
7
+ switch (tone) {
8
+ case "saved":
9
+ return _jsx(Checkmark, {});
10
+ case "retry":
11
+ return _jsx(StatusDot, { tone: "warning" });
12
+ case "error":
13
+ return _jsx(StatusDot, { tone: "danger" });
14
+ case "offline":
15
+ return _jsx(WifiOff, { "aria-hidden": true, className: "size-3.5 text-muted-foreground" });
16
+ case "loading":
17
+ case "updating":
18
+ case "syncing":
19
+ return _jsx(StatusDot, { tone: "active" });
20
+ }
21
+ }
22
+ /**
23
+ * Named inline status: icon + text, announced politely (`role=status`).
24
+ * Name the operation ("Saving report…", not "Loading…") so a worried
25
+ * user always knows what is happening and where.
26
+ */
27
+ export function StatusLabel({ tone, children, className }) {
28
+ return (_jsxs("span", { role: "status", className: cn("inline-flex items-center gap-1.5 text-xs", tone === "error" ? "text-destructive" : "text-muted-foreground", className), children: [_jsx("span", { className: "flex size-4 shrink-0 items-center justify-center", children: _jsx(ToneIcon, { tone: tone }) }), children] }));
29
+ }
30
+ //# sourceMappingURL=status-label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-label.js","sourceRoot":"","sources":["../src/status-label.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAUhC,SAAS,QAAQ,CAAC,EAAE,IAAI,EAA6B;IACnD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,KAAC,SAAS,KAAG,CAAC;QACvB,KAAK,OAAO;YACV,OAAO,KAAC,SAAS,IAAC,IAAI,EAAC,SAAS,GAAG,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,KAAC,SAAS,IAAC,IAAI,EAAC,QAAQ,GAAG,CAAC;QACrC,KAAK,SAAS;YACZ,OAAO,KAAC,OAAO,yBAAa,SAAS,EAAC,gCAAgC,GAAG,CAAC;QAC5E,KAAK,SAAS,CAAC;QACf,KAAK,UAAU,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,KAAC,SAAS,IAAC,IAAI,EAAC,QAAQ,GAAG,CAAC;IACvC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAoB;IACzE,OAAO,CACL,gBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CACX,0CAA0C,EAC1C,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,uBAAuB,EAC/D,SAAS,CACV,aAED,eAAM,SAAS,EAAC,kDAAkD,YAChE,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,GAAI,GACnB,EACN,QAAQ,IACJ,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface UpdatedAgoProps {
2
+ /** What the timestamp counts from (anything future reads as now). */
3
+ date: Date | number;
4
+ prefix?: string;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Stale-while-revalidate stamp ("Updated 3 minutes ago"): keep showing
9
+ * the old content and let this say how old it is. Static snapshot —
10
+ * re-render when the data refreshes.
11
+ */
12
+ export declare function UpdatedAgo({ date, prefix, className }: UpdatedAgoProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=updated-ago.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updated-ago.d.ts","sourceRoot":"","sources":["../src/updated-ago.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,MAAkB,EAAE,SAAS,EAAE,EAAE,eAAe,+BAOlF"}
@@ -0,0 +1,29 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "./utils.js";
3
+ const SECOND = 1_000;
4
+ const MINUTE = 60 * SECOND;
5
+ const HOUR = 60 * MINUTE;
6
+ const DAY = 24 * HOUR;
7
+ const formatter = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
8
+ function relativeFrom(now, then) {
9
+ const elapsed = Math.max(now - then, 0);
10
+ if (elapsed < 5 * SECOND)
11
+ return "just now";
12
+ if (elapsed < MINUTE)
13
+ return formatter.format(-Math.floor(elapsed / SECOND), "second");
14
+ if (elapsed < HOUR)
15
+ return formatter.format(-Math.floor(elapsed / MINUTE), "minute");
16
+ if (elapsed < DAY)
17
+ return formatter.format(-Math.floor(elapsed / HOUR), "hour");
18
+ return formatter.format(-Math.floor(elapsed / DAY), "day");
19
+ }
20
+ /**
21
+ * Stale-while-revalidate stamp ("Updated 3 minutes ago"): keep showing
22
+ * the old content and let this say how old it is. Static snapshot —
23
+ * re-render when the data refreshes.
24
+ */
25
+ export function UpdatedAgo({ date, prefix = "Updated", className }) {
26
+ const then = date instanceof Date ? date.getTime() : date;
27
+ return (_jsxs("span", { className: cn("text-xs text-muted-foreground", className), children: [prefix, " ", relativeFrom(Date.now(), then)] }));
28
+ }
29
+ //# sourceMappingURL=updated-ago.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updated-ago.js","sourceRoot":"","sources":["../src/updated-ago.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAShC,MAAM,MAAM,GAAG,KAAK,CAAC;AACrB,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;AAC3B,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC;AACzB,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;AAEzE,SAAS,YAAY,CAAC,GAAW,EAAE,IAAY;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,IAAI,OAAO,GAAG,CAAC,GAAG,MAAM;QAAE,OAAO,UAAU,CAAC;IAC5C,IAAI,OAAO,GAAG,MAAM;QAAE,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvF,IAAI,OAAO,GAAG,IAAI;QAAE,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IACrF,IAAI,OAAO,GAAG,GAAG;QAAE,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IAChF,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAmB;IACjF,MAAM,IAAI,GAAG,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,OAAO,CACL,gBAAM,SAAS,EAAE,EAAE,CAAC,+BAA+B,EAAE,SAAS,CAAC,aAC5D,MAAM,OAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,IACnC,CACR,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zedtech/zedkit-ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -92,7 +92,7 @@
92
92
  "typescript": "5.9.3",
93
93
  "vitest": "2.1.9",
94
94
  "vitest-axe": "0.1.0",
95
- "@zedtech/zedkit-core": "0.1.1"
95
+ "@zedtech/zedkit-core": "0.1.2"
96
96
  },
97
97
  "scripts": {
98
98
  "build": "tsc -p tsconfig.json",
@@ -0,0 +1,31 @@
1
+ import { Skeleton } from "./skeleton.js";
2
+ import { cn } from "./utils.js";
3
+
4
+ export interface CardSkeletonProps {
5
+ label?: string;
6
+ className?: string;
7
+ }
8
+
9
+ /**
10
+ * Faithful loading shape of Card: header block plus three text lines
11
+ * in the same bordered box, so content lands without shifting.
12
+ */
13
+ export function CardSkeleton({ label = "Loading", className }: CardSkeletonProps) {
14
+ return (
15
+ <div
16
+ role="status"
17
+ aria-label={label}
18
+ className={cn("rounded-xl border bg-card p-6 shadow", className)}
19
+ >
20
+ <div className="space-y-1.5">
21
+ <Skeleton className="h-5 w-1/3" />
22
+ <Skeleton className="h-4 w-2/3" />
23
+ </div>
24
+ <div className="mt-4 space-y-2">
25
+ <Skeleton className="h-4 w-full" />
26
+ <Skeleton className="h-4 w-full" />
27
+ <Skeleton className="h-4 w-4/5" />
28
+ </div>
29
+ </div>
30
+ );
31
+ }
@@ -0,0 +1,53 @@
1
+ import { Skeleton } from "./skeleton.js";
2
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
3
+ import { cn } from "./utils.js";
4
+
5
+ export interface DataTableSkeletonProps {
6
+ label?: string;
7
+ columns?: number;
8
+ rows?: number;
9
+ filter?: boolean;
10
+ className?: string;
11
+ }
12
+
13
+ /**
14
+ * Standalone loading shape of DataTable for Suspense fallbacks: filter
15
+ * slot plus a headed table of skeleton rows. (DataTable's own inline
16
+ * loading state stays untouched inside the table body.)
17
+ */
18
+ export function DataTableSkeleton({
19
+ label = "Loading",
20
+ columns = 4,
21
+ rows = 3,
22
+ filter = true,
23
+ className,
24
+ }: DataTableSkeletonProps) {
25
+ return (
26
+ <div role="status" aria-label={label} className={cn("space-y-4", className)}>
27
+ {filter ? <Skeleton className="h-9 max-w-sm" /> : null}
28
+ {/* Decorative shape only — the zone label above carries the meaning. */}
29
+ <Table aria-hidden>
30
+ <TableHeader>
31
+ <TableRow>
32
+ {Array.from({ length: columns }, (_, index) => (
33
+ <TableHead key={index}>
34
+ <Skeleton className="h-4 w-2/3" />
35
+ </TableHead>
36
+ ))}
37
+ </TableRow>
38
+ </TableHeader>
39
+ <TableBody>
40
+ {Array.from({ length: rows }, (_, row) => (
41
+ <TableRow key={row}>
42
+ {Array.from({ length: columns }, (_, column) => (
43
+ <TableCell key={column}>
44
+ <Skeleton className="h-4 w-full" />
45
+ </TableCell>
46
+ ))}
47
+ </TableRow>
48
+ ))}
49
+ </TableBody>
50
+ </Table>
51
+ </div>
52
+ );
53
+ }
@@ -0,0 +1,29 @@
1
+ import { Skeleton } from "./skeleton.js";
2
+ import { cn } from "./utils.js";
3
+
4
+ export interface DetailPanelSkeletonProps {
5
+ label?: string;
6
+ rows?: number;
7
+ className?: string;
8
+ }
9
+
10
+ /**
11
+ * Faithful loading shape of DetailPanel: label/value skeleton pairs
12
+ * in the same divided box, so rows land without shifting.
13
+ */
14
+ export function DetailPanelSkeleton({ label = "Loading", rows = 4, className }: DetailPanelSkeletonProps) {
15
+ return (
16
+ <div
17
+ role="status"
18
+ aria-label={label}
19
+ className={cn("divide-y divide-border rounded-lg border", className)}
20
+ >
21
+ {Array.from({ length: rows }, (_, index) => (
22
+ <div key={index} className="grid grid-cols-3 gap-4 px-4 py-3">
23
+ <Skeleton className="h-4 w-20" />
24
+ <Skeleton className="col-span-2 h-4 w-2/3" />
25
+ </div>
26
+ ))}
27
+ </div>
28
+ );
29
+ }
package/src/dialog.tsx CHANGED
@@ -17,7 +17,12 @@ const DialogOverlay = React.forwardRef<
17
17
  >(({ className, ...props }, ref) => (
18
18
  <DialogPrimitive.Overlay
19
19
  ref={ref}
20
- className={cn("fixed inset-0 z-50 bg-overlay/80", className)}
20
+ className={cn(
21
+ "fixed inset-0 z-50 bg-overlay/80",
22
+ "motion-safe:data-[state=open]:animate-[zk-fade-in_var(--motion-base)_var(--ease-enter)]",
23
+ "motion-safe:data-[state=closed]:animate-[zk-fade-out_var(--motion-base)_var(--ease-exit)]",
24
+ className,
25
+ )}
21
26
  {...props}
22
27
  />
23
28
  ));
@@ -33,6 +38,8 @@ const DialogContent = React.forwardRef<
33
38
  ref={ref}
34
39
  className={cn(
35
40
  "fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg",
41
+ "motion-safe:data-[state=open]:animate-[zk-zoom-in_var(--motion-base)_var(--ease-enter)]",
42
+ "motion-safe:data-[state=closed]:animate-[zk-zoom-out_var(--motion-base)_var(--ease-exit)]",
36
43
  className,
37
44
  )}
38
45
  {...props}
package/src/index.ts CHANGED
@@ -68,6 +68,8 @@ export { LivePulse, type LivePulseProps } from "./live-pulse.js";
68
68
  export { StatusDot, type StatusDotProps, type StatusDotTone } from "./status-dot.js";
69
69
  export { ProgressBar, type ProgressBarProps } from "./progress-bar.js";
70
70
  export { Checkmark, type CheckmarkProps } from "./checkmark.js";
71
+ export { StatusLabel, type StatusLabelProps, type StatusLabelTone } from "./status-label.js";
72
+ export { UpdatedAgo, type UpdatedAgoProps } from "./updated-ago.js";
71
73
  export { OptionCards, type OptionCard, type OptionCardsProps } from "./option-cards.js";
72
74
  export { PageHeader, type PageHeaderProps } from "./page-header.js";
73
75
  export { SecretField, type SecretFieldProps } from "./secret-field.js";
@@ -109,3 +111,7 @@ export {
109
111
  type TextProps,
110
112
  } from "./typography.js";
111
113
  export { cn } from "./utils.js";
114
+ export { CardSkeleton, type CardSkeletonProps } from "./card-skeleton.js";
115
+ export { DataTableSkeleton, type DataTableSkeletonProps } from "./data-table-skeleton.js";
116
+ export { DetailPanelSkeleton, type DetailPanelSkeletonProps } from "./detail-panel-skeleton.js";
117
+ export { PageHeaderSkeleton, type PageHeaderSkeletonProps } from "./page-header-skeleton.js";
@@ -0,0 +1,39 @@
1
+ import { Skeleton } from "./skeleton.js";
2
+ import { cn } from "./utils.js";
3
+
4
+ export interface PageHeaderSkeletonProps {
5
+ label?: string;
6
+ description?: boolean;
7
+ actions?: boolean;
8
+ className?: string;
9
+ }
10
+
11
+ /**
12
+ * Faithful loading shape of PageHeader: title, optional description
13
+ * and action slots. Same box, no layout shift when content lands.
14
+ */
15
+ export function PageHeaderSkeleton({
16
+ label = "Loading",
17
+ description = true,
18
+ actions = true,
19
+ className,
20
+ }: PageHeaderSkeletonProps) {
21
+ return (
22
+ <div
23
+ role="status"
24
+ aria-label={label}
25
+ className={cn("mb-6 flex flex-wrap items-start justify-between gap-4", className)}
26
+ >
27
+ <div className="space-y-1">
28
+ <Skeleton className="h-7 w-48" />
29
+ {description ? <Skeleton className="h-4 w-64" /> : null}
30
+ </div>
31
+ {actions ? (
32
+ <div className="flex items-center gap-2">
33
+ <Skeleton className="h-9 w-24" />
34
+ <Skeleton className="h-9 w-24" />
35
+ </div>
36
+ ) : null}
37
+ </div>
38
+ );
39
+ }
package/src/skeleton.tsx CHANGED
@@ -2,7 +2,7 @@
2
2
  import { cn } from "./utils.js";
3
3
 
4
4
  function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
5
- return <div className={cn("animate-pulse rounded-md bg-muted", className)} {...props} />;
5
+ return <div className={cn("rounded-md bg-muted motion-safe:animate-pulse", className)} {...props} />;
6
6
  }
7
7
 
8
8
  export { Skeleton };
@@ -0,0 +1,53 @@
1
+ import { WifiOff } from "lucide-react";
2
+
3
+ import { Checkmark } from "./checkmark.js";
4
+ import { StatusDot } from "./status-dot.js";
5
+ import { cn } from "./utils.js";
6
+
7
+ export type StatusLabelTone = "loading" | "updating" | "syncing" | "saved" | "retry" | "error" | "offline";
8
+
9
+ export interface StatusLabelProps {
10
+ tone: StatusLabelTone;
11
+ children: React.ReactNode;
12
+ className?: string;
13
+ }
14
+
15
+ function ToneIcon({ tone }: { tone: StatusLabelTone }) {
16
+ switch (tone) {
17
+ case "saved":
18
+ return <Checkmark />;
19
+ case "retry":
20
+ return <StatusDot tone="warning" />;
21
+ case "error":
22
+ return <StatusDot tone="danger" />;
23
+ case "offline":
24
+ return <WifiOff aria-hidden className="size-3.5 text-muted-foreground" />;
25
+ case "loading":
26
+ case "updating":
27
+ case "syncing":
28
+ return <StatusDot tone="active" />;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Named inline status: icon + text, announced politely (`role=status`).
34
+ * Name the operation ("Saving report…", not "Loading…") so a worried
35
+ * user always knows what is happening and where.
36
+ */
37
+ export function StatusLabel({ tone, children, className }: StatusLabelProps) {
38
+ return (
39
+ <span
40
+ role="status"
41
+ className={cn(
42
+ "inline-flex items-center gap-1.5 text-xs",
43
+ tone === "error" ? "text-destructive" : "text-muted-foreground",
44
+ className,
45
+ )}
46
+ >
47
+ <span className="flex size-4 shrink-0 items-center justify-center">
48
+ <ToneIcon tone={tone} />
49
+ </span>
50
+ {children}
51
+ </span>
52
+ );
53
+ }
package/src/styles.css CHANGED
@@ -130,3 +130,64 @@
130
130
  stroke-dashoffset: 0;
131
131
  }
132
132
  }
133
+
134
+ /*
135
+ * Motion tokens: every overlay animation references these durations
136
+ * and easings — apps never hardcode transition styles.
137
+ */
138
+ :root {
139
+ --motion-fast: 150ms;
140
+ --motion-base: 200ms;
141
+ --motion-slow: 250ms;
142
+ --ease-enter: cubic-bezier(0.16, 1, 0.3, 1);
143
+ --ease-exit: cubic-bezier(0.4, 0, 1, 1);
144
+ }
145
+
146
+ @keyframes zk-fade-in {
147
+ from {
148
+ opacity: 0;
149
+ }
150
+ }
151
+
152
+ @keyframes zk-fade-out {
153
+ to {
154
+ opacity: 0;
155
+ }
156
+ }
157
+
158
+ @keyframes zk-zoom-in {
159
+ from {
160
+ opacity: 0;
161
+ transform: scale(0.96);
162
+ }
163
+ }
164
+
165
+ @keyframes zk-zoom-out {
166
+ to {
167
+ opacity: 0;
168
+ transform: scale(0.96);
169
+ }
170
+ }
171
+
172
+ /*
173
+ * Vaul (drawer) ships its own slide keyframes at 500ms with no
174
+ * reduced-motion guard: retune to the kit tokens, disable fully
175
+ * when motion is reduced. `!important` beats vaul's injected
176
+ * high-specificity state selectors — deliberately, in one place.
177
+ */
178
+ html [data-vaul-drawer] {
179
+ animation-duration: var(--motion-slow);
180
+ transition-duration: var(--motion-slow);
181
+ }
182
+
183
+ html [data-vaul-overlay] {
184
+ animation-duration: var(--motion-base);
185
+ }
186
+
187
+ @media (prefers-reduced-motion: reduce) {
188
+ html [data-vaul-drawer],
189
+ html [data-vaul-overlay] {
190
+ animation: none !important;
191
+ transition: none !important;
192
+ }
193
+ }
@@ -0,0 +1,38 @@
1
+ import { cn } from "./utils.js";
2
+
3
+ export interface UpdatedAgoProps {
4
+ /** What the timestamp counts from (anything future reads as now). */
5
+ date: Date | number;
6
+ prefix?: string;
7
+ className?: string;
8
+ }
9
+
10
+ const SECOND = 1_000;
11
+ const MINUTE = 60 * SECOND;
12
+ const HOUR = 60 * MINUTE;
13
+ const DAY = 24 * HOUR;
14
+
15
+ const formatter = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
16
+
17
+ function relativeFrom(now: number, then: number): string {
18
+ const elapsed = Math.max(now - then, 0);
19
+ if (elapsed < 5 * SECOND) return "just now";
20
+ if (elapsed < MINUTE) return formatter.format(-Math.floor(elapsed / SECOND), "second");
21
+ if (elapsed < HOUR) return formatter.format(-Math.floor(elapsed / MINUTE), "minute");
22
+ if (elapsed < DAY) return formatter.format(-Math.floor(elapsed / HOUR), "hour");
23
+ return formatter.format(-Math.floor(elapsed / DAY), "day");
24
+ }
25
+
26
+ /**
27
+ * Stale-while-revalidate stamp ("Updated 3 minutes ago"): keep showing
28
+ * the old content and let this say how old it is. Static snapshot —
29
+ * re-render when the data refreshes.
30
+ */
31
+ export function UpdatedAgo({ date, prefix = "Updated", className }: UpdatedAgoProps) {
32
+ const then = date instanceof Date ? date.getTime() : date;
33
+ return (
34
+ <span className={cn("text-xs text-muted-foreground", className)}>
35
+ {prefix} {relativeFrom(Date.now(), then)}
36
+ </span>
37
+ );
38
+ }