pi-kiosk-shared 2.2.36 → 2.2.37
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/permissions/permissionLabels.d.ts +7 -0
- package/dist/permissions/permissionLabels.d.ts.map +1 -1
- package/dist/permissions/permissionLabels.js +132 -1
- package/dist/permissions/permissionLabels.js.map +1 -1
- package/dist/ui/Avatar/Avatar.d.ts +15 -0
- package/dist/ui/Avatar/Avatar.d.ts.map +1 -0
- package/dist/ui/Avatar/Avatar.js +37 -0
- package/dist/ui/Avatar/Avatar.js.map +1 -0
- package/dist/ui/Badge/Badge.d.ts +60 -0
- package/dist/ui/Badge/Badge.d.ts.map +1 -0
- package/dist/ui/Badge/Badge.js +91 -0
- package/dist/ui/Badge/Badge.js.map +1 -0
- package/dist/ui/BottomSheet/BottomSheet.d.ts +18 -0
- package/dist/ui/BottomSheet/BottomSheet.d.ts.map +1 -0
- package/dist/ui/BottomSheet/BottomSheet.js +29 -0
- package/dist/ui/BottomSheet/BottomSheet.js.map +1 -0
- package/dist/ui/Breadcrumbs/Breadcrumbs.d.ts +19 -0
- package/dist/ui/Breadcrumbs/Breadcrumbs.d.ts.map +1 -0
- package/dist/ui/Breadcrumbs/Breadcrumbs.js +13 -0
- package/dist/ui/Breadcrumbs/Breadcrumbs.js.map +1 -0
- package/dist/ui/Checkbox/Checkbox.d.ts +9 -0
- package/dist/ui/Checkbox/Checkbox.d.ts.map +1 -0
- package/dist/ui/Checkbox/Checkbox.js +18 -0
- package/dist/ui/Checkbox/Checkbox.js.map +1 -0
- package/dist/ui/Dialog/Dialog.d.ts +16 -0
- package/dist/ui/Dialog/Dialog.d.ts.map +1 -0
- package/dist/ui/Dialog/Dialog.js +31 -0
- package/dist/ui/Dialog/Dialog.js.map +1 -0
- package/dist/ui/FAB/FAB.d.ts +15 -0
- package/dist/ui/FAB/FAB.d.ts.map +1 -0
- package/dist/ui/FAB/FAB.js +18 -0
- package/dist/ui/FAB/FAB.js.map +1 -0
- package/dist/ui/FilterChip/FilterChip.d.ts +16 -0
- package/dist/ui/FilterChip/FilterChip.d.ts.map +1 -0
- package/dist/ui/FilterChip/FilterChip.js +26 -0
- package/dist/ui/FilterChip/FilterChip.js.map +1 -0
- package/dist/ui/Icon/Icon.d.ts +18 -0
- package/dist/ui/Icon/Icon.d.ts.map +1 -0
- package/dist/ui/Icon/Icon.js +17 -0
- package/dist/ui/Icon/Icon.js.map +1 -0
- package/dist/ui/Icon/index.d.ts +4 -0
- package/dist/ui/Icon/index.d.ts.map +1 -0
- package/dist/ui/Icon/index.js +3 -0
- package/dist/ui/Icon/index.js.map +1 -0
- package/dist/ui/Icon/lucide.d.ts +7 -0
- package/dist/ui/Icon/lucide.d.ts.map +1 -0
- package/dist/ui/Icon/lucide.js +2 -0
- package/dist/ui/Icon/lucide.js.map +1 -0
- package/dist/ui/IconButton/IconButton.d.ts +51 -0
- package/dist/ui/IconButton/IconButton.d.ts.map +1 -0
- package/dist/ui/IconButton/IconButton.js +37 -0
- package/dist/ui/IconButton/IconButton.js.map +1 -0
- package/dist/ui/IconButton/index.d.ts +2 -0
- package/dist/ui/IconButton/index.d.ts.map +1 -0
- package/dist/ui/IconButton/index.js +2 -0
- package/dist/ui/IconButton/index.js.map +1 -0
- package/dist/ui/Input/Input.d.ts +24 -0
- package/dist/ui/Input/Input.d.ts.map +1 -0
- package/dist/ui/Input/Input.js +25 -0
- package/dist/ui/Input/Input.js.map +1 -0
- package/dist/ui/Loader/Loader.d.ts +13 -0
- package/dist/ui/Loader/Loader.d.ts.map +1 -0
- package/dist/ui/Loader/Loader.js +17 -0
- package/dist/ui/Loader/Loader.js.map +1 -0
- package/dist/ui/NavStepper/NavStepper.d.ts +16 -0
- package/dist/ui/NavStepper/NavStepper.d.ts.map +1 -0
- package/dist/ui/NavStepper/NavStepper.js +31 -0
- package/dist/ui/NavStepper/NavStepper.js.map +1 -0
- package/dist/ui/QuantityStepper/QuantityStepper.d.ts +19 -0
- package/dist/ui/QuantityStepper/QuantityStepper.d.ts.map +1 -0
- package/dist/ui/QuantityStepper/QuantityStepper.js +13 -0
- package/dist/ui/QuantityStepper/QuantityStepper.js.map +1 -0
- package/dist/ui/QuantityStepper/index.d.ts +2 -0
- package/dist/ui/QuantityStepper/index.d.ts.map +1 -0
- package/dist/ui/QuantityStepper/index.js +2 -0
- package/dist/ui/QuantityStepper/index.js.map +1 -0
- package/dist/ui/Radio/Radio.d.ts +9 -0
- package/dist/ui/Radio/Radio.d.ts.map +1 -0
- package/dist/ui/Radio/Radio.js +18 -0
- package/dist/ui/Radio/Radio.js.map +1 -0
- package/dist/ui/ScreenState/ScreenState.d.ts +27 -0
- package/dist/ui/ScreenState/ScreenState.d.ts.map +1 -0
- package/dist/ui/ScreenState/ScreenState.js +29 -0
- package/dist/ui/ScreenState/ScreenState.js.map +1 -0
- package/dist/ui/SegmentTabs/SegmentTabs.d.ts +21 -0
- package/dist/ui/SegmentTabs/SegmentTabs.d.ts.map +1 -0
- package/dist/ui/SegmentTabs/SegmentTabs.js +49 -0
- package/dist/ui/SegmentTabs/SegmentTabs.js.map +1 -0
- package/dist/ui/SegmentTabs/SegmentTabsOverflow.d.ts +17 -0
- package/dist/ui/SegmentTabs/SegmentTabsOverflow.d.ts.map +1 -0
- package/dist/ui/SegmentTabs/SegmentTabsOverflow.js +24 -0
- package/dist/ui/SegmentTabs/SegmentTabsOverflow.js.map +1 -0
- package/dist/ui/Select/Select.d.ts +30 -0
- package/dist/ui/Select/Select.d.ts.map +1 -0
- package/dist/ui/Select/Select.js +101 -0
- package/dist/ui/Select/Select.js.map +1 -0
- package/dist/ui/Select/index.d.ts +2 -0
- package/dist/ui/Select/index.d.ts.map +1 -0
- package/dist/ui/Select/index.js +2 -0
- package/dist/ui/Select/index.js.map +1 -0
- package/dist/ui/Skeleton/Skeleton.d.ts +15 -0
- package/dist/ui/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/ui/Skeleton/Skeleton.js +16 -0
- package/dist/ui/Skeleton/Skeleton.js.map +1 -0
- package/dist/ui/Switch/Switch.d.ts +11 -0
- package/dist/ui/Switch/Switch.d.ts.map +1 -0
- package/dist/ui/Switch/Switch.js +36 -0
- package/dist/ui/Switch/Switch.js.map +1 -0
- package/dist/ui/Textarea/Textarea.d.ts +24 -0
- package/dist/ui/Textarea/Textarea.d.ts.map +1 -0
- package/dist/ui/Textarea/Textarea.js +25 -0
- package/dist/ui/Textarea/Textarea.js.map +1 -0
- package/dist/ui/Toast/Toast.d.ts +14 -0
- package/dist/ui/Toast/Toast.d.ts.map +1 -0
- package/dist/ui/Toast/Toast.js +21 -0
- package/dist/ui/Toast/Toast.js.map +1 -0
- package/dist/ui/Typography/Typography.d.ts +70 -0
- package/dist/ui/Typography/Typography.d.ts.map +1 -0
- package/dist/ui/Typography/Typography.js +58 -0
- package/dist/ui/Typography/Typography.js.map +1 -0
- package/package.json +1 -1
- package/src/tokens/brand-bridge.css +6 -0
- package/src/tokens/tokens.sync.json +989 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { tv } from '../tvShim.js';
|
|
4
|
+
const input = tv({
|
|
5
|
+
base: [
|
|
6
|
+
'h-10 w-full rounded-md border px-3 text-sm',
|
|
7
|
+
'border-[var(--color-border,var(--color-an-border))]',
|
|
8
|
+
'bg-[var(--color-surface,var(--color-an-surface))]',
|
|
9
|
+
'text-[var(--color-on-surface,var(--color-an-text))]',
|
|
10
|
+
'placeholder:text-[var(--color-on-surface-muted,var(--color-an-text-muted))]',
|
|
11
|
+
'focus-visible:outline-none focus-visible:border-[var(--color-focus-ring,var(--color-an-primary))]',
|
|
12
|
+
'disabled:cursor-not-allowed disabled:opacity-60',
|
|
13
|
+
].join(' '),
|
|
14
|
+
variants: {
|
|
15
|
+
invalid: {
|
|
16
|
+
true: 'border-[var(--color-danger,var(--color-an-danger))]',
|
|
17
|
+
false: '',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: { invalid: false },
|
|
21
|
+
});
|
|
22
|
+
/** CMP-0004 Input */
|
|
23
|
+
export const Input = forwardRef(({ className, invalid, ...rest }, ref) => (_jsx("input", { ref: ref, className: input({ invalid, className }), ...rest })));
|
|
24
|
+
Input.displayName = 'Input';
|
|
25
|
+
//# sourceMappingURL=Input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../src/ui/Input/Input.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAqB,MAAM,cAAc,CAAC;AAErD,MAAM,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,EAAE;QACJ,4CAA4C;QAC5C,qDAAqD;QACrD,mDAAmD;QACnD,qDAAqD;QACrD,6EAA6E;QAC7E,mGAAmG;QACnG,iDAAiD;KAClD,CAAC,IAAI,CAAC,GAAG,CAAC;IACX,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,IAAI,EAAE,qDAAqD;YAC3D,KAAK,EAAE,EAAE;SACV;KACF;IACD,eAAe,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;CACpC,CAAC,CAAC;AAMH,qBAAqB;AACrB,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAC7B,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACxC,gBAAO,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,KAAM,IAAI,GAAI,CACxE,CACF,CAAC;AACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMP-0013 Loader — spinner alias.
|
|
3
|
+
*/
|
|
4
|
+
export interface LoaderProps {
|
|
5
|
+
readonly size?: 'sm' | 'md' | 'lg';
|
|
6
|
+
readonly label?: string;
|
|
7
|
+
readonly className?: string;
|
|
8
|
+
readonly testId?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function Loader({ size, label, className, testId, }: LoaderProps): JSX.Element;
|
|
11
|
+
/** Spinner alias for CMP-0013. */
|
|
12
|
+
export declare const Spinner: typeof Loader;
|
|
13
|
+
//# sourceMappingURL=Loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Loader.d.ts","sourceRoot":"","sources":["../../../src/ui/Loader/Loader.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAQD,wBAAgB,MAAM,CAAC,EACrB,IAAW,EACX,KAAiB,EACjB,SAAS,EACT,MAAiB,GAClB,EAAE,WAAW,GAAG,GAAG,CAAC,OAAO,CAqB3B;AAED,kCAAkC;AAClC,eAAO,MAAM,OAAO,eAAS,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const SIZE_CLASS = {
|
|
3
|
+
sm: 'h-4 w-4 border-2',
|
|
4
|
+
md: 'h-8 w-8 border-2',
|
|
5
|
+
lg: 'h-12 w-12 border-[3px]',
|
|
6
|
+
};
|
|
7
|
+
export function Loader({ size = 'md', label = 'Loading', className, testId = 'loader', }) {
|
|
8
|
+
return (_jsxs("div", { className: ['inline-flex flex-col items-center gap-2', className].filter(Boolean).join(' '), role: "status", "aria-live": "polite", "aria-busy": "true", "data-testid": testId, children: [_jsx("span", { className: [
|
|
9
|
+
'inline-block animate-spin rounded-full border-solid',
|
|
10
|
+
'border-[var(--color-border,var(--color-an-border))]',
|
|
11
|
+
'border-t-[var(--color-action-primary,var(--color-an-primary))]',
|
|
12
|
+
SIZE_CLASS[size],
|
|
13
|
+
].join(' '), "aria-hidden": "true" }), _jsx("span", { className: "sr-only", children: label })] }));
|
|
14
|
+
}
|
|
15
|
+
/** Spinner alias for CMP-0013. */
|
|
16
|
+
export const Spinner = Loader;
|
|
17
|
+
//# sourceMappingURL=Loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Loader.js","sourceRoot":"","sources":["../../../src/ui/Loader/Loader.tsx"],"names":[],"mappings":";AAUA,MAAM,UAAU,GAAqD;IACnE,EAAE,EAAE,kBAAkB;IACtB,EAAE,EAAE,kBAAkB;IACtB,EAAE,EAAE,wBAAwB;CAC7B,CAAC;AAEF,MAAM,UAAU,MAAM,CAAC,EACrB,IAAI,GAAG,IAAI,EACX,KAAK,GAAG,SAAS,EACjB,SAAS,EACT,MAAM,GAAG,QAAQ,GACL;IACZ,OAAO,CACL,eACE,SAAS,EAAE,CAAC,yCAAyC,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAC3F,IAAI,EAAC,QAAQ,eACH,QAAQ,eACR,MAAM,iBACH,MAAM,aAEnB,eACE,SAAS,EAAE;oBACT,qDAAqD;oBACrD,qDAAqD;oBACrD,gEAAgE;oBAChE,UAAU,CAAC,IAAI,CAAC;iBACjB,CAAC,IAAI,CAAC,GAAG,CAAC,iBACC,MAAM,GAClB,EACF,eAAM,SAAS,EAAC,SAAS,YAAE,KAAK,GAAQ,IACpC,CACP,CAAC;AACJ,CAAC;AAED,kCAAkC;AAClC,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMP-0027 NavStepper — linear multi-step chrome (≠ QuantityStepper).
|
|
3
|
+
*/
|
|
4
|
+
export interface NavStepperStep {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly label: string;
|
|
7
|
+
}
|
|
8
|
+
export interface NavStepperProps {
|
|
9
|
+
readonly steps: readonly NavStepperStep[];
|
|
10
|
+
readonly activeStepId: string;
|
|
11
|
+
readonly ariaLabel?: string;
|
|
12
|
+
readonly className?: string;
|
|
13
|
+
readonly testId?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function NavStepper({ steps, activeStepId, ariaLabel, className, testId, }: NavStepperProps): JSX.Element;
|
|
16
|
+
//# sourceMappingURL=NavStepper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavStepper.d.ts","sourceRoot":"","sources":["../../../src/ui/NavStepper/NavStepper.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAsBD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,MAAsB,GACvB,EAAE,eAAe,GAAG,GAAG,CAAC,OAAO,CAqC/B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function stepSurfaceClass(isActive, isComplete) {
|
|
3
|
+
if (isActive) {
|
|
4
|
+
return 'border-[var(--color-accent,var(--color-an-primary))] bg-[var(--color-surface,var(--color-an-surface))] text-[var(--color-on-surface,var(--color-an-text))]';
|
|
5
|
+
}
|
|
6
|
+
if (isComplete) {
|
|
7
|
+
return 'border-[var(--color-border,var(--color-an-border))] bg-[var(--color-surface-muted,var(--color-an-bg))] text-[var(--color-on-surface,var(--color-an-text))]';
|
|
8
|
+
}
|
|
9
|
+
return 'border-[var(--color-border,var(--color-an-border))] bg-transparent text-[var(--color-on-surface-muted,var(--color-an-text-muted))]';
|
|
10
|
+
}
|
|
11
|
+
function stepDataState(isActive, isComplete) {
|
|
12
|
+
if (isActive) {
|
|
13
|
+
return 'active';
|
|
14
|
+
}
|
|
15
|
+
if (isComplete) {
|
|
16
|
+
return 'complete';
|
|
17
|
+
}
|
|
18
|
+
return 'upcoming';
|
|
19
|
+
}
|
|
20
|
+
export function NavStepper({ steps, activeStepId, ariaLabel, className, testId = 'nav-stepper', }) {
|
|
21
|
+
const activeIndex = Math.max(0, steps.findIndex((step) => step.id === activeStepId));
|
|
22
|
+
return (_jsx("nav", { "aria-label": ariaLabel, className: ['w-full', className ?? ''].filter((part) => part.length > 0).join(' '), "data-testid": testId, children: _jsx("ol", { className: "m-0 flex w-full list-none items-stretch gap-1 p-0", children: steps.map((step, index) => {
|
|
23
|
+
const isActive = step.id === activeStepId;
|
|
24
|
+
const isComplete = index < activeIndex;
|
|
25
|
+
return (_jsxs("li", { className: [
|
|
26
|
+
'flex min-w-0 flex-1 flex-col items-center gap-1 rounded-md border px-2 py-2 text-center',
|
|
27
|
+
stepSurfaceClass(isActive, isComplete),
|
|
28
|
+
].join(' '), "aria-current": isActive ? 'step' : undefined, "data-testid": `${testId}-step-${step.id}`, "data-state": stepDataState(isActive, isComplete), children: [_jsx("span", { className: "text-[0.65rem] font-semibold tabular-nums tracking-wide", children: index + 1 }), _jsx("span", { className: "truncate text-xs font-medium sm:text-sm", children: step.label })] }, step.id));
|
|
29
|
+
}) }) }));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=NavStepper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavStepper.js","sourceRoot":"","sources":["../../../src/ui/NavStepper/NavStepper.tsx"],"names":[],"mappings":";AAiBA,SAAS,gBAAgB,CAAC,QAAiB,EAAE,UAAmB;IAC9D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,4JAA4J,CAAC;IACtK,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,4JAA4J,CAAC;IACtK,CAAC;IACD,OAAO,oIAAoI,CAAC;AAC9I,CAAC;AAED,SAAS,aAAa,CAAC,QAAiB,EAAE,UAAmB;IAC3D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,MAAM,GAAG,aAAa,GACN;IAChB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAC1B,CAAC,EACD,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,YAAY,CAAC,CACpD,CAAC;IAEF,OAAO,CACL,4BACc,SAAS,EACrB,SAAS,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,iBACrE,MAAM,YAEnB,aAAI,SAAS,EAAC,mDAAmD,YAC9D,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,KAAK,YAAY,CAAC;gBAC1C,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC;gBACvC,OAAO,CACL,cAEE,SAAS,EAAE;wBACT,yFAAyF;wBACzF,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC;qBACvC,CAAC,IAAI,CAAC,GAAG,CAAC,kBACG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,iBAC9B,GAAG,MAAM,SAAS,IAAI,CAAC,EAAE,EAAE,gBAC5B,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,aAE/C,eAAM,SAAS,EAAC,yDAAyD,YACtE,KAAK,GAAG,CAAC,GACL,EACP,eAAM,SAAS,EAAC,yCAAyC,YAAE,IAAI,CAAC,KAAK,GAAQ,KAZxE,IAAI,CAAC,EAAE,CAaT,CACN,CAAC;YACJ,CAAC,CAAC,GACC,GACD,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface QuantityStepperProps {
|
|
2
|
+
readonly value: number;
|
|
3
|
+
readonly onInc: () => void;
|
|
4
|
+
readonly onDec: () => void;
|
|
5
|
+
readonly min?: number;
|
|
6
|
+
readonly max?: number;
|
|
7
|
+
/** When true, both controls are disabled (e.g. line not selected). */
|
|
8
|
+
readonly disabled?: boolean;
|
|
9
|
+
/** Accessible name for the stepper group (buttons get derived labels). */
|
|
10
|
+
readonly 'aria-label': string;
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
readonly testId?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* CMP-0016 QuantityStepper — thin +/- quantity control.
|
|
16
|
+
* Prefer this over one-off IconButtons for cart/line qty.
|
|
17
|
+
*/
|
|
18
|
+
export declare function QuantityStepper({ value, onInc, onDec, min, max, disabled, 'aria-label': ariaLabel, className, testId, }: QuantityStepperProps): JSX.Element;
|
|
19
|
+
//# sourceMappingURL=QuantityStepper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuantityStepper.d.ts","sourceRoot":"","sources":["../../../src/ui/QuantityStepper/QuantityStepper.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,KAAK,EACL,GAAO,EACP,GAAG,EACH,QAAgB,EAChB,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,MAA2B,GAC5B,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CAqCpC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Minus, Plus } from '../Icon/lucide.js';
|
|
3
|
+
import { IconButton } from '../IconButton/IconButton.js';
|
|
4
|
+
/**
|
|
5
|
+
* CMP-0016 QuantityStepper — thin +/- quantity control.
|
|
6
|
+
* Prefer this over one-off IconButtons for cart/line qty.
|
|
7
|
+
*/
|
|
8
|
+
export function QuantityStepper({ value, onInc, onDec, min = 0, max, disabled = false, 'aria-label': ariaLabel, className, testId = 'quantity-stepper', }) {
|
|
9
|
+
const atMin = value <= min;
|
|
10
|
+
const atMax = max !== undefined && value >= max;
|
|
11
|
+
return (_jsxs("div", { className: ['inline-flex items-center gap-2', className].filter(Boolean).join(' '), role: "group", "aria-label": ariaLabel, "data-testid": testId, children: [_jsx(IconButton, { icon: Minus, size: "sm", tone: "muted", "aria-label": `${ariaLabel}: decrease`, disabled: disabled || atMin, onClick: onDec, "data-testid": `${testId}-dec` }), _jsx("span", { className: "min-w-8 text-center text-base font-semibold tabular-nums text-[var(--color-text-primary,var(--color-on-surface))]", "aria-live": "polite", "data-testid": `${testId}-value`, children: value }), _jsx(IconButton, { icon: Plus, size: "sm", "aria-label": `${ariaLabel}: increase`, disabled: disabled || atMax, onClick: onInc, "data-testid": `${testId}-inc` })] }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=QuantityStepper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuantityStepper.js","sourceRoot":"","sources":["../../../src/ui/QuantityStepper/QuantityStepper.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAgBzD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,EACL,KAAK,EACL,KAAK,EACL,GAAG,GAAG,CAAC,EACP,GAAG,EACH,QAAQ,GAAG,KAAK,EAChB,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,MAAM,GAAG,kBAAkB,GACN;IACrB,MAAM,KAAK,GAAG,KAAK,IAAI,GAAG,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,IAAI,KAAK,IAAI,GAAG,CAAC;IAEhD,OAAO,CACL,eACE,SAAS,EAAE,CAAC,gCAAgC,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAClF,IAAI,EAAC,OAAO,gBACA,SAAS,iBACR,MAAM,aAEnB,KAAC,UAAU,IACT,IAAI,EAAE,KAAK,EACX,IAAI,EAAC,IAAI,EACT,IAAI,EAAC,OAAO,gBACA,GAAG,SAAS,YAAY,EACpC,QAAQ,EAAE,QAAQ,IAAI,KAAK,EAC3B,OAAO,EAAE,KAAK,iBACD,GAAG,MAAM,MAAM,GAC5B,EACF,eACE,SAAS,EAAC,mHAAmH,eACnH,QAAQ,iBACL,GAAG,MAAM,QAAQ,YAE7B,KAAK,GACD,EACP,KAAC,UAAU,IACT,IAAI,EAAE,IAAI,EACV,IAAI,EAAC,IAAI,gBACG,GAAG,SAAS,YAAY,EACpC,QAAQ,EAAE,QAAQ,IAAI,KAAK,EAC3B,OAAO,EAAE,KAAK,iBACD,GAAG,MAAM,MAAM,GAC5B,IACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/QuantityStepper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/QuantityStepper/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA6B,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type InputHTMLAttributes } from 'react';
|
|
2
|
+
export type RadioProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> & {
|
|
3
|
+
readonly label?: string;
|
|
4
|
+
};
|
|
5
|
+
/** CMP-0007 Radio — native control. */
|
|
6
|
+
export declare const Radio: import("react").ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type"> & {
|
|
7
|
+
readonly label?: string;
|
|
8
|
+
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
9
|
+
//# sourceMappingURL=Radio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Radio.d.ts","sourceRoot":"","sources":["../../../src/ui/Radio/Radio.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAE7D,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG;IAC7E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,KAAK;qBAJC,MAAM;oDAkCxB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
/** CMP-0007 Radio — native control. */
|
|
4
|
+
export const Radio = forwardRef(({ className, label, id, ...rest }, ref) => {
|
|
5
|
+
const input = (_jsx("input", { ref: ref, id: id, type: "radio", className: [
|
|
6
|
+
'h-4 w-4 border-[var(--color-border,var(--color-an-border))]',
|
|
7
|
+
'accent-[var(--color-action-primary,var(--color-an-primary))]',
|
|
8
|
+
className,
|
|
9
|
+
]
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.join(' '), ...rest }));
|
|
12
|
+
if (!label) {
|
|
13
|
+
return input;
|
|
14
|
+
}
|
|
15
|
+
return (_jsxs("label", { className: "inline-flex items-center gap-2 text-sm text-[var(--color-on-surface,var(--color-an-text))]", htmlFor: id, children: [input, _jsx("span", { children: label })] }));
|
|
16
|
+
});
|
|
17
|
+
Radio.displayName = 'Radio';
|
|
18
|
+
//# sourceMappingURL=Radio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Radio.js","sourceRoot":"","sources":["../../../src/ui/Radio/Radio.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAM7D,uCAAuC;AACvC,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAC7B,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE;IACzC,MAAM,KAAK,GAAG,CACZ,gBACE,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,EAAE,EACN,IAAI,EAAC,OAAO,EACZ,SAAS,EAAE;YACT,6DAA6D;YAC7D,8DAA8D;YAC9D,SAAS;SACV;aACE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,KACR,IAAI,GACR,CACH,CAAC;IACF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CACL,iBACE,SAAS,EAAC,4FAA4F,EACtG,OAAO,EAAE,EAAE,aAEV,KAAK,EACN,yBAAO,KAAK,GAAQ,IACd,CACT,CAAC;AACJ,CAAC,CACF,CAAC;AACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* CMP-0015 ScreenState — Q12 union (ADR-FE-UI-001 v4).
|
|
4
|
+
* Presentational only — callers own i18n copy.
|
|
5
|
+
*/
|
|
6
|
+
export type ScreenStateVariant = 'loading' | 'error' | 'empty' | 'offline' | 'success';
|
|
7
|
+
export interface ScreenStateAction {
|
|
8
|
+
readonly label: string;
|
|
9
|
+
readonly onClick: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface ScreenStateProps {
|
|
12
|
+
readonly variant: ScreenStateVariant;
|
|
13
|
+
readonly title?: string;
|
|
14
|
+
readonly message?: string;
|
|
15
|
+
readonly hint?: string;
|
|
16
|
+
readonly icon?: ReactNode;
|
|
17
|
+
readonly error?: Error;
|
|
18
|
+
readonly onRetry?: () => void;
|
|
19
|
+
readonly retryLabel?: string;
|
|
20
|
+
readonly action?: ScreenStateAction;
|
|
21
|
+
readonly testId?: string;
|
|
22
|
+
readonly className?: string;
|
|
23
|
+
/** Optional custom body (e.g. app skeleton / spinner). */
|
|
24
|
+
readonly children?: ReactNode;
|
|
25
|
+
}
|
|
26
|
+
export declare function ScreenState({ variant, title, message, hint, icon, error, onRetry, retryLabel, action, testId, className, children, }: ScreenStateProps): JSX.Element;
|
|
27
|
+
//# sourceMappingURL=ScreenState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenState.d.ts","sourceRoot":"","sources":["../../../src/ui/ScreenState/ScreenState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAEvF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAwBD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAoB,EACpB,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,GACT,EAAE,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAyDhC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function panelClass(variant) {
|
|
3
|
+
if (variant === 'error' || variant === 'offline') {
|
|
4
|
+
return [
|
|
5
|
+
'rounded-lg border border-[var(--color-danger,var(--color-an-danger,#dc2626))]',
|
|
6
|
+
'bg-[color-mix(in_oklab,var(--color-danger,var(--color-an-danger,#dc2626))_10%,transparent)]',
|
|
7
|
+
'p-4 text-center',
|
|
8
|
+
].join(' ');
|
|
9
|
+
}
|
|
10
|
+
if (variant === 'success') {
|
|
11
|
+
return [
|
|
12
|
+
'rounded-lg border border-[color-mix(in_oklab,var(--color-success,var(--color-an-success,#16a34a))_55%,transparent)]',
|
|
13
|
+
'bg-[color-mix(in_oklab,var(--color-success,var(--color-an-success,#16a34a))_12%,transparent)]',
|
|
14
|
+
'p-4 text-[var(--color-success,var(--color-an-success,#16a34a))]',
|
|
15
|
+
].join(' ');
|
|
16
|
+
}
|
|
17
|
+
return [
|
|
18
|
+
'rounded-lg border border-[var(--color-border,var(--color-an-border,#e5e7eb))]',
|
|
19
|
+
'bg-[var(--color-surface,var(--color-an-surface,#fff))]',
|
|
20
|
+
'p-4 text-center',
|
|
21
|
+
].join(' ');
|
|
22
|
+
}
|
|
23
|
+
export function ScreenState({ variant, title, message, hint, icon, error, onRetry, retryLabel = 'Retry', action, testId, className, children, }) {
|
|
24
|
+
const resolvedMessage = error?.message ?? message;
|
|
25
|
+
const role = variant === 'error' || variant === 'offline' ? 'alert' : 'status';
|
|
26
|
+
const live = variant === 'loading' ? 'polite' : undefined;
|
|
27
|
+
return (_jsxs("div", { className: [panelClass(variant), className].filter(Boolean).join(' '), role: role, "aria-live": live, "aria-busy": variant === 'loading' ? true : undefined, "data-testid": testId ?? `screen-state-${variant}`, "data-variant": variant, children: [icon ? _jsx("div", { className: "mb-2 flex justify-center text-2xl", "aria-hidden": "true", children: icon }) : null, title ? (_jsx("h3", { className: "m-0 text-base font-semibold text-[var(--color-on-surface,var(--color-an-text,#111))]", children: title })) : null, resolvedMessage ? (_jsx("p", { className: "mt-1 mb-0 text-sm text-[var(--color-on-surface-muted,var(--color-an-text-muted,#6b7280))]", children: resolvedMessage })) : null, hint ? (_jsx("p", { className: "mt-1 mb-0 text-xs text-[var(--color-on-surface-muted,var(--color-an-text-muted,#6b7280))]", children: hint })) : null, children, onRetry ? (_jsx("div", { className: "mt-3", children: _jsx("button", { type: "button", className: "inline-flex min-h-[44px] items-center justify-center rounded-md bg-[var(--color-action-primary,var(--color-an-primary,#4f46e5))] px-4 py-2 text-sm font-semibold text-white", onClick: onRetry, "data-testid": `${testId ?? 'screen-state'}-retry`, children: retryLabel }) })) : null, action ? (_jsx("div", { className: "mt-3", children: _jsx("button", { type: "button", className: "inline-flex min-h-[44px] items-center justify-center rounded-md border border-[var(--color-border,var(--color-an-border))] px-4 py-2 text-sm font-semibold", onClick: action.onClick, "data-testid": `${testId ?? 'screen-state'}-action`, children: action.label }) })) : null] }));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=ScreenState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScreenState.js","sourceRoot":"","sources":["../../../src/ui/ScreenState/ScreenState.tsx"],"names":[],"mappings":";AA6BA,SAAS,UAAU,CAAC,OAA2B;IAC7C,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACjD,OAAO;YACL,+EAA+E;YAC/E,6FAA6F;YAC7F,iBAAiB;SAClB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO;YACL,qHAAqH;YACrH,+FAA+F;YAC/F,iEAAiE;SAClE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;IACD,OAAO;QACL,+EAA+E;QAC/E,wDAAwD;QACxD,iBAAiB;KAClB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAU,GAAG,OAAO,EACpB,MAAM,EACN,MAAM,EACN,SAAS,EACT,QAAQ,GACS;IACjB,MAAM,eAAe,GAAG,KAAK,EAAE,OAAO,IAAI,OAAO,CAAC;IAClD,MAAM,IAAI,GAAG,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/E,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1D,OAAO,CACL,eACE,SAAS,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACrE,IAAI,EAAE,IAAI,eACC,IAAI,eACJ,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,iBACtC,MAAM,IAAI,gBAAgB,OAAO,EAAE,kBAClC,OAAO,aAEpB,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,mCAAmC,iBAAa,MAAM,YAAE,IAAI,GAAO,CAAC,CAAC,CAAC,IAAI,EAChG,KAAK,CAAC,CAAC,CAAC,CACP,aAAI,SAAS,EAAC,sFAAsF,YACjG,KAAK,GACH,CACN,CAAC,CAAC,CAAC,IAAI,EACP,eAAe,CAAC,CAAC,CAAC,CACjB,YAAG,SAAS,EAAC,2FAA2F,YACrG,eAAe,GACd,CACL,CAAC,CAAC,CAAC,IAAI,EACP,IAAI,CAAC,CAAC,CAAC,CACN,YAAG,SAAS,EAAC,2FAA2F,YACrG,IAAI,GACH,CACL,CAAC,CAAC,CAAC,IAAI,EACP,QAAQ,EACR,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAC,MAAM,YACnB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,6KAA6K,EACvL,OAAO,EAAE,OAAO,iBACH,GAAG,MAAM,IAAI,cAAc,QAAQ,YAE/C,UAAU,GACJ,GACL,CACP,CAAC,CAAC,CAAC,IAAI,EACP,MAAM,CAAC,CAAC,CAAC,CACR,cAAK,SAAS,EAAC,MAAM,YACnB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,4JAA4J,EACtK,OAAO,EAAE,MAAM,CAAC,OAAO,iBACV,GAAG,MAAM,IAAI,cAAc,SAAS,YAEhD,MAAM,CAAC,KAAK,GACN,GACL,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CMP-0021 SegmentTabs — exclusive filter chrome (Radix-free; ≠ FilterChip).
|
|
3
|
+
*/
|
|
4
|
+
export interface SegmentTabItem {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly label: string;
|
|
7
|
+
readonly count?: number;
|
|
8
|
+
}
|
|
9
|
+
export type SegmentTabsVariant = 'default' | 'analytics' | 'sic';
|
|
10
|
+
export interface SegmentTabsProps {
|
|
11
|
+
readonly tabs: readonly SegmentTabItem[];
|
|
12
|
+
readonly activeId: string;
|
|
13
|
+
readonly onChange: (id: string) => void;
|
|
14
|
+
readonly ariaLabel?: string;
|
|
15
|
+
readonly className?: string;
|
|
16
|
+
readonly idPrefix?: string;
|
|
17
|
+
readonly variant?: SegmentTabsVariant;
|
|
18
|
+
readonly testId?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function SegmentTabs({ tabs, activeId, onChange, ariaLabel, className, idPrefix, variant, testId, }: SegmentTabsProps): JSX.Element;
|
|
21
|
+
//# sourceMappingURL=SegmentTabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentTabs.d.ts","sourceRoot":"","sources":["../../../src/ui/SegmentTabs/SegmentTabs.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,WAAW,GAAG,KAAK,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AA4CD,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,QAAoB,EACpB,OAAmB,EACnB,MAAuB,GACxB,EAAE,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAqChC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function tabListClass(variant, className) {
|
|
3
|
+
if (variant === 'analytics' || variant === 'sic') {
|
|
4
|
+
return ['mb-4 flex flex-wrap gap-1', className ?? ''].filter(Boolean).join(' ');
|
|
5
|
+
}
|
|
6
|
+
return [
|
|
7
|
+
'flex w-full flex-wrap gap-1 rounded-lg border border-[var(--color-border,var(--color-an-border))]',
|
|
8
|
+
'bg-[var(--color-surface-muted,var(--color-an-bg))] p-1',
|
|
9
|
+
className ?? '',
|
|
10
|
+
]
|
|
11
|
+
.filter(Boolean)
|
|
12
|
+
.join(' ');
|
|
13
|
+
}
|
|
14
|
+
function tabClass(variant, isActive) {
|
|
15
|
+
if (variant === 'analytics' || variant === 'sic') {
|
|
16
|
+
return [
|
|
17
|
+
'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',
|
|
18
|
+
isActive
|
|
19
|
+
? 'bg-[var(--color-an-primary,var(--color-action-primary))] text-white'
|
|
20
|
+
: 'bg-[var(--color-an-surface,var(--color-surface))] text-[var(--color-an-text-muted,var(--color-on-surface-muted))] hover:text-[var(--color-an-text,var(--color-on-surface))]',
|
|
21
|
+
].join(' ');
|
|
22
|
+
}
|
|
23
|
+
return [
|
|
24
|
+
'inline-flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-2 text-sm font-medium',
|
|
25
|
+
isActive
|
|
26
|
+
? 'bg-[var(--color-surface,var(--color-an-surface))] text-[var(--color-on-surface,var(--color-an-text))] shadow-sm'
|
|
27
|
+
: 'text-[var(--color-on-surface-muted,var(--color-an-text-muted))] hover:text-[var(--color-on-surface,var(--color-an-text))]',
|
|
28
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
|
|
29
|
+
'focus-visible:outline-[var(--color-accent,var(--color-an-primary))]',
|
|
30
|
+
].join(' ');
|
|
31
|
+
}
|
|
32
|
+
function countClass(variant, isActive) {
|
|
33
|
+
if ((variant === 'analytics' || variant === 'sic') && isActive) {
|
|
34
|
+
return 'inline-flex min-w-[1.25rem] items-center justify-center rounded-md bg-white/20 px-1.5 text-xs font-semibold tabular-nums';
|
|
35
|
+
}
|
|
36
|
+
return [
|
|
37
|
+
'inline-flex min-w-[1.25rem] items-center justify-center rounded-md px-1.5 text-xs font-semibold tabular-nums',
|
|
38
|
+
'bg-[var(--color-surface,var(--color-an-surface-muted,var(--color-an-bg)))] text-[var(--color-on-surface-muted,var(--color-an-text-muted))]',
|
|
39
|
+
].join(' ');
|
|
40
|
+
}
|
|
41
|
+
export function SegmentTabs({ tabs, activeId, onChange, ariaLabel, className, idPrefix = 'segment', variant = 'default', testId = 'segment-tabs', }) {
|
|
42
|
+
return (_jsx("div", { role: "tablist", "aria-label": ariaLabel, className: tabListClass(variant, className), "data-testid": testId, "data-variant": variant, children: tabs.map((tab) => {
|
|
43
|
+
const isActive = tab.id === activeId;
|
|
44
|
+
const tabId = `${idPrefix}-tab-${tab.id}`;
|
|
45
|
+
const panelId = `${idPrefix}-panel-${tab.id}`;
|
|
46
|
+
return (_jsx("button", { id: tabId, type: "button", role: "tab", "aria-selected": isActive, "aria-controls": panelId, tabIndex: isActive ? 0 : -1, className: tabClass(variant, isActive), "data-testid": `${testId}-tab-${tab.id}`, onClick: () => onChange(tab.id), children: _jsxs("span", { className: "inline-flex items-center gap-1.5", children: [tab.label, tab.count !== undefined ? (_jsx("span", { className: countClass(variant, isActive), children: tab.count })) : null] }) }, tab.id));
|
|
47
|
+
}) }));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=SegmentTabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentTabs.js","sourceRoot":"","sources":["../../../src/ui/SegmentTabs/SegmentTabs.tsx"],"names":[],"mappings":";AAuBA,SAAS,YAAY,CAAC,OAA2B,EAAE,SAAkB;IACnE,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACjD,OAAO,CAAC,2BAA2B,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClF,CAAC;IACD,OAAO;QACL,mGAAmG;QACnG,wDAAwD;QACxD,SAAS,IAAI,EAAE;KAChB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,OAA2B,EAAE,QAAiB;IAC9D,IAAI,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACjD,OAAO;YACL,8DAA8D;YAC9D,QAAQ;gBACN,CAAC,CAAC,qEAAqE;gBACvE,CAAC,CAAC,6KAA6K;SAClL,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;IACD,OAAO;QACL,iGAAiG;QACjG,QAAQ;YACN,CAAC,CAAC,iHAAiH;YACnH,CAAC,CAAC,2HAA2H;QAC/H,8EAA8E;QAC9E,qEAAqE;KACtE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,OAA2B,EAAE,QAAiB;IAChE,IAAI,CAAC,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC/D,OAAO,0HAA0H,CAAC;IACpI,CAAC;IACD,OAAO;QACL,8GAA8G;QAC9G,4IAA4I;KAC7I,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,QAAQ,GAAG,SAAS,EACpB,OAAO,GAAG,SAAS,EACnB,MAAM,GAAG,cAAc,GACN;IACjB,OAAO,CACL,cACE,IAAI,EAAC,SAAS,gBACF,SAAS,EACrB,SAAS,EAAE,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,iBAC9B,MAAM,kBACL,OAAO,YAEpB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAChB,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC;YACrC,MAAM,KAAK,GAAG,GAAG,QAAQ,QAAQ,GAAG,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,GAAG,QAAQ,UAAU,GAAG,CAAC,EAAE,EAAE,CAAC;YAC9C,OAAO,CACL,iBAEE,EAAE,EAAE,KAAK,EACT,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,QAAQ,mBACR,OAAO,EACtB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3B,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,iBACzB,GAAG,MAAM,QAAQ,GAAG,CAAC,EAAE,EAAE,EACtC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,YAE/B,gBAAM,SAAS,EAAC,kCAAkC,aAC/C,GAAG,CAAC,KAAK,EACT,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACzB,eAAM,SAAS,EAAE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAG,GAAG,CAAC,KAAK,GAAQ,CACnE,CAAC,CAAC,CAAC,IAAI,IACH,IAhBF,GAAG,CAAC,EAAE,CAiBJ,CACV,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SegmentTabItem } from './SegmentTabs.js';
|
|
2
|
+
/**
|
|
3
|
+
* CMP-0021 companion — overflow "+N" for dense admin tab rows (<1024px).
|
|
4
|
+
* Kept Radix-free; menu is a native details/summary pattern.
|
|
5
|
+
*/
|
|
6
|
+
export interface SegmentTabsOverflowProps {
|
|
7
|
+
readonly visibleTabs: readonly SegmentTabItem[];
|
|
8
|
+
readonly overflowTabs: readonly SegmentTabItem[];
|
|
9
|
+
readonly activeId: string;
|
|
10
|
+
readonly onChange: (id: string) => void;
|
|
11
|
+
readonly ariaLabel?: string;
|
|
12
|
+
readonly overflowLabel?: string;
|
|
13
|
+
readonly idPrefix?: string;
|
|
14
|
+
readonly className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function SegmentTabsOverflow({ visibleTabs, overflowTabs, activeId, onChange, ariaLabel, overflowLabel, idPrefix, className, }: SegmentTabsOverflowProps): JSX.Element;
|
|
17
|
+
//# sourceMappingURL=SegmentTabsOverflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentTabsOverflow.d.ts","sourceRoot":"","sources":["../../../src/ui/SegmentTabs/SegmentTabsOverflow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IAChD,QAAQ,CAAC,YAAY,EAAE,SAAS,cAAc,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,aAAwB,EACxB,QAA6B,EAC7B,SAAS,GACV,EAAE,wBAAwB,GAAG,GAAG,CAAC,OAAO,CA+ExC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
export function SegmentTabsOverflow({ visibleTabs, overflowTabs, activeId, onChange, ariaLabel, overflowLabel = '+ more', idPrefix = 'segment-overflow', className, }) {
|
|
4
|
+
const [open, setOpen] = useState(false);
|
|
5
|
+
const overflowActive = useMemo(() => overflowTabs.some((tab) => tab.id === activeId), [overflowTabs, activeId]);
|
|
6
|
+
return (_jsxs("div", { className: ['mb-4 flex flex-wrap items-center gap-1', className].filter(Boolean).join(' '), role: "tablist", "aria-label": ariaLabel, "data-testid": "segment-tabs-overflow", children: [visibleTabs.map((tab) => {
|
|
7
|
+
const isActive = tab.id === activeId;
|
|
8
|
+
return (_jsx("button", { id: `${idPrefix}-tab-${tab.id}`, type: "button", role: "tab", "aria-selected": isActive, tabIndex: isActive ? 0 : -1, className: [
|
|
9
|
+
'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',
|
|
10
|
+
isActive
|
|
11
|
+
? 'bg-[var(--color-an-primary,var(--color-action-primary))] text-white'
|
|
12
|
+
: 'bg-[var(--color-an-surface,var(--color-surface))] text-[var(--color-an-text-muted,var(--color-on-surface-muted))]',
|
|
13
|
+
].join(' '), onClick: () => onChange(tab.id), children: tab.label }, tab.id));
|
|
14
|
+
}), overflowTabs.length > 0 ? (_jsxs("div", { className: "relative", children: [_jsx("button", { type: "button", className: [
|
|
15
|
+
'rounded-md px-2 py-1.5 text-sm font-medium',
|
|
16
|
+
overflowActive
|
|
17
|
+
? 'bg-[var(--color-an-primary-soft,var(--color-surface-soft))] text-[var(--color-an-primary,var(--color-action-primary))]'
|
|
18
|
+
: 'text-[var(--color-an-text-muted,var(--color-on-surface-muted))]',
|
|
19
|
+
].join(' '), "aria-expanded": open, "aria-haspopup": "menu", onClick: () => setOpen((prev) => !prev), "data-testid": "segment-tabs-overflow-trigger", children: overflowLabel }), open ? (_jsx("ul", { role: "menu", className: "absolute z-20 mt-1 min-w-[10rem] rounded-md border border-[var(--color-an-border,var(--color-border))] bg-[var(--color-an-surface,var(--color-surface))] p-1 shadow-md", children: overflowTabs.map((tab) => (_jsx("li", { role: "none", children: _jsx("button", { type: "button", role: "menuitem", className: "block w-full rounded px-3 py-2 text-left text-sm hover:bg-[var(--color-an-bg,var(--color-surface-muted))]", onClick: () => {
|
|
20
|
+
onChange(tab.id);
|
|
21
|
+
setOpen(false);
|
|
22
|
+
}, children: tab.label }) }, tab.id))) })) : null] })) : null] }));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=SegmentTabsOverflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SegmentTabsOverflow.js","sourceRoot":"","sources":["../../../src/ui/SegmentTabs/SegmentTabsOverflow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAkB1C,MAAM,UAAU,mBAAmB,CAAC,EAClC,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,aAAa,GAAG,QAAQ,EACxB,QAAQ,GAAG,kBAAkB,EAC7B,SAAS,GACgB;IACzB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,OAAO,CAC5B,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,EACrD,CAAC,YAAY,EAAE,QAAQ,CAAC,CACzB,CAAC;IAEF,OAAO,CACL,eACE,SAAS,EAAE,CAAC,wCAAwC,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAC1F,IAAI,EAAC,SAAS,gBACF,SAAS,iBACT,uBAAuB,aAElC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC;gBACrC,OAAO,CACL,iBAEE,EAAE,EAAE,GAAG,QAAQ,QAAQ,GAAG,CAAC,EAAE,EAAE,EAC/B,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,QAAQ,EACvB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3B,SAAS,EAAE;wBACT,8DAA8D;wBAC9D,QAAQ;4BACN,CAAC,CAAC,qEAAqE;4BACvE,CAAC,CAAC,mHAAmH;qBACxH,CAAC,IAAI,CAAC,GAAG,CAAC,EACX,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,YAE9B,GAAG,CAAC,KAAK,IAdL,GAAG,CAAC,EAAE,CAeJ,CACV,CAAC;YACJ,CAAC,CAAC,EACD,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACzB,eAAK,SAAS,EAAC,UAAU,aACvB,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE;4BACT,4CAA4C;4BAC5C,cAAc;gCACZ,CAAC,CAAC,wHAAwH;gCAC1H,CAAC,CAAC,iEAAiE;yBACtE,CAAC,IAAI,CAAC,GAAG,CAAC,mBACI,IAAI,mBACL,MAAM,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,iBAC3B,+BAA+B,YAE1C,aAAa,GACP,EACR,IAAI,CAAC,CAAC,CAAC,CACN,aACE,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,wKAAwK,YAEjL,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACzB,aAAiB,IAAI,EAAC,MAAM,YAC1B,iBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,UAAU,EACf,SAAS,EAAC,2GAA2G,EACrH,OAAO,EAAE,GAAG,EAAE;oCACZ,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oCACjB,OAAO,CAAC,KAAK,CAAC,CAAC;gCACjB,CAAC,YAEA,GAAG,CAAC,KAAK,GACH,IAXF,GAAG,CAAC,EAAE,CAYV,CACN,CAAC,GACC,CACN,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type SelectSurface = 'admin' | 'customer' | 'kiosk' | 'pickup';
|
|
2
|
+
export interface SelectOption {
|
|
3
|
+
readonly value: string;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface SelectProps {
|
|
8
|
+
readonly id?: string;
|
|
9
|
+
readonly options: readonly SelectOption[];
|
|
10
|
+
readonly value?: string;
|
|
11
|
+
readonly onValueChange: (value: string) => void;
|
|
12
|
+
readonly disabled?: boolean;
|
|
13
|
+
readonly placeholder?: string;
|
|
14
|
+
readonly className?: string;
|
|
15
|
+
readonly triggerClassName?: string;
|
|
16
|
+
readonly contentClassName?: string;
|
|
17
|
+
readonly surface?: SelectSurface;
|
|
18
|
+
readonly testId?: string;
|
|
19
|
+
readonly itemTestIdPrefix?: string;
|
|
20
|
+
readonly name?: string;
|
|
21
|
+
readonly 'aria-busy'?: boolean;
|
|
22
|
+
readonly 'aria-label'?: string;
|
|
23
|
+
readonly 'aria-labelledby'?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Shared Select API (CMP-0005 / Q24=C).
|
|
27
|
+
* Radix is an implementation detail — apps must not import `@radix-ui/react-select` for new UI.
|
|
28
|
+
*/
|
|
29
|
+
export declare const Select: import("react").ForwardRefExoticComponent<SelectProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
30
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/ui/Select/Select.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAyFD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAoBD;;;GAGG;AACH,eAAO,MAAM,MAAM,2GAwEjB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as RadixSelect from '@radix-ui/react-select';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import { tv } from '../tvShim.js';
|
|
5
|
+
const selectRecipe = tv({
|
|
6
|
+
slots: {
|
|
7
|
+
trigger: [
|
|
8
|
+
'inline-flex min-h-[44px] min-w-[44px] items-center justify-between gap-2',
|
|
9
|
+
'rounded-lg border px-3 text-left touch-manipulation',
|
|
10
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
|
|
11
|
+
'disabled:cursor-not-allowed disabled:opacity-60',
|
|
12
|
+
].join(' '),
|
|
13
|
+
icon: 'h-4 w-4 shrink-0',
|
|
14
|
+
content: 'z-50 overflow-hidden rounded-lg border shadow-lg',
|
|
15
|
+
viewport: 'max-h-64 p-1',
|
|
16
|
+
item: [
|
|
17
|
+
'relative flex min-h-[44px] min-w-[44px] cursor-pointer select-none items-center',
|
|
18
|
+
'rounded-md px-3 py-2 outline-none',
|
|
19
|
+
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
20
|
+
'data-[state=checked]:font-semibold',
|
|
21
|
+
].join(' '),
|
|
22
|
+
},
|
|
23
|
+
variants: {
|
|
24
|
+
surface: {
|
|
25
|
+
admin: {
|
|
26
|
+
trigger: [
|
|
27
|
+
'border-[var(--color-an-border)] bg-[var(--color-an-surface)]',
|
|
28
|
+
'text-sm text-[var(--color-an-text)]',
|
|
29
|
+
'focus-visible:outline-[var(--color-an-primary)]',
|
|
30
|
+
].join(' '),
|
|
31
|
+
icon: 'text-[var(--color-an-text-muted)]',
|
|
32
|
+
content: 'border-[var(--color-an-border)] bg-[var(--color-an-surface)] text-[var(--color-an-text)]',
|
|
33
|
+
item: [
|
|
34
|
+
'text-sm text-[var(--color-an-text)]',
|
|
35
|
+
'data-[highlighted]:bg-[var(--color-an-primary-soft)] data-[highlighted]:text-[var(--color-an-primary)]',
|
|
36
|
+
].join(' '),
|
|
37
|
+
},
|
|
38
|
+
customer: {
|
|
39
|
+
trigger: [
|
|
40
|
+
'border-[var(--color-border)] bg-[var(--color-surface)]',
|
|
41
|
+
'text-base text-[var(--color-on-surface)]',
|
|
42
|
+
'focus-visible:outline-[var(--color-focus-ring)]',
|
|
43
|
+
].join(' '),
|
|
44
|
+
icon: 'text-[var(--color-on-surface-muted)]',
|
|
45
|
+
content: 'border-[var(--color-border)] bg-[var(--color-surface)] text-[var(--color-on-surface)]',
|
|
46
|
+
item: [
|
|
47
|
+
'text-sm text-[var(--color-on-surface)]',
|
|
48
|
+
'data-[highlighted]:bg-[var(--brand-consumer-accent-soft)] data-[highlighted]:text-[var(--brand-consumer-accent)]',
|
|
49
|
+
].join(' '),
|
|
50
|
+
},
|
|
51
|
+
kiosk: {
|
|
52
|
+
trigger: [
|
|
53
|
+
'border-[var(--color-border)] bg-[var(--color-surface)]',
|
|
54
|
+
'text-base text-[var(--color-on-surface)]',
|
|
55
|
+
'focus-visible:outline-[var(--color-focus-ring)]',
|
|
56
|
+
].join(' '),
|
|
57
|
+
icon: 'text-[var(--color-on-surface-muted)]',
|
|
58
|
+
content: 'border-[var(--color-border)] bg-[var(--color-surface)] text-[var(--color-on-surface)]',
|
|
59
|
+
item: [
|
|
60
|
+
'text-base text-[var(--color-on-surface)]',
|
|
61
|
+
'data-[highlighted]:bg-[var(--color-surface-muted)] data-[highlighted]:text-[var(--color-on-surface)]',
|
|
62
|
+
].join(' '),
|
|
63
|
+
},
|
|
64
|
+
pickup: {
|
|
65
|
+
trigger: [
|
|
66
|
+
'border-[var(--color-border)] bg-[var(--color-surface)]',
|
|
67
|
+
'text-sm text-[var(--color-on-surface)]',
|
|
68
|
+
'focus-visible:outline-[var(--color-focus-ring)]',
|
|
69
|
+
].join(' '),
|
|
70
|
+
icon: 'text-[var(--color-on-surface-muted)]',
|
|
71
|
+
content: [
|
|
72
|
+
'z-[var(--pickup-z-80,80)] border-[var(--color-border)]',
|
|
73
|
+
'bg-[var(--color-surface)] text-[var(--color-on-surface)]',
|
|
74
|
+
].join(' '),
|
|
75
|
+
item: [
|
|
76
|
+
'text-sm text-[var(--color-on-surface)]',
|
|
77
|
+
'data-[highlighted]:bg-[var(--brand-consumer-accent-soft)] data-[highlighted]:text-[var(--brand-consumer-accent)]',
|
|
78
|
+
].join(' '),
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
defaultVariants: {
|
|
83
|
+
surface: 'customer',
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
function ChevronIcon({ className }) {
|
|
87
|
+
return (_jsx("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, focusable: "false", children: _jsx("path", { d: "M6 9l6 6 6-6" }) }));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Shared Select API (CMP-0005 / Q24=C).
|
|
91
|
+
* Radix is an implementation detail — apps must not import `@radix-ui/react-select` for new UI.
|
|
92
|
+
*/
|
|
93
|
+
export const Select = forwardRef(function Select({ id, options, value, onValueChange, disabled = false, placeholder, className, triggerClassName, contentClassName, surface = 'customer', testId = 'select-trigger', itemTestIdPrefix, name, 'aria-busy': ariaBusy, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, }, ref) {
|
|
94
|
+
const slots = selectRecipe({ surface: surface });
|
|
95
|
+
const resolvedValue = value !== undefined && value !== '' ? value : undefined;
|
|
96
|
+
return (_jsxs(RadixSelect.Root, { value: resolvedValue, disabled: disabled || options.length === 0, name: name, onValueChange: onValueChange, children: [_jsxs(RadixSelect.Trigger, { ref: ref, id: id, className: slots.trigger({ className: [triggerClassName, className].filter(Boolean).join(' ') }), "data-testid": testId, "aria-busy": ariaBusy || undefined, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children: [_jsx(RadixSelect.Value, { placeholder: placeholder }), _jsx(RadixSelect.Icon, { children: _jsx(ChevronIcon, { className: slots.icon() }) })] }), _jsx(RadixSelect.Portal, { children: _jsx(RadixSelect.Content, { className: slots.content({ className: contentClassName }), position: "popper", sideOffset: 4, children: _jsx(RadixSelect.Viewport, { className: slots.viewport(), children: options.map((option) => (_jsx(RadixSelect.Item, { value: option.value, disabled: option.disabled, className: slots.item(), "data-testid": itemTestIdPrefix !== undefined
|
|
97
|
+
? `${itemTestIdPrefix}${option.value}`
|
|
98
|
+
: undefined, children: _jsx(RadixSelect.ItemText, { children: option.label }) }, option.value))) }) }) })] }));
|
|
99
|
+
});
|
|
100
|
+
Select.displayName = 'Select';
|
|
101
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../../../src/ui/Select/Select.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/Select/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC"}
|