@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.
- package/dist/components/__tests__/animated-list-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/animated-list-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/animated-list-skeleton.test.js +11 -0
- package/dist/components/__tests__/animated-list-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/card-grid-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/card-grid-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/card-grid-skeleton.test.js +22 -0
- package/dist/components/__tests__/card-grid-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.js +39 -0
- package/dist/components/__tests__/dashboard-stats-grid-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/data-table-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/data-table-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/data-table-skeleton.test.js +27 -0
- package/dist/components/__tests__/data-table-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/detail-page-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/detail-page-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/detail-page-skeleton.test.js +30 -0
- package/dist/components/__tests__/detail-page-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/list-item-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/list-item-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/list-item-skeleton.test.js +38 -0
- package/dist/components/__tests__/list-item-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/profile-header-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/profile-header-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/profile-header-skeleton.test.js +17 -0
- package/dist/components/__tests__/profile-header-skeleton.test.js.map +1 -0
- package/dist/components/__tests__/stat-card-skeleton.test.d.ts +2 -0
- package/dist/components/__tests__/stat-card-skeleton.test.d.ts.map +1 -0
- package/dist/components/__tests__/stat-card-skeleton.test.js +33 -0
- package/dist/components/__tests__/stat-card-skeleton.test.js.map +1 -0
- package/dist/components/animated-list.d.ts +11 -1
- package/dist/components/animated-list.d.ts.map +1 -1
- package/dist/components/animated-list.js +7 -1
- package/dist/components/animated-list.js.map +1 -1
- package/dist/components/animated-list.stories.d.ts +3 -2
- package/dist/components/animated-list.stories.d.ts.map +1 -1
- package/dist/components/bottle-extract-dialog.js +4 -5
- package/dist/components/bottle-extract-dialog.js.map +1 -1
- package/dist/components/card-grid-skeleton.d.ts +9 -0
- package/dist/components/card-grid-skeleton.d.ts.map +1 -0
- package/dist/components/card-grid-skeleton.js +16 -0
- package/dist/components/card-grid-skeleton.js.map +1 -0
- package/dist/components/card-grid-skeleton.stories.d.ts +35 -0
- package/dist/components/card-grid-skeleton.stories.d.ts.map +1 -0
- package/dist/components/card-grid-skeleton.stories.js +22 -0
- package/dist/components/card-grid-skeleton.stories.js.map +1 -0
- package/dist/components/dashboard-stats-grid.d.ts +11 -1
- package/dist/components/dashboard-stats-grid.d.ts.map +1 -1
- package/dist/components/dashboard-stats-grid.js +19 -12
- package/dist/components/dashboard-stats-grid.js.map +1 -1
- package/dist/components/dashboard-stats-grid.stories.d.ts +19 -0
- package/dist/components/dashboard-stats-grid.stories.d.ts.map +1 -0
- package/dist/components/dashboard-stats-grid.stories.js +34 -0
- package/dist/components/dashboard-stats-grid.stories.js.map +1 -0
- package/dist/components/data-table-skeleton.d.ts +9 -0
- package/dist/components/data-table-skeleton.d.ts.map +1 -0
- package/dist/components/data-table-skeleton.js +14 -0
- package/dist/components/data-table-skeleton.js.map +1 -0
- package/dist/components/data-table-skeleton.stories.d.ts +36 -0
- package/dist/components/data-table-skeleton.stories.d.ts.map +1 -0
- package/dist/components/data-table-skeleton.stories.js +22 -0
- package/dist/components/data-table-skeleton.stories.js.map +1 -0
- package/dist/components/detail-page-skeleton.d.ts +11 -0
- package/dist/components/detail-page-skeleton.d.ts.map +1 -0
- package/dist/components/detail-page-skeleton.js +14 -0
- package/dist/components/detail-page-skeleton.js.map +1 -0
- package/dist/components/detail-page-skeleton.stories.d.ts +15 -0
- package/dist/components/detail-page-skeleton.stories.d.ts.map +1 -0
- package/dist/components/detail-page-skeleton.stories.js +15 -0
- package/dist/components/detail-page-skeleton.stories.js.map +1 -0
- package/dist/components/extraction-phase-stepper.d.ts.map +1 -1
- package/dist/components/extraction-phase-stepper.js +5 -4
- package/dist/components/extraction-phase-stepper.js.map +1 -1
- package/dist/components/list-item-skeleton.d.ts +9 -0
- package/dist/components/list-item-skeleton.d.ts.map +1 -0
- package/dist/components/list-item-skeleton.js +13 -0
- package/dist/components/list-item-skeleton.js.map +1 -0
- package/dist/components/list-item-skeleton.stories.d.ts +27 -0
- package/dist/components/list-item-skeleton.stories.d.ts.map +1 -0
- package/dist/components/list-item-skeleton.stories.js +21 -0
- package/dist/components/list-item-skeleton.stories.js.map +1 -0
- package/dist/components/opportunity-brief.d.ts +44 -1
- package/dist/components/opportunity-brief.d.ts.map +1 -1
- package/dist/components/opportunity-brief.js +50 -2
- package/dist/components/opportunity-brief.js.map +1 -1
- package/dist/components/opportunity-brief.stories.d.ts +13 -0
- package/dist/components/opportunity-brief.stories.d.ts.map +1 -1
- package/dist/components/opportunity-brief.stories.js +48 -0
- package/dist/components/opportunity-brief.stories.js.map +1 -1
- package/dist/components/profile-header-skeleton.d.ts +12 -0
- package/dist/components/profile-header-skeleton.d.ts.map +1 -0
- package/dist/components/profile-header-skeleton.js +15 -0
- package/dist/components/profile-header-skeleton.js.map +1 -0
- package/dist/components/profile-header-skeleton.stories.d.ts +15 -0
- package/dist/components/profile-header-skeleton.stories.d.ts.map +1 -0
- package/dist/components/profile-header-skeleton.stories.js +15 -0
- package/dist/components/profile-header-skeleton.stories.js.map +1 -0
- package/dist/components/skeleton.d.ts +6 -1
- package/dist/components/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton.js +5 -2
- package/dist/components/skeleton.js.map +1 -1
- package/dist/components/skeleton.stories.d.ts +9 -1
- package/dist/components/skeleton.stories.d.ts.map +1 -1
- package/dist/components/skeleton.stories.js +16 -5
- package/dist/components/skeleton.stories.js.map +1 -1
- package/dist/components/sortable-card-shell.test.d.ts +2 -0
- package/dist/components/sortable-card-shell.test.d.ts.map +1 -0
- package/dist/components/sortable-card-shell.test.js +115 -0
- package/dist/components/sortable-card-shell.test.js.map +1 -0
- package/dist/components/stat-card.d.ts +10 -1
- package/dist/components/stat-card.d.ts.map +1 -1
- package/dist/components/stat-card.js +15 -1
- package/dist/components/stat-card.js.map +1 -1
- package/dist/components/stat-card.stories.d.ts +6 -2
- package/dist/components/stat-card.stories.d.ts.map +1 -1
- package/dist/components/stat-card.stories.js +17 -4
- package/dist/components/stat-card.stories.js.map +1 -1
- package/dist/components/variant-picker-dialog.d.ts +13 -1
- package/dist/components/variant-picker-dialog.d.ts.map +1 -1
- package/dist/components/variant-picker-dialog.js +2 -2
- package/dist/components/variant-picker-dialog.js.map +1 -1
- package/dist/components/variant-picker-dialog.stories.d.ts +13 -0
- package/dist/components/variant-picker-dialog.stories.d.ts.map +1 -1
- package/dist/components/variant-picker-dialog.stories.js +72 -0
- package/dist/components/variant-picker-dialog.stories.js.map +1 -1
- package/dist/components/variant-picker-dialog.test.js +1 -1
- package/dist/components/variant-picker-dialog.test.js.map +1 -1
- package/dist/globe/__tests__/globe-loading-skeleton.test.d.ts +2 -0
- package/dist/globe/__tests__/globe-loading-skeleton.test.d.ts.map +1 -0
- package/dist/globe/__tests__/globe-loading-skeleton.test.js +29 -0
- package/dist/globe/__tests__/globe-loading-skeleton.test.js.map +1 -0
- package/dist/globe/globe-loading-skeleton.d.ts +13 -5
- package/dist/globe/globe-loading-skeleton.d.ts.map +1 -1
- package/dist/globe/globe-loading-skeleton.js +9 -2
- package/dist/globe/globe-loading-skeleton.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/skeleton/__tests__/loader.test.d.ts +2 -0
- package/dist/skeleton/__tests__/loader.test.d.ts.map +1 -0
- package/dist/skeleton/__tests__/loader.test.js +33 -0
- package/dist/skeleton/__tests__/loader.test.js.map +1 -0
- package/dist/skeleton/__tests__/primitive.test.d.ts +2 -0
- package/dist/skeleton/__tests__/primitive.test.d.ts.map +1 -0
- package/dist/skeleton/__tests__/primitive.test.js +36 -0
- package/dist/skeleton/__tests__/primitive.test.js.map +1 -0
- package/dist/skeleton/__tests__/provider.test.d.ts +2 -0
- package/dist/skeleton/__tests__/provider.test.d.ts.map +1 -0
- package/dist/skeleton/__tests__/provider.test.js +78 -0
- package/dist/skeleton/__tests__/provider.test.js.map +1 -0
- package/dist/skeleton/index.d.ts +5 -0
- package/dist/skeleton/index.d.ts.map +1 -0
- package/dist/skeleton/index.js +5 -0
- package/dist/skeleton/index.js.map +1 -0
- package/dist/skeleton/loader.d.ts +15 -0
- package/dist/skeleton/loader.d.ts.map +1 -0
- package/dist/skeleton/loader.js +21 -0
- package/dist/skeleton/loader.js.map +1 -0
- package/dist/skeleton/loader.stories.d.ts +16 -0
- package/dist/skeleton/loader.stories.d.ts.map +1 -0
- package/dist/skeleton/loader.stories.js +27 -0
- package/dist/skeleton/loader.stories.js.map +1 -0
- package/dist/skeleton/provider.d.ts +13 -0
- package/dist/skeleton/provider.d.ts.map +1 -0
- package/dist/skeleton/provider.js +27 -0
- package/dist/skeleton/provider.js.map +1 -0
- package/dist/skeleton/stagger.d.ts +30 -0
- package/dist/skeleton/stagger.d.ts.map +1 -0
- package/dist/skeleton/stagger.js +45 -0
- package/dist/skeleton/stagger.js.map +1 -0
- package/package.json +1 -1
- 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
|
-
|
|
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;
|
|
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
|
-
|
|
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":"
|
|
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
|
-
|
|
4
|
-
|
|
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":";
|
|
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
|
|
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;
|
|
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
|
-
|
|
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
|
|
16
|
-
render: () => (
|
|
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;
|
|
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 @@
|
|
|
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":";AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGxD,4EAA4E;AAC5E,2EAA2E;AAC3E,uDAAuD;AACvD,IAAI,OAAO,UAAU,CAAC,cAAc,KAAK,WAAW,EAAE,CAAC;IACrD,MAAM,sBAAsB;QAC1B,OAAO,KAAI,CAAC;QACZ,SAAS,KAAI,CAAC;QACd,UAAU,KAAI,CAAC;KAChB;IACA,UAA2E,CAAC,cAAc;QACzF,sBAAsB,CAAC;AAC3B,CAAC;AAED,0EAA0E;AAC1E,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC5D,MAAM,EAAE,iBAAiB,EAAE,8BAA8B,EAAE,GAAG,MAAM,MAAM,CACxE,uBAAuB,CACxB,CAAC;AAEF,SAAS,CAAC,GAAG,EAAE;IACb,6CAA6C;IAC7C,MAAM,CAAC,OAAO,UAAU,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,8EAA8E;AAC9E,wEAAwE;AACxE,yEAAyE;AACzE,mBAAmB;AACnB,uEAAuE;AACvE,sEAAsE;AACtE,0EAA0E;AAC1E,2EAA2E;AAC3E,+DAA+D;AAC/D,EAAE;AACF,yEAAyE;AACzE,yEAAyE;AACzE,kDAAkD;AAElD,SAAS,kBAAkB,CAAC,EAAa;IACvC,OAAO,MAAM,CAAC,KAAC,gBAAgB,cAAE,EAAE,GAAoB,CAAC,CAAC;AAC3D,CAAC;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,kBAAkB,CAChB,KAAC,iBAAiB,IAAC,EAAE,EAAC,QAAQ,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,YACpD,6BAAiB,WAAW,qCAAsB,GAChC,CACrB,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,kBAAkB,CAChB,KAAC,iBAAiB,IAAC,EAAE,EAAC,QAAQ,EAAC,IAAI,EAAC,WAAW,YAC7C,6BAAiB,WAAW,iCAAkB,GAC5B,CACrB,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,CACtC,KAAC,iBAAiB,IAAC,EAAE,EAAC,WAAW,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,YACvD,iCAAe,GACG,CACrB,CAAC;QAEF,uEAAuE;QACvE,wEAAwE;QACxE,6BAA6B;QAC7B,MAAM,IAAI,GAAG,SAAS,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC5B,qEAAqE;QACrE,kDAAkD;QAClD,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QACzD,sDAAsD;QACtD,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,CACtC,KAAC,iBAAiB,IAAC,EAAE,EAAC,cAAc,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,EAAC,QAAQ,kBACnE,iCAAe,GACG,CACrB,CAAC;QAEF,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,6EAA6E;IAC7E,EAAE;IACF,2CAA2C;IAC3C,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IAEzE,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACpF,kBAAkB,CAChB,KAAC,iBAAiB,IAAC,EAAE,EAAC,UAAU,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,YACtD,wBACE,iBAAQ,IAAI,EAAC,QAAQ,iBAAa,UAAU,qBAEnC,GACL,GACY,CACrB,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC3C,sEAAsE;QACtE,+DAA+D;QAC/D,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,kBAAkB,CAChB,KAAC,iBAAiB,IAAC,EAAE,EAAC,cAAc,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,YAC1D,wBACE,mDAA8B,OAAO,sBAE/B,GACF,GACY,CACrB,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2FAA2F,EAAE,GAAG,EAAE;QACnG,kBAAkB,CAChB,KAAC,iBAAiB,IAAC,EAAE,EAAC,YAAY,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,YACxD,6BAAiB,YAAY,kCAAwB,GACnC,CACrB,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAC/C,uEAAuE;QACvE,yCAAyC;QACzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,uEAAuE;QACvE,uEAAuE;QACvE,kCAAkC;QAClC,kBAAkB,CAChB,KAAC,iBAAiB,IAAC,EAAE,EAAC,aAAa,EAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAC,OAAO,YACzD,wBACE,iBAAQ,IAAI,EAAC,QAAQ,YACnB,8BAAkB,MAAM,kBAAS,GAC1B,GACL,GACY,CACrB,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,oEAAoE;QACpE,sEAAsE;QACtE,gBAAgB;QAChB,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACnE,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC3D,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACtD,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,CAAC,8BAA8B,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -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
|
-
|
|
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,
|
|
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
|
-
|
|
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;
|
|
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:
|
|
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;
|
|
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"}
|