@cellarnode/ui 0.12.15 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/components/opportunity-brief.d.ts +23 -0
  2. package/dist/components/opportunity-brief.d.ts.map +1 -0
  3. package/dist/components/opportunity-brief.js +13 -0
  4. package/dist/components/opportunity-brief.js.map +1 -0
  5. package/dist/components/opportunity-brief.stories.d.ts +17 -0
  6. package/dist/components/opportunity-brief.stories.d.ts.map +1 -0
  7. package/dist/components/opportunity-brief.stories.js +38 -0
  8. package/dist/components/opportunity-brief.stories.js.map +1 -0
  9. package/dist/components/picker-empty-guidance.d.ts +20 -0
  10. package/dist/components/picker-empty-guidance.d.ts.map +1 -0
  11. package/dist/components/picker-empty-guidance.js +14 -0
  12. package/dist/components/picker-empty-guidance.js.map +1 -0
  13. package/dist/components/picker-empty-guidance.stories.d.ts +20 -0
  14. package/dist/components/picker-empty-guidance.stories.d.ts.map +1 -0
  15. package/dist/components/picker-empty-guidance.stories.js +33 -0
  16. package/dist/components/picker-empty-guidance.stories.js.map +1 -0
  17. package/dist/components/reason-pill.d.ts +17 -0
  18. package/dist/components/reason-pill.d.ts.map +1 -0
  19. package/dist/components/reason-pill.js +20 -0
  20. package/dist/components/reason-pill.js.map +1 -0
  21. package/dist/components/reason-pill.stories.d.ts +18 -0
  22. package/dist/components/reason-pill.stories.d.ts.map +1 -0
  23. package/dist/components/reason-pill.stories.js +18 -0
  24. package/dist/components/reason-pill.stories.js.map +1 -0
  25. package/dist/components/score-chip.d.ts +16 -0
  26. package/dist/components/score-chip.d.ts.map +1 -0
  27. package/dist/components/score-chip.js +26 -0
  28. package/dist/components/score-chip.js.map +1 -0
  29. package/dist/components/score-chip.stories.d.ts +18 -0
  30. package/dist/components/score-chip.stories.d.ts.map +1 -0
  31. package/dist/components/score-chip.stories.js +18 -0
  32. package/dist/components/score-chip.stories.js.map +1 -0
  33. package/dist/components/variant-picker-dialog.d.ts +38 -32
  34. package/dist/components/variant-picker-dialog.d.ts.map +1 -1
  35. package/dist/components/variant-picker-dialog.js +54 -76
  36. package/dist/components/variant-picker-dialog.js.map +1 -1
  37. package/dist/components/variant-picker-dialog.stories.d.ts +3 -3
  38. package/dist/components/variant-picker-dialog.stories.d.ts.map +1 -1
  39. package/dist/components/variant-picker-dialog.stories.js +133 -92
  40. package/dist/components/variant-picker-dialog.stories.js.map +1 -1
  41. package/dist/index.d.ts +5 -1
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +6 -1
  44. package/dist/index.js.map +1 -1
  45. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ export interface OpportunityBriefChip {
2
+ label: string;
3
+ }
4
+ export interface OpportunityBriefProps {
5
+ /** Title shown bold. */
6
+ name: string;
7
+ /** Optional buyer name shown muted under the title. */
8
+ buyerName?: string | null;
9
+ /** Pills (category, subtype, country, volume, deadline). Display order = props order. */
10
+ chips: OpportunityBriefChip[];
11
+ /** Eyebrow label above the name. @default "Looking for" */
12
+ eyebrow?: string;
13
+ className?: string;
14
+ }
15
+ /**
16
+ * Compact opportunity-context banner used at the top of the producer picker
17
+ * and anywhere an opportunity needs to be identified at a glance (importer
18
+ * opportunity list, match detail pane).
19
+ *
20
+ * Intentionally visual-only — all interaction happens on the host container.
21
+ */
22
+ export declare function OpportunityBrief({ name, buyerName, chips, eyebrow, className, }: OpportunityBriefProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=opportunity-brief.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opportunity-brief.d.ts","sourceRoot":"","sources":["../../src/components/opportunity-brief.tsx"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yFAAyF;IACzF,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,SAAS,EACT,KAAK,EACL,OAAuB,EACvB,SAAS,GACV,EAAE,qBAAqB,2CA6BvB"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils";
3
+ /**
4
+ * Compact opportunity-context banner used at the top of the producer picker
5
+ * and anywhere an opportunity needs to be identified at a glance (importer
6
+ * opportunity list, match detail pane).
7
+ *
8
+ * Intentionally visual-only — all interaction happens on the host container.
9
+ */
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))) }))] }));
12
+ }
13
+ //# sourceMappingURL=opportunity-brief.js.map
@@ -0,0 +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"}
@@ -0,0 +1,17 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ import { OpportunityBrief } from "./opportunity-brief";
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof OpportunityBrief;
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 NoBuyer: Story;
15
+ export declare const NoChips: Story;
16
+ export declare const CustomEyebrow: Story;
17
+ //# sourceMappingURL=opportunity-brief.stories.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,38 @@
1
+ import { OpportunityBrief } from "./opportunity-brief";
2
+ const meta = {
3
+ title: "Picker/OpportunityBrief",
4
+ component: OpportunityBrief,
5
+ tags: ["autodocs"],
6
+ parameters: { layout: "centered" },
7
+ };
8
+ export default meta;
9
+ export const Default = {
10
+ args: {
11
+ name: "brandy spirits · Spain Selection",
12
+ buyerName: "Systembolaget",
13
+ chips: [
14
+ { label: "Spirits" },
15
+ { label: "Brandy" },
16
+ { label: "Spain" },
17
+ { label: "330 L" },
18
+ { label: "due Mar 17" },
19
+ ],
20
+ },
21
+ };
22
+ export const NoBuyer = {
23
+ args: {
24
+ name: "Riesling Selection 2026",
25
+ chips: [{ label: "Wine" }, { label: "White wine" }, { label: "Germany" }],
26
+ },
27
+ };
28
+ export const NoChips = {
29
+ args: { name: "Untyped opportunity", chips: [] },
30
+ };
31
+ export const CustomEyebrow = {
32
+ args: {
33
+ name: "Q2 discovery wishlist",
34
+ eyebrow: "Saved search",
35
+ chips: [{ label: "Organic" }, { label: "<15 EUR" }],
36
+ },
37
+ };
38
+ //# sourceMappingURL=opportunity-brief.stories.js.map
@@ -0,0 +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"}
@@ -0,0 +1,20 @@
1
+ export interface PickerEmptyGuidanceProps {
2
+ /** Display label for the missing category, e.g. "Spirits · Brandy". */
3
+ categoryLabel: string;
4
+ /** CTA label for the create-new button, e.g. "Create a new brandy product". */
5
+ createLabel: string;
6
+ /** Skip CTA label. @default "Draft manually" */
7
+ skipLabel?: string;
8
+ /** Override the body copy (defaults to a category-aware message). */
9
+ body?: string;
10
+ onCreate: () => void;
11
+ onSkip: () => void;
12
+ className?: string;
13
+ }
14
+ /**
15
+ * Empty-state block shown inside the picker when the producer has no
16
+ * in-category products. Create-new CTA is elevated (primary); skip-to-manual
17
+ * is secondary. Host wires both handlers to its own navigation / mutation.
18
+ */
19
+ export declare function PickerEmptyGuidance({ categoryLabel, createLabel, skipLabel, body, onCreate, onSkip, className, }: PickerEmptyGuidanceProps): import("react/jsx-runtime").JSX.Element;
20
+ //# sourceMappingURL=picker-empty-guidance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-empty-guidance.d.ts","sourceRoot":"","sources":["../../src/components/picker-empty-guidance.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,aAAa,EACb,WAAW,EACX,SAA4B,EAC5B,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,GACV,EAAE,wBAAwB,2CA6B1B"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ArrowRight, Plus } from "lucide-react";
3
+ import { cn } from "../lib/utils";
4
+ /**
5
+ * Empty-state block shown inside the picker when the producer has no
6
+ * in-category products. Create-new CTA is elevated (primary); skip-to-manual
7
+ * is secondary. Host wires both handlers to its own navigation / mutation.
8
+ */
9
+ export function PickerEmptyGuidance({ categoryLabel, createLabel, skipLabel = "Draft manually", body, onCreate, onSkip, className, }) {
10
+ const message = body
11
+ ?? `Your portfolio has no ${categoryLabel}. To respond to this opportunity you can either add a matching product or draft the offer manually.`;
12
+ return (_jsxs("div", { className: cn("flex flex-col gap-2", className), children: [_jsx("div", { className: "rounded-lg border border-dashed border-warning/60 bg-warning/10 px-3 py-2.5 text-[11px] leading-relaxed text-warning-foreground", children: message }), _jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", children: [_jsxs("button", { type: "button", onClick: onCreate, className: "inline-flex flex-1 items-center justify-center gap-2 rounded-lg bg-primary px-3 py-2 text-[12px] font-semibold text-primary-foreground transition-[filter] hover:brightness-110 focus:outline-none focus:ring-2 focus:ring-primary/40", children: [_jsx(Plus, { className: "size-3.5", "aria-hidden": true }), createLabel] }), _jsxs("button", { type: "button", onClick: onSkip, className: "inline-flex flex-1 items-center justify-center gap-2 rounded-lg border border-border bg-background px-3 py-2 text-[12px] font-semibold text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus:ring-2 focus:ring-primary/40", children: [_jsx(ArrowRight, { className: "size-3.5", "aria-hidden": true }), skipLabel] })] })] }));
13
+ }
14
+ //# sourceMappingURL=picker-empty-guidance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-empty-guidance.js","sourceRoot":"","sources":["../../src/components/picker-empty-guidance.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAgBlC;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,aAAa,EACb,WAAW,EACX,SAAS,GAAG,gBAAgB,EAC5B,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,GACgB;IACzB,MAAM,OAAO,GAAG,IAAI;WACf,yBAAyB,aAAa,qGAAqG,CAAC;IAEjJ,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,aAClD,cAAK,SAAS,EAAC,iIAAiI,YAC7I,OAAO,GACJ,EACN,eAAK,SAAS,EAAC,iCAAiC,aAC9C,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAC,uOAAuO,aAEjP,KAAC,IAAI,IAAC,SAAS,EAAC,UAAU,wBAAe,EACxC,WAAW,IACL,EACT,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAC,4PAA4P,aAEtQ,KAAC,UAAU,IAAC,SAAS,EAAC,UAAU,wBAAe,EAC9C,SAAS,IACH,IACL,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ import { PickerEmptyGuidance } from "./picker-empty-guidance";
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof PickerEmptyGuidance;
6
+ tags: string[];
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ args: {
11
+ onCreate: import("storybook/test").Mock<(...args: any[]) => any>;
12
+ onSkip: import("storybook/test").Mock<(...args: any[]) => any>;
13
+ };
14
+ };
15
+ export default meta;
16
+ type Story = StoryObj<typeof meta>;
17
+ export declare const NoBrandy: Story;
18
+ export declare const NoWine: Story;
19
+ export declare const CustomBody: Story;
20
+ //# sourceMappingURL=picker-empty-guidance.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-empty-guidance.stories.d.ts","sourceRoot":"","sources":["../../src/components/picker-empty-guidance.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,QAAA,MAAM,IAAI;;;;;;;;;;;CASkC,CAAC;AAE7C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,QAAQ,EAAE,KAKtB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,KAKpB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { fn } from "storybook/test";
2
+ import { PickerEmptyGuidance } from "./picker-empty-guidance";
3
+ const meta = {
4
+ title: "Picker/PickerEmptyGuidance",
5
+ component: PickerEmptyGuidance,
6
+ tags: ["autodocs"],
7
+ parameters: { layout: "centered" },
8
+ args: {
9
+ onCreate: fn(),
10
+ onSkip: fn(),
11
+ },
12
+ };
13
+ export default meta;
14
+ export const NoBrandy = {
15
+ args: {
16
+ categoryLabel: "Spirits · Brandy",
17
+ createLabel: "Create a new brandy product",
18
+ },
19
+ };
20
+ export const NoWine = {
21
+ args: {
22
+ categoryLabel: "Wine",
23
+ createLabel: "Create a new wine product",
24
+ },
25
+ };
26
+ export const CustomBody = {
27
+ args: {
28
+ categoryLabel: "Cider · Perry",
29
+ createLabel: "Add a perry",
30
+ body: "No perry in your portfolio yet. Add one now so the opportunity's specifications pre-fill the new product page.",
31
+ },
32
+ };
33
+ //# sourceMappingURL=picker-empty-guidance.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-empty-guidance.stories.js","sourceRoot":"","sources":["../../src/components/picker-empty-guidance.stories.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,4BAA4B;IACnC,SAAS,EAAE,mBAAmB;IAC9B,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;IAClC,IAAI,EAAE;QACJ,QAAQ,EAAE,EAAE,EAAE;QACd,MAAM,EAAE,EAAE,EAAE;KACb;CACyC,CAAC;AAE7C,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,QAAQ,GAAU;IAC7B,IAAI,EAAE;QACJ,aAAa,EAAE,kBAAkB;QACjC,WAAW,EAAE,6BAA6B;KAC3C;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAU;IAC3B,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM;QACrB,WAAW,EAAE,2BAA2B;KACzC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,IAAI,EAAE;QACJ,aAAa,EAAE,eAAe;QAC9B,WAAW,EAAE,aAAa;QAC1B,IAAI,EAAE,gHAAgH;KACvH;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type ReasonPillKind = "ok" | "warn" | "miss";
2
+ export type ReasonPillSignal = "subtype" | "country" | "region" | "capacity" | "price";
3
+ export interface ReasonPillProps {
4
+ kind: ReasonPillKind;
5
+ signal: ReasonPillSignal;
6
+ label: string;
7
+ className?: string;
8
+ }
9
+ /**
10
+ * Tiny pill that communicates why a variant scored the way it did. Used
11
+ * inside the product picker, stacked under each ranked row.
12
+ *
13
+ * `ok` → check icon + brand tint. `warn` → `≈` glyph + amber tint (lucide
14
+ * has no almost-equal icon). `miss` → X icon + struck-through muted tint.
15
+ */
16
+ export declare function ReasonPill({ kind, signal, label, className }: ReasonPillProps): import("react/jsx-runtime").JSX.Element;
17
+ //# sourceMappingURL=reason-pill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reason-pill.d.ts","sourceRoot":"","sources":["../../src/components/reason-pill.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AACpD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,2CAgB7E"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Check, X } from "lucide-react";
3
+ import { cn } from "../lib/utils";
4
+ const kindClasses = {
5
+ ok: "bg-primary/15 text-primary",
6
+ warn: "bg-warning/20 text-warning-foreground",
7
+ // strike-through + muted so "miss" reads as a negative at a glance
8
+ miss: "bg-muted text-muted-foreground line-through",
9
+ };
10
+ /**
11
+ * Tiny pill that communicates why a variant scored the way it did. Used
12
+ * inside the product picker, stacked under each ranked row.
13
+ *
14
+ * `ok` → check icon + brand tint. `warn` → `≈` glyph + amber tint (lucide
15
+ * has no almost-equal icon). `miss` → X icon + struck-through muted tint.
16
+ */
17
+ export function ReasonPill({ kind, signal, label, className }) {
18
+ return (_jsxs("span", { className: cn("inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] font-semibold leading-none", kindClasses[kind], className), title: `${signal}: ${label}`, children: [kind === "ok" && _jsx(Check, { className: "size-2.5", "aria-hidden": true }), kind === "miss" && _jsx(X, { className: "size-2.5", "aria-hidden": true }), kind === "warn" && _jsx("span", { "aria-hidden": true, children: "\u2248" }), _jsx("span", { children: label })] }));
19
+ }
20
+ //# sourceMappingURL=reason-pill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reason-pill.js","sourceRoot":"","sources":["../../src/components/reason-pill.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAYlC,MAAM,WAAW,GAAmC;IAClD,EAAE,EAAE,4BAA4B;IAChC,IAAI,EAAE,uCAAuC;IAC7C,mEAAmE;IACnE,IAAI,EAAE,6CAA6C;CACpD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAmB;IAC5E,OAAO,CACL,gBACE,SAAS,EAAE,EAAE,CACX,kGAAkG,EAClG,WAAW,CAAC,IAAI,CAAC,EACjB,SAAS,CACV,EACD,KAAK,EAAE,GAAG,MAAM,KAAK,KAAK,EAAE,aAE3B,IAAI,KAAK,IAAI,IAAI,KAAC,KAAK,IAAC,SAAS,EAAC,UAAU,wBAAe,EAC3D,IAAI,KAAK,MAAM,IAAI,KAAC,CAAC,IAAC,SAAS,EAAC,UAAU,wBAAe,EACzD,IAAI,KAAK,MAAM,IAAI,yDAA0B,EAC9C,yBAAO,KAAK,GAAQ,IACf,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ import { ReasonPill } from "./reason-pill";
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof ReasonPill;
6
+ tags: string[];
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ };
11
+ export default meta;
12
+ type Story = StoryObj<typeof meta>;
13
+ export declare const OkSubtype: Story;
14
+ export declare const OkCountry: Story;
15
+ export declare const WarnAlias: Story;
16
+ export declare const MissCountry: Story;
17
+ export declare const Row: Story;
18
+ //# sourceMappingURL=reason-pill.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reason-pill.stories.d.ts","sourceRoot":"","sources":["../../src/components/reason-pill.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,QAAA,MAAM,IAAI;;;;;;;CAKyB,CAAC;AAEpC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,SAAS,EAAE,KAAoE,CAAC;AAC7F,eAAO,MAAM,SAAS,EAAE,KAAmE,CAAC;AAC5F,eAAO,MAAM,SAAS,EAAE,KAA2E,CAAC;AACpG,eAAO,MAAM,WAAW,EAAE,KAAqE,CAAC;AAEhG,eAAO,MAAM,GAAG,EAAE,KAYjB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ReasonPill } from "./reason-pill";
3
+ const meta = {
4
+ title: "Picker/ReasonPill",
5
+ component: ReasonPill,
6
+ tags: ["autodocs"],
7
+ parameters: { layout: "centered" },
8
+ };
9
+ export default meta;
10
+ export const OkSubtype = { args: { kind: "ok", signal: "subtype", label: "Brandy" } };
11
+ export const OkCountry = { args: { kind: "ok", signal: "country", label: "Spain" } };
12
+ export const WarnAlias = { args: { kind: "warn", signal: "subtype", label: "Aguardiente" } };
13
+ export const MissCountry = { args: { kind: "miss", signal: "country", label: "Spain" } };
14
+ export const Row = {
15
+ args: { kind: "ok", signal: "subtype", label: "Brandy" },
16
+ render: () => (_jsxs("div", { className: "flex flex-wrap gap-1.5 p-4", children: [_jsx(ReasonPill, { kind: "ok", signal: "subtype", label: "Brandy" }), _jsx(ReasonPill, { kind: "ok", signal: "country", label: "Spain" }), _jsx(ReasonPill, { kind: "warn", signal: "subtype", label: "Aguardiente" }), _jsx(ReasonPill, { kind: "ok", signal: "region", label: "Rioja" }), _jsx(ReasonPill, { kind: "miss", signal: "capacity", label: "low capacity" }), _jsx(ReasonPill, { kind: "miss", signal: "price", label: "below price band" })] })),
17
+ };
18
+ //# sourceMappingURL=reason-pill.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reason-pill.stories.js","sourceRoot":"","sources":["../../src/components/reason-pill.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,mBAAmB;IAC1B,SAAS,EAAE,UAAU;IACrB,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;CACD,CAAC;AAEpC,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,SAAS,GAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC;AAC7F,MAAM,CAAC,MAAM,SAAS,GAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;AAC5F,MAAM,CAAC,MAAM,SAAS,GAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC;AACpG,MAAM,CAAC,MAAM,WAAW,GAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;AAEhG,MAAM,CAAC,MAAM,GAAG,GAAU;IACxB,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE;IACxD,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,eAAK,SAAS,EAAC,4BAA4B,aACzC,KAAC,UAAU,IAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,KAAK,EAAC,QAAQ,GAAG,EACxD,KAAC,UAAU,IAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,KAAK,EAAC,OAAO,GAAG,EACvD,KAAC,UAAU,IAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,SAAS,EAAC,KAAK,EAAC,aAAa,GAAG,EAC/D,KAAC,UAAU,IAAC,IAAI,EAAC,IAAI,EAAC,MAAM,EAAC,QAAQ,EAAC,KAAK,EAAC,OAAO,GAAG,EACtD,KAAC,UAAU,IAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,UAAU,EAAC,KAAK,EAAC,cAAc,GAAG,EACjE,KAAC,UAAU,IAAC,IAAI,EAAC,MAAM,EAAC,MAAM,EAAC,OAAO,EAAC,KAAK,EAAC,kBAAkB,GAAG,IAC9D,CACP;CACF,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type ScoreBand = "top" | "good" | "weak";
2
+ export interface ScoreChipProps {
3
+ /** 0–100 score. Rounded for display. */
4
+ score: number;
5
+ /** Explicit band override. When omitted, derived from the score. */
6
+ band?: ScoreBand;
7
+ className?: string;
8
+ }
9
+ /**
10
+ * Compact 0–100 match-score pill, band-colored by quality.
11
+ *
12
+ * Reused by the producer journey picker and the importer AI-matches view
13
+ * — anywhere we need to surface a numeric "fit" score next to a row.
14
+ */
15
+ export declare function ScoreChip({ score, band, className }: ScoreChipProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=score-chip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score-chip.d.ts","sourceRoot":"","sources":["../../src/components/score-chip.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,cAAc,2CAenE"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils";
3
+ function deriveBand(score) {
4
+ if (score >= 80)
5
+ return "top";
6
+ if (score >= 50)
7
+ return "good";
8
+ return "weak";
9
+ }
10
+ const bandClasses = {
11
+ top: "bg-primary text-primary-foreground",
12
+ good: "bg-warning text-warning-foreground",
13
+ weak: "bg-muted text-muted-foreground",
14
+ };
15
+ /**
16
+ * Compact 0–100 match-score pill, band-colored by quality.
17
+ *
18
+ * Reused by the producer journey picker and the importer AI-matches view
19
+ * — anywhere we need to surface a numeric "fit" score next to a row.
20
+ */
21
+ export function ScoreChip({ score, band, className }) {
22
+ const b = band ?? deriveBand(score);
23
+ const display = Math.max(0, Math.min(100, Math.round(score)));
24
+ return (_jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center rounded-full px-2 py-0.5 text-[10px] font-bold leading-none tabular-nums", bandClasses[b], className), "aria-label": `Match score ${display} of 100`, children: display }));
25
+ }
26
+ //# sourceMappingURL=score-chip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score-chip.js","sourceRoot":"","sources":["../../src/components/score-chip.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAYlC,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,WAAW,GAA8B;IAC7C,GAAG,EAAE,oCAAoC;IACzC,IAAI,EAAE,oCAAoC;IAC1C,IAAI,EAAE,gCAAgC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAkB;IAClE,MAAM,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9D,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,2HAA2H,EAC3H,WAAW,CAAC,CAAC,CAAC,EACd,SAAS,CACV,gBACW,eAAe,OAAO,SAAS,YAE1C,OAAO,GACH,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { StoryObj } from "@storybook/react-vite";
2
+ import { ScoreChip } from "./score-chip";
3
+ declare const meta: {
4
+ title: string;
5
+ component: typeof ScoreChip;
6
+ tags: string[];
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ };
11
+ export default meta;
12
+ type Story = StoryObj<typeof meta>;
13
+ export declare const Top: Story;
14
+ export declare const Good: Story;
15
+ export declare const Weak: Story;
16
+ export declare const ExplicitBand: Story;
17
+ export declare const Range: Story;
18
+ //# sourceMappingURL=score-chip.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score-chip.stories.d.ts","sourceRoot":"","sources":["../../src/components/score-chip.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,QAAA,MAAM,IAAI;;;;;;;CAKwB,CAAC;AAEnC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,GAAG,EAAE,KAA+B,CAAC;AAClD,eAAO,MAAM,IAAI,EAAE,KAA+B,CAAC;AACnD,eAAO,MAAM,IAAI,EAAE,KAA+B,CAAC;AACnD,eAAO,MAAM,YAAY,EAAE,KAA4C,CAAC;AAExE,eAAO,MAAM,KAAK,EAAE,KAYnB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ScoreChip } from "./score-chip";
3
+ const meta = {
4
+ title: "Picker/ScoreChip",
5
+ component: ScoreChip,
6
+ tags: ["autodocs"],
7
+ parameters: { layout: "centered" },
8
+ };
9
+ export default meta;
10
+ export const Top = { args: { score: 92 } };
11
+ export const Good = { args: { score: 68 } };
12
+ export const Weak = { args: { score: 22 } };
13
+ export const ExplicitBand = { args: { score: 50, band: "top" } };
14
+ export const Range = {
15
+ args: { score: 0 },
16
+ render: () => (_jsx("div", { className: "flex items-center gap-2 p-4", children: [100, 92, 80, 79, 60, 50, 49, 22, 0].map((s) => (_jsxs("div", { className: "flex flex-col items-center gap-1", children: [_jsx(ScoreChip, { score: s }), _jsx("span", { className: "text-[10px] text-muted-foreground", children: s })] }, s))) })),
17
+ };
18
+ //# sourceMappingURL=score-chip.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score-chip.stories.js","sourceRoot":"","sources":["../../src/components/score-chip.stories.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,kBAAkB;IACzB,SAAS,EAAE,SAAS;IACpB,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;CACF,CAAC;AAEnC,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,GAAG,GAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;AAClD,MAAM,CAAC,MAAM,IAAI,GAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;AACnD,MAAM,CAAC,MAAM,IAAI,GAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC;AACnD,MAAM,CAAC,MAAM,YAAY,GAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;AAExE,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;IAClB,MAAM,EAAE,GAAG,EAAE,CAAC,CACZ,cAAK,SAAS,EAAC,6BAA6B,YACzC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAC/C,eAAa,SAAS,EAAC,kCAAkC,aACvD,KAAC,SAAS,IAAC,KAAK,EAAE,CAAC,GAAI,EACvB,eAAM,SAAS,EAAC,mCAAmC,YAAE,CAAC,GAAQ,KAFtD,CAAC,CAGL,CACP,CAAC,GACE,CACP;CACF,CAAC"}
@@ -1,49 +1,55 @@
1
- import * as React from "react";
2
- export interface VariantPickerItem {
1
+ import { type OpportunityBriefChip } from "./opportunity-brief";
2
+ import { type ReasonPillKind, type ReasonPillSignal } from "./reason-pill";
3
+ import { type ScoreBand } from "./score-chip";
4
+ /** A pre-ranked variant row. Host builds this from server response. */
5
+ export interface ScoredVariantDisplay {
3
6
  id: string;
4
- name: string;
5
- vintage?: string | number | null;
7
+ beverageId: string;
8
+ beverageName: string;
9
+ vintage?: number | string | null;
10
+ packaging?: string | null;
11
+ containerVolume?: string | number | null;
6
12
  category?: string | null;
7
13
  subtype?: string | null;
8
- beverageName?: string | null;
14
+ countryOfOrigin?: string | null;
15
+ region?: string | null;
16
+ score: number;
17
+ band: ScoreBand;
18
+ reasons: {
19
+ kind: ReasonPillKind;
20
+ signal: ReasonPillSignal;
21
+ label: string;
22
+ }[];
9
23
  }
10
- /** Opportunity context shown as a banner inside the picker. */
11
24
  export interface VariantPickerOpportunityContext {
12
25
  name: string;
13
- buyer?: string;
14
- category?: string;
15
- deadline?: string;
16
- volume?: string;
26
+ buyerName?: string | null;
27
+ chips: OpportunityBriefChip[];
28
+ }
29
+ export interface VariantPickerEmptyGuidance {
30
+ categoryLabel: string;
31
+ createLabel: string;
17
32
  }
18
33
  export interface VariantPickerDialogProps {
19
- /** Whether the dialog is open. */
20
34
  open: boolean;
21
- /** Called when the dialog should close. */
22
35
  onClose: () => void;
23
- /** Called when the user confirms a variant selection. */
24
- onSelect: (variant: VariantPickerItem) => void;
25
- /** Called when the user clicks "Skip — empty draft". Falls back to onClose if not provided. */
36
+ onSelect: (variantId: string) => void;
37
+ /** When provided + goodFits empty, renders PickerEmptyGuidance with this callback on the primary CTA. */
38
+ onCreateNew?: () => void;
39
+ /** Skip to empty draft. Defaults to onClose when omitted. */
26
40
  onSkip?: () => void;
27
- /** List of variants to choose from. */
28
- variants: VariantPickerItem[];
29
- /** Show a loading spinner instead of the list. */
30
- isLoading?: boolean;
31
- /** Current search input value (controlled). */
41
+ goodFits: ScoredVariantDisplay[];
42
+ crossCategory: ScoredVariantDisplay[];
43
+ opportunityContext: VariantPickerOpportunityContext;
32
44
  searchValue: string;
33
- /** Called when the search input changes. */
34
45
  onSearchChange: (value: string) => void;
35
- /** Dialog heading. @default "Select a product" */
46
+ isLoading?: boolean;
47
+ /** When provided AND goodFits.length === 0 AND onCreateNew is set, renders the empty-state CTAs. */
48
+ emptyGuidance?: VariantPickerEmptyGuidance;
49
+ /** Pre-select a variant on mount (used for the add-product round-trip). */
50
+ initialSelectedId?: string | null;
36
51
  title?: string;
37
- /** Descriptive text below the heading. */
38
52
  description?: string;
39
- /** Optional custom renderer for each variant row. */
40
- renderVariant?: (variant: VariantPickerItem, isSelected: boolean) => React.ReactNode;
41
- /** Pre-filter: show matching variants first (same category). */
42
- filterCategory?: string | null;
43
- /** Pre-filter: show matching variants first (same subtype). */
44
- filterSubtype?: string | null;
45
- /** Opportunity context banner shown at the top of the dialog. */
46
- opportunityContext?: VariantPickerOpportunityContext | null;
47
53
  }
48
- export declare function VariantPickerDialog({ open, onClose, onSelect, onSkip, variants, isLoading, searchValue, onSearchChange, title, description, renderVariant, filterCategory, filterSubtype, opportunityContext, }: VariantPickerDialogProps): import("react/jsx-runtime").JSX.Element | null;
54
+ export declare function VariantPickerDialog(props: VariantPickerDialogProps): import("react/jsx-runtime").JSX.Element | null;
49
55
  //# sourceMappingURL=variant-picker-dialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"variant-picker-dialog.d.ts","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,+DAA+D;AAC/D,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,2CAA2C;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,yDAAyD;IACzD,QAAQ,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,+FAA+F;IAC/F,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,uCAAuC;IACvC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC;IACrF,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,+BAA+B,GAAG,IAAI,CAAC;CAC7D;AAwDD,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,EACjB,WAAW,EACX,cAAc,EACd,KAA0B,EAC1B,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,kBAAkB,GACnB,EAAE,wBAAwB,kDAsB1B"}
1
+ {"version":3,"file":"variant-picker-dialog.d.ts","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAElF,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAMzD,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9E;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,oBAAoB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,yGAAyG;IACzG,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,kBAAkB,EAAE,+BAA+B,CAAC;IAEpD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,oGAAoG;IACpG,aAAa,CAAC,EAAE,0BAA0B,CAAC;IAE3C,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,kDAKlE"}