@cellarnode/ui 0.16.8 → 0.17.1

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 (175) hide show
  1. package/dist/components/__tests__/animated-list-skeleton.test.d.ts +2 -0
  2. package/dist/components/__tests__/animated-list-skeleton.test.d.ts.map +1 -0
  3. package/dist/components/__tests__/animated-list-skeleton.test.js +11 -0
  4. package/dist/components/__tests__/animated-list-skeleton.test.js.map +1 -0
  5. package/dist/components/__tests__/card-grid-skeleton.test.d.ts +2 -0
  6. package/dist/components/__tests__/card-grid-skeleton.test.d.ts.map +1 -0
  7. package/dist/components/__tests__/card-grid-skeleton.test.js +22 -0
  8. package/dist/components/__tests__/card-grid-skeleton.test.js.map +1 -0
  9. package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.d.ts +2 -0
  10. package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.d.ts.map +1 -0
  11. package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.js +39 -0
  12. package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.js.map +1 -0
  13. package/dist/components/__tests__/data-table-skeleton.test.d.ts +2 -0
  14. package/dist/components/__tests__/data-table-skeleton.test.d.ts.map +1 -0
  15. package/dist/components/__tests__/data-table-skeleton.test.js +27 -0
  16. package/dist/components/__tests__/data-table-skeleton.test.js.map +1 -0
  17. package/dist/components/__tests__/detail-page-skeleton.test.d.ts +2 -0
  18. package/dist/components/__tests__/detail-page-skeleton.test.d.ts.map +1 -0
  19. package/dist/components/__tests__/detail-page-skeleton.test.js +30 -0
  20. package/dist/components/__tests__/detail-page-skeleton.test.js.map +1 -0
  21. package/dist/components/__tests__/list-item-skeleton.test.d.ts +2 -0
  22. package/dist/components/__tests__/list-item-skeleton.test.d.ts.map +1 -0
  23. package/dist/components/__tests__/list-item-skeleton.test.js +38 -0
  24. package/dist/components/__tests__/list-item-skeleton.test.js.map +1 -0
  25. package/dist/components/__tests__/profile-header-skeleton.test.d.ts +2 -0
  26. package/dist/components/__tests__/profile-header-skeleton.test.d.ts.map +1 -0
  27. package/dist/components/__tests__/profile-header-skeleton.test.js +17 -0
  28. package/dist/components/__tests__/profile-header-skeleton.test.js.map +1 -0
  29. package/dist/components/__tests__/stat-card-skeleton.test.d.ts +2 -0
  30. package/dist/components/__tests__/stat-card-skeleton.test.d.ts.map +1 -0
  31. package/dist/components/__tests__/stat-card-skeleton.test.js +33 -0
  32. package/dist/components/__tests__/stat-card-skeleton.test.js.map +1 -0
  33. package/dist/components/animated-list.d.ts +11 -1
  34. package/dist/components/animated-list.d.ts.map +1 -1
  35. package/dist/components/animated-list.js +7 -1
  36. package/dist/components/animated-list.js.map +1 -1
  37. package/dist/components/animated-list.stories.d.ts +3 -2
  38. package/dist/components/animated-list.stories.d.ts.map +1 -1
  39. package/dist/components/bottle-extract-dialog.js +4 -5
  40. package/dist/components/bottle-extract-dialog.js.map +1 -1
  41. package/dist/components/card-grid-skeleton.d.ts +9 -0
  42. package/dist/components/card-grid-skeleton.d.ts.map +1 -0
  43. package/dist/components/card-grid-skeleton.js +16 -0
  44. package/dist/components/card-grid-skeleton.js.map +1 -0
  45. package/dist/components/card-grid-skeleton.stories.d.ts +35 -0
  46. package/dist/components/card-grid-skeleton.stories.d.ts.map +1 -0
  47. package/dist/components/card-grid-skeleton.stories.js +22 -0
  48. package/dist/components/card-grid-skeleton.stories.js.map +1 -0
  49. package/dist/components/dashboard-stats-grid.d.ts +11 -1
  50. package/dist/components/dashboard-stats-grid.d.ts.map +1 -1
  51. package/dist/components/dashboard-stats-grid.js +19 -12
  52. package/dist/components/dashboard-stats-grid.js.map +1 -1
  53. package/dist/components/dashboard-stats-grid.stories.d.ts +19 -0
  54. package/dist/components/dashboard-stats-grid.stories.d.ts.map +1 -0
  55. package/dist/components/dashboard-stats-grid.stories.js +34 -0
  56. package/dist/components/dashboard-stats-grid.stories.js.map +1 -0
  57. package/dist/components/data-table-skeleton.d.ts +9 -0
  58. package/dist/components/data-table-skeleton.d.ts.map +1 -0
  59. package/dist/components/data-table-skeleton.js +14 -0
  60. package/dist/components/data-table-skeleton.js.map +1 -0
  61. package/dist/components/data-table-skeleton.stories.d.ts +36 -0
  62. package/dist/components/data-table-skeleton.stories.d.ts.map +1 -0
  63. package/dist/components/data-table-skeleton.stories.js +22 -0
  64. package/dist/components/data-table-skeleton.stories.js.map +1 -0
  65. package/dist/components/detail-page-skeleton.d.ts +11 -0
  66. package/dist/components/detail-page-skeleton.d.ts.map +1 -0
  67. package/dist/components/detail-page-skeleton.js +14 -0
  68. package/dist/components/detail-page-skeleton.js.map +1 -0
  69. package/dist/components/detail-page-skeleton.stories.d.ts +15 -0
  70. package/dist/components/detail-page-skeleton.stories.d.ts.map +1 -0
  71. package/dist/components/detail-page-skeleton.stories.js +15 -0
  72. package/dist/components/detail-page-skeleton.stories.js.map +1 -0
  73. package/dist/components/extraction-phase-stepper.d.ts.map +1 -1
  74. package/dist/components/extraction-phase-stepper.js +5 -4
  75. package/dist/components/extraction-phase-stepper.js.map +1 -1
  76. package/dist/components/list-item-skeleton.d.ts +9 -0
  77. package/dist/components/list-item-skeleton.d.ts.map +1 -0
  78. package/dist/components/list-item-skeleton.js +13 -0
  79. package/dist/components/list-item-skeleton.js.map +1 -0
  80. package/dist/components/list-item-skeleton.stories.d.ts +27 -0
  81. package/dist/components/list-item-skeleton.stories.d.ts.map +1 -0
  82. package/dist/components/list-item-skeleton.stories.js +21 -0
  83. package/dist/components/list-item-skeleton.stories.js.map +1 -0
  84. package/dist/components/opportunity-brief.d.ts +44 -1
  85. package/dist/components/opportunity-brief.d.ts.map +1 -1
  86. package/dist/components/opportunity-brief.js +50 -2
  87. package/dist/components/opportunity-brief.js.map +1 -1
  88. package/dist/components/opportunity-brief.stories.d.ts +13 -0
  89. package/dist/components/opportunity-brief.stories.d.ts.map +1 -1
  90. package/dist/components/opportunity-brief.stories.js +48 -0
  91. package/dist/components/opportunity-brief.stories.js.map +1 -1
  92. package/dist/components/profile-header-skeleton.d.ts +12 -0
  93. package/dist/components/profile-header-skeleton.d.ts.map +1 -0
  94. package/dist/components/profile-header-skeleton.js +15 -0
  95. package/dist/components/profile-header-skeleton.js.map +1 -0
  96. package/dist/components/profile-header-skeleton.stories.d.ts +15 -0
  97. package/dist/components/profile-header-skeleton.stories.d.ts.map +1 -0
  98. package/dist/components/profile-header-skeleton.stories.js +15 -0
  99. package/dist/components/profile-header-skeleton.stories.js.map +1 -0
  100. package/dist/components/skeleton.d.ts +6 -1
  101. package/dist/components/skeleton.d.ts.map +1 -1
  102. package/dist/components/skeleton.js +5 -2
  103. package/dist/components/skeleton.js.map +1 -1
  104. package/dist/components/skeleton.stories.d.ts +9 -1
  105. package/dist/components/skeleton.stories.d.ts.map +1 -1
  106. package/dist/components/skeleton.stories.js +16 -5
  107. package/dist/components/skeleton.stories.js.map +1 -1
  108. package/dist/components/sortable-card-shell.test.d.ts +2 -0
  109. package/dist/components/sortable-card-shell.test.d.ts.map +1 -0
  110. package/dist/components/sortable-card-shell.test.js +115 -0
  111. package/dist/components/sortable-card-shell.test.js.map +1 -0
  112. package/dist/components/stat-card.d.ts +10 -1
  113. package/dist/components/stat-card.d.ts.map +1 -1
  114. package/dist/components/stat-card.js +15 -1
  115. package/dist/components/stat-card.js.map +1 -1
  116. package/dist/components/stat-card.stories.d.ts +6 -2
  117. package/dist/components/stat-card.stories.d.ts.map +1 -1
  118. package/dist/components/stat-card.stories.js +17 -4
  119. package/dist/components/stat-card.stories.js.map +1 -1
  120. package/dist/components/variant-picker-dialog.d.ts +13 -1
  121. package/dist/components/variant-picker-dialog.d.ts.map +1 -1
  122. package/dist/components/variant-picker-dialog.js +2 -2
  123. package/dist/components/variant-picker-dialog.js.map +1 -1
  124. package/dist/components/variant-picker-dialog.stories.d.ts +13 -0
  125. package/dist/components/variant-picker-dialog.stories.d.ts.map +1 -1
  126. package/dist/components/variant-picker-dialog.stories.js +72 -0
  127. package/dist/components/variant-picker-dialog.stories.js.map +1 -1
  128. package/dist/components/variant-picker-dialog.test.js +1 -1
  129. package/dist/components/variant-picker-dialog.test.js.map +1 -1
  130. package/dist/globe/__tests__/globe-loading-skeleton.test.d.ts +2 -0
  131. package/dist/globe/__tests__/globe-loading-skeleton.test.d.ts.map +1 -0
  132. package/dist/globe/__tests__/globe-loading-skeleton.test.js +29 -0
  133. package/dist/globe/__tests__/globe-loading-skeleton.test.js.map +1 -0
  134. package/dist/globe/globe-loading-skeleton.d.ts +13 -5
  135. package/dist/globe/globe-loading-skeleton.d.ts.map +1 -1
  136. package/dist/globe/globe-loading-skeleton.js +9 -2
  137. package/dist/globe/globe-loading-skeleton.js.map +1 -1
  138. package/dist/index.d.ts +7 -2
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +7 -1
  141. package/dist/index.js.map +1 -1
  142. package/dist/skeleton/__tests__/loader.test.d.ts +2 -0
  143. package/dist/skeleton/__tests__/loader.test.d.ts.map +1 -0
  144. package/dist/skeleton/__tests__/loader.test.js +33 -0
  145. package/dist/skeleton/__tests__/loader.test.js.map +1 -0
  146. package/dist/skeleton/__tests__/primitive.test.d.ts +2 -0
  147. package/dist/skeleton/__tests__/primitive.test.d.ts.map +1 -0
  148. package/dist/skeleton/__tests__/primitive.test.js +36 -0
  149. package/dist/skeleton/__tests__/primitive.test.js.map +1 -0
  150. package/dist/skeleton/__tests__/provider.test.d.ts +2 -0
  151. package/dist/skeleton/__tests__/provider.test.d.ts.map +1 -0
  152. package/dist/skeleton/__tests__/provider.test.js +78 -0
  153. package/dist/skeleton/__tests__/provider.test.js.map +1 -0
  154. package/dist/skeleton/index.d.ts +5 -0
  155. package/dist/skeleton/index.d.ts.map +1 -0
  156. package/dist/skeleton/index.js +5 -0
  157. package/dist/skeleton/index.js.map +1 -0
  158. package/dist/skeleton/loader.d.ts +15 -0
  159. package/dist/skeleton/loader.d.ts.map +1 -0
  160. package/dist/skeleton/loader.js +21 -0
  161. package/dist/skeleton/loader.js.map +1 -0
  162. package/dist/skeleton/loader.stories.d.ts +16 -0
  163. package/dist/skeleton/loader.stories.d.ts.map +1 -0
  164. package/dist/skeleton/loader.stories.js +27 -0
  165. package/dist/skeleton/loader.stories.js.map +1 -0
  166. package/dist/skeleton/provider.d.ts +13 -0
  167. package/dist/skeleton/provider.d.ts.map +1 -0
  168. package/dist/skeleton/provider.js +27 -0
  169. package/dist/skeleton/provider.js.map +1 -0
  170. package/dist/skeleton/stagger.d.ts +30 -0
  171. package/dist/skeleton/stagger.d.ts.map +1 -0
  172. package/dist/skeleton/stagger.js +45 -0
  173. package/dist/skeleton/stagger.js.map +1 -0
  174. package/package.json +1 -1
  175. package/src/theme/tokens.css +93 -0
@@ -1,5 +1,33 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils";
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ function formatPriceRange(range, currency) {
7
+ if (!range)
8
+ return null;
9
+ const { min, max } = range;
10
+ if (min == null && max == null)
11
+ return null;
12
+ const cur = currency ?? "";
13
+ const prefix = cur ? `${cur} ` : "";
14
+ if (min != null && max != null)
15
+ return `${prefix}${min} – ${max}`.trim();
16
+ if (min != null)
17
+ return `${prefix}${min}+`.trim();
18
+ return `up to ${prefix}${max}`.trim();
19
+ }
20
+ function formatHsCode(heading, subheadings) {
21
+ const parts = [];
22
+ if (heading)
23
+ parts.push(heading);
24
+ if (subheadings && subheadings.length > 0) {
25
+ parts.push(subheadings.map((s) => s.code).join(", "));
26
+ }
27
+ if (parts.length === 0)
28
+ return null;
29
+ return `HS ${parts.join(" · ")}`;
30
+ }
3
31
  /**
4
32
  * Compact opportunity-context banner used at the top of the producer picker
5
33
  * and anywhere an opportunity needs to be identified at a glance (importer
@@ -7,7 +35,27 @@ import { cn } from "../lib/utils";
7
35
  *
8
36
  * Intentionally visual-only — all interaction happens on the host container.
9
37
  */
10
- export function OpportunityBrief({ name, buyerName, chips, eyebrow = "Looking for", className, }) {
11
- return (_jsxs("div", { className: cn("rounded-lg border-l-[3px] border-primary bg-primary/5 px-3 py-2.5", className), children: [_jsx("p", { className: "text-[10px] font-bold uppercase tracking-[0.08em] text-primary", children: eyebrow }), _jsx("p", { className: "mt-0.5 text-sm font-semibold text-foreground", children: name }), buyerName && (_jsx("p", { className: "text-[11px] text-muted-foreground", children: buyerName })), chips.length > 0 && (_jsx("div", { className: "mt-1.5 flex flex-wrap gap-1", children: chips.map((c) => (_jsx("span", { className: "rounded-full bg-primary/15 px-2 py-0.5 text-[10px] font-semibold text-primary", children: c.label }, c.label))) }))] }));
38
+ export function OpportunityBrief({ name, buyerName, chips, detail, eyebrow = "Looking for", className, }) {
39
+ const description = detail?.description?.trim() || null;
40
+ const hsCode = formatHsCode(detail?.hsHeading, detail?.hsSubheadings);
41
+ const priceRangeLabel = formatPriceRange(detail?.priceRange, detail?.currency);
42
+ const vintageRequirement = detail?.vintageRequirement?.trim() || null;
43
+ const certificateRequirements = detail?.certificateRequirements?.filter((r) => r && r.trim().length > 0) ?? [];
44
+ // Packaging/closure rendered as chips only if the caller hasn't already
45
+ // supplied equivalent chips (case-insensitive match on label).
46
+ const chipLabels = new Set(chips.map((c) => c.label.toLowerCase()));
47
+ const extraChips = [];
48
+ if (detail?.packaging && !chipLabels.has(detail.packaging.toLowerCase())) {
49
+ extraChips.push({ label: detail.packaging });
50
+ }
51
+ if (detail?.closure && !chipLabels.has(detail.closure.toLowerCase())) {
52
+ extraChips.push({ label: detail.closure });
53
+ }
54
+ const hasAnyDetail = description != null ||
55
+ hsCode != null ||
56
+ priceRangeLabel != null ||
57
+ vintageRequirement != null ||
58
+ certificateRequirements.length > 0;
59
+ return (_jsxs("div", { className: cn("rounded-lg border-l-[3px] border-primary bg-primary/5 px-3 py-2.5", className), children: [_jsx("p", { className: "text-[10px] font-bold uppercase tracking-[0.08em] text-primary", children: eyebrow }), _jsx("p", { className: "mt-0.5 text-sm font-semibold text-foreground", children: name }), buyerName && (_jsx("p", { className: "text-[11px] text-muted-foreground", children: buyerName })), description && (_jsx("p", { className: "mt-1 line-clamp-2 text-[11px]/5 text-foreground/70", children: description })), (chips.length > 0 || extraChips.length > 0) && (_jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [chips.map((c) => (_jsx("span", { className: "rounded-full bg-primary/15 px-2 py-0.5 text-[10px] font-semibold text-primary", children: c.label }, c.label))), extraChips.map((c) => (_jsx("span", { className: "rounded-full bg-primary/15 px-2 py-0.5 text-[10px] font-semibold text-primary", children: c.label }, `extra-${c.label}`)))] })), hasAnyDetail && (_jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] text-muted-foreground", children: [priceRangeLabel && (_jsxs("span", { children: [_jsx("span", { className: "font-semibold text-foreground/80", children: "Price " }), priceRangeLabel] })), vintageRequirement && (_jsxs("span", { children: [_jsx("span", { className: "font-semibold text-foreground/80", children: "Vintage " }), vintageRequirement] })), hsCode && _jsx("span", { children: hsCode })] })), certificateRequirements.length > 0 && (_jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-1", children: [_jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-foreground/70", children: "Certs" }), certificateRequirements.map((r) => (_jsx("span", { className: "rounded-full border border-border bg-background/60 px-2 py-0.5 text-[10px] font-medium text-foreground/80", children: r }, r)))] }))] }));
12
60
  }
13
61
  //# sourceMappingURL=opportunity-brief.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity-brief.js","sourceRoot":"","sources":["../../src/components/opportunity-brief.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAkBlC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,IAAI,EACJ,SAAS,EACT,KAAK,EACL,OAAO,GAAG,aAAa,EACvB,SAAS,GACa;IACtB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,mEAAmE,EACnE,SAAS,CACV,aAED,YAAG,SAAS,EAAC,gEAAgE,YAC1E,OAAO,GACN,EACJ,YAAG,SAAS,EAAC,8CAA8C,YAAE,IAAI,GAAK,EACrE,SAAS,IAAI,CACZ,YAAG,SAAS,EAAC,mCAAmC,YAAE,SAAS,GAAK,CACjE,EACA,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CACnB,cAAK,SAAS,EAAC,6BAA6B,YACzC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAChB,eAEE,SAAS,EAAC,+EAA+E,YAExF,CAAC,CAAC,KAAK,IAHH,CAAC,CAAC,KAAK,CAIP,CACR,CAAC,GACE,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"opportunity-brief.js","sourceRoot":"","sources":["../../src/components/opportunity-brief.tsx"],"names":[],"mappings":"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"}
@@ -14,4 +14,17 @@ export declare const Default: Story;
14
14
  export declare const NoBuyer: Story;
15
15
  export declare const NoChips: Story;
16
16
  export declare const CustomEyebrow: Story;
17
+ /**
18
+ * Rich banner: consumer has the full `OpportunityDetail` (from live
19
+ * `GET /opportunities/:id` or an offer's frozen `opportunitySnapshot`) and
20
+ * passes `detail` alongside the slim chips. All rich fields are optional —
21
+ * absent fields are silently skipped.
22
+ */
23
+ export declare const WithDetail: Story;
24
+ /**
25
+ * Partial detail: only some rich fields are present (e.g., no certificate
26
+ * requirements, no HS code). Absent fields are silently skipped — no empty
27
+ * labels.
28
+ */
29
+ export declare const WithPartialDetail: Story;
17
30
  //# sourceMappingURL=opportunity-brief.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity-brief.stories.d.ts","sourceRoot":"","sources":["../../src/components/opportunity-brief.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,QAAA,MAAM,IAAI;;;;;;;CAK+B,CAAC;AAE1C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAM3B,CAAC"}
1
+ {"version":3,"file":"opportunity-brief.stories.d.ts","sourceRoot":"","sources":["../../src/components/opportunity-brief.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,QAAA,MAAM,IAAI;;;;;;;CAK+B,CAAC;AAE1C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAM3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,KA0BxB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAU/B,CAAC"}
@@ -35,4 +35,52 @@ export const CustomEyebrow = {
35
35
  chips: [{ label: "Organic" }, { label: "<15 EUR" }],
36
36
  },
37
37
  };
38
+ /**
39
+ * Rich banner: consumer has the full `OpportunityDetail` (from live
40
+ * `GET /opportunities/:id` or an offer's frozen `opportunitySnapshot`) and
41
+ * passes `detail` alongside the slim chips. All rich fields are optional —
42
+ * absent fields are silently skipped.
43
+ */
44
+ export const WithDetail = {
45
+ args: {
46
+ name: "brandy spirits · Spain Selection",
47
+ buyerName: "Systembolaget",
48
+ chips: [
49
+ { label: "Spirits" },
50
+ { label: "Brandy" },
51
+ { label: "Spain" },
52
+ { label: "330 L" },
53
+ { label: "due Mar 17" },
54
+ ],
55
+ detail: {
56
+ description: "Systembolaget is seeking a premium Spanish brandy (Jerez region preferred) with a solera-aged profile for its Q2 2026 spirits selection. Minimum 36-month ageing; exclusivity preferred.",
57
+ hsHeading: "2208",
58
+ hsSubheadings: [
59
+ { code: "2208.20", description: "Spirits from grape wine/marc" },
60
+ ],
61
+ priceRange: { min: 18, max: 32 },
62
+ currency: "EUR",
63
+ vintageRequirement: "NV — 36mo+ aged",
64
+ packaging: "bottle",
65
+ closure: "cork",
66
+ certificateRequirements: ["Organic", "DOP Jerez", "BRC"],
67
+ },
68
+ },
69
+ };
70
+ /**
71
+ * Partial detail: only some rich fields are present (e.g., no certificate
72
+ * requirements, no HS code). Absent fields are silently skipped — no empty
73
+ * labels.
74
+ */
75
+ export const WithPartialDetail = {
76
+ args: {
77
+ name: "Riesling Selection 2026",
78
+ chips: [{ label: "Wine" }, { label: "White wine" }, { label: "Germany" }],
79
+ detail: {
80
+ description: "Looking for a late-harvest Riesling, medium-sweet, from Mosel or Rheingau.",
81
+ priceRange: { min: 12, max: null },
82
+ currency: "EUR",
83
+ },
84
+ },
85
+ };
38
86
  //# sourceMappingURL=opportunity-brief.stories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opportunity-brief.stories.js","sourceRoot":"","sources":["../../src/components/opportunity-brief.stories.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,yBAAyB;IAChC,SAAS,EAAE,gBAAgB;IAC3B,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;CACK,CAAC;AAE1C,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,kCAAkC;QACxC,SAAS,EAAE,eAAe;QAC1B,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,SAAS,EAAE;YACpB,EAAE,KAAK,EAAE,QAAQ,EAAE;YACnB,EAAE,KAAK,EAAE,OAAO,EAAE;YAClB,EAAE,KAAK,EAAE,OAAO,EAAE;YAClB,EAAE,KAAK,EAAE,YAAY,EAAE;SACxB;KACF;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,yBAAyB;QAC/B,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KAC1E;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,EAAE,EAAE;CACjD,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAU;IAClC,IAAI,EAAE;QACJ,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KACpD;CACF,CAAC"}
1
+ {"version":3,"file":"opportunity-brief.stories.js","sourceRoot":"","sources":["../../src/components/opportunity-brief.stories.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,yBAAyB;IAChC,SAAS,EAAE,gBAAgB;IAC3B,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;CACK,CAAC;AAE1C,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,kCAAkC;QACxC,SAAS,EAAE,eAAe;QAC1B,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,SAAS,EAAE;YACpB,EAAE,KAAK,EAAE,QAAQ,EAAE;YACnB,EAAE,KAAK,EAAE,OAAO,EAAE;YAClB,EAAE,KAAK,EAAE,OAAO,EAAE;YAClB,EAAE,KAAK,EAAE,YAAY,EAAE;SACxB;KACF;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,yBAAyB;QAC/B,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KAC1E;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,EAAE,EAAE;CACjD,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAU;IAClC,IAAI,EAAE;QACJ,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,cAAc;QACvB,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;KACpD;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,IAAI,EAAE;QACJ,IAAI,EAAE,kCAAkC;QACxC,SAAS,EAAE,eAAe;QAC1B,KAAK,EAAE;YACL,EAAE,KAAK,EAAE,SAAS,EAAE;YACpB,EAAE,KAAK,EAAE,QAAQ,EAAE;YACnB,EAAE,KAAK,EAAE,OAAO,EAAE;YAClB,EAAE,KAAK,EAAE,OAAO,EAAE;YAClB,EAAE,KAAK,EAAE,YAAY,EAAE;SACxB;QACD,MAAM,EAAE;YACN,WAAW,EACT,0LAA0L;YAC5L,SAAS,EAAE,MAAM;YACjB,aAAa,EAAE;gBACb,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,8BAA8B,EAAE;aACjE;YACD,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;YAChC,QAAQ,EAAE,KAAK;YACf,kBAAkB,EAAE,iBAAiB;YACrC,SAAS,EAAE,QAAQ;YACnB,OAAO,EAAE,MAAM;YACf,uBAAuB,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC;SACzD;KACF;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAU;IACtC,IAAI,EAAE;QACJ,IAAI,EAAE,yBAAyB;QAC/B,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QACzE,MAAM,EAAE;YACN,WAAW,EAAE,4EAA4E;YACzF,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;YAClC,QAAQ,EAAE,KAAK;SAChB;KACF;CACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+ import { type SkeletonTier } from "../skeleton/stagger";
3
+ export interface ProfileHeaderSkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ tier?: SkeletonTier;
5
+ }
6
+ /**
7
+ * Replaces the 9-part hand-rolled skeleton currently inlined in
8
+ * cellarnode-importer-dashboard's organization-profile-content.tsx.
9
+ * Shape: banner (wide rectangle) + avatar (circle) + title + description + 2 grid cards.
10
+ */
11
+ export declare function ProfileHeaderSkeleton({ tier, className, ...rest }: ProfileHeaderSkeletonProps): import("react/jsx-runtime").JSX.Element;
12
+ //# sourceMappingURL=profile-header-skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-header-skeleton.d.ts","sourceRoot":"","sources":["../../src/components/profile-header-skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,WAAW,0BAA2B,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACtF,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,EACR,EAAE,0BAA0B,2CA6B5B"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils";
3
+ import { Skeleton } from "./skeleton";
4
+ import { useSkeletonContext } from "../skeleton/stagger";
5
+ /**
6
+ * Replaces the 9-part hand-rolled skeleton currently inlined in
7
+ * cellarnode-importer-dashboard's organization-profile-content.tsx.
8
+ * Shape: banner (wide rectangle) + avatar (circle) + title + description + 2 grid cards.
9
+ */
10
+ export function ProfileHeaderSkeleton({ tier, className, ...rest }) {
11
+ const ctx = useSkeletonContext();
12
+ const resolvedTier = tier ?? (ctx.hasProvider ? ctx.tier : "hero");
13
+ return (_jsxs("div", { className: cn("flex flex-col gap-6", className), ...rest, children: [_jsx(Skeleton, { tier: resolvedTier, className: "h-40 w-full rounded-2xl" }), _jsxs("div", { className: "flex items-start gap-4", children: [_jsx(Skeleton, { tier: resolvedTier, className: "size-20 shrink-0 rounded-full" }), _jsxs("div", { className: "flex flex-1 flex-col gap-3", children: [_jsx(Skeleton, { tier: resolvedTier, className: "h-6 w-64" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-4 w-full max-w-2xl" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-4 w-3/4 max-w-xl" })] })] }), _jsxs("div", { className: "grid gap-4 md:grid-cols-2", children: [_jsxs("div", { className: "flex flex-col gap-3 rounded-2xl border border-border/60 bg-card p-5", children: [_jsx(Skeleton, { tier: resolvedTier, className: "h-3 w-24" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-5 w-40" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-3 w-full max-w-xs" })] }), _jsxs("div", { className: "flex flex-col gap-3 rounded-2xl border border-border/60 bg-card p-5", children: [_jsx(Skeleton, { tier: resolvedTier, className: "h-3 w-24" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-5 w-40" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-3 w-full max-w-xs" })] })] })] }));
14
+ }
15
+ //# sourceMappingURL=profile-header-skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-header-skeleton.js","sourceRoot":"","sources":["../../src/components/profile-header-skeleton.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAqB,MAAM,qBAAqB,CAAC;AAM5E;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,IAAI,EACJ,SAAS,EACT,GAAG,IAAI,EACoB;IAC3B,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,MAAM,YAAY,GAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAEjF,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,KAAM,IAAI,aAC5D,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,yBAAyB,GAAG,EACpE,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,+BAA+B,GAAG,EAC1E,eAAK,SAAS,EAAC,4BAA4B,aACzC,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,EACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,sBAAsB,GAAG,EACjE,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,oBAAoB,GAAG,IAC3D,IACF,EACN,eAAK,SAAS,EAAC,2BAA2B,aACxC,eAAK,SAAS,EAAC,qEAAqE,aAClF,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,EACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,EACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,qBAAqB,GAAG,IAC5D,EACN,eAAK,SAAS,EAAC,qEAAqE,aAClF,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,EACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,EACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,qBAAqB,GAAG,IAC5D,IACF,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ import { ProfileHeaderSkeleton } from "./profile-header-skeleton";
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof ProfileHeaderSkeleton;
6
+ tags: string[];
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ };
11
+ export default meta;
12
+ type Story = StoryObj<typeof meta>;
13
+ export declare const Default: Story;
14
+ export declare const InProvider: Story;
15
+ //# sourceMappingURL=profile-header-skeleton.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-header-skeleton.stories.d.ts","sourceRoot":"","sources":["../../src/components/profile-header-skeleton.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,QAAA,MAAM,IAAI;;;;;;;CAKoC,CAAC;AAE/C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AACjC,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ProfileHeaderSkeleton } from "./profile-header-skeleton";
3
+ import { SkeletonProvider } from "../skeleton/provider";
4
+ const meta = {
5
+ title: "Components/ProfileHeaderSkeleton",
6
+ component: ProfileHeaderSkeleton,
7
+ tags: ["autodocs"],
8
+ parameters: { layout: "padded" },
9
+ };
10
+ export default meta;
11
+ export const Default = {};
12
+ export const InProvider = {
13
+ render: () => (_jsx(SkeletonProvider, { tier: "hero", children: _jsx(ProfileHeaderSkeleton, {}) })),
14
+ };
15
+ //# sourceMappingURL=profile-header-skeleton.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-header-skeleton.stories.js","sourceRoot":"","sources":["../../src/components/profile-header-skeleton.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,kCAAkC;IACzC,SAAS,EAAE,qBAAqB;IAChC,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;CACY,CAAC;AAE/C,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,OAAO,GAAU,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,KAAC,gBAAgB,IAAC,IAAI,EAAC,MAAM,YAC3B,KAAC,qBAAqB,KAAG,GACR,CACpB;CACF,CAAC"}
@@ -1,3 +1,8 @@
1
- declare function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
1
+ import * as React from "react";
2
+ import { type SkeletonTier } from "../skeleton/stagger";
3
+ export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ tier?: SkeletonTier;
5
+ }
6
+ declare function Skeleton({ tier, className, ...props }: SkeletonProps): import("react/jsx-runtime").JSX.Element;
2
7
  export { Skeleton };
3
8
  //# sourceMappingURL=skeleton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../src/components/skeleton.tsx"],"names":[],"mappings":"AAEA,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,2CAE9E;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../src/components/skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACzE,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,iBAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,2CAY7D;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,7 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils";
3
- function Skeleton({ className, ...props }) {
4
- return _jsx("div", { className: cn("animate-pulse rounded-md bg-muted", className), ...props });
3
+ import { useSkeletonContext } from "../skeleton/stagger";
4
+ function Skeleton({ tier, className, ...props }) {
5
+ const ctx = useSkeletonContext();
6
+ const resolvedTier = tier ?? ctx.tier;
7
+ return (_jsx("div", { "data-skeleton": "", "data-tier": resolvedTier, "aria-hidden": "true", className: cn("rounded-md", className), ...props }));
5
8
  }
6
9
  export { Skeleton };
7
10
  //# sourceMappingURL=skeleton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../../src/components/skeleton.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,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/components/skeleton.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAqB,MAAM,qBAAqB,CAAC;AAM5E,SAAS,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiB;IAC5D,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,MAAM,YAAY,GAAiB,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC;IACpD,OAAO,CACL,+BACgB,EAAE,eACL,YAAY,iBACX,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,KAClC,KAAK,GACT,CACH,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -7,10 +7,18 @@ declare const meta: {
7
7
  parameters: {
8
8
  layout: string;
9
9
  };
10
+ argTypes: {
11
+ tier: {
12
+ control: "select";
13
+ options: string[];
14
+ };
15
+ };
10
16
  };
11
17
  export default meta;
12
18
  type Story = StoryObj<typeof meta>;
13
19
  export declare const Default: Story;
14
- export declare const CardSkeleton: Story;
20
+ export declare const ThreeTiers: Story;
21
+ export declare const InProviderInheritsTier: Story;
22
+ export declare const CardComposition: Story;
15
23
  export declare const CircleSkeleton: Story;
16
24
  //# sourceMappingURL=skeleton.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.stories.d.ts","sourceRoot":"","sources":["../../src/components/skeleton.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,QAAA,MAAM,IAAI;;;;;;;CAKuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KA4B1B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAU5B,CAAC"}
1
+ {"version":3,"file":"skeleton.stories.d.ts","sourceRoot":"","sources":["../../src/components/skeleton.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC,QAAA,MAAM,IAAI;;;;;;;;;;;;;CAWuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KAUpC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAU7B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAU5B,CAAC"}
@@ -1,19 +1,30 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Skeleton } from "./skeleton";
3
+ import { SkeletonProvider } from "../skeleton/provider";
3
4
  const meta = {
4
5
  title: "Components/Skeleton",
5
6
  component: Skeleton,
6
7
  tags: ["autodocs"],
7
8
  parameters: { layout: "centered" },
9
+ argTypes: {
10
+ tier: {
11
+ control: "select",
12
+ options: ["hero", "data", "inline"],
13
+ },
14
+ },
8
15
  };
9
16
  export default meta;
10
17
  export const Default = {
11
- args: {
12
- className: "h-4 w-48",
13
- },
18
+ args: { className: "h-4 w-48" },
19
+ };
20
+ export const ThreeTiers = {
21
+ render: () => (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "w-16 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Inline" }), _jsx(Skeleton, { tier: "inline", className: "h-4 w-48" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "w-16 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Data" }), _jsx(Skeleton, { tier: "data", className: "h-4 w-48" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "w-16 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Hero" }), _jsx(Skeleton, { tier: "hero", className: "h-4 w-48" })] })] })),
22
+ };
23
+ export const InProviderInheritsTier = {
24
+ render: () => (_jsx(SkeletonProvider, { tier: "data", children: _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Skeleton, { className: "h-4 w-64" }), _jsx(Skeleton, { className: "h-4 w-48" }), _jsx(Skeleton, { className: "h-4 w-56" })] }) })),
14
25
  };
15
- export const CardSkeleton = {
16
- render: () => (_jsxs("div", { className: "w-80 rounded-lg border bg-card p-8 shadow-sm", children: [_jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(Skeleton, { className: "h-5 w-3/4" }), _jsx(Skeleton, { className: "h-4 w-full" }), _jsx(Skeleton, { className: "h-4 w-5/6" })] }), _jsxs("div", { className: "mt-6 flex flex-col gap-2", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx(Skeleton, { className: "h-3 w-16" }), _jsx(Skeleton, { className: "h-3 w-20" })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx(Skeleton, { className: "h-3 w-16" }), _jsx(Skeleton, { className: "h-3 w-14" })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx(Skeleton, { className: "h-3 w-16" }), _jsx(Skeleton, { className: "h-3 w-10" })] })] }), _jsxs("div", { className: "mt-6 flex gap-2", children: [_jsx(Skeleton, { className: "h-6 w-20 rounded-md" }), _jsx(Skeleton, { className: "h-6 w-16 rounded-md" })] })] })),
26
+ export const CardComposition = {
27
+ render: () => (_jsx("div", { className: "w-80 rounded-lg border bg-card p-8 shadow-sm", children: _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx(Skeleton, { className: "h-5 w-3/4" }), _jsx(Skeleton, { className: "h-4 w-full" }), _jsx(Skeleton, { className: "h-4 w-5/6" })] }) })),
17
28
  };
18
29
  export const CircleSkeleton = {
19
30
  render: () => (_jsxs("div", { className: "flex items-center gap-4", children: [_jsx(Skeleton, { className: "size-12 rounded-full" }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Skeleton, { className: "h-4 w-32" }), _jsx(Skeleton, { className: "h-3 w-24" })] })] })),
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton.stories.js","sourceRoot":"","sources":["../../src/components/skeleton.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,qBAAqB;IAC5B,SAAS,EAAE,QAAQ;IACnB,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;CACH,CAAC;AAElC,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,SAAS,EAAE,UAAU;KACtB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAU;IACjC,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,eAAK,SAAS,EAAC,8CAA8C,aAC3D,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,EAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,YAAY,GAAG,EACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,EACN,eAAK,SAAS,EAAC,0BAA0B,aACvC,eAAK,SAAS,EAAC,sBAAsB,aACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,EACN,eAAK,SAAS,EAAC,sBAAsB,aACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,EACN,eAAK,SAAS,EAAC,sBAAsB,aACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,IACF,EACN,eAAK,SAAS,EAAC,iBAAiB,aAC9B,KAAC,QAAQ,IAAC,SAAS,EAAC,qBAAqB,GAAG,EAC5C,KAAC,QAAQ,IAAC,SAAS,EAAC,qBAAqB,GAAG,IACxC,IACF,CACP;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAU;IACnC,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,QAAQ,IAAC,SAAS,EAAC,sBAAsB,GAAG,EAC7C,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,IACF,CACP;CACF,CAAC"}
1
+ {"version":3,"file":"skeleton.stories.js","sourceRoot":"","sources":["../../src/components/skeleton.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,qBAAqB;IAC5B,SAAS,EAAE,QAAQ;IACnB,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;IAClC,QAAQ,EAAE;QACR,IAAI,EAAE;YACJ,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC;KACF;CAC8B,CAAC;AAElC,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;CAChC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,eAAK,SAAS,EAAC,qBAAqB,aAClC,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAM,SAAS,EAAC,0EAA0E,uBAAc,EACxG,KAAC,QAAQ,IAAC,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,UAAU,GAAG,IAC3C,EACN,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAM,SAAS,EAAC,0EAA0E,qBAAY,EACtG,KAAC,QAAQ,IAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,UAAU,GAAG,IACzC,EACN,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAM,SAAS,EAAC,0EAA0E,qBAAY,EACtG,KAAC,QAAQ,IAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,UAAU,GAAG,IACzC,IACF,CACP;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAU;IAC3C,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,KAAC,gBAAgB,IAAC,IAAI,EAAC,MAAM,YAC3B,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,GACW,CACpB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAU;IACpC,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,cAAK,SAAS,EAAC,8CAA8C,YAC3D,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,EAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,YAAY,GAAG,EACnC,KAAC,QAAQ,IAAC,SAAS,EAAC,WAAW,GAAG,IAC9B,GACF,CACP;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAU;IACnC,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,eAAK,SAAS,EAAC,yBAAyB,aACtC,KAAC,QAAQ,IAAC,SAAS,EAAC,sBAAsB,GAAG,EAC7C,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,IAC7B,IACF,CACP;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sortable-card-shell.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sortable-card-shell.test.d.ts","sourceRoot":"","sources":["../../src/components/sortable-card-shell.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, beforeAll } from "vitest";
3
+ import { render, screen } from "@testing-library/react";
4
+ // @dnd-kit/dom touches `ResizeObserver` at module load time; jsdom does not
5
+ // provide one. Install a no-op polyfill BEFORE importing @dnd-kit/react or
6
+ // the shell (which transitively imports @dnd-kit/dom).
7
+ if (typeof globalThis.ResizeObserver === "undefined") {
8
+ class ResizeObserverPolyfill {
9
+ observe() { }
10
+ unobserve() { }
11
+ disconnect() { }
12
+ }
13
+ globalThis.ResizeObserver =
14
+ ResizeObserverPolyfill;
15
+ }
16
+ // Imports deferred to after the polyfill so module-level access succeeds.
17
+ const { DragDropProvider } = await import("@dnd-kit/react");
18
+ const { SortableCardShell, SORTABLE_CARD_NO_DRAG_SELECTOR } = await import("./sortable-card-shell");
19
+ beforeAll(() => {
20
+ // Sanity check — confirm the polyfill stuck.
21
+ expect(typeof globalThis.ResizeObserver).toBe("function");
22
+ });
23
+ // ─── Test harness ───────────────────────────────────────────────────────────
24
+ //
25
+ // `SortableCardShell` uses `useSortable` / `useDraggable` from @dnd-kit/react,
26
+ // which require a `DragDropProvider` ancestor. All tests wrap children in the
27
+ // provider; we are NOT testing dnd-kit's internals (activation, pointer
28
+ // tracking, drop detection) — we trust those. We test the two invariants
29
+ // this shell owns:
30
+ // 1. Visual affordances (grip is aria-hidden + pointer-events-none).
31
+ // 2. The interactive-element guard SELECTOR used by PointerSensor's
32
+ // `preventActivation` hook. The selector itself is a pure string, so
33
+ // we can verify its semantics by querying DOM with `closest()` — this
34
+ // is exactly the same call the guard performs at runtime.
35
+ //
36
+ // We do NOT try to actually fire a drag and assert the sensor's internal
37
+ // state: that would require a much heavier jsdom + PointerEvent polyfill
38
+ // setup and would mostly re-test @dnd-kit itself.
39
+ function renderWithProvider(ui) {
40
+ return render(_jsx(DragDropProvider, { children: ui }));
41
+ }
42
+ describe("SortableCardShell", () => {
43
+ it("renders children (smoke test, sortable mode)", () => {
44
+ renderWithProvider(_jsx(SortableCardShell, { id: "card-1", index: 0, group: "col-a", children: _jsx("div", { "data-testid": "card-body", children: "Ch\u00E2teau Margaux" }) }));
45
+ expect(screen.getByTestId("card-body")).toBeInTheDocument();
46
+ expect(screen.getByText("Château Margaux")).toBeInTheDocument();
47
+ });
48
+ it("renders children in draggable mode", () => {
49
+ renderWithProvider(_jsx(SortableCardShell, { id: "card-2", mode: "draggable", children: _jsx("div", { "data-testid": "card-body", children: "P\u00E9trus 2015" }) }));
50
+ expect(screen.getByTestId("card-body")).toBeInTheDocument();
51
+ });
52
+ it("renders a grip affordance that is aria-hidden and pointer-events-none", () => {
53
+ const { container } = renderWithProvider(_jsx(SortableCardShell, { id: "card-grip", index: 0, group: "col-a", children: _jsx("div", { children: "body" }) }));
54
+ // The grip is an aria-hidden <span> sibling of the card body. Query it
55
+ // by attribute — this is the most robust selector since the grip has no
56
+ // accessible name by design.
57
+ const grip = container.querySelector('[aria-hidden="true"]');
58
+ expect(grip).not.toBeNull();
59
+ // Pointer events must be disabled so the whole card remains the drag
60
+ // activation surface — the grip is purely visual.
61
+ expect(grip?.className).toContain("pointer-events-none");
62
+ // lucide-react renders an inline SVG inside the grip.
63
+ expect(grip?.querySelector("svg")).not.toBeNull();
64
+ });
65
+ it("omits the grip when hideGrip is true", () => {
66
+ const { container } = renderWithProvider(_jsx(SortableCardShell, { id: "card-no-grip", index: 0, group: "col-a", hideGrip: true, children: _jsx("div", { children: "body" }) }));
67
+ expect(container.querySelector('[aria-hidden="true"]')).toBeNull();
68
+ });
69
+ // ─── Interactive-element guard ────────────────────────────────────────────
70
+ //
71
+ // The shell registers a PointerSensor with
72
+ // `preventActivation: (e) => shouldPreventDragActivation(e)`, which does
73
+ // `target.closest(SORTABLE_CARD_NO_DRAG_SELECTOR)`. We verify the selector
74
+ // matches the right elements; that is the same check the guard performs.
75
+ it("interactive guard: a <button> inside the card matches the no-drag selector", () => {
76
+ renderWithProvider(_jsx(SortableCardShell, { id: "card-btn", index: 0, group: "col-a", children: _jsx("div", { children: _jsx("button", { type: "button", "data-testid": "row-menu", children: "Menu" }) }) }));
77
+ const btn = screen.getByTestId("row-menu");
78
+ // `closest()` on the button itself should return the button — meaning
79
+ // a pointerdown on that target would short-circuit activation.
80
+ expect(btn.closest(SORTABLE_CARD_NO_DRAG_SELECTOR)).toBe(btn);
81
+ });
82
+ it("interactive guard: an element with data-no-drag matches the no-drag selector", () => {
83
+ renderWithProvider(_jsx(SortableCardShell, { id: "card-no-drag", index: 0, group: "col-a", children: _jsx("div", { children: _jsx("div", { "data-no-drag": true, "data-testid": "badge", children: "Badge" }) }) }));
84
+ const badge = screen.getByTestId("badge");
85
+ expect(badge.closest(SORTABLE_CARD_NO_DRAG_SELECTOR)).toBe(badge);
86
+ });
87
+ it("interactive guard: a plain <div> does NOT match the no-drag selector (drag would proceed)", () => {
88
+ renderWithProvider(_jsx(SortableCardShell, { id: "card-plain", index: 0, group: "col-a", children: _jsx("div", { "data-testid": "plain-body", children: "Drag me from here" }) }));
89
+ const plain = screen.getByTestId("plain-body");
90
+ // No ancestor or self matches any interactive selector — activation is
91
+ // allowed to proceed (drag would start).
92
+ expect(plain.closest(SORTABLE_CARD_NO_DRAG_SELECTOR)).toBeNull();
93
+ });
94
+ it("interactive guard: a nested element inside a <button> matches via closest()", () => {
95
+ // Realistic case: a button containing an icon <span> — the pointerdown
96
+ // target is often the inner element, and `closest()` should still find
97
+ // the wrapping <button> ancestor.
98
+ renderWithProvider(_jsx(SortableCardShell, { id: "card-nested", index: 0, group: "col-a", children: _jsx("div", { children: _jsx("button", { type: "button", children: _jsx("span", { "data-testid": "icon", children: "x" }) }) }) }));
99
+ const icon = screen.getByTestId("icon");
100
+ const match = icon.closest(SORTABLE_CARD_NO_DRAG_SELECTOR);
101
+ expect(match).not.toBeNull();
102
+ expect(match?.tagName).toBe("BUTTON");
103
+ });
104
+ it("exports a selector string that includes the common interactive tags", () => {
105
+ // Defensive snapshot of the guard's surface area. If this list ever
106
+ // shrinks, a regression would silently break click-through; this test
107
+ // will flag it.
108
+ expect(SORTABLE_CARD_NO_DRAG_SELECTOR).toContain("[data-no-drag]");
109
+ expect(SORTABLE_CARD_NO_DRAG_SELECTOR).toContain("button");
110
+ expect(SORTABLE_CARD_NO_DRAG_SELECTOR).toContain("a");
111
+ expect(SORTABLE_CARD_NO_DRAG_SELECTOR).toContain("input");
112
+ expect(SORTABLE_CARD_NO_DRAG_SELECTOR).toContain("[role='menuitem']");
113
+ });
114
+ });
115
+ //# sourceMappingURL=sortable-card-shell.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sortable-card-shell.test.js","sourceRoot":"","sources":["../../src/components/sortable-card-shell.test.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import * as React from "react";
2
+ import { type SkeletonTier } from "../skeleton/stagger";
2
3
  export interface StatCardProps {
3
4
  icon: React.ReactNode;
4
5
  label: string;
@@ -8,5 +9,13 @@ export interface StatCardProps {
8
9
  renderLink?: (href: string, children: React.ReactNode) => React.ReactNode;
9
10
  className?: string;
10
11
  }
11
- export declare function StatCard({ icon, label, value, description, href, renderLink, className, }: StatCardProps): import("react/jsx-runtime").JSX.Element;
12
+ declare function StatCardBase({ icon, label, value, description, href, renderLink, className, }: StatCardProps): import("react/jsx-runtime").JSX.Element;
13
+ export interface StatCardSkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
14
+ tier?: SkeletonTier;
15
+ }
16
+ declare function StatCardSkeleton({ tier, style, className, ...rest }: StatCardSkeletonProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare const StatCard: typeof StatCardBase & {
18
+ Skeleton: typeof StatCardSkeleton;
19
+ };
20
+ export {};
12
21
  //# sourceMappingURL=stat-card.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../../src/components/stat-card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,WAAW,EACX,IAAI,EACJ,UAAU,EACV,SAAS,GACV,EAAE,aAAa,2CAiCf"}
1
+ {"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../../src/components/stat-card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAuC,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE7F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iBAAS,YAAY,CAAC,EACpB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,WAAW,EACX,IAAI,EACJ,UAAU,EACV,SAAS,GACV,EAAE,aAAa,2CAiCf;AAED,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACjF,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,iBAAS,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,qBAAqB,2CAgCnF;AAED,eAAO,MAAM,QAAQ;;CAA8D,CAAC"}
@@ -1,10 +1,24 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils";
3
- export function StatCard({ icon, label, value, description, href, renderLink, className, }) {
3
+ import { Skeleton } from "./skeleton";
4
+ import { useCascadeIndex, useSkeletonContext } from "../skeleton/stagger";
5
+ function StatCardBase({ icon, label, value, description, href, renderLink, className, }) {
4
6
  const cardContent = (_jsxs("div", { className: cn("h-full border-border/60 bg-card rounded-2xl p-5 transition-colors", href && renderLink && "hover:bg-accent/30 cursor-pointer", className), children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsx("p", { className: "text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: label }), _jsx("p", { className: "text-3xl font-bold tracking-tight text-foreground", children: value })] }), _jsx("div", { className: "tone-icon tone-brand shrink-0 rounded-xl p-2.5", children: icon })] }), description && (_jsx("p", { className: "mt-4 text-sm/5 text-muted-foreground", children: description }))] }));
5
7
  if (href && renderLink) {
6
8
  return _jsx(_Fragment, { children: renderLink(href, cardContent) });
7
9
  }
8
10
  return cardContent;
9
11
  }
12
+ function StatCardSkeleton({ tier, style, className, ...rest }) {
13
+ const ctx = useSkeletonContext();
14
+ const resolvedTier = tier ?? (ctx.hasProvider ? ctx.tier : "hero");
15
+ const index = useCascadeIndex();
16
+ const delayMs = index * ctx.stagger;
17
+ const mergedStyle = {
18
+ ...(style ?? {}),
19
+ ["--skeleton-delay"]: `${delayMs}ms`,
20
+ };
21
+ return (_jsxs("div", { "data-skeleton-card": "", "data-tier": resolvedTier, className: cn("rounded-2xl border border-border/60 bg-card p-5", className), style: mergedStyle, ...rest, children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "grid gap-2.5", children: [_jsx(Skeleton, { tier: resolvedTier, className: "h-3 w-20" }), _jsx(Skeleton, { tier: resolvedTier, className: "h-7 w-24" })] }), _jsx(Skeleton, { tier: resolvedTier, className: "size-9 rounded-xl" })] }), _jsx(Skeleton, { tier: resolvedTier, className: "mt-4 h-3 w-40" })] }));
22
+ }
23
+ export const StatCard = Object.assign(StatCardBase, { Skeleton: StatCardSkeleton });
10
24
  //# sourceMappingURL=stat-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stat-card.js","sourceRoot":"","sources":["../../src/components/stat-card.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAYlC,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,WAAW,EACX,IAAI,EACJ,UAAU,EACV,SAAS,GACK;IACd,MAAM,WAAW,GAAG,CAClB,eACE,SAAS,EAAE,EAAE,CACX,mEAAmE,EACnE,IAAI,IAAI,UAAU,IAAI,mCAAmC,EACzD,SAAS,CACV,aAED,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAK,SAAS,EAAC,cAAc,aAC3B,YAAG,SAAS,EAAC,yEAAyE,YACnF,KAAK,GACJ,EACJ,YAAG,SAAS,EAAC,mDAAmD,YAC7D,KAAK,GACJ,IACA,EACN,cAAK,SAAS,EAAC,gDAAgD,YAC5D,IAAI,GACD,IACF,EACL,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,sCAAsC,YAAE,WAAW,GAAK,CACtE,IACG,CACP,CAAC;IAEF,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC;QACvB,OAAO,4BAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,GAAI,CAAC;IAC9C,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"stat-card.js","sourceRoot":"","sources":["../../src/components/stat-card.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAqB,MAAM,qBAAqB,CAAC;AAY7F,SAAS,YAAY,CAAC,EACpB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,WAAW,EACX,IAAI,EACJ,UAAU,EACV,SAAS,GACK;IACd,MAAM,WAAW,GAAG,CAClB,eACE,SAAS,EAAE,EAAE,CACX,mEAAmE,EACnE,IAAI,IAAI,UAAU,IAAI,mCAAmC,EACzD,SAAS,CACV,aAED,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAK,SAAS,EAAC,cAAc,aAC3B,YAAG,SAAS,EAAC,yEAAyE,YACnF,KAAK,GACJ,EACJ,YAAG,SAAS,EAAC,mDAAmD,YAC7D,KAAK,GACJ,IACA,EACN,cAAK,SAAS,EAAC,gDAAgD,YAC5D,IAAI,GACD,IACF,EACL,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,sCAAsC,YAAE,WAAW,GAAK,CACtE,IACG,CACP,CAAC;IAEF,IAAI,IAAI,IAAI,UAAU,EAAE,CAAC;QACvB,OAAO,4BAAG,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,GAAI,CAAC;IAC9C,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAMD,SAAS,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAyB;IAClF,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,MAAM,YAAY,GAAiB,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC;IAEpC,MAAM,WAAW,GAAwB;QACvC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAChB,CAAC,kBAA4B,CAAC,EAAE,GAAG,OAAO,IAAI;KAC/C,CAAC;IAEF,OAAO,CACL,qCACqB,EAAE,eACV,YAAY,EACvB,SAAS,EAAE,EAAE,CACX,iDAAiD,EACjD,SAAS,CACV,EACD,KAAK,EAAE,WAAW,KACd,IAAI,aAER,eAAK,SAAS,EAAC,wCAAwC,aACrD,eAAK,SAAS,EAAC,cAAc,aAC3B,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,EACrD,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,UAAU,GAAG,IACjD,EACN,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,mBAAmB,GAAG,IAC1D,EACN,KAAC,QAAQ,IAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAC,eAAe,GAAG,IACtD,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import type { StoryObj } from "@storybook/react-vite";
2
- import { StatCard } from "./stat-card";
3
2
  declare const meta: {
4
3
  title: string;
5
- component: typeof StatCard;
4
+ component: (({ icon, label, value, description, href, renderLink, className, }: import("./stat-card").StatCardProps) => import("react/jsx-runtime").JSX.Element) & {
5
+ Skeleton: ({ tier, style, className, ...rest }: import("./stat-card").StatCardSkeletonProps) => import("react/jsx-runtime").JSX.Element;
6
+ };
6
7
  tags: string[];
7
8
  parameters: {
8
9
  layout: string;
@@ -14,4 +15,7 @@ export declare const Default: Story;
14
15
  export declare const WithDescription: Story;
15
16
  export declare const Grid: Story;
16
17
  export declare const Clickable: Story;
18
+ export declare const SkeletonStandalone: Story;
19
+ export declare const SkeletonInProvider: Story;
20
+ export declare const SkeletonInlineTier: Story;
17
21
  //# sourceMappingURL=stat-card.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stat-card.stories.d.ts","sourceRoot":"","sources":["../../src/components/stat-card.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,QAAA,MAAM,IAAI;;;;;;;CAKuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAoEnC,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAQ7B,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KA8BlB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAcvB,CAAC"}
1
+ {"version":3,"file":"stat-card.stories.d.ts","sourceRoot":"","sources":["../../src/components/stat-card.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAsE5D,QAAA,MAAM,IAAI;;;;;;;;;CAKuB,CAAC;AAElC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAQ7B,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,KA8BlB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAcvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAGhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAYhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAGhC,CAAC"}