@alfadocs/ui-kit-debug 1.112.1 → 1.113.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 (228) hide show
  1. package/dist/_chunks/{ai-prompt-input-CG9BEggs.js → ai-prompt-input-JIPbrTF3.js} +2 -2
  2. package/dist/_chunks/{ai-prompt-input-CG9BEggs.js.map → ai-prompt-input-JIPbrTF3.js.map} +1 -1
  3. package/dist/_chunks/{anamnesis-summary-rows-BrTx7diS.js → anamnesis-summary-rows-DfDulR_c.js} +3 -3
  4. package/dist/_chunks/{anamnesis-summary-rows-BrTx7diS.js.map → anamnesis-summary-rows-DfDulR_c.js.map} +1 -1
  5. package/dist/_chunks/{audio-recorder-BlDozxdU.js → audio-recorder-CsnM_WDy.js} +2 -2
  6. package/dist/_chunks/{audio-recorder-BlDozxdU.js.map → audio-recorder-CsnM_WDy.js.map} +1 -1
  7. package/dist/_chunks/{balance-badge-cell-wJ6cTD_h.js → balance-badge-cell-BAZynD--.js} +4 -4
  8. package/dist/_chunks/{balance-badge-cell-wJ6cTD_h.js.map → balance-badge-cell-BAZynD--.js.map} +1 -1
  9. package/dist/_chunks/{bishop-score-BhMomGcX.js → bishop-score-CnIft4eV.js} +2 -2
  10. package/dist/_chunks/{bishop-score-BhMomGcX.js.map → bishop-score-CnIft4eV.js.map} +1 -1
  11. package/dist/_chunks/{calendar-appointment-editor-dialog-Oc3Df8O3.js → calendar-appointment-editor-dialog-CaZm5wGR.js} +5 -5
  12. package/dist/_chunks/{calendar-appointment-editor-dialog-Oc3Df8O3.js.map → calendar-appointment-editor-dialog-CaZm5wGR.js.map} +1 -1
  13. package/dist/_chunks/{data-table-zXBxFYpJ.js → data-table-C9idMvs0.js} +2 -2
  14. package/dist/_chunks/{data-table-zXBxFYpJ.js.map → data-table-C9idMvs0.js.map} +1 -1
  15. package/dist/_chunks/{document-preview-BalyZqnn.js → document-preview-5xs64jME.js} +2 -2
  16. package/dist/_chunks/{document-preview-BalyZqnn.js.map → document-preview-5xs64jME.js.map} +1 -1
  17. package/dist/_chunks/email-input-DxwbREpx.js +156 -0
  18. package/dist/_chunks/email-input-DxwbREpx.js.map +1 -0
  19. package/dist/_chunks/{file-manager-CVxBE4yy.js → file-manager-LG7B_UHB.js} +2 -2
  20. package/dist/_chunks/{file-manager-CVxBE4yy.js.map → file-manager-LG7B_UHB.js.map} +1 -1
  21. package/dist/_chunks/{forgot-password-form-vfCO2-Tt.js → forgot-password-form-YQVzSskq.js} +8 -7
  22. package/dist/_chunks/{forgot-password-form-vfCO2-Tt.js.map → forgot-password-form-YQVzSskq.js.map} +1 -1
  23. package/dist/_chunks/{gestational-age-calculator-AnaH00nk.js → gestational-age-calculator-Dv3IePb-.js} +2 -2
  24. package/dist/_chunks/{gestational-age-calculator-AnaH00nk.js.map → gestational-age-calculator-Dv3IePb-.js.map} +1 -1
  25. package/dist/_chunks/{heatmap-D4qqpCEj.js → heatmap-BiwC7Gdx.js} +2 -2
  26. package/dist/_chunks/{heatmap-D4qqpCEj.js.map → heatmap-BiwC7Gdx.js.map} +1 -1
  27. package/dist/_chunks/isEmail-BfVspSvV.js +248 -0
  28. package/dist/_chunks/isEmail-BfVspSvV.js.map +1 -0
  29. package/dist/_chunks/{kit-extensions-VaJ-u44J.js → kit-extensions-BOsUgWnE.js} +3 -3
  30. package/dist/_chunks/{kit-extensions-VaJ-u44J.js.map → kit-extensions-BOsUgWnE.js.map} +1 -1
  31. package/dist/_chunks/{link-cell-renderer-C8vfCOEp.js → link-cell-renderer-_Fv3WEmb.js} +2 -2
  32. package/dist/_chunks/{link-cell-renderer-C8vfCOEp.js.map → link-cell-renderer-_Fv3WEmb.js.map} +1 -1
  33. package/dist/_chunks/{login-dev-card-Cz1Clugq.js → login-dev-card-B6-zCFq3.js} +47 -46
  34. package/dist/_chunks/{login-dev-card-Cz1Clugq.js.map → login-dev-card-B6-zCFq3.js.map} +1 -1
  35. package/dist/_chunks/{muscle-scheme-1BZd1-RE.js → muscle-scheme-BkmDUTmk.js} +2 -2
  36. package/dist/_chunks/{muscle-scheme-1BZd1-RE.js.map → muscle-scheme-BkmDUTmk.js.map} +1 -1
  37. package/dist/_chunks/{optical-prescription-BGVeDVSP.js → optical-prescription-CvbN8yD2.js} +2 -2
  38. package/dist/_chunks/{optical-prescription-BGVeDVSP.js.map → optical-prescription-CvbN8yD2.js.map} +1 -1
  39. package/dist/_chunks/{patient-details-wMgTFtpp.js → patient-details-RsT3SaYh.js} +2 -2
  40. package/dist/_chunks/{patient-details-wMgTFtpp.js.map → patient-details-RsT3SaYh.js.map} +1 -1
  41. package/dist/_chunks/{patient-field-row-Bhm2Ig1P.js → patient-field-row-D9rb-QJH.js} +3 -3
  42. package/dist/_chunks/{patient-field-row-Bhm2Ig1P.js.map → patient-field-row-D9rb-QJH.js.map} +1 -1
  43. package/dist/_chunks/{patient-summary-card-DMdPPG3n.js → patient-summary-card-BjZErlbt.js} +2 -2
  44. package/dist/_chunks/{patient-summary-card-DMdPPG3n.js.map → patient-summary-card-BjZErlbt.js.map} +1 -1
  45. package/dist/_chunks/{practice-results-BOpaPaav.js → practice-results-BByRCIuR.js} +620 -566
  46. package/dist/_chunks/practice-results-BByRCIuR.js.map +1 -0
  47. package/dist/_chunks/{pregnancy-dating-D6dLkMpl.js → pregnancy-dating-Cs8xpZA8.js} +2 -2
  48. package/dist/_chunks/{pregnancy-dating-D6dLkMpl.js.map → pregnancy-dating-Cs8xpZA8.js.map} +1 -1
  49. package/dist/_chunks/{registration-form-CEJRUS9G.js → registration-form-Cq5_OSIL.js} +8 -7
  50. package/dist/_chunks/{registration-form-CEJRUS9G.js.map → registration-form-Cq5_OSIL.js.map} +1 -1
  51. package/dist/_chunks/{reserved.agent-C-C9cvO5.js → reserved.agent-BMkapgom.js} +3 -3
  52. package/dist/_chunks/{reserved.agent-C-C9cvO5.js.map → reserved.agent-BMkapgom.js.map} +1 -1
  53. package/dist/_chunks/{reset-password-form-B0acanDD.js → reset-password-form-BVsL2fOJ.js} +2 -2
  54. package/dist/_chunks/{reset-password-form-B0acanDD.js.map → reset-password-form-BVsL2fOJ.js.map} +1 -1
  55. package/dist/_chunks/{select-BBDRYxJl.js → select-uESzXTX6.js} +42 -39
  56. package/dist/_chunks/select-uESzXTX6.js.map +1 -0
  57. package/dist/_chunks/{send-registration-link-form-Nn0jf65G.js → send-registration-link-form-OgPomrZN.js} +8 -7
  58. package/dist/_chunks/{send-registration-link-form-Nn0jf65G.js.map → send-registration-link-form-OgPomrZN.js.map} +1 -1
  59. package/dist/_chunks/{signature-request-DJwdPji_.js → signature-request-BnTihryS.js} +2 -2
  60. package/dist/_chunks/{signature-request-DJwdPji_.js.map → signature-request-BnTihryS.js.map} +1 -1
  61. package/dist/_chunks/{tabs-DYHgRVSJ.js → tabs-CXYjr_8O.js} +2 -2
  62. package/dist/_chunks/{tabs-DYHgRVSJ.js.map → tabs-CXYjr_8O.js.map} +1 -1
  63. package/dist/_chunks/{task-editor-jqRf2JP6.js → task-editor-gqWF1jI6.js} +2 -2
  64. package/dist/_chunks/{task-editor-jqRf2JP6.js.map → task-editor-gqWF1jI6.js.map} +1 -1
  65. package/dist/_chunks/{tasks-panel-CFo5uIHx.js → tasks-panel-OuIaydK5.js} +2 -2
  66. package/dist/_chunks/{tasks-panel-CFo5uIHx.js.map → tasks-panel-OuIaydK5.js.map} +1 -1
  67. package/dist/_chunks/{unit-converter-C95sa5y8.js → unit-converter-D77vmlzN.js} +2 -2
  68. package/dist/_chunks/{unit-converter-C95sa5y8.js.map → unit-converter-D77vmlzN.js.map} +1 -1
  69. package/dist/_chunks/{use-appointment-details-read-VI26Z-pc.js → use-appointment-details-read-DvK7Looa.js} +2 -2
  70. package/dist/_chunks/{use-appointment-details-read-VI26Z-pc.js.map → use-appointment-details-read-DvK7Looa.js.map} +1 -1
  71. package/dist/_chunks/verify-identity-types-C85EXNzy.js +707 -0
  72. package/dist/_chunks/verify-identity-types-C85EXNzy.js.map +1 -0
  73. package/dist/_chunks/{voice-control-panel-B0TUZAiP.js → voice-control-panel-BGiX4sqB.js} +2 -2
  74. package/dist/_chunks/{voice-control-panel-B0TUZAiP.js.map → voice-control-panel-BGiX4sqB.js.map} +1 -1
  75. package/dist/agent-catalog.json +106 -2
  76. package/dist/agent-i18n/en.json +11 -0
  77. package/dist/components/ai-prompt-input/index.js +1 -1
  78. package/dist/components/appointment-details-panel/index.js +1 -1
  79. package/dist/components/audio-recorder/index.js +1 -1
  80. package/dist/components/bishop-score/index.js +1 -1
  81. package/dist/components/booking/index.js +1 -1
  82. package/dist/components/data-table/index.js +2 -2
  83. package/dist/components/document-preview/index.js +1 -1
  84. package/dist/components/email-input/index.js +1 -1
  85. package/dist/components/file-manager/index.js +1 -1
  86. package/dist/components/gestational-age-calculator/index.js +1 -1
  87. package/dist/components/heatmap/index.js +1 -1
  88. package/dist/components/index.d.ts +1 -0
  89. package/dist/components/index.d.ts.map +1 -1
  90. package/dist/components/muscle-scheme/index.js +1 -1
  91. package/dist/components/optical-prescription/index.js +1 -1
  92. package/dist/components/patient-details/index.js +1 -1
  93. package/dist/components/patient-summary-card/index.js +1 -1
  94. package/dist/components/patient-table/index.js +1 -1
  95. package/dist/components/practice-results/index.js +1 -1
  96. package/dist/components/practice-results/practice-results.d.ts +28 -0
  97. package/dist/components/practice-results/practice-results.d.ts.map +1 -1
  98. package/dist/components/pregnancy-dating/index.js +1 -1
  99. package/dist/components/rich-text-editor/index.js +1 -1
  100. package/dist/components/select/index.js +1 -1
  101. package/dist/components/select/select.d.ts.map +1 -1
  102. package/dist/components/skeleton-scheme/index.js +1 -1
  103. package/dist/components/tabs/index.js +1 -1
  104. package/dist/components/task-editor/index.js +1 -1
  105. package/dist/components/tasks-panel/index.js +1 -1
  106. package/dist/components/unit-converter/index.js +1 -1
  107. package/dist/components/voice-control-panel/index.js +1 -1
  108. package/dist/core.css +1 -1
  109. package/dist/i18n/locales/ar.d.ts +67 -0
  110. package/dist/i18n/locales/ar.d.ts.map +1 -1
  111. package/dist/i18n/locales/ar.js +68 -1
  112. package/dist/i18n/locales/ar.js.map +1 -1
  113. package/dist/i18n/locales/de.d.ts +67 -0
  114. package/dist/i18n/locales/de.d.ts.map +1 -1
  115. package/dist/i18n/locales/de.js +68 -1
  116. package/dist/i18n/locales/de.js.map +1 -1
  117. package/dist/i18n/locales/el.d.ts +67 -0
  118. package/dist/i18n/locales/el.d.ts.map +1 -1
  119. package/dist/i18n/locales/el.js +68 -1
  120. package/dist/i18n/locales/el.js.map +1 -1
  121. package/dist/i18n/locales/en.d.ts +67 -0
  122. package/dist/i18n/locales/en.d.ts.map +1 -1
  123. package/dist/i18n/locales/en.js +67 -0
  124. package/dist/i18n/locales/en.js.map +1 -1
  125. package/dist/i18n/locales/es.d.ts +67 -0
  126. package/dist/i18n/locales/es.d.ts.map +1 -1
  127. package/dist/i18n/locales/es.js +68 -1
  128. package/dist/i18n/locales/es.js.map +1 -1
  129. package/dist/i18n/locales/fr.d.ts +67 -0
  130. package/dist/i18n/locales/fr.d.ts.map +1 -1
  131. package/dist/i18n/locales/fr.js +68 -1
  132. package/dist/i18n/locales/fr.js.map +1 -1
  133. package/dist/i18n/locales/hi.d.ts +67 -0
  134. package/dist/i18n/locales/hi.d.ts.map +1 -1
  135. package/dist/i18n/locales/hi.js +68 -1
  136. package/dist/i18n/locales/hi.js.map +1 -1
  137. package/dist/i18n/locales/it.d.ts +67 -0
  138. package/dist/i18n/locales/it.d.ts.map +1 -1
  139. package/dist/i18n/locales/it.js +68 -1
  140. package/dist/i18n/locales/it.js.map +1 -1
  141. package/dist/i18n/locales/ja.d.ts +67 -0
  142. package/dist/i18n/locales/ja.d.ts.map +1 -1
  143. package/dist/i18n/locales/ja.js +68 -1
  144. package/dist/i18n/locales/ja.js.map +1 -1
  145. package/dist/i18n/locales/nl.d.ts +67 -0
  146. package/dist/i18n/locales/nl.d.ts.map +1 -1
  147. package/dist/i18n/locales/nl.js +68 -1
  148. package/dist/i18n/locales/nl.js.map +1 -1
  149. package/dist/i18n/locales/pl.d.ts +67 -0
  150. package/dist/i18n/locales/pl.d.ts.map +1 -1
  151. package/dist/i18n/locales/pl.js +68 -1
  152. package/dist/i18n/locales/pl.js.map +1 -1
  153. package/dist/i18n/locales/pt.d.ts +67 -0
  154. package/dist/i18n/locales/pt.d.ts.map +1 -1
  155. package/dist/i18n/locales/pt.js +68 -1
  156. package/dist/i18n/locales/pt.js.map +1 -1
  157. package/dist/i18n/locales/ro.d.ts +67 -0
  158. package/dist/i18n/locales/ro.d.ts.map +1 -1
  159. package/dist/i18n/locales/ro.js +68 -1
  160. package/dist/i18n/locales/ro.js.map +1 -1
  161. package/dist/i18n/locales/ru.d.ts +67 -0
  162. package/dist/i18n/locales/ru.d.ts.map +1 -1
  163. package/dist/i18n/locales/ru.js +68 -1
  164. package/dist/i18n/locales/ru.js.map +1 -1
  165. package/dist/i18n/locales/sq.d.ts +67 -0
  166. package/dist/i18n/locales/sq.d.ts.map +1 -1
  167. package/dist/i18n/locales/sq.js +68 -1
  168. package/dist/i18n/locales/sq.js.map +1 -1
  169. package/dist/i18n/locales/sv.d.ts +67 -0
  170. package/dist/i18n/locales/sv.d.ts.map +1 -1
  171. package/dist/i18n/locales/sv.js +68 -1
  172. package/dist/i18n/locales/sv.js.map +1 -1
  173. package/dist/i18n/locales/tr.d.ts +67 -0
  174. package/dist/i18n/locales/tr.d.ts.map +1 -1
  175. package/dist/i18n/locales/tr.js +68 -1
  176. package/dist/i18n/locales/tr.js.map +1 -1
  177. package/dist/i18n/locales/zh.d.ts +67 -0
  178. package/dist/i18n/locales/zh.d.ts.map +1 -1
  179. package/dist/i18n/locales/zh.js +68 -1
  180. package/dist/i18n/locales/zh.js.map +1 -1
  181. package/dist/index.js +352 -347
  182. package/dist/index.js.map +1 -1
  183. package/dist/locales/ar.json +68 -1
  184. package/dist/locales/de.json +68 -1
  185. package/dist/locales/el.json +68 -1
  186. package/dist/locales/en.json +67 -0
  187. package/dist/locales/es.json +68 -1
  188. package/dist/locales/fr.json +68 -1
  189. package/dist/locales/hi.json +68 -1
  190. package/dist/locales/it.json +68 -1
  191. package/dist/locales/ja.json +68 -1
  192. package/dist/locales/nl.json +68 -1
  193. package/dist/locales/pl.json +68 -1
  194. package/dist/locales/pt.json +68 -1
  195. package/dist/locales/ro.json +68 -1
  196. package/dist/locales/ru.json +68 -1
  197. package/dist/locales/sq.json +68 -1
  198. package/dist/locales/sv.json +68 -1
  199. package/dist/locales/tr.json +68 -1
  200. package/dist/locales/zh.json +68 -1
  201. package/dist/patterns/anamnesis/index.js +1 -1
  202. package/dist/patterns/calendar/index.js +1 -1
  203. package/dist/patterns/forgot-password-form/index.js +1 -1
  204. package/dist/patterns/login-form/index.js +1 -1
  205. package/dist/patterns/registration-form/index.js +1 -1
  206. package/dist/patterns/reset-password-form/index.js +1 -1
  207. package/dist/patterns/send-registration-link-form/index.js +1 -1
  208. package/dist/patterns/signature-request/index.js +1 -1
  209. package/dist/patterns/verify-identity/change-email-dialog.d.ts +26 -0
  210. package/dist/patterns/verify-identity/change-email-dialog.d.ts.map +1 -0
  211. package/dist/patterns/verify-identity/index.d.ts +7 -0
  212. package/dist/patterns/verify-identity/index.d.ts.map +1 -0
  213. package/dist/patterns/verify-identity/index.js +8 -0
  214. package/dist/patterns/verify-identity/index.js.map +1 -0
  215. package/dist/patterns/verify-identity/use-countdown.d.ts +12 -0
  216. package/dist/patterns/verify-identity/use-countdown.d.ts.map +1 -0
  217. package/dist/patterns/verify-identity/verify-identity-steps.d.ts +21 -0
  218. package/dist/patterns/verify-identity/verify-identity-steps.d.ts.map +1 -0
  219. package/dist/patterns/verify-identity/verify-identity-types.d.ts +47 -0
  220. package/dist/patterns/verify-identity/verify-identity-types.d.ts.map +1 -0
  221. package/dist/patterns/verify-identity/verify-identity.d.ts +54 -0
  222. package/dist/patterns/verify-identity/verify-identity.d.ts.map +1 -0
  223. package/dist/tokens.css +1 -1
  224. package/package.json +5 -1
  225. package/dist/_chunks/email-input-BEO3vonE.js +0 -399
  226. package/dist/_chunks/email-input-BEO3vonE.js.map +0 -1
  227. package/dist/_chunks/practice-results-BOpaPaav.js.map +0 -1
  228. package/dist/_chunks/select-BBDRYxJl.js.map +0 -1
@@ -7,7 +7,7 @@ import { C as B } from "./card-C85_Ndhb.js";
7
7
  import { E as G } from "./empty-state-DwJ5YNzz.js";
8
8
  import { P as Y } from "./panel-header-CbtlTe85.js";
9
9
  import { P as J } from "./pdf-viewer-BnBKdx0y.js";
10
- import { T as O, b as Q, c as X, a as Z } from "./tabs-DYHgRVSJ.js";
10
+ import { T as O, b as Q, c as X, a as Z } from "./tabs-CXYjr_8O.js";
11
11
  import { u as ee } from "./registry-DvAUVLHh.js";
12
12
  import { F as ie } from "./file-image-cDgE-BTy.js";
13
13
  import { F as te } from "./file-text-5yv6r2ls.js";
@@ -288,4 +288,4 @@ export {
288
288
  ue as D,
289
289
  de as d
290
290
  };
291
- //# sourceMappingURL=document-preview-BalyZqnn.js.map
291
+ //# sourceMappingURL=document-preview-5xs64jME.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"document-preview-BalyZqnn.js","sources":["../../node_modules/lucide-react/dist/esm/icons/files.mjs","../../src/components/document-preview/document-preview.agent.ts","../../src/components/document-preview/document-preview.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8\", key: \"14sh0y\" }],\n [\n \"path\",\n {\n d: \"M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z\",\n key: \"1970lx\"\n }\n ],\n [\"path\", { d: \"M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1\", key: \"l4dndm\" }]\n];\nconst Files = createLucideIcon(\"files\", __iconNode);\n\nexport { __iconNode, Files as default };\n//# sourceMappingURL=files.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — DocumentPreview. */\n/* */\n/* A passive, read-only viewer, so it declares no interactive */\n/* capabilities. The always-on state slot carries only the structural */\n/* render `kind` (pdf / image / metadata / empty) — never the document */\n/* name. */\n/* */\n/* PHI rule (PRS §26 §7): the document display name can identify a */\n/* patient (e.g. \"Rossi Maria — referto 2026.pdf\"). It renders as text */\n/* (fine) but the only name-returning read is the deliberate get_name */\n/* action with `safety: 'phi'`, so the host gates it behind confirm + */\n/* audit. No name is ever emitted in a data-* hook. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DocumentPreviewHandle } from './document-preview';\n\nexport const documentPreviewAgent: AgentAdapter<DocumentPreviewHandle> = {\n id: 'document-preview',\n capabilities: [],\n state: {\n kind: {\n type: \"'pdf' | 'image' | 'metadata' | 'empty'\",\n descriptionKey: 'ui.agent.documentPreview.state.kind',\n description:\n 'Which render branch is active: pdf, image, metadata (no inline preview), or empty (no document). Structural — never the document name.',\n read: (handle) => handle.getKind(),\n },\n },\n actions: {\n get_name: {\n // phi (not read): resolves the document display name, which can identify\n // patients. PRS §26 — phi outranks read so the host gates it behind\n // stricter confirm + audit. The always-on kind slot stays name-free.\n safety: 'phi',\n returns: 'string | undefined',\n returnsSchema: { type: ['string', 'null'] },\n idempotent: true,\n descriptionKey: 'ui.agent.documentPreview.actions.getName',\n description:\n 'Read the display name of the previewed document. May identify a patient (PHI).',\n invoke: (handle) => handle.getName(),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'document-preview',\n description: 'Marks the DocumentPreview region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* DocumentPreview — a standalone, reusable document viewer. */\n/* */\n/* Decoupled from FileManager: it takes primitive props (name, mimeType, */\n/* src, metadata) rather than a FileManagerItem, so signing, the patient */\n/* portal, and the Control Room rail can all reuse it. The body is an */\n/* elevated Card: a bounded preview viewport (PDF → kit PDFViewer; */\n/* image/* → <img>; otherwise a MIME-icon placeholder) above an always-on */\n/* Details block (badges + every structural field the host supplies), so */\n/* the metadata is never dropped when a real preview renders. No name → */\n/* EmptyState. */\n/* */\n/* Title lives in the canonical PanelHeader (the same header every rail */\n/* panel adopts) so the Control Room rail can inject its pin / close */\n/* controls into it. Pass `documents` (≥ 2) to preview a SELECTION as */\n/* tabs — one tab per document, the active one shown below; a single */\n/* entry (or the single-document props) renders without a tab strip. */\n/* */\n/* The root is a `<section>` (region landmark) so the PanelHeader's */\n/* <header> is scoped and never exposed as a page banner — the same */\n/* shape RadiographPanel uses. It is also a keyboard-focusable scroll */\n/* region (tabIndex 0 + labelled focus ring). */\n/* */\n/* PHI: the visible name renders as text (fine), but the only */\n/* name-returning handle read is surfaced by document-preview.agent.ts */\n/* as a `safety: 'phi'` action — never in always-on state, never in a */\n/* data-* hook. In tabbed mode the handle reflects the ACTIVE tab. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n Fragment,\n useImperativeHandle,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n File as FileIcon,\n FileImage,\n FileText,\n Files,\n type LucideIcon,\n} from 'lucide-react';\nimport { Badge } from '../badge';\nimport { Card } from '../card';\nimport { EmptyState } from '../empty-state';\nimport { PanelHeader } from '../panel-header';\nimport { PDFViewer } from '../pdf-viewer';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '../tabs';\nimport { useAgentRegistration } from '../../agent';\nimport { documentPreviewAgent } from './document-preview.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type DocumentPreviewSignatureStatus = 'none' | 'pending' | 'signed';\n\n/** Which render branch DocumentPreview is showing — structural, never PHI. */\nexport type DocumentPreviewKind = 'pdf' | 'image' | 'metadata' | 'empty';\n\nexport interface DocumentPreviewMetadata {\n /** Size in bytes. */\n size?: number;\n /** Display name of whoever created the document (host-supplied). */\n createdBy?: string;\n /** ISO 8601 timestamp the document was created. */\n createdAt?: string;\n /** ISO 8601 timestamp of the last modification. */\n updatedAt?: string;\n /** ISO 8601 timestamp a signature was requested from the patient. */\n signatureRequestedAt?: string;\n /** ISO 8601 timestamp the document was signed. */\n signedAt?: string;\n /** ISO 8601 timestamp the document was shared with the patient. */\n sharedAt?: string;\n /** Open document-type category (non-identifying), e.g. `'xray'`. */\n documentType?: string;\n /** Signature workflow state. */\n signatureStatus?: DocumentPreviewSignatureStatus;\n /** Clinical-document flag (host-defined semantics). */\n clinical?: boolean;\n /** ISO 8601 expiry (e.g. identification documents). */\n expiresAt?: string;\n}\n\n/**\n * A single previewable document. In multi-document mode each becomes a tab;\n * `id` is the tab value (never a patient name) and `name` is the tab label.\n */\nexport interface DocumentPreviewDocument {\n /** Stable, non-identifying id. Emitted as the tab value — never PHI. */\n id: string;\n /** Display name (PHI). Also the tab label in multi-document mode. */\n name: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n}\n\nexport interface DocumentPreviewProps extends VariantProps<\n typeof documentPreviewVariants\n> {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Display name. Absent (and no `documents`) → empty state. PHI. */\n name?: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. The host owns auth. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n /**\n * Multiple documents to preview as tabs — e.g. a multi-row selection. Two\n * or more render a tab per document (label = name) with the active one\n * shown below; a single entry renders without a tab strip. When non-empty\n * this takes precedence over the single-document props. Names are PHI.\n */\n documents?: DocumentPreviewDocument[];\n className?: string;\n}\n\nexport interface DocumentPreviewHandle {\n /** Which render branch is active — structural, safe for always-on reads. */\n getKind: () => DocumentPreviewKind;\n /** The active document's display name (PHI). Surfaced by the adapter as a `phi` action. */\n getName: () => string | undefined;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst documentPreviewVariants = cva(\n [\n 'ds:flex ds:h-full ds:min-h-0 ds:min-w-0 ds:flex-col ds:overflow-auto',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring',\n ].join(' '),\n);\n\nconst SIGNATURE_VARIANT: Record<\n Exclude<DocumentPreviewSignatureStatus, 'none'>,\n 'success' | 'warning'\n> = {\n signed: 'success',\n pending: 'warning',\n};\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction resolveKind(\n name: string | undefined,\n mimeType: string | undefined,\n src: string | undefined,\n): DocumentPreviewKind {\n if (!name) return 'empty';\n const mime = mimeType ?? '';\n if (mime === 'application/pdf' && src) return 'pdf';\n if (mime.startsWith('image/') && src) return 'image';\n return 'metadata';\n}\n\n/** Fallback icon for the header / metadata card — a small MIME-family lookup. */\nfunction iconForMime(mimeType: string | undefined): LucideIcon {\n const mime = mimeType ?? '';\n if (mime.startsWith('image/')) return FileImage;\n if (\n mime === 'application/pdf' ||\n mime.startsWith('text/') ||\n mime.includes('word')\n ) {\n return FileText;\n }\n return FileIcon;\n}\n\nconst UNIT_KEYS = [\n 'documentPreview.units.bytes',\n 'documentPreview.units.kilobytes',\n 'documentPreview.units.megabytes',\n 'documentPreview.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nfunction formatBytes(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n return `${formatted} ${t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex])}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const DocumentPreview = forwardRef<\n DocumentPreviewHandle,\n DocumentPreviewProps\n>(({ id, name, mimeType, src, metadata, documents, className }, ref) => {\n const { t, i18n } = useTranslation('ui');\n\n // Resolve the document list: an explicit `documents` list wins; otherwise\n // the single-document props form a one-item list; nothing → empty. The\n // synthetic single-doc id is never emitted as a tab value (a lone doc\n // renders without a tab strip), so falling back to the name is PHI-safe.\n const docs = useMemo<DocumentPreviewDocument[]>(() => {\n if (documents && documents.length > 0) return documents;\n if (name) return [{ id: id ?? name, name, mimeType, src, metadata }];\n return [];\n }, [documents, id, name, mimeType, src, metadata]);\n\n const isTabbed = docs.length > 1;\n\n // Active tab (multi mode). When the current id is stale after the selection\n // changes we fall back to the first document — no reconciling effect needed.\n const [activeId, setActiveId] = useState<string | undefined>(undefined);\n const activeDoc = docs.find((doc) => doc.id === activeId) ?? docs[0];\n\n const handle = useMemo<DocumentPreviewHandle>(\n () => ({\n getKind: () =>\n activeDoc\n ? resolveKind(activeDoc.name, activeDoc.mimeType, activeDoc.src)\n : 'empty',\n getName: () => activeDoc?.name,\n }),\n [activeDoc],\n );\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(documentPreviewAgent, handle, id);\n\n /* The per-document body — an elevated Card with a bounded preview viewport\n (pdf / image / placeholder) above an always-on Details block. The title is\n NOT rendered here (the PanelHeader owns it, or the tab label in multi mode). */\n const renderBody = (doc: DocumentPreviewDocument): ReactNode => {\n const kind = resolveKind(doc.name, doc.mimeType, doc.src);\n const meta = doc.metadata;\n const PlaceholderIcon = iconForMime(doc.mimeType);\n\n // Preview viewport — the rendered document, or a MIME-icon placeholder when\n // no source resolves. Bounded to a consistent aspect so the Details below\n // stay reachable in the rail.\n let viewport: ReactNode;\n if (kind === 'pdf' && doc.src) {\n viewport = (\n <PDFViewer\n src={doc.src}\n toolbarVariant=\"minimal\"\n // Name the embedded viewer after the document so it stays distinct\n // from the surrounding \"Document preview\" region (nested landmarks\n // must not share an accessible name). Mirrors visible header text.\n ariaLabel={doc.name}\n className=\"ds:h-full ds:w-full\"\n />\n );\n } else if (kind === 'image' && doc.src) {\n viewport = (\n <img\n src={doc.src}\n alt={t('documentPreview.imageAlt', 'Preview of {{name}}', {\n name: doc.name,\n })}\n className=\"ds:max-h-full ds:max-w-full ds:object-contain\"\n />\n );\n } else {\n viewport = (\n <span className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-muted-foreground\">\n <PlaceholderIcon aria-hidden=\"true\" className=\"ds:size-10\" />\n <span className=\"type-body-sm\">\n {t('documentPreview.noPreview', 'No preview available.')}\n </span>\n </span>\n );\n }\n\n // Badges: type / clinical / signature status.\n const status = meta?.signatureStatus;\n const hasBadges =\n Boolean(meta?.documentType) ||\n Boolean(meta?.clinical) ||\n (status !== undefined && status !== 'none');\n\n // Detail rows — every structural field the host supplies, so nothing is\n // dropped when a real preview renders. Only present fields render a row.\n const fmtDate = (iso: string): string =>\n new Intl.DateTimeFormat(i18n.language, { dateStyle: 'medium' }).format(\n new Date(iso),\n );\n const rows: Array<{ key: string; label: string; value: string }> = [];\n if (meta?.createdBy)\n rows.push({\n key: 'createdBy',\n label: t('documentPreview.fields.createdBy', 'Created by'),\n value: meta.createdBy,\n });\n if (meta?.createdAt)\n rows.push({\n key: 'created',\n label: t('documentPreview.fields.created', 'Created'),\n value: fmtDate(meta.createdAt),\n });\n if (meta?.updatedAt)\n rows.push({\n key: 'modified',\n label: t('documentPreview.fields.modified', 'Modified'),\n value: fmtDate(meta.updatedAt),\n });\n if (meta?.signatureRequestedAt)\n rows.push({\n key: 'signatureRequested',\n label: t(\n 'documentPreview.fields.signatureRequested',\n 'Signature requested',\n ),\n value: fmtDate(meta.signatureRequestedAt),\n });\n if (meta?.signedAt)\n rows.push({\n key: 'signed',\n label: t('documentPreview.fields.signed', 'Signed'),\n value: fmtDate(meta.signedAt),\n });\n if (meta?.sharedAt)\n rows.push({\n key: 'sharedWithPatient',\n label: t(\n 'documentPreview.fields.sharedWithPatient',\n 'Shared with patient',\n ),\n value: fmtDate(meta.sharedAt),\n });\n if (meta?.size !== undefined)\n rows.push({\n key: 'size',\n label: t('documentPreview.fields.size', 'Size'),\n value: formatBytes(meta.size, i18n.language, t),\n });\n if (meta?.expiresAt)\n rows.push({\n key: 'expires',\n label: t('documentPreview.fields.expires', 'Expires'),\n value: fmtDate(meta.expiresAt),\n });\n\n const hasDetails = hasBadges || rows.length > 0;\n\n return (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <Card\n variant=\"elevated\"\n className=\"ds:flex ds:flex-col ds:overflow-hidden\"\n >\n <div className=\"ds:flex ds:aspect-[4/3] ds:min-h-0 ds:items-center ds:justify-center ds:overflow-hidden ds:border-b ds:border-[color:var(--card-border)] ds:bg-muted\">\n {viewport}\n </div>\n {hasDetails && (\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3 className=\"type-eyebrow ds:m-0 ds:text-muted-foreground\">\n {t('documentPreview.detailsTitle', 'Details')}\n </h3>\n {hasBadges && (\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {meta?.documentType && (\n <Badge variant=\"neutral\" size=\"sm\">\n {meta.documentType}\n </Badge>\n )}\n {meta?.clinical && (\n <Badge variant=\"info\" size=\"sm\">\n {t('documentPreview.clinical', 'Clinical')}\n </Badge>\n )}\n {status && status !== 'none' && (\n <Badge\n variant={SIGNATURE_VARIANT[status]}\n size=\"sm\"\n withDot\n >\n {t(`documentPreview.signature.${status}`, status)}\n </Badge>\n )}\n </span>\n )}\n {rows.length > 0 && (\n <dl className=\"ds:grid ds:grid-cols-[auto_1fr] ds:gap-x-[var(--spacing-md)] ds:gap-y-[var(--spacing-xs)] type-body-sm\">\n {rows.map((row) => (\n <Fragment key={row.key}>\n <dt className=\"ds:text-muted-foreground\">{row.label}</dt>\n <dd className=\"ds:m-0\">{row.value}</dd>\n </Fragment>\n ))}\n </dl>\n )}\n </Card.Body>\n )}\n </Card>\n </div>\n );\n };\n\n // Header: a MIME icon + the document name for a single doc; a Files glyph +\n // a count badge (RadiographPanel's title-plus-badge shape) when tabbed.\n const HeaderMimeIcon = iconForMime(activeDoc?.mimeType);\n const headerIcon = isTabbed ? (\n <Files aria-hidden=\"true\" />\n ) : (\n <HeaderMimeIcon aria-hidden=\"true\" />\n );\n const headerTitle: ReactNode = isTabbed ? (\n <>\n {t('documentPreview.multiTitle', 'Documents')}\n <Badge variant=\"neutral\" size=\"sm\">\n {docs.length}\n </Badge>\n </>\n ) : (\n activeDoc?.name\n );\n\n let content: ReactNode;\n if (docs.length === 0) {\n content = (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t('documentPreview.emptyTitle', 'No document selected')}\n description={t(\n 'documentPreview.emptyDescription',\n 'Select a document to preview it here.',\n )}\n />\n );\n } else if (isTabbed) {\n content = (\n <Tabs\n value={activeDoc?.id ?? ''}\n onValueChange={setActiveId}\n variant=\"underlined\"\n size=\"sm\"\n // Each tab shows its full file name when there's room and shrinks with\n // an ellipsis only when the tabs would otherwise overflow the width\n // (`min-inline-size:0` lets a tab shrink below its content; the label\n // truncates). The full name stays the accessible name and shows in the\n // body, so nothing is lost.\n className=\"ds:min-h-0 ds:flex-1 ds:pt-[var(--spacing-sm)]\"\n >\n <TabsList\n aria-label={t('documentPreview.tabsLabel', 'Selected documents')}\n className=\"ds:gap-[var(--spacing-sm)]\"\n >\n {docs.map((doc) => {\n const TabIcon = iconForMime(doc.mimeType);\n return (\n <TabsTrigger\n key={doc.id}\n value={doc.id}\n // Match the header glyph: same 16px size (never larger) and the\n // accent tint that marks a file across the grid and the rail.\n icon={\n <TabIcon\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:text-[color:var(--accent)]\"\n />\n }\n className=\"ds:[min-inline-size:0]\"\n >\n <span className=\"ds:block ds:truncate ds:[min-inline-size:0]\">\n {doc.name}\n </span>\n </TabsTrigger>\n );\n })}\n </TabsList>\n {docs.map((doc) => (\n <TabsContent\n key={doc.id}\n value={doc.id}\n className=\"ds:min-h-0 ds:flex-1\"\n >\n {renderBody(doc)}\n </TabsContent>\n ))}\n </Tabs>\n );\n } else {\n content = renderBody(activeDoc);\n }\n\n return (\n <section\n data-component=\"document-preview\"\n data-component-id={id}\n // The preview body scrolls (PDF pages, tall images, long metadata), so\n // the region needs a keyboard tab stop (axe scrollable-region-focusable).\n // A labelled <section> is a region landmark, which also scopes the\n // PanelHeader's <header> so it is never exposed as a page banner.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- keyboard-focusable scroll region (see comment above)\n tabIndex={0}\n aria-label={t('documentPreview.regionLabel', 'Document preview')}\n className={documentPreviewVariants({ className })}\n >\n {docs.length > 0 && (\n <PanelHeader sticky icon={headerIcon} title={headerTitle} />\n )}\n {content}\n </section>\n );\n});\n\nDocumentPreview.displayName = 'DocumentPreview';\n"],"names":["__iconNode","Files","createLucideIcon","documentPreviewAgent","handle","documentPreviewVariants","cva","SIGNATURE_VARIANT","resolveKind","name","mimeType","src","mime","iconForMime","FileImage","FileText","FileIcon","UNIT_KEYS","UNIT_FALLBACKS","formatBytes","bytes","locale","t","value","unitIndex","DocumentPreview","forwardRef","id","metadata","documents","className","ref","i18n","useTranslation","docs","useMemo","isTabbed","activeId","setActiveId","useState","activeDoc","doc","useImperativeHandle","useAgentRegistration","renderBody","kind","meta","PlaceholderIcon","viewport","jsx","PDFViewer","jsxs","status","hasBadges","fmtDate","iso","rows","hasDetails","Card","Badge","row","Fragment","HeaderMimeIcon","headerIcon","headerTitle","content","EmptyState","Tabs","TabsList","TabIcon","TabsTrigger","TabsContent","PanelHeader"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"document-preview-5xs64jME.js","sources":["../../node_modules/lucide-react/dist/esm/icons/files.mjs","../../src/components/document-preview/document-preview.agent.ts","../../src/components/document-preview/document-preview.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 2h-4a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8\", key: \"14sh0y\" }],\n [\n \"path\",\n {\n d: \"M16.706 2.706A2.4 2.4 0 0 0 15 2v5a1 1 0 0 0 1 1h5a2.4 2.4 0 0 0-.706-1.706z\",\n key: \"1970lx\"\n }\n ],\n [\"path\", { d: \"M5 7a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h8a2 2 0 0 0 1.732-1\", key: \"l4dndm\" }]\n];\nconst Files = createLucideIcon(\"files\", __iconNode);\n\nexport { __iconNode, Files as default };\n//# sourceMappingURL=files.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — DocumentPreview. */\n/* */\n/* A passive, read-only viewer, so it declares no interactive */\n/* capabilities. The always-on state slot carries only the structural */\n/* render `kind` (pdf / image / metadata / empty) — never the document */\n/* name. */\n/* */\n/* PHI rule (PRS §26 §7): the document display name can identify a */\n/* patient (e.g. \"Rossi Maria — referto 2026.pdf\"). It renders as text */\n/* (fine) but the only name-returning read is the deliberate get_name */\n/* action with `safety: 'phi'`, so the host gates it behind confirm + */\n/* audit. No name is ever emitted in a data-* hook. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DocumentPreviewHandle } from './document-preview';\n\nexport const documentPreviewAgent: AgentAdapter<DocumentPreviewHandle> = {\n id: 'document-preview',\n capabilities: [],\n state: {\n kind: {\n type: \"'pdf' | 'image' | 'metadata' | 'empty'\",\n descriptionKey: 'ui.agent.documentPreview.state.kind',\n description:\n 'Which render branch is active: pdf, image, metadata (no inline preview), or empty (no document). Structural — never the document name.',\n read: (handle) => handle.getKind(),\n },\n },\n actions: {\n get_name: {\n // phi (not read): resolves the document display name, which can identify\n // patients. PRS §26 — phi outranks read so the host gates it behind\n // stricter confirm + audit. The always-on kind slot stays name-free.\n safety: 'phi',\n returns: 'string | undefined',\n returnsSchema: { type: ['string', 'null'] },\n idempotent: true,\n descriptionKey: 'ui.agent.documentPreview.actions.getName',\n description:\n 'Read the display name of the previewed document. May identify a patient (PHI).',\n invoke: (handle) => handle.getName(),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'document-preview',\n description: 'Marks the DocumentPreview region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* DocumentPreview — a standalone, reusable document viewer. */\n/* */\n/* Decoupled from FileManager: it takes primitive props (name, mimeType, */\n/* src, metadata) rather than a FileManagerItem, so signing, the patient */\n/* portal, and the Control Room rail can all reuse it. The body is an */\n/* elevated Card: a bounded preview viewport (PDF → kit PDFViewer; */\n/* image/* → <img>; otherwise a MIME-icon placeholder) above an always-on */\n/* Details block (badges + every structural field the host supplies), so */\n/* the metadata is never dropped when a real preview renders. No name → */\n/* EmptyState. */\n/* */\n/* Title lives in the canonical PanelHeader (the same header every rail */\n/* panel adopts) so the Control Room rail can inject its pin / close */\n/* controls into it. Pass `documents` (≥ 2) to preview a SELECTION as */\n/* tabs — one tab per document, the active one shown below; a single */\n/* entry (or the single-document props) renders without a tab strip. */\n/* */\n/* The root is a `<section>` (region landmark) so the PanelHeader's */\n/* <header> is scoped and never exposed as a page banner — the same */\n/* shape RadiographPanel uses. It is also a keyboard-focusable scroll */\n/* region (tabIndex 0 + labelled focus ring). */\n/* */\n/* PHI: the visible name renders as text (fine), but the only */\n/* name-returning handle read is surfaced by document-preview.agent.ts */\n/* as a `safety: 'phi'` action — never in always-on state, never in a */\n/* data-* hook. In tabbed mode the handle reflects the ACTIVE tab. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n Fragment,\n useImperativeHandle,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n File as FileIcon,\n FileImage,\n FileText,\n Files,\n type LucideIcon,\n} from 'lucide-react';\nimport { Badge } from '../badge';\nimport { Card } from '../card';\nimport { EmptyState } from '../empty-state';\nimport { PanelHeader } from '../panel-header';\nimport { PDFViewer } from '../pdf-viewer';\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '../tabs';\nimport { useAgentRegistration } from '../../agent';\nimport { documentPreviewAgent } from './document-preview.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type DocumentPreviewSignatureStatus = 'none' | 'pending' | 'signed';\n\n/** Which render branch DocumentPreview is showing — structural, never PHI. */\nexport type DocumentPreviewKind = 'pdf' | 'image' | 'metadata' | 'empty';\n\nexport interface DocumentPreviewMetadata {\n /** Size in bytes. */\n size?: number;\n /** Display name of whoever created the document (host-supplied). */\n createdBy?: string;\n /** ISO 8601 timestamp the document was created. */\n createdAt?: string;\n /** ISO 8601 timestamp of the last modification. */\n updatedAt?: string;\n /** ISO 8601 timestamp a signature was requested from the patient. */\n signatureRequestedAt?: string;\n /** ISO 8601 timestamp the document was signed. */\n signedAt?: string;\n /** ISO 8601 timestamp the document was shared with the patient. */\n sharedAt?: string;\n /** Open document-type category (non-identifying), e.g. `'xray'`. */\n documentType?: string;\n /** Signature workflow state. */\n signatureStatus?: DocumentPreviewSignatureStatus;\n /** Clinical-document flag (host-defined semantics). */\n clinical?: boolean;\n /** ISO 8601 expiry (e.g. identification documents). */\n expiresAt?: string;\n}\n\n/**\n * A single previewable document. In multi-document mode each becomes a tab;\n * `id` is the tab value (never a patient name) and `name` is the tab label.\n */\nexport interface DocumentPreviewDocument {\n /** Stable, non-identifying id. Emitted as the tab value — never PHI. */\n id: string;\n /** Display name (PHI). Also the tab label in multi-document mode. */\n name: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n}\n\nexport interface DocumentPreviewProps extends VariantProps<\n typeof documentPreviewVariants\n> {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Display name. Absent (and no `documents`) → empty state. PHI. */\n name?: string;\n /** MIME type — drives the render branch and the fallback icon. */\n mimeType?: string;\n /** Resolved URL / data URI for the PDF or image viewer. The host owns auth. */\n src?: string;\n /** Structural metadata rendered by the metadata-card branch. */\n metadata?: DocumentPreviewMetadata;\n /**\n * Multiple documents to preview as tabs — e.g. a multi-row selection. Two\n * or more render a tab per document (label = name) with the active one\n * shown below; a single entry renders without a tab strip. When non-empty\n * this takes precedence over the single-document props. Names are PHI.\n */\n documents?: DocumentPreviewDocument[];\n className?: string;\n}\n\nexport interface DocumentPreviewHandle {\n /** Which render branch is active — structural, safe for always-on reads. */\n getKind: () => DocumentPreviewKind;\n /** The active document's display name (PHI). Surfaced by the adapter as a `phi` action. */\n getName: () => string | undefined;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst documentPreviewVariants = cva(\n [\n 'ds:flex ds:h-full ds:min-h-0 ds:min-w-0 ds:flex-col ds:overflow-auto',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring',\n ].join(' '),\n);\n\nconst SIGNATURE_VARIANT: Record<\n Exclude<DocumentPreviewSignatureStatus, 'none'>,\n 'success' | 'warning'\n> = {\n signed: 'success',\n pending: 'warning',\n};\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction resolveKind(\n name: string | undefined,\n mimeType: string | undefined,\n src: string | undefined,\n): DocumentPreviewKind {\n if (!name) return 'empty';\n const mime = mimeType ?? '';\n if (mime === 'application/pdf' && src) return 'pdf';\n if (mime.startsWith('image/') && src) return 'image';\n return 'metadata';\n}\n\n/** Fallback icon for the header / metadata card — a small MIME-family lookup. */\nfunction iconForMime(mimeType: string | undefined): LucideIcon {\n const mime = mimeType ?? '';\n if (mime.startsWith('image/')) return FileImage;\n if (\n mime === 'application/pdf' ||\n mime.startsWith('text/') ||\n mime.includes('word')\n ) {\n return FileText;\n }\n return FileIcon;\n}\n\nconst UNIT_KEYS = [\n 'documentPreview.units.bytes',\n 'documentPreview.units.kilobytes',\n 'documentPreview.units.megabytes',\n 'documentPreview.units.gigabytes',\n] as const;\n\nconst UNIT_FALLBACKS = ['B', 'KB', 'MB', 'GB'] as const;\n\nfunction formatBytes(\n bytes: number,\n locale: string,\n t: (key: string, fallback: string) => string,\n): string {\n let value = bytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < UNIT_FALLBACKS.length - 1) {\n value /= 1024;\n unitIndex++;\n }\n const formatted = new Intl.NumberFormat(locale, {\n maximumFractionDigits: unitIndex === 0 ? 0 : 1,\n }).format(value);\n return `${formatted} ${t(UNIT_KEYS[unitIndex], UNIT_FALLBACKS[unitIndex])}`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const DocumentPreview = forwardRef<\n DocumentPreviewHandle,\n DocumentPreviewProps\n>(({ id, name, mimeType, src, metadata, documents, className }, ref) => {\n const { t, i18n } = useTranslation('ui');\n\n // Resolve the document list: an explicit `documents` list wins; otherwise\n // the single-document props form a one-item list; nothing → empty. The\n // synthetic single-doc id is never emitted as a tab value (a lone doc\n // renders without a tab strip), so falling back to the name is PHI-safe.\n const docs = useMemo<DocumentPreviewDocument[]>(() => {\n if (documents && documents.length > 0) return documents;\n if (name) return [{ id: id ?? name, name, mimeType, src, metadata }];\n return [];\n }, [documents, id, name, mimeType, src, metadata]);\n\n const isTabbed = docs.length > 1;\n\n // Active tab (multi mode). When the current id is stale after the selection\n // changes we fall back to the first document — no reconciling effect needed.\n const [activeId, setActiveId] = useState<string | undefined>(undefined);\n const activeDoc = docs.find((doc) => doc.id === activeId) ?? docs[0];\n\n const handle = useMemo<DocumentPreviewHandle>(\n () => ({\n getKind: () =>\n activeDoc\n ? resolveKind(activeDoc.name, activeDoc.mimeType, activeDoc.src)\n : 'empty',\n getName: () => activeDoc?.name,\n }),\n [activeDoc],\n );\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(documentPreviewAgent, handle, id);\n\n /* The per-document body — an elevated Card with a bounded preview viewport\n (pdf / image / placeholder) above an always-on Details block. The title is\n NOT rendered here (the PanelHeader owns it, or the tab label in multi mode). */\n const renderBody = (doc: DocumentPreviewDocument): ReactNode => {\n const kind = resolveKind(doc.name, doc.mimeType, doc.src);\n const meta = doc.metadata;\n const PlaceholderIcon = iconForMime(doc.mimeType);\n\n // Preview viewport — the rendered document, or a MIME-icon placeholder when\n // no source resolves. Bounded to a consistent aspect so the Details below\n // stay reachable in the rail.\n let viewport: ReactNode;\n if (kind === 'pdf' && doc.src) {\n viewport = (\n <PDFViewer\n src={doc.src}\n toolbarVariant=\"minimal\"\n // Name the embedded viewer after the document so it stays distinct\n // from the surrounding \"Document preview\" region (nested landmarks\n // must not share an accessible name). Mirrors visible header text.\n ariaLabel={doc.name}\n className=\"ds:h-full ds:w-full\"\n />\n );\n } else if (kind === 'image' && doc.src) {\n viewport = (\n <img\n src={doc.src}\n alt={t('documentPreview.imageAlt', 'Preview of {{name}}', {\n name: doc.name,\n })}\n className=\"ds:max-h-full ds:max-w-full ds:object-contain\"\n />\n );\n } else {\n viewport = (\n <span className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-muted-foreground\">\n <PlaceholderIcon aria-hidden=\"true\" className=\"ds:size-10\" />\n <span className=\"type-body-sm\">\n {t('documentPreview.noPreview', 'No preview available.')}\n </span>\n </span>\n );\n }\n\n // Badges: type / clinical / signature status.\n const status = meta?.signatureStatus;\n const hasBadges =\n Boolean(meta?.documentType) ||\n Boolean(meta?.clinical) ||\n (status !== undefined && status !== 'none');\n\n // Detail rows — every structural field the host supplies, so nothing is\n // dropped when a real preview renders. Only present fields render a row.\n const fmtDate = (iso: string): string =>\n new Intl.DateTimeFormat(i18n.language, { dateStyle: 'medium' }).format(\n new Date(iso),\n );\n const rows: Array<{ key: string; label: string; value: string }> = [];\n if (meta?.createdBy)\n rows.push({\n key: 'createdBy',\n label: t('documentPreview.fields.createdBy', 'Created by'),\n value: meta.createdBy,\n });\n if (meta?.createdAt)\n rows.push({\n key: 'created',\n label: t('documentPreview.fields.created', 'Created'),\n value: fmtDate(meta.createdAt),\n });\n if (meta?.updatedAt)\n rows.push({\n key: 'modified',\n label: t('documentPreview.fields.modified', 'Modified'),\n value: fmtDate(meta.updatedAt),\n });\n if (meta?.signatureRequestedAt)\n rows.push({\n key: 'signatureRequested',\n label: t(\n 'documentPreview.fields.signatureRequested',\n 'Signature requested',\n ),\n value: fmtDate(meta.signatureRequestedAt),\n });\n if (meta?.signedAt)\n rows.push({\n key: 'signed',\n label: t('documentPreview.fields.signed', 'Signed'),\n value: fmtDate(meta.signedAt),\n });\n if (meta?.sharedAt)\n rows.push({\n key: 'sharedWithPatient',\n label: t(\n 'documentPreview.fields.sharedWithPatient',\n 'Shared with patient',\n ),\n value: fmtDate(meta.sharedAt),\n });\n if (meta?.size !== undefined)\n rows.push({\n key: 'size',\n label: t('documentPreview.fields.size', 'Size'),\n value: formatBytes(meta.size, i18n.language, t),\n });\n if (meta?.expiresAt)\n rows.push({\n key: 'expires',\n label: t('documentPreview.fields.expires', 'Expires'),\n value: fmtDate(meta.expiresAt),\n });\n\n const hasDetails = hasBadges || rows.length > 0;\n\n return (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <Card\n variant=\"elevated\"\n className=\"ds:flex ds:flex-col ds:overflow-hidden\"\n >\n <div className=\"ds:flex ds:aspect-[4/3] ds:min-h-0 ds:items-center ds:justify-center ds:overflow-hidden ds:border-b ds:border-[color:var(--card-border)] ds:bg-muted\">\n {viewport}\n </div>\n {hasDetails && (\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <h3 className=\"type-eyebrow ds:m-0 ds:text-muted-foreground\">\n {t('documentPreview.detailsTitle', 'Details')}\n </h3>\n {hasBadges && (\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {meta?.documentType && (\n <Badge variant=\"neutral\" size=\"sm\">\n {meta.documentType}\n </Badge>\n )}\n {meta?.clinical && (\n <Badge variant=\"info\" size=\"sm\">\n {t('documentPreview.clinical', 'Clinical')}\n </Badge>\n )}\n {status && status !== 'none' && (\n <Badge\n variant={SIGNATURE_VARIANT[status]}\n size=\"sm\"\n withDot\n >\n {t(`documentPreview.signature.${status}`, status)}\n </Badge>\n )}\n </span>\n )}\n {rows.length > 0 && (\n <dl className=\"ds:grid ds:grid-cols-[auto_1fr] ds:gap-x-[var(--spacing-md)] ds:gap-y-[var(--spacing-xs)] type-body-sm\">\n {rows.map((row) => (\n <Fragment key={row.key}>\n <dt className=\"ds:text-muted-foreground\">{row.label}</dt>\n <dd className=\"ds:m-0\">{row.value}</dd>\n </Fragment>\n ))}\n </dl>\n )}\n </Card.Body>\n )}\n </Card>\n </div>\n );\n };\n\n // Header: a MIME icon + the document name for a single doc; a Files glyph +\n // a count badge (RadiographPanel's title-plus-badge shape) when tabbed.\n const HeaderMimeIcon = iconForMime(activeDoc?.mimeType);\n const headerIcon = isTabbed ? (\n <Files aria-hidden=\"true\" />\n ) : (\n <HeaderMimeIcon aria-hidden=\"true\" />\n );\n const headerTitle: ReactNode = isTabbed ? (\n <>\n {t('documentPreview.multiTitle', 'Documents')}\n <Badge variant=\"neutral\" size=\"sm\">\n {docs.length}\n </Badge>\n </>\n ) : (\n activeDoc?.name\n );\n\n let content: ReactNode;\n if (docs.length === 0) {\n content = (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t('documentPreview.emptyTitle', 'No document selected')}\n description={t(\n 'documentPreview.emptyDescription',\n 'Select a document to preview it here.',\n )}\n />\n );\n } else if (isTabbed) {\n content = (\n <Tabs\n value={activeDoc?.id ?? ''}\n onValueChange={setActiveId}\n variant=\"underlined\"\n size=\"sm\"\n // Each tab shows its full file name when there's room and shrinks with\n // an ellipsis only when the tabs would otherwise overflow the width\n // (`min-inline-size:0` lets a tab shrink below its content; the label\n // truncates). The full name stays the accessible name and shows in the\n // body, so nothing is lost.\n className=\"ds:min-h-0 ds:flex-1 ds:pt-[var(--spacing-sm)]\"\n >\n <TabsList\n aria-label={t('documentPreview.tabsLabel', 'Selected documents')}\n className=\"ds:gap-[var(--spacing-sm)]\"\n >\n {docs.map((doc) => {\n const TabIcon = iconForMime(doc.mimeType);\n return (\n <TabsTrigger\n key={doc.id}\n value={doc.id}\n // Match the header glyph: same 16px size (never larger) and the\n // accent tint that marks a file across the grid and the rail.\n icon={\n <TabIcon\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:text-[color:var(--accent)]\"\n />\n }\n className=\"ds:[min-inline-size:0]\"\n >\n <span className=\"ds:block ds:truncate ds:[min-inline-size:0]\">\n {doc.name}\n </span>\n </TabsTrigger>\n );\n })}\n </TabsList>\n {docs.map((doc) => (\n <TabsContent\n key={doc.id}\n value={doc.id}\n className=\"ds:min-h-0 ds:flex-1\"\n >\n {renderBody(doc)}\n </TabsContent>\n ))}\n </Tabs>\n );\n } else {\n content = renderBody(activeDoc);\n }\n\n return (\n <section\n data-component=\"document-preview\"\n data-component-id={id}\n // The preview body scrolls (PDF pages, tall images, long metadata), so\n // the region needs a keyboard tab stop (axe scrollable-region-focusable).\n // A labelled <section> is a region landmark, which also scopes the\n // PanelHeader's <header> so it is never exposed as a page banner.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- keyboard-focusable scroll region (see comment above)\n tabIndex={0}\n aria-label={t('documentPreview.regionLabel', 'Document preview')}\n className={documentPreviewVariants({ className })}\n >\n {docs.length > 0 && (\n <PanelHeader sticky icon={headerIcon} title={headerTitle} />\n )}\n {content}\n </section>\n );\n});\n\nDocumentPreview.displayName = 'DocumentPreview';\n"],"names":["__iconNode","Files","createLucideIcon","documentPreviewAgent","handle","documentPreviewVariants","cva","SIGNATURE_VARIANT","resolveKind","name","mimeType","src","mime","iconForMime","FileImage","FileText","FileIcon","UNIT_KEYS","UNIT_FALLBACKS","formatBytes","bytes","locale","t","value","unitIndex","DocumentPreview","forwardRef","id","metadata","documents","className","ref","i18n","useTranslation","docs","useMemo","isTabbed","activeId","setActiveId","useState","activeDoc","doc","useImperativeHandle","useAgentRegistration","renderBody","kind","meta","PlaceholderIcon","viewport","jsx","PDFViewer","jsxs","status","hasBadges","fmtDate","iso","rows","hasDetails","Card","Badge","row","Fragment","HeaderMimeIcon","headerIcon","headerTitle","content","EmptyState","Tabs","TabsList","TabIcon","TabsTrigger","TabsContent","PanelHeader"],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1,156 @@
1
+ import { jsxs as R, jsx as h } from "react/jsx-runtime";
2
+ import { forwardRef as U, useRef as T, useId as W, useState as V, useMemo as g, useEffect as X, useCallback as k } from "react";
3
+ import { useTranslation as Y } from "react-i18next";
4
+ import { i as N } from "./isEmail-BfVspSvV.js";
5
+ import { T as Z } from "./text-input-B6iAgCr3.js";
6
+ import { u as _ } from "./form-field-context-DtiROUJV.js";
7
+ import { c as $ } from "./compose-refs-C0k0tdqF.js";
8
+ import { u as C } from "./registry-DvAUVLHh.js";
9
+ import { C as ee } from "./circle-alert-rGDZ73Wh.js";
10
+ const te = {
11
+ id: "email-input",
12
+ capabilities: [],
13
+ state: {
14
+ value: {
15
+ type: "string",
16
+ descriptionKey: "ui.agent.emailInput.state.value",
17
+ description: "The current email address typed into the field.",
18
+ read: (t) => t.getValue()
19
+ },
20
+ isValid: {
21
+ type: "boolean",
22
+ descriptionKey: "ui.agent.emailInput.state.isValid",
23
+ description: "True when the value is non-empty AND parses as a valid email per RFC 5322.",
24
+ read: (t) => t.isValid()
25
+ }
26
+ },
27
+ actions: {},
28
+ domHooks: {
29
+ root: {
30
+ attr: "data-component",
31
+ value: "email-input",
32
+ description: 'Marks the EmailInput wrapper. The inline error element carries `role="alert"` when validation fails.'
33
+ },
34
+ instanceId: {
35
+ attr: "data-component-id",
36
+ sourceProp: "id",
37
+ description: "Sourced from the id prop, when provided."
38
+ }
39
+ }
40
+ };
41
+ function ie(t) {
42
+ return t.length === 0 ? !0 : N(t);
43
+ }
44
+ const re = U(
45
+ ({
46
+ errorMessage: t,
47
+ onValidityChange: n,
48
+ disableBuiltInValidation: A = !1,
49
+ autoComplete: j = "email",
50
+ value: a,
51
+ defaultValue: d,
52
+ onChange: o,
53
+ onBlur: l,
54
+ id: c,
55
+ "aria-describedby": I,
56
+ "aria-invalid": x,
57
+ ...F
58
+ }, M) => {
59
+ const { t: S } = Y("ui"), u = _(), p = T(null), H = $(M, p), m = W(), r = a !== void 0, [K, O] = V(() => typeof a == "string" ? a : typeof d == "string" ? d : ""), i = r ? String(a) : K, [f, z] = V(
60
+ () => i.length > 0
61
+ ), v = g(
62
+ () => ie(i),
63
+ [i]
64
+ ), D = !A && f && i.length > 0 && !v, y = T(null);
65
+ X(() => {
66
+ if (!f) return;
67
+ const e = i.length > 0 && v;
68
+ y.current !== e && (y.current = e, n == null || n(e));
69
+ }, [f, i, v, n]);
70
+ const P = k(
71
+ (e) => {
72
+ r || O(e.target.value), o == null || o(e);
73
+ },
74
+ [r, o]
75
+ ), q = k(
76
+ (e) => {
77
+ z(!0), l == null || l(e);
78
+ },
79
+ [l]
80
+ ), B = g(
81
+ () => ({
82
+ getValue: () => {
83
+ var e;
84
+ return ((e = p.current) == null ? void 0 : e.value) ?? "";
85
+ },
86
+ isValid: () => {
87
+ var w;
88
+ const e = ((w = p.current) == null ? void 0 : w.value) ?? "";
89
+ return e.length > 0 && N(e);
90
+ }
91
+ }),
92
+ []
93
+ );
94
+ C(te, B, c);
95
+ const s = D && t !== null && !u.invalid, b = u.describedBy || void 0, G = g(() => {
96
+ const e = [
97
+ I,
98
+ b,
99
+ s ? m : null
100
+ ].filter(Boolean);
101
+ return e.length > 0 ? e.join(" ") : void 0;
102
+ }, [
103
+ I,
104
+ b,
105
+ s,
106
+ m
107
+ ]), E = x === !0 || x === "true", J = s || t === null && E ? "error" : "default", L = s || u.invalid || E || void 0, Q = t !== void 0 ? t : S("inputs.email.invalid", "Enter a valid email address.");
108
+ return /* @__PURE__ */ R(
109
+ "div",
110
+ {
111
+ "data-component": "email-input",
112
+ "data-component-id": c,
113
+ className: "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]",
114
+ children: [
115
+ /* @__PURE__ */ h(
116
+ Z,
117
+ {
118
+ ...F,
119
+ ref: H,
120
+ id: c,
121
+ type: "email",
122
+ inputMode: "email",
123
+ autoComplete: j,
124
+ tone: J,
125
+ value: r ? i : void 0,
126
+ defaultValue: r ? void 0 : d,
127
+ onChange: P,
128
+ onBlur: q,
129
+ "aria-invalid": L,
130
+ "aria-describedby": G
131
+ }
132
+ ),
133
+ s ? /* @__PURE__ */ R(
134
+ "p",
135
+ {
136
+ id: m,
137
+ role: "alert",
138
+ "data-slot": "email-input-error",
139
+ className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-destructive",
140
+ children: [
141
+ /* @__PURE__ */ h(ee, { "aria-hidden": "true", className: "ds:size-4 ds:shrink-0" }),
142
+ /* @__PURE__ */ h("span", { children: Q })
143
+ ]
144
+ }
145
+ ) : null
146
+ ]
147
+ }
148
+ );
149
+ }
150
+ );
151
+ re.displayName = "EmailInput";
152
+ export {
153
+ re as E,
154
+ te as e
155
+ };
156
+ //# sourceMappingURL=email-input-DxwbREpx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-input-DxwbREpx.js","sources":["../../src/components/email-input/email-input.agent.ts","../../src/components/email-input/email-input.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — EmailInput. */\n/* */\n/* Presentational specialisation of TextInput — no actions of its own. */\n/* The handle re-exposes the underlying input's value-setter so agents */\n/* can drive the field through the normal TextInput contract without */\n/* needing to know it's wrapped. See `src/docs/26-agent-readiness.mdx` */\n/* for the contract. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\n\n/**\n * Curated agent handle for EmailInput. State stays scoped to the visible\n * value + the kit-derived validity flag; never PHI (per PRS §Security).\n */\nexport interface EmailInputHandle {\n /** Returns the current input value. */\n getValue: () => string;\n /** Returns whether the current value parses as a valid email (non-empty + RFC). */\n isValid: () => boolean;\n}\n\nexport const emailInputAgent: AgentAdapter<EmailInputHandle> = {\n id: 'email-input',\n capabilities: [],\n state: {\n value: {\n type: 'string',\n descriptionKey: 'ui.agent.emailInput.state.value',\n description: 'The current email address typed into the field.',\n read: (handle) => handle.getValue(),\n },\n isValid: {\n type: 'boolean',\n descriptionKey: 'ui.agent.emailInput.state.isValid',\n description:\n 'True when the value is non-empty AND parses as a valid email per RFC 5322.',\n read: (handle) => handle.isValid(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'email-input',\n description:\n 'Marks the EmailInput wrapper. The inline error element carries `role=\"alert\"` when validation fails.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop, when provided.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type FocusEvent,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CircleAlert } from 'lucide-react';\n// Tree-shaken import — pulling `validator/lib/isEmail` instead of the\n// barrel keeps the bundle to ~3 KB. `import { isEmail } from 'validator'`\n// drags in ~50 KB of unused validators.\nimport isEmail from 'validator/lib/isEmail';\nimport { TextInput, type TextInputProps } from '../text-input';\nimport { useFormField } from '../form-field/form-field-context';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useAgentRegistration } from '../../agent';\nimport { emailInputAgent, type EmailInputHandle } from './email-input.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public API */\n/* */\n/* `type`, `inputMode`, and `tone` are baked in — the component decides */\n/* those itself. `autoComplete` is `email` unless a sign-in form asks */\n/* for `username`. `tone` is computed from the */\n/* validation state so consumers can never wedge it into an inconsistent*/\n/* visual signal. */\n/* ------------------------------------------------------------------ */\n\nexport interface EmailInputProps extends Omit<\n TextInputProps,\n 'type' | 'autoComplete' | 'inputMode' | 'tone'\n> {\n /**\n * Override the \"Enter a valid email address.\" error message. When omitted, the\n * translated default `t('inputs.email.invalid')` is used.\n *\n * Pass `null` when the host shows the message itself (a `FormField`\n * `error`, or its own element). The input then never marks itself\n * invalid: it turns red only when the host says so, through the\n * FormField's `error` or `aria-invalid`. `onValidityChange` still fires.\n */\n errorMessage?: ReactNode | null;\n /**\n * Called whenever the validation state flips. `valid` is `true` when\n * the value is non-empty AND parses as a valid email, `false`\n * otherwise. The callback fires on every blur AND on every change\n * after the first blur — never before the user has had a chance to\n * type something.\n */\n onValidityChange?: (valid: boolean) => void;\n /**\n * Skip the built-in validation entirely. The input behaves like a\n * plain `<TextInput type=\"email\">` — useful when the consumer is\n * wiring `FormField`'s `invalid` prop themselves, or running their\n * own schema validation (zod, react-hook-form). Default: `false`.\n */\n disableBuiltInValidation?: boolean;\n /**\n * Autocomplete hint. Default `email`. Use `username` on a sign-in form,\n * where the email is what the account is known by: browsers and\n * password managers pair `username` with `current-password`.\n */\n autoComplete?: 'email' | 'username';\n}\n\n/* ------------------------------------------------------------------ */\n/* Validation engine */\n/* */\n/* Pure helper — empty values are NOT flagged (let `required` handle */\n/* empty separately). Whitespace-only values fall through to validator */\n/* which rejects them as malformed. */\n/* ------------------------------------------------------------------ */\n\nfunction checkValidity(value: string): boolean {\n if (value.length === 0) return true;\n return isEmail(value);\n}\n\nexport const EmailInput = forwardRef<HTMLInputElement, EmailInputProps>(\n (\n {\n errorMessage,\n onValidityChange,\n disableBuiltInValidation = false,\n autoComplete = 'email',\n value,\n defaultValue,\n onChange,\n onBlur,\n id,\n 'aria-describedby': consumerDescribedBy,\n 'aria-invalid': consumerAriaInvalid,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const ctx = useFormField();\n\n const innerRef = useRef<HTMLInputElement | null>(null);\n const composedRef = composeRefs(ref, innerRef);\n\n // An id of its own: the FormField's error element owns `ctx.errorId`.\n const errorElementId = useId();\n\n const isControlled = value !== undefined;\n\n // Seed once from controlled `value` or `defaultValue` so we can\n // validate an already-populated field at mount (e.g. server-side\n // rehydration). Recomputing on prop changes would defeat the React\n // \"defaultValue is initial only\" contract — we read it once via the\n // lazy initialiser and let `currentValue` track every change after.\n const [internalValue, setInternalValue] = useState<string>(() => {\n if (typeof value === 'string') return value;\n if (typeof defaultValue === 'string') return defaultValue;\n return '';\n });\n const currentValue = isControlled ? String(value) : internalValue;\n\n // `touched` flips to `true` on first blur, or immediately if the\n // field is seeded with a non-empty value (consumer is asking us to\n // validate something they already collected).\n const [touched, setTouched] = useState<boolean>(\n () => currentValue.length > 0,\n );\n\n const computedValid = useMemo(\n () => checkValidity(currentValue),\n [currentValue],\n );\n\n // The format fails only when the field has been touched AND the\n // value is non-empty AND the value fails RFC. Empty is always\n // \"not yet invalid\" — `required` covers the empty case separately.\n const formatInvalid =\n !disableBuiltInValidation &&\n touched &&\n currentValue.length > 0 &&\n !computedValid;\n\n // Notify consumers on every validity flip after the first blur.\n // Empty before first blur is reported as `true` so consumers don't\n // light up a \"valid\" indicator prematurely — we only fire after\n // touched so the first emission reflects user intent.\n const lastValidRef = useRef<boolean | null>(null);\n useEffect(() => {\n if (!touched) return;\n // Empty value after touch -> `valid` is `false` because the user\n // emptied a field they were editing. This mirrors the spec note\n // that empty is reported as `false` in `onValidityChange`.\n const nextValid = currentValue.length > 0 && computedValid;\n if (lastValidRef.current !== nextValid) {\n lastValidRef.current = nextValid;\n onValidityChange?.(nextValid);\n }\n }, [touched, currentValue, computedValid, onValidityChange]);\n\n const handleChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalValue(event.target.value);\n }\n onChange?.(event);\n },\n [isControlled, onChange],\n );\n\n const handleBlur = useCallback(\n (event: FocusEvent<HTMLInputElement>) => {\n setTouched(true);\n onBlur?.(event);\n },\n [onBlur],\n );\n\n /* ------------------------------------------------------------------ */\n /* Agent adapter */\n /* ------------------------------------------------------------------ */\n\n // Stable handle — both `getValue` and `isValid` read the live DOM\n // node, so the closure captures no React state. Empty dep array\n // keeps the agent registry from churning on every keystroke.\n const agentHandle = useMemo<EmailInputHandle>(\n () => ({\n getValue: () => innerRef.current?.value ?? '',\n isValid: () => {\n const v = innerRef.current?.value ?? '';\n return v.length > 0 && isEmail(v);\n },\n }),\n [],\n );\n useAgentRegistration(emailInputAgent, agentHandle, id);\n\n /* ------------------------------------------------------------------ */\n /* One message at a time */\n /* */\n /* A FormField `error` wins: its element is already in the context's */\n /* `describedBy`, so the inline message is not rendered beside it. With */\n /* `errorMessage={null}` the host owns the message, so the input never */\n /* looks invalid on its own account, with nothing to say why. */\n /* ------------------------------------------------------------------ */\n\n const showInlineError =\n formatInvalid && errorMessage !== null && !ctx.invalid;\n const contextDescribedBy = ctx.describedBy || undefined;\n const describedBy = useMemo(() => {\n const parts = [\n consumerDescribedBy,\n contextDescribedBy,\n showInlineError ? errorElementId : null,\n ].filter(Boolean) as string[];\n return parts.length > 0 ? parts.join(' ') : undefined;\n }, [\n consumerDescribedBy,\n contextDescribedBy,\n showInlineError,\n errorElementId,\n ]);\n\n // A wrapping consumer may assert invalidity for a BUSINESS reason while the\n // format is fine (e.g. \"already in use\") — honour it on the a11y attribute\n // so it's announced. Visual `tone` stays format-only, except when the\n // host owns the message: then its `aria-invalid` is the only signal.\n const consumerInvalid =\n consumerAriaInvalid === true || consumerAriaInvalid === 'true';\n const hostOwnsMessage = errorMessage === null;\n // The TextInput adds the FormField's own invalid tone.\n const effectiveTone =\n showInlineError || (hostOwnsMessage && consumerInvalid)\n ? 'error'\n : 'default';\n const effectiveAriaInvalid =\n showInlineError || ctx.invalid || consumerInvalid || undefined;\n\n const resolvedErrorMessage =\n errorMessage !== undefined\n ? errorMessage\n : t('inputs.email.invalid', 'Enter a valid email address.');\n\n return (\n <div\n data-component=\"email-input\"\n data-component-id={id}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <TextInput\n {...rest}\n ref={composedRef}\n id={id}\n type=\"email\"\n inputMode=\"email\"\n autoComplete={autoComplete}\n tone={effectiveTone}\n value={isControlled ? currentValue : undefined}\n defaultValue={!isControlled ? defaultValue : undefined}\n onChange={handleChange}\n onBlur={handleBlur}\n aria-invalid={effectiveAriaInvalid}\n aria-describedby={describedBy}\n />\n {showInlineError ? (\n <p\n id={errorElementId}\n role=\"alert\"\n data-slot=\"email-input-error\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-destructive\"\n >\n <CircleAlert aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0\" />\n <span>{resolvedErrorMessage}</span>\n </p>\n ) : null}\n </div>\n );\n },\n);\n\nEmailInput.displayName = 'EmailInput';\n"],"names":["emailInputAgent","handle","checkValidity","value","isEmail","EmailInput","forwardRef","errorMessage","onValidityChange","disableBuiltInValidation","autoComplete","defaultValue","onChange","onBlur","id","consumerDescribedBy","consumerAriaInvalid","rest","ref","t","useTranslation","ctx","useFormField","innerRef","useRef","composedRef","composeRefs","errorElementId","useId","isControlled","internalValue","setInternalValue","useState","currentValue","touched","setTouched","computedValid","useMemo","formatInvalid","lastValidRef","useEffect","nextValid","handleChange","useCallback","event","handleBlur","agentHandle","_a","v","useAgentRegistration","showInlineError","contextDescribedBy","describedBy","parts","consumerInvalid","effectiveTone","effectiveAriaInvalid","resolvedErrorMessage","jsxs","jsx","TextInput","CircleAlert"],"mappings":"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"}
@@ -18,7 +18,7 @@ import { F as Ft } from "./file-text-5yv6r2ls.js";
18
18
  import { F as Tt } from "./file-spreadsheet-DmwyfV4O.js";
19
19
  import { F as At } from "./file-BuG1VMAy.js";
20
20
  import { C as Dt } from "./chevron-right-I9AeSxH2.js";
21
- import { D as Fe } from "./data-table-zXBxFYpJ.js";
21
+ import { D as Fe } from "./data-table-C9idMvs0.js";
22
22
  import { A as Rt, a as It } from "./actions-cell-renderer-BVn3vDTg.js";
23
23
  import { B as $e } from "./badge-BUk4RjTS.js";
24
24
  import { D as Ue } from "./download-CfYKJO_j.js";
@@ -1744,4 +1744,4 @@ export {
1744
1744
  hn as F,
1745
1745
  Gt as f
1746
1746
  };
1747
- //# sourceMappingURL=file-manager-CVxBE4yy.js.map
1747
+ //# sourceMappingURL=file-manager-LG7B_UHB.js.map