@alfadocs/ui-kit-debug 1.95.0 → 1.95.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/{actions-cell-renderer-B1yaOfQM.js → actions-cell-renderer-BVn3vDTg.js} +3 -3
- package/dist/_chunks/{actions-cell-renderer-B1yaOfQM.js.map → actions-cell-renderer-BVn3vDTg.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-DTZ3per6.js → anamnesis-summary-rows-krsCC-F4.js} +4 -4
- package/dist/_chunks/{anamnesis-summary-rows-DTZ3per6.js.map → anamnesis-summary-rows-krsCC-F4.js.map} +1 -1
- package/dist/_chunks/{appointment-card-Bstc1p7a.js → appointment-card-Csx4544A.js} +2 -2
- package/dist/_chunks/{appointment-card-Bstc1p7a.js.map → appointment-card-Csx4544A.js.map} +1 -1
- package/dist/_chunks/{appointment-peek-C0kKqnFk.js → appointment-peek-CcDCWb-F.js} +2 -2
- package/dist/_chunks/{appointment-peek-C0kKqnFk.js.map → appointment-peek-CcDCWb-F.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-rbt9AwHO.js → appointment-timeline-DW6FN6u8.js} +3 -3
- package/dist/_chunks/{appointment-timeline-rbt9AwHO.js.map → appointment-timeline-DW6FN6u8.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-6zd8RLIL.js → appointment-tray-CZfXwHWz.js} +2 -2
- package/dist/_chunks/{appointment-tray-6zd8RLIL.js.map → appointment-tray-CZfXwHWz.js.map} +1 -1
- package/dist/_chunks/{balance-badge-cell-vZxbOFgP.js → balance-badge-cell-DbgEQsou.js} +3 -3
- package/dist/_chunks/{balance-badge-cell-vZxbOFgP.js.map → balance-badge-cell-DbgEQsou.js.map} +1 -1
- package/dist/_chunks/{button-group-ZVb1Q-w4.js → button-group-CUnNnt8a.js} +2 -2
- package/dist/_chunks/{button-group-ZVb1Q-w4.js.map → button-group-CUnNnt8a.js.map} +1 -1
- package/dist/_chunks/{calendar-appointment-editor-dialog-WDKc3jMA.js → calendar-appointment-editor-dialog-D3tQ8N34.js} +11 -11
- package/dist/_chunks/{calendar-appointment-editor-dialog-WDKc3jMA.js.map → calendar-appointment-editor-dialog-D3tQ8N34.js.map} +1 -1
- package/dist/_chunks/{care-plan-card-DD9rEWYN.js → care-plan-card-YWKV8Kjq.js} +2 -2
- package/dist/_chunks/{care-plan-card-DD9rEWYN.js.map → care-plan-card-YWKV8Kjq.js.map} +1 -1
- package/dist/_chunks/{care-plan-entry-card-4VaY2c96.js → care-plan-entry-card-CApivtMW.js} +2 -2
- package/dist/_chunks/{care-plan-entry-card-4VaY2c96.js.map → care-plan-entry-card-CApivtMW.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-CXUJQt8Q.js → care-plan-header-BBh0X7EO.js} +2 -2
- package/dist/_chunks/{care-plan-header-CXUJQt8Q.js.map → care-plan-header-BBh0X7EO.js.map} +1 -1
- package/dist/_chunks/{chart-pMkQN-qy.js → chart-bddVIElM.js} +2 -2
- package/dist/_chunks/{chart-pMkQN-qy.js.map → chart-bddVIElM.js.map} +1 -1
- package/dist/_chunks/{dashboard-grid-DwJ_HV3d.js → dashboard-grid-DrOkTtya.js} +2 -2
- package/dist/_chunks/{dashboard-grid-DwJ_HV3d.js.map → dashboard-grid-DrOkTtya.js.map} +1 -1
- package/dist/_chunks/{data-table-C_nnpJ-Q.js → data-table-Bh9_IEj4.js} +3 -3
- package/dist/_chunks/{data-table-C_nnpJ-Q.js.map → data-table-Bh9_IEj4.js.map} +1 -1
- package/dist/_chunks/{document-preview-ytR1FcWA.js → document-preview-CL1xsnLS.js} +2 -2
- package/dist/_chunks/{document-preview-ytR1FcWA.js.map → document-preview-CL1xsnLS.js.map} +1 -1
- package/dist/_chunks/{dropdown-menu-D1we7oAY.js → dropdown-menu-CqxBthww.js} +2 -2
- package/dist/_chunks/{dropdown-menu-D1we7oAY.js.map → dropdown-menu-CqxBthww.js.map} +1 -1
- package/dist/_chunks/{editable-currency-cell-renderer-rWYiF4EI.js → editable-currency-cell-renderer-BQYL5GjP.js} +2 -2
- package/dist/_chunks/{editable-currency-cell-renderer-rWYiF4EI.js.map → editable-currency-cell-renderer-BQYL5GjP.js.map} +1 -1
- package/dist/_chunks/{face-scheme-BKSE98bo.js → face-scheme-DyHc3zPt.js} +4 -4
- package/dist/_chunks/{face-scheme-BKSE98bo.js.map → face-scheme-DyHc3zPt.js.map} +1 -1
- package/dist/_chunks/{file-manager-CAIbuaSs.js → file-manager-Cgf2yc10.js} +4 -4
- package/dist/_chunks/{file-manager-CAIbuaSs.js.map → file-manager-Cgf2yc10.js.map} +1 -1
- package/dist/_chunks/{header-settings-BeA2fnol.js → header-settings-DittkpqU.js} +2 -2
- package/dist/_chunks/{header-settings-BeA2fnol.js.map → header-settings-DittkpqU.js.map} +1 -1
- package/dist/_chunks/{heatmap-DdF8qTTV.js → heatmap-9Ql8Ny9d.js} +2 -2
- package/dist/_chunks/{heatmap-DdF8qTTV.js.map → heatmap-9Ql8Ny9d.js.map} +1 -1
- package/dist/_chunks/{icon-button-group-CRKFR48b.js → icon-button-group-mXvYDaba.js} +2 -2
- package/dist/_chunks/{icon-button-group-CRKFR48b.js.map → icon-button-group-mXvYDaba.js.map} +1 -1
- package/dist/_chunks/{marketplace-app-shell-CJQtx3sv.js → marketplace-app-shell-C8nHixB8.js} +4 -4
- package/dist/_chunks/{marketplace-app-shell-CJQtx3sv.js.map → marketplace-app-shell-C8nHixB8.js.map} +1 -1
- package/dist/_chunks/{message-tray-Cllf-v0G.js → message-tray-18_TrLCy.js} +2 -2
- package/dist/_chunks/{message-tray-Cllf-v0G.js.map → message-tray-18_TrLCy.js.map} +1 -1
- package/dist/_chunks/{muscle-scheme-B7qMW0ho.js → muscle-scheme-CznhrQlo.js} +2 -2
- package/dist/_chunks/{muscle-scheme-B7qMW0ho.js.map → muscle-scheme-CznhrQlo.js.map} +1 -1
- package/dist/_chunks/{notes-panel-ib7I3aNf.js → notes-panel-D6YhNGHU.js} +2 -2
- package/dist/_chunks/{notes-panel-ib7I3aNf.js.map → notes-panel-D6YhNGHU.js.map} +1 -1
- package/dist/_chunks/{notification-tray-0OkA2duS.js → notification-tray-CQK3lw87.js} +2 -2
- package/dist/_chunks/{notification-tray-0OkA2duS.js.map → notification-tray-CQK3lw87.js.map} +1 -1
- package/dist/_chunks/{patient-details-DTlpBYHJ.js → patient-details-DQQpgx4A.js} +2 -2
- package/dist/_chunks/{patient-details-DTlpBYHJ.js.map → patient-details-DQQpgx4A.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-DWTKV1hF.js → patient-field-row-Cb5jUd5Q.js} +2 -2
- package/dist/_chunks/{patient-field-row-DWTKV1hF.js.map → patient-field-row-Cb5jUd5Q.js.map} +1 -1
- package/dist/_chunks/{patient-search-Ca9j5cWb.js → patient-search-Cp2efqHs.js} +2 -2
- package/dist/_chunks/{patient-search-Ca9j5cWb.js.map → patient-search-Cp2efqHs.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-C61AR4Tn.js → patient-summary-card-BvMI0eMu.js} +2 -2
- package/dist/_chunks/{patient-summary-card-C61AR4Tn.js.map → patient-summary-card-BvMI0eMu.js.map} +1 -1
- package/dist/_chunks/{practice-results-BWX9y6mS.js → practice-results-ZOVlrb43.js} +3 -3
- package/dist/_chunks/practice-results-ZOVlrb43.js.map +1 -0
- package/dist/_chunks/{product-hub-panel-bHi7lkVD.js → product-hub-panel-CqRJlmb7.js} +2 -2
- package/dist/_chunks/{product-hub-panel-bHi7lkVD.js.map → product-hub-panel-CqRJlmb7.js.map} +1 -1
- package/dist/_chunks/{public-footer-IoRWoAMz.js → public-footer-BiPiU_lk.js} +2 -2
- package/dist/_chunks/{public-footer-IoRWoAMz.js.map → public-footer-BiPiU_lk.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-BfEu57dk.js → rich-text-editor-iw2tJLKA.js} +2 -2
- package/dist/_chunks/{rich-text-editor-BfEu57dk.js.map → rich-text-editor-iw2tJLKA.js.map} +1 -1
- package/dist/_chunks/{separator-CYU_bGFn.js → separator-Bdc9bqoJ.js} +18 -19
- package/dist/_chunks/separator-Bdc9bqoJ.js.map +1 -0
- package/dist/_chunks/{signature-request-BVGeF0qB.js → signature-request-CLtMgQKi.js} +3 -3
- package/dist/_chunks/{signature-request-BVGeF0qB.js.map → signature-request-CLtMgQKi.js.map} +1 -1
- package/dist/_chunks/{signed-out-frame-CgRXOUzi.js → signed-out-frame-CRwVTCjY.js} +2 -2
- package/dist/_chunks/{signed-out-frame-CgRXOUzi.js.map → signed-out-frame-CRwVTCjY.js.map} +1 -1
- package/dist/_chunks/{tab-bar-BEODTG6k.js → tab-bar-C_pggqVr.js} +2 -2
- package/dist/_chunks/{tab-bar-BEODTG6k.js.map → tab-bar-C_pggqVr.js.map} +1 -1
- package/dist/_chunks/{tabs-BmxQu-TJ.js → tabs-DYHgRVSJ.js} +2 -2
- package/dist/_chunks/{tabs-BmxQu-TJ.js.map → tabs-DYHgRVSJ.js.map} +1 -1
- package/dist/_chunks/{task-editor-Cv7xSakv.js → task-editor-BlGdXR9F.js} +2 -2
- package/dist/_chunks/{task-editor-Cv7xSakv.js.map → task-editor-BlGdXR9F.js.map} +1 -1
- package/dist/_chunks/{tasks-panel-BTCYGLGA.js → tasks-panel-Q0CiEAff.js} +2 -2
- package/dist/_chunks/{tasks-panel-BTCYGLGA.js.map → tasks-panel-Q0CiEAff.js.map} +1 -1
- package/dist/_chunks/{theme-toggle-DKpzb0-M.js → theme-toggle-jZRbAidE.js} +3 -3
- package/dist/_chunks/{theme-toggle-DKpzb0-M.js.map → theme-toggle-jZRbAidE.js.map} +1 -1
- package/dist/_chunks/{token-insert-menu-DtAnBd0x.js → token-insert-menu-Dl3x2ekR.js} +2 -2
- package/dist/_chunks/{token-insert-menu-DtAnBd0x.js.map → token-insert-menu-Dl3x2ekR.js.map} +1 -1
- package/dist/_chunks/{tooth-scheme-COJJkdsi.js → tooth-scheme-Bd7xECuj.js} +2 -2
- package/dist/_chunks/{tooth-scheme-COJJkdsi.js.map → tooth-scheme-Bd7xECuj.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-B6uhmNdV.js → use-appointment-details-read-CpXRSfPI.js} +5 -5
- package/dist/_chunks/{use-appointment-details-read-B6uhmNdV.js.map → use-appointment-details-read-CpXRSfPI.js.map} +1 -1
- package/dist/_chunks/{workflow-map-BcfOwsSB.js → workflow-map-BWJhlZbC.js} +2 -2
- package/dist/_chunks/{workflow-map-BcfOwsSB.js.map → workflow-map-BWJhlZbC.js.map} +1 -1
- package/dist/_chunks/{workflow-status-Dc_CyEz5.js → workflow-status-HQ6ziE46.js} +2 -2
- package/dist/_chunks/{workflow-status-Dc_CyEz5.js.map → workflow-status-HQ6ziE46.js.map} +1 -1
- package/dist/_chunks/{workflow-webhook-action-B_nBJ_ht.js → workflow-webhook-action-Uhyfr6_6.js} +2 -2
- package/dist/_chunks/{workflow-webhook-action-B_nBJ_ht.js.map → workflow-webhook-action-Uhyfr6_6.js.map} +1 -1
- package/dist/agent-catalog.json +1 -1
- package/dist/components/appointment-card/index.js +2 -2
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/appointment-peek/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/button-group/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-entry-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/chart/index.js +1 -1
- package/dist/components/dashboard-grid/index.js +1 -1
- package/dist/components/data-table/index.js +3 -3
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/dropdown-menu/index.js +1 -1
- package/dist/components/face-scheme/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/heatmap/index.js +1 -1
- package/dist/components/icon-button-group/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/muscle-scheme/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/public-footer/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/separator/index.js +1 -1
- package/dist/components/separator/separator.d.ts.map +1 -1
- package/dist/components/skeleton-scheme/index.js +1 -1
- package/dist/components/tab-bar/index.js +1 -1
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/token-insert-menu/index.js +1 -1
- package/dist/components/tooth-scheme/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/components/workflow-status/index.js +1 -1
- package/dist/core.css +1 -1
- package/dist/host-compat.css +4 -1
- package/dist/index.js +48 -48
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/patterns/signed-out-frame/index.js +1 -1
- package/dist/patterns/workflow-webhook-action/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/practice-results-BWX9y6mS.js.map +0 -1
- package/dist/_chunks/separator-CYU_bGFn.js.map +0 -1
|
@@ -7,7 +7,7 @@ import { C as B } from "./card-BA4Ig_kn.js";
|
|
|
7
7
|
import { E as G } from "./empty-state-DwJ5YNzz.js";
|
|
8
8
|
import { P as Y } from "./panel-header-CbtlTe85.js";
|
|
9
9
|
import { P as J } from "./pdf-viewer-gAsNUsA8.js";
|
|
10
|
-
import { T as O, b as Q, c as X, a as Z } from "./tabs-
|
|
10
|
+
import { T as O, b as Q, c as X, a as Z } from "./tabs-DYHgRVSJ.js";
|
|
11
11
|
import { u as ee } from "./registry-DvAUVLHh.js";
|
|
12
12
|
import { F as ie } from "./file-image-cDgE-BTy.js";
|
|
13
13
|
import { F as te } from "./file-text-5yv6r2ls.js";
|
|
@@ -288,4 +288,4 @@ export {
|
|
|
288
288
|
ue as D,
|
|
289
289
|
de as d
|
|
290
290
|
};
|
|
291
|
-
//# sourceMappingURL=document-preview-
|
|
291
|
+
//# sourceMappingURL=document-preview-CL1xsnLS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document-preview-ytR1FcWA.js","sources":["../../node_modules/lucide-react/dist/esm/icons/files.mjs","../../src/components/document-preview/document-preview.agent.ts","../../src/components/document-preview/document-preview.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8\", key: \"14sh0y\" }],\n [\n \"path\",\n {\n d: \"M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z\",\n key: \"1970lx\"\n }\n ],\n [\"path\", { d: \"M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1\", key: \"l4dndm\" }]\n];\nconst Files = createLucideIcon(\"files\", __iconNode);\n\nexport { __iconNode, Files as default };\n//# sourceMappingURL=files.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — DocumentPreview. */\n/* */\n/* A passive, read-only viewer, so it declares no interactive */\n/* capabilities. The always-on state slot carries only the structural */\n/* render `kind` (pdf / image / metadata / empty) — never the document */\n/* name. */\n/* */\n/* PHI rule (PRS §26 §7): the document display name can identify a */\n/* patient (e.g. \"Rossi Maria — referto 2026.pdf\"). It renders as text */\n/* (fine) but the only name-returning read is the deliberate get_name */\n/* action with `safety: 'phi'`, so the host gates it behind confirm + */\n/* audit. No name is ever emitted in a data-* hook. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DocumentPreviewHandle } from './document-preview';\n\nexport const documentPreviewAgent: AgentAdapter<DocumentPreviewHandle> = {\n id: 'document-preview',\n capabilities: [],\n state: {\n kind: {\n type: \"'pdf' | 'image' | 'metadata' | 'empty'\",\n descriptionKey: 'ui.agent.documentPreview.state.kind',\n description:\n 'Which render branch is active: pdf, image, metadata (no inline preview), or empty (no document). Structural — never the document name.',\n read: (handle) => handle.getKind(),\n },\n },\n actions: {\n get_name: {\n // phi (not read): resolves the document display name, which can identify\n // patients. PRS §26 — phi outranks read so the host gates it behind\n // stricter confirm + audit. The always-on kind slot stays name-free.\n safety: 'phi',\n returns: 'string | undefined',\n returnsSchema: { type: ['string', 'null'] },\n idempotent: true,\n descriptionKey: 'ui.agent.documentPreview.actions.getName',\n description:\n 'Read the display name of the previewed document. May identify a patient (PHI).',\n invoke: (handle) => handle.getName(),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'document-preview',\n description: 'Marks the DocumentPreview region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* DocumentPreview — a standalone, reusable document viewer. */\n/* */\n/* Decoupled from FileManager: it takes primitive props (name, mimeType, */\n/* src, metadata) rather than a FileManagerItem, so signing, the patient */\n/* portal, and the Control Room rail can all reuse it. The body is an */\n/* elevated Card: a bounded preview viewport (PDF → kit PDFViewer; */\n/* image/* → <img>; otherwise a MIME-icon placeholder) above an always-on */\n/* Details block (badges + every structural field the host supplies), so */\n/* the metadata is never dropped when a real preview renders. No name → */\n/* EmptyState. */\n/* */\n/* Title lives in the canonical PanelHeader (the same header every rail */\n/* panel adopts) so the Control Room rail can inject its pin / close */\n/* controls into it. Pass `documents` (≥ 2) to preview a SELECTION as */\n/* tabs — one tab per document, the active one shown below; a single */\n/* entry (or the single-document props) renders without a tab strip. */\n/* */\n/* The root is a `<section>` (region landmark) so the PanelHeader's */\n/* <header> is scoped and never exposed as a page banner — the same */\n/* shape RadiographPanel uses. It is also a keyboard-focusable scroll */\n/* region (tabIndex 0 + labelled focus ring). */\n/* */\n/* PHI: the visible name renders as text (fine), but the only */\n/* name-returning handle read is surfaced by document-preview.agent.ts */\n/* as a `safety: 'phi'` action — never in always-on state, never in a */\n/* data-* hook. In tabbed mode the handle reflects the ACTIVE tab. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n Fragment,\n useImperativeHandle,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n File as FileIcon,\n FileImage,\n FileText,\n Files,\n type LucideIcon,\n} from 'lucide-react';\nimport { Badge } from '../badge';\nimport { Card } from '../card';\nimport { EmptyState } from '../empty-state';\nimport { PanelHeader } from '../panel-header';\nimport { PDFViewer } from '../pdf-viewer';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '../tabs';\nimport { useAgentRegistration } from '../../agent';\nimport { documentPreviewAgent } from './document-preview.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type DocumentPreviewSignatureStatus = 'none' | 'pending' | 'signed';\n\n/** Which render branch DocumentPreview is showing — structural, never PHI. */\nexport type DocumentPreviewKind = 'pdf' | 'image' | 'metadata' | 'empty';\n\nexport interface DocumentPreviewMetadata {\n /** Size in bytes. */\n size?: number;\n /** Display name of whoever created the document (host-supplied). */\n createdBy?: string;\n /** ISO 8601 timestamp the document was created. */\n createdAt?: string;\n /** ISO 8601 timestamp of the last modification. */\n updatedAt?: string;\n /** ISO 8601 timestamp a signature was requested from the patient. */\n signatureRequestedAt?: string;\n /** ISO 8601 timestamp the document was signed. */\n signedAt?: string;\n /** ISO 8601 timestamp the document was shared with the patient. */\n sharedAt?: string;\n /** Open document-type category (non-identifying), e.g. `'xray'`. */\n documentType?: string;\n /** Signature workflow state. */\n signatureStatus?: DocumentPreviewSignatureStatus;\n /** Clinical-document flag (host-defined semantics). */\n clinical?: boolean;\n /** ISO 8601 expiry (e.g. identification documents). */\n expiresAt?: string;\n}\n\n/**\n * A single previewable document. In multi-document mode each becomes a tab;\n * `id` is the tab value (never a patient name) and `name` is the tab label.\n */\nexport interface DocumentPreviewDocument {\n /** Stable, non-identifying id. Emitted as the tab value — never PHI. */\n id: string;\n /** Display name (PHI). Also the tab label in multi-document mode. */\n name: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n}\n\nexport interface DocumentPreviewProps extends VariantProps<\n typeof documentPreviewVariants\n> {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Display name. Absent (and no `documents`) → empty state. PHI. */\n name?: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. The host owns auth. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n /**\n * Multiple documents to preview as tabs — e.g. a multi-row selection. Two\n * or more render a tab per document (label = name) with the active one\n * shown below; a single entry renders without a tab strip. When non-empty\n * this takes precedence over the single-document props. Names are PHI.\n */\n documents?: DocumentPreviewDocument[];\n className?: string;\n}\n\nexport interface DocumentPreviewHandle {\n /** Which render branch is active — structural, safe for always-on reads. */\n getKind: () => DocumentPreviewKind;\n /** The active document's display name (PHI). Surfaced by the adapter as a `phi` action. */\n getName: () => string | undefined;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst documentPreviewVariants = cva(\n [\n 'ds:flex ds:h-full ds:min-h-0 ds:min-w-0 ds:flex-col ds:overflow-auto',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring',\n ].join(' '),\n);\n\nconst SIGNATURE_VARIANT: Record<\n Exclude<DocumentPreviewSignatureStatus, 'none'>,\n 'success' | 'warning'\n> = {\n signed: 'success',\n pending: 'warning',\n};\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction resolveKind(\n name: string | undefined,\n mimeType: string | undefined,\n src: string | undefined,\n): DocumentPreviewKind {\n if (!name) return 'empty';\n const mime = mimeType ?? '';\n if (mime === 'application/pdf' && src) return 'pdf';\n if (mime.startsWith('image/') && src) return 'image';\n return 'metadata';\n}\n\n/** Fallback icon for the header / metadata card — a small MIME-family lookup. */\nfunction iconForMime(mimeType: string | undefined): LucideIcon {\n const mime = mimeType ?? '';\n if (mime.startsWith('image/')) return FileImage;\n if (\n mime === 'application/pdf' ||\n mime.startsWith('text/') ||\n mime.includes('word')\n ) {\n return FileText;\n }\n return FileIcon;\n}\n\nconst UNIT_KEYS = [\n 'documentPreview.units.bytes',\n 'documentPreview.units.kilobytes',\n 'documentPreview.units.megabytes',\n 'documentPreview.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nfunction formatBytes(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n return `${formatted} ${t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex])}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const DocumentPreview = forwardRef<\n DocumentPreviewHandle,\n DocumentPreviewProps\n>(({ id, name, mimeType, src, metadata, documents, className }, ref) => {\n const { t, i18n } = useTranslation('ui');\n\n // Resolve the document list: an explicit `documents` list wins; otherwise\n // the single-document props form a one-item list; nothing → empty. The\n // synthetic single-doc id is never emitted as a tab value (a lone doc\n // renders without a tab strip), so falling back to the name is PHI-safe.\n const docs = useMemo<DocumentPreviewDocument[]>(() => {\n if (documents && documents.length > 0) return documents;\n if (name) return [{ id: id ?? name, name, mimeType, src, metadata }];\n return [];\n }, [documents, id, name, mimeType, src, metadata]);\n\n const isTabbed = docs.length > 1;\n\n // Active tab (multi mode). When the current id is stale after the selection\n // changes we fall back to the first document — no reconciling effect needed.\n const [activeId, setActiveId] = useState<string | undefined>(undefined);\n const activeDoc = docs.find((doc) => doc.id === activeId) ?? docs[0];\n\n const handle = useMemo<DocumentPreviewHandle>(\n () => ({\n getKind: () =>\n activeDoc\n ? resolveKind(activeDoc.name, activeDoc.mimeType, activeDoc.src)\n : 'empty',\n getName: () => activeDoc?.name,\n }),\n [activeDoc],\n );\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(documentPreviewAgent, handle, id);\n\n /* The per-document body — an elevated Card with a bounded preview viewport\n (pdf / image / placeholder) above an always-on Details block. The title is\n NOT rendered here (the PanelHeader owns it, or the tab label in multi mode). */\n const renderBody = (doc: DocumentPreviewDocument): ReactNode => {\n const kind = resolveKind(doc.name, doc.mimeType, doc.src);\n const meta = doc.metadata;\n const PlaceholderIcon = iconForMime(doc.mimeType);\n\n // Preview viewport — the rendered document, or a MIME-icon placeholder when\n // no source resolves. Bounded to a consistent aspect so the Details below\n // stay reachable in the rail.\n let viewport: ReactNode;\n if (kind === 'pdf' && doc.src) {\n viewport = (\n <PDFViewer\n src={doc.src}\n toolbarVariant=\"minimal\"\n // Name the embedded viewer after the document so it stays distinct\n // from the surrounding \"Document preview\" region (nested landmarks\n // must not share an accessible name). Mirrors visible header text.\n ariaLabel={doc.name}\n className=\"ds:h-full ds:w-full\"\n />\n );\n } else if (kind === 'image' && doc.src) {\n viewport = (\n <img\n src={doc.src}\n alt={t('documentPreview.imageAlt', 'Preview of {{name}}', {\n name: doc.name,\n })}\n className=\"ds:max-h-full ds:max-w-full ds:object-contain\"\n />\n );\n } else {\n viewport = (\n <span className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-muted-foreground\">\n <PlaceholderIcon aria-hidden=\"true\" className=\"ds:size-10\" />\n <span className=\"type-body-sm\">\n {t('documentPreview.noPreview', 'No preview available.')}\n </span>\n </span>\n );\n }\n\n // Badges: type / clinical / signature status.\n const status = meta?.signatureStatus;\n const hasBadges =\n Boolean(meta?.documentType) ||\n Boolean(meta?.clinical) ||\n (status !== undefined && status !== 'none');\n\n // Detail rows — every structural field the host supplies, so nothing is\n // dropped when a real preview renders. Only present fields render a row.\n const fmtDate = (iso: string): string =>\n new Intl.DateTimeFormat(i18n.language, { dateStyle: 'medium' }).format(\n new Date(iso),\n );\n const rows: Array<{ key: string; label: string; value: string }> = [];\n if (meta?.createdBy)\n rows.push({\n key: 'createdBy',\n label: t('documentPreview.fields.createdBy', 'Created by'),\n value: meta.createdBy,\n });\n if (meta?.createdAt)\n rows.push({\n key: 'created',\n label: t('documentPreview.fields.created', 'Created'),\n value: fmtDate(meta.createdAt),\n });\n if (meta?.updatedAt)\n rows.push({\n key: 'modified',\n label: t('documentPreview.fields.modified', 'Modified'),\n value: fmtDate(meta.updatedAt),\n });\n if (meta?.signatureRequestedAt)\n rows.push({\n key: 'signatureRequested',\n label: t(\n 'documentPreview.fields.signatureRequested',\n 'Signature requested',\n ),\n value: fmtDate(meta.signatureRequestedAt),\n });\n if (meta?.signedAt)\n rows.push({\n key: 'signed',\n label: t('documentPreview.fields.signed', 'Signed'),\n value: fmtDate(meta.signedAt),\n });\n if (meta?.sharedAt)\n rows.push({\n key: 'sharedWithPatient',\n label: t(\n 'documentPreview.fields.sharedWithPatient',\n 'Shared with patient',\n ),\n value: fmtDate(meta.sharedAt),\n });\n if (meta?.size !== undefined)\n rows.push({\n key: 'size',\n label: t('documentPreview.fields.size', 'Size'),\n value: formatBytes(meta.size, i18n.language, t),\n });\n if (meta?.expiresAt)\n rows.push({\n key: 'expires',\n label: t('documentPreview.fields.expires', 'Expires'),\n value: fmtDate(meta.expiresAt),\n });\n\n const hasDetails = hasBadges || rows.length > 0;\n\n return (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <Card\n variant=\"elevated\"\n className=\"ds:flex ds:flex-col ds:overflow-hidden\"\n >\n <div className=\"ds:flex ds:aspect-[4/3] ds:min-h-0 ds:items-center ds:justify-center ds:overflow-hidden ds:border-b ds:border-[color:var(--card-border)] ds:bg-muted\">\n {viewport}\n </div>\n {hasDetails && (\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3 className=\"type-eyebrow ds:m-0 ds:text-muted-foreground\">\n {t('documentPreview.detailsTitle', 'Details')}\n </h3>\n {hasBadges && (\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {meta?.documentType && (\n <Badge variant=\"neutral\" size=\"sm\">\n {meta.documentType}\n </Badge>\n )}\n {meta?.clinical && (\n <Badge variant=\"info\" size=\"sm\">\n {t('documentPreview.clinical', 'Clinical')}\n </Badge>\n )}\n {status && status !== 'none' && (\n <Badge\n variant={SIGNATURE_VARIANT[status]}\n size=\"sm\"\n withDot\n >\n {t(`documentPreview.signature.${status}`, status)}\n </Badge>\n )}\n </span>\n )}\n {rows.length > 0 && (\n <dl className=\"ds:grid ds:grid-cols-[auto_1fr] ds:gap-x-[var(--spacing-md)] ds:gap-y-[var(--spacing-xs)] type-body-sm\">\n {rows.map((row) => (\n <Fragment key={row.key}>\n <dt className=\"ds:text-muted-foreground\">{row.label}</dt>\n <dd className=\"ds:m-0\">{row.value}</dd>\n </Fragment>\n ))}\n </dl>\n )}\n </Card.Body>\n )}\n </Card>\n </div>\n );\n };\n\n // Header: a MIME icon + the document name for a single doc; a Files glyph +\n // a count badge (RadiographPanel's title-plus-badge shape) when tabbed.\n const HeaderMimeIcon = iconForMime(activeDoc?.mimeType);\n const headerIcon = isTabbed ? (\n <Files aria-hidden=\"true\" />\n ) : (\n <HeaderMimeIcon aria-hidden=\"true\" />\n );\n const headerTitle: ReactNode = isTabbed ? (\n <>\n {t('documentPreview.multiTitle', 'Documents')}\n <Badge variant=\"neutral\" size=\"sm\">\n {docs.length}\n </Badge>\n </>\n ) : (\n activeDoc?.name\n );\n\n let content: ReactNode;\n if (docs.length === 0) {\n content = (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t('documentPreview.emptyTitle', 'No document selected')}\n description={t(\n 'documentPreview.emptyDescription',\n 'Select a document to preview it here.',\n )}\n />\n );\n } else if (isTabbed) {\n content = (\n <Tabs\n value={activeDoc?.id ?? ''}\n onValueChange={setActiveId}\n variant=\"underlined\"\n size=\"sm\"\n // Each tab shows its full file name when there's room and shrinks with\n // an ellipsis only when the tabs would otherwise overflow the width\n // (`min-inline-size:0` lets a tab shrink below its content; the label\n // truncates). The full name stays the accessible name and shows in the\n // body, so nothing is lost.\n className=\"ds:min-h-0 ds:flex-1 ds:pt-[var(--spacing-sm)]\"\n >\n <TabsList\n aria-label={t('documentPreview.tabsLabel', 'Selected documents')}\n className=\"ds:gap-[var(--spacing-sm)]\"\n >\n {docs.map((doc) => {\n const TabIcon = iconForMime(doc.mimeType);\n return (\n <TabsTrigger\n key={doc.id}\n value={doc.id}\n // Match the header glyph: same 16px size (never larger) and the\n // accent tint that marks a file across the grid and the rail.\n icon={\n <TabIcon\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:text-[color:var(--accent)]\"\n />\n }\n className=\"ds:[min-inline-size:0]\"\n >\n <span className=\"ds:block ds:truncate ds:[min-inline-size:0]\">\n {doc.name}\n </span>\n </TabsTrigger>\n );\n })}\n </TabsList>\n {docs.map((doc) => (\n <TabsContent\n key={doc.id}\n value={doc.id}\n className=\"ds:min-h-0 ds:flex-1\"\n >\n {renderBody(doc)}\n </TabsContent>\n ))}\n </Tabs>\n );\n } else {\n content = renderBody(activeDoc);\n }\n\n return (\n <section\n data-component=\"document-preview\"\n data-component-id={id}\n // The preview body scrolls (PDF pages, tall images, long metadata), so\n // the region needs a keyboard tab stop (axe scrollable-region-focusable).\n // A labelled <section> is a region landmark, which also scopes the\n // PanelHeader's <header> so it is never exposed as a page banner.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- keyboard-focusable scroll region (see comment above)\n tabIndex={0}\n aria-label={t('documentPreview.regionLabel', 'Document preview')}\n className={documentPreviewVariants({ className })}\n >\n {docs.length > 0 && (\n <PanelHeader sticky icon={headerIcon} title={headerTitle} />\n )}\n {content}\n </section>\n );\n});\n\nDocumentPreview.displayName = 'DocumentPreview';\n"],"names":["__iconNode","Files","createLucideIcon","documentPreviewAgent","handle","documentPreviewVariants","cva","SIGNATURE_VARIANT","resolveKind","name","mimeType","src","mime","iconForMime","FileImage","FileText","FileIcon","UNIT_KEYS","UNIT_FALLBACKS","formatBytes","bytes","locale","t","value","unitIndex","DocumentPreview","forwardRef","id","metadata","documents","className","ref","i18n","useTranslation","docs","useMemo","isTabbed","activeId","setActiveId","useState","activeDoc","doc","useImperativeHandle","useAgentRegistration","renderBody","kind","meta","PlaceholderIcon","viewport","jsx","PDFViewer","jsxs","status","hasBadges","fmtDate","iso","rows","hasDetails","Card","Badge","row","Fragment","HeaderMimeIcon","headerIcon","headerTitle","content","EmptyState","Tabs","TabsList","TabIcon","TabsTrigger","TabsContent","PanelHeader"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"document-preview-CL1xsnLS.js","sources":["../../node_modules/lucide-react/dist/esm/icons/files.mjs","../../src/components/document-preview/document-preview.agent.ts","../../src/components/document-preview/document-preview.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8\", key: \"14sh0y\" }],\n [\n \"path\",\n {\n d: \"M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z\",\n key: \"1970lx\"\n }\n ],\n [\"path\", { d: \"M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1\", key: \"l4dndm\" }]\n];\nconst Files = createLucideIcon(\"files\", __iconNode);\n\nexport { __iconNode, Files as default };\n//# sourceMappingURL=files.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — DocumentPreview. */\n/* */\n/* A passive, read-only viewer, so it declares no interactive */\n/* capabilities. The always-on state slot carries only the structural */\n/* render `kind` (pdf / image / metadata / empty) — never the document */\n/* name. */\n/* */\n/* PHI rule (PRS §26 §7): the document display name can identify a */\n/* patient (e.g. \"Rossi Maria — referto 2026.pdf\"). It renders as text */\n/* (fine) but the only name-returning read is the deliberate get_name */\n/* action with `safety: 'phi'`, so the host gates it behind confirm + */\n/* audit. No name is ever emitted in a data-* hook. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DocumentPreviewHandle } from './document-preview';\n\nexport const documentPreviewAgent: AgentAdapter<DocumentPreviewHandle> = {\n id: 'document-preview',\n capabilities: [],\n state: {\n kind: {\n type: \"'pdf' | 'image' | 'metadata' | 'empty'\",\n descriptionKey: 'ui.agent.documentPreview.state.kind',\n description:\n 'Which render branch is active: pdf, image, metadata (no inline preview), or empty (no document). Structural — never the document name.',\n read: (handle) => handle.getKind(),\n },\n },\n actions: {\n get_name: {\n // phi (not read): resolves the document display name, which can identify\n // patients. PRS §26 — phi outranks read so the host gates it behind\n // stricter confirm + audit. The always-on kind slot stays name-free.\n safety: 'phi',\n returns: 'string | undefined',\n returnsSchema: { type: ['string', 'null'] },\n idempotent: true,\n descriptionKey: 'ui.agent.documentPreview.actions.getName',\n description:\n 'Read the display name of the previewed document. May identify a patient (PHI).',\n invoke: (handle) => handle.getName(),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'document-preview',\n description: 'Marks the DocumentPreview region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* DocumentPreview — a standalone, reusable document viewer. */\n/* */\n/* Decoupled from FileManager: it takes primitive props (name, mimeType, */\n/* src, metadata) rather than a FileManagerItem, so signing, the patient */\n/* portal, and the Control Room rail can all reuse it. The body is an */\n/* elevated Card: a bounded preview viewport (PDF → kit PDFViewer; */\n/* image/* → <img>; otherwise a MIME-icon placeholder) above an always-on */\n/* Details block (badges + every structural field the host supplies), so */\n/* the metadata is never dropped when a real preview renders. No name → */\n/* EmptyState. */\n/* */\n/* Title lives in the canonical PanelHeader (the same header every rail */\n/* panel adopts) so the Control Room rail can inject its pin / close */\n/* controls into it. Pass `documents` (≥ 2) to preview a SELECTION as */\n/* tabs — one tab per document, the active one shown below; a single */\n/* entry (or the single-document props) renders without a tab strip. */\n/* */\n/* The root is a `<section>` (region landmark) so the PanelHeader's */\n/* <header> is scoped and never exposed as a page banner — the same */\n/* shape RadiographPanel uses. It is also a keyboard-focusable scroll */\n/* region (tabIndex 0 + labelled focus ring). */\n/* */\n/* PHI: the visible name renders as text (fine), but the only */\n/* name-returning handle read is surfaced by document-preview.agent.ts */\n/* as a `safety: 'phi'` action — never in always-on state, never in a */\n/* data-* hook. In tabbed mode the handle reflects the ACTIVE tab. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n Fragment,\n useImperativeHandle,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n File as FileIcon,\n FileImage,\n FileText,\n Files,\n type LucideIcon,\n} from 'lucide-react';\nimport { Badge } from '../badge';\nimport { Card } from '../card';\nimport { EmptyState } from '../empty-state';\nimport { PanelHeader } from '../panel-header';\nimport { PDFViewer } from '../pdf-viewer';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '../tabs';\nimport { useAgentRegistration } from '../../agent';\nimport { documentPreviewAgent } from './document-preview.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type DocumentPreviewSignatureStatus = 'none' | 'pending' | 'signed';\n\n/** Which render branch DocumentPreview is showing — structural, never PHI. */\nexport type DocumentPreviewKind = 'pdf' | 'image' | 'metadata' | 'empty';\n\nexport interface DocumentPreviewMetadata {\n /** Size in bytes. */\n size?: number;\n /** Display name of whoever created the document (host-supplied). */\n createdBy?: string;\n /** ISO 8601 timestamp the document was created. */\n createdAt?: string;\n /** ISO 8601 timestamp of the last modification. */\n updatedAt?: string;\n /** ISO 8601 timestamp a signature was requested from the patient. */\n signatureRequestedAt?: string;\n /** ISO 8601 timestamp the document was signed. */\n signedAt?: string;\n /** ISO 8601 timestamp the document was shared with the patient. */\n sharedAt?: string;\n /** Open document-type category (non-identifying), e.g. `'xray'`. */\n documentType?: string;\n /** Signature workflow state. */\n signatureStatus?: DocumentPreviewSignatureStatus;\n /** Clinical-document flag (host-defined semantics). */\n clinical?: boolean;\n /** ISO 8601 expiry (e.g. identification documents). */\n expiresAt?: string;\n}\n\n/**\n * A single previewable document. In multi-document mode each becomes a tab;\n * `id` is the tab value (never a patient name) and `name` is the tab label.\n */\nexport interface DocumentPreviewDocument {\n /** Stable, non-identifying id. Emitted as the tab value — never PHI. */\n id: string;\n /** Display name (PHI). Also the tab label in multi-document mode. */\n name: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n}\n\nexport interface DocumentPreviewProps extends VariantProps<\n typeof documentPreviewVariants\n> {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Display name. Absent (and no `documents`) → empty state. PHI. */\n name?: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. The host owns auth. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n /**\n * Multiple documents to preview as tabs — e.g. a multi-row selection. Two\n * or more render a tab per document (label = name) with the active one\n * shown below; a single entry renders without a tab strip. When non-empty\n * this takes precedence over the single-document props. Names are PHI.\n */\n documents?: DocumentPreviewDocument[];\n className?: string;\n}\n\nexport interface DocumentPreviewHandle {\n /** Which render branch is active — structural, safe for always-on reads. */\n getKind: () => DocumentPreviewKind;\n /** The active document's display name (PHI). Surfaced by the adapter as a `phi` action. */\n getName: () => string | undefined;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst documentPreviewVariants = cva(\n [\n 'ds:flex ds:h-full ds:min-h-0 ds:min-w-0 ds:flex-col ds:overflow-auto',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring',\n ].join(' '),\n);\n\nconst SIGNATURE_VARIANT: Record<\n Exclude<DocumentPreviewSignatureStatus, 'none'>,\n 'success' | 'warning'\n> = {\n signed: 'success',\n pending: 'warning',\n};\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction resolveKind(\n name: string | undefined,\n mimeType: string | undefined,\n src: string | undefined,\n): DocumentPreviewKind {\n if (!name) return 'empty';\n const mime = mimeType ?? '';\n if (mime === 'application/pdf' && src) return 'pdf';\n if (mime.startsWith('image/') && src) return 'image';\n return 'metadata';\n}\n\n/** Fallback icon for the header / metadata card — a small MIME-family lookup. */\nfunction iconForMime(mimeType: string | undefined): LucideIcon {\n const mime = mimeType ?? '';\n if (mime.startsWith('image/')) return FileImage;\n if (\n mime === 'application/pdf' ||\n mime.startsWith('text/') ||\n mime.includes('word')\n ) {\n return FileText;\n }\n return FileIcon;\n}\n\nconst UNIT_KEYS = [\n 'documentPreview.units.bytes',\n 'documentPreview.units.kilobytes',\n 'documentPreview.units.megabytes',\n 'documentPreview.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nfunction formatBytes(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n return `${formatted} ${t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex])}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const DocumentPreview = forwardRef<\n DocumentPreviewHandle,\n DocumentPreviewProps\n>(({ id, name, mimeType, src, metadata, documents, className }, ref) => {\n const { t, i18n } = useTranslation('ui');\n\n // Resolve the document list: an explicit `documents` list wins; otherwise\n // the single-document props form a one-item list; nothing → empty. The\n // synthetic single-doc id is never emitted as a tab value (a lone doc\n // renders without a tab strip), so falling back to the name is PHI-safe.\n const docs = useMemo<DocumentPreviewDocument[]>(() => {\n if (documents && documents.length > 0) return documents;\n if (name) return [{ id: id ?? name, name, mimeType, src, metadata }];\n return [];\n }, [documents, id, name, mimeType, src, metadata]);\n\n const isTabbed = docs.length > 1;\n\n // Active tab (multi mode). When the current id is stale after the selection\n // changes we fall back to the first document — no reconciling effect needed.\n const [activeId, setActiveId] = useState<string | undefined>(undefined);\n const activeDoc = docs.find((doc) => doc.id === activeId) ?? docs[0];\n\n const handle = useMemo<DocumentPreviewHandle>(\n () => ({\n getKind: () =>\n activeDoc\n ? resolveKind(activeDoc.name, activeDoc.mimeType, activeDoc.src)\n : 'empty',\n getName: () => activeDoc?.name,\n }),\n [activeDoc],\n );\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(documentPreviewAgent, handle, id);\n\n /* The per-document body — an elevated Card with a bounded preview viewport\n (pdf / image / placeholder) above an always-on Details block. The title is\n NOT rendered here (the PanelHeader owns it, or the tab label in multi mode). */\n const renderBody = (doc: DocumentPreviewDocument): ReactNode => {\n const kind = resolveKind(doc.name, doc.mimeType, doc.src);\n const meta = doc.metadata;\n const PlaceholderIcon = iconForMime(doc.mimeType);\n\n // Preview viewport — the rendered document, or a MIME-icon placeholder when\n // no source resolves. Bounded to a consistent aspect so the Details below\n // stay reachable in the rail.\n let viewport: ReactNode;\n if (kind === 'pdf' && doc.src) {\n viewport = (\n <PDFViewer\n src={doc.src}\n toolbarVariant=\"minimal\"\n // Name the embedded viewer after the document so it stays distinct\n // from the surrounding \"Document preview\" region (nested landmarks\n // must not share an accessible name). Mirrors visible header text.\n ariaLabel={doc.name}\n className=\"ds:h-full ds:w-full\"\n />\n );\n } else if (kind === 'image' && doc.src) {\n viewport = (\n <img\n src={doc.src}\n alt={t('documentPreview.imageAlt', 'Preview of {{name}}', {\n name: doc.name,\n })}\n className=\"ds:max-h-full ds:max-w-full ds:object-contain\"\n />\n );\n } else {\n viewport = (\n <span className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-muted-foreground\">\n <PlaceholderIcon aria-hidden=\"true\" className=\"ds:size-10\" />\n <span className=\"type-body-sm\">\n {t('documentPreview.noPreview', 'No preview available.')}\n </span>\n </span>\n );\n }\n\n // Badges: type / clinical / signature status.\n const status = meta?.signatureStatus;\n const hasBadges =\n Boolean(meta?.documentType) ||\n Boolean(meta?.clinical) ||\n (status !== undefined && status !== 'none');\n\n // Detail rows — every structural field the host supplies, so nothing is\n // dropped when a real preview renders. Only present fields render a row.\n const fmtDate = (iso: string): string =>\n new Intl.DateTimeFormat(i18n.language, { dateStyle: 'medium' }).format(\n new Date(iso),\n );\n const rows: Array<{ key: string; label: string; value: string }> = [];\n if (meta?.createdBy)\n rows.push({\n key: 'createdBy',\n label: t('documentPreview.fields.createdBy', 'Created by'),\n value: meta.createdBy,\n });\n if (meta?.createdAt)\n rows.push({\n key: 'created',\n label: t('documentPreview.fields.created', 'Created'),\n value: fmtDate(meta.createdAt),\n });\n if (meta?.updatedAt)\n rows.push({\n key: 'modified',\n label: t('documentPreview.fields.modified', 'Modified'),\n value: fmtDate(meta.updatedAt),\n });\n if (meta?.signatureRequestedAt)\n rows.push({\n key: 'signatureRequested',\n label: t(\n 'documentPreview.fields.signatureRequested',\n 'Signature requested',\n ),\n value: fmtDate(meta.signatureRequestedAt),\n });\n if (meta?.signedAt)\n rows.push({\n key: 'signed',\n label: t('documentPreview.fields.signed', 'Signed'),\n value: fmtDate(meta.signedAt),\n });\n if (meta?.sharedAt)\n rows.push({\n key: 'sharedWithPatient',\n label: t(\n 'documentPreview.fields.sharedWithPatient',\n 'Shared with patient',\n ),\n value: fmtDate(meta.sharedAt),\n });\n if (meta?.size !== undefined)\n rows.push({\n key: 'size',\n label: t('documentPreview.fields.size', 'Size'),\n value: formatBytes(meta.size, i18n.language, t),\n });\n if (meta?.expiresAt)\n rows.push({\n key: 'expires',\n label: t('documentPreview.fields.expires', 'Expires'),\n value: fmtDate(meta.expiresAt),\n });\n\n const hasDetails = hasBadges || rows.length > 0;\n\n return (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <Card\n variant=\"elevated\"\n className=\"ds:flex ds:flex-col ds:overflow-hidden\"\n >\n <div className=\"ds:flex ds:aspect-[4/3] ds:min-h-0 ds:items-center ds:justify-center ds:overflow-hidden ds:border-b ds:border-[color:var(--card-border)] ds:bg-muted\">\n {viewport}\n </div>\n {hasDetails && (\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3 className=\"type-eyebrow ds:m-0 ds:text-muted-foreground\">\n {t('documentPreview.detailsTitle', 'Details')}\n </h3>\n {hasBadges && (\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {meta?.documentType && (\n <Badge variant=\"neutral\" size=\"sm\">\n {meta.documentType}\n </Badge>\n )}\n {meta?.clinical && (\n <Badge variant=\"info\" size=\"sm\">\n {t('documentPreview.clinical', 'Clinical')}\n </Badge>\n )}\n {status && status !== 'none' && (\n <Badge\n variant={SIGNATURE_VARIANT[status]}\n size=\"sm\"\n withDot\n >\n {t(`documentPreview.signature.${status}`, status)}\n </Badge>\n )}\n </span>\n )}\n {rows.length > 0 && (\n <dl className=\"ds:grid ds:grid-cols-[auto_1fr] ds:gap-x-[var(--spacing-md)] ds:gap-y-[var(--spacing-xs)] type-body-sm\">\n {rows.map((row) => (\n <Fragment key={row.key}>\n <dt className=\"ds:text-muted-foreground\">{row.label}</dt>\n <dd className=\"ds:m-0\">{row.value}</dd>\n </Fragment>\n ))}\n </dl>\n )}\n </Card.Body>\n )}\n </Card>\n </div>\n );\n };\n\n // Header: a MIME icon + the document name for a single doc; a Files glyph +\n // a count badge (RadiographPanel's title-plus-badge shape) when tabbed.\n const HeaderMimeIcon = iconForMime(activeDoc?.mimeType);\n const headerIcon = isTabbed ? (\n <Files aria-hidden=\"true\" />\n ) : (\n <HeaderMimeIcon aria-hidden=\"true\" />\n );\n const headerTitle: ReactNode = isTabbed ? (\n <>\n {t('documentPreview.multiTitle', 'Documents')}\n <Badge variant=\"neutral\" size=\"sm\">\n {docs.length}\n </Badge>\n </>\n ) : (\n activeDoc?.name\n );\n\n let content: ReactNode;\n if (docs.length === 0) {\n content = (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t('documentPreview.emptyTitle', 'No document selected')}\n description={t(\n 'documentPreview.emptyDescription',\n 'Select a document to preview it here.',\n )}\n />\n );\n } else if (isTabbed) {\n content = (\n <Tabs\n value={activeDoc?.id ?? ''}\n onValueChange={setActiveId}\n variant=\"underlined\"\n size=\"sm\"\n // Each tab shows its full file name when there's room and shrinks with\n // an ellipsis only when the tabs would otherwise overflow the width\n // (`min-inline-size:0` lets a tab shrink below its content; the label\n // truncates). The full name stays the accessible name and shows in the\n // body, so nothing is lost.\n className=\"ds:min-h-0 ds:flex-1 ds:pt-[var(--spacing-sm)]\"\n >\n <TabsList\n aria-label={t('documentPreview.tabsLabel', 'Selected documents')}\n className=\"ds:gap-[var(--spacing-sm)]\"\n >\n {docs.map((doc) => {\n const TabIcon = iconForMime(doc.mimeType);\n return (\n <TabsTrigger\n key={doc.id}\n value={doc.id}\n // Match the header glyph: same 16px size (never larger) and the\n // accent tint that marks a file across the grid and the rail.\n icon={\n <TabIcon\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:text-[color:var(--accent)]\"\n />\n }\n className=\"ds:[min-inline-size:0]\"\n >\n <span className=\"ds:block ds:truncate ds:[min-inline-size:0]\">\n {doc.name}\n </span>\n </TabsTrigger>\n );\n })}\n </TabsList>\n {docs.map((doc) => (\n <TabsContent\n key={doc.id}\n value={doc.id}\n className=\"ds:min-h-0 ds:flex-1\"\n >\n {renderBody(doc)}\n </TabsContent>\n ))}\n </Tabs>\n );\n } else {\n content = renderBody(activeDoc);\n }\n\n return (\n <section\n data-component=\"document-preview\"\n data-component-id={id}\n // The preview body scrolls (PDF pages, tall images, long metadata), so\n // the region needs a keyboard tab stop (axe scrollable-region-focusable).\n // A labelled <section> is a region landmark, which also scopes the\n // PanelHeader's <header> so it is never exposed as a page banner.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- keyboard-focusable scroll region (see comment above)\n tabIndex={0}\n aria-label={t('documentPreview.regionLabel', 'Document preview')}\n className={documentPreviewVariants({ className })}\n >\n {docs.length > 0 && (\n <PanelHeader sticky icon={headerIcon} title={headerTitle} />\n )}\n {content}\n </section>\n );\n});\n\nDocumentPreview.displayName = 'DocumentPreview';\n"],"names":["__iconNode","Files","createLucideIcon","documentPreviewAgent","handle","documentPreviewVariants","cva","SIGNATURE_VARIANT","resolveKind","name","mimeType","src","mime","iconForMime","FileImage","FileText","FileIcon","UNIT_KEYS","UNIT_FALLBACKS","formatBytes","bytes","locale","t","value","unitIndex","DocumentPreview","forwardRef","id","metadata","documents","className","ref","i18n","useTranslation","docs","useMemo","isTabbed","activeId","setActiveId","useState","activeDoc","doc","useImperativeHandle","useAgentRegistration","renderBody","kind","meta","PlaceholderIcon","viewport","jsx","PDFViewer","jsxs","status","hasBadges","fmtDate","iso","rows","hasDetails","Card","Badge","row","Fragment","HeaderMimeIcon","headerIcon","headerTitle","content","EmptyState","Tabs","TabsList","TabIcon","TabsTrigger","TabsContent","PanelHeader"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -2,7 +2,7 @@ import { jsxs as b, jsx as s } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as m, useContext as P, useRef as M, useEffect as O, useMemo as _, useLayoutEffect as ne, createContext as G } from "react";
|
|
3
3
|
import * as o from "@radix-ui/react-dropdown-menu";
|
|
4
4
|
import { c as D } from "./index-D2ZczOXr.js";
|
|
5
|
-
import { S as oe } from "./separator-
|
|
5
|
+
import { S as oe } from "./separator-Bdc9bqoJ.js";
|
|
6
6
|
import { K } from "./kbd-Bx7eQv9f.js";
|
|
7
7
|
import { b as A } from "./menu-row-BAr8bx1I.js";
|
|
8
8
|
import { P as E } from "./popup-region-qz_5_A0V.js";
|
|
@@ -592,4 +592,4 @@ export {
|
|
|
592
592
|
ze as D,
|
|
593
593
|
ue as d
|
|
594
594
|
};
|
|
595
|
-
//# sourceMappingURL=dropdown-menu-
|
|
595
|
+
//# sourceMappingURL=dropdown-menu-CqxBthww.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-menu-D1we7oAY.js","sources":["../../src/components/dropdown-menu/dropdown-menu.agent.ts","../../src/components/dropdown-menu/dropdown-menu.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { DropdownMenuHandle } from './dropdown-menu';\n\n// The handle cannot run an arbitrary item (Radix owns item activation), so\n// there is no 'pick' capability. It CAN drive settings rows: a ChoiceSub or\n// SwitchItem given a `name` registers with its Root, and set_value /\n// set_checked call that row's own onValueChange / onCheckedChange, exactly\n// as a click would. Rows mount with the menu, so a closed menu opens for the\n// moment and closes again.\nexport const dropdownMenuAgent: AgentAdapter<DropdownMenuHandle> = {\n id: 'dropdown-menu',\n capabilities: ['open', 'close', 'set_value'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dropdownMenu.state.isOpen',\n description: 'True when the menu is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n settings: {\n type: 'Array<{ setting: string; kind: \"choice\" | \"switch\"; value?: string; options?: string[]; checked?: boolean; disabled: boolean }>',\n descriptionKey: 'ui.agent.dropdownMenu.state.settings',\n description:\n \"The menu's named settings rows and their current values: choice rows with the selected value and every option's value, switch rows with whether they are on. Rows are listed only while the menu is open; open it first to read them.\",\n read: (handle) => handle.getSettings(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.open',\n description: 'Open the menu.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.close',\n description: 'Close the menu.',\n invoke: (handle) => {\n handle.close();\n },\n },\n set_value: {\n safety: 'write',\n argsType: '{ setting: string; value: string }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n value: {\n type: 'string',\n description: \"One of the row's option values.\",\n },\n },\n required: ['setting', 'value'],\n },\n idempotent: true,\n errors: [\n 'No choice row with that name in this menu',\n 'The value is not one of the options, or it or the row is disabled',\n ],\n examples: [\n {\n args: { setting: 'slotDensity', value: 'comfortable' },\n note: 'Calendar display settings: switch to comfortable rows.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setValue',\n description:\n 'Pick an option on a named choice row (ChoiceSub), as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; value: string }) =>\n handle.setValue(args.setting, args.value),\n },\n set_checked: {\n safety: 'write',\n argsType: '{ setting: string; checked: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n checked: { type: 'boolean' },\n },\n required: ['setting', 'checked'],\n },\n idempotent: true,\n errors: [\n 'No switch row with that name in this menu',\n 'The row is disabled',\n ],\n examples: [\n {\n args: { setting: 'zebraRows', checked: true },\n note: 'Calendar display settings: turn zebra rows on.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setChecked',\n description:\n 'Turn a named switch row (SwitchItem) on or off, as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; checked: boolean }) =>\n handle.setChecked(args.setting, args.checked),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dropdown-menu' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on DropdownMenu.Root.',\n },\n item: {\n attr: 'data-setting',\n sourceProp: 'name',\n description:\n 'On a ChoiceSub or SwitchItem row given a name: the setting that set_value / set_checked address.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, ChevronRight } from 'lucide-react';\nimport { Separator as DsSeparator } from '../separator/separator';\nimport { Kbd, type KbdNamedKey } from '../kbd/kbd';\nimport { useDocumentDirection } from '../_shared/use-direction';\nimport { MENU_ROW_HIGHLIGHT } from '../_shared/menu-row';\nimport { PopupRegion } from '../_shared/popup-region';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { dropdownMenuAgent } from './dropdown-menu.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst contentVariants = cva(\n [\n 'ds:z-[var(--z-dropdown)]',\n // Roomier panel: wider floor, larger radius, deeper float and a\n // breath more padding so menus read as elevated surfaces rather\n // than flat lists hugging their trigger.\n 'ds:min-w-[14rem]',\n 'ds:rounded-[var(--radius-lg)]',\n // Border kept (transparent) so the forced-colors override below can\n // repaint a visible edge in HCM. In normal modes the soft drop-shadow\n // carries the edge cue; the heavy `--border` (grey-800 since WCAG\n // 1.4.11 bump in 67fef8c) made the menu read as a charcoal box.\n 'ds:border ds:border-transparent',\n 'ds:bg-[var(--popover)] ds:text-[color:var(--popover-foreground)]',\n 'ds:shadow-[var(--shadow-xl)]',\n 'ds:p-[var(--spacing-sm)]',\n // Never taller than the room Radix measures beside the trigger: a long\n // menu scrolls instead of running off the screen. Submenus portal out,\n // so the scroll never clips them. Radix sets the same variable on\n // Content and SubContent.\n 'ds:max-h-[var(--radix-dropdown-menu-content-available-height)] ds:overflow-y-auto',\n // Motion — gated on --animation-duration via Tailwind's animate-in\n // preset. motion-reduce disables via the no-preference query.\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=open]:fade-in ds:data-[state=closed]:fade-out',\n 'ds:data-[state=open]:zoom-in-95 ds:data-[state=closed]:zoom-out-95',\n 'ds:data-[state=open]:slide-in-from-top-1',\n 'ds:motion-reduce:animate-none',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n);\n\nconst itemClasses = cva(\n [\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)]',\n 'ds:cursor-pointer ds:select-none ds:outline-none',\n // Radix highlights on hover and on keyboard focus alike.\n MENU_ROW_HIGHLIGHT.highlighted,\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n // Disabled\n 'ds:data-[disabled]:opacity-50 ds:data-[disabled]:cursor-not-allowed',\n 'ds:data-[disabled]:pointer-events-none',\n ].join(' '),\n);\n\nconst labelClasses = cva(\n [\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-2xs)]',\n // Quiet sentence-case caption — the shouty uppercase eyebrow made\n // every menu read as a form. Groups should lean on separators first\n // and reach for a Label only when the grouping is genuinely unclear.\n 'ds:text-[length:var(--font-size-xs)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:text-[color:var(--muted-foreground)]',\n 'ds:select-none',\n ].join(' '),\n);\n\nconst indicatorSlotClasses =\n 'ds:inline-flex ds:items-center ds:justify-center ds:size-4 ds:shrink-0';\n\n/* ------------------------------------------------------------------ */\n/* Root / Trigger / Portal */\n/* ------------------------------------------------------------------ */\n\n/** A named settings row (a ChoiceSub or SwitchItem given a `name`) and\n * its current state, as an agent reads it. Values only, never labels. */\nexport interface DropdownMenuSetting {\n setting: string;\n kind: 'choice' | 'switch';\n /** ChoiceSub: the selected value and every option's value. */\n value?: string;\n options?: string[];\n /** SwitchItem: whether it is on. */\n checked?: boolean;\n disabled: boolean;\n}\n\n// Curated agent-readiness handle — see dropdown-menu.agent.ts.\nexport interface DropdownMenuHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n /** The named settings rows, while the menu is open (closed: none). */\n getSettings: () => DropdownMenuSetting[];\n /** Pick `value` on the named ChoiceSub. A closed menu opens for the\n * moment and closes again. Rejects on an unknown row, value or a\n * disabled one. */\n setValue: (setting: string, value: string) => Promise<void>;\n /** Turn the named SwitchItem on or off, as `setValue` does. */\n setChecked: (setting: string, checked: boolean) => Promise<void>;\n}\n\n/* A named row registers with its Root so the handle can drive it. */\ntype SettingRow =\n | {\n kind: 'choice';\n read: () => {\n value: string;\n options: ReadonlyArray<{ value: string; disabled?: boolean }>;\n disabled: boolean;\n closeOnSelect: boolean;\n };\n pick: (value: string) => void;\n }\n | {\n kind: 'switch';\n read: () => { checked: boolean; disabled: boolean };\n pick: (checked: boolean) => void;\n };\n\ntype RegisterSettingRow = (name: string, row: SettingRow) => () => void;\n\nconst SettingRowsContext = createContext<RegisterSettingRow | undefined>(\n undefined,\n);\n\nconst nextFrame = () =>\n new Promise<void>((resolve) => {\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => resolve());\n } else {\n setTimeout(resolve, 16);\n }\n });\n\nexport interface DropdownMenuRootProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Root\n> {\n /** Opaque instance id — forwarded to DropdownMenu.Content as `data-component-id`. */\n id?: string;\n}\n\nconst DropdownMenuIdContext = createContext<string | undefined>(undefined);\n\nconst Root = ({\n dir,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}: DropdownMenuRootProps) => {\n const autoDir = useDocumentDirection();\n const [openRaw, setOpen] = useControllableState<boolean>({\n value: openProp,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n const open = openRaw ?? false;\n\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const rowsRef = useRef(new Map<string, SettingRow>());\n // Counts explicit open/close calls on the handle.\n const openRequestsRef = useRef(0);\n const registerRow = useMemo<RegisterSettingRow>(\n () => (name, row) => {\n rowsRef.current.set(name, row);\n return () => {\n if (rowsRef.current.get(name) === row) rowsRef.current.delete(name);\n };\n },\n [],\n );\n\n const handle = useMemo<DropdownMenuHandle>(() => {\n /* Rows mount with the menu. A closed menu opens for the moment, waits\n for the row to register, and closes again once the change lands. */\n // open/close update the ref at once, not a render later, so a set\n // right after an explicit open() sees the menu as open and leaves it so.\n const show = (next: boolean) => {\n openRef.current = next;\n setOpen(next);\n };\n const withRow = async <K extends SettingRow['kind']>(\n setting: string,\n kind: K,\n apply: (row: Extract<SettingRow, { kind: K }>) => void,\n ) => {\n const opened = !openRef.current;\n if (opened) show(true);\n const requests = openRequestsRef.current;\n try {\n // A row mounts a render or two after the menu opens.\n let row = rowsRef.current.get(setting);\n for (let frame = 0; !row && frame < 30; frame += 1) {\n await nextFrame();\n row = rowsRef.current.get(setting);\n }\n if (!row || row.kind !== kind) {\n throw new Error(`No ${kind} setting named \"${setting}\" in this menu`);\n }\n apply(row as Extract<SettingRow, { kind: K }>);\n } finally {\n // Close only a menu this call opened, and nobody asked for since.\n if (opened && openRequestsRef.current === requests) show(false);\n }\n };\n return {\n getIsOpen: () => openRef.current,\n open: () => {\n openRequestsRef.current += 1;\n show(true);\n },\n close: () => {\n openRequestsRef.current += 1;\n show(false);\n },\n getSettings: () =>\n [...rowsRef.current].map(([setting, row]) => {\n if (row.kind === 'choice') {\n const { value, options, disabled } = row.read();\n return {\n setting,\n kind: 'choice' as const,\n value,\n options: options.map((option) => option.value),\n disabled,\n };\n }\n const { checked, disabled } = row.read();\n return { setting, kind: 'switch' as const, checked, disabled };\n }),\n setValue: (setting, value) =>\n withRow(setting, 'choice', (row) => {\n const { options, disabled, closeOnSelect } = row.read();\n const option = options.find((o) => o.value === value);\n if (disabled || !option || option.disabled) {\n throw new Error(\n `\"${value}\" is not an option that \"${setting}\" can take now`,\n );\n }\n row.pick(value);\n // As a click on the option would.\n if (closeOnSelect) show(false);\n }),\n setChecked: (setting, checked) =>\n withRow(setting, 'switch', (row) => {\n if (row.read().disabled) {\n throw new Error(`\"${setting}\" is disabled`);\n }\n row.pick(checked);\n }),\n };\n }, [setOpen]);\n useAgentRegistration(dropdownMenuAgent, handle, id);\n\n return (\n <DropdownMenuIdContext.Provider value={id}>\n <SettingRowsContext.Provider value={registerRow}>\n <RadixDropdownMenu.Root\n dir={dir ?? autoDir}\n open={open}\n onOpenChange={setOpen}\n {...props}\n />\n </SettingRowsContext.Provider>\n </DropdownMenuIdContext.Provider>\n );\n};\nRoot.displayName = 'DropdownMenu.Root';\n\nconst Trigger = RadixDropdownMenu.Trigger;\nconst Portal = RadixDropdownMenu.Portal;\nconst RadixGroup = RadixDropdownMenu.Group;\nconst RadixRadioGroup = RadixDropdownMenu.RadioGroup;\n\n/* ------------------------------------------------------------------ */\n/* Content */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuContentProps\n extends\n ComponentPropsWithoutRef<typeof RadixDropdownMenu.Content>,\n VariantProps<typeof contentVariants> {}\n\nconst Content = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Content>,\n DropdownMenuContentProps\n>(({ className, sideOffset = 8, ...props }, ref) => {\n const instanceId = useContext(DropdownMenuIdContext);\n return (\n <RadixDropdownMenu.Portal>\n {/* A region named after the trigger, so axe `region` passes while open. */}\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.Content\n ref={popupRef}\n sideOffset={sideOffset}\n className={contentVariants({ className })}\n data-component=\"dropdown-menu\"\n data-component-id={instanceId}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n );\n});\nContent.displayName = 'DropdownMenu.Content';\n\n/* ------------------------------------------------------------------ */\n/* Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Item\n> {\n startIcon?: ReactNode;\n endIcon?: ReactNode;\n description?: ReactNode;\n /** Convenience — renders a DS <Kbd keys={…}> on the inline-end. */\n shortcut?: Array<KbdNamedKey | string>;\n}\n\nconst Item = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Item>,\n DropdownMenuItemProps\n>(\n (\n {\n className,\n startIcon,\n endIcon,\n description,\n shortcut,\n children,\n ...props\n },\n ref,\n ) => (\n <RadixDropdownMenu.Item\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:flex ds:flex-col ds:min-w-0\">\n <span className=\"ds:truncate\">{children}</span>\n {description ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {description}\n </span>\n ) : null}\n </span>\n {shortcut ? (\n <span className=\"ds:ms-auto\">\n <Kbd keys={shortcut} size=\"sm\" />\n </span>\n ) : endIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:ms-auto ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {endIcon}\n </span>\n ) : null}\n </RadixDropdownMenu.Item>\n ),\n);\nItem.displayName = 'DropdownMenu.Item';\n\n/* ------------------------------------------------------------------ */\n/* CheckboxItem */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuCheckboxItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n>;\n\nconst CheckboxItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuCheckboxItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n <span className={indicatorSlotClasses}>\n <RadixDropdownMenu.ItemIndicator>\n <Check aria-hidden className=\"ds:size-4\" />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.CheckboxItem>\n));\nCheckboxItem.displayName = 'DropdownMenu.CheckboxItem';\n\n/* Registers a named row with its Root for as long as it is mounted. The\n row object is rebuilt each render; the Root reads it through a ref, so\n it always sees the latest value and callback. */\nfunction useSettingRow(name: string | undefined, row: SettingRow): void {\n const register = useContext(SettingRowsContext);\n const latest = useRef(row);\n useLayoutEffect(() => {\n latest.current = row;\n });\n useEffect(() => {\n if (!name || !register) return undefined;\n const proxy: SettingRow =\n latest.current.kind === 'choice'\n ? {\n kind: 'choice',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'choice' }>\n ).read(),\n pick: (value) =>\n (latest.current as Extract<SettingRow, { kind: 'choice' }>).pick(\n value,\n ),\n }\n : {\n kind: 'switch',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'switch' }>\n ).read(),\n pick: (checked) =>\n (latest.current as Extract<SettingRow, { kind: 'switch' }>).pick(\n checked,\n ),\n };\n return register(name, proxy);\n }, [name, register]);\n}\n\n/* ------------------------------------------------------------------ */\n/* SwitchItem */\n/* */\n/* A persistent on/off toggle row (menuitemcheckbox semantics) whose */\n/* indicator is a trailing switch glyph instead of a tick — for */\n/* settings that live inside a menu (e.g. accessible mode). Selecting */\n/* keeps the menu open so the user sees the toggle land. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuSwitchItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n> {\n /** Names the row for agents (the menu's `set_checked` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n}\n\n// Mirrors the kit Switch's `sm` metrics (track h-4 w-7, thumb size-3)\n// and its primary checked fill so the two switch affordances stay kin.\n// The muted-foreground border keeps the OFF state perceivable — without\n// it the muted track sits at ~1.2:1 on the popover (WCAG 1.4.11).\nconst switchTrackClasses = [\n 'ds:ms-auto ds:inline-flex ds:items-center ds:shrink-0',\n 'ds:h-4 ds:w-7 ds:p-[2px]',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:bg-[color:var(--muted)]',\n 'ds:[[data-state=checked]_&]:bg-[color:var(--primary)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--primary)]',\n // Thumb slides via justify swap — logical-direction safe, no\n // transform to fight under prefers-reduced-motion.\n 'ds:justify-start ds:[[data-state=checked]_&]:justify-end',\n 'ds:forced-colors:border-[CanvasText]',\n // HCM strips fills — paint the checked track with the system\n // selection colour so state isn't conveyed by thumb position alone.\n 'ds:forced-colors:[[data-state=checked]_&]:bg-[SelectedItem]',\n].join(' ');\n\nconst switchThumbClasses = [\n 'ds:block ds:size-3',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[color:var(--background)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-transparent',\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:forced-colors:bg-[CanvasText]',\n].join(' ');\n\nconst SwitchItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuSwitchItemProps\n>(({ className, children, onSelect, name, ...props }, ref) => {\n const { checked, onCheckedChange, disabled } = props;\n useSettingRow(name, {\n kind: 'switch',\n read: () => ({ checked: checked === true, disabled: disabled === true }),\n // What a click does, and only when it would change something: the\n // consumer's onSelect, then the new state.\n pick: (next) => {\n if (next === (checked === true)) return;\n onSelect?.(new Event('menu.itemSelect', { cancelable: true }));\n onCheckedChange?.(next);\n },\n });\n return (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n data-setting={name}\n onSelect={(event) => {\n // Keep-open is unconditional — prevent first so a throwing consumer\n // handler can't close the menu as a side effect.\n event.preventDefault();\n onSelect?.(event);\n }}\n {...props}\n >\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <span aria-hidden=\"true\" className={switchTrackClasses}>\n <span className={switchThumbClasses} />\n </span>\n </RadixDropdownMenu.CheckboxItem>\n );\n});\nSwitchItem.displayName = 'DropdownMenu.SwitchItem';\n\n/* ------------------------------------------------------------------ */\n/* RadioGroup / RadioItem */\n/* ------------------------------------------------------------------ */\n\nconst RadioGroup = RadixRadioGroup;\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.RadioItem\n>;\n\nconst RadioItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.RadioItem>,\n DropdownMenuRadioItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.RadioItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {/* Real radio affordance: an always-visible ring with a filled dot\n when selected — a tick reads as a checkbox, not a single choice.\n The ring colours via the item's own data-state so the unchecked\n options still advertise that they are part of a radio set. */}\n <span className={indicatorSlotClasses} aria-hidden=\"true\">\n <span\n className={[\n 'ds:inline-flex ds:size-4 ds:items-center ds:justify-center ds:shrink-0',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--accent)]',\n // Accent on the lit row would vanish, so ring and dot take its ink.\n 'ds:not-forced-colors:[[data-highlighted][data-state=checked]_&]:border-[color:var(--accent-foreground)]',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' ')}\n >\n <RadixDropdownMenu.ItemIndicator>\n <span\n className={[\n 'ds:block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--accent)]',\n 'ds:not-forced-colors:group-data-[highlighted]/menu-row:bg-[color:var(--accent-foreground)]',\n 'ds:forced-colors:bg-[CanvasText]',\n ].join(' ')}\n />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.RadioItem>\n));\nRadioItem.displayName = 'DropdownMenu.RadioItem';\n\n/* ------------------------------------------------------------------ */\n/* Label */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuLabelProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Label\n>;\n\nconst Label = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Label>,\n DropdownMenuLabelProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Label\n ref={ref}\n className={labelClasses({ className })}\n {...props}\n />\n));\nLabel.displayName = 'DropdownMenu.Label';\n\n/* ------------------------------------------------------------------ */\n/* Separator */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuSeparatorProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Separator\n>;\n\nconst MenuSeparator = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Separator>,\n DropdownMenuSeparatorProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Separator ref={ref} asChild {...props}>\n <DsSeparator\n className={['ds:my-[calc(var(--spacing-xs)/2)]', className ?? '']\n .filter(Boolean)\n .join(' ')}\n />\n </RadixDropdownMenu.Separator>\n));\nMenuSeparator.displayName = 'DropdownMenu.Separator';\n\n/* ------------------------------------------------------------------ */\n/* Shortcut — thin wrapper over DS Kbd for the right side of an Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuShortcutProps {\n keys: Array<KbdNamedKey | string>;\n separator?: 'none' | 'plus' | 'then';\n}\n\nconst Shortcut = forwardRef<HTMLSpanElement, DropdownMenuShortcutProps>(\n ({ keys, separator = 'none' }, ref) => (\n <span ref={ref} className=\"ds:ms-auto ds:ps-[var(--spacing-sm)]\">\n <Kbd keys={keys} separator={separator} size=\"sm\" />\n </span>\n ),\n);\nShortcut.displayName = 'DropdownMenu.Shortcut';\n\n/* ------------------------------------------------------------------ */\n/* Sub-menu */\n/* ------------------------------------------------------------------ */\n\nconst Sub = RadixDropdownMenu.Sub;\n\nexport interface DropdownMenuSubTriggerProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubTrigger\n> {\n startIcon?: ReactNode;\n}\n\nconst SubTrigger = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubTrigger>,\n DropdownMenuSubTriggerProps\n>(({ className, startIcon, children, ...props }, ref) => (\n <RadixDropdownMenu.SubTrigger\n ref={ref}\n // Stays lit while focus is in its submenu, so the path is visible.\n className={itemClasses({\n className: [MENU_ROW_HIGHLIGHT.open, className].filter(Boolean).join(' '),\n })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <ChevronRight\n aria-hidden\n className=\"ds:ms-auto ds:size-4 ds:shrink-0 ds:rtl:-scale-x-100\"\n />\n </RadixDropdownMenu.SubTrigger>\n));\nSubTrigger.displayName = 'DropdownMenu.SubTrigger';\n\nexport type DropdownMenuSubContentProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubContent\n>;\n\nconst SubContent = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubContent>,\n DropdownMenuSubContentProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Portal>\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.SubContent\n ref={popupRef}\n sideOffset={8}\n data-component=\"dropdown-menu-sub-content\"\n className={contentVariants({ className })}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n));\nSubContent.displayName = 'DropdownMenu.SubContent';\n\n/* ------------------------------------------------------------------ */\n/* ChoiceSub */\n/* */\n/* One setting with a few exclusive options, as a single menu row that */\n/* names the setting and shows its current value (\"Row density · */\n/* Compact ›\"). The row opens a submenu of radio items. It replaces the */\n/* \"label + Select\" row inside popovers: no Select ever opens inside a */\n/* menu, and the whole settings menu stays keyboard-native. Picking an */\n/* option keeps the menu open by default, like SwitchItem, so the user */\n/* sees the value land and can adjust the next setting. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuChoiceOption<T extends string = string> {\n value: T;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport interface DropdownMenuChoiceSubProps<T extends string = string> {\n /** The setting's name, shown at the start of the row. */\n label: ReactNode;\n /** The selected option's value; its label shows at the end of the row. */\n value: T;\n onValueChange: (value: T) => void;\n options: ReadonlyArray<DropdownMenuChoiceOption<T>>;\n startIcon?: ReactNode;\n disabled?: boolean;\n /** Close the whole menu after a pick. @default false */\n closeOnSelect?: boolean;\n /** Names the row for agents (the menu's `set_value` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n className?: string;\n}\n\nfunction ChoiceSub<T extends string>({\n label,\n value,\n onValueChange,\n options,\n startIcon,\n disabled,\n closeOnSelect = false,\n name,\n className,\n}: DropdownMenuChoiceSubProps<T>) {\n const current = options.find((option) => option.value === value);\n useSettingRow(name, {\n kind: 'choice',\n read: () => ({\n value,\n options,\n disabled: disabled === true,\n closeOnSelect,\n }),\n pick: (next) => onValueChange(next as T),\n });\n return (\n <Sub>\n <SubTrigger\n startIcon={startIcon}\n disabled={disabled}\n className={className}\n data-component=\"dropdown-menu-choice\"\n data-value={value}\n data-setting={name}\n >\n <span className=\"ds:flex ds:min-w-0 ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <span className=\"ds:truncate\">{label}</span>\n {current ? (\n <span className=\"ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:[[data-highlighted]_&]:text-current\">\n {current.label}\n </span>\n ) : null}\n </span>\n </SubTrigger>\n <SubContent>\n <RadioGroup\n value={value}\n onValueChange={(next) => onValueChange(next as T)}\n >\n {options.map((option) => (\n <RadioItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n onSelect={\n closeOnSelect ? undefined : (event) => event.preventDefault()\n }\n >\n {option.label}\n </RadioItem>\n ))}\n </RadioGroup>\n </SubContent>\n </Sub>\n );\n}\nChoiceSub.displayName = 'DropdownMenu.ChoiceSub';\n\n/* ------------------------------------------------------------------ */\n/* Assembled namespace export */\n/* ------------------------------------------------------------------ */\n\nexport const DropdownMenu = {\n Root,\n Trigger,\n Portal,\n Content,\n Group: RadixGroup,\n Item,\n CheckboxItem,\n SwitchItem,\n RadioGroup,\n RadioItem,\n Label,\n Separator: MenuSeparator,\n Shortcut,\n Sub,\n SubTrigger,\n SubContent,\n ChoiceSub,\n};\n"],"names":["dropdownMenuAgent","handle","args","contentVariants","cva","itemClasses","MENU_ROW_HIGHLIGHT","labelClasses","indicatorSlotClasses","SettingRowsContext","createContext","nextFrame","resolve","DropdownMenuIdContext","Root","dir","id","openProp","defaultOpen","onOpenChange","props","autoDir","useDocumentDirection","openRaw","setOpen","useControllableState","open","openRef","useRef","useEffect","rowsRef","openRequestsRef","registerRow","useMemo","name","row","show","next","withRow","setting","kind","apply","opened","requests","frame","value","options","disabled","option","checked","closeOnSelect","o","useAgentRegistration","jsx","RadixDropdownMenu","Trigger","Portal","RadixGroup","RadixRadioGroup","Content","forwardRef","className","sideOffset","ref","instanceId","useContext","PopupRegion","popupRef","Item","startIcon","endIcon","description","shortcut","children","jsxs","Kbd","CheckboxItem","Check","useSettingRow","register","latest","useLayoutEffect","proxy","switchTrackClasses","switchThumbClasses","SwitchItem","onSelect","onCheckedChange","event","RadioGroup","RadioItem","Label","MenuSeparator","DsSeparator","Shortcut","keys","separator","Sub","SubTrigger","ChevronRight","SubContent","ChoiceSub","label","onValueChange","current","DropdownMenu"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown-menu-CqxBthww.js","sources":["../../src/components/dropdown-menu/dropdown-menu.agent.ts","../../src/components/dropdown-menu/dropdown-menu.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { DropdownMenuHandle } from './dropdown-menu';\n\n// The handle cannot run an arbitrary item (Radix owns item activation), so\n// there is no 'pick' capability. It CAN drive settings rows: a ChoiceSub or\n// SwitchItem given a `name` registers with its Root, and set_value /\n// set_checked call that row's own onValueChange / onCheckedChange, exactly\n// as a click would. Rows mount with the menu, so a closed menu opens for the\n// moment and closes again.\nexport const dropdownMenuAgent: AgentAdapter<DropdownMenuHandle> = {\n id: 'dropdown-menu',\n capabilities: ['open', 'close', 'set_value'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dropdownMenu.state.isOpen',\n description: 'True when the menu is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n settings: {\n type: 'Array<{ setting: string; kind: \"choice\" | \"switch\"; value?: string; options?: string[]; checked?: boolean; disabled: boolean }>',\n descriptionKey: 'ui.agent.dropdownMenu.state.settings',\n description:\n \"The menu's named settings rows and their current values: choice rows with the selected value and every option's value, switch rows with whether they are on. Rows are listed only while the menu is open; open it first to read them.\",\n read: (handle) => handle.getSettings(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.open',\n description: 'Open the menu.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dropdownMenu.actions.close',\n description: 'Close the menu.',\n invoke: (handle) => {\n handle.close();\n },\n },\n set_value: {\n safety: 'write',\n argsType: '{ setting: string; value: string }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n value: {\n type: 'string',\n description: \"One of the row's option values.\",\n },\n },\n required: ['setting', 'value'],\n },\n idempotent: true,\n errors: [\n 'No choice row with that name in this menu',\n 'The value is not one of the options, or it or the row is disabled',\n ],\n examples: [\n {\n args: { setting: 'slotDensity', value: 'comfortable' },\n note: 'Calendar display settings: switch to comfortable rows.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setValue',\n description:\n 'Pick an option on a named choice row (ChoiceSub), as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; value: string }) =>\n handle.setValue(args.setting, args.value),\n },\n set_checked: {\n safety: 'write',\n argsType: '{ setting: string; checked: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n setting: {\n type: 'string',\n description: \"The row's name (its data-setting attribute).\",\n },\n checked: { type: 'boolean' },\n },\n required: ['setting', 'checked'],\n },\n idempotent: true,\n errors: [\n 'No switch row with that name in this menu',\n 'The row is disabled',\n ],\n examples: [\n {\n args: { setting: 'zebraRows', checked: true },\n note: 'Calendar display settings: turn zebra rows on.',\n },\n ],\n descriptionKey: 'ui.agent.dropdownMenu.actions.setChecked',\n description:\n 'Turn a named switch row (SwitchItem) on or off, as clicking it would. A closed menu opens for the moment and closes again.',\n invoke: (handle, args: { setting: string; checked: boolean }) =>\n handle.setChecked(args.setting, args.checked),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dropdown-menu' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on DropdownMenu.Root.',\n },\n item: {\n attr: 'data-setting',\n sourceProp: 'name',\n description:\n 'On a ChoiceSub or SwitchItem row given a name: the setting that set_value / set_checked address.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, ChevronRight } from 'lucide-react';\nimport { Separator as DsSeparator } from '../separator/separator';\nimport { Kbd, type KbdNamedKey } from '../kbd/kbd';\nimport { useDocumentDirection } from '../_shared/use-direction';\nimport { MENU_ROW_HIGHLIGHT } from '../_shared/menu-row';\nimport { PopupRegion } from '../_shared/popup-region';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { dropdownMenuAgent } from './dropdown-menu.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst contentVariants = cva(\n [\n 'ds:z-[var(--z-dropdown)]',\n // Roomier panel: wider floor, larger radius, deeper float and a\n // breath more padding so menus read as elevated surfaces rather\n // than flat lists hugging their trigger.\n 'ds:min-w-[14rem]',\n 'ds:rounded-[var(--radius-lg)]',\n // Border kept (transparent) so the forced-colors override below can\n // repaint a visible edge in HCM. In normal modes the soft drop-shadow\n // carries the edge cue; the heavy `--border` (grey-800 since WCAG\n // 1.4.11 bump in 67fef8c) made the menu read as a charcoal box.\n 'ds:border ds:border-transparent',\n 'ds:bg-[var(--popover)] ds:text-[color:var(--popover-foreground)]',\n 'ds:shadow-[var(--shadow-xl)]',\n 'ds:p-[var(--spacing-sm)]',\n // Never taller than the room Radix measures beside the trigger: a long\n // menu scrolls instead of running off the screen. Submenus portal out,\n // so the scroll never clips them. Radix sets the same variable on\n // Content and SubContent.\n 'ds:max-h-[var(--radix-dropdown-menu-content-available-height)] ds:overflow-y-auto',\n // Motion — gated on --animation-duration via Tailwind's animate-in\n // preset. motion-reduce disables via the no-preference query.\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=open]:fade-in ds:data-[state=closed]:fade-out',\n 'ds:data-[state=open]:zoom-in-95 ds:data-[state=closed]:zoom-out-95',\n 'ds:data-[state=open]:slide-in-from-top-1',\n 'ds:motion-reduce:animate-none',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n);\n\nconst itemClasses = cva(\n [\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)]',\n 'ds:cursor-pointer ds:select-none ds:outline-none',\n // Radix highlights on hover and on keyboard focus alike.\n MENU_ROW_HIGHLIGHT.highlighted,\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n // Disabled\n 'ds:data-[disabled]:opacity-50 ds:data-[disabled]:cursor-not-allowed',\n 'ds:data-[disabled]:pointer-events-none',\n ].join(' '),\n);\n\nconst labelClasses = cva(\n [\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-xs)] ds:pb-[var(--spacing-2xs)]',\n // Quiet sentence-case caption — the shouty uppercase eyebrow made\n // every menu read as a form. Groups should lean on separators first\n // and reach for a Label only when the grouping is genuinely unclear.\n 'ds:text-[length:var(--font-size-xs)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:text-[color:var(--muted-foreground)]',\n 'ds:select-none',\n ].join(' '),\n);\n\nconst indicatorSlotClasses =\n 'ds:inline-flex ds:items-center ds:justify-center ds:size-4 ds:shrink-0';\n\n/* ------------------------------------------------------------------ */\n/* Root / Trigger / Portal */\n/* ------------------------------------------------------------------ */\n\n/** A named settings row (a ChoiceSub or SwitchItem given a `name`) and\n * its current state, as an agent reads it. Values only, never labels. */\nexport interface DropdownMenuSetting {\n setting: string;\n kind: 'choice' | 'switch';\n /** ChoiceSub: the selected value and every option's value. */\n value?: string;\n options?: string[];\n /** SwitchItem: whether it is on. */\n checked?: boolean;\n disabled: boolean;\n}\n\n// Curated agent-readiness handle — see dropdown-menu.agent.ts.\nexport interface DropdownMenuHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n /** The named settings rows, while the menu is open (closed: none). */\n getSettings: () => DropdownMenuSetting[];\n /** Pick `value` on the named ChoiceSub. A closed menu opens for the\n * moment and closes again. Rejects on an unknown row, value or a\n * disabled one. */\n setValue: (setting: string, value: string) => Promise<void>;\n /** Turn the named SwitchItem on or off, as `setValue` does. */\n setChecked: (setting: string, checked: boolean) => Promise<void>;\n}\n\n/* A named row registers with its Root so the handle can drive it. */\ntype SettingRow =\n | {\n kind: 'choice';\n read: () => {\n value: string;\n options: ReadonlyArray<{ value: string; disabled?: boolean }>;\n disabled: boolean;\n closeOnSelect: boolean;\n };\n pick: (value: string) => void;\n }\n | {\n kind: 'switch';\n read: () => { checked: boolean; disabled: boolean };\n pick: (checked: boolean) => void;\n };\n\ntype RegisterSettingRow = (name: string, row: SettingRow) => () => void;\n\nconst SettingRowsContext = createContext<RegisterSettingRow | undefined>(\n undefined,\n);\n\nconst nextFrame = () =>\n new Promise<void>((resolve) => {\n if (typeof requestAnimationFrame === 'function') {\n requestAnimationFrame(() => resolve());\n } else {\n setTimeout(resolve, 16);\n }\n });\n\nexport interface DropdownMenuRootProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Root\n> {\n /** Opaque instance id — forwarded to DropdownMenu.Content as `data-component-id`. */\n id?: string;\n}\n\nconst DropdownMenuIdContext = createContext<string | undefined>(undefined);\n\nconst Root = ({\n dir,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}: DropdownMenuRootProps) => {\n const autoDir = useDocumentDirection();\n const [openRaw, setOpen] = useControllableState<boolean>({\n value: openProp,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n const open = openRaw ?? false;\n\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const rowsRef = useRef(new Map<string, SettingRow>());\n // Counts explicit open/close calls on the handle.\n const openRequestsRef = useRef(0);\n const registerRow = useMemo<RegisterSettingRow>(\n () => (name, row) => {\n rowsRef.current.set(name, row);\n return () => {\n if (rowsRef.current.get(name) === row) rowsRef.current.delete(name);\n };\n },\n [],\n );\n\n const handle = useMemo<DropdownMenuHandle>(() => {\n /* Rows mount with the menu. A closed menu opens for the moment, waits\n for the row to register, and closes again once the change lands. */\n // open/close update the ref at once, not a render later, so a set\n // right after an explicit open() sees the menu as open and leaves it so.\n const show = (next: boolean) => {\n openRef.current = next;\n setOpen(next);\n };\n const withRow = async <K extends SettingRow['kind']>(\n setting: string,\n kind: K,\n apply: (row: Extract<SettingRow, { kind: K }>) => void,\n ) => {\n const opened = !openRef.current;\n if (opened) show(true);\n const requests = openRequestsRef.current;\n try {\n // A row mounts a render or two after the menu opens.\n let row = rowsRef.current.get(setting);\n for (let frame = 0; !row && frame < 30; frame += 1) {\n await nextFrame();\n row = rowsRef.current.get(setting);\n }\n if (!row || row.kind !== kind) {\n throw new Error(`No ${kind} setting named \"${setting}\" in this menu`);\n }\n apply(row as Extract<SettingRow, { kind: K }>);\n } finally {\n // Close only a menu this call opened, and nobody asked for since.\n if (opened && openRequestsRef.current === requests) show(false);\n }\n };\n return {\n getIsOpen: () => openRef.current,\n open: () => {\n openRequestsRef.current += 1;\n show(true);\n },\n close: () => {\n openRequestsRef.current += 1;\n show(false);\n },\n getSettings: () =>\n [...rowsRef.current].map(([setting, row]) => {\n if (row.kind === 'choice') {\n const { value, options, disabled } = row.read();\n return {\n setting,\n kind: 'choice' as const,\n value,\n options: options.map((option) => option.value),\n disabled,\n };\n }\n const { checked, disabled } = row.read();\n return { setting, kind: 'switch' as const, checked, disabled };\n }),\n setValue: (setting, value) =>\n withRow(setting, 'choice', (row) => {\n const { options, disabled, closeOnSelect } = row.read();\n const option = options.find((o) => o.value === value);\n if (disabled || !option || option.disabled) {\n throw new Error(\n `\"${value}\" is not an option that \"${setting}\" can take now`,\n );\n }\n row.pick(value);\n // As a click on the option would.\n if (closeOnSelect) show(false);\n }),\n setChecked: (setting, checked) =>\n withRow(setting, 'switch', (row) => {\n if (row.read().disabled) {\n throw new Error(`\"${setting}\" is disabled`);\n }\n row.pick(checked);\n }),\n };\n }, [setOpen]);\n useAgentRegistration(dropdownMenuAgent, handle, id);\n\n return (\n <DropdownMenuIdContext.Provider value={id}>\n <SettingRowsContext.Provider value={registerRow}>\n <RadixDropdownMenu.Root\n dir={dir ?? autoDir}\n open={open}\n onOpenChange={setOpen}\n {...props}\n />\n </SettingRowsContext.Provider>\n </DropdownMenuIdContext.Provider>\n );\n};\nRoot.displayName = 'DropdownMenu.Root';\n\nconst Trigger = RadixDropdownMenu.Trigger;\nconst Portal = RadixDropdownMenu.Portal;\nconst RadixGroup = RadixDropdownMenu.Group;\nconst RadixRadioGroup = RadixDropdownMenu.RadioGroup;\n\n/* ------------------------------------------------------------------ */\n/* Content */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuContentProps\n extends\n ComponentPropsWithoutRef<typeof RadixDropdownMenu.Content>,\n VariantProps<typeof contentVariants> {}\n\nconst Content = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Content>,\n DropdownMenuContentProps\n>(({ className, sideOffset = 8, ...props }, ref) => {\n const instanceId = useContext(DropdownMenuIdContext);\n return (\n <RadixDropdownMenu.Portal>\n {/* A region named after the trigger, so axe `region` passes while open. */}\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.Content\n ref={popupRef}\n sideOffset={sideOffset}\n className={contentVariants({ className })}\n data-component=\"dropdown-menu\"\n data-component-id={instanceId}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n );\n});\nContent.displayName = 'DropdownMenu.Content';\n\n/* ------------------------------------------------------------------ */\n/* Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Item\n> {\n startIcon?: ReactNode;\n endIcon?: ReactNode;\n description?: ReactNode;\n /** Convenience — renders a DS <Kbd keys={…}> on the inline-end. */\n shortcut?: Array<KbdNamedKey | string>;\n}\n\nconst Item = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Item>,\n DropdownMenuItemProps\n>(\n (\n {\n className,\n startIcon,\n endIcon,\n description,\n shortcut,\n children,\n ...props\n },\n ref,\n ) => (\n <RadixDropdownMenu.Item\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:flex ds:flex-col ds:min-w-0\">\n <span className=\"ds:truncate\">{children}</span>\n {description ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {description}\n </span>\n ) : null}\n </span>\n {shortcut ? (\n <span className=\"ds:ms-auto\">\n <Kbd keys={shortcut} size=\"sm\" />\n </span>\n ) : endIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:ms-auto ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {endIcon}\n </span>\n ) : null}\n </RadixDropdownMenu.Item>\n ),\n);\nItem.displayName = 'DropdownMenu.Item';\n\n/* ------------------------------------------------------------------ */\n/* CheckboxItem */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuCheckboxItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n>;\n\nconst CheckboxItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuCheckboxItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n <span className={indicatorSlotClasses}>\n <RadixDropdownMenu.ItemIndicator>\n <Check aria-hidden className=\"ds:size-4\" />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.CheckboxItem>\n));\nCheckboxItem.displayName = 'DropdownMenu.CheckboxItem';\n\n/* Registers a named row with its Root for as long as it is mounted. The\n row object is rebuilt each render; the Root reads it through a ref, so\n it always sees the latest value and callback. */\nfunction useSettingRow(name: string | undefined, row: SettingRow): void {\n const register = useContext(SettingRowsContext);\n const latest = useRef(row);\n useLayoutEffect(() => {\n latest.current = row;\n });\n useEffect(() => {\n if (!name || !register) return undefined;\n const proxy: SettingRow =\n latest.current.kind === 'choice'\n ? {\n kind: 'choice',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'choice' }>\n ).read(),\n pick: (value) =>\n (latest.current as Extract<SettingRow, { kind: 'choice' }>).pick(\n value,\n ),\n }\n : {\n kind: 'switch',\n read: () =>\n (\n latest.current as Extract<SettingRow, { kind: 'switch' }>\n ).read(),\n pick: (checked) =>\n (latest.current as Extract<SettingRow, { kind: 'switch' }>).pick(\n checked,\n ),\n };\n return register(name, proxy);\n }, [name, register]);\n}\n\n/* ------------------------------------------------------------------ */\n/* SwitchItem */\n/* */\n/* A persistent on/off toggle row (menuitemcheckbox semantics) whose */\n/* indicator is a trailing switch glyph instead of a tick — for */\n/* settings that live inside a menu (e.g. accessible mode). Selecting */\n/* keeps the menu open so the user sees the toggle land. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuSwitchItemProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.CheckboxItem\n> {\n /** Names the row for agents (the menu's `set_checked` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n}\n\n// Mirrors the kit Switch's `sm` metrics (track h-4 w-7, thumb size-3)\n// and its primary checked fill so the two switch affordances stay kin.\n// The muted-foreground border keeps the OFF state perceivable — without\n// it the muted track sits at ~1.2:1 on the popover (WCAG 1.4.11).\nconst switchTrackClasses = [\n 'ds:ms-auto ds:inline-flex ds:items-center ds:shrink-0',\n 'ds:h-4 ds:w-7 ds:p-[2px]',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:bg-[color:var(--muted)]',\n 'ds:[[data-state=checked]_&]:bg-[color:var(--primary)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--primary)]',\n // Thumb slides via justify swap — logical-direction safe, no\n // transform to fight under prefers-reduced-motion.\n 'ds:justify-start ds:[[data-state=checked]_&]:justify-end',\n 'ds:forced-colors:border-[CanvasText]',\n // HCM strips fills — paint the checked track with the system\n // selection colour so state isn't conveyed by thumb position alone.\n 'ds:forced-colors:[[data-state=checked]_&]:bg-[SelectedItem]',\n].join(' ');\n\nconst switchThumbClasses = [\n 'ds:block ds:size-3',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[color:var(--background)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-transparent',\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:forced-colors:bg-[CanvasText]',\n].join(' ');\n\nconst SwitchItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.CheckboxItem>,\n DropdownMenuSwitchItemProps\n>(({ className, children, onSelect, name, ...props }, ref) => {\n const { checked, onCheckedChange, disabled } = props;\n useSettingRow(name, {\n kind: 'switch',\n read: () => ({ checked: checked === true, disabled: disabled === true }),\n // What a click does, and only when it would change something: the\n // consumer's onSelect, then the new state.\n pick: (next) => {\n if (next === (checked === true)) return;\n onSelect?.(new Event('menu.itemSelect', { cancelable: true }));\n onCheckedChange?.(next);\n },\n });\n return (\n <RadixDropdownMenu.CheckboxItem\n ref={ref}\n className={itemClasses({ className })}\n data-setting={name}\n onSelect={(event) => {\n // Keep-open is unconditional — prevent first so a throwing consumer\n // handler can't close the menu as a side effect.\n event.preventDefault();\n onSelect?.(event);\n }}\n {...props}\n >\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <span aria-hidden=\"true\" className={switchTrackClasses}>\n <span className={switchThumbClasses} />\n </span>\n </RadixDropdownMenu.CheckboxItem>\n );\n});\nSwitchItem.displayName = 'DropdownMenu.SwitchItem';\n\n/* ------------------------------------------------------------------ */\n/* RadioGroup / RadioItem */\n/* ------------------------------------------------------------------ */\n\nconst RadioGroup = RadixRadioGroup;\n\nexport type DropdownMenuRadioItemProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.RadioItem\n>;\n\nconst RadioItem = forwardRef<\n ElementRef<typeof RadixDropdownMenu.RadioItem>,\n DropdownMenuRadioItemProps\n>(({ className, children, ...props }, ref) => (\n <RadixDropdownMenu.RadioItem\n ref={ref}\n className={itemClasses({ className })}\n {...props}\n >\n {/* Real radio affordance: an always-visible ring with a filled dot\n when selected — a tick reads as a checkbox, not a single choice.\n The ring colours via the item's own data-state so the unchecked\n options still advertise that they are part of a radio set. */}\n <span className={indicatorSlotClasses} aria-hidden=\"true\">\n <span\n className={[\n 'ds:inline-flex ds:size-4 ds:items-center ds:justify-center ds:shrink-0',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:border ds:border-[length:var(--border-width-sm)] ds:border-[color:var(--muted-foreground)]',\n 'ds:[[data-state=checked]_&]:border-[color:var(--accent)]',\n // Accent on the lit row would vanish, so ring and dot take its ink.\n 'ds:not-forced-colors:[[data-highlighted][data-state=checked]_&]:border-[color:var(--accent-foreground)]',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' ')}\n >\n <RadixDropdownMenu.ItemIndicator>\n <span\n className={[\n 'ds:block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--accent)]',\n 'ds:not-forced-colors:group-data-[highlighted]/menu-row:bg-[color:var(--accent-foreground)]',\n 'ds:forced-colors:bg-[CanvasText]',\n ].join(' ')}\n />\n </RadixDropdownMenu.ItemIndicator>\n </span>\n </span>\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n </RadixDropdownMenu.RadioItem>\n));\nRadioItem.displayName = 'DropdownMenu.RadioItem';\n\n/* ------------------------------------------------------------------ */\n/* Label */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuLabelProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Label\n>;\n\nconst Label = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Label>,\n DropdownMenuLabelProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Label\n ref={ref}\n className={labelClasses({ className })}\n {...props}\n />\n));\nLabel.displayName = 'DropdownMenu.Label';\n\n/* ------------------------------------------------------------------ */\n/* Separator */\n/* ------------------------------------------------------------------ */\n\nexport type DropdownMenuSeparatorProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.Separator\n>;\n\nconst MenuSeparator = forwardRef<\n ElementRef<typeof RadixDropdownMenu.Separator>,\n DropdownMenuSeparatorProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Separator ref={ref} asChild {...props}>\n <DsSeparator\n className={['ds:my-[calc(var(--spacing-xs)/2)]', className ?? '']\n .filter(Boolean)\n .join(' ')}\n />\n </RadixDropdownMenu.Separator>\n));\nMenuSeparator.displayName = 'DropdownMenu.Separator';\n\n/* ------------------------------------------------------------------ */\n/* Shortcut — thin wrapper over DS Kbd for the right side of an Item */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuShortcutProps {\n keys: Array<KbdNamedKey | string>;\n separator?: 'none' | 'plus' | 'then';\n}\n\nconst Shortcut = forwardRef<HTMLSpanElement, DropdownMenuShortcutProps>(\n ({ keys, separator = 'none' }, ref) => (\n <span ref={ref} className=\"ds:ms-auto ds:ps-[var(--spacing-sm)]\">\n <Kbd keys={keys} separator={separator} size=\"sm\" />\n </span>\n ),\n);\nShortcut.displayName = 'DropdownMenu.Shortcut';\n\n/* ------------------------------------------------------------------ */\n/* Sub-menu */\n/* ------------------------------------------------------------------ */\n\nconst Sub = RadixDropdownMenu.Sub;\n\nexport interface DropdownMenuSubTriggerProps extends ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubTrigger\n> {\n startIcon?: ReactNode;\n}\n\nconst SubTrigger = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubTrigger>,\n DropdownMenuSubTriggerProps\n>(({ className, startIcon, children, ...props }, ref) => (\n <RadixDropdownMenu.SubTrigger\n ref={ref}\n // Stays lit while focus is in its submenu, so the path is visible.\n className={itemClasses({\n className: [MENU_ROW_HIGHLIGHT.open, className].filter(Boolean).join(' '),\n })}\n {...props}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center\"\n >\n {startIcon}\n </span>\n ) : null}\n <span className=\"ds:flex-1 ds:truncate\">{children}</span>\n <ChevronRight\n aria-hidden\n className=\"ds:ms-auto ds:size-4 ds:shrink-0 ds:rtl:-scale-x-100\"\n />\n </RadixDropdownMenu.SubTrigger>\n));\nSubTrigger.displayName = 'DropdownMenu.SubTrigger';\n\nexport type DropdownMenuSubContentProps = ComponentPropsWithoutRef<\n typeof RadixDropdownMenu.SubContent\n>;\n\nconst SubContent = forwardRef<\n ElementRef<typeof RadixDropdownMenu.SubContent>,\n DropdownMenuSubContentProps\n>(({ className, ...props }, ref) => (\n <RadixDropdownMenu.Portal>\n <PopupRegion popupRef={ref}>\n {(popupRef) => (\n <RadixDropdownMenu.SubContent\n ref={popupRef}\n sideOffset={8}\n data-component=\"dropdown-menu-sub-content\"\n className={contentVariants({ className })}\n {...props}\n />\n )}\n </PopupRegion>\n </RadixDropdownMenu.Portal>\n));\nSubContent.displayName = 'DropdownMenu.SubContent';\n\n/* ------------------------------------------------------------------ */\n/* ChoiceSub */\n/* */\n/* One setting with a few exclusive options, as a single menu row that */\n/* names the setting and shows its current value (\"Row density · */\n/* Compact ›\"). The row opens a submenu of radio items. It replaces the */\n/* \"label + Select\" row inside popovers: no Select ever opens inside a */\n/* menu, and the whole settings menu stays keyboard-native. Picking an */\n/* option keeps the menu open by default, like SwitchItem, so the user */\n/* sees the value land and can adjust the next setting. */\n/* ------------------------------------------------------------------ */\n\nexport interface DropdownMenuChoiceOption<T extends string = string> {\n value: T;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport interface DropdownMenuChoiceSubProps<T extends string = string> {\n /** The setting's name, shown at the start of the row. */\n label: ReactNode;\n /** The selected option's value; its label shows at the end of the row. */\n value: T;\n onValueChange: (value: T) => void;\n options: ReadonlyArray<DropdownMenuChoiceOption<T>>;\n startIcon?: ReactNode;\n disabled?: boolean;\n /** Close the whole menu after a pick. @default false */\n closeOnSelect?: boolean;\n /** Names the row for agents (the menu's `set_value` action and\n * `settings` state) and emits `data-setting`. */\n name?: string;\n className?: string;\n}\n\nfunction ChoiceSub<T extends string>({\n label,\n value,\n onValueChange,\n options,\n startIcon,\n disabled,\n closeOnSelect = false,\n name,\n className,\n}: DropdownMenuChoiceSubProps<T>) {\n const current = options.find((option) => option.value === value);\n useSettingRow(name, {\n kind: 'choice',\n read: () => ({\n value,\n options,\n disabled: disabled === true,\n closeOnSelect,\n }),\n pick: (next) => onValueChange(next as T),\n });\n return (\n <Sub>\n <SubTrigger\n startIcon={startIcon}\n disabled={disabled}\n className={className}\n data-component=\"dropdown-menu-choice\"\n data-value={value}\n data-setting={name}\n >\n <span className=\"ds:flex ds:min-w-0 ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <span className=\"ds:truncate\">{label}</span>\n {current ? (\n <span className=\"ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:[[data-highlighted]_&]:text-current\">\n {current.label}\n </span>\n ) : null}\n </span>\n </SubTrigger>\n <SubContent>\n <RadioGroup\n value={value}\n onValueChange={(next) => onValueChange(next as T)}\n >\n {options.map((option) => (\n <RadioItem\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n onSelect={\n closeOnSelect ? undefined : (event) => event.preventDefault()\n }\n >\n {option.label}\n </RadioItem>\n ))}\n </RadioGroup>\n </SubContent>\n </Sub>\n );\n}\nChoiceSub.displayName = 'DropdownMenu.ChoiceSub';\n\n/* ------------------------------------------------------------------ */\n/* Assembled namespace export */\n/* ------------------------------------------------------------------ */\n\nexport const DropdownMenu = {\n Root,\n Trigger,\n Portal,\n Content,\n Group: RadixGroup,\n Item,\n CheckboxItem,\n SwitchItem,\n RadioGroup,\n RadioItem,\n Label,\n Separator: MenuSeparator,\n Shortcut,\n Sub,\n SubTrigger,\n SubContent,\n ChoiceSub,\n};\n"],"names":["dropdownMenuAgent","handle","args","contentVariants","cva","itemClasses","MENU_ROW_HIGHLIGHT","labelClasses","indicatorSlotClasses","SettingRowsContext","createContext","nextFrame","resolve","DropdownMenuIdContext","Root","dir","id","openProp","defaultOpen","onOpenChange","props","autoDir","useDocumentDirection","openRaw","setOpen","useControllableState","open","openRef","useRef","useEffect","rowsRef","openRequestsRef","registerRow","useMemo","name","row","show","next","withRow","setting","kind","apply","opened","requests","frame","value","options","disabled","option","checked","closeOnSelect","o","useAgentRegistration","jsx","RadixDropdownMenu","Trigger","Portal","RadixGroup","RadixRadioGroup","Content","forwardRef","className","sideOffset","ref","instanceId","useContext","PopupRegion","popupRef","Item","startIcon","endIcon","description","shortcut","children","jsxs","Kbd","CheckboxItem","Check","useSettingRow","register","latest","useLayoutEffect","proxy","switchTrackClasses","switchThumbClasses","SwitchItem","onSelect","onCheckedChange","event","RadioGroup","RadioItem","Label","MenuSeparator","DsSeparator","Shortcut","keys","separator","Sub","SubTrigger","ChevronRight","SubContent","ChoiceSub","label","onValueChange","current","DropdownMenu"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { jsx as i, jsxs as L } from "react/jsx-runtime";
|
|
|
3
3
|
import { T as P } from "./tag-DOZGz0fT.js";
|
|
4
4
|
import { useTranslation as x } from "react-i18next";
|
|
5
5
|
import { I as S } from "./icon-button-S8_weU3g.js";
|
|
6
|
-
import { I as V } from "./icon-button-group-
|
|
6
|
+
import { I as V } from "./icon-button-group-mXvYDaba.js";
|
|
7
7
|
import { A as $, a as H } from "./arrow-up-BYvcvTkB.js";
|
|
8
8
|
import { S as G } from "./square-check-big-dj0o8yA3.js";
|
|
9
9
|
import { S as O } from "./square-DASBRZ0U.js";
|
|
@@ -409,4 +409,4 @@ export {
|
|
|
409
409
|
ge as r,
|
|
410
410
|
me as u
|
|
411
411
|
};
|
|
412
|
-
//# sourceMappingURL=editable-currency-cell-renderer-
|
|
412
|
+
//# sourceMappingURL=editable-currency-cell-renderer-BQYL5GjP.js.map
|