@alfadocs/ui-kit-debug 0.97.2 → 0.98.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/_chunks/{booking-BSpSMmJ2.js → booking-Bhbvef95.js} +2 -2
- package/dist/_chunks/{booking-BSpSMmJ2.js.map → booking-Bhbvef95.js.map} +1 -1
- package/dist/_chunks/{document-preview-DXl9migE.js → document-preview-DXsCEj4U.js} +2 -2
- package/dist/_chunks/{document-preview-DXl9migE.js.map → document-preview-DXsCEj4U.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-flfZh2qY.js → link-cell-renderer-Bt-mXeQY.js} +2 -2
- package/dist/_chunks/{link-cell-renderer-flfZh2qY.js.map → link-cell-renderer-Bt-mXeQY.js.map} +1 -1
- package/dist/_chunks/{multi-select-D5QLBJM1.js → multi-select-CC52Qws6.js} +275 -263
- package/dist/_chunks/multi-select-CC52Qws6.js.map +1 -0
- package/dist/_chunks/{muscle-scheme-CFBE2dme.js → muscle-scheme-kgCX5qfO.js} +2 -2
- package/dist/_chunks/{muscle-scheme-CFBE2dme.js.map → muscle-scheme-kgCX5qfO.js.map} +1 -1
- package/dist/_chunks/{notes-panel-BLjlYBt-.js → notes-panel-BKwd-bOV.js} +2 -2
- package/dist/_chunks/{notes-panel-BLjlYBt-.js.map → notes-panel-BKwd-bOV.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-vn1H4xWj.js → patient-summary-card-C-iVDo53.js} +4 -2
- package/dist/_chunks/{patient-summary-card-vn1H4xWj.js.map → patient-summary-card-C-iVDo53.js.map} +1 -1
- package/dist/_chunks/{patient-table-CvZTIM2R.js → patient-table-QEVsFvwq.js} +2 -2
- package/dist/_chunks/{patient-table-CvZTIM2R.js.map → patient-table-QEVsFvwq.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-rX_VA6hd.js → public-header.agent-_8W9biCO.js} +4 -2
- package/dist/_chunks/public-header.agent-_8W9biCO.js.map +1 -0
- package/dist/_chunks/{rich-text-editor-RRkBN_WB.js → rich-text-editor-DHpV2q6d.js} +4 -4
- package/dist/_chunks/rich-text-editor-DHpV2q6d.js.map +1 -0
- package/dist/_chunks/{sign-document-DI561d1C.js → sign-document-cH9CboWB.js} +2 -2
- package/dist/_chunks/{sign-document-DI561d1C.js.map → sign-document-cH9CboWB.js.map} +1 -1
- package/dist/_chunks/{signature-capture-DN52VNKL.js → signature-capture-D6ut9_IR.js} +2 -2
- package/dist/_chunks/signature-capture-D6ut9_IR.js.map +1 -0
- package/dist/_chunks/{tabs-CVTukWRD.js → tabs-CBb2AidH.js} +17 -17
- package/dist/_chunks/tabs-CBb2AidH.js.map +1 -0
- package/dist/_chunks/{warning-stack-CAHQ0xxS.js → warning-stack-DKeAfj5M.js} +3 -3
- package/dist/_chunks/warning-stack-DKeAfj5M.js.map +1 -0
- package/dist/agent-catalog.json +291 -1
- package/dist/agent-i18n/en.json +23 -0
- package/dist/components/booking/index.js +1 -1
- package/dist/components/data-table/index.js +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/multi-select/index.js +1 -1
- package/dist/components/multi-select/multi-select.d.ts.map +1 -1
- package/dist/components/muscle-scheme/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-summary-card/patient-summary-card.d.ts.map +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/public-header/public-header.d.ts.map +1 -1
- package/dist/components/rich-text-editor/editor-toolbar.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/sign-document/index.js +1 -1
- package/dist/components/signature-capture/index.js +1 -1
- package/dist/components/signature-capture/signature-capture.d.ts.map +1 -1
- package/dist/components/skeleton-scheme/index.js +1 -1
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/tabs/tabs.d.ts.map +1 -1
- package/dist/components/warning-stack/index.js +1 -1
- package/dist/components/warning-stack/warning-stack.d.ts.map +1 -1
- package/dist/host-compat.css +578 -0
- package/dist/index.js +14 -14
- package/dist/tokens.css +1 -1
- package/package.json +10 -3
- package/dist/_chunks/multi-select-D5QLBJM1.js.map +0 -1
- package/dist/_chunks/public-header.agent-rX_VA6hd.js.map +0 -1
- package/dist/_chunks/rich-text-editor-RRkBN_WB.js.map +0 -1
- package/dist/_chunks/signature-capture-DN52VNKL.js.map +0 -1
- package/dist/_chunks/tabs-CVTukWRD.js.map +0 -1
- package/dist/_chunks/warning-stack-CAHQ0xxS.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signature-capture-DN52VNKL.js","sources":["../../src/components/signature-capture/signature-capture.agent.ts","../../src/components/signature-capture/signature-capture.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { SignatureCaptureHandle } from './signature-capture';\n\nexport const signatureCaptureAgent: AgentAdapter<SignatureCaptureHandle> = {\n id: 'signature-capture',\n // Multi-step media lifecycle: draw / type strokes (capture) then commit the\n // serialised signature (submit).\n capabilities: ['capture', 'submit'],\n state: {\n isEmpty: {\n type: 'boolean',\n descriptionKey: 'ui.agent.signatureCapture.state.isEmpty',\n description: 'True when no signature has been drawn or typed.',\n read: (handle) => handle.isEmpty(),\n },\n },\n actions: {\n clear: {\n // Erases all captured strokes — destructive (loses drawn/typed input).\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.signatureCapture.actions.clear',\n description: 'Erase the current signature. Loses unsaved input.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n undo: {\n // Removes the last stroke — reversible by redrawing.\n safety: 'write',\n descriptionKey: 'ui.agent.signatureCapture.actions.undo',\n description: 'Undo the last stroke.',\n invoke: (handle) => {\n handle.undo();\n },\n },\n confirm: {\n // Commits the captured media and returns its serialised payload.\n safety: 'write',\n returns: 'SignatureConfirmPayload | null',\n returnsSchema: {\n oneOf: [\n {\n type: 'object',\n description: 'The committed signature payload.',\n properties: {\n dataUrl: {\n type: 'string',\n description: 'PNG data URL of the captured signature.',\n },\n capturedAt: {\n type: 'string',\n description: 'ISO-8601 UTC timestamp of the commit.',\n },\n },\n required: ['dataUrl'],\n },\n {\n type: 'null',\n description: 'Returned when the pad is empty.',\n },\n ],\n },\n descriptionKey: 'ui.agent.signatureCapture.actions.confirm',\n description: 'Commit the signature and return its serialised payload.',\n invoke: (handle) => handle.confirm(),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'signature-capture' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* SignatureCapture — thin React wrapper over signature_pad. */\n/* */\n/* - Library: `signature_pad` (08-third-party §Signature Pad). We */\n/* instantiate one pad per mounted canvas and expose imperative */\n/* clear / undo / isEmpty / confirm verbs to the consumer. */\n/* - Colors: `penColor` / `backgroundColor` default to */\n/* `--foreground` / `--background` via `getComputedStyle()`. Theme */\n/* switches are observed via a MutationObserver on `<html class>` */\n/* so the ink recolours when the theme flips. */\n/* - DPR scaling: canvas attribute `width/height = cssSize * DPR`; the */\n/* 2D context is scaled by the same factor. A `ResizeObserver` */\n/* replays strokes via `fromData()` on re-scale so nothing is lost. */\n/* - Typed fallback: keyboard-only path renders a text input styled in */\n/* italic `var(--font-sans)` (per 23-constraints §10 — serif is */\n/* marketing only). On confirm we render the string to an offscreen */\n/* canvas for the PNG/SVG export. */\n/* - Confirm payload: `{ png, svg, widthMm, heightMm, capturedAt, */\n/* sha256, strokes? }`. `sha256` is the SubtleCrypto digest of the */\n/* PNG bytes — tamper-evident for audit trails. */\n/* - Security: no `fetch` / `XMLHttpRequest` / `localStorage` / */\n/* `sessionStorage` in this file — the consumer owns persistence. */\n/* */\n/* TODO: */\n/* - 3× DPI re-render for print: currently `toDataURL('image/png')` */\n/* exports the live canvas (already at DPR). A proper 300-DPI */\n/* pipeline would create an offscreen canvas at `cssSize × 3` and */\n/* replay strokes via `fromData()` — deferred pending the print */\n/* bridge landing. */\n/* - Typed-fallback canvas font can't read CSS variables directly */\n/* (Canvas2D resolves fonts at paint time and won't expand */\n/* `var(--font-size-2xl)`); we use a fixed `32px italic` + the */\n/* user's font stack, which is visually close but not */\n/* theme-reactive. Will migrate once the typography tokens expose */\n/* a resolved `font` shorthand. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from 'react';\nimport SignaturePad from 'signature_pad';\nimport type { PointGroup } from 'signature_pad';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Check, Eraser, PenLine, Type } from 'lucide-react';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { signatureCaptureAgent } from './signature-capture.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface SignatureConfirmPayload {\n /** Data URL of the captured signature rendered as PNG. */\n png: string;\n /** SVG string trimmed to the stroke bounding box. */\n svg: string;\n /** Physical width in millimetres, derived from CSS px. */\n widthMm: number;\n /** Physical height in millimetres, derived from CSS px. */\n heightMm: number;\n /** ISO-8601 UTC timestamp for when `confirm()` resolved. */\n capturedAt: string;\n /** Hex-encoded SHA-256 digest of the PNG bytes. */\n sha256: string;\n /** Raw stroke data from `signature_pad.toData()` — optional for replays. */\n strokes?: PointGroup[];\n}\n\nexport interface SignatureCaptureProps {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Called with the export payload when the user confirms the signature. */\n onConfirm?: (payload: SignatureConfirmPayload) => void;\n /** Called after the pad is cleared (explicit user action). */\n onClear?: () => void;\n /** Called when the user starts drawing a new stroke. */\n onStart?: () => void;\n /** CSS width of the pad. Default 400. */\n width?: number | string;\n /** CSS height of the pad. Default 200. */\n height?: number | string;\n /** Pen colour override — defaults to `var(--foreground)`. */\n penColor?: string;\n /** Background override — defaults to `var(--background)`. */\n backgroundColor?: string;\n /** Show the typed-name fallback toggle. Default `true`. */\n allowTypedFallback?: boolean;\n /**\n * When set, on confirm() the captured PNG data URL is written into a hidden\n * `<input name={name}>` so consumers can POST the signature declaratively.\n * The PNG data URL satisfies the server's `data:image/png` prefix check.\n * Default off.\n */\n name?: string;\n /** Disable the entire component. */\n disabled?: boolean;\n /** Accessible label for the pad region. */\n ariaLabel?: string;\n /** Extra class names on the wrapper. */\n className?: string;\n}\n\nexport interface SignatureCaptureHandle {\n clear: () => void;\n undo: () => void;\n isEmpty: () => boolean;\n confirm: () => Promise<SignatureConfirmPayload | null>;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst wrapperVariants = cva(\n [\n 'ds:signature-capture-alfadocs ds:flex ds:flex-col',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--card-border)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:[.theme-accessible_&]:border-2',\n 'ds:p-[var(--spacing-sm)]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst padFrameVariants = cva(\n [\n 'ds:relative ds:block',\n // Mobile-first: fill the available width but never exceed the configured\n // pad width. Arbitrary-property form because `inline-size-[…]` /\n // `block-size-[…]` named utilities emit no CSS here (see canvasVariants).\n 'ds:[inline-size:100%]',\n 'ds:[max-inline-size:var(--signature-width)]',\n 'ds:[block-size:var(--signature-height)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)]',\n 'ds:overflow-hidden',\n 'ds:touch-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\nconst canvasVariants = cva(\n [\n 'ds:block',\n // Arbitrary-property form, NOT `inline-size-full` / `block-size-full`:\n // the `inline-size-*` / `block-size-*` named utilities generate no CSS in\n // this Tailwind setup, so on a block <div> they silently fall back to auto\n // (harmless) but on a replaced <canvas> the element then sizes to its\n // backing-store `width`/`height` attribute — which scaleCanvas drives up to\n // MAX_CANVAS_PX (4096) in a feedback loop, overflowing the pad on mobile.\n // The `[property:value]` escape hatch always emits, pinning the canvas to\n // the frame so the loop can't run away.\n 'ds:[inline-size:100%]',\n 'ds:[block-size:100%]',\n 'ds:touch-none',\n 'ds:select-none',\n ].join(' '),\n);\n\n// The toolbar is a named container: below 30rem the action captions hide and\n// the buttons fall back to their icons (one compact row instead of wrapped\n// text), so the row works inside a phone-width Dialog. At the default pad\n// width (400px = 25rem) the toolbar stays icon-only; stretched to a desktop\n// dialog (width=\"100%\" in a size=\"lg\" Dialog, ~37rem) the captions appear.\n// aria-labels keep the full names regardless of width.\nconst toolbarVariants = cva(\n [\n 'ds:@container/sigactions',\n 'ds:flex ds:items-stretch ds:flex-wrap ds:gap-[var(--spacing-sm)]',\n ].join(' '),\n);\n\n// Caption span inside each toolbar action — hidden until the toolbar\n// container is wide enough for all three text labels on one row.\nconst actionCaptionVariants = cva('ds:hidden ds:@[30rem]/sigactions:inline');\n\n// Toolbar actions are sized for thumbs: they grow to fill the pad width\n// (`flex-1`), sit above the 44/48px floor, and use base-size text so they read\n// clearly on a phone.\nconst actionButtonVariants = cva(\n [\n 'ds:inline-flex ds:flex-1 ds:items-center ds:justify-center',\n 'ds:[min-block-size:var(--min-target-size)]',\n 'ds:[min-inline-size:var(--min-target-size)]',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-transparent ds:text-[var(--foreground)]',\n 'ds:text-[length:var(--font-size-base)] ds:font-medium',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-[var(--muted)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst confirmButtonVariants = cva(\n [\n 'ds:inline-flex ds:flex-1 ds:items-center ds:justify-center',\n 'ds:[min-block-size:var(--min-target-size)]',\n 'ds:[min-inline-size:var(--min-target-size)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]',\n 'ds:text-[length:var(--font-size-base)] ds:font-medium',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:hover:bg-[var(--primary-hover)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n);\n\nconst typedInputVariants = cva(\n [\n 'ds:block ds:inline-size-full',\n 'ds:[min-block-size:var(--min-target-size)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:font-[family-name:var(--font-sans)]',\n 'ds:italic',\n 'ds:tracking-[0.1em]',\n 'ds:text-[length:var(--font-size-lg)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\nconst typedPreviewVariants = cva(\n [\n 'ds:flex ds:items-center ds:justify-center',\n // Match the pad frame: responsive width capped at the configured size.\n // Arbitrary-property form (the named `*-size-[…]` utilities are no-ops here).\n 'ds:[inline-size:100%]',\n 'ds:[max-inline-size:var(--signature-width)]',\n 'ds:[block-size:var(--signature-height)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border ds:border-[color:var(--card-border)]',\n 'ds:[.theme-accessible_&]:border-2',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:font-[family-name:var(--font-sans)]',\n 'ds:italic',\n 'ds:tracking-[0.1em]',\n 'ds:text-[length:var(--font-size-2xl)]',\n 'ds:p-[var(--spacing-md)]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\ntype SignatureState = 'empty' | 'drawing' | 'captured' | 'cleared';\n\n/**\n * Resolve a CSS custom property against `document.documentElement`. We\n * can't pass `var(--foreground)` to signature_pad directly — the lib\n * stamps the string straight into `ctx.strokeStyle`, which only accepts\n * concrete colour values. Looking the variable up at runtime keeps the\n * component in tokens-only compliance.\n */\nfunction resolveCssVar(name: string): string {\n if (typeof document === 'undefined') return '';\n const value = getComputedStyle(document.documentElement)\n .getPropertyValue(name)\n .trim();\n return value;\n}\n\nfunction toCssSize(v: number | string | undefined, fallback: string): string {\n if (typeof v === 'number') return `${v}px`;\n if (typeof v === 'string' && v.length > 0) return v;\n return fallback;\n}\n\n/**\n * Parse a pixel value, returning `null` for non-pixel strings (e.g.\n * \"100%\", \"50vw\") so the caller can fall back to the measured rect.\n * parseFloat(\"100%\") would silently return 100 — a 100mm-wide export\n * masquerading as 26mm. Allow only digits, dot, minus, whitespace, \"px\".\n */\nfunction parsePxValue(v: string): number | null {\n if (typeof v === 'string' && /[^0-9.\\s\\-px]/i.test(v)) return null;\n const n = parseFloat(v);\n if (!Number.isFinite(n)) return null;\n return n;\n}\n\n/** Hex-encode a Uint8Array. */\nfunction toHex(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 1) {\n const b = bytes[i];\n out += b.toString(16).padStart(2, '0');\n }\n return out;\n}\n\n/** Decode a base64 string into bytes without `atob` polyfills. */\nfunction base64ToBytes(b64: string): Uint8Array {\n if (typeof atob === 'function') {\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i += 1) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n // Fallback — node-style Buffer, gated behind a runtime check.\n const g = globalThis as {\n Buffer?: { from: (s: string, enc: string) => Uint8Array };\n };\n if (g.Buffer) return g.Buffer.from(b64, 'base64');\n return new Uint8Array();\n}\n\nasync function sha256Hex(bytes: Uint8Array): Promise<string> {\n const g = globalThis as { crypto?: Crypto };\n if (g.crypto?.subtle) {\n // Copy the bytes into a fresh ArrayBuffer so the slice is always an\n // ArrayBuffer (never a SharedArrayBuffer) — SubtleCrypto's BufferSource\n // narrowing doesn't accept the latter.\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n const digest = await g.crypto.subtle.digest('SHA-256', copy.buffer);\n return toHex(new Uint8Array(digest));\n }\n // No subtle crypto — return empty so callers can still use the rest\n // of the payload. Test env is expected to stub crypto.subtle.\n return '';\n}\n\n/**\n * Render the typed fallback string onto an offscreen canvas and return\n * it. Used by the confirm path when the user has typed their name\n * instead of drawing. Size is fixed at `32px italic` because Canvas2D\n * resolves fonts eagerly and can't expand `var(--font-size-*)`.\n */\nfunction renderTypedSignatureToCanvas(\n text: string,\n cssWidth: number,\n cssHeight: number,\n penColor: string,\n backgroundColor: string,\n): HTMLCanvasElement {\n const dpr = Math.max(\n 1,\n typeof window !== 'undefined' ? window.devicePixelRatio : 1,\n );\n const canvas = document.createElement('canvas');\n canvas.width = Math.floor(cssWidth * dpr);\n canvas.height = Math.floor(cssHeight * dpr);\n const ctx = canvas.getContext('2d');\n if (!ctx) return canvas;\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n // Fill background with the token-resolved colour.\n ctx.fillStyle = backgroundColor || 'transparent';\n ctx.fillRect(0, 0, cssWidth, cssHeight);\n // Draw the typed signature centred.\n ctx.fillStyle = penColor || 'currentColor';\n ctx.font = '32px italic sans-serif';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(text, cssWidth / 2, cssHeight / 2, cssWidth - 16);\n return canvas;\n}\n\n/* ------------------------------------------------------------------ */\n/* SignatureCapture */\n/* ------------------------------------------------------------------ */\n\nexport const SignatureCapture = forwardRef<\n SignatureCaptureHandle,\n SignatureCaptureProps\n>(\n (\n {\n id,\n onConfirm,\n onClear,\n onStart,\n width = 400,\n height = 200,\n penColor,\n backgroundColor,\n allowTypedFallback = true,\n name,\n disabled = false,\n ariaLabel,\n className,\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const rawId = useId();\n const idSafe = useMemo(\n () => `sig-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}`,\n [rawId],\n );\n const liveRegionId = `${idSafe}-live`;\n\n const wrapperRef = useRef<HTMLDivElement>(null);\n const padFrameRef = useRef<HTMLDivElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const typedPreviewRef = useRef<HTMLDivElement>(null);\n const signaturePadRef = useRef<SignaturePad | null>(null);\n\n const [mode, setMode] = useState<'draw' | 'typed'>('draw');\n const [typedValue, setTypedValue] = useState('');\n // Mirrors the last confirmed PNG data URL into a hidden form field when\n // `name` is set, so consumers can POST the signature declaratively.\n const [boundValue, setBoundValue] = useState('');\n // Tracks whether the pad has any ink — gates the Confirm button.\n // signature_pad's isEmpty() is a sync ref read and won't trigger\n // re-renders; this state mirrors it so React sees the change.\n const [padHasInk, setPadHasInk] = useState(false);\n // Retained state — consumers may subscribe to the pad's lifecycle via\n // `onConfirm`/`onClear`/`onStart`; we still track the machine internally\n // so the live region + confirm button stay coherent.\n const signatureStateRef = useRef<SignatureState>('empty');\n const [announcement, setAnnouncement] = useState<string>('');\n const [resolvedPen, setResolvedPen] = useState<string>('');\n const [resolvedBg, setResolvedBg] = useState<string>('');\n\n // Stable callback refs so we can wire signature_pad once without\n // re-instantiating on every render.\n const onStartRef = useRef<SignatureCaptureProps['onStart']>(onStart);\n const onClearRef = useRef<SignatureCaptureProps['onClear']>(onClear);\n const onConfirmRef = useRef<SignatureCaptureProps['onConfirm']>(onConfirm);\n useEffect(() => {\n onStartRef.current = onStart;\n onClearRef.current = onClear;\n onConfirmRef.current = onConfirm;\n }, [onStart, onClear, onConfirm]);\n\n /* ---- Announce helper ---------------------------------------- */\n const announce = useCallback(\n (next: SignatureState) => {\n signatureStateRef.current = next;\n setAnnouncement(t(`signature.state.${next}`));\n },\n [t],\n );\n\n /* ---- Resolve tokens ----------------------------------------- */\n useEffect(() => {\n if (typeof document === 'undefined') return undefined;\n function resolveAll(): void {\n const pen = penColor ?? resolveCssVar('--foreground');\n const bg = backgroundColor ?? resolveCssVar('--background');\n // Fall back to `currentColor` / `transparent` — keyword literals\n // are token-neutral and honour the surrounding theme even when\n // the CSS variable is briefly unavailable (SSR, initial paint).\n setResolvedPen(pen || 'currentColor');\n setResolvedBg(bg || 'transparent');\n }\n resolveAll();\n // Watch for theme-class changes on <html>.\n const mo = new MutationObserver(() => {\n resolveAll();\n });\n mo.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class'],\n });\n return () => mo.disconnect();\n }, [penColor, backgroundColor]);\n\n /* ---- Apply colour changes to an existing pad ---------------- */\n useEffect(() => {\n const pad = signaturePadRef.current;\n if (!pad) return;\n if (resolvedPen) pad.penColor = resolvedPen;\n if (resolvedBg) pad.backgroundColor = resolvedBg;\n }, [resolvedPen, resolvedBg]);\n\n /* ---- Instantiate signature_pad ------------------------------ */\n useEffect(() => {\n if (mode !== 'draw') return undefined;\n const canvas = canvasRef.current;\n if (!canvas) return undefined;\n\n const pad = new SignaturePad(canvas, {\n penColor: resolvedPen || 'currentColor',\n backgroundColor: resolvedBg || 'transparent',\n minWidth: 0.5,\n maxWidth: 2.5,\n velocityFilterWeight: 0.7,\n });\n signaturePadRef.current = pad;\n\n const handleBegin = (): void => {\n setPadHasInk(true);\n announce('drawing');\n onStartRef.current?.();\n };\n const handleEnd = (): void => {\n // Keep state as 'drawing' — transition to 'captured' on confirm.\n };\n pad.addEventListener('beginStroke', handleBegin);\n pad.addEventListener('endStroke', handleEnd);\n\n // Initial DPR scale + announcement.\n scaleCanvas(canvas);\n announce('empty');\n\n return () => {\n pad.removeEventListener('beginStroke', handleBegin);\n pad.removeEventListener('endStroke', handleEnd);\n // Clear strokes from memory; 08-third-party §Signature Pad.\n pad.clear();\n pad.off();\n signaturePadRef.current = null;\n };\n // We intentionally re-create the pad only when switching between\n // typed and draw modes. Color updates flow through the effect above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [mode]);\n\n /* ---- Disabled state ----------------------------------------- */\n useEffect(() => {\n const pad = signaturePadRef.current;\n if (!pad) return;\n if (disabled) pad.off();\n else pad.on();\n }, [disabled, mode]);\n\n /* ---- DPR + ResizeObserver ----------------------------------- */\n // Hard-cap backing-store dimensions to bound memory. 4096 px × 4096 px at\n // 4 bytes per pixel is ~67 MB — generous for any realistic signature, but\n // well under the multi-GB allocation a careless or malicious prop could\n // request on a high-DPR display. See security-hardening.mdx.\n const MAX_CANVAS_PX = 4096;\n const scaleCanvas = useCallback(\n (canvas: HTMLCanvasElement) => {\n const rect = canvas.getBoundingClientRect();\n const dpr = Math.max(\n 1,\n typeof window !== 'undefined' ? window.devicePixelRatio : 1,\n );\n const rawWidth = Math.max(1, Math.floor(rect.width * dpr));\n const rawHeight = Math.max(1, Math.floor(rect.height * dpr));\n const targetWidth = Math.min(rawWidth, MAX_CANVAS_PX);\n const targetHeight = Math.min(rawHeight, MAX_CANVAS_PX);\n if (\n import.meta.env.DEV &&\n (rawWidth !== targetWidth || rawHeight !== targetHeight)\n ) {\n // Silent in production; a consumer shipping 10k × 10k probably wants\n // the nudge.\n console.warn(\n `[SignatureCapture] clamped canvas backing store from ${rawWidth}x${rawHeight} to ${targetWidth}x${targetHeight} (cap = ${MAX_CANVAS_PX}px).`,\n );\n }\n if (canvas.width === targetWidth && canvas.height === targetHeight)\n return;\n\n const pad = signaturePadRef.current;\n const prior = pad ? pad.toData() : null;\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n const ctx = canvas.getContext('2d');\n if (ctx) ctx.scale(dpr, dpr);\n if (pad) {\n if (resolvedBg) pad.backgroundColor = resolvedBg;\n if (resolvedPen) pad.penColor = resolvedPen;\n pad.clear();\n if (prior && prior.length > 0) {\n pad.fromData(prior);\n }\n }\n },\n [resolvedBg, resolvedPen],\n );\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return undefined;\n if (typeof ResizeObserver === 'undefined') {\n scaleCanvas(canvas);\n return undefined;\n }\n const ro = new ResizeObserver(() => {\n scaleCanvas(canvas);\n });\n ro.observe(canvas);\n return () => ro.disconnect();\n }, [scaleCanvas]);\n\n /* ---- Imperative handle -------------------------------------- */\n const clear = useCallback(() => {\n const pad = signaturePadRef.current;\n if (pad) pad.clear();\n setTypedValue('');\n setBoundValue('');\n setPadHasInk(false);\n announce('cleared');\n onClearRef.current?.();\n }, [announce]);\n\n const undo = useCallback(() => {\n const pad = signaturePadRef.current;\n if (!pad) return;\n const data = pad.toData();\n if (!data || data.length === 0) return;\n data.pop();\n pad.fromData(data);\n if (data.length === 0) {\n setPadHasInk(false);\n announce('empty');\n }\n }, [announce]);\n\n const isEmpty = useCallback((): boolean => {\n if (mode === 'typed') return typedValue.trim().length === 0;\n const pad = signaturePadRef.current;\n return pad ? pad.isEmpty() : true;\n }, [mode, typedValue]);\n\n const confirm =\n useCallback(async (): Promise<SignatureConfirmPayload | null> => {\n // parsePxValue returns null for \"100%\" / \"50vw\" etc. — fall back\n // to the live rendered rect so widthMm reflects reality, not a\n // mis-parsed parseFloat(\"100%\") = 100.\n const widthParsed = parsePxValue(\n typeof width === 'number' ? `${width}` : String(width),\n );\n const heightParsed = parsePxValue(\n typeof height === 'number' ? `${height}` : String(height),\n );\n const measureEl =\n mode === 'draw'\n ? (canvasRef.current ?? padFrameRef.current ?? wrapperRef.current)\n : (typedPreviewRef.current ?? wrapperRef.current);\n const measuredRect = measureEl?.getBoundingClientRect();\n const cssWidth =\n widthParsed ?? (measuredRect ? measuredRect.width : 400);\n const cssHeight =\n heightParsed ?? (measuredRect ? measuredRect.height : 200);\n\n let pngDataUrl = '';\n let svgString = '';\n let strokes: PointGroup[] | undefined;\n\n if (mode === 'draw') {\n const pad = signaturePadRef.current;\n if (!pad || pad.isEmpty()) return null;\n pngDataUrl = pad.toDataURL('image/png');\n svgString = pad.toSVG();\n strokes = pad.toData();\n } else {\n const value = typedValue.trim();\n if (value.length === 0) return null;\n const offscreen = renderTypedSignatureToCanvas(\n value,\n cssWidth,\n cssHeight,\n resolvedPen || 'currentColor',\n resolvedBg || 'transparent',\n );\n pngDataUrl = offscreen.toDataURL('image/png');\n // Inline SVG — we can't call toSVG() because signature_pad isn't\n // driving the canvas. Build a minimal SVG with the rendered text.\n const safeText = value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n svgString =\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${cssWidth} ${cssHeight}\" width=\"${cssWidth}\" height=\"${cssHeight}\">` +\n `<text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" font-family=\"sans-serif\" font-style=\"italic\" font-size=\"32\" fill=\"${resolvedPen || 'currentColor'}\" letter-spacing=\"3\">${safeText}</text>` +\n `</svg>`;\n }\n\n // 96 CSS px = 25.4 mm (per W3C CSS absolute length definition).\n const widthMm = (cssWidth * 25.4) / 96;\n const heightMm = (cssHeight * 25.4) / 96;\n const capturedAt = new Date().toISOString();\n\n // Compute SHA-256 of the PNG bytes.\n let sha256 = '';\n if (pngDataUrl) {\n const commaIx = pngDataUrl.indexOf(',');\n const b64 = commaIx >= 0 ? pngDataUrl.slice(commaIx + 1) : '';\n const bytes = base64ToBytes(b64);\n sha256 = await sha256Hex(bytes);\n }\n\n const payload: SignatureConfirmPayload = {\n png: pngDataUrl,\n svg: svgString,\n widthMm,\n heightMm,\n capturedAt,\n sha256,\n strokes,\n };\n\n announce('captured');\n if (name) setBoundValue(payload.png);\n onConfirmRef.current?.(payload);\n return payload;\n }, [\n mode,\n typedValue,\n width,\n height,\n resolvedPen,\n resolvedBg,\n announce,\n name,\n ]);\n\n const agentHandle = useMemo<SignatureCaptureHandle>(\n () => ({\n clear,\n undo,\n isEmpty,\n confirm,\n }),\n [clear, undo, isEmpty, confirm],\n );\n useImperativeHandle(ref, () => agentHandle, [agentHandle]);\n useAgentRegistration(signatureCaptureAgent, agentHandle, id);\n\n /* ---- Derived UI state --------------------------------------- */\n // Gate Confirm on React state, not the signature_pad ref — its\n // isEmpty() doesn't trigger re-renders, leaving the button stale.\n const hasContent =\n mode === 'typed' ? typedValue.trim().length > 0 : padHasInk;\n const confirmDisabled = disabled || !hasContent;\n // Inline style — permitted per 23-constraints §Runtime-computed\n // dimensions (CSS custom property setter for dynamic width/height\n // from consumer props; the width rule lives in Tailwind arbitrary\n // values that read --signature-width / --signature-height).\n const sizeStyle: CSSProperties = {\n ['--signature-width' as unknown as keyof CSSProperties]: toCssSize(\n width,\n 'var(--signature-default-width)',\n ),\n ['--signature-height' as unknown as keyof CSSProperties]: toCssSize(\n height,\n 'var(--signature-default-height)',\n ),\n } as CSSProperties;\n\n /* ---- Render -------------------------------------------------- */\n return (\n <div\n ref={wrapperRef}\n role=\"group\"\n aria-label={ariaLabel ?? t('signature.padLabel')}\n aria-disabled={disabled || undefined}\n className={[wrapperVariants(), className].filter(Boolean).join(' ')}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-computed pad dimensions\n style={sizeStyle}\n data-component=\"signature-capture\"\n data-component-id={id}\n >\n {name ? (\n <input type=\"hidden\" name={name} value={boundValue} readOnly />\n ) : null}\n {mode === 'draw' ? (\n <div ref={padFrameRef} className={padFrameVariants()}>\n <canvas\n ref={canvasRef}\n role=\"img\"\n aria-label={t('signature.padLabel')}\n className={canvasVariants()}\n data-testid=\"signature-canvas\"\n />\n </div>\n ) : (\n <label className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <span className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {t('signature.typedFallback.label')}\n </span>\n <input\n type=\"text\"\n value={typedValue}\n onChange={(e) => {\n setTypedValue(e.target.value);\n if (e.target.value.length > 0) announce('drawing');\n else announce('empty');\n }}\n placeholder={t('signature.typedFallback.placeholder')}\n aria-label={t('signature.typedFallback.label')}\n disabled={disabled}\n className={typedInputVariants()}\n data-testid=\"signature-typed-input\"\n />\n {typedValue ? (\n <div\n ref={typedPreviewRef}\n className={typedPreviewVariants()}\n aria-hidden=\"true\"\n >\n {typedValue}\n </div>\n ) : null}\n </label>\n )}\n\n {/* Live region — state transitions (empty, drawing, captured, cleared) */}\n <div\n id={liveRegionId}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"ds:sr-only\"\n data-testid=\"signature-live\"\n >\n {announcement}\n </div>\n\n <div\n className={toolbarVariants()}\n role=\"group\"\n aria-label={t('signature.padLabel')}\n >\n <button\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n clear();\n }}\n aria-disabled={disabled || undefined}\n aria-label={t('signature.clear')}\n className={actionButtonVariants()}\n >\n <Eraser aria-hidden=\"true\" className=\"ds:size-4\" />\n <span className={actionCaptionVariants()}>\n {t('signature.clear')}\n </span>\n </button>\n {allowTypedFallback ? (\n <button\n type=\"button\"\n onClick={() => {\n if (disabled) return;\n setTypedValue('');\n setMode((m) => (m === 'draw' ? 'typed' : 'draw'));\n announce('cleared');\n }}\n aria-disabled={disabled || undefined}\n aria-label={\n mode === 'draw'\n ? t('signature.typedFallback.toggle')\n : t('signature.typedFallback.toggleDraw')\n }\n className={actionButtonVariants()}\n aria-pressed={mode === 'typed'}\n >\n {mode === 'draw' ? (\n <Type aria-hidden=\"true\" className=\"ds:size-4\" />\n ) : (\n <PenLine aria-hidden=\"true\" className=\"ds:size-4\" />\n )}\n <span className={actionCaptionVariants()}>\n {mode === 'draw'\n ? t('signature.typedFallback.toggle')\n : t('signature.typedFallback.toggleDraw')}\n </span>\n </button>\n ) : null}\n <button\n type=\"button\"\n onClick={() => {\n if (confirmDisabled) return;\n void confirm();\n }}\n aria-disabled={confirmDisabled || undefined}\n aria-describedby={liveRegionId}\n aria-label={t('signature.confirm')}\n className={confirmButtonVariants()}\n data-testid=\"signature-confirm\"\n >\n <Check aria-hidden=\"true\" className=\"ds:size-4\" />\n <span className={actionCaptionVariants()}>\n {t('signature.confirm')}\n </span>\n </button>\n </div>\n </div>\n );\n },\n);\n\nSignatureCapture.displayName = 'SignatureCapture';\n\nexport {\n wrapperVariants as signatureWrapperVariants,\n actionButtonVariants as signatureActionButtonVariants,\n confirmButtonVariants as signatureConfirmButtonVariants,\n};\n"],"names":["signatureCaptureAgent","handle","wrapperVariants","cva","padFrameVariants","canvasVariants","toolbarVariants","actionCaptionVariants","actionButtonVariants","confirmButtonVariants","typedInputVariants","typedPreviewVariants","resolveCssVar","name","toCssSize","v","fallback","parsePxValue","toHex","bytes","out","i","b","base64ToBytes","b64","bin","g","sha256Hex","_a","copy","digest","renderTypedSignatureToCanvas","text","cssWidth","cssHeight","penColor","backgroundColor","dpr","canvas","ctx","SignatureCapture","forwardRef","id","onConfirm","onClear","onStart","width","height","allowTypedFallback","disabled","ariaLabel","className","ref","t","useTranslation","rawId","useId","liveRegionId","useMemo","wrapperRef","useRef","padFrameRef","canvasRef","typedPreviewRef","signaturePadRef","mode","setMode","useState","typedValue","setTypedValue","boundValue","setBoundValue","padHasInk","setPadHasInk","signatureStateRef","announcement","setAnnouncement","resolvedPen","setResolvedPen","resolvedBg","setResolvedBg","onStartRef","onClearRef","onConfirmRef","useEffect","announce","useCallback","next","resolveAll","pen","bg","mo","pad","SignaturePad","handleBegin","handleEnd","scaleCanvas","MAX_CANVAS_PX","rect","rawWidth","rawHeight","targetWidth","targetHeight","prior","ro","clear","undo","data","isEmpty","confirm","widthParsed","heightParsed","measureEl","measuredRect","pngDataUrl","svgString","strokes","value","safeText","widthMm","heightMm","capturedAt","sha256","commaIx","payload","agentHandle","useImperativeHandle","useAgentRegistration","hasContent","confirmDisabled","sizeStyle","jsxs","jsx","Eraser","m","Type","PenLine","Check"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tabs-CVTukWRD.js","sources":["../../src/components/tabs/tabs.agent.ts","../../src/components/tabs/tabs.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { TabsHandle } from './tabs';\n\nexport const tabsAgent: AgentAdapter<TabsHandle> = {\n id: 'tabs',\n capabilities: ['select_single'],\n state: {\n activeTab: {\n type: 'string | null',\n descriptionKey: 'ui.agent.tabs.state.activeTab',\n description: 'Value of the currently-active tab.',\n read: (handle) => handle.getActiveTab(),\n },\n },\n actions: {\n select_tab: {\n safety: 'read',\n argsType: '{ value: string }',\n argsSchema: {\n type: 'object',\n properties: { value: { type: 'string' } },\n required: ['value'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.tabs.actions.selectTab',\n description: 'Activate the tab with the given value.',\n invoke: (handle, args: { value: string }) => {\n handle.selectTab(args.value);\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'tabs' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on Tabs.Root.',\n },\n item: {\n attr: 'data-tab-id',\n description: 'Each Tab.Trigger emits its value as data-tab-id.',\n },\n },\n};\n","import {\n Children,\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type MutableRefObject,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport * as TabsPrimitive from '@radix-ui/react-tabs';\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { cva, cx, type VariantProps } from 'class-variance-authority';\nimport { X, ChevronDown } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useDirection } from '../_shared/use-direction';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { Select, type SelectOption } from '../select/select';\nimport { useAgentRegistration } from '../../agent';\nimport { tabsAgent } from './tabs.agent';\n\n// ---------------------------------------------------------------------------\n// CVA recipes\n// ---------------------------------------------------------------------------\n\nexport const tabsListVariants = cva('ds:relative ds:flex', {\n variants: {\n variant: {\n // Shadcn-style segmented control: light container, white active card\n default:\n 'ds:flex-1 ds:min-w-0 ds:items-center ds:bg-muted/10 ds:rounded-[var(--radius-md)] ds:p-1',\n // Classic underline tabs: bottom border with colored active indicator\n underlined:\n 'ds:flex-1 ds:min-w-0 ds:items-end ds:[border-block-end:1px_solid_var(--border)]',\n // Segmented control: warm secondary container, content-width\n pills:\n 'ds:items-center ds:bg-secondary ds:rounded-[var(--radius-md)] ds:p-1',\n },\n orientation: {\n horizontal: 'ds:flex-row ds:overflow-hidden',\n vertical: 'ds:flex-col',\n },\n },\n defaultVariants: {\n variant: 'default',\n orientation: 'horizontal',\n },\n});\n\nexport const tabsTriggerVariants = cva(\n [\n 'ds:relative ds:inline-flex ds:items-center ds:justify-center ds:whitespace-nowrap ds:border-0',\n 'ds:gap-2 ds:font-medium ds:transition-colors',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:cursor-pointer ds:select-none',\n 'ds:disabled:pointer-events-none ds:disabled:opacity-50',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n ].join(' '),\n {\n variants: {\n variant: {\n default: [\n 'ds:rounded-[var(--radius-sm)] ds:bg-transparent ds:text-muted-foreground',\n 'ds:hover:bg-muted/10 ds:hover:text-foreground',\n 'ds:data-[state=active]:bg-background ds:data-[state=active]:text-foreground',\n 'ds:data-[state=active]:shadow-sm',\n ].join(' '),\n underlined: [\n 'ds:bg-transparent ds:text-muted-foreground',\n 'ds:[border-block-end:2px_solid_transparent]',\n 'ds:hover:bg-muted/10 ds:hover:text-foreground',\n 'ds:data-[state=active]:[border-block-end-color:var(--primary)]',\n 'ds:data-[state=active]:text-foreground ds:data-[state=active]:[margin-block-end:-1px]',\n ].join(' '),\n pills: [\n 'ds:rounded-[var(--radius-full)] ds:bg-transparent ds:text-muted-foreground',\n 'ds:hover:bg-muted/20 ds:hover:text-foreground',\n 'ds:data-[state=active]:bg-primary ds:data-[state=active]:text-primary-foreground',\n ].join(' '),\n },\n size: {\n sm: 'ds:h-8 ds:px-[var(--spacing-sm)] ds:text-[length:var(--font-size-sm)]',\n md: 'ds:h-10 ds:px-[var(--spacing-md)] ds:text-[length:var(--font-size-base)]',\n lg: 'ds:h-12 ds:px-[var(--spacing-lg)] ds:text-[length:var(--font-size-lg)]',\n },\n orientation: {\n horizontal: '',\n vertical: 'ds:w-full ds:justify-start',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n orientation: 'horizontal',\n },\n },\n);\n\n// ---------------------------------------------------------------------------\n// Context\n// ---------------------------------------------------------------------------\n\ntype TabsOverflow = 'dropdown' | 'select';\n\ninterface TabsContextValue {\n variant: 'default' | 'underlined' | 'pills';\n size: 'sm' | 'md' | 'lg';\n orientation: 'horizontal' | 'vertical';\n overflow: TabsOverflow;\n value: string;\n setValue: (value: string) => void;\n}\n\nconst TabsContext = createContext<TabsContextValue>({\n variant: 'default',\n size: 'md',\n orientation: 'horizontal',\n overflow: 'dropdown',\n value: '',\n setValue: () => {},\n});\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n// Curated agent-readiness handle — see tabs.agent.ts.\nexport interface TabsHandle {\n getActiveTab: () => string | null;\n selectTab: (value: string) => void;\n}\n\nexport interface TabsRootProps extends Omit<\n ComponentPropsWithoutRef<typeof TabsPrimitive.Root>,\n 'orientation'\n> {\n variant?: 'default' | 'underlined' | 'pills';\n size?: 'sm' | 'md' | 'lg';\n orientation?: 'horizontal' | 'vertical';\n /**\n * Strategy for tabs that don't fit horizontally.\n *\n * - `'dropdown'` (default) — overflowing tabs collapse into a \"More\"\n * `DropdownMenu` rendered next to the visible tab list. Most tabs\n * stay visible inline; the few that don't fit hide behind the menu.\n * Best when there are 5–7 tabs at moderately narrow viewports.\n * - `'select'` — at narrow container widths (under the `@md` breakpoint)\n * the entire tab strip collapses into a single `Select` whose value\n * is the active tab. Best when there are many tabs and the panel is\n * genuinely cramped (mobile, side-panel host). Above `@md`, the\n * inline tab list reappears unchanged.\n *\n * Limitation: the Select mirror builds option labels from each\n * `Tabs.Trigger`'s `children`. Plain string / number children are\n * used verbatim; richer children (icon + text, fragments) fall back\n * to the trigger's `value` so the option remains selectable. Prefer\n * plain-text trigger children when using `overflow=\"select\"`, or use\n * the trigger's `icon` prop for the icon and keep `children` a\n * plain string.\n *\n * @default 'dropdown'\n */\n overflow?: TabsOverflow;\n}\n\nexport interface TabsListProps extends ComponentPropsWithoutRef<\n typeof TabsPrimitive.List\n> {\n 'aria-label'?: string;\n}\n\nexport interface TabsTriggerProps\n extends\n ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>,\n VariantProps<typeof tabsTriggerVariants> {\n icon?: ReactNode;\n badge?: ReactNode;\n dismissible?: boolean;\n onDismiss?: () => void;\n}\n\nexport type TabsContentProps = ComponentPropsWithoutRef<\n typeof TabsPrimitive.Content\n>;\n\n// ---------------------------------------------------------------------------\n// TabsRoot\n// ---------------------------------------------------------------------------\n\nconst TabsRoot = forwardRef<HTMLDivElement, TabsRootProps>(\n (\n {\n variant = 'default',\n size = 'md',\n orientation = 'horizontal',\n overflow = 'dropdown',\n className,\n children,\n value: valueProp,\n defaultValue,\n onValueChange,\n id,\n ...props\n },\n ref,\n ) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const composedRef = composeRefs(ref, rootRef);\n const dir = useDirection(rootRef);\n\n // Track the active tab so the `overflow=\"select\"` mirror can read it\n // without forcing consumers into controlled mode. If `value` is passed\n // we honour it; otherwise we manage internal state seeded from\n // `defaultValue` and notify consumers via `onValueChange`. Net effect\n // is identical to Radix's own controlled / uncontrolled split — we\n // just shadow the value into context so the Select can mirror it.\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = useState<string>(\n defaultValue ?? '',\n );\n const value = isControlled ? (valueProp ?? '') : internalValue;\n const setValue = useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n },\n [isControlled, onValueChange],\n );\n\n const ctxValue = useMemo(\n () => ({ variant, size, orientation, overflow, value, setValue }),\n [variant, size, orientation, overflow, value, setValue],\n );\n\n // Agent handle — ref mirrors value for fresh reads.\n const valueRef = useRef<string>(value);\n useEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n const agentHandle = useMemo<TabsHandle>(\n () => ({\n getActiveTab: () => valueRef.current || null,\n selectTab: (next) => setValue(next),\n }),\n [setValue],\n );\n useAgentRegistration(tabsAgent, agentHandle, id);\n\n return (\n <TabsContext.Provider value={ctxValue}>\n <TabsPrimitive.Root\n ref={composedRef}\n orientation={orientation}\n dir={dir}\n // We always run Radix in controlled mode against our shadow state\n // (seeded from `defaultValue`) so the `overflow=\"select\"` mirror\n // can read the active value via context without DOM observation.\n value={value}\n onValueChange={setValue}\n id={id}\n data-component=\"tabs\"\n data-component-id={id}\n className={cx(\n 'ds:flex',\n orientation === 'vertical'\n ? 'ds:flex-row ds:gap-[var(--spacing-md)]'\n : 'ds:flex-col',\n className,\n )}\n {...props}\n >\n {children}\n </TabsPrimitive.Root>\n </TabsContext.Provider>\n );\n },\n);\nTabsRoot.displayName = 'Tabs';\n\n// ---------------------------------------------------------------------------\n// TabsList — with overflow detection\n// ---------------------------------------------------------------------------\n\nconst TabsList = forwardRef<HTMLDivElement, TabsListProps>(\n ({ className, children, 'aria-label': ariaLabel, ...props }, ref) => {\n const { variant, size, orientation, overflow, value, setValue } =\n useContext(TabsContext);\n const { t } = useTranslation();\n\n const listRef = useRef<HTMLDivElement>(null);\n const [overflowTabs, setOverflowTabs] = useState<\n { value: string; label: string }[]\n >([]);\n const isHorizontal = orientation === 'horizontal';\n // The `select` overflow strategy renders a Select mirror at narrow\n // container widths and skips the DropdownMenu overflow detector\n // (it's the wrong UX for that case — a select-and-a-dropdown would\n // double up). The dropdown detector only runs when `overflow` is\n // `dropdown` and the strip is horizontal.\n const isDropdownOverflow = overflow === 'dropdown' && isHorizontal;\n\n useEffect(() => {\n if (!isDropdownOverflow) {\n setOverflowTabs([]);\n return;\n }\n const el = listRef.current;\n if (!el) return;\n\n const detectOverflow = () => {\n const containerRight = el.getBoundingClientRect().right;\n const hidden: { value: string; label: string }[] = [];\n el.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]').forEach(\n (tab) => {\n const rect = tab.getBoundingClientRect();\n if (rect.right > containerRight + 2) {\n const value =\n tab.getAttribute('data-value') ?? tab.dataset['value'] ?? '';\n const label = tab.textContent?.trim() ?? value;\n hidden.push({ value, label });\n }\n },\n );\n setOverflowTabs(hidden);\n };\n\n const ro = new ResizeObserver(detectOverflow);\n ro.observe(el);\n detectOverflow();\n return () => ro.disconnect();\n }, [isDropdownOverflow, children]);\n\n const combinedRef = (node: HTMLDivElement | null) => {\n (listRef as MutableRefObject<HTMLDivElement | null>).current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref)\n (ref as MutableRefObject<HTMLDivElement | null>).current = node;\n };\n\n // For `overflow=\"select\"` we mirror the Trigger children as Select\n // options. Triggers may carry icon + text; for the Select label we\n // prefer the trigger's plain-text children — anything else falls\n // back to the trigger's `value` so the option is at least selectable.\n const selectOptions = useMemo<SelectOption<string>[]>(() => {\n if (overflow !== 'select') return [];\n return Children.toArray(children)\n .filter((child): child is ReactElement<TabsTriggerProps> =>\n isValidElement(child),\n )\n .filter(\n (child) =>\n typeof child.props.value === 'string' &&\n child.props.value.length > 0,\n )\n .map((child) => {\n const triggerValue = child.props.value as string;\n const labelChild = child.props.children;\n const label =\n typeof labelChild === 'string'\n ? labelChild\n : typeof labelChild === 'number'\n ? String(labelChild)\n : triggerValue;\n return { value: triggerValue, label };\n });\n }, [children, overflow]);\n\n if (overflow === 'select' && isHorizontal) {\n // Container queries gate the swap: above `@md` (Tailwind v4 default\n // 28rem container width) the inline tab strip renders; below it,\n // the Select takes over. The Tabs.List markup stays mounted in\n // both modes so Radix's roving-tabindex / ARIA wiring is preserved\n // even when the strip is visually hidden — keyboard users who land\n // on the panel via skip-link still get to the active tab.\n return (\n <div className=\"ds:@container/tabs ds:relative ds:w-full\">\n {/* Select mirror — visible at narrow container widths only. */}\n <div className=\"ds:block ds:@md/tabs:hidden\">\n <Select\n options={selectOptions}\n value={value}\n onValueChange={(next) => {\n if (typeof next === 'string' && next.length > 0) setValue(next);\n }}\n size={size}\n aria-label={ariaLabel ?? t('tabs.selectLabel')}\n />\n </div>\n {/* Inline tab strip — visible at wider container widths. */}\n <div className=\"ds:hidden ds:@md/tabs:flex ds:relative ds:items-center\">\n <TabsPrimitive.List\n ref={combinedRef}\n aria-label={ariaLabel}\n className={tabsListVariants({ variant, orientation, className })}\n {...props}\n >\n {children}\n </TabsPrimitive.List>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"ds:relative ds:flex ds:items-center\">\n <TabsPrimitive.List\n ref={combinedRef}\n aria-label={ariaLabel}\n className={tabsListVariants({ variant, orientation, className })}\n {...props}\n >\n {children}\n </TabsPrimitive.List>\n\n {isDropdownOverflow && overflowTabs.length > 0 && (\n <OverflowMenu\n tabs={overflowTabs}\n label={t('tabs.moreTabs')}\n size={size}\n />\n )}\n </div>\n );\n },\n);\nTabsList.displayName = 'TabsList';\n\n// ---------------------------------------------------------------------------\n// OverflowMenu (internal)\n// ---------------------------------------------------------------------------\n\ninterface OverflowMenuProps {\n tabs: { value: string; label: string }[];\n label: string;\n size: 'sm' | 'md' | 'lg';\n}\n\nfunction OverflowMenu({ tabs, label, size }: OverflowMenuProps) {\n const { variant } = useContext(TabsContext);\n\n return (\n <DropdownMenuPrimitive.Root>\n <DropdownMenuPrimitive.Trigger\n className={cx(\n tabsTriggerVariants({ variant, size, orientation: 'horizontal' }),\n 'ds:shrink-0 ds:ms-1',\n )}\n aria-label={label}\n >\n {label}\n <ChevronDown aria-hidden=\"true\" className=\"ds:size-4\" />\n </DropdownMenuPrimitive.Trigger>\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n sideOffset={4}\n className={cx(\n 'ds:z-50 ds:min-w-40 ds:overflow-hidden ds:rounded-[var(--radius-md)]',\n 'ds:border ds:border-border ds:bg-popover ds:p-1 ds:shadow-md',\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=closed]:fade-out-0 ds:data-[state=open]:fade-in-0',\n 'ds:data-[state=closed]:zoom-out-95 ds:data-[state=open]:zoom-in-95',\n )}\n >\n {tabs.map(({ value, label: tabLabel }) => (\n <DropdownMenuPrimitive.Item\n key={value}\n className={cx(\n 'ds:relative ds:flex ds:cursor-pointer ds:select-none ds:items-center',\n 'ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:text-[var(--font-size-sm)] ds:text-foreground ds:outline-none',\n 'ds:hover:bg-muted ds:focus:bg-muted',\n 'ds:data-[disabled]:pointer-events-none ds:data-[disabled]:opacity-50',\n )}\n onSelect={() => {\n const tab = document.querySelector<HTMLButtonElement>(\n `[role=\"tab\"][data-value=\"${CSS.escape(value)}\"]`,\n );\n tab?.click();\n tab?.scrollIntoView({ inline: 'nearest' });\n }}\n >\n {tabLabel}\n </DropdownMenuPrimitive.Item>\n ))}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n </DropdownMenuPrimitive.Root>\n );\n}\n\n// ---------------------------------------------------------------------------\n// TabsTrigger\n// ---------------------------------------------------------------------------\n\nconst TabsTrigger = forwardRef<HTMLButtonElement, TabsTriggerProps>(\n (\n {\n variant: variantProp,\n size: sizeProp,\n orientation: orientationProp,\n icon,\n badge,\n dismissible = false,\n onDismiss,\n className,\n children,\n value,\n onKeyDown,\n ...props\n },\n ref,\n ) => {\n const ctx = useContext(TabsContext);\n const variant = variantProp ?? ctx.variant;\n const size = sizeProp ?? ctx.size;\n const orientation = orientationProp ?? ctx.orientation;\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>) => {\n // APG dismissible-tab pattern: Delete/Backspace while trigger is focused closes the tab.\n // The visual X is pointer-only (aria-hidden) to avoid nested-interactive HTML violation.\n if (dismissible && (e.key === 'Delete' || e.key === 'Backspace')) {\n e.preventDefault();\n onDismiss?.();\n }\n onKeyDown?.(e);\n };\n\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n value={value}\n data-value={value}\n data-tab-id={value}\n className={tabsTriggerVariants({\n variant,\n size,\n orientation,\n className,\n })}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {icon && (\n <span aria-hidden=\"true\" className=\"ds:shrink-0 ds:size-4\">\n {icon}\n </span>\n )}\n {children}\n {badge && <span className=\"ds:shrink-0\">{badge}</span>}\n {dismissible && (\n // Visual-only dismiss indicator — pointer dismiss fires here; keyboard dismiss fires via Delete/Backspace on the trigger above.\n // No role/tabIndex to avoid nested-interactive (interactive content inside <button> is invalid HTML).\n <span\n aria-hidden=\"true\"\n className={cx(\n 'ds:inline-flex ds:items-center ds:justify-center ds:shrink-0',\n 'ds:size-6 ds:rounded-[var(--radius-sm)]',\n 'ds:hover:bg-muted-foreground/20',\n )}\n onPointerDown={(e) => {\n e.stopPropagation();\n e.preventDefault();\n onDismiss?.();\n }}\n >\n <X className=\"ds:size-3.5\" />\n </span>\n )}\n </TabsPrimitive.Trigger>\n );\n },\n);\nTabsTrigger.displayName = 'TabsTrigger';\n\n// ---------------------------------------------------------------------------\n// TabsContent\n// ---------------------------------------------------------------------------\n\nconst TabsContent = forwardRef<HTMLDivElement, TabsContentProps>(\n ({ className, children, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n className={cx(\n 'ds:mt-[var(--spacing-sm)] ds:outline-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n className,\n )}\n {...props}\n >\n {children}\n </TabsPrimitive.Content>\n ),\n);\nTabsContent.displayName = 'TabsContent';\n\n// ---------------------------------------------------------------------------\n// Compound export\n// ---------------------------------------------------------------------------\n\nexport const Tabs = Object.assign(TabsRoot, {\n Root: TabsRoot,\n List: TabsList,\n Trigger: TabsTrigger,\n Content: TabsContent,\n});\n\nexport { TabsList, TabsTrigger, TabsContent };\n"],"names":["tabsAgent","handle","args","tabsListVariants","cva","tabsTriggerVariants","TabsContext","createContext","TabsRoot","forwardRef","variant","size","orientation","overflow","className","children","valueProp","defaultValue","onValueChange","id","props","ref","rootRef","useRef","composedRef","composeRefs","dir","useDirection","isControlled","internalValue","setInternalValue","useState","value","setValue","useCallback","next","ctxValue","useMemo","valueRef","useEffect","agentHandle","useAgentRegistration","jsx","TabsPrimitive","cx","TabsList","ariaLabel","useContext","t","useTranslation","listRef","overflowTabs","setOverflowTabs","isHorizontal","isDropdownOverflow","el","detectOverflow","containerRight","hidden","tab","label","_a","ro","combinedRef","node","selectOptions","Children","child","isValidElement","triggerValue","labelChild","jsxs","Select","OverflowMenu","tabs","DropdownMenuPrimitive","ChevronDown","tabLabel","TabsTrigger","variantProp","sizeProp","orientationProp","icon","badge","dismissible","onDismiss","onKeyDown","ctx","handleKeyDown","e","X","TabsContent","Tabs"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"warning-stack-CAHQ0xxS.js","sources":["../../src/components/warning-stack/warning-stack.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronDown, X } from 'lucide-react';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { Alert, type AlertProps } from '../alert/alert';\nimport { Button } from '../button/button';\nimport { IconButton } from '../button/icon-button';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface WarningStackItem {\n id: string;\n variant?: AlertProps['variant'];\n title: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n actions?: ReactNode;\n dismissible?: boolean;\n}\n\n/** Empty-collapse fold phases (no-`emptyState` path only). See the fold\n * state machine in the component body. */\ntype FoldPhase = 'open' | 'settling' | 'closing' | 'closed';\n\nconst stackVariants = cva(\n [\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-md)]',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n 'ds:p-[var(--spacing-md)]',\n ].join(' '),\n {\n variants: {\n // `stretch: true` fills the parent layout cell — mirrors the `stretch`\n // prop on `Card` so a WarningStack rendered next to a Card in a grid\n // row ends up at matching height.\n stretch: {\n true: 'ds:h-full ds:self-stretch',\n false: '',\n },\n },\n defaultVariants: {\n stretch: false,\n },\n },\n);\n\n// Single column by default; two columns once the stack itself is wide\n// enough (container query — viewport width lies when the stack sits in\n// a narrow grid cell). A trailing odd item spans both columns so the\n// grid never ends on a half-width hole, which also keeps a lone item\n// full-width exactly as before.\nconst LIST_CLASSES = [\n 'ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-md)]',\n 'ds:@3xl/warning-stack:grid-cols-2',\n 'ds:@3xl/warning-stack:[&>li:nth-child(odd):last-child]:col-span-full',\n].join(' ');\n\nconst TOGGLE_CLASSES = [\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] ds:self-start',\n].join(' ');\n\n/* ------------------------------------------------------------------ */\n/* Empty-collapse animation */\n/* */\n/* When the stack empties (every notice dismissed) and no `emptyState` */\n/* is supplied, the whole region folds away instead of leaving a hole. */\n/* The grid `1fr → 0fr` track is the only CSS-only way to animate to/ */\n/* from `height: auto`; JS-measured `max-height` is barred by the */\n/* no-inline-styles constraint. The outer wrapper owns the height */\n/* track; the inner wrapper owns the cross-fade + overflow clip. */\n/* ------------------------------------------------------------------ */\n\n/** Floor for how long the folding region stays mounted after it empties, so a\n * screen reader can voice the cleared count even when `--animation-duration`\n * is 0ms (accessible themes). The region is already visually collapsed, so\n * this window is imperceptible. */\nconst MIN_FOLD_UNMOUNT_MS = 250;\n\n/** Reads `--animation-duration` (ms) so the unmount timer matches the\n * CSS transition. Falls back to 200ms when it can't be resolved. */\nfunction readAnimationDurationMs(): number {\n if (typeof window === 'undefined') return 200;\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue('--animation-duration');\n const trimmed = raw.trim();\n const n = parseFloat(trimmed);\n if (!Number.isFinite(n)) return 200;\n return trimmed.endsWith('ms') ? n : n * 1000;\n}\n\n/** Outer height-collapse track. Always a grid so the `grid-template-rows`\n * transition has a stable from/to; only the row size flips. */\nfunction collapseTrackClass(collapsed: boolean, stretch: boolean): string {\n return [\n 'ds:grid ds:transition-[grid-template-rows]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n collapsed ? 'ds:grid-rows-[0fr]' : 'ds:grid-rows-[1fr]',\n stretch ? 'ds:h-full ds:self-stretch' : '',\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/** Inner cross-fade layer. `min-h-0` lets the grid item shrink below its\n * content; `overflow-hidden` (only while animating) clips the fold so the\n * card's resting drop-shadow isn't clipped at rest. */\nfunction collapseInnerClass(collapsed: boolean, closing: boolean): string {\n return [\n 'ds:min-h-0',\n 'ds:transition-opacity ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n collapsed ? 'ds:opacity-0 ds:overflow-hidden' : 'ds:opacity-100',\n closing ? 'ds:pointer-events-none' : '',\n ]\n .filter(Boolean)\n .join(' ');\n}\n\nexport interface WarningStackProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'role' | 'title'>,\n VariantProps<typeof stackVariants> {\n /** Items rendered inside the stack. */\n items: WarningStackItem[];\n /** Fill the parent layout cell — use in a dashboard grid row so the\n * stack ends up with matching height to sibling Cards. */\n stretch?: boolean;\n /** Visible title rendered as an `<h2>` above the stack. Also labels the\n * region for assistive tech. When omitted, the region is labelled via a\n * visually hidden heading using `ariaLabel` (or the default \"Warnings\"). */\n title?: ReactNode;\n /** Optional short description rendered under the title. */\n description?: ReactNode;\n /** Cap on visible items before a \"Show N more\" toggle appears. Defaults to\n * `2`; pass a larger number (or `Infinity`) to show more before collapsing. */\n maxVisible?: number;\n /** Whether the stack starts collapsed when items exceed `maxVisible`. */\n defaultCollapsed?: boolean;\n /** Fires when a dismissible item's close control is activated. */\n onDismiss?: (item: WarningStackItem) => void;\n /** Whether the whole-stack close control is shown at the header's inline-end.\n * Defaults to `true` — the tray is closable. Set `false` for stacks that\n * carry notices which must not be bulk-cleared (e.g. hard compliance blocks). */\n closable?: boolean;\n /** Fires when the whole-stack close control is activated, after every\n * currently-visible notice has been dismissed (folding the region away).\n * Optional — the fold happens internally regardless; supply this only to\n * mirror the bulk dismissal into the consumer's own store. */\n onDismissAll?: () => void;\n /** Accessible label for the whole-stack close control. Defaults to the\n * localised \"Dismiss all notices\". */\n dismissAllLabel?: string;\n /** Accessible label for the region when `title` is not set. */\n ariaLabel?: string;\n /** Optional node rendered when the stack has zero items. */\n emptyState?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport const WarningStack = forwardRef<HTMLDivElement, WarningStackProps>(\n (\n {\n items,\n title,\n description,\n maxVisible = 2,\n defaultCollapsed = true,\n onDismiss,\n closable = true,\n onDismissAll,\n dismissAllLabel,\n stretch = false,\n ariaLabel,\n emptyState,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const labelId = useId();\n const listId = useId();\n\n // Track dismissed ids internally so the <li> unmounts even when the\n // consumer doesn't mirror dismissal into `items` — otherwise the list\n // keeps a ghost entry (and the two-column grid a blank cell). Pruned\n // when an id leaves `items`, so a re-pushed item renders again.\n const [dismissedIds, setDismissedIds] = useState<ReadonlySet<string>>(\n () => new Set(),\n );\n useEffect(() => {\n setDismissedIds((prev) => {\n if (prev.size === 0) return prev;\n const ids = new Set(items.map((item) => item.id));\n const next = new Set([...prev].filter((id) => ids.has(id)));\n return next.size === prev.size ? prev : next;\n });\n }, [items]);\n\n const liveItems = useMemo(\n () => items.filter((item) => !dismissedIds.has(item.id)),\n [items, dismissedIds],\n );\n\n const overflow = maxVisible !== undefined && liveItems.length > maxVisible;\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n\n // Live-region announces the count when items change.\n const liveRef = useRef<HTMLDivElement>(null);\n const lastCountRef = useRef<number>(liveItems.length);\n\n useEffect(() => {\n if (!liveRef.current) return;\n const prev = lastCountRef.current;\n const next = liveItems.length;\n if (prev !== next) {\n liveRef.current.textContent = t('warningStack.countChanged', {\n count: next,\n defaultValue: '{{count}} warnings to review',\n });\n }\n lastCountRef.current = next;\n }, [liveItems.length, t]);\n\n const visible = useMemo(() => {\n if (!overflow || !collapsed) return liveItems;\n return liveItems.slice(0, maxVisible);\n }, [liveItems, overflow, collapsed, maxVisible]);\n\n const hiddenCount = overflow ? liveItems.length - (maxVisible ?? 0) : 0;\n\n /* ----- Empty-collapse phase ------------------------------------- */\n const hasItems = liveItems.length > 0;\n const hasEmptyState = emptyState != null;\n // There is something to show whenever a live notice remains, or an\n // empty state has been supplied to fill the region in its place.\n const present = hasItems || hasEmptyState;\n\n // Only the no-`emptyState` path animates the fold. It runs in two beats\n // so the height transition has a stable start: a CSS transition can't\n // interpolate when the element's content changes in the same commit as\n // the track flip, so `settling` first re-renders the emptied region at\n // full height (track still open), then `closing` flips the track to 0fr\n // on the next frame — now the browser animates from a real height.\n // open → settling → closing → closed (unmounted, until a notice lands)\n const [phase, setPhase] = useState<FoldPhase>(present ? 'open' : 'closed');\n // Drives the expand-in when a notice lands after the region had folded.\n const [entering, setEntering] = useState(false);\n\n useIsomorphicLayoutEffect(() => {\n if (present) {\n if (phase !== 'open') {\n // Replay the expand only when re-appearing from a collapsed state.\n if (phase === 'closing' || phase === 'closed') setEntering(true);\n setPhase('open');\n }\n } else if (phase === 'open') {\n setPhase('settling');\n }\n }, [present, phase]);\n\n // settling → closing: flip the track shut one frame after the emptied\n // region has painted at full height, so the collapse actually animates.\n useEffect(() => {\n if (phase !== 'settling') return;\n const raf = window.requestAnimationFrame(() => setPhase('closing'));\n return () => window.cancelAnimationFrame(raf);\n }, [phase]);\n\n // closing → closed: unmount once the collapse transition has run. The\n // delay is floored so the polite live region (which lives in this subtree)\n // survives long enough for assistive tech to voice the cleared count\n // before the node is removed — otherwise an accessible theme, where\n // `--animation-duration` is 0ms, would unmount in the same frame and\n // swallow the announcement. The region is already collapsed to zero\n // height by then, so the extra mounted time is invisible.\n useEffect(() => {\n if (phase !== 'closing') return;\n const delay = Math.max(readAnimationDurationMs(), MIN_FOLD_UNMOUNT_MS);\n const id = window.setTimeout(() => setPhase('closed'), delay);\n return () => window.clearTimeout(id);\n }, [phase]);\n\n // Expand-in: clear the collapsed start-state on the next frame so the\n // grid track animates open instead of snapping to full height.\n useEffect(() => {\n if (!entering) return;\n const raf = window.requestAnimationFrame(() => setEntering(false));\n return () => window.cancelAnimationFrame(raf);\n }, [entering]);\n\n const closing = phase === 'closing';\n const animCollapsed = closing || entering;\n const mounted = present || phase === 'settling' || phase === 'closing';\n\n // Focus hand-off: dismissing unmounts the focused close button, which\n // would otherwise drop focus to <body> (WCAG 2.4.3). Aim for the\n // dismiss control now occupying the same list position (the next\n // item), else the last remaining one, else the region itself.\n const sectionRef = useRef<HTMLElement | null>(null);\n const setSectionRef = useCallback(\n (node: HTMLElement | null) => {\n sectionRef.current = node;\n if (typeof ref === 'function') {\n ref(node as HTMLDivElement | null);\n } else if (ref) {\n (ref as MutableRefObject<HTMLDivElement | null>).current =\n node as HTMLDivElement | null;\n }\n },\n [ref],\n );\n const pendingFocusIndexRef = useRef<number | null>(null);\n // No dependency array on purpose: this runs after every render but is\n // gated by `pendingFocusIndexRef`, which is only non-null on the render\n // that immediately follows a dismissal. Don't \"fix\" it to `[liveItems]`.\n useEffect(() => {\n if (pendingFocusIndexRef.current === null) return;\n const index = pendingFocusIndexRef.current;\n pendingFocusIndexRef.current = null;\n const section = sectionRef.current;\n if (!section) return;\n const dismissControls = Array.from(\n section.querySelectorAll<HTMLButtonElement>('[data-alert-dismiss]'),\n );\n const target =\n dismissControls[Math.min(index, dismissControls.length - 1)];\n if (target) target.focus();\n // Last notice gone: only land focus on the region if it survives the\n // dismissal (an emptyState keeps it mounted). When the stack folds\n // away entirely there is no stable target here — the consumer owns\n // re-homing focus (see the dashboard pattern) and the live region\n // announces the cleared count.\n else if (hasEmptyState) section.focus();\n });\n\n const handleDismiss = useCallback(\n (item: WarningStackItem, index: number) => (open: boolean) => {\n if (open) return;\n pendingFocusIndexRef.current = index;\n setDismissedIds((prev) => new Set(prev).add(item.id));\n onDismiss?.(item);\n },\n [onDismiss],\n );\n\n // Whole-stack close: dismiss every currently-visible notice in one go,\n // which empties `liveItems` and folds the region away. Focus re-homing on\n // the fold is the consumer's responsibility (same as the last-item case) —\n // there's no surviving in-component target once the header unmounts.\n const handleDismissAll = useCallback(() => {\n setDismissedIds((prev) => {\n const next = new Set(prev);\n for (const item of liveItems) next.add(item.id);\n return next;\n });\n onDismissAll?.();\n }, [liveItems, onDismissAll]);\n\n const toggle = useCallback(() => setCollapsed((c) => !c), []);\n\n const regionLabel = ariaLabel ?? t('warningStack.regionLabel', 'Warnings');\n\n // Title block: a visible header when `title` is provided; otherwise a\n // visually hidden heading so the region still has a programmatic name.\n // A `<div>` rather than `<header>` wrapper keeps the `<header>` element's\n // implicit banner role from leaking out of the region. The whole-stack\n // close control (when enabled) sits at the inline-end of this row.\n const titleBlock = title ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <h2\n id={labelId}\n className=\"ds:text-start type-title-section ds:text-[var(--foreground)]\"\n >\n {title}\n </h2>\n {description ? (\n <p className=\"ds:text-start type-body-sm ds:text-[var(--muted-foreground)]\">\n {description}\n </p>\n ) : null}\n </div>\n ) : (\n <h2 id={labelId} className=\"ds:sr-only\">\n {regionLabel}\n </h2>\n );\n\n const showStackClose = closable && hasItems;\n const header = showStackClose ? (\n <div className=\"ds:flex ds:items-start ds:justify-between ds:gap-[var(--spacing-sm)]\">\n {titleBlock}\n <IconButton\n type=\"button\"\n icon={<X aria-hidden=\"true\" />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={\n dismissAllLabel ??\n t('warningStack.dismissAll', 'Dismiss all notices')\n }\n onClick={handleDismissAll}\n // Pull flush to the card's inline-end padding edge, and never let\n // the button compress when the title wraps.\n className=\"ds:-me-[var(--spacing-2xs)] ds:shrink-0\"\n />\n </div>\n ) : (\n titleBlock\n );\n\n // Fully folded away (or cold-start empty with no emptyState): render\n // nothing. Matches the long-standing \"empty + no emptyState → null\"\n // contract, now reached via the fold-out animation rather than instantly.\n if (!mounted) return null;\n\n return (\n // Outer: height-collapse track. Carries the bounding marker so it is\n // the cascade-reset boundary even mid-fold.\n <div\n data-component=\"warning-stack\"\n className={collapseTrackClass(animCollapsed, stretch)}\n >\n {/* Inner: cross-fade + overflow clip while folding. */}\n <div className={collapseInnerClass(animCollapsed, closing)}>\n <section\n ref={setSectionRef}\n aria-labelledby={labelId}\n // Programmatically focusable so a surviving region can take the\n // last dismissal's focus (see the focus hand-off above).\n tabIndex={-1}\n className={[stackVariants({ stretch }), className]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {header}\n {/* The live region announces the count as it changes. Omitted in\n emptyState mode, where the empty state itself communicates. */}\n {!hasEmptyState ? (\n <div\n ref={liveRef}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"ds:sr-only\"\n />\n ) : null}\n {hasItems ? (\n <>\n {/* Container-type lives on this wrapper (never on the flex\n section itself) so the list can query its own inline size. */}\n <div className=\"ds:@container/warning-stack\">\n <ul\n id={listId}\n className={LIST_CLASSES}\n // Neutral wording — the list mixes warnings with info\n // notices and promo offers.\n aria-label={t('warningStack.listLabel', 'Notices')}\n >\n {visible.map((item, index) => {\n const variant = item.variant ?? 'warning';\n return (\n <li key={item.id}>\n <Alert\n variant={variant}\n dismissible={item.dismissible}\n icon={item.icon}\n onOpenChange={handleDismiss(item, index)}\n // Compact: clamp title/description so a notice stays\n // a predictable height — keeps the tray tight and\n // side-by-side cards even.\n clamp\n // Fill the row so side-by-side alerts equalise height.\n className=\"ds:h-full\"\n >\n {/* `as=\"h3\"` keeps a clean heading ladder — the\n stack's h2 labels the region, then each item's\n h3 rises from it. */}\n <Alert.Title as=\"h3\">{item.title}</Alert.Title>\n {item.description ? (\n <Alert.Description>\n {item.description}\n </Alert.Description>\n ) : null}\n {item.actions ? (\n <Alert.Action>{item.actions}</Alert.Action>\n ) : null}\n </Alert>\n </li>\n );\n })}\n </ul>\n </div>\n\n {overflow ? (\n <Button\n type=\"button\"\n intent=\"link\"\n size=\"sm\"\n aria-expanded={!collapsed}\n aria-controls={listId}\n onClick={toggle}\n className={TOGGLE_CLASSES}\n >\n <ChevronDown\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n collapsed ? '' : 'ds:rotate-180',\n ].join(' ')}\n />\n {collapsed\n ? t('warningStack.showMore', {\n count: hiddenCount,\n defaultValue: 'Show {{count}} more warnings',\n })\n : t('warningStack.showLess', 'Show less')}\n </Button>\n ) : null}\n </>\n ) : (\n emptyState\n )}\n </section>\n </div>\n </div>\n );\n },\n);\n\nWarningStack.displayName = 'WarningStack';\n"],"names":["stackVariants","cva","LIST_CLASSES","TOGGLE_CLASSES","MIN_FOLD_UNMOUNT_MS","readAnimationDurationMs","trimmed","n","collapseTrackClass","collapsed","stretch","collapseInnerClass","closing","WarningStack","forwardRef","items","title","description","maxVisible","defaultCollapsed","onDismiss","closable","onDismissAll","dismissAllLabel","ariaLabel","emptyState","className","rest","ref","t","useTranslation","labelId","useId","listId","dismissedIds","setDismissedIds","useState","useEffect","prev","ids","item","next","id","liveItems","useMemo","overflow","setCollapsed","liveRef","useRef","lastCountRef","visible","hiddenCount","hasItems","hasEmptyState","present","phase","setPhase","entering","setEntering","useIsomorphicLayoutEffect","raf","delay","animCollapsed","mounted","sectionRef","setSectionRef","useCallback","node","pendingFocusIndexRef","index","section","dismissControls","target","handleDismiss","open","handleDismissAll","toggle","c","regionLabel","titleBlock","jsxs","jsx","header","IconButton","X","Fragment","variant","Alert","Button","ChevronDown"],"mappings":"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"}
|