@cellarnode/ui 0.13.0 → 0.15.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/bottle-extract-dialog.d.ts +25 -0
- package/dist/components/bottle-extract-dialog.d.ts.map +1 -0
- package/dist/components/bottle-extract-dialog.js +87 -0
- package/dist/components/bottle-extract-dialog.js.map +1 -0
- package/dist/components/bottle-extract-dialog.stories.d.ts +17 -0
- package/dist/components/bottle-extract-dialog.stories.d.ts.map +1 -0
- package/dist/components/bottle-extract-dialog.stories.js +54 -0
- package/dist/components/bottle-extract-dialog.stories.js.map +1 -0
- package/dist/components/bottle-extraction-inline-progress.d.ts +14 -0
- package/dist/components/bottle-extraction-inline-progress.d.ts.map +1 -0
- package/dist/components/bottle-extraction-inline-progress.js +28 -0
- package/dist/components/bottle-extraction-inline-progress.js.map +1 -0
- package/dist/components/bottle-extraction-inline-progress.stories.d.ts +17 -0
- package/dist/components/bottle-extraction-inline-progress.stories.d.ts.map +1 -0
- package/dist/components/bottle-extraction-inline-progress.stories.js +35 -0
- package/dist/components/bottle-extraction-inline-progress.stories.js.map +1 -0
- package/dist/components/extraction-phase-stepper.d.ts +19 -0
- package/dist/components/extraction-phase-stepper.d.ts.map +1 -0
- package/dist/components/extraction-phase-stepper.js +26 -0
- package/dist/components/extraction-phase-stepper.js.map +1 -0
- package/dist/components/extraction-phase-stepper.stories.d.ts +18 -0
- package/dist/components/extraction-phase-stepper.stories.d.ts.map +1 -0
- package/dist/components/extraction-phase-stepper.stories.js +31 -0
- package/dist/components/extraction-phase-stepper.stories.js.map +1 -0
- package/dist/components/flagged-field-editor.d.ts +23 -0
- package/dist/components/flagged-field-editor.d.ts.map +1 -0
- package/dist/components/flagged-field-editor.js +16 -0
- package/dist/components/flagged-field-editor.js.map +1 -0
- package/dist/components/flagged-field-editor.stories.d.ts +27 -0
- package/dist/components/flagged-field-editor.stories.d.ts.map +1 -0
- package/dist/components/flagged-field-editor.stories.js +60 -0
- package/dist/components/flagged-field-editor.stories.js.map +1 -0
- package/dist/components/picker-empty-guidance.js +1 -1
- package/dist/components/picker-empty-guidance.js.map +1 -1
- package/dist/components/preflight-verdict-sheet.d.ts +20 -0
- package/dist/components/preflight-verdict-sheet.d.ts.map +1 -0
- package/dist/components/preflight-verdict-sheet.js +23 -0
- package/dist/components/preflight-verdict-sheet.js.map +1 -0
- package/dist/components/preflight-verdict-sheet.stories.d.ts +29 -0
- package/dist/components/preflight-verdict-sheet.stories.d.ts.map +1 -0
- package/dist/components/preflight-verdict-sheet.stories.js +48 -0
- package/dist/components/preflight-verdict-sheet.stories.js.map +1 -0
- package/dist/components/reason-pill.d.ts.map +1 -1
- package/dist/components/reason-pill.js +5 -2
- package/dist/components/reason-pill.js.map +1 -1
- package/dist/components/score-chip.js +1 -1
- package/dist/components/score-chip.js.map +1 -1
- package/dist/components/variant-picker-dialog.d.ts +30 -2
- package/dist/components/variant-picker-dialog.d.ts.map +1 -1
- package/dist/components/variant-picker-dialog.js +31 -18
- package/dist/components/variant-picker-dialog.js.map +1 -1
- package/dist/components/variant-picker-dialog.test.d.ts +2 -0
- package/dist/components/variant-picker-dialog.test.d.ts.map +1 -0
- package/dist/components/variant-picker-dialog.test.js +140 -0
- package/dist/components/variant-picker-dialog.test.js.map +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,6 +9,6 @@ import { cn } from "../lib/utils";
|
|
|
9
9
|
export function PickerEmptyGuidance({ categoryLabel, createLabel, skipLabel = "Draft manually", body, onCreate, onSkip, className, }) {
|
|
10
10
|
const message = body
|
|
11
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]
|
|
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]/5 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-4 py-2.5 text-sm 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-4 py-2.5 text-sm 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
13
|
}
|
|
14
14
|
//# sourceMappingURL=picker-empty-guidance.js.map
|
|
@@ -1 +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,
|
|
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,mHAAmH,YAC/H,OAAO,GACJ,EACN,eAAK,SAAS,EAAC,iCAAiC,aAC9C,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAC,qOAAqO,aAE/O,KAAC,IAAI,IAAC,SAAS,EAAC,UAAU,wBAAe,EACxC,WAAW,IACL,EACT,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAC,0PAA0P,aAEpQ,KAAC,UAAU,IAAC,SAAS,EAAC,UAAU,wBAAe,EAC9C,SAAS,IACH,IACL,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type PreflightVerdictColor = "green" | "amber" | "red";
|
|
2
|
+
export interface PreflightVerdictSheetProps {
|
|
3
|
+
verdict: PreflightVerdictColor;
|
|
4
|
+
reason: string;
|
|
5
|
+
fileKind?: string;
|
|
6
|
+
suggestedPages?: string | null;
|
|
7
|
+
estimatedProductCount?: number | null;
|
|
8
|
+
onProceed: () => void;
|
|
9
|
+
onProceedWithPages?: (pages: string) => void;
|
|
10
|
+
onCancel: () => void;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Preflight verdict panel shown after the extraction preflight LLM pass.
|
|
15
|
+
* Renders a semantic alert tinted by verdict color with contextual actions:
|
|
16
|
+
* - green → single "Start extraction" CTA
|
|
17
|
+
* - amber/red → "Extract pages X-Y" (if suggested), "Process entire file", "Cancel"
|
|
18
|
+
*/
|
|
19
|
+
export declare function PreflightVerdictSheet(props: PreflightVerdictSheetProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=preflight-verdict-sheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-verdict-sheet.d.ts","sourceRoot":"","sources":["../../src/components/preflight-verdict-sheet.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAE9D,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,2CA+EtE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils";
|
|
3
|
+
/**
|
|
4
|
+
* Preflight verdict panel shown after the extraction preflight LLM pass.
|
|
5
|
+
* Renders a semantic alert tinted by verdict color with contextual actions:
|
|
6
|
+
* - green → single "Start extraction" CTA
|
|
7
|
+
* - amber/red → "Extract pages X-Y" (if suggested), "Process entire file", "Cancel"
|
|
8
|
+
*/
|
|
9
|
+
export function PreflightVerdictSheet(props) {
|
|
10
|
+
const { verdict, reason, suggestedPages, estimatedProductCount, onProceed, onProceedWithPages, onCancel, className, } = props;
|
|
11
|
+
const tone = verdict === "green"
|
|
12
|
+
? "border-emerald-300 bg-emerald-50 text-emerald-950 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-100"
|
|
13
|
+
: verdict === "amber"
|
|
14
|
+
? "border-amber-300 bg-amber-50 text-amber-950 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-100"
|
|
15
|
+
: "border-red-300 bg-red-50 text-red-950 dark:border-red-800 dark:bg-red-950/40 dark:text-red-100";
|
|
16
|
+
const title = verdict === "green"
|
|
17
|
+
? "Ready to extract"
|
|
18
|
+
: verdict === "amber"
|
|
19
|
+
? "This file looks partially like a product catalog"
|
|
20
|
+
: "This file doesn't look like a product catalog";
|
|
21
|
+
return (_jsxs("section", { role: "alert", "aria-live": "polite", className: cn("rounded-xl border p-5", tone, className), children: [_jsx("h3", { className: "text-base font-semibold", children: title }), _jsx("p", { className: "mt-2 text-sm", children: reason }), suggestedPages && estimatedProductCount != null && (_jsxs("p", { className: "mt-2 text-xs opacity-75", children: ["Pages to process: ", _jsx("b", { children: suggestedPages }), " \u00B7 estimated", " ", estimatedProductCount, " products."] })), _jsx("div", { className: "mt-4 flex flex-wrap gap-2", children: verdict === "green" ? (_jsx("button", { type: "button", onClick: onProceed, className: "rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white hover:bg-indigo-700 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-indigo-400", children: "Start extraction" })) : (_jsxs(_Fragment, { children: [suggestedPages && onProceedWithPages && (_jsxs("button", { type: "button", onClick: () => onProceedWithPages(suggestedPages), className: "rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white hover:bg-indigo-700 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-indigo-400", children: ["Extract pages ", suggestedPages] })), _jsx("button", { type: "button", onClick: onProceed, className: "rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-semibold text-gray-800 hover:bg-gray-50 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-gray-400 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:hover:bg-gray-800", children: "Process entire file" }), _jsx("button", { type: "button", onClick: onCancel, className: "rounded-lg bg-transparent px-4 py-2 text-sm font-semibold text-gray-600 hover:bg-gray-100 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-gray-400 dark:text-gray-300 dark:hover:bg-gray-800", children: "Cancel" })] })) })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=preflight-verdict-sheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-verdict-sheet.js","sourceRoot":"","sources":["../../src/components/preflight-verdict-sheet.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAgBlC;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiC;IACrE,MAAM,EACJ,OAAO,EACP,MAAM,EACN,cAAc,EACd,qBAAqB,EACrB,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,SAAS,GACV,GAAG,KAAK,CAAC;IAEV,MAAM,IAAI,GACR,OAAO,KAAK,OAAO;QACjB,CAAC,CAAC,wHAAwH;QAC1H,CAAC,CAAC,OAAO,KAAK,OAAO;YACnB,CAAC,CAAC,4GAA4G;YAC9G,CAAC,CAAC,gGAAgG,CAAC;IAEzG,MAAM,KAAK,GACT,OAAO,KAAK,OAAO;QACjB,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,OAAO,KAAK,OAAO;YACnB,CAAC,CAAC,kDAAkD;YACpD,CAAC,CAAC,+CAA+C,CAAC;IAExD,OAAO,CACL,mBACE,IAAI,EAAC,OAAO,eACF,QAAQ,EAClB,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,IAAI,EAAE,SAAS,CAAC,aAEvD,aAAI,SAAS,EAAC,yBAAyB,YAAE,KAAK,GAAM,EACpD,YAAG,SAAS,EAAC,cAAc,YAAE,MAAM,GAAK,EACvC,cAAc,IAAI,qBAAqB,IAAI,IAAI,IAAI,CAClD,aAAG,SAAS,EAAC,yBAAyB,mCAClB,sBAAI,cAAc,GAAK,uBAAa,GAAG,EACxD,qBAAqB,kBACpB,CACL,EACD,cAAK,SAAS,EAAC,2BAA2B,YACvC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CACrB,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,SAAS,EAClB,SAAS,EAAC,uKAAuK,iCAG1K,CACV,CAAC,CAAC,CAAC,CACF,8BACG,cAAc,IAAI,kBAAkB,IAAI,CACvC,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,cAAc,CAAC,EACjD,SAAS,EAAC,uKAAuK,+BAElK,cAAc,IACtB,CACV,EACD,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,SAAS,EAClB,SAAS,EAAC,uQAAuQ,oCAG1Q,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAC,iNAAiN,uBAGpN,IACR,CACJ,GACG,IACE,CACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { PreflightVerdictSheet } from "./preflight-verdict-sheet";
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof PreflightVerdictSheet;
|
|
6
|
+
tags: string[];
|
|
7
|
+
parameters: {
|
|
8
|
+
a11y: {
|
|
9
|
+
test: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
argTypes: {
|
|
13
|
+
onProceed: {
|
|
14
|
+
action: string;
|
|
15
|
+
};
|
|
16
|
+
onProceedWithPages: {
|
|
17
|
+
action: string;
|
|
18
|
+
};
|
|
19
|
+
onCancel: {
|
|
20
|
+
action: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export default meta;
|
|
25
|
+
type Story = StoryObj<typeof meta>;
|
|
26
|
+
export declare const Green: Story;
|
|
27
|
+
export declare const Amber: Story;
|
|
28
|
+
export declare const Red: Story;
|
|
29
|
+
//# sourceMappingURL=preflight-verdict-sheet.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-verdict-sheet.stories.d.ts","sourceRoot":"","sources":["../../src/components/preflight-verdict-sheet.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;CAUoC,CAAC;AAE/C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,KAAK,EAAE,KASnB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAWnB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,KAUjB,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { PreflightVerdictSheet } from "./preflight-verdict-sheet";
|
|
2
|
+
const noop = () => { };
|
|
3
|
+
const meta = {
|
|
4
|
+
title: "Extraction/PreflightVerdictSheet",
|
|
5
|
+
component: PreflightVerdictSheet,
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
parameters: { a11y: { test: "error" } },
|
|
8
|
+
argTypes: {
|
|
9
|
+
onProceed: { action: "proceed" },
|
|
10
|
+
onProceedWithPages: { action: "proceedWithPages" },
|
|
11
|
+
onCancel: { action: "cancel" },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
export const Green = {
|
|
16
|
+
args: {
|
|
17
|
+
verdict: "green",
|
|
18
|
+
reason: "This file looks like a product catalog.",
|
|
19
|
+
fileKind: "product_catalog",
|
|
20
|
+
estimatedProductCount: 12,
|
|
21
|
+
onProceed: noop,
|
|
22
|
+
onCancel: noop,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
export const Amber = {
|
|
26
|
+
args: {
|
|
27
|
+
verdict: "amber",
|
|
28
|
+
reason: "Looks partially like a product catalog.",
|
|
29
|
+
fileKind: "mixed",
|
|
30
|
+
suggestedPages: "7-12",
|
|
31
|
+
estimatedProductCount: 8,
|
|
32
|
+
onProceed: noop,
|
|
33
|
+
onProceedWithPages: noop,
|
|
34
|
+
onCancel: noop,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export const Red = {
|
|
38
|
+
args: {
|
|
39
|
+
verdict: "red",
|
|
40
|
+
reason: "This doesn't look like a product catalog.",
|
|
41
|
+
fileKind: "winery_bio",
|
|
42
|
+
estimatedProductCount: null,
|
|
43
|
+
suggestedPages: null,
|
|
44
|
+
onProceed: noop,
|
|
45
|
+
onCancel: noop,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=preflight-verdict-sheet.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-verdict-sheet.stories.js","sourceRoot":"","sources":["../../src/components/preflight-verdict-sheet.stories.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtB,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,kCAAkC;IACzC,SAAS,EAAE,qBAAqB;IAChC,IAAI,EAAE,CAAC,UAAU,CAAC;IAClB,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IACvC,QAAQ,EAAE;QACR,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;QAChC,kBAAkB,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;QAClD,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;KAC/B;CAC2C,CAAC;AAE/C,eAAe,IAAI,CAAC;AAGpB,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,IAAI,EAAE;QACJ,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,yCAAyC;QACjD,QAAQ,EAAE,iBAAiB;QAC3B,qBAAqB,EAAE,EAAE;QACzB,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,IAAI,EAAE;QACJ,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,yCAAyC;QACjD,QAAQ,EAAE,OAAO;QACjB,cAAc,EAAE,MAAM;QACtB,qBAAqB,EAAE,CAAC;QACxB,SAAS,EAAE,IAAI;QACf,kBAAkB,EAAE,IAAI;QACxB,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAU;IACxB,IAAI,EAAE;QACJ,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,2CAA2C;QACnD,QAAQ,EAAE,YAAY;QACtB,qBAAqB,EAAE,IAAI;QAC3B,cAAc,EAAE,IAAI;QACpB,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,IAAI;KACf;CACF,CAAC"}
|
|
@@ -1 +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,
|
|
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,2CAqB7E"}
|
|
@@ -3,7 +3,7 @@ import { Check, X } from "lucide-react";
|
|
|
3
3
|
import { cn } from "../lib/utils";
|
|
4
4
|
const kindClasses = {
|
|
5
5
|
ok: "bg-primary/15 text-primary",
|
|
6
|
-
warn: "bg-
|
|
6
|
+
warn: "bg-amber-500/20 text-amber-900 dark:bg-amber-400/15 dark:text-amber-300",
|
|
7
7
|
// strike-through + muted so "miss" reads as a negative at a glance
|
|
8
8
|
miss: "bg-muted text-muted-foreground line-through",
|
|
9
9
|
};
|
|
@@ -15,6 +15,9 @@ const kindClasses = {
|
|
|
15
15
|
* has no almost-equal icon). `miss` → X icon + struck-through muted tint.
|
|
16
16
|
*/
|
|
17
17
|
export function ReasonPill({ kind, signal, label, className }) {
|
|
18
|
-
|
|
18
|
+
const ariaLabel = kind === "miss" ? `${signal} mismatch: ${label}` :
|
|
19
|
+
kind === "warn" ? `${signal} partial match: ${label}` :
|
|
20
|
+
`${signal} match: ${label}`;
|
|
21
|
+
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), "aria-label": ariaLabel, 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", { "aria-hidden": true, children: label })] }));
|
|
19
22
|
}
|
|
20
23
|
//# sourceMappingURL=reason-pill.js.map
|
|
@@ -1 +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,
|
|
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,yEAAyE;IAC/E,mEAAmE;IACnE,IAAI,EAAE,6CAA6C;CACpD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAmB;IAC5E,MAAM,SAAS,GACb,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,cAAc,KAAK,EAAE,CAAC,CAAC;QAClD,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,mBAAmB,KAAK,EAAE,CAAC,CAAC;YACvD,GAAG,MAAM,WAAW,KAAK,EAAE,CAAC;IAE9B,OAAO,CACL,gBACE,SAAS,EAAE,EAAE,CACX,kGAAkG,EAClG,WAAW,CAAC,IAAI,CAAC,EACjB,SAAS,CACV,gBACW,SAAS,aAEpB,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,8CAAmB,KAAK,GAAQ,IAC3B,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -9,7 +9,7 @@ function deriveBand(score) {
|
|
|
9
9
|
}
|
|
10
10
|
const bandClasses = {
|
|
11
11
|
top: "bg-primary text-primary-foreground",
|
|
12
|
-
good: "bg-
|
|
12
|
+
good: "bg-amber-500/20 text-amber-900 dark:bg-amber-400/20 dark:text-amber-200",
|
|
13
13
|
weak: "bg-muted text-muted-foreground",
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
@@ -1 +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,
|
|
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,yEAAyE;IAC/E,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"}
|
|
@@ -6,7 +6,7 @@ export interface ScoredVariantDisplay {
|
|
|
6
6
|
id: string;
|
|
7
7
|
beverageId: string;
|
|
8
8
|
beverageName: string;
|
|
9
|
-
vintage?: number |
|
|
9
|
+
vintage?: number | null;
|
|
10
10
|
packaging?: string | null;
|
|
11
11
|
containerVolume?: string | number | null;
|
|
12
12
|
category?: string | null;
|
|
@@ -30,6 +30,25 @@ export interface VariantPickerEmptyGuidance {
|
|
|
30
30
|
categoryLabel: string;
|
|
31
31
|
createLabel: string;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Copy/i18n overrides for the VariantPickerDialog. Pass a partial object via
|
|
35
|
+
* the `copy` prop; missing keys fall back to defaults. Host apps typically
|
|
36
|
+
* feed translated strings from their i18n layer.
|
|
37
|
+
*/
|
|
38
|
+
export interface VariantPickerDialogCopy {
|
|
39
|
+
title: string;
|
|
40
|
+
description: string;
|
|
41
|
+
searchPlaceholder: string;
|
|
42
|
+
goodFitsLabel: (count: number) => string;
|
|
43
|
+
otherProductsLabel: string;
|
|
44
|
+
crossCategoryLabel: string;
|
|
45
|
+
loadingLabel: string;
|
|
46
|
+
selectButton: string;
|
|
47
|
+
skipButton: string;
|
|
48
|
+
cancelButton: string;
|
|
49
|
+
closestFitTag: string;
|
|
50
|
+
differentCategoryTag: string;
|
|
51
|
+
}
|
|
33
52
|
export interface VariantPickerDialogProps {
|
|
34
53
|
open: boolean;
|
|
35
54
|
onClose: () => void;
|
|
@@ -48,8 +67,17 @@ export interface VariantPickerDialogProps {
|
|
|
48
67
|
emptyGuidance?: VariantPickerEmptyGuidance;
|
|
49
68
|
/** Pre-select a variant on mount (used for the add-product round-trip). */
|
|
50
69
|
initialSelectedId?: string | null;
|
|
70
|
+
/**
|
|
71
|
+
* @deprecated Prefer `copy.title`. If provided, takes priority over `copy.title` for
|
|
72
|
+
* backward compatibility.
|
|
73
|
+
*/
|
|
51
74
|
title?: string;
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated Prefer `copy.description`. If provided, takes priority over `copy.description`.
|
|
77
|
+
*/
|
|
52
78
|
description?: string;
|
|
79
|
+
/** Copy overrides for i18n. Missing keys fall back to English defaults. */
|
|
80
|
+
copy?: Partial<VariantPickerDialogCopy>;
|
|
53
81
|
}
|
|
54
|
-
export declare function VariantPickerDialog(props: VariantPickerDialogProps): import("react/jsx-runtime").JSX.Element
|
|
82
|
+
export declare function VariantPickerDialog(props: VariantPickerDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
55
83
|
//# 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":"
|
|
1
|
+
{"version":3,"file":"variant-picker-dialog.d.ts","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import * as Dialog from "@radix-ui/react-dialog";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import { ChevronRight, Search } from "lucide-react";
|
|
4
5
|
import { cn } from "../lib/utils";
|
|
@@ -6,17 +7,37 @@ import { OpportunityBrief } from "./opportunity-brief";
|
|
|
6
7
|
import { PickerEmptyGuidance } from "./picker-empty-guidance";
|
|
7
8
|
import { ReasonPill } from "./reason-pill";
|
|
8
9
|
import { ScoreChip } from "./score-chip";
|
|
10
|
+
const DEFAULT_COPY = {
|
|
11
|
+
title: "Pick a product for this tender",
|
|
12
|
+
description: "Ranked by how well each fits the opportunity",
|
|
13
|
+
searchPlaceholder: "Search your portfolio...",
|
|
14
|
+
goodFitsLabel: (n) => `Good fits · ${n}`,
|
|
15
|
+
otherProductsLabel: "Other portfolio products",
|
|
16
|
+
crossCategoryLabel: "Cross-category",
|
|
17
|
+
loadingLabel: "Ranking your portfolio…",
|
|
18
|
+
selectButton: "Select & pre-fill",
|
|
19
|
+
skipButton: "Skip — empty draft",
|
|
20
|
+
cancelButton: "Cancel",
|
|
21
|
+
closestFitTag: "· closest fit",
|
|
22
|
+
differentCategoryTag: "· different category",
|
|
23
|
+
};
|
|
9
24
|
// ---------------------------------------------------------------------------
|
|
10
25
|
// Component
|
|
11
26
|
// ---------------------------------------------------------------------------
|
|
12
27
|
export function VariantPickerDialog(props) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
// Radix manages mount/unmount via `open`; we still gate the inner content so
|
|
29
|
+
// its local state resets on each open.
|
|
30
|
+
return (_jsx(Dialog.Root, { open: props.open, onOpenChange: (next) => {
|
|
31
|
+
if (!next)
|
|
32
|
+
props.onClose();
|
|
33
|
+
}, children: props.open ? _jsx(VariantPickerContent, { ...props }) : null }));
|
|
18
34
|
}
|
|
19
|
-
function VariantPickerContent({ onClose, onSelect, onCreateNew, onSkip, goodFits, crossCategory, opportunityContext, searchValue, onSearchChange, isLoading, emptyGuidance, initialSelectedId, title
|
|
35
|
+
function VariantPickerContent({ onClose, onSelect, onCreateNew, onSkip, goodFits, crossCategory, opportunityContext, searchValue, onSearchChange, isLoading, emptyGuidance, initialSelectedId, title, description, copy, }) {
|
|
36
|
+
// Merge copy overrides with defaults. Legacy `title`/`description` props
|
|
37
|
+
// take priority for backward compatibility with existing call sites.
|
|
38
|
+
const c = { ...DEFAULT_COPY, ...copy };
|
|
39
|
+
const resolvedTitle = title ?? c.title;
|
|
40
|
+
const resolvedDescription = description ?? c.description;
|
|
20
41
|
const [selectedId, setSelectedId] = React.useState(initialSelectedId ?? null);
|
|
21
42
|
// Cross-category starts expanded when there are no good fits, so producers
|
|
22
43
|
// see their portfolio without extra clicks in the empty case.
|
|
@@ -31,14 +52,6 @@ function VariantPickerContent({ onClose, onSelect, onCreateNew, onSkip, goodFits
|
|
|
31
52
|
setSelectedId(initialSelectedId);
|
|
32
53
|
}
|
|
33
54
|
}
|
|
34
|
-
const handleBackdrop = (e) => {
|
|
35
|
-
if (e.target === e.currentTarget)
|
|
36
|
-
onClose();
|
|
37
|
-
};
|
|
38
|
-
const handleKey = (e) => {
|
|
39
|
-
if (e.key === "Escape")
|
|
40
|
-
onClose();
|
|
41
|
-
};
|
|
42
55
|
const confirm = () => {
|
|
43
56
|
if (selectedId) {
|
|
44
57
|
onSelect(selectedId);
|
|
@@ -47,7 +60,7 @@ function VariantPickerContent({ onClose, onSelect, onCreateNew, onSkip, goodFits
|
|
|
47
60
|
};
|
|
48
61
|
const skip = () => (onSkip ? onSkip() : onClose());
|
|
49
62
|
const showEmptyGuidance = goodFits.length === 0 && emptyGuidance != null && onCreateNew != null;
|
|
50
|
-
return (_jsxs(
|
|
63
|
+
return (_jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-foreground/20 backdrop-blur-xs" }), _jsxs(Dialog.Content, { className: cn("glass-panel fixed left-1/2 top-1/2 z-50 flex max-h-[min(36rem,85dvh)] w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 flex-col", "rounded-2xl border border-border bg-card p-0 shadow-xl"), children: [_jsxs("div", { className: "shrink-0 px-5 pt-5 pb-3", children: [_jsx(Dialog.Title, { className: "text-base/6 font-semibold text-foreground", children: resolvedTitle }), _jsx(Dialog.Description, { className: "mt-1 text-sm/5 text-muted-foreground", children: resolvedDescription })] }), _jsx("div", { className: "px-3", children: _jsx(OpportunityBrief, { name: opportunityContext.name, buyerName: opportunityContext.buyerName ?? null, chips: opportunityContext.chips }) }), _jsx("div", { className: "px-3 pt-2", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground", "aria-hidden": true }), _jsx("input", { type: "text", value: searchValue, onChange: (e) => onSearchChange(e.target.value), placeholder: c.searchPlaceholder, autoFocus: true, className: "w-full rounded-xl border border-border bg-muted/30 py-2 pl-9 pr-3 text-sm/5 text-foreground placeholder:text-muted-foreground/60 outline-none transition-colors focus:border-primary/40 focus:ring-2 focus:ring-primary/20" })] }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pt-3 pb-1", children: isLoading ? (_jsx("div", { className: "flex flex-col items-center justify-center py-12", children: _jsx("p", { className: "text-sm/5 text-muted-foreground", children: c.loadingLabel }) })) : (_jsxs(_Fragment, { children: [_jsx(SectionLabel, { label: c.goodFitsLabel(goodFits.length), emphasis: goodFits.length > 0 }), showEmptyGuidance ? (_jsx(PickerEmptyGuidance, { categoryLabel: emptyGuidance.categoryLabel, createLabel: emptyGuidance.createLabel, onCreate: onCreateNew, onSkip: skip, className: "mt-2" })) : (_jsx("div", { className: "mt-2 flex flex-col gap-1.5", children: goodFits.map((v, i) => (_jsx(VariantRow, { variant: v, isSelected: v.id === selectedId, isTop: i === 0, onSelect: () => setSelectedId(v.id), closestFitTag: c.closestFitTag, differentCategoryTag: c.differentCategoryTag }, v.id))) })), crossCategory.length > 0 && (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => setShowCross((s) => !s), className: "mt-3 flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-left text-[11px] font-semibold text-muted-foreground transition-colors hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-card", children: [_jsx(ChevronRight, { className: cn("size-3 transition-transform", showCross && "rotate-90"), "aria-hidden": true }), goodFits.length === 0 ? c.crossCategoryLabel : c.otherProductsLabel, _jsxs("span", { className: "ml-1", children: ["(", crossCategory.length, ")"] })] }), showCross && (_jsx("div", { className: "mt-1.5 flex flex-col gap-1.5 rounded-xl bg-muted/20 p-1.5", children: crossCategory.map((v) => (_jsx(VariantRow, { variant: v, isSelected: v.id === selectedId, isCrossCategory: true, onSelect: () => setSelectedId(v.id), closestFitTag: c.closestFitTag, differentCategoryTag: c.differentCategoryTag }, v.id))) }))] }))] })) }), _jsx("div", { className: "shrink-0 border-t border-border px-5 py-3", children: _jsxs("div", { className: "flex items-center justify-end gap-2.5", children: [showEmptyGuidance ? (_jsx("button", { type: "button", onClick: onClose, className: "rounded-xl px-4 py-2 text-sm/5 font-medium text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-card", children: c.cancelButton })) : (_jsx("button", { type: "button", onClick: skip, className: "rounded-xl px-4 py-2 text-sm/5 font-medium text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-card", children: c.skipButton })), _jsx("button", { type: "button", onClick: confirm, disabled: !selectedId, className: cn("rounded-xl bg-primary px-4 py-2 text-sm/5 font-medium text-primary-foreground transition-[filter] focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-card", selectedId ? "hover:brightness-110" : "cursor-not-allowed opacity-50"), children: c.selectButton })] }) })] })] }));
|
|
51
64
|
}
|
|
52
65
|
// ---------------------------------------------------------------------------
|
|
53
66
|
// Helpers
|
|
@@ -55,7 +68,7 @@ function VariantPickerContent({ onClose, onSelect, onCreateNew, onSkip, goodFits
|
|
|
55
68
|
function SectionLabel({ label, emphasis }) {
|
|
56
69
|
return (_jsx("p", { className: cn("text-[10px] font-bold uppercase tracking-[0.06em]", emphasis ? "text-primary" : "text-muted-foreground"), children: label }));
|
|
57
70
|
}
|
|
58
|
-
function VariantRow({ variant, isSelected, isTop, isCrossCategory, onSelect, }) {
|
|
71
|
+
function VariantRow({ variant, isSelected, isTop, isCrossCategory, onSelect, closestFitTag, differentCategoryTag, }) {
|
|
59
72
|
const meta = [
|
|
60
73
|
variant.countryOfOrigin,
|
|
61
74
|
variant.containerVolume ? `${variant.containerVolume}` : null,
|
|
@@ -64,12 +77,12 @@ function VariantRow({ variant, isSelected, isTop, isCrossCategory, onSelect, })
|
|
|
64
77
|
]
|
|
65
78
|
.filter(Boolean)
|
|
66
79
|
.join(" · ");
|
|
67
|
-
return (_jsxs("button", { type: "button", onClick: onSelect, className: cn("flex w-full items-center gap-2.5 rounded-xl border px-3 py-2.5 text-left transition-colors", isSelected
|
|
80
|
+
return (_jsxs("button", { type: "button", onClick: onSelect, "aria-pressed": isSelected, className: cn("flex w-full items-center gap-2.5 rounded-xl border px-3 py-2.5 text-left transition-colors", "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-card", isSelected
|
|
68
81
|
? "border-primary bg-primary/5"
|
|
69
82
|
: isTop
|
|
70
83
|
? "border-primary/60 shadow-[0_0_0_2px] shadow-primary/10 hover:bg-muted/30"
|
|
71
84
|
: "border-border hover:bg-muted/30"), children: [_jsx("span", { className: cn("size-3.5 shrink-0 rounded-full border-2 transition-colors", isSelected
|
|
72
85
|
? "border-primary bg-primary shadow-[inset_0_0_0_2.5px] shadow-background"
|
|
73
|
-
: "border-muted-foreground/40"), "aria-hidden": true }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: "truncate text-[12px] font-semibold text-foreground", children: [variant.beverageName, isTop && !isCrossCategory && (_jsx("span", { className: "ml-1.5 text-[10px] font-medium text-primary", children:
|
|
86
|
+
: "border-muted-foreground/40"), "aria-hidden": true }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: "truncate text-[12px] font-semibold text-foreground", children: [variant.beverageName, isTop && !isCrossCategory && (_jsx("span", { className: "ml-1.5 text-[10px] font-medium text-primary", children: closestFitTag })), isCrossCategory && (_jsx("span", { className: "ml-1.5 text-[10px] font-medium text-warning-foreground", children: differentCategoryTag }))] }), meta && _jsx("p", { className: "text-[10px] text-muted-foreground", children: meta }), variant.reasons.length > 0 && (_jsx("div", { className: "mt-1 flex flex-wrap gap-1", children: variant.reasons.map((r) => (_jsx(ReasonPill, { kind: r.kind, signal: r.signal, label: r.label }, `${r.kind}-${r.signal}-${r.label}`))) }))] }), _jsx(ScoreChip, { score: variant.score, band: variant.band })] }));
|
|
74
87
|
}
|
|
75
88
|
//# sourceMappingURL=variant-picker-dialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"variant-picker-dialog.js","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAA6B,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAA8C,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"variant-picker-dialog.js","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variant-picker-dialog.test.d.ts","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { describe, it, expect, vi } from "vitest";
|
|
3
|
+
import { render, screen, fireEvent } from "@testing-library/react";
|
|
4
|
+
import { VariantPickerDialog } from "./variant-picker-dialog";
|
|
5
|
+
const goodFits = [
|
|
6
|
+
{
|
|
7
|
+
id: "v1",
|
|
8
|
+
beverageId: "b1",
|
|
9
|
+
beverageName: "Solera Brandy",
|
|
10
|
+
score: 92,
|
|
11
|
+
band: "top",
|
|
12
|
+
reasons: [{ kind: "ok", signal: "subtype", label: "Brandy" }],
|
|
13
|
+
countryOfOrigin: "Spain",
|
|
14
|
+
region: null,
|
|
15
|
+
vintage: 2019,
|
|
16
|
+
packaging: "750ml bottle",
|
|
17
|
+
containerVolume: "750ml",
|
|
18
|
+
category: "spirits",
|
|
19
|
+
subtype: "brandy",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "v2",
|
|
23
|
+
beverageId: "b2",
|
|
24
|
+
beverageName: "Aguardiente",
|
|
25
|
+
score: 65,
|
|
26
|
+
band: "good",
|
|
27
|
+
reasons: [{ kind: "warn", signal: "subtype", label: "Aguardiente" }],
|
|
28
|
+
countryOfOrigin: "Portugal",
|
|
29
|
+
region: null,
|
|
30
|
+
vintage: 2021,
|
|
31
|
+
packaging: "750ml bottle",
|
|
32
|
+
containerVolume: "750ml",
|
|
33
|
+
category: "spirits",
|
|
34
|
+
subtype: "aguardiente",
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
const crossCategory = [
|
|
38
|
+
{
|
|
39
|
+
id: "v3",
|
|
40
|
+
beverageId: "b3",
|
|
41
|
+
beverageName: "Riesling 2022",
|
|
42
|
+
score: 22,
|
|
43
|
+
band: "weak",
|
|
44
|
+
reasons: [{ kind: "miss", signal: "subtype", label: "White wine" }],
|
|
45
|
+
countryOfOrigin: "Germany",
|
|
46
|
+
region: null,
|
|
47
|
+
vintage: 2022,
|
|
48
|
+
packaging: "375ml bottle",
|
|
49
|
+
containerVolume: "375ml",
|
|
50
|
+
category: "wine",
|
|
51
|
+
subtype: "white-wine",
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
const baseProps = {
|
|
55
|
+
open: true,
|
|
56
|
+
onClose: vi.fn(),
|
|
57
|
+
onSelect: vi.fn(),
|
|
58
|
+
onSkip: vi.fn(),
|
|
59
|
+
searchValue: "",
|
|
60
|
+
onSearchChange: vi.fn(),
|
|
61
|
+
opportunityContext: {
|
|
62
|
+
name: "brandy spirits · Spain Selection",
|
|
63
|
+
buyerName: "Systembolaget",
|
|
64
|
+
chips: [{ label: "Spirits" }, { label: "Brandy" }],
|
|
65
|
+
},
|
|
66
|
+
goodFits,
|
|
67
|
+
crossCategory,
|
|
68
|
+
};
|
|
69
|
+
describe("VariantPickerDialog", () => {
|
|
70
|
+
it("renders nothing when open=false", () => {
|
|
71
|
+
const { container } = render(_jsx(VariantPickerDialog, { ...baseProps, open: false }));
|
|
72
|
+
// Radix Dialog.Root still renders the root element but portal content is absent
|
|
73
|
+
expect(screen.queryByText(/Solera Brandy/)).not.toBeInTheDocument();
|
|
74
|
+
expect(screen.queryByText(/Pick a product/i)).not.toBeInTheDocument();
|
|
75
|
+
});
|
|
76
|
+
it("renders the opportunity brief and good fits when open", () => {
|
|
77
|
+
render(_jsx(VariantPickerDialog, { ...baseProps }));
|
|
78
|
+
expect(screen.getByText(/brandy spirits/)).toBeInTheDocument();
|
|
79
|
+
expect(screen.getByText(/Solera Brandy/)).toBeInTheDocument();
|
|
80
|
+
// "Aguardiente" appears in both the beverage name and the reason pill label;
|
|
81
|
+
// use getAllByText and assert at least one match is present.
|
|
82
|
+
expect(screen.getAllByText(/Aguardiente/)[0]).toBeInTheDocument();
|
|
83
|
+
});
|
|
84
|
+
it("disables 'Select & pre-fill' until a row is selected", () => {
|
|
85
|
+
render(_jsx(VariantPickerDialog, { ...baseProps }));
|
|
86
|
+
const selectBtn = screen.getByRole("button", { name: /select.*pre-fill/i });
|
|
87
|
+
expect(selectBtn).toBeDisabled();
|
|
88
|
+
});
|
|
89
|
+
it("enables 'Select & pre-fill' after clicking a variant row, and onSelect fires with that variantId on confirm", () => {
|
|
90
|
+
const onSelect = vi.fn();
|
|
91
|
+
const onClose = vi.fn();
|
|
92
|
+
render(_jsx(VariantPickerDialog, { ...baseProps, onSelect: onSelect, onClose: onClose }));
|
|
93
|
+
// Click the row button (aria-pressed=false) that contains "Solera Brandy"
|
|
94
|
+
const rows = screen.getAllByRole("button", { name: /Solera Brandy/i });
|
|
95
|
+
fireEvent.click(rows[0]);
|
|
96
|
+
const selectBtn = screen.getByRole("button", { name: /select.*pre-fill/i });
|
|
97
|
+
expect(selectBtn).not.toBeDisabled();
|
|
98
|
+
fireEvent.click(selectBtn);
|
|
99
|
+
expect(onSelect).toHaveBeenCalledWith("v1");
|
|
100
|
+
expect(onClose).toHaveBeenCalled();
|
|
101
|
+
});
|
|
102
|
+
it("'Skip — empty draft' calls onSkip", () => {
|
|
103
|
+
const onSkip = vi.fn();
|
|
104
|
+
render(_jsx(VariantPickerDialog, { ...baseProps, onSkip: onSkip }));
|
|
105
|
+
fireEvent.click(screen.getByRole("button", { name: /skip/i }));
|
|
106
|
+
expect(onSkip).toHaveBeenCalled();
|
|
107
|
+
});
|
|
108
|
+
it("renders empty-state guidance when goodFits is empty AND emptyGuidance + onCreateNew provided", () => {
|
|
109
|
+
const onCreateNew = vi.fn();
|
|
110
|
+
render(_jsx(VariantPickerDialog, { ...baseProps, goodFits: [], onCreateNew: onCreateNew, emptyGuidance: { categoryLabel: "Spirits · Brandy", createLabel: "Create a new brandy product" } }));
|
|
111
|
+
expect(screen.getByText(/Your portfolio has no Spirits · Brandy/i)).toBeInTheDocument();
|
|
112
|
+
expect(screen.getByRole("button", { name: /create a new brandy/i })).toBeInTheDocument();
|
|
113
|
+
fireEvent.click(screen.getByRole("button", { name: /create a new brandy/i }));
|
|
114
|
+
expect(onCreateNew).toHaveBeenCalled();
|
|
115
|
+
});
|
|
116
|
+
it("footer 'Cancel' calls onClose (NOT onSkip) in empty-state mode", () => {
|
|
117
|
+
const onClose = vi.fn();
|
|
118
|
+
const onSkip = vi.fn();
|
|
119
|
+
render(_jsx(VariantPickerDialog, { ...baseProps, goodFits: [], onClose: onClose, onSkip: onSkip, onCreateNew: vi.fn(), emptyGuidance: { categoryLabel: "Spirits · Brandy", createLabel: "Create a new brandy product" } }));
|
|
120
|
+
fireEvent.click(screen.getByRole("button", { name: /^cancel$/i }));
|
|
121
|
+
expect(onClose).toHaveBeenCalled();
|
|
122
|
+
expect(onSkip).not.toHaveBeenCalled();
|
|
123
|
+
});
|
|
124
|
+
it("renders cross-category section with toggle", () => {
|
|
125
|
+
render(_jsx(VariantPickerDialog, { ...baseProps }));
|
|
126
|
+
expect(screen.getByText(/other portfolio products/i)).toBeInTheDocument();
|
|
127
|
+
});
|
|
128
|
+
it("calls onSearchChange when typing in the search input", () => {
|
|
129
|
+
const onSearchChange = vi.fn();
|
|
130
|
+
render(_jsx(VariantPickerDialog, { ...baseProps, onSearchChange: onSearchChange }));
|
|
131
|
+
const input = screen.getByPlaceholderText(/search your portfolio/i);
|
|
132
|
+
fireEvent.change(input, { target: { value: "reserva" } });
|
|
133
|
+
expect(onSearchChange).toHaveBeenCalledWith("reserva");
|
|
134
|
+
});
|
|
135
|
+
it("respects copy prop for i18n customization", () => {
|
|
136
|
+
render(_jsx(VariantPickerDialog, { ...baseProps, copy: { selectButton: "Använd produkt" } }));
|
|
137
|
+
expect(screen.getByRole("button", { name: /använd produkt/i })).toBeInTheDocument();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=variant-picker-dialog.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variant-picker-dialog.test.js","sourceRoot":"","sources":["../../src/components/variant-picker-dialog.test.tsx"],"names":[],"mappings":"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"}
|