@alfadocs/ui-kit-debug 0.77.0 → 0.79.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/_chunks/{alia-sidebar-w6B0TEx7.js → alia-sidebar-DzNz1gDf.js} +2 -2
  2. package/dist/_chunks/{alia-sidebar-w6B0TEx7.js.map → alia-sidebar-DzNz1gDf.js.map} +1 -1
  3. package/dist/_chunks/calendar-4dXTvsCz.js +1136 -0
  4. package/dist/_chunks/calendar-4dXTvsCz.js.map +1 -0
  5. package/dist/_chunks/calendar-event-card-C6qGtywL.js +257 -0
  6. package/dist/_chunks/calendar-event-card-C6qGtywL.js.map +1 -0
  7. package/dist/_chunks/{chat-input-BTCDqUDX.js → chat-input-QpHxBEnN.js} +32 -31
  8. package/dist/_chunks/chat-input-QpHxBEnN.js.map +1 -0
  9. package/dist/_chunks/document-preview-nwfulDEs.js +290 -0
  10. package/dist/_chunks/document-preview-nwfulDEs.js.map +1 -0
  11. package/dist/_chunks/{fiscal-code-input-DWA6C8x8.js → fiscal-code-input-QP9gkyDE.js} +2 -2
  12. package/dist/_chunks/fiscal-code-input-QP9gkyDE.js.map +1 -0
  13. package/dist/_chunks/{patient-details-zy76MRh7.js → patient-details-COvYWp2e.js} +2 -2
  14. package/dist/_chunks/{patient-details-zy76MRh7.js.map → patient-details-COvYWp2e.js.map} +1 -1
  15. package/dist/_chunks/signature-request-CEOrCDyk.js +341 -0
  16. package/dist/_chunks/signature-request-CEOrCDyk.js.map +1 -0
  17. package/dist/agent-catalog.json +1 -1
  18. package/dist/components/_shared/contrast-warning.d.ts +46 -0
  19. package/dist/components/_shared/contrast-warning.d.ts.map +1 -0
  20. package/dist/components/calendar/calendar.d.ts +284 -7
  21. package/dist/components/calendar/calendar.d.ts.map +1 -1
  22. package/dist/components/calendar/index.d.ts +1 -1
  23. package/dist/components/calendar/index.d.ts.map +1 -1
  24. package/dist/components/calendar/index.js +1 -1
  25. package/dist/components/calendar-event-card/calendar-event-card.d.ts +103 -0
  26. package/dist/components/calendar-event-card/calendar-event-card.d.ts.map +1 -0
  27. package/dist/components/calendar-event-card/index.d.ts +3 -0
  28. package/dist/components/calendar-event-card/index.d.ts.map +1 -0
  29. package/dist/components/calendar-event-card/index.js +5 -0
  30. package/dist/components/calendar-event-card/index.js.map +1 -0
  31. package/dist/components/chat-input/chat-input.d.ts.map +1 -1
  32. package/dist/components/chat-input/index.js +1 -1
  33. package/dist/components/document-preview/document-preview.d.ts +10 -0
  34. package/dist/components/document-preview/document-preview.d.ts.map +1 -1
  35. package/dist/components/document-preview/index.js +1 -1
  36. package/dist/components/fiscal-code-input/index.js +1 -1
  37. package/dist/components/index.d.ts +1 -0
  38. package/dist/components/index.d.ts.map +1 -1
  39. package/dist/components/patient-details/index.js +1 -1
  40. package/dist/i18n/locales/ar.d.ts +6 -0
  41. package/dist/i18n/locales/ar.d.ts.map +1 -1
  42. package/dist/i18n/locales/ar.js +6 -0
  43. package/dist/i18n/locales/ar.js.map +1 -1
  44. package/dist/i18n/locales/de.d.ts +6 -0
  45. package/dist/i18n/locales/de.d.ts.map +1 -1
  46. package/dist/i18n/locales/de.js +6 -0
  47. package/dist/i18n/locales/de.js.map +1 -1
  48. package/dist/i18n/locales/el.d.ts +6 -0
  49. package/dist/i18n/locales/el.d.ts.map +1 -1
  50. package/dist/i18n/locales/el.js +6 -0
  51. package/dist/i18n/locales/el.js.map +1 -1
  52. package/dist/i18n/locales/en.d.ts +6 -0
  53. package/dist/i18n/locales/en.d.ts.map +1 -1
  54. package/dist/i18n/locales/en.js +6 -0
  55. package/dist/i18n/locales/en.js.map +1 -1
  56. package/dist/i18n/locales/es.d.ts +6 -0
  57. package/dist/i18n/locales/es.d.ts.map +1 -1
  58. package/dist/i18n/locales/es.js +6 -0
  59. package/dist/i18n/locales/es.js.map +1 -1
  60. package/dist/i18n/locales/fr.d.ts +6 -0
  61. package/dist/i18n/locales/fr.d.ts.map +1 -1
  62. package/dist/i18n/locales/fr.js +6 -0
  63. package/dist/i18n/locales/fr.js.map +1 -1
  64. package/dist/i18n/locales/hi.d.ts +6 -0
  65. package/dist/i18n/locales/hi.d.ts.map +1 -1
  66. package/dist/i18n/locales/hi.js +6 -0
  67. package/dist/i18n/locales/hi.js.map +1 -1
  68. package/dist/i18n/locales/it.d.ts +6 -0
  69. package/dist/i18n/locales/it.d.ts.map +1 -1
  70. package/dist/i18n/locales/it.js +6 -0
  71. package/dist/i18n/locales/it.js.map +1 -1
  72. package/dist/i18n/locales/ja.d.ts +6 -0
  73. package/dist/i18n/locales/ja.d.ts.map +1 -1
  74. package/dist/i18n/locales/ja.js +6 -0
  75. package/dist/i18n/locales/ja.js.map +1 -1
  76. package/dist/i18n/locales/nl.d.ts +6 -0
  77. package/dist/i18n/locales/nl.d.ts.map +1 -1
  78. package/dist/i18n/locales/nl.js +6 -0
  79. package/dist/i18n/locales/nl.js.map +1 -1
  80. package/dist/i18n/locales/pl.d.ts +6 -0
  81. package/dist/i18n/locales/pl.d.ts.map +1 -1
  82. package/dist/i18n/locales/pl.js +6 -0
  83. package/dist/i18n/locales/pl.js.map +1 -1
  84. package/dist/i18n/locales/pt.d.ts +6 -0
  85. package/dist/i18n/locales/pt.d.ts.map +1 -1
  86. package/dist/i18n/locales/pt.js +6 -0
  87. package/dist/i18n/locales/pt.js.map +1 -1
  88. package/dist/i18n/locales/ro.d.ts +6 -0
  89. package/dist/i18n/locales/ro.d.ts.map +1 -1
  90. package/dist/i18n/locales/ro.js +6 -0
  91. package/dist/i18n/locales/ro.js.map +1 -1
  92. package/dist/i18n/locales/ru.d.ts +6 -0
  93. package/dist/i18n/locales/ru.d.ts.map +1 -1
  94. package/dist/i18n/locales/ru.js +6 -0
  95. package/dist/i18n/locales/ru.js.map +1 -1
  96. package/dist/i18n/locales/sq.d.ts +6 -0
  97. package/dist/i18n/locales/sq.d.ts.map +1 -1
  98. package/dist/i18n/locales/sq.js +6 -0
  99. package/dist/i18n/locales/sq.js.map +1 -1
  100. package/dist/i18n/locales/sv.d.ts +6 -0
  101. package/dist/i18n/locales/sv.d.ts.map +1 -1
  102. package/dist/i18n/locales/sv.js +6 -0
  103. package/dist/i18n/locales/sv.js.map +1 -1
  104. package/dist/i18n/locales/tr.d.ts +6 -0
  105. package/dist/i18n/locales/tr.d.ts.map +1 -1
  106. package/dist/i18n/locales/tr.js +6 -0
  107. package/dist/i18n/locales/tr.js.map +1 -1
  108. package/dist/i18n/locales/zh.d.ts +6 -0
  109. package/dist/i18n/locales/zh.d.ts.map +1 -1
  110. package/dist/i18n/locales/zh.js +6 -0
  111. package/dist/i18n/locales/zh.js.map +1 -1
  112. package/dist/index.js +252 -250
  113. package/dist/index.js.map +1 -1
  114. package/dist/locales/ar.json +6 -0
  115. package/dist/locales/de.json +6 -0
  116. package/dist/locales/el.json +6 -0
  117. package/dist/locales/en.json +6 -0
  118. package/dist/locales/es.json +6 -0
  119. package/dist/locales/fr.json +6 -0
  120. package/dist/locales/hi.json +6 -0
  121. package/dist/locales/it.json +6 -0
  122. package/dist/locales/ja.json +6 -0
  123. package/dist/locales/nl.json +6 -0
  124. package/dist/locales/pl.json +6 -0
  125. package/dist/locales/pt.json +6 -0
  126. package/dist/locales/ro.json +6 -0
  127. package/dist/locales/ru.json +6 -0
  128. package/dist/locales/sq.json +6 -0
  129. package/dist/locales/sv.json +6 -0
  130. package/dist/locales/tr.json +6 -0
  131. package/dist/locales/zh.json +6 -0
  132. package/dist/patterns/alia-assistant/index.js +1 -1
  133. package/dist/patterns/signature-request/index.js +1 -1
  134. package/dist/patterns/signature-request/signature-request.d.ts +7 -0
  135. package/dist/patterns/signature-request/signature-request.d.ts.map +1 -1
  136. package/dist/tokens.css +9 -5
  137. package/package.json +5 -1
  138. package/dist/_chunks/calendar-DeAlFPsF.js +0 -1050
  139. package/dist/_chunks/calendar-DeAlFPsF.js.map +0 -1
  140. package/dist/_chunks/chat-input-BTCDqUDX.js.map +0 -1
  141. package/dist/_chunks/document-preview-CvHnHf6T.js +0 -243
  142. package/dist/_chunks/document-preview-CvHnHf6T.js.map +0 -1
  143. package/dist/_chunks/fiscal-code-input-DWA6C8x8.js.map +0 -1
  144. package/dist/_chunks/signature-request-C-mskXwi.js +0 -318
  145. package/dist/_chunks/signature-request-C-mskXwi.js.map +0 -1
  146. package/dist/components/calendar/contrast-warning.d.ts +0 -20
  147. package/dist/components/calendar/contrast-warning.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-preview-CvHnHf6T.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. Render branches, */\n/* in order: PDF (application/pdf + src) → kit PDFViewer; image (image/* */\n/* + src) → <img>; otherwise a metadata card; no name → 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 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 { 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 /** ISO 8601 timestamp of the last modification. */\n updatedAt?: 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();\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 — pdf / image / metadata card. The title is NOT\n 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\n if (kind === 'pdf' && doc.src) {\n return (\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\"\n />\n );\n }\n\n if (kind === 'image' && doc.src) {\n return (\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:ms-auto ds:me-auto ds:object-contain\"\n />\n );\n }\n\n // Metadata card.\n const status = doc.metadata?.signatureStatus;\n const hasBadges =\n Boolean(doc.metadata?.documentType) ||\n Boolean(doc.metadata?.clinical) ||\n (status !== undefined && status !== 'none');\n\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]\">\n {hasBadges && (\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {doc.metadata?.documentType && (\n <Badge variant=\"neutral\" size=\"sm\">\n {doc.metadata.documentType}\n </Badge>\n )}\n {doc.metadata?.clinical && (\n <Badge variant=\"info\" size=\"sm\">\n {t('documentPreview.clinical', 'Clinical')}\n </Badge>\n )}\n {status && status !== 'none' && (\n <Badge variant={SIGNATURE_VARIANT[status]} size=\"sm\" withDot>\n {t(`documentPreview.signature.${status}`, status)}\n </Badge>\n )}\n </span>\n )}\n\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 {doc.metadata?.size !== undefined && (\n <>\n <dt className=\"ds:text-muted-foreground\">\n {t('documentPreview.fields.size', 'Size')}\n </dt>\n <dd className=\"ds:m-0\">\n {formatBytes(doc.metadata.size, i18n.language, t)}\n </dd>\n </>\n )}\n {doc.metadata?.updatedAt && (\n <>\n <dt className=\"ds:text-muted-foreground\">\n {t('documentPreview.fields.modified', 'Modified')}\n </dt>\n <dd className=\"ds:m-0\">\n {new Intl.DateTimeFormat(i18n.language, {\n dateStyle: 'medium',\n }).format(new Date(doc.metadata.updatedAt))}\n </dd>\n </>\n )}\n {doc.metadata?.expiresAt && (\n <>\n <dt className=\"ds:text-muted-foreground\">\n {t('documentPreview.fields.expires', 'Expires')}\n </dt>\n <dd className=\"ds:m-0\">\n {new Intl.DateTimeFormat(i18n.language, {\n dateStyle: 'medium',\n }).format(new Date(doc.metadata.expiresAt))}\n </dd>\n </>\n )}\n </dl>\n\n <p className=\"type-body-sm ds:m-0 ds:text-muted-foreground\">\n {t('documentPreview.noPreview', 'No preview available.')}\n </p>\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","jsx","PDFViewer","status","_a","hasBadges","_b","_c","jsxs","_d","Badge","_e","_f","Fragment","_g","_h","HeaderMimeIcon","headerIcon","headerTitle","content","EmptyState","Tabs","TabsList","TabIcon","TabsTrigger","TabsContent","PanelHeader"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"fiscal-code-input-DWA6C8x8.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calculator.mjs","../../src/components/fiscal-code-input/fiscal-code-input.agent.ts","../../src/components/fiscal-code-input/is-valid-codice-fiscale.ts","../../src/components/fiscal-code-input/calculate-codice-fiscale.ts","../../src/components/fiscal-code-input/fiscal-code-input.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 [\"rect\", { width: \"16\", height: \"20\", x: \"4\", y: \"2\", rx: \"2\", key: \"1nb95v\" }],\n [\"line\", { x1: \"8\", x2: \"16\", y1: \"6\", y2: \"6\", key: \"x4nwl0\" }],\n [\"line\", { x1: \"16\", x2: \"16\", y1: \"14\", y2: \"18\", key: \"wjye3r\" }],\n [\"path\", { d: \"M16 10h.01\", key: \"1m94wz\" }],\n [\"path\", { d: \"M12 10h.01\", key: \"1nrarc\" }],\n [\"path\", { d: \"M8 10h.01\", key: \"19clt8\" }],\n [\"path\", { d: \"M12 14h.01\", key: \"1etili\" }],\n [\"path\", { d: \"M8 14h.01\", key: \"6423bh\" }],\n [\"path\", { d: \"M12 18h.01\", key: \"mhygvu\" }],\n [\"path\", { d: \"M8 18h.01\", key: \"lrp35t\" }]\n];\nconst Calculator = createLucideIcon(\"calculator\", __iconNode);\n\nexport { __iconNode, Calculator as default };\n//# sourceMappingURL=calculator.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — FiscalCodeInput. */\n/* */\n/* See `src/docs/26-agent-readiness.mdx` for the contract. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { FiscalCodeInputHandle } from './fiscal-code-input';\n\nexport const fiscalCodeInputAgent: AgentAdapter<FiscalCodeInputHandle> = {\n id: 'fiscal-code-input',\n capabilities: ['set_value'],\n state: {\n value: {\n type: 'string',\n descriptionKey: 'ui.agent.fiscalCodeInput.state.value',\n description:\n 'Current codice fiscale, normalised (uppercased, 0–16 [A-Z0-9] characters).',\n read: (handle) => handle.getValue(),\n },\n isValid: {\n type: 'boolean',\n descriptionKey: 'ui.agent.fiscalCodeInput.state.isValid',\n description:\n 'Whether the value is 16 structurally-sound characters with a matching control character.',\n read: (handle) => handle.isValid(),\n },\n },\n actions: {\n set_value: {\n safety: 'write',\n argsType: '{ value: string }',\n argsSchema: {\n type: 'object',\n properties: { value: { type: 'string' } },\n required: ['value'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.fiscalCodeInput.actions.setValue',\n description:\n 'Replace the codice fiscale. The value is uppercased and stripped to [A-Z0-9], capped at 16 characters.',\n examples: [\n {\n args: { value: 'RSSMRA85T10A562S' },\n note: 'A complete, structurally-sound codice fiscale.',\n },\n ],\n invoke: (handle, args: { value: string }) => {\n handle.setValue(args.value);\n },\n },\n clear: {\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.fiscalCodeInput.actions.clear',\n description: 'Empty the input. Loses any typed value.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n focus: {\n safety: 'read',\n descriptionKey: 'ui.agent.fiscalCodeInput.actions.focus',\n description: 'Move keyboard focus to the codice fiscale input.',\n invoke: (handle) => {\n handle.focus();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'fiscal-code-input',\n description: 'Marks the FiscalCodeInput wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* Codice Fiscale (Italian fiscal code) — client-side structural + */\n/* control-character checksum validator. */\n/* */\n/* SCOPE: this is a CLIENT MIRROR of the platform's */\n/* ValidateFiscalCodeService used ONLY to give instant feedback. It */\n/* validates two things and nothing more: */\n/* 1. The structural shape — 15 alphanumerics followed by 1 control */\n/* letter, where each position obeys its letter/digit class */\n/* (/^[A-Z0-9]{15}[A-Z]$/ plus the per-position class pattern). */\n/* 2. The 16th control character, derived from the first 15 via the */\n/* official odd/even per-position weighted-sum mod-26 algorithm. */\n/* */\n/* OUT OF SCOPE (server stays source of truth): birth-date / comune */\n/* Belfiore-code cross-checks and omocodia digit-substitution. A */\n/* structurally-correct code with a valid control character can still */\n/* be rejected by the server — the client never hard-blocks submit on */\n/* its own verdict. */\n/* ------------------------------------------------------------------ */\n\n/** Outcome of a structural + checksum check on a 16-char candidate. */\nexport type FiscalCodeReason =\n | 'empty'\n | 'incomplete'\n | 'badFormat'\n | 'badChecksum'\n | 'valid';\n\n/**\n * Position classes for the 15 informative characters. Positions are\n * 0-indexed. Letter positions accept A–Z; digit positions accept 0–9.\n * The 16th (control) character is a letter and validated separately.\n *\n * Standard layout (ignoring omocodia substitution, which the SERVER\n * handles): surname (0–2 letters), name (3–5 letters), year (6–7\n * digits), month (8 letter), day (9–10 digits), comune (11 letter +\n * 12–14 digits). For client structural feedback we accept the canonical\n * non-omocodic layout; omocodic variants surface as `badFormat` here and\n * are resolved server-side — documented as an accepted client limitation.\n */\nconst LETTER_POSITIONS = new Set([0, 1, 2, 3, 4, 5, 8, 11]);\nconst DIGIT_POSITIONS = new Set([6, 7, 9, 10, 12, 13, 14]);\n\nconst ODD_MAP: Readonly<Record<string, number>> = Object.freeze({\n '0': 1,\n '1': 0,\n '2': 5,\n '3': 7,\n '4': 9,\n '5': 13,\n '6': 15,\n '7': 17,\n '8': 19,\n '9': 21,\n A: 1,\n B: 0,\n C: 5,\n D: 7,\n E: 9,\n F: 13,\n G: 15,\n H: 17,\n I: 19,\n J: 21,\n K: 2,\n L: 4,\n M: 18,\n N: 20,\n O: 11,\n P: 3,\n Q: 6,\n R: 8,\n S: 12,\n T: 14,\n U: 16,\n V: 10,\n W: 22,\n X: 25,\n Y: 24,\n Z: 23,\n});\n\nconst EVEN_MAP: Readonly<Record<string, number>> = Object.freeze({\n '0': 0,\n '1': 1,\n '2': 2,\n '3': 3,\n '4': 4,\n '5': 5,\n '6': 6,\n '7': 7,\n '8': 8,\n '9': 9,\n A: 0,\n B: 1,\n C: 2,\n D: 3,\n E: 4,\n F: 5,\n G: 6,\n H: 7,\n I: 8,\n J: 9,\n K: 10,\n L: 11,\n M: 12,\n N: 13,\n O: 14,\n P: 15,\n Q: 16,\n R: 17,\n S: 18,\n T: 19,\n U: 20,\n V: 21,\n W: 22,\n X: 23,\n Y: 24,\n Z: 25,\n});\n\nconst REMAINDER_TO_CONTROL = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n/** True when every informative position matches its letter/digit class. */\nfunction hasValidStructure(code: string): boolean {\n if (!/^[A-Z0-9]{15}[A-Z]$/.test(code)) return false;\n for (let i = 0; i < 15; i += 1) {\n const ch = code[i];\n const isDigit = ch >= '0' && ch <= '9';\n if (LETTER_POSITIONS.has(i) && isDigit) return false;\n if (DIGIT_POSITIONS.has(i) && !isDigit) return false;\n }\n return true;\n}\n\n/**\n * Compute the expected 16th control character from the first 15\n * informative characters. The input MUST already be 15 uppercase\n * `[A-Z0-9]` characters (callers guard with `hasValidStructure`).\n */\nexport function computeControlChar(first15: string): string {\n let sum = 0;\n for (let i = 0; i < 15; i += 1) {\n const ch = first15[i];\n // Per the official spec, odd POSITIONS (1st, 3rd, … — i.e. 0-indexed\n // even i) use the ODD weight table; even positions use the EVEN table.\n sum += i % 2 === 0 ? ODD_MAP[ch] : EVEN_MAP[ch];\n }\n return REMAINDER_TO_CONTROL[sum % 26];\n}\n\n/**\n * Classify a normalised (uppercased, `[A-Z0-9]`-only) candidate.\n *\n * - `empty` — no characters.\n * - `incomplete` — fewer than 16 characters.\n * - `badFormat` — 16 characters but the position-class pattern fails.\n * - `badChecksum` — 16 well-formed characters but the control char is wrong.\n * - `valid` — structurally sound and the control char matches.\n */\nexport function classifyCodiceFiscale(raw: string): FiscalCodeReason {\n if (raw.length === 0) return 'empty';\n if (raw.length < 16) return 'incomplete';\n // raw is normalised to at most 16 chars by the component; guard anyway.\n const code = raw.slice(0, 16);\n if (!hasValidStructure(code)) return 'badFormat';\n if (computeControlChar(code.slice(0, 15)) !== code[15]) return 'badChecksum';\n return 'valid';\n}\n\n/** Convenience boolean: structurally sound AND control character matches. */\nexport function isValidCodiceFiscale(raw: string): boolean {\n return classifyCodiceFiscale(raw) === 'valid';\n}\n","/* ------------------------------------------------------------------ */\n/* Codice Fiscale (Italian fiscal code) — client-side DERIVATION. */\n/* */\n/* SCOPE: a pure, self-contained function that computes the 16-char */\n/* codice fiscale from a person's identity data when the caller already */\n/* holds it. This is a CONVENIENCE so a form that knows surname / name */\n/* / birth date / sex / birthplace can pre-fill the field — the server */\n/* (ValidateFiscalCodeService) remains the source of truth. */\n/* */\n/* OUT OF SCOPE: municipality-name → Belfiore (cadastral) code lookup. */\n/* That mapping requires a ~8000-row table the kit must not bundle, so */\n/* the caller supplies the 4-character `belfioreCode` directly. */\n/* Omocodia digit-substitution (used only when two people would share a */\n/* code) is also out of scope — the base, non-omocodic code is emitted. */\n/* ------------------------------------------------------------------ */\n\nimport { computeControlChar } from './is-valid-codice-fiscale';\n\n/** Identity inputs needed to derive the (non-omocodic) codice fiscale. */\nexport interface CodiceFiscaleInput {\n /** Family name (cognome). Diacritics are folded; non-letters ignored. */\n surname: string;\n /** Given name (nome). Diacritics are folded; non-letters ignored. */\n name: string;\n /** Date of birth — a `Date` or an ISO `YYYY-MM-DD` (or full ISO) string. */\n birthDate: Date | string;\n /** Biological sex as recorded for the fiscal code: 'M' or 'F'. */\n sex: 'M' | 'F';\n /** 4-character cadastral / Belfiore code of the birthplace (e.g. H501). */\n belfioreCode: string;\n}\n\nconst VOWELS = new Set(['A', 'E', 'I', 'O', 'U']);\n\n/** Month → fiscal-code letter (Jan→A … Dec→T), 0-indexed by month. */\nconst MONTH_LETTERS = [\n 'A',\n 'B',\n 'C',\n 'D',\n 'E',\n 'H',\n 'L',\n 'M',\n 'P',\n 'R',\n 'S',\n 'T',\n] as const;\n\n/**\n * Fold a free-text name to bare uppercase A–Z: strip diacritics via NFD,\n * drop combining marks, uppercase, and keep only A–Z. Spaces / apostrophes\n * in compound names collapse away (the algorithm treats the name as one run\n * of letters).\n */\nfunction foldToLetters(input: string): string {\n return input\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toUpperCase()\n .replace(/[^A-Z]/g, '');\n}\n\nfunction consonantsOf(letters: string): string {\n return [...letters].filter((c) => !VOWELS.has(c)).join('');\n}\n\nfunction vowelsOf(letters: string): string {\n return [...letters].filter((c) => VOWELS.has(c)).join('');\n}\n\n/**\n * Surname triple: consonants first, then vowels, right-padded with 'X'.\n * (e.g. \"Rossi\" → R S S; \"Fo\" → F O X.)\n */\nfunction surnameCode(surname: string): string {\n const letters = foldToLetters(surname);\n const code = consonantsOf(letters) + vowelsOf(letters);\n return (code + 'XXX').slice(0, 3);\n}\n\n/**\n * Name triple. With 4+ consonants, take the 1st, 3rd and 4th (the standard\n * \"skip the 2nd consonant\" rule); otherwise consonants then vowels,\n * right-padded with 'X'. (e.g. \"Mario\" → M R A; \"Maria\" → M RA → MRA;\n * \"Gianfranco\" → G F R.)\n */\nfunction nameCode(name: string): string {\n const letters = foldToLetters(name);\n const cons = consonantsOf(letters);\n if (cons.length >= 4) {\n return cons[0] + cons[2] + cons[3];\n }\n const code = cons + vowelsOf(letters);\n return (code + 'XXX').slice(0, 3);\n}\n\n/** Coerce a `Date` or ISO string to a `Date`; throws on an unparseable value. */\nfunction toDate(birthDate: Date | string): Date {\n const d = birthDate instanceof Date ? birthDate : new Date(birthDate);\n if (Number.isNaN(d.getTime())) {\n throw new Error(`calculateCodiceFiscale: invalid birthDate \"${birthDate}\"`);\n }\n return d;\n}\n\n/**\n * Two-digit zero-padded value. The fiscal code uses LOCAL calendar fields\n * (a birth date is a calendar date, not an instant), so we read the UTC\n * fields of a date-only ISO string consistently — see the date handling\n * below.\n */\nfunction pad2(n: number): string {\n return String(n).padStart(2, '0');\n}\n\n/**\n * Birth-date triple: 2-digit year + month letter + 2-digit day (+40 for\n * female). Returns the 5 characters `YYMDD`.\n *\n * Date fields are read in UTC so a date-only string like \"1980-01-01\"\n * (parsed by `Date` as UTC midnight) yields day 01 regardless of the\n * runtime timezone. Callers passing a `Date` built from local components\n * should construct it at UTC midnight (e.g. `new Date('1980-01-01')`).\n */\nfunction birthCode(birthDate: Date | string, sex: 'M' | 'F'): string {\n const d = toDate(birthDate);\n const yy = pad2(d.getUTCFullYear() % 100);\n const monthLetter = MONTH_LETTERS[d.getUTCMonth()];\n const day = d.getUTCDate() + (sex === 'F' ? 40 : 0);\n return yy + monthLetter + pad2(day);\n}\n\n/**\n * Compute the full 16-character (non-omocodic) codice fiscale from a\n * person's identity data. The caller supplies the 4-char Belfiore code of\n * the birthplace (the kit does not bundle the municipality table).\n *\n * Throws if `birthDate` is unparseable or `belfioreCode` is not 4\n * `[A-Z][0-9]{3}`-shaped characters — i.e. a letter followed by 3 digits,\n * the canonical Belfiore shape.\n */\nexport function calculateCodiceFiscale(input: CodiceFiscaleInput): string {\n const { surname, name, birthDate, sex, belfioreCode } = input;\n\n const belfiore = belfioreCode.trim().toUpperCase();\n if (!/^[A-Z][0-9]{3}$/.test(belfiore)) {\n throw new Error(\n `calculateCodiceFiscale: belfioreCode must be a letter + 3 digits (e.g. \"H501\"), got \"${belfioreCode}\"`,\n );\n }\n\n const first15 =\n surnameCode(surname) +\n nameCode(name) +\n birthCode(birthDate, sex) +\n belfiore;\n\n return first15 + computeControlChar(first15);\n}\n","import {\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type ClipboardEvent,\n type CompositionEvent,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { AlertCircle, CheckCircle2, Calculator } from 'lucide-react';\nimport {\n FormFieldContext,\n useFormField,\n} from '../form-field/form-field-context';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_HEIGHT,\n INPUT_SURFACE_TEXT,\n INPUT_SURFACE_TONE,\n} from '../_shared/input-surface';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent';\nimport { IconButton } from '../button';\nimport { fiscalCodeInputAgent } from './fiscal-code-input.agent';\nimport {\n classifyCodiceFiscale,\n type FiscalCodeReason,\n} from './is-valid-codice-fiscale';\nimport {\n calculateCodiceFiscale,\n type CodiceFiscaleInput,\n} from './calculate-codice-fiscale';\n\n/** Agent-readiness curated handle for FiscalCodeInput. */\nexport interface FiscalCodeInputHandle {\n getValue: () => string;\n setValue: (value: string) => void;\n clear: () => void;\n focus: () => void;\n isValid: () => boolean;\n}\n\n/** Structured payload emitted on every keystroke alongside the raw value. */\nexport interface FiscalCodeChangeMeta {\n /** Structurally sound AND control character matches (always 16 chars). */\n isValid: boolean;\n /** Whether all 16 characters are present (regardless of validity). */\n isComplete: boolean;\n /** Why the value is (in)valid — drives consumer messaging. */\n reason: FiscalCodeReason;\n}\n\nexport interface FiscalCodeInputProps {\n /** Controlled value (raw, uppercased, no spaces). Pair with onChange. */\n value?: string;\n /** Uncontrolled initial value. Normalised on mount. */\n defaultValue?: string;\n /** Fires on every keystroke with the normalised raw string + meta. */\n onChange?: (raw: string, meta: FiscalCodeChangeMeta) => void;\n size?: 'sm' | 'md' | 'lg';\n tone?: 'default' | 'error';\n /** When the invalid tone + error string surface. Never marks partial input invalid. */\n validateOn?: 'change' | 'blur' | 'submit';\n /** Controlled escape hatch to force the invalid state (e.g. server rejection). */\n showError?: boolean;\n /** Overrides the kit's default i18n error string. */\n errorMessage?: string;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n placeholder?: string;\n /** Render the \"16 characters\" caption when NOT inside a FormField. */\n showFormatHint?: boolean;\n /**\n * OPT-IN. When the consuming form already holds the person's identity\n * data, supply it here to render an inline \"calculate\" affordance: a\n * small icon button that derives the codice fiscale and fills the field.\n * The caller supplies the 4-char `belfioreCode` of the birthplace — the\n * kit does not bundle the municipality lookup table. Omit to render\n * nothing extra (no behavioural change). Ignored when readOnly/disabled.\n */\n calculateFrom?: CodiceFiscaleInput;\n id?: string;\n name?: string;\n className?: string;\n 'aria-label'?: string;\n}\n\nconst MAX_LEN = 16;\n\nconst wrapperVariants = cva(\n ['ds:relative ds:flex ds:items-center ds:w-full', INPUT_SURFACE_CHROME].join(\n ' ',\n ),\n {\n variants: {\n size: {\n sm: INPUT_SURFACE_HEIGHT.sm,\n md: INPUT_SURFACE_HEIGHT.md,\n lg: INPUT_SURFACE_HEIGHT.lg,\n },\n tone: {\n default: INPUT_SURFACE_TONE.default,\n error: `${INPUT_SURFACE_TONE.error} ds:focus-within:outline-destructive`,\n },\n },\n defaultVariants: { size: 'md', tone: 'default' },\n },\n);\n\nconst inputVariants = cva(\n [\n // dir=\"ltr\" + tabular-nums keep the alphanumeric code rendering\n // left-to-right and evenly spaced even under an RTL/CJK surrounding\n // UI — this is a value-RENDERING concern (the code is never mirrored),\n // not a layout-direction violation, so logical-prop rules don't apply\n // to the code glyphs themselves.\n 'ds:w-full ds:min-w-0 ds:bg-transparent ds:text-foreground ds:placeholder:text-muted-foreground',\n 'ds:border-0 ds:outline-none ds:tabular-nums ds:uppercase ds:tracking-wide',\n 'ds:disabled:cursor-not-allowed',\n 'ds:read-only:cursor-default',\n ].join(' '),\n {\n variants: {\n size: {\n sm: `ds:pe-3 ${INPUT_SURFACE_TEXT.sm}`,\n md: `ds:pe-3 ${INPUT_SURFACE_TEXT.md}`,\n lg: `ds:pe-4 ${INPUT_SURFACE_TEXT.lg}`,\n },\n // When the calculate affordance is shown, the input text starts after\n // the inline-start icon button (mirrors `hasEnd`'s pe-10 reservation).\n hasStart: {\n true: 'ds:ps-10',\n false: '',\n },\n hasEnd: {\n true: 'ds:pe-10',\n false: '',\n },\n },\n compoundVariants: [\n { size: 'sm', hasStart: false, class: 'ds:ps-3' },\n { size: 'md', hasStart: false, class: 'ds:ps-3' },\n { size: 'lg', hasStart: false, class: 'ds:ps-4' },\n ],\n defaultVariants: { size: 'md', hasStart: false, hasEnd: false },\n },\n);\n\nconst adornmentEnd =\n 'ds:absolute ds:inset-y-0 ds:end-0 ds:pe-3 ds:flex ds:items-center ds:pointer-events-none ds:[&_svg]:size-4';\n\n// Inline-start wrapper for the calculate icon button. Positioned over the\n// reserved `ps-10` gutter; the button itself remains pointer-interactive.\nconst adornmentStart =\n 'ds:absolute ds:inset-y-0 ds:start-0 ds:ps-1 ds:flex ds:items-center';\n\nconst captionBase = 'type-body-sm ds:mt-[var(--spacing-xs)]';\n\n/** Uppercase, strip non-[A-Z0-9], normalise full-width / Eastern-Arabic\n * digits, and cap at 16 characters. */\nfunction normaliseFiscalCode(input: string): string {\n return (\n input\n .normalize('NFKC')\n // Eastern-Arabic & Extended-Arabic-Indic digits → ASCII (otp-input precedent).\n .replace(/[٠-٩]/g, (c) => String(c.charCodeAt(0) - 0x0660))\n .replace(/[۰-۹]/g, (c) => String(c.charCodeAt(0) - 0x06f0))\n .toUpperCase()\n .replace(/[^A-Z0-9]/g, '')\n .slice(0, MAX_LEN)\n );\n}\n\n/** Count [A-Z0-9] characters before `position` in the RAW (pre-normalise)\n * string, so the caret can be restored after re-normalising. */\nfunction countKeptBefore(str: string, position: number): number {\n let kept = 0;\n for (let i = 0; i < position && i < str.length; i += 1) {\n const c = str[i];\n if (\n (c >= '0' && c <= '9') ||\n (c >= 'A' && c <= 'Z') ||\n (c >= 'a' && c <= 'z')\n ) {\n kept += 1;\n }\n }\n return kept;\n}\n\nexport const FiscalCodeInput = forwardRef<\n HTMLInputElement,\n FiscalCodeInputProps\n>(function FiscalCodeInput(\n {\n value,\n defaultValue,\n onChange,\n size = 'md',\n tone = 'default',\n validateOn = 'blur',\n showError,\n errorMessage,\n disabled,\n readOnly,\n required,\n placeholder,\n showFormatHint = true,\n calculateFrom,\n id,\n name,\n className,\n 'aria-label': ariaLabel,\n },\n ref,\n) {\n const { t } = useTranslation();\n const ctx = useFormField();\n const inFormField = useContext(FormFieldContext) !== null;\n\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string>(() =>\n normaliseFiscalCode(defaultValue ?? ''),\n );\n const currentValue = isControlled\n ? normaliseFiscalCode(value ?? '')\n : internalValue;\n\n const [blurred, setBlurred] = useState(false);\n const composingRef = useRef(false);\n const pendingCaretRef = useRef<number | null>(null);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const composedRef = composeRefs(ref, inputRef);\n\n const reactId = useId();\n const generatedHintId = `${reactId}-hint`;\n const generatedStatusId = `${reactId}-status`;\n const generatedErrorId = `${reactId}-error`;\n\n // DEV-time guard: a standalone field with no visible label needs an\n // aria-label, mirroring Button's icon-only guard. No-op in production.\n useEffect(() => {\n const isDev =\n typeof import.meta !== 'undefined' &&\n typeof import.meta.env !== 'undefined' &&\n import.meta.env.DEV === true;\n if (isDev && !inFormField && !ariaLabel) {\n // eslint-disable-next-line no-console\n console.warn(\n '[FiscalCodeInput] No FormField/label and no `aria-label` — the field has no accessible name. Wrap it in a FormField or pass `aria-label`.',\n );\n }\n }, [inFormField, ariaLabel]);\n\n const reason = useMemo(\n () => classifyCodiceFiscale(currentValue),\n [currentValue],\n );\n const isComplete = currentValue.length === MAX_LEN;\n const isValid = reason === 'valid';\n\n const effectiveDisabled =\n (inFormField ? ctx.disabled : false) || Boolean(disabled);\n const effectiveRequired =\n (inFormField ? ctx.required : false) || Boolean(required);\n\n // Whether the component's OWN feedback should surface.\n //\n // `showError` is a controlled escape hatch (e.g. the server rejected the\n // code on submit): it forces the error regardless of completeness or the\n // client's own verdict. Otherwise the client only flags a COMPLETE\n // (16-char) code that fails its structural/checksum check — never a\n // partially-typed code — and `validateOn` governs the trigger.\n const ownFeedbackActive =\n !readOnly &&\n (Boolean(showError) ||\n (isComplete &&\n !isValid &&\n (validateOn === 'change' || (validateOn === 'blur' && blurred))));\n\n // When inside a FormField with its own error, FormField's role=alert wins\n // and this component stays silent (no double message / duplicate\n // aria-describedby target).\n const formFieldHasError = inFormField && ctx.invalid;\n const showOwnError = ownFeedbackActive && !formFieldHasError;\n\n const effectiveInvalid = formFieldHasError || showOwnError;\n const effectiveTone: 'default' | 'error' =\n effectiveInvalid || tone === 'error' ? 'error' : 'default';\n\n const ownErrorText = useMemo(() => {\n if (errorMessage) return errorMessage;\n if (reason === 'badChecksum') return t('inputs.fiscalCode.errorChecksum');\n if (reason === 'badFormat') return t('inputs.fiscalCode.errorFormat');\n return t('inputs.fiscalCode.errorIncomplete');\n }, [errorMessage, reason, t]);\n\n // Standalone (no FormField) describedby: format hint + the live region that\n // is currently surfacing. When the component is showing its OWN error we\n // point at the assertive error node; otherwise at the polite status node\n // (valid affordance / typing progress). Inside a FormField, the FormField\n // owns describedBy entirely.\n const wantsHint = !inFormField && showFormatHint && !readOnly;\n const standaloneDescribedBy = inFormField\n ? undefined\n : [\n wantsHint ? generatedHintId : null,\n showOwnError ? generatedErrorId : generatedStatusId,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n const describedBy = inFormField\n ? ctx.describedBy || undefined\n : standaloneDescribedBy;\n\n const inputId = id ?? ctx.id;\n\n const emit = useCallback(\n (next: string) => {\n const nextReason = classifyCodiceFiscale(next);\n onChange?.(next, {\n isValid: nextReason === 'valid',\n isComplete: next.length === MAX_LEN,\n reason: nextReason,\n });\n },\n [onChange],\n );\n\n const commit = useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next);\n emit(next);\n },\n [isControlled, emit],\n );\n\n // Restore caret after a normalising re-render that may have changed the\n // string length (mid-string edit / paste). Mirrors phone-input's caret\n // discipline.\n useIsomorphicLayoutEffect(() => {\n if (pendingCaretRef.current == null) return;\n const pos = pendingCaretRef.current;\n pendingCaretRef.current = null;\n const node = inputRef.current;\n if (node && document.activeElement === node) {\n // Re-clamp against the value the input ACTUALLY rendered this pass, not\n // the value we committed: a controlled parent may transform or reject\n // the emitted change so the echoed value diverges. Clamping to the live\n // DOM length keeps the caret inside the rendered string.\n const safePos = Math.min(pos, node.value.length);\n node.setSelectionRange(safePos, safePos);\n }\n });\n\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (readOnly) return;\n // Don't re-mask mid-IME composition or the user loses input; the\n // uppercase mask is re-applied on composition end / next change.\n if (composingRef.current) return;\n const target = event.target;\n const raw = target.value;\n const caret = target.selectionStart ?? raw.length;\n const keptBefore = countKeptBefore(raw, caret);\n const next = normaliseFiscalCode(raw);\n pendingCaretRef.current = Math.min(keptBefore, next.length);\n commit(next);\n };\n\n const handleCompositionStart = () => {\n composingRef.current = true;\n };\n\n const handleCompositionEnd = (event: CompositionEvent<HTMLInputElement>) => {\n composingRef.current = false;\n if (readOnly) return;\n const next = normaliseFiscalCode(event.currentTarget.value);\n pendingCaretRef.current = next.length;\n commit(next);\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLInputElement>) => {\n if (readOnly) return;\n const text = event.clipboardData.getData('text');\n event.preventDefault();\n const node = inputRef.current;\n const selStart = node?.selectionStart ?? currentValue.length;\n const selEnd = node?.selectionEnd ?? currentValue.length;\n const cleaned = normaliseFiscalCode(text);\n const before = currentValue.slice(0, selStart);\n const after = currentValue.slice(selEnd);\n const next = normaliseFiscalCode(before + cleaned + after);\n pendingCaretRef.current = Math.min((before + cleaned).length, next.length);\n commit(next);\n };\n\n const handleBlur = () => {\n if (validateOn === 'blur') setBlurred(true);\n };\n\n // Opt-in derivation. Compute the CF from the supplied identity data and\n // route it through the SAME commit path as typing/paste so the controlled\n // / uncontrolled contract, the validation verdict, and the live-region\n // announcement all behave identically to a user-entered value.\n const handleCalculate = () => {\n if (!calculateFrom || readOnly || effectiveDisabled) return;\n let computed: string;\n try {\n computed = calculateCodiceFiscale(calculateFrom);\n } catch {\n // Bad identity data (unparseable date / malformed Belfiore code) is a\n // caller error, not a user action — fail quietly rather than throwing\n // out of an event handler and leave the field untouched.\n return;\n }\n const next = normaliseFiscalCode(computed);\n // After a successful derivation the value is complete: let blur-gated\n // validation surface immediately (the derived code is valid by\n // construction, so this confirms rather than errors).\n if (validateOn === 'blur') setBlurred(true);\n commit(next);\n inputRef.current?.focus();\n };\n\n const agentHandle = useMemo<FiscalCodeInputHandle>(\n () => ({\n getValue: () => currentValue,\n setValue: (next) => {\n const normalised = normaliseFiscalCode(next);\n if (!isControlled) setInternalValue(normalised);\n emit(normalised);\n inputRef.current?.focus();\n },\n clear: () => {\n if (!isControlled) setInternalValue('');\n emit('');\n inputRef.current?.focus();\n },\n focus: () => inputRef.current?.focus(),\n isValid: () => classifyCodiceFiscale(currentValue) === 'valid',\n }),\n [currentValue, isControlled, emit],\n );\n useAgentRegistration(fiscalCodeInputAgent, agentHandle, id);\n\n const resolvedPlaceholder = placeholder ?? t('inputs.fiscalCode.placeholder');\n\n // Polite status text (role=status). Carries ONLY non-error affordances:\n // the valid confirmation and, while typing an incomplete code, the live\n // character-count progress. Errors the user must act on are announced\n // assertively via the separate role=alert node below — never here.\n // Gated on !inFormField (matching showEndIcon): inside a FormField the\n // FormField owns every helper/status/error slot, so this stays silent.\n const statusMessage =\n readOnly || inFormField\n ? ''\n : isValid\n ? t('inputs.fiscalCode.valid')\n : currentValue.length > 0 && !isComplete\n ? t('inputs.fiscalCode.charactersEntered', {\n count: currentValue.length,\n })\n : '';\n\n // Assertive error text (role=alert) — surfaces only the component's own\n // actionable validation error, mirroring FormField's error <p>.\n const errorText = showOwnError ? ownErrorText : '';\n\n const showEndIcon = !readOnly && (showOwnError || (isValid && !inFormField));\n\n // Opt-in calculate affordance: only when identity data is supplied AND the\n // field is editable. Disabled/read-only fields render nothing extra.\n const showCalculate =\n Boolean(calculateFrom) && !readOnly && !effectiveDisabled;\n\n return (\n <div\n className=\"ds:flex ds:flex-col\"\n data-component=\"fiscal-code-input\"\n data-component-id={id}\n >\n <div\n data-slot=\"fiscal-code-input\"\n className={wrapperVariants({ size, tone: effectiveTone, className })}\n >\n {showCalculate ? (\n <span className={adornmentStart}>\n <IconButton\n type=\"button\"\n size=\"sm\"\n intent=\"ghost\"\n icon={<Calculator />}\n aria-label={t('inputs.fiscalCode.calculate')}\n onClick={handleCalculate}\n />\n </span>\n ) : null}\n <input\n ref={composedRef}\n id={inputId}\n name={name}\n // dir=\"ltr\": the codice fiscale glyphs render LTR even under an\n // RTL surrounding UI — a value-rendering concern, not a layout\n // direction violation (see inputVariants comment).\n dir=\"ltr\"\n type=\"text\"\n inputMode=\"text\"\n autoCapitalize=\"characters\"\n autoCorrect=\"off\"\n autoComplete=\"off\"\n spellCheck={false}\n maxLength={MAX_LEN}\n // Loose structural mirror: 15 [A-Z0-9] + a final letter control\n // char (value is always uppercased). The real position-class /\n // checksum rule is enforced in classifyCodiceFiscale; this native\n // pattern is only a non-JS fallback.\n pattern=\"[A-Z0-9]{15}[A-Z]\"\n value={currentValue}\n placeholder={resolvedPlaceholder}\n disabled={effectiveDisabled}\n readOnly={readOnly}\n aria-label={ariaLabel}\n aria-describedby={describedBy}\n aria-invalid={effectiveInvalid || undefined}\n aria-required={effectiveRequired || undefined}\n onChange={handleChange}\n onCompositionStart={handleCompositionStart}\n onCompositionEnd={handleCompositionEnd}\n onPaste={handlePaste}\n onBlur={handleBlur}\n className={inputVariants({\n size,\n hasStart: showCalculate,\n hasEnd: showEndIcon,\n })}\n />\n {showEndIcon ? (\n <span\n aria-hidden=\"true\"\n className={`${adornmentEnd} ${\n showOwnError ? 'ds:text-destructive' : 'ds:text-success'\n }`}\n >\n {showOwnError ? <AlertCircle /> : <CheckCircle2 />}\n </span>\n ) : null}\n </div>\n\n {wantsHint ? (\n <p\n id={generatedHintId}\n className={`${captionBase} ds:text-muted-foreground`}\n >\n {t('inputs.fiscalCode.formatHint')}\n </p>\n ) : null}\n\n {/* Polite live region (role=status): announces the valid affordance\n and the typing-progress count as TEXT, satisfying 1.4.1 (never\n colour-only). Never carries an actionable error — that goes to the\n assertive node below, mirroring the kit's input-error convention. */}\n <p\n id={generatedStatusId}\n role=\"status\"\n aria-live=\"polite\"\n className={`${captionBase} ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] ${\n isValid ? 'ds:text-success' : 'ds:text-muted-foreground'\n } ${statusMessage ? '' : 'ds:sr-only'}`}\n >\n {statusMessage ? (\n <>\n {isValid ? (\n <CheckCircle2\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0\"\n />\n ) : null}\n <span>{statusMessage}</span>\n </>\n ) : null}\n </p>\n\n {/* Assertive error region (role=alert): a validation error the user\n must correct is announced assertively, mirroring FormField's error\n <p> (form-field.tsx). Rendered only when the component owns the\n error — inside a FormField, FormField's role=alert wins. */}\n {errorText ? (\n <p\n id={generatedErrorId}\n role=\"alert\"\n className={`${captionBase} ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-destructive`}\n >\n <AlertCircle aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0\" />\n <span>{errorText}</span>\n </p>\n ) : null}\n </div>\n );\n});\n\nFiscalCodeInput.displayName = 'FiscalCodeInput';\n\nexport { wrapperVariants as fiscalCodeWrapperVariants };\n"],"names":["__iconNode","Calculator","createLucideIcon","fiscalCodeInputAgent","handle","args","LETTER_POSITIONS","DIGIT_POSITIONS","ODD_MAP","EVEN_MAP","REMAINDER_TO_CONTROL","hasValidStructure","code","i","ch","isDigit","computeControlChar","first15","sum","classifyCodiceFiscale","raw","isValidCodiceFiscale","VOWELS","MONTH_LETTERS","foldToLetters","input","consonantsOf","letters","c","vowelsOf","surnameCode","surname","nameCode","name","cons","toDate","birthDate","d","pad2","n","birthCode","sex","yy","monthLetter","day","calculateCodiceFiscale","belfioreCode","belfiore","MAX_LEN","wrapperVariants","cva","INPUT_SURFACE_CHROME","INPUT_SURFACE_HEIGHT","INPUT_SURFACE_TONE","inputVariants","INPUT_SURFACE_TEXT","adornmentEnd","adornmentStart","captionBase","normaliseFiscalCode","countKeptBefore","str","position","kept","FiscalCodeInput","forwardRef","value","defaultValue","onChange","size","tone","validateOn","showError","errorMessage","disabled","readOnly","required","placeholder","showFormatHint","calculateFrom","id","className","ariaLabel","ref","t","useTranslation","ctx","useFormField","inFormField","useContext","FormFieldContext","isControlled","internalValue","setInternalValue","useState","currentValue","blurred","setBlurred","composingRef","useRef","pendingCaretRef","inputRef","composedRef","composeRefs","reactId","useId","generatedHintId","generatedStatusId","generatedErrorId","useEffect","reason","useMemo","isComplete","isValid","effectiveDisabled","effectiveRequired","ownFeedbackActive","formFieldHasError","showOwnError","effectiveInvalid","effectiveTone","ownErrorText","wantsHint","standaloneDescribedBy","describedBy","inputId","emit","useCallback","next","nextReason","commit","useIsomorphicLayoutEffect","pos","node","safePos","handleChange","event","target","caret","keptBefore","handleCompositionStart","handleCompositionEnd","handlePaste","text","selStart","selEnd","cleaned","before","after","handleBlur","handleCalculate","computed","_a","agentHandle","normalised","useAgentRegistration","resolvedPlaceholder","statusMessage","errorText","showEndIcon","showCalculate","jsxs","jsx","IconButton","AlertCircle","CheckCircle2","Fragment"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,318 +0,0 @@
1
- import { jsx as e, jsxs as n } from "react/jsx-runtime";
2
- import { forwardRef as Z, useRef as b, useState as T, useEffect as ee } from "react";
3
- import { useTranslation as se } from "react-i18next";
4
- import { D as d } from "./dialog-UbKJCi1X.js";
5
- import { B as f } from "./button-CPGiR_bH.js";
6
- import { I as ae } from "./icon-button-C_kbcd7I.js";
7
- import { C as te } from "./checkbox-BuZ1u__2.js";
8
- import { a as re } from "./whatsapp-button-BIy6NaJK.js";
9
- import { S as B } from "./select-BW5ecXlX.js";
10
- import { S as ne } from "./switch-OILsBLWo.js";
11
- import { A as p } from "./alert-KJbsPYkI.js";
12
- import { S as ie } from "./separator-CYU_bGFn.js";
13
- import { A as j } from "./avatar-BNQNhoyL.js";
14
- import { c as S } from "./createLucideIcon-DhHxpK9K.js";
15
- import { M as le } from "./mail-BqXVF2zH.js";
16
- import { P as de } from "./plus-DzMQ_c6b.js";
17
- import { X as ce } from "./x-B5YnXwCz.js";
18
- import { P as oe } from "./pen-line-D0De5zdl.js";
19
- /**
20
- * @license lucide-react v1.22.0 - ISC
21
- *
22
- * This source code is licensed under the ISC license.
23
- * See the LICENSE file in the root directory of this source tree.
24
- */
25
- const ue = [
26
- [
27
- "path",
28
- {
29
- d: "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",
30
- key: "18887p"
31
- }
32
- ],
33
- ["path", { d: "M7 11h10", key: "1twpyw" }],
34
- ["path", { d: "M7 15h6", key: "d9of3u" }],
35
- ["path", { d: "M7 7h8", key: "af5zfr" }]
36
- ], me = S("message-square-text", ue);
37
- /**
38
- * @license lucide-react v1.22.0 - ISC
39
- *
40
- * This source code is licensed under the ISC license.
41
- * See the LICENSE file in the root directory of this source tree.
42
- */
43
- const pe = [
44
- ["rect", { width: "16", height: "20", x: "4", y: "2", rx: "2", ry: "2", key: "76otgf" }],
45
- ["line", { x1: "12", x2: "12.01", y1: "18", y2: "18", key: "1dp563" }]
46
- ], he = S("tablet", pe);
47
- /**
48
- * @license lucide-react v1.22.0 - ISC
49
- *
50
- * This source code is licensed under the ISC license.
51
- * See the LICENSE file in the root directory of this source tree.
52
- */
53
- const ge = [
54
- ["path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2", key: "1yyitq" }],
55
- ["circle", { cx: "9", cy: "7", r: "4", key: "nufk8" }],
56
- ["line", { x1: "19", x2: "19", y1: "8", y2: "14", key: "1bvyxn" }],
57
- ["line", { x1: "22", x2: "16", y1: "11", y2: "11", key: "1shjgl" }]
58
- ], ve = S("user-plus", ge), h = "__assign-later__";
59
- function H(c, x) {
60
- var l;
61
- return ((l = c.find((o) => o.value === x)) == null ? void 0 : l.label) ?? "";
62
- }
63
- const fe = Z(
64
- ({
65
- open: c,
66
- onOpenChange: x,
67
- operators: l,
68
- signerOptions: o,
69
- currentOperatorId: k,
70
- allowAssignLater: q = !0,
71
- initialOperatorId: C,
72
- initialSigners: R,
73
- maxSigners: L = 2,
74
- busy: i = !1,
75
- error: z,
76
- title: V,
77
- description: E,
78
- onRequestSignature: F,
79
- contentProps: W
80
- }, G) => {
81
- const { t: a } = se(), _ = b(0), M = b(null), P = () => {
82
- var s, r;
83
- return C === null ? q ? h : ((s = l[0]) == null ? void 0 : s.value) ?? h : C ?? ((r = l[0]) == null ? void 0 : r.value) ?? (q ? h : "");
84
- }, A = () => (R && R.length > 0 ? R : o.length > 0 ? [
85
- {
86
- signerId: o[0].value,
87
- channel: "on-device"
88
- }
89
- ] : []).map((r) => ({ ...r, rowId: _.current++ })), [g, w] = T(P), [u, v] = T(A), D = b(c);
90
- ee(() => {
91
- c && !D.current && (w(P()), v(A())), D.current = c;
92
- }, [c]);
93
- const U = q ? [
94
- ...l,
95
- { value: h, label: a("signatureRequest.assignLater") }
96
- ] : l, y = g === h, $ = [
97
- {
98
- value: "sms",
99
- label: a("signatureRequest.viaSms"),
100
- icon: /* @__PURE__ */ e(me, { className: "ds:size-4", "aria-hidden": !0 })
101
- },
102
- {
103
- value: "email",
104
- label: a("signatureRequest.viaEmail"),
105
- icon: /* @__PURE__ */ e(le, { className: "ds:size-4", "aria-hidden": !0 })
106
- },
107
- {
108
- value: "whatsapp",
109
- label: a("signatureRequest.viaWhatsapp"),
110
- icon: /* @__PURE__ */ e(re, { className: "ds:size-4", "aria-hidden": !0 })
111
- },
112
- {
113
- value: "on-device",
114
- label: a("signatureRequest.onThisDevice"),
115
- icon: /* @__PURE__ */ e(he, { className: "ds:size-4", "aria-hidden": !0 })
116
- }
117
- ], O = u.map((s) => s.signerId), I = o.find(
118
- (s) => !O.includes(s.value)
119
- ), X = !i && u.length < L && I !== void 0, N = (s, r) => {
120
- v(
121
- (m) => m.map(
122
- (t) => t.rowId === s ? { ...t, ...r } : t
123
- )
124
- );
125
- }, J = () => {
126
- I && v((s) => [
127
- ...s,
128
- {
129
- signerId: I.value,
130
- channel: "sms",
131
- rowId: _.current++
132
- }
133
- ]);
134
- }, K = (s) => {
135
- var r;
136
- (r = M.current) == null || r.focus(), v(
137
- (m) => m.filter((t) => t.rowId !== s)
138
- );
139
- }, Q = () => {
140
- F({
141
- operatorId: y ? null : g,
142
- signers: u.map(({ rowId: s, ...r }) => r)
143
- });
144
- };
145
- return /* @__PURE__ */ e("div", { ref: G, className: "ds:contents", "data-component": "signature-request", children: /* @__PURE__ */ e(d, { open: c, onOpenChange: x, children: /* @__PURE__ */ n(d.Content, { size: "lg", hideCloseButton: !0, ...W, children: [
146
- /* @__PURE__ */ n(d.Header, { children: [
147
- /* @__PURE__ */ e(d.Title, { children: V ?? a("signatureRequest.title") }),
148
- /* @__PURE__ */ e(d.Description, { children: E ?? a("signatureRequest.noSignedVersions") })
149
- ] }),
150
- /* @__PURE__ */ n(d.Body, { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]", children: [
151
- /* @__PURE__ */ n("section", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]", children: [
152
- /* @__PURE__ */ n("div", { className: "ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]", children: [
153
- /* @__PURE__ */ e("p", { className: "type-eyebrow ds:text-start ds:text-[color:var(--muted-foreground)]", children: a("signatureRequest.operatorSection") }),
154
- k !== void 0 ? /* @__PURE__ */ e(
155
- f,
156
- {
157
- intent: "primary",
158
- size: "sm",
159
- startIcon: /* @__PURE__ */ e(ve, {}),
160
- disabled: i,
161
- onClick: () => w(k),
162
- children: a("signatureRequest.assignToMe")
163
- }
164
- ) : null
165
- ] }),
166
- /* @__PURE__ */ n("div", { className: "ds:flex ds:items-center ds:gap-[var(--spacing-sm)]", children: [
167
- /* @__PURE__ */ e(
168
- j,
169
- {
170
- "aria-hidden": "true",
171
- name: y ? void 0 : H(l, g),
172
- size: "sm"
173
- }
174
- ),
175
- /* @__PURE__ */ e("div", { className: "ds:min-w-0 ds:flex-1 ds:text-start", children: /* @__PURE__ */ e(
176
- B,
177
- {
178
- options: U,
179
- value: g,
180
- onValueChange: (s) => s && w(s),
181
- required: !0,
182
- disabled: i,
183
- placeholder: a("signatureRequest.operatorPlaceholder"),
184
- "aria-label": a("signatureRequest.operatorSection")
185
- }
186
- ) })
187
- ] }),
188
- y ? null : /* @__PURE__ */ e(p, { variant: "info", children: /* @__PURE__ */ e(p.Description, { children: a("signatureRequest.operatorHint") }) })
189
- ] }),
190
- /* @__PURE__ */ e(ie, { decorative: !0 }),
191
- /* @__PURE__ */ n("section", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:text-start", children: [
192
- /* @__PURE__ */ n("div", { className: "ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]", children: [
193
- /* @__PURE__ */ e("p", { className: "type-eyebrow ds:text-[color:var(--muted-foreground)]", children: a("signatureRequest.signersSection") }),
194
- /* @__PURE__ */ e(
195
- f,
196
- {
197
- ref: M,
198
- intent: "primary",
199
- size: "sm",
200
- startIcon: /* @__PURE__ */ e(de, {}),
201
- disabled: !X,
202
- onClick: J,
203
- children: a("signatureRequest.addSigner")
204
- }
205
- )
206
- ] }),
207
- u.map((s) => {
208
- const r = o.filter(
209
- (t) => t.value === s.signerId || !O.includes(t.value)
210
- ), m = H(o, s.signerId);
211
- return /* @__PURE__ */ n(
212
- "div",
213
- {
214
- role: "group",
215
- "aria-label": m,
216
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]",
217
- children: [
218
- /* @__PURE__ */ n("div", { className: "ds:flex ds:items-center ds:gap-[var(--spacing-sm)]", children: [
219
- /* @__PURE__ */ e(j, { "aria-hidden": "true", name: m, size: "sm" }),
220
- /* @__PURE__ */ e("div", { className: "ds:min-w-0 ds:flex-1", children: /* @__PURE__ */ e(
221
- B,
222
- {
223
- options: r,
224
- value: s.signerId,
225
- onValueChange: (t) => t && N(s.rowId, { signerId: t }),
226
- required: !0,
227
- disabled: i,
228
- placeholder: a(
229
- "signatureRequest.signerPlaceholder"
230
- ),
231
- "aria-label": a("signatureRequest.signerPlaceholder")
232
- }
233
- ) }),
234
- u.length > 1 ? /* @__PURE__ */ e(
235
- ae,
236
- {
237
- intent: "ghost",
238
- size: "sm",
239
- icon: /* @__PURE__ */ e(ce, {}),
240
- disabled: i,
241
- "aria-label": a("signatureRequest.removeSigner"),
242
- onClick: () => K(s.rowId)
243
- }
244
- ) : null
245
- ] }),
246
- /* @__PURE__ */ e(
247
- "div",
248
- {
249
- role: "group",
250
- "aria-label": a("signatureRequest.channelLabel"),
251
- className: "ds:flex ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-lg)] ds:gap-y-[var(--spacing-sm)] ds:ps-[var(--spacing-xl)]",
252
- children: $.map((t) => /* @__PURE__ */ e(
253
- te,
254
- {
255
- checked: s.channel === t.value,
256
- disabled: i,
257
- onCheckedChange: (Y) => Y === !0 && N(s.rowId, {
258
- channel: t.value,
259
- skipOtp: void 0
260
- }),
261
- label: /* @__PURE__ */ n("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]", children: [
262
- /* @__PURE__ */ e(
263
- "span",
264
- {
265
- "aria-hidden": "true",
266
- className: "ds:text-[var(--accent)]",
267
- children: t.icon
268
- }
269
- ),
270
- t.label
271
- ] })
272
- },
273
- t.value
274
- ))
275
- }
276
- ),
277
- s.channel === "on-device" ? /* @__PURE__ */ e("div", { className: "ds:ps-[var(--spacing-xl)]", children: /* @__PURE__ */ e(
278
- ne,
279
- {
280
- label: a("signatureRequest.noOtp"),
281
- checked: s.skipOtp === !0,
282
- disabled: i,
283
- onCheckedChange: (t) => N(s.rowId, { skipOtp: t })
284
- }
285
- ) }) : null
286
- ]
287
- },
288
- s.rowId
289
- );
290
- })
291
- ] }),
292
- u.some(
293
- (s) => s.channel === "on-device" && s.skipOtp === !0
294
- ) ? /* @__PURE__ */ e(p, { variant: "warning", children: /* @__PURE__ */ e(p.Description, { children: a("signatureRequest.noOtpWarning") }) }) : null,
295
- z ? /* @__PURE__ */ e(p, { variant: "error", children: /* @__PURE__ */ e(p.Description, { children: z }) }) : null
296
- ] }),
297
- /* @__PURE__ */ n(d.Footer, { children: [
298
- /* @__PURE__ */ e(
299
- f,
300
- {
301
- intent: "primary",
302
- startIcon: /* @__PURE__ */ e(oe, {}),
303
- onClick: Q,
304
- disabled: i || u.length === 0,
305
- loading: i,
306
- children: a("signatureRequest.requestSignature")
307
- }
308
- ),
309
- /* @__PURE__ */ e(d.Close, { asChild: !0, children: /* @__PURE__ */ e(f, { intent: "outline", disabled: i, children: a("signatureRequest.close") }) })
310
- ] })
311
- ] }) }) });
312
- }
313
- );
314
- fe.displayName = "SignatureRequestModal";
315
- export {
316
- fe as S
317
- };
318
- //# sourceMappingURL=signature-request-C-mskXwi.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"signature-request-C-mskXwi.js","sources":["../../node_modules/lucide-react/dist/esm/icons/message-square-text.mjs","../../node_modules/lucide-react/dist/esm/icons/tablet.mjs","../../node_modules/lucide-react/dist/esm/icons/user-plus.mjs","../../src/patterns/signature-request/signature-request.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 [\n \"path\",\n {\n d: \"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z\",\n key: \"18887p\"\n }\n ],\n [\"path\", { d: \"M7 11h10\", key: \"1twpyw\" }],\n [\"path\", { d: \"M7 15h6\", key: \"d9of3u\" }],\n [\"path\", { d: \"M7 7h8\", key: \"af5zfr\" }]\n];\nconst MessageSquareText = createLucideIcon(\"message-square-text\", __iconNode);\n\nexport { __iconNode, MessageSquareText as default };\n//# sourceMappingURL=message-square-text.mjs.map\n","/**\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 [\"rect\", { width: \"16\", height: \"20\", x: \"4\", y: \"2\", rx: \"2\", ry: \"2\", key: \"76otgf\" }],\n [\"line\", { x1: \"12\", x2: \"12.01\", y1: \"18\", y2: \"18\", key: \"1dp563\" }]\n];\nconst Tablet = createLucideIcon(\"tablet\", __iconNode);\n\nexport { __iconNode, Tablet as default };\n//# sourceMappingURL=tablet.mjs.map\n","/**\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: \"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\", key: \"1yyitq\" }],\n [\"circle\", { cx: \"9\", cy: \"7\", r: \"4\", key: \"nufk8\" }],\n [\"line\", { x1: \"19\", x2: \"19\", y1: \"8\", y2: \"14\", key: \"1bvyxn\" }],\n [\"line\", { x1: \"22\", x2: \"16\", y1: \"11\", y2: \"11\", key: \"1shjgl\" }]\n];\nconst UserPlus = createLucideIcon(\"user-plus\", __iconNode);\n\nexport { __iconNode, UserPlus as default };\n//# sourceMappingURL=user-plus.mjs.map\n","/**\n * SignatureRequestModal — the practice-side \"Documenti firmati\" modal that\n * dispatches a document-signature request: assign the operator who must\n * counter-sign (or leave the request unassigned), build the patient-side\n * signer roster (up to `maxSigners`, each with their own delivery channel\n * and, for on-device signing, an OTP waiver), and send.\n *\n * Runtime pattern: real consuming apps mount this in production (surfaced via\n * `src/patterns/index.ts` and the `./patterns/signature-request` subpath).\n * The component owns the form state — re-seeded from the `initial*` props\n * every time `open` flips back to `true` — while the host owns `open`, the\n * option lists, and what happens on submit. Multiple on-device signers sign\n * sequentially in roster order — the execution side is the Signing pattern's\n * multi-signer flow; this modal only encodes the intents.\n */\nimport {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Mail,\n MessageSquareText,\n PenLine,\n Plus,\n Tablet,\n UserPlus,\n X,\n} from 'lucide-react';\nimport { Dialog } from '../../components/dialog';\nimport { Button } from '../../components/button';\nimport { IconButton } from '../../components/icon-button';\nimport { Checkbox } from '../../components/checkbox';\nimport { WhatsAppGlyph } from '../../components/whatsapp-button';\nimport { Select } from '../../components/select';\nimport { Switch } from '../../components/switch';\nimport { Alert } from '../../components/alert';\nimport { Separator } from '../../components/separator';\nimport { Avatar } from '../../components/avatar';\n\n/** Delivery channel for one signer's signature request. */\nexport type SignatureChannel = 'sms' | 'email' | 'whatsapp' | 'on-device';\n\n/** One selectable person/role for the operator or signer selects. */\nexport interface SignerOption {\n value: string;\n label: string;\n}\n\n/** One patient-side signer row in the submission. */\nexport interface SignerRequest {\n signerId: string;\n channel: SignatureChannel;\n /** Only meaningful when `channel` is `'on-device'`. */\n skipOtp?: boolean;\n}\n\n/** Payload handed to `onRequestSignature`. */\nexport interface SignatureRequestSubmission {\n /** `null` when the counter-signing operator is left unassigned. */\n operatorId: string | null;\n /** 1..N signers; on-device signers sign sequentially in this order. */\n signers: SignerRequest[];\n}\n\nexport interface SignatureRequestModalProps {\n /** Controlled open state. Reopening re-seeds the form from `initial*`. */\n open: boolean;\n /**\n * Fires when the dialog requests a state change (<kbd>Esc</kbd> or the\n * footer Close button). `false` is the dismiss signal — hosts typically\n * persist a \"dismissed this session\" flag there.\n */\n onOpenChange: (open: boolean) => void;\n /** Operators offered as the counter-signing signer. */\n operators: SignerOption[];\n /** Patient-side people/roles offered in each signer row. */\n signerOptions: SignerOption[];\n /** Enables the \"Assign to me\" shortcut targeting this operator. */\n currentOperatorId?: string;\n /** Offer an \"Assign later\" option in the operator select. Default `true`. */\n allowAssignLater?: boolean;\n /**\n * Preselected operator; `null` preselects \"Assign later\" (honoured only\n * while `allowAssignLater` — otherwise the first operator is seeded).\n */\n initialOperatorId?: string | null;\n /** Seed the signer roster. Defaults to the first option, on-device. */\n initialSigners?: SignerRequest[];\n /** Cap on roster size. Default `2`. */\n maxSigners?: number;\n /** Disables all inputs and shows the primary action as loading. */\n busy?: boolean;\n /** Consumer-translated error shown above the footer (e.g. server failure). */\n error?: string;\n /** Override the dialog title. Defaults to the `ui.*` string. */\n title?: string;\n /** Override the dialog description. Defaults to the `ui.*` string. */\n description?: string;\n /** Receives the completed submission. The host closes via `onOpenChange`. */\n onRequestSignature: (submission: SignatureRequestSubmission) => void;\n /**\n * Extra attributes for the portaled dialog surface (e.g. `dir`/`lang`\n * when the host pins a locale below `<html>`, or a test id).\n */\n contentProps?: ComponentPropsWithoutRef<'div'>;\n}\n\nconst ASSIGN_LATER = '__assign-later__';\n\n/** Internal roster row — `rowId` keys the DOM so editing a row's person\n * never remounts the row (which would drop keyboard focus). */\ninterface RosterRow extends SignerRequest {\n rowId: number;\n}\n\nfunction labelFor(options: SignerOption[], value: string): string {\n return options.find((option) => option.value === value)?.label ?? '';\n}\n\nexport const SignatureRequestModal = forwardRef<\n HTMLDivElement,\n SignatureRequestModalProps\n>(\n (\n {\n open,\n onOpenChange,\n operators,\n signerOptions,\n currentOperatorId,\n allowAssignLater = true,\n initialOperatorId,\n initialSigners,\n maxSigners = 2,\n busy = false,\n error,\n title,\n description,\n onRequestSignature,\n contentProps,\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const nextRowId = useRef(0);\n const addButtonRef = useRef<HTMLButtonElement>(null);\n\n const seedOperator = () => {\n if (initialOperatorId === null) {\n return allowAssignLater\n ? ASSIGN_LATER\n : (operators[0]?.value ?? ASSIGN_LATER);\n }\n return (\n initialOperatorId ??\n operators[0]?.value ??\n (allowAssignLater ? ASSIGN_LATER : '')\n );\n };\n const seedRows = (): RosterRow[] => {\n const seed =\n initialSigners && initialSigners.length > 0\n ? initialSigners\n : signerOptions.length > 0\n ? [\n {\n signerId: signerOptions[0].value,\n channel: 'on-device' as const,\n },\n ]\n : [];\n return seed.map((signer) => ({ ...signer, rowId: nextRowId.current++ }));\n };\n\n const [operator, setOperator] = useState<string>(seedOperator);\n const [signers, setSigners] = useState<RosterRow[]>(seedRows);\n\n // Re-seed the form whenever the host reopens the (still-mounted) modal,\n // so a previous request's choices never leak into the next one.\n const wasOpen = useRef(open);\n useEffect(() => {\n if (open && !wasOpen.current) {\n setOperator(seedOperator());\n setSigners(seedRows());\n }\n wasOpen.current = open;\n // The seeds intentionally read the render-time props on the rising\n // edge only — prop changes while open (or closed) don't reset input.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n const operatorSelectOptions = allowAssignLater\n ? [\n ...operators,\n { value: ASSIGN_LATER, label: t('signatureRequest.assignLater') },\n ]\n : operators;\n const isUnassigned = operator === ASSIGN_LATER;\n\n const channelOptions: {\n value: SignatureChannel;\n label: string;\n icon: React.ReactNode;\n }[] = [\n {\n value: 'sms',\n label: t('signatureRequest.viaSms'),\n icon: <MessageSquareText className=\"ds:size-4\" aria-hidden />,\n },\n {\n value: 'email',\n label: t('signatureRequest.viaEmail'),\n icon: <Mail className=\"ds:size-4\" aria-hidden />,\n },\n {\n value: 'whatsapp',\n label: t('signatureRequest.viaWhatsapp'),\n icon: <WhatsAppGlyph className=\"ds:size-4\" aria-hidden />,\n },\n {\n value: 'on-device',\n label: t('signatureRequest.onThisDevice'),\n icon: <Tablet className=\"ds:size-4\" aria-hidden />,\n },\n ];\n\n const chosenIds = signers.map((signer) => signer.signerId);\n const nextFreeOption = signerOptions.find(\n (option) => !chosenIds.includes(option.value),\n );\n const canAddSigner =\n !busy && signers.length < maxSigners && nextFreeOption !== undefined;\n\n const patchSigner = (rowId: number, patch: Partial<SignerRequest>) => {\n setSigners((current) =>\n current.map((signer) =>\n signer.rowId === rowId ? { ...signer, ...patch } : signer,\n ),\n );\n };\n\n const addSigner = () => {\n if (!nextFreeOption) return;\n setSigners((current) => [\n ...current,\n {\n signerId: nextFreeOption.value,\n channel: 'sms',\n rowId: nextRowId.current++,\n },\n ]);\n };\n\n const removeSigner = (rowId: number) => {\n // Move focus BEFORE the row (and the focused remove button) unmounts —\n // otherwise Radix's focus scope dumps focus on the dialog container.\n addButtonRef.current?.focus();\n setSigners((current) =>\n current.filter((signer) => signer.rowId !== rowId),\n );\n };\n\n const handleRequest = () => {\n onRequestSignature({\n operatorId: isUnassigned ? null : operator,\n signers: signers.map(({ rowId: _rowId, ...signer }) => signer),\n });\n };\n\n return (\n <div ref={ref} className=\"ds:contents\" data-component=\"signature-request\">\n <Dialog open={open} onOpenChange={onOpenChange}>\n <Dialog.Content size=\"lg\" hideCloseButton {...contentProps}>\n <Dialog.Header>\n <Dialog.Title>\n {title ?? t('signatureRequest.title')}\n </Dialog.Title>\n <Dialog.Description>\n {description ?? t('signatureRequest.noSignedVersions')}\n </Dialog.Description>\n </Dialog.Header>\n\n <Dialog.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <section className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <p className=\"type-eyebrow ds:text-start ds:text-[color:var(--muted-foreground)]\">\n {t('signatureRequest.operatorSection')}\n </p>\n {currentOperatorId !== undefined ? (\n <Button\n intent=\"primary\"\n size=\"sm\"\n startIcon={<UserPlus />}\n disabled={busy}\n onClick={() => setOperator(currentOperatorId)}\n >\n {t('signatureRequest.assignToMe')}\n </Button>\n ) : null}\n </div>\n\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n {/* Mirrors the select value — decorative for AT. No name →\n Avatar's built-in placeholder-icon fallback. */}\n <Avatar\n aria-hidden=\"true\"\n name={\n isUnassigned ? undefined : labelFor(operators, operator)\n }\n size=\"sm\"\n />\n <div className=\"ds:min-w-0 ds:flex-1 ds:text-start\">\n <Select\n options={operatorSelectOptions}\n value={operator}\n onValueChange={(value) => value && setOperator(value)}\n required\n disabled={busy}\n placeholder={t('signatureRequest.operatorPlaceholder')}\n aria-label={t('signatureRequest.operatorSection')}\n />\n </div>\n </div>\n\n {isUnassigned ? null : (\n <Alert variant=\"info\">\n <Alert.Description>\n {t('signatureRequest.operatorHint')}\n </Alert.Description>\n </Alert>\n )}\n </section>\n\n <Separator decorative />\n\n <section className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:text-start\">\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <p className=\"type-eyebrow ds:text-[color:var(--muted-foreground)]\">\n {t('signatureRequest.signersSection')}\n </p>\n <Button\n ref={addButtonRef}\n intent=\"primary\"\n size=\"sm\"\n startIcon={<Plus />}\n disabled={!canAddSigner}\n onClick={addSigner}\n >\n {t('signatureRequest.addSigner')}\n </Button>\n </div>\n\n {signers.map((signer) => {\n const rowOptions = signerOptions.filter(\n (option) =>\n option.value === signer.signerId ||\n !chosenIds.includes(option.value),\n );\n const rowLabel = labelFor(signerOptions, signer.signerId);\n return (\n <div\n key={signer.rowId}\n role=\"group\"\n aria-label={rowLabel}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n {/* Mirrors the select value — decorative for AT. */}\n <Avatar aria-hidden=\"true\" name={rowLabel} size=\"sm\" />\n <div className=\"ds:min-w-0 ds:flex-1\">\n <Select\n options={rowOptions}\n value={signer.signerId}\n onValueChange={(value) =>\n value &&\n patchSigner(signer.rowId, { signerId: value })\n }\n required\n disabled={busy}\n placeholder={t(\n 'signatureRequest.signerPlaceholder',\n )}\n aria-label={t('signatureRequest.signerPlaceholder')}\n />\n </div>\n {signers.length > 1 ? (\n <IconButton\n intent=\"ghost\"\n size=\"sm\"\n icon={<X />}\n disabled={busy}\n aria-label={t('signatureRequest.removeSigner')}\n onClick={() => removeSigner(signer.rowId)}\n />\n ) : null}\n </div>\n\n {/* One channel per signer — checkbox visuals, but the\n choice is mutually exclusive: checking a channel\n unchecks the others, and the active one can't be\n unchecked. */}\n <div\n role=\"group\"\n aria-label={t('signatureRequest.channelLabel')}\n className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-lg)] ds:gap-y-[var(--spacing-sm)] ds:ps-[var(--spacing-xl)]\"\n >\n {channelOptions.map((option) => (\n <Checkbox\n key={option.value}\n checked={signer.channel === option.value}\n disabled={busy}\n onCheckedChange={(checked) =>\n checked === true &&\n patchSigner(signer.rowId, {\n channel: option.value,\n skipOtp: undefined,\n })\n }\n label={\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className=\"ds:text-[var(--accent)]\"\n >\n {option.icon}\n </span>\n {option.label}\n </span>\n }\n />\n ))}\n </div>\n\n {signer.channel === 'on-device' ? (\n <div className=\"ds:ps-[var(--spacing-xl)]\">\n <Switch\n label={t('signatureRequest.noOtp')}\n checked={signer.skipOtp === true}\n disabled={busy}\n onCheckedChange={(checked) =>\n patchSigner(signer.rowId, { skipOtp: checked })\n }\n />\n </div>\n ) : null}\n </div>\n );\n })}\n </section>\n\n {/* Dedicated alert area — one warning regardless of how many\n signers waive OTP, stacked with any submission error, all at\n the same full width as the operator hint. */}\n {signers.some(\n (signer) =>\n signer.channel === 'on-device' && signer.skipOtp === true,\n ) ? (\n <Alert variant=\"warning\">\n <Alert.Description>\n {t('signatureRequest.noOtpWarning')}\n </Alert.Description>\n </Alert>\n ) : null}\n {error ? (\n <Alert variant=\"error\">\n <Alert.Description>{error}</Alert.Description>\n </Alert>\n ) : null}\n </Dialog.Body>\n\n <Dialog.Footer>\n <Button\n intent=\"primary\"\n startIcon={<PenLine />}\n onClick={handleRequest}\n disabled={busy || signers.length === 0}\n loading={busy}\n >\n {t('signatureRequest.requestSignature')}\n </Button>\n <Dialog.Close asChild>\n <Button intent=\"outline\" disabled={busy}>\n {t('signatureRequest.close')}\n </Button>\n </Dialog.Close>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog>\n </div>\n );\n },\n);\nSignatureRequestModal.displayName = 'SignatureRequestModal';\n"],"names":["__iconNode","MessageSquareText","createLucideIcon","Tablet","UserPlus","ASSIGN_LATER","labelFor","options","value","_a","option","SignatureRequestModal","forwardRef","open","onOpenChange","operators","signerOptions","currentOperatorId","allowAssignLater","initialOperatorId","initialSigners","maxSigners","busy","error","title","description","onRequestSignature","contentProps","ref","t","useTranslation","nextRowId","useRef","addButtonRef","seedOperator","_b","seedRows","signer","operator","setOperator","useState","signers","setSigners","wasOpen","useEffect","operatorSelectOptions","isUnassigned","channelOptions","jsx","Mail","WhatsAppGlyph","chosenIds","nextFreeOption","canAddSigner","patchSigner","rowId","patch","current","addSigner","removeSigner","handleRequest","_rowId","Dialog","jsxs","Button","Avatar","Select","Alert","Separator","Plus","rowOptions","rowLabel","IconButton","X","Checkbox","checked","Switch","PenLine"],"mappings":"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","x_google_ignoreList":[0,1,2]}