@alfadocs/ui-kit-debug 1.96.0 → 1.98.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 (314) hide show
  1. package/dist/_chunks/{address-autocomplete-DR4Xn23Z.js → address-autocomplete-DC-H-MZw.js} +2 -2
  2. package/dist/_chunks/{address-autocomplete-DR4Xn23Z.js.map → address-autocomplete-DC-H-MZw.js.map} +1 -1
  3. package/dist/_chunks/{address-fields-qxQkGwPf.js → address-fields-D5Ije0S2.js} +7 -7
  4. package/dist/_chunks/{address-fields-qxQkGwPf.js.map → address-fields-D5Ije0S2.js.map} +1 -1
  5. package/dist/_chunks/{agenda-card-BhY342MA.js → agenda-card-bRQ4j6U6.js} +2 -2
  6. package/dist/_chunks/{agenda-card-BhY342MA.js.map → agenda-card-bRQ4j6U6.js.map} +1 -1
  7. package/dist/_chunks/{agenda-tray-BmxBGEci.js → agenda-tray-CzE3E8GU.js} +2 -2
  8. package/dist/_chunks/{agenda-tray-BmxBGEci.js.map → agenda-tray-CzE3E8GU.js.map} +1 -1
  9. package/dist/_chunks/{alia-sidebar-ovRX_oti.js → alia-sidebar-B5mu44g2.js} +3 -3
  10. package/dist/_chunks/{alia-sidebar-ovRX_oti.js.map → alia-sidebar-B5mu44g2.js.map} +1 -1
  11. package/dist/_chunks/{anamnesis-summary-rows-CdRUXoaA.js → anamnesis-summary-rows-B9HqOGd7.js} +4 -4
  12. package/dist/_chunks/{anamnesis-summary-rows-CdRUXoaA.js.map → anamnesis-summary-rows-B9HqOGd7.js.map} +1 -1
  13. package/dist/_chunks/{appointment-card-Csx4544A.js → appointment-card-zPr0brha.js} +3 -3
  14. package/dist/_chunks/{appointment-card-Csx4544A.js.map → appointment-card-zPr0brha.js.map} +1 -1
  15. package/dist/_chunks/{appointment-peek-CcDCWb-F.js → appointment-peek-xFTBany4.js} +3 -3
  16. package/dist/_chunks/{appointment-peek-CcDCWb-F.js.map → appointment-peek-xFTBany4.js.map} +1 -1
  17. package/dist/_chunks/{appointment-timeline-DW6FN6u8.js → appointment-timeline-AKkVx9AN.js} +2 -2
  18. package/dist/_chunks/{appointment-timeline-DW6FN6u8.js.map → appointment-timeline-AKkVx9AN.js.map} +1 -1
  19. package/dist/_chunks/{appointment-tray-CZfXwHWz.js → appointment-tray-B8qQBW65.js} +2 -2
  20. package/dist/_chunks/{appointment-tray-CZfXwHWz.js.map → appointment-tray-B8qQBW65.js.map} +1 -1
  21. package/dist/_chunks/{aspect-ratio-DeSNzASA.js → aspect-ratio-B-6cyOpm.js} +13 -13
  22. package/dist/_chunks/aspect-ratio-B-6cyOpm.js.map +1 -0
  23. package/dist/_chunks/{autocomplete-BXMcNoa3.js → autocomplete-D10ydpgi.js} +2 -2
  24. package/dist/_chunks/{autocomplete-BXMcNoa3.js.map → autocomplete-D10ydpgi.js.map} +1 -1
  25. package/dist/_chunks/{avatar-a6042Ox2.js → avatar-BoqdWsNe.js} +2 -2
  26. package/dist/_chunks/avatar-BoqdWsNe.js.map +1 -0
  27. package/dist/_chunks/{balance-badge-cell-DcBmtijD.js → balance-badge-cell-C-Rz616n.js} +3 -3
  28. package/dist/_chunks/{balance-badge-cell-DcBmtijD.js.map → balance-badge-cell-C-Rz616n.js.map} +1 -1
  29. package/dist/_chunks/{breadcrumb-Bn29NCnf.js → breadcrumb-zxa_PNhF.js} +2 -2
  30. package/dist/_chunks/breadcrumb-zxa_PNhF.js.map +1 -0
  31. package/dist/_chunks/{calendar-CmiMS4FJ.js → calendar-DVe5eArk.js} +2 -2
  32. package/dist/_chunks/{calendar-CmiMS4FJ.js.map → calendar-DVe5eArk.js.map} +1 -1
  33. package/dist/_chunks/{calendar-appointment-editor-dialog-BOZ5wk96.js → calendar-appointment-editor-dialog-CUJMnFL7.js} +12 -12
  34. package/dist/_chunks/{calendar-appointment-editor-dialog-BOZ5wk96.js.map → calendar-appointment-editor-dialog-CUJMnFL7.js.map} +1 -1
  35. package/dist/_chunks/{chat-message-LRO_6Ee3.js → chat-message-CkBCAcwn.js} +2 -2
  36. package/dist/_chunks/{chat-message-LRO_6Ee3.js.map → chat-message-CkBCAcwn.js.map} +1 -1
  37. package/dist/_chunks/{city-input-CA59CjnV.js → city-input-DXipzTfZ.js} +3 -3
  38. package/dist/_chunks/{city-input-CA59CjnV.js.map → city-input-DXipzTfZ.js.map} +1 -1
  39. package/dist/_chunks/{clinical-note-card-CWHFnCmY.js → clinical-note-card--juv_ELr.js} +2 -2
  40. package/dist/_chunks/{clinical-note-card-CWHFnCmY.js.map → clinical-note-card--juv_ELr.js.map} +1 -1
  41. package/dist/_chunks/{combobox-D-gpgEDy.js → combobox-duuDRI1t.js} +2 -2
  42. package/dist/_chunks/{combobox-D-gpgEDy.js.map → combobox-duuDRI1t.js.map} +1 -1
  43. package/dist/_chunks/{command-palette-B3dVqm9D.js → command-palette-DxQBU4wH.js} +3 -3
  44. package/dist/_chunks/command-palette-DxQBU4wH.js.map +1 -0
  45. package/dist/_chunks/{contact-profile-card-jBf9U4At.js → contact-profile-card-QPUgGu-t.js} +57 -57
  46. package/dist/_chunks/contact-profile-card-QPUgGu-t.js.map +1 -0
  47. package/dist/_chunks/{copy-field-hgVSc51W.js → copy-field-BaYEDJ9f.js} +24 -24
  48. package/dist/_chunks/copy-field-BaYEDJ9f.js.map +1 -0
  49. package/dist/_chunks/{country-select-BfmX9y5i.js → country-select-CUuGOAoZ.js} +2 -2
  50. package/dist/_chunks/{country-select-BfmX9y5i.js.map → country-select-CUuGOAoZ.js.map} +1 -1
  51. package/dist/_chunks/{data-table-xUDjZS_O.js → data-table-C5uN4ato.js} +10 -8
  52. package/dist/_chunks/data-table-C5uN4ato.js.map +1 -0
  53. package/dist/_chunks/{data-table-tabs-CcgU2lr5.js → data-table-tabs-Db7zToFD.js} +2 -2
  54. package/dist/_chunks/{data-table-tabs-CcgU2lr5.js.map → data-table-tabs-Db7zToFD.js.map} +1 -1
  55. package/dist/_chunks/{dependent-selector-CyNi7M_f.js → dependent-selector-DRN0P0Kr.js} +2 -2
  56. package/dist/_chunks/{dependent-selector-CyNi7M_f.js.map → dependent-selector-DRN0P0Kr.js.map} +1 -1
  57. package/dist/_chunks/{document-preview-DWIQryMW.js → document-preview-U8H6tnDJ.js} +2 -2
  58. package/dist/_chunks/{document-preview-DWIQryMW.js.map → document-preview-U8H6tnDJ.js.map} +1 -1
  59. package/dist/_chunks/{document-scanner-BQP0Rqrt.js → document-scanner-Bf3VUp00.js} +24 -24
  60. package/dist/_chunks/document-scanner-Bf3VUp00.js.map +1 -0
  61. package/dist/_chunks/{editable-currency-cell-renderer-BEaj2NT_.js → editable-currency-cell-renderer-BUdFMh67.js} +2 -2
  62. package/dist/_chunks/{editable-currency-cell-renderer-BEaj2NT_.js.map → editable-currency-cell-renderer-BUdFMh67.js.map} +1 -1
  63. package/dist/_chunks/{email-input-C7THAwh2.js → email-input-BEO3vonE.js} +2 -2
  64. package/dist/_chunks/{email-input-C7THAwh2.js.map → email-input-BEO3vonE.js.map} +1 -1
  65. package/dist/_chunks/{entity-summary-BJdfIsk_.js → entity-summary-B4p8zP1J.js} +2 -2
  66. package/dist/_chunks/{entity-summary-BJdfIsk_.js.map → entity-summary-B4p8zP1J.js.map} +1 -1
  67. package/dist/_chunks/{face-scheme-BmygzbZr.js → face-scheme-DdVLQ5dP.js} +3 -3
  68. package/dist/_chunks/{face-scheme-BmygzbZr.js.map → face-scheme-DdVLQ5dP.js.map} +1 -1
  69. package/dist/_chunks/{file-manager-Ba_TcfCj.js → file-manager-CnGBVX_q.js} +4 -4
  70. package/dist/_chunks/{file-manager-Ba_TcfCj.js.map → file-manager-CnGBVX_q.js.map} +1 -1
  71. package/dist/_chunks/{fiscal-code-input-BzWmNDnl.js → fiscal-code-input-BBvU7sAo.js} +2 -2
  72. package/dist/_chunks/{fiscal-code-input-BzWmNDnl.js.map → fiscal-code-input-BBvU7sAo.js.map} +1 -1
  73. package/dist/_chunks/{forgot-password-form-BCk4rGIh.js → forgot-password-form-CeTb5p-x.js} +2 -2
  74. package/dist/_chunks/{forgot-password-form-BCk4rGIh.js.map → forgot-password-form-CeTb5p-x.js.map} +1 -1
  75. package/dist/_chunks/{header-settings-C2D74i4g.js → header-settings-Df9q1uHt.js} +2 -2
  76. package/dist/_chunks/{header-settings-C2D74i4g.js.map → header-settings-Df9q1uHt.js.map} +1 -1
  77. package/dist/_chunks/{heatmap-C9tEvqEm.js → heatmap-Cz0Krieg.js} +666 -650
  78. package/dist/_chunks/{heatmap-C9tEvqEm.js.map → heatmap-Cz0Krieg.js.map} +1 -1
  79. package/dist/_chunks/{help-me-write-templates-BJSf24xS.js → help-me-write-templates-ra5a__Yy.js} +2 -2
  80. package/dist/_chunks/{help-me-write-templates-BJSf24xS.js.map → help-me-write-templates-ra5a__Yy.js.map} +1 -1
  81. package/dist/_chunks/{iban-input-B9L2QDHh.js → iban-input-DuTwKok5.js} +2 -2
  82. package/dist/_chunks/{iban-input-B9L2QDHh.js.map → iban-input-DuTwKok5.js.map} +1 -1
  83. package/dist/_chunks/{icon-picker-DQMG9L6M.js → icon-picker-BmU6gpZT.js} +2 -2
  84. package/dist/_chunks/{icon-picker-DQMG9L6M.js.map → icon-picker-BmU6gpZT.js.map} +1 -1
  85. package/dist/_chunks/{info-tip-Do3RFt60.js → info-tip-CG-DEfkd.js} +106 -93
  86. package/dist/_chunks/info-tip-CG-DEfkd.js.map +1 -0
  87. package/dist/_chunks/{input-surface-iBmxVBfr.js → input-surface-BMffm2Vd.js} +4 -4
  88. package/dist/_chunks/{input-surface-iBmxVBfr.js.map → input-surface-BMffm2Vd.js.map} +1 -1
  89. package/dist/_chunks/{link-cell-renderer-OmvrkUeN.js → link-cell-renderer-DKMgD-2v.js} +4 -4
  90. package/dist/_chunks/{link-cell-renderer-OmvrkUeN.js.map → link-cell-renderer-DKMgD-2v.js.map} +1 -1
  91. package/dist/_chunks/{locale-picker-B1NAHW4U.js → locale-picker-C86h8Yt1.js} +2 -2
  92. package/dist/_chunks/{locale-picker-B1NAHW4U.js.map → locale-picker-C86h8Yt1.js.map} +1 -1
  93. package/dist/_chunks/{login-dev-card-DcfcFJrm.js → login-dev-card-D5BV5j1i.js} +4 -4
  94. package/dist/_chunks/{login-dev-card-DcfcFJrm.js.map → login-dev-card-D5BV5j1i.js.map} +1 -1
  95. package/dist/_chunks/{map-view--c9bJDRw.js → map-view-V7etHnyF.js} +2 -2
  96. package/dist/_chunks/map-view-V7etHnyF.js.map +1 -0
  97. package/dist/_chunks/{marketplace-app-shell-DDZI-uBl.js → marketplace-app-shell-D2qgIuXX.js} +4 -4
  98. package/dist/_chunks/{marketplace-app-shell-DDZI-uBl.js.map → marketplace-app-shell-D2qgIuXX.js.map} +1 -1
  99. package/dist/_chunks/{message-card-B6SduXJv.js → message-card-BzJEITml.js} +2 -2
  100. package/dist/_chunks/{message-card-B6SduXJv.js.map → message-card-BzJEITml.js.map} +1 -1
  101. package/dist/_chunks/{message-tray-18_TrLCy.js → message-tray-DiPgJbOb.js} +2 -2
  102. package/dist/_chunks/{message-tray-18_TrLCy.js.map → message-tray-DiPgJbOb.js.map} +1 -1
  103. package/dist/_chunks/{multi-select-i5MFRpXg.js → multi-select-Df3R8lv_.js} +30 -30
  104. package/dist/_chunks/multi-select-Df3R8lv_.js.map +1 -0
  105. package/dist/_chunks/{navigation-menu-DbaSlvdO.js → navigation-menu-1MrpIVkY.js} +3 -3
  106. package/dist/_chunks/navigation-menu-1MrpIVkY.js.map +1 -0
  107. package/dist/_chunks/{notes-panel-DfjF83IK.js → notes-panel-BbNLYcdv.js} +3 -3
  108. package/dist/_chunks/{notes-panel-DfjF83IK.js.map → notes-panel-BbNLYcdv.js.map} +1 -1
  109. package/dist/_chunks/{operator-hero-N_ziNGFF.js → operator-hero-BcuPTzS_.js} +2 -2
  110. package/dist/_chunks/{operator-hero-N_ziNGFF.js.map → operator-hero-BcuPTzS_.js.map} +1 -1
  111. package/dist/_chunks/{pagination-DvKGrsXu.js → pagination-C7N_NiRN.js} +2 -2
  112. package/dist/_chunks/{pagination-DvKGrsXu.js.map → pagination-C7N_NiRN.js.map} +1 -1
  113. package/dist/_chunks/{password-input-BokZ_rnT.js → password-input-SJGHFdOO.js} +2 -2
  114. package/dist/_chunks/{password-input-BokZ_rnT.js.map → password-input-SJGHFdOO.js.map} +1 -1
  115. package/dist/_chunks/{patient-details-DGHkAErB.js → patient-details-DoIOWP6j.js} +3 -3
  116. package/dist/_chunks/{patient-details-DGHkAErB.js.map → patient-details-DoIOWP6j.js.map} +1 -1
  117. package/dist/_chunks/{patient-field-row-BVK4y98C.js → patient-field-row--dCDO5oB.js} +9 -9
  118. package/dist/_chunks/{patient-field-row-BVK4y98C.js.map → patient-field-row--dCDO5oB.js.map} +1 -1
  119. package/dist/_chunks/{patient-search-CL6dtBIq.js → patient-search-DJy0IZSx.js} +2 -2
  120. package/dist/_chunks/{patient-search-CL6dtBIq.js.map → patient-search-DJy0IZSx.js.map} +1 -1
  121. package/dist/_chunks/{patient-summary-card-DXz07c2X.js → patient-summary-card-CL04aq8h.js} +3 -3
  122. package/dist/_chunks/{patient-summary-card-DXz07c2X.js.map → patient-summary-card-CL04aq8h.js.map} +1 -1
  123. package/dist/_chunks/{payment-automation-upsell-CZk6f8aK.js → payment-automation-upsell-BPF0c-5D.js} +2 -2
  124. package/dist/_chunks/{payment-automation-upsell-CZk6f8aK.js.map → payment-automation-upsell-BPF0c-5D.js.map} +1 -1
  125. package/dist/_chunks/{pdf-viewer-gAsNUsA8.js → pdf-viewer-DlceXkfW.js} +267 -286
  126. package/dist/_chunks/pdf-viewer-DlceXkfW.js.map +1 -0
  127. package/dist/_chunks/{phone-input-DJ4BN8tG.js → phone-input-BL8Sj6OG.js} +3 -3
  128. package/dist/_chunks/phone-input-BL8Sj6OG.js.map +1 -0
  129. package/dist/_chunks/{postal-code-input-CfZOnIkW.js → postal-code-input-dJdSAVkP.js} +2 -2
  130. package/dist/_chunks/{postal-code-input-CfZOnIkW.js.map → postal-code-input-dJdSAVkP.js.map} +1 -1
  131. package/dist/_chunks/{practice-profile-hero-DKmnB-M0.js → practice-profile-hero-B8vykoci.js} +2 -2
  132. package/dist/_chunks/{practice-profile-hero-DKmnB-M0.js.map → practice-profile-hero-B8vykoci.js.map} +1 -1
  133. package/dist/_chunks/{practice-results-ZOVlrb43.js → practice-results-U-5kpnJa.js} +3 -3
  134. package/dist/_chunks/{practice-results-ZOVlrb43.js.map → practice-results-U-5kpnJa.js.map} +1 -1
  135. package/dist/_chunks/{province-select-D64whw0m.js → province-select-cVOlwEc5.js} +2 -2
  136. package/dist/_chunks/{province-select-D64whw0m.js.map → province-select-cVOlwEc5.js.map} +1 -1
  137. package/dist/_chunks/{public-footer-BiPiU_lk.js → public-footer-t6gx6sjn.js} +163 -152
  138. package/dist/_chunks/public-footer-t6gx6sjn.js.map +1 -0
  139. package/dist/_chunks/{registration-form-K4j2tdLt.js → registration-form-JzzTomhd.js} +5 -5
  140. package/dist/_chunks/{registration-form-K4j2tdLt.js.map → registration-form-JzzTomhd.js.map} +1 -1
  141. package/dist/_chunks/{reserved.agent-TRbKB39d.js → reserved.agent-CB-92Vi9.js} +8 -8
  142. package/dist/_chunks/{reserved.agent-TRbKB39d.js.map → reserved.agent-CB-92Vi9.js.map} +1 -1
  143. package/dist/_chunks/{reset-password-form-C6XLV7SI.js → reset-password-form-DDdGEoIL.js} +3 -3
  144. package/dist/_chunks/{reset-password-form-C6XLV7SI.js.map → reset-password-form-DDdGEoIL.js.map} +1 -1
  145. package/dist/_chunks/{rich-text-editor-CJfT08It.js → rich-text-editor-F04przIt.js} +2 -2
  146. package/dist/_chunks/{rich-text-editor-CJfT08It.js.map → rich-text-editor-F04przIt.js.map} +1 -1
  147. package/dist/_chunks/{search-bar-mA4bPe3t.js → search-bar-CQ9_V3EJ.js} +2 -2
  148. package/dist/_chunks/{search-bar-mA4bPe3t.js.map → search-bar-CQ9_V3EJ.js.map} +1 -1
  149. package/dist/_chunks/{search-input-BAlDd05M.js → search-input-CRAMo1CA.js} +2 -2
  150. package/dist/_chunks/{search-input-BAlDd05M.js.map → search-input-CRAMo1CA.js.map} +1 -1
  151. package/dist/_chunks/{send-registration-link-form-yLSfcaPk.js → send-registration-link-form-DHCQpA4C.js} +3 -3
  152. package/dist/_chunks/{send-registration-link-form-yLSfcaPk.js.map → send-registration-link-form-DHCQpA4C.js.map} +1 -1
  153. package/dist/_chunks/{sidebar-BS24EnYd.js → sidebar-2VsPlNkZ.js} +3 -3
  154. package/dist/_chunks/sidebar-2VsPlNkZ.js.map +1 -0
  155. package/dist/_chunks/{sign-document-BiOTs1P4.js → sign-document-B5qZhthO.js} +10 -10
  156. package/dist/_chunks/sign-document-B5qZhthO.js.map +1 -0
  157. package/dist/_chunks/{signature-capture-Chqh62Pc.js → signature-capture-BJc7kfqi.js} +2 -2
  158. package/dist/_chunks/signature-capture-BJc7kfqi.js.map +1 -0
  159. package/dist/_chunks/{signature-field-Y01UB5DA.js → signature-field-DjabvRZm.js} +28 -34
  160. package/dist/_chunks/{signature-field-Y01UB5DA.js.map → signature-field-DjabvRZm.js.map} +1 -1
  161. package/dist/_chunks/{signature-request-CLtMgQKi.js → signature-request-CQ0torGq.js} +2 -2
  162. package/dist/_chunks/{signature-request-CLtMgQKi.js.map → signature-request-CQ0torGq.js.map} +1 -1
  163. package/dist/_chunks/{signed-out-frame-CRwVTCjY.js → signed-out-frame-BcQE00H1.js} +2 -2
  164. package/dist/_chunks/{signed-out-frame-CRwVTCjY.js.map → signed-out-frame-BcQE00H1.js.map} +1 -1
  165. package/dist/_chunks/{stat-Dno2ZihS.js → stat-BFKZV50y.js} +137 -117
  166. package/dist/_chunks/stat-BFKZV50y.js.map +1 -0
  167. package/dist/_chunks/{state-backed-text-input-Cgh4ms3p.js → state-backed-text-input-DVETOhSS.js} +2 -2
  168. package/dist/_chunks/{state-backed-text-input-Cgh4ms3p.js.map → state-backed-text-input-DVETOhSS.js.map} +1 -1
  169. package/dist/_chunks/{stepper-accordion-DDTSOUHc.js → stepper-accordion-CYjrmRte.js} +44 -44
  170. package/dist/_chunks/stepper-accordion-CYjrmRte.js.map +1 -0
  171. package/dist/_chunks/{task-editor-qXfMbHsy.js → task-editor-BiPGFXtB.js} +3 -3
  172. package/dist/_chunks/{task-editor-qXfMbHsy.js.map → task-editor-BiPGFXtB.js.map} +1 -1
  173. package/dist/_chunks/{text-input-CaG9ApoE.js → text-input-B6iAgCr3.js} +2 -2
  174. package/dist/_chunks/{text-input-CaG9ApoE.js.map → text-input-B6iAgCr3.js.map} +1 -1
  175. package/dist/_chunks/{timeline-B32dylRJ.js → timeline-tn5QQJdS.js} +2 -2
  176. package/dist/_chunks/{timeline-B32dylRJ.js.map → timeline-tn5QQJdS.js.map} +1 -1
  177. package/dist/_chunks/{transcript-panel-CoHHpcFg.js → transcript-panel-A781Pkzr.js} +2 -2
  178. package/dist/_chunks/{transcript-panel-CoHHpcFg.js.map → transcript-panel-A781Pkzr.js.map} +1 -1
  179. package/dist/_chunks/{use-appointment-details-read-UXXvBeGZ.js → use-appointment-details-read-BbIoPWO6.js} +5 -5
  180. package/dist/_chunks/{use-appointment-details-read-UXXvBeGZ.js.map → use-appointment-details-read-BbIoPWO6.js.map} +1 -1
  181. package/dist/_chunks/{widget-picker-B9HpT2Tb.js → widget-picker-DNYIqRT1.js} +2 -2
  182. package/dist/_chunks/{widget-picker-B9HpT2Tb.js.map → widget-picker-DNYIqRT1.js.map} +1 -1
  183. package/dist/_chunks/{workflow-map-flsvqQ3L.js → workflow-map-k-dQkpe7.js} +20 -20
  184. package/dist/_chunks/{workflow-map-flsvqQ3L.js.map → workflow-map-k-dQkpe7.js.map} +1 -1
  185. package/dist/_chunks/{workflow-status-HQ6ziE46.js → workflow-status-9wb7iWUd.js} +2 -2
  186. package/dist/_chunks/{workflow-status-HQ6ziE46.js.map → workflow-status-9wb7iWUd.js.map} +1 -1
  187. package/dist/_chunks/{workflow-webhook-action-BD-6UyOs.js → workflow-webhook-action-B_52rH7O.js} +3 -3
  188. package/dist/_chunks/{workflow-webhook-action-BD-6UyOs.js.map → workflow-webhook-action-B_52rH7O.js.map} +1 -1
  189. package/dist/ag-grid.css +4 -3
  190. package/dist/agent-catalog.json +1 -1
  191. package/dist/components/_shared/input-surface.d.ts +3 -3
  192. package/dist/components/address-autocomplete/index.js +1 -1
  193. package/dist/components/address-fields/index.js +1 -1
  194. package/dist/components/agenda-card/index.js +1 -1
  195. package/dist/components/agenda-tray/index.js +1 -1
  196. package/dist/components/appointment-card/index.js +2 -2
  197. package/dist/components/appointment-details-panel/index.js +1 -1
  198. package/dist/components/appointment-peek/index.js +1 -1
  199. package/dist/components/appointment-timeline/index.js +1 -1
  200. package/dist/components/aspect-ratio/index.js +1 -1
  201. package/dist/components/autocomplete/index.js +1 -1
  202. package/dist/components/avatar/index.js +1 -1
  203. package/dist/components/booking/index.js +1 -1
  204. package/dist/components/breadcrumb/index.js +1 -1
  205. package/dist/components/calendar/index.js +1 -1
  206. package/dist/components/chat-message/index.js +1 -1
  207. package/dist/components/city-input/index.js +1 -1
  208. package/dist/components/clinical-note-card/index.js +1 -1
  209. package/dist/components/combobox/index.js +1 -1
  210. package/dist/components/command-palette/index.js +1 -1
  211. package/dist/components/contact-profile-card/index.js +1 -1
  212. package/dist/components/copy-field/index.js +1 -1
  213. package/dist/components/country-select/index.js +1 -1
  214. package/dist/components/data-table/index.js +3 -3
  215. package/dist/components/data-table/toolbar.d.ts +1 -0
  216. package/dist/components/data-table/toolbar.d.ts.map +1 -1
  217. package/dist/components/data-table-tabs/index.js +1 -1
  218. package/dist/components/dependent-selector/index.js +1 -1
  219. package/dist/components/document-preview/index.js +1 -1
  220. package/dist/components/document-scanner/index.js +1 -1
  221. package/dist/components/email-input/index.js +1 -1
  222. package/dist/components/entity-summary/index.js +1 -1
  223. package/dist/components/face-scheme/index.js +1 -1
  224. package/dist/components/file-manager/index.js +1 -1
  225. package/dist/components/fiscal-code-input/index.js +1 -1
  226. package/dist/components/header-settings/index.js +1 -1
  227. package/dist/components/heatmap/heatmap-table-view.d.ts.map +1 -1
  228. package/dist/components/heatmap/index.js +1 -1
  229. package/dist/components/iban-input/index.js +1 -1
  230. package/dist/components/icon-picker/index.js +1 -1
  231. package/dist/components/info-tip/index.js +1 -1
  232. package/dist/components/info-tip/info-tip.d.ts +2 -1
  233. package/dist/components/info-tip/info-tip.d.ts.map +1 -1
  234. package/dist/components/locale-picker/index.js +1 -1
  235. package/dist/components/map-view/index.js +1 -1
  236. package/dist/components/message-card/index.js +1 -1
  237. package/dist/components/message-tray/index.js +1 -1
  238. package/dist/components/multi-select/index.js +1 -1
  239. package/dist/components/navigation-menu/index.js +1 -1
  240. package/dist/components/notes-panel/index.js +1 -1
  241. package/dist/components/operator-hero/index.js +1 -1
  242. package/dist/components/pagination/index.js +1 -1
  243. package/dist/components/password-input/index.js +1 -1
  244. package/dist/components/patient-details/index.js +1 -1
  245. package/dist/components/patient-search/index.js +1 -1
  246. package/dist/components/patient-summary-card/index.js +1 -1
  247. package/dist/components/patient-table/index.js +1 -1
  248. package/dist/components/pdf-viewer/index.js +1 -1
  249. package/dist/components/pdf-viewer/pdf-viewer.d.ts.map +1 -1
  250. package/dist/components/phone-input/index.js +1 -1
  251. package/dist/components/postal-code-input/index.js +1 -1
  252. package/dist/components/practice-profile-hero/index.js +1 -1
  253. package/dist/components/practice-results/index.js +1 -1
  254. package/dist/components/province-select/index.js +1 -1
  255. package/dist/components/public-footer/index.js +1 -1
  256. package/dist/components/public-footer/public-footer.d.ts.map +1 -1
  257. package/dist/components/rich-text-editor/index.js +1 -1
  258. package/dist/components/search-bar/index.js +1 -1
  259. package/dist/components/search-input/index.js +1 -1
  260. package/dist/components/sidebar/index.js +1 -1
  261. package/dist/components/sign-document/index.js +1 -1
  262. package/dist/components/signature-capture/index.js +1 -1
  263. package/dist/components/signature-field/index.js +1 -1
  264. package/dist/components/signature-field/signature-field.d.ts.map +1 -1
  265. package/dist/components/stat/index.js +1 -1
  266. package/dist/components/stat/stat.d.ts +8 -0
  267. package/dist/components/stat/stat.d.ts.map +1 -1
  268. package/dist/components/stepper-accordion/index.js +1 -1
  269. package/dist/components/task-editor/index.js +1 -1
  270. package/dist/components/text-input/index.js +1 -1
  271. package/dist/components/timeline/index.js +1 -1
  272. package/dist/components/transcript-panel/index.js +1 -1
  273. package/dist/components/widget-picker/index.js +1 -1
  274. package/dist/components/workflow/index.js +1 -1
  275. package/dist/components/workflow-status/index.js +1 -1
  276. package/dist/core.css +1 -1
  277. package/dist/host-compat.css +13 -1
  278. package/dist/index.js +89 -89
  279. package/dist/patterns/alia-assistant/index.js +1 -1
  280. package/dist/patterns/anamnesis/index.js +1 -1
  281. package/dist/patterns/calendar/index.js +1 -1
  282. package/dist/patterns/forgot-password-form/index.js +1 -1
  283. package/dist/patterns/help-me-write-templates/index.js +1 -1
  284. package/dist/patterns/login-form/index.js +1 -1
  285. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  286. package/dist/patterns/payment-automation-upsell/index.js +1 -1
  287. package/dist/patterns/registration-form/index.js +1 -1
  288. package/dist/patterns/reset-password-form/index.js +1 -1
  289. package/dist/patterns/send-registration-link-form/index.js +1 -1
  290. package/dist/patterns/signature-request/index.js +1 -1
  291. package/dist/patterns/signed-out-frame/index.js +1 -1
  292. package/dist/patterns/workflow-webhook-action/index.js +1 -1
  293. package/dist/tokens.css +5 -4
  294. package/package.json +1 -1
  295. package/dist/_chunks/aspect-ratio-DeSNzASA.js.map +0 -1
  296. package/dist/_chunks/avatar-a6042Ox2.js.map +0 -1
  297. package/dist/_chunks/breadcrumb-Bn29NCnf.js.map +0 -1
  298. package/dist/_chunks/command-palette-B3dVqm9D.js.map +0 -1
  299. package/dist/_chunks/contact-profile-card-jBf9U4At.js.map +0 -1
  300. package/dist/_chunks/copy-field-hgVSc51W.js.map +0 -1
  301. package/dist/_chunks/data-table-xUDjZS_O.js.map +0 -1
  302. package/dist/_chunks/document-scanner-BQP0Rqrt.js.map +0 -1
  303. package/dist/_chunks/info-tip-Do3RFt60.js.map +0 -1
  304. package/dist/_chunks/map-view--c9bJDRw.js.map +0 -1
  305. package/dist/_chunks/multi-select-i5MFRpXg.js.map +0 -1
  306. package/dist/_chunks/navigation-menu-DbaSlvdO.js.map +0 -1
  307. package/dist/_chunks/pdf-viewer-gAsNUsA8.js.map +0 -1
  308. package/dist/_chunks/phone-input-DJ4BN8tG.js.map +0 -1
  309. package/dist/_chunks/public-footer-BiPiU_lk.js.map +0 -1
  310. package/dist/_chunks/sidebar-BS24EnYd.js.map +0 -1
  311. package/dist/_chunks/sign-document-BiOTs1P4.js.map +0 -1
  312. package/dist/_chunks/signature-capture-Chqh62Pc.js.map +0 -1
  313. package/dist/_chunks/stat-Dno2ZihS.js.map +0 -1
  314. package/dist/_chunks/stepper-accordion-DDTSOUHc.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"document-scanner-BQP0Rqrt.js","sources":["../../src/components/document-scanner/document-scanner.agent.ts","../../src/components/document-scanner/document-scanner.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — DocumentScanner. */\n/* */\n/* State exposes only structural lifecycle info — never the captured */\n/* image bytes (PHI). Actions drive the camera + capture flow. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DocumentScannerHandle } from './document-scanner';\n\nexport const documentScannerAgent: AgentAdapter<DocumentScannerHandle> = {\n id: 'document-scanner',\n capabilities: ['capture', 'submit'],\n state: {\n hasCapture: {\n type: 'boolean',\n descriptionKey: 'documentScanner.agent.state.hasCapture',\n description: 'True when a captured or uploaded image is available.',\n read: (handle) => handle.hasCapture(),\n },\n phase: {\n type: 'string',\n descriptionKey: 'documentScanner.agent.state.phase',\n description:\n \"Lifecycle phase: 'idle' | 'requesting' | 'streaming' | 'captured' | 'error'.\",\n read: (handle) => handle.getPhase(),\n },\n },\n actions: {\n start_camera: {\n safety: 'write',\n idempotent: true,\n descriptionKey: 'documentScanner.agent.actions.startCamera',\n description: 'Request camera permission and begin the live viewfinder.',\n errors: [\n 'permission-denied',\n 'no-camera',\n 'not-readable',\n 'insecure-context',\n ],\n invoke: (handle) => handle.startCamera(),\n },\n capture: {\n safety: 'write',\n descriptionKey: 'documentScanner.agent.actions.capture',\n description: 'Freeze the current viewfinder frame as a captured image.',\n errors: ['capture-failed'],\n invoke: (handle) => handle.capture(),\n },\n submit: {\n safety: 'write',\n descriptionKey: 'documentScanner.agent.actions.confirm',\n description: 'Confirm the current capture, emitting it via onConfirm.',\n invoke: (handle) => {\n handle.confirm();\n },\n },\n retake: {\n safety: 'destructive',\n descriptionKey: 'documentScanner.agent.actions.retake',\n description:\n 'Discard the current capture and return to the capture path.',\n invoke: (handle) => {\n handle.retake();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'document-scanner',\n description: 'Marks the DocumentScanner wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* DocumentScanner — patient check-in ID-document capture. */\n/* */\n/* - Native MediaDevices: a live <video autoplay playsinline muted> */\n/* viewfinder via getUserMedia({ video: { facingMode } }), an */\n/* offscreen <canvas> for the freeze-frame / crop draw, and an <img> */\n/* for the captured preview. No third-party dependency for capture. */\n/* - Upload fallback: the existing kit FileUpload (variant='button') */\n/* handles accept / maxSize / reject and is ALWAYS reachable — even */\n/* on a hard camera error it is the recovery path (per HTP-5113). */\n/* - Lifecycle: the camera starts only on an explicit user gesture and */\n/* every MediaStreamTrack is stopped on unmount, on capture, on */\n/* error, on Escape, and on document visibilitychange→hidden so the */\n/* camera LED is released (privacy + battery). Mirrors */\n/* audio-recorder's teardown pattern. */\n/* - Confirm payload: { dataUrl, blob, source, width, height, mimeType, */\n/* byteSize, capturedAt (ISO-8601), sha256 }. sha256 is the */\n/* SubtleCrypto digest of the encoded bytes — tamper-evident for */\n/* audit, matching signature-capture. Document-only: no selfie, no */\n/* liveness, no OCR / MRZ / auto-crop (out of scope, would need a */\n/* separate 08-third-party dependency). */\n/* - Security: no fetch / XHR / localStorage / sessionStorage / globals */\n/* in this file — the captured ID document is PHI and the consumer */\n/* owns persistence + the \"already on file → skip\" decision. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Camera, RotateCcw, Check, LoaderCircle } from 'lucide-react';\nimport { Button } from '../button';\nimport { Alert } from '../alert';\nimport { FileUpload, type FileUploadRejection } from '../file-upload';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { documentScannerAgent } from './document-scanner.agent';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type DocumentScannerSource = 'camera' | 'upload';\n\nexport interface DocumentCapture {\n /** Data URL of the captured / uploaded image (encoded to `mimeType`). */\n dataUrl: string;\n /** Encoded bytes as a Blob — the consumer persists this. */\n blob: Blob;\n /** Where the image came from. */\n source: DocumentScannerSource;\n /** Intrinsic pixel width of the encoded image. */\n width: number;\n /** Intrinsic pixel height of the encoded image. */\n height: number;\n /** MIME of the encoded image. */\n mimeType: string;\n /** Encoded byte size. */\n byteSize: number;\n /** ISO-8601 UTC timestamp for when the capture was confirmed. */\n capturedAt: string;\n /** Hex-encoded SHA-256 digest of the encoded bytes. */\n sha256: string;\n}\n\nexport type DocumentScannerErrorKind =\n | 'permission-denied'\n | 'no-camera'\n | 'not-readable'\n | 'insecure-context'\n | 'capture-failed'\n | 'file-invalid-type'\n | 'file-too-large';\n\nexport interface DocumentScannerError {\n kind: DocumentScannerErrorKind;\n}\n\nexport type DocumentType = 'tessera-sanitaria' | 'cie' | 'id-card' | 'generic';\n\nexport type DocumentScannerPhase =\n | 'idle'\n | 'requesting'\n | 'streaming'\n | 'captured'\n | 'error';\n\n/** Curated imperative handle for agent / external automation. */\nexport interface DocumentScannerHandle {\n /** True when a captured or uploaded image is held. */\n hasCapture: () => boolean;\n /** Current lifecycle phase. */\n getPhase: () => DocumentScannerPhase;\n /** Request the camera and begin the viewfinder. */\n startCamera: () => Promise<void> | void;\n /** Freeze the current viewfinder frame. */\n capture: () => Promise<void> | void;\n /** Confirm the current capture, firing `onConfirm`. */\n confirm: () => void;\n /** Discard the current capture and return to the capture path. */\n retake: () => void;\n}\n\nexport interface DocumentScannerProps {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Controlled captured-image value. When defined the component is controlled. */\n value?: DocumentCapture | null;\n /** Initial captured image for uncontrolled use; seeds the `captured` preview. */\n defaultValue?: DocumentCapture | null;\n /** Fired when the user confirms a captured or uploaded image. */\n onConfirm?: (capture: DocumentCapture) => void;\n /** Fired when the user discards the current capture to retake / re-upload. */\n onRetake?: () => void;\n /** Fired on a permission / hardware / decode failure (telemetry). */\n onError?: (error: DocumentScannerError) => void;\n /** Drives the overlay frame aspect ratio + the translated hint copy. */\n documentType?: DocumentType;\n /** Camera-vs-upload strategy. `auto` falls back to upload on camera failure. */\n captureMode?: 'auto' | 'camera-only' | 'upload-only';\n /** react-dropzone accept map for the upload fallback. */\n accept?: Record<string, string[]>;\n /** Max upload byte size. Defaults to 10MB. */\n maxSize?: number;\n /** Camera to request. Defaults to the rear (`environment`) camera. */\n facingMode?: 'environment' | 'user';\n /** MIME of the encoded capture. */\n outputType?: 'image/jpeg' | 'image/webp' | 'image/png';\n /** 0..1 quality for lossy `outputType`. Ignored for image/png. */\n outputQuality?: number;\n /** Crop the confirmed image to the overlay frame rect. */\n cropToFrame?: boolean;\n /** Disable all controls and skip the camera request. */\n disabled?: boolean;\n /** Accessible label for the component's group region. */\n ariaLabel?: string;\n /** Extra classes merged onto the outermost wrapper. */\n className?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-md)]',\n 'ds:rounded-[var(--radius-md)] ds:[:where(&)]:border-[length:var(--surface-border-width,var(--border-width-sm))] ds:border-[color:var(--card-border)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:p-[var(--spacing-md)]',\n 'ds:aria-disabled:opacity-[var(--opacity-50)] ds:aria-disabled:cursor-not-allowed',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:[max-inline-size:20rem]',\n md: 'ds:[max-inline-size:28rem]',\n lg: 'ds:[max-inline-size:36rem]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\n// The viewport is a positioned, neutral surface that holds the <video> /\n// <img> and the (absolutely-positioned, aria-hidden) frame overlay. The\n// document aspect ratio drives the box shape so the frame matches the card.\nconst viewportVariants = cva(\n [\n 'ds:relative ds:block ds:inline-size-full ds:overflow-hidden',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:bg-[var(--muted)]',\n ].join(' '),\n {\n variants: {\n // ID-1 cards (Tessera Sanitaria / CIE / id-card) are ~1.586:1; the\n // generic frame is a slightly squarer neutral card.\n frame: {\n 'tessera-sanitaria': 'ds:aspect-[1.586/1]',\n cie: 'ds:aspect-[1.586/1]',\n 'id-card': 'ds:aspect-[1.586/1]',\n generic: 'ds:aspect-[1.4/1]',\n },\n },\n defaultVariants: { frame: 'tessera-sanitaria' },\n },\n);\n\nconst mediaVariants = cva(\n [\n 'ds:absolute ds:inset-0 ds:block',\n 'ds:inline-size-full ds:block-size-full',\n 'ds:object-cover',\n ].join(' '),\n);\n\n// The alignment frame sits over arbitrary live video. It is a\n// high-contrast neutral stroke (var(--background) = white on light /\n// near-black on dark) backed by a tokenised scrim — NEVER the magenta\n// accent (fails AA over an unknown image). Decorative → aria-hidden.\nconst frameOverlayVariants = cva(\n [\n 'ds:pointer-events-none ds:absolute',\n 'ds:inset-[12%]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:border-2 ds:border-[color:var(--background)]',\n 'ds:shadow-[0_0_0_100vmax_color-mix(in_srgb,var(--foreground)_45%,transparent)]',\n ].join(' '),\n);\n\nconst cornerVariants = cva(\n [\n 'ds:pointer-events-none ds:absolute ds:size-6',\n 'ds:border-[color:var(--background)]',\n ].join(' '),\n);\n\nconst controlBarVariants = cva(\n [\n // Phone: actions stack full-width; sm+: a wrapping row.\n 'ds:flex ds:flex-col ds:items-stretch ds:gap-[var(--spacing-sm)]',\n 'ds:sm:flex-row ds:sm:flex-wrap ds:sm:items-center',\n ].join(' '),\n);\n\nconst hintVariants = cva(\n ['type-body-sm ds:text-center', 'ds:text-[var(--muted-foreground)]'].join(\n ' ',\n ),\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction toHex(bytes: Uint8Array): string {\n let out = '';\n for (let i = 0; i < bytes.length; i += 1) {\n out += bytes[i].toString(16).padStart(2, '0');\n }\n return out;\n}\n\nasync function sha256Hex(buffer: ArrayBuffer): Promise<string> {\n const g = globalThis as { crypto?: Crypto };\n if (g.crypto?.subtle) {\n // Copy into a fresh ArrayBuffer so the BufferSource is never a\n // SharedArrayBuffer (SubtleCrypto's narrowing rejects the latter).\n const copy = new Uint8Array(buffer.byteLength);\n copy.set(new Uint8Array(buffer));\n const digest = await g.crypto.subtle.digest('SHA-256', copy.buffer);\n return toHex(new Uint8Array(digest));\n }\n // No subtle crypto (older test env) — return empty so the rest of the\n // payload is still usable. Tests stub crypto.subtle.\n return '';\n}\n\n/** Map a getUserMedia rejection (a DOMException) to our error kind. */\nfunction classifyMediaError(err: unknown): DocumentScannerErrorKind {\n const name = err instanceof Error ? err.name : '';\n if (name === 'NotAllowedError' || name === 'SecurityError') {\n return 'permission-denied';\n }\n if (name === 'NotFoundError' || name === 'OverconstrainedError') {\n return 'no-camera';\n }\n if (name === 'NotReadableError' || name === 'AbortError') {\n return 'not-readable';\n }\n return 'capture-failed';\n}\n\n/** True when getUserMedia is actually reachable (HTTPS / localhost + API). */\nfunction mediaDevicesAvailable(): boolean {\n return (\n typeof navigator !== 'undefined' &&\n typeof navigator.mediaDevices !== 'undefined' &&\n typeof navigator.mediaDevices.getUserMedia === 'function'\n );\n}\n\nconst HINT_KEY: Record<DocumentType, string> = {\n 'tessera-sanitaria': 'documentScanner.hint.tesseraSanitaria',\n cie: 'documentScanner.hint.cie',\n 'id-card': 'documentScanner.hint.idCard',\n generic: 'documentScanner.hint.generic',\n};\n\nconst ERROR_KEY: Record<DocumentScannerErrorKind, string> = {\n 'permission-denied': 'documentScanner.error.permissionDenied',\n 'no-camera': 'documentScanner.error.noCamera',\n 'not-readable': 'documentScanner.error.notReadable',\n 'insecure-context': 'documentScanner.error.insecureContext',\n 'capture-failed': 'documentScanner.error.captureFailed',\n 'file-invalid-type': 'documentScanner.error.fileInvalidType',\n 'file-too-large': 'documentScanner.error.fileTooLarge',\n};\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\ntype SizeVariant = NonNullable<VariantProps<typeof rootVariants>['size']>;\n\ninterface DocumentScannerInternalProps extends DocumentScannerProps {\n /** Visual size variant (exposed via Controls). */\n size?: SizeVariant;\n}\n\nexport const DocumentScanner = forwardRef<\n DocumentScannerHandle,\n DocumentScannerInternalProps\n>(\n (\n {\n id,\n value,\n defaultValue = null,\n onConfirm,\n onRetake,\n onError,\n documentType = 'tessera-sanitaria',\n captureMode = 'auto',\n accept = {\n 'image/jpeg': ['.jpg', '.jpeg'],\n 'image/png': ['.png'],\n 'image/webp': ['.webp'],\n },\n maxSize = 10 * 1024 * 1024,\n facingMode = 'environment',\n outputType = 'image/jpeg',\n outputQuality = 0.92,\n cropToFrame = true,\n disabled = false,\n size = 'md',\n ariaLabel,\n className,\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const rawId = useId();\n const hintId = `ds-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}-hint`;\n\n // Controlled / uncontrolled captured value. `value` defined → controlled.\n const [capture, setCapture] = useControllableState<DocumentCapture | null>({\n value,\n defaultValue,\n });\n\n // Whether the captured value was seeded by `defaultValue` (already on\n // file) — drives the \"Already on file\" badge + Retake-only chrome.\n const seededRef = useRef<boolean>(defaultValue != null || value != null);\n\n const [phase, setPhase] = useState<DocumentScannerPhase>(\n defaultValue != null || value != null ? 'captured' : 'idle',\n );\n const [errorKind, setErrorKind] = useState<DocumentScannerErrorKind | null>(\n null,\n );\n const [streamReady, setStreamReady] = useState(false);\n // True while an uploaded image is being decoded (distinct from the\n // camera-permission `requesting` so the live region announces the right\n // \"Processing image\" copy).\n const [decoding, setDecoding] = useState(false);\n\n const videoRef = useRef<HTMLVideoElement>(null);\n const viewportRef = useRef<HTMLDivElement>(null);\n const streamRef = useRef<MediaStream | null>(null);\n const unmountedRef = useRef(false);\n\n const confirmBtnRef = useRef<HTMLButtonElement>(null);\n const shutterBtnRef = useRef<HTMLButtonElement>(null);\n const useCameraBtnRef = useRef<HTMLButtonElement>(null);\n const recoveryRef = useRef<HTMLButtonElement>(null);\n\n // Latest callbacks via refs so the async media path never closes over\n // a stale prop.\n const onErrorRef = useRef(onError);\n const onConfirmRef = useRef(onConfirm);\n const onRetakeRef = useRef(onRetake);\n useEffect(() => {\n onErrorRef.current = onError;\n onConfirmRef.current = onConfirm;\n onRetakeRef.current = onRetake;\n }, [onError, onConfirm, onRetake]);\n\n const isControlled = value !== undefined;\n const isUploadOnly = captureMode === 'upload-only';\n\n /* ---- Stream teardown — the single most important privacy path ---- */\n const stopStream = useCallback(() => {\n const held = streamRef.current;\n if (held) {\n held.getTracks().forEach((track) => track.stop());\n }\n streamRef.current = null;\n const video = videoRef.current;\n if (video) {\n // Detach so the element releases its reference to the (now-stopped)\n // stream and the browser drops the camera indicator.\n video.srcObject = null;\n }\n setStreamReady(false);\n }, []);\n\n const reportError = useCallback((kind: DocumentScannerErrorKind) => {\n setErrorKind(kind);\n setPhase('error');\n onErrorRef.current?.({ kind });\n }, []);\n\n /* ---- Start the camera — user gesture only, never auto on mount ---- */\n const startCamera = useCallback(async () => {\n if (disabled || isUploadOnly) return;\n if (!mediaDevicesAvailable()) {\n // No mediaDevices → insecure context (non-HTTPS) or unsupported.\n reportError('insecure-context');\n return;\n }\n setErrorKind(null);\n setPhase('requesting');\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n video: { facingMode },\n audio: false,\n });\n // Guard against an unmount between the permission prompt and\n // resolution — otherwise the freshly-acquired track leaks and the\n // camera LED stays live.\n if (unmountedRef.current) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n streamRef.current = stream;\n const video = videoRef.current;\n if (video) {\n try {\n video.srcObject = stream;\n } catch {\n // Some environments reject a non-native MediaStream on\n // srcObject; the stream is still held + torn down correctly.\n }\n // iOS Safari needs an explicit play() after attaching.\n const playResult = video.play?.();\n if (playResult && typeof playResult.catch === 'function') {\n playResult.catch(() => {\n /* autoplay can reject silently in some browsers; the\n loadedmetadata handler still enables the shutter */\n });\n }\n }\n setPhase('streaming');\n } catch (err: unknown) {\n stopStream();\n reportError(classifyMediaError(err));\n }\n }, [disabled, isUploadOnly, facingMode, stopStream, reportError]);\n\n /* ---- Shutter enablement: gate on the video actually playing ---- */\n const handleVideoReady = useCallback(() => {\n const video = videoRef.current;\n if (!video) return;\n // HAVE_CURRENT_DATA (2) means at least one frame is decodable.\n if (video.readyState >= 2) {\n setStreamReady(true);\n }\n }, []);\n\n /* ---- Poll readiness on entering streaming ---- */\n // The loadedmetadata / canplay events can fire before React attaches the\n // listeners (the metadata may already be decoded by the time the stream\n // is swapped onto the element). A short poll closes that race so the\n // shutter reliably enables.\n useEffect(() => {\n if (phase !== 'streaming') return undefined;\n handleVideoReady();\n const interval = window.setInterval(handleVideoReady, 100);\n const stopAfter = window.setTimeout(\n () => window.clearInterval(interval),\n 4000,\n );\n return () => {\n window.clearInterval(interval);\n window.clearTimeout(stopAfter);\n };\n }, [phase, handleVideoReady]);\n\n /* ---- Capture: freeze the current frame onto a canvas ---- */\n const capturePhoto = useCallback(async () => {\n const video = videoRef.current;\n if (!video || video.readyState < 2) {\n reportError('capture-failed');\n return;\n }\n const vw = video.videoWidth || video.clientWidth;\n const vh = video.videoHeight || video.clientHeight;\n if (vw === 0 || vh === 0) {\n reportError('capture-failed');\n return;\n }\n\n // Crop region in source-video pixel space. The overlay frame is\n // inset 12% on each edge of the viewport; mirror that onto the\n // source so the cropped image is the document, not the whole frame.\n let sx = 0;\n let sy = 0;\n let sw = vw;\n let sh = vh;\n if (cropToFrame) {\n const insetX = vw * 0.12;\n const insetY = vh * 0.12;\n sx = insetX;\n sy = insetY;\n sw = vw - insetX * 2;\n sh = vh - insetY * 2;\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, Math.round(sw));\n canvas.height = Math.max(1, Math.round(sh));\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n reportError('capture-failed');\n return;\n }\n try {\n ctx.drawImage(video, sx, sy, sw, sh, 0, 0, canvas.width, canvas.height);\n } catch {\n // A video element with no decoded frame throws InvalidStateError in\n // some browsers — surface it as a capture failure rather than crash.\n reportError('capture-failed');\n return;\n }\n\n // Release the camera as soon as the frame is frozen — we no longer\n // need the live stream and the LED should go dark immediately.\n stopStream();\n\n const blob = await new Promise<Blob | null>((resolve) => {\n if (typeof canvas.toBlob === 'function') {\n canvas.toBlob(\n (b) => resolve(b),\n outputType,\n outputType === 'image/png' ? undefined : outputQuality,\n );\n } else {\n resolve(null);\n }\n });\n if (!blob) {\n reportError('capture-failed');\n return;\n }\n const dataUrl = canvas.toDataURL(\n outputType,\n outputType === 'image/png' ? undefined : outputQuality,\n );\n const arrayBuffer = await blob.arrayBuffer();\n const sha256 = await sha256Hex(arrayBuffer);\n\n seededRef.current = false;\n const next: DocumentCapture = {\n dataUrl,\n blob,\n source: 'camera',\n width: canvas.width,\n height: canvas.height,\n mimeType: outputType,\n byteSize: blob.size,\n capturedAt: new Date().toISOString(),\n sha256,\n };\n setCapture(next);\n setPhase('captured');\n }, [\n cropToFrame,\n outputType,\n outputQuality,\n stopStream,\n reportError,\n setCapture,\n ]);\n\n /* ---- Upload fallback → decode an image File into a capture ---- */\n const handleUploadDrop = useCallback(\n async (accepted: File[]) => {\n const file = accepted[0];\n if (!file) return;\n setDecoding(true);\n try {\n const objectUrl = URL.createObjectURL(file);\n const dimensions = await new Promise<{ w: number; h: number }>(\n (resolve, reject) => {\n const img = new Image();\n img.onload = () =>\n resolve({ w: img.naturalWidth, h: img.naturalHeight });\n img.onerror = () => reject(new Error('decode-failed'));\n img.src = objectUrl;\n },\n ).finally(() => {\n // The object URL is only needed to read intrinsic dimensions;\n // the persisted payload carries a data URL instead.\n URL.revokeObjectURL(objectUrl);\n });\n\n const dataUrl = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result));\n reader.onerror = () => reject(new Error('read-failed'));\n reader.readAsDataURL(file);\n });\n\n const arrayBuffer = await file.arrayBuffer();\n const sha256 = await sha256Hex(arrayBuffer);\n\n seededRef.current = false;\n setErrorKind(null);\n setCapture({\n dataUrl,\n blob: file,\n source: 'upload',\n width: dimensions.w,\n height: dimensions.h,\n mimeType: file.type || outputType,\n byteSize: file.size,\n capturedAt: new Date().toISOString(),\n sha256,\n });\n setPhase('captured');\n } catch {\n reportError('capture-failed');\n } finally {\n setDecoding(false);\n }\n },\n [outputType, reportError, setCapture],\n );\n\n const handleUploadReject = useCallback(\n (rejections: FileUploadRejection[]) => {\n // FileUpload's reason enum is wider than our two error kinds. The\n // dropzone is locked to a single image (maxFiles:1, multiple:false),\n // so 'too-many-files' / 'file-too-small' are unreachable here; both\n // size/type problems fold into the matching inline message and\n // default to invalid-type for anything else.\n const reason = rejections[0]?.reason;\n const kind: DocumentScannerErrorKind =\n reason === 'file-too-large' ? 'file-too-large' : 'file-invalid-type';\n reportError(kind);\n },\n [reportError],\n );\n\n /* ---- Confirm / Retake ---- */\n const confirm = useCallback(() => {\n if (!capture) return;\n onConfirmRef.current?.(capture);\n }, [capture]);\n\n // Set when a user-initiated transition back to idle should move focus to\n // the Use-camera button (Retake). Distinguishes retake-to-idle from the\n // initial idle mount, so focus is never stolen on first paint.\n const focusUseCameraRef = useRef(false);\n\n const retake = useCallback(() => {\n // Controlled mode: retake is advisory only. The consumer owns `value`,\n // so we must NOT clear the capture, flip seededRef, or force a local\n // phase — doing so would race the controlled-value sync effect (which\n // re-asserts `captured` while value is still set), dropping the\n // \"already on file\" badge and surfacing a stray Confirm for an\n // already-persisted image. Emit onRetake and let the value drive phase.\n if (isControlled) {\n onRetakeRef.current?.();\n return;\n }\n seededRef.current = false;\n focusUseCameraRef.current = true;\n setCapture(null);\n setErrorKind(null);\n setDecoding(false);\n setPhase('idle');\n onRetakeRef.current?.();\n }, [isControlled, setCapture]);\n\n /* ---- Focus management on phase transitions ---- */\n useEffect(() => {\n if (phase === 'captured' && !seededRef.current) {\n // Land the keyboard / SR user on the next logical action.\n confirmBtnRef.current?.focus();\n } else if (phase === 'error') {\n recoveryRef.current?.focus();\n } else if (phase === 'idle' && focusUseCameraRef.current) {\n // After a Retake, return focus to the capture entry point. Never on\n // the initial idle mount (the flag is only set by retake()).\n focusUseCameraRef.current = false;\n useCameraBtnRef.current?.focus();\n }\n }, [phase]);\n\n /* ---- Escape from streaming returns to idle and stops the stream ---- */\n useEffect(() => {\n if (phase !== 'streaming') return undefined;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n stopStream();\n setPhase('idle');\n }\n };\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [phase, stopStream]);\n\n /* ---- Release the camera when the tab is hidden ---- */\n useEffect(() => {\n const onVisibility = () => {\n if (document.visibilityState === 'hidden' && streamRef.current) {\n stopStream();\n setPhase('idle');\n }\n };\n document.addEventListener('visibilitychange', onVisibility);\n return () =>\n document.removeEventListener('visibilitychange', onVisibility);\n }, [stopStream]);\n\n /* ---- Unmount cleanup: release the camera if still held ---- */\n useEffect(() => {\n return () => {\n unmountedRef.current = true;\n const held = streamRef.current;\n if (held) held.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n };\n }, []);\n\n /* ---- Sync controlled value → phase ---- */\n useEffect(() => {\n if (!isControlled) return;\n if (value != null) {\n setPhase('captured');\n } else if (phase === 'captured') {\n setPhase('idle');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value, isControlled]);\n\n /* ---- Imperative handle + agent registration ---- */\n const agentHandle = useMemo<DocumentScannerHandle>(\n () => ({\n hasCapture: () => capture != null,\n getPhase: () => phase,\n startCamera: () => startCamera(),\n capture: () => capturePhoto(),\n confirm: () => confirm(),\n retake: () => retake(),\n }),\n [capture, phase, startCamera, capturePhoto, confirm, retake],\n );\n useImperativeHandle(ref, () => agentHandle, [agentHandle]);\n useAgentRegistration(documentScannerAgent, agentHandle, id);\n\n /* ---- Derived strings ---- */\n const regionLabel = ariaLabel ?? t('documentScanner.regionLabel');\n const hintText = t(HINT_KEY[documentType]);\n const maxSizeMb = Math.round(maxSize / (1024 * 1024));\n\n const statusText = (() => {\n if (decoding) return t('documentScanner.state.uploading');\n switch (phase) {\n case 'idle':\n return t('documentScanner.state.idle');\n case 'requesting':\n return t('documentScanner.state.requesting');\n case 'streaming':\n return t('documentScanner.state.streaming');\n case 'captured':\n return t('documentScanner.state.captured');\n case 'error':\n return errorKind\n ? t(ERROR_KEY[errorKind], { maxSizeMb })\n : t('documentScanner.error.captureFailed');\n }\n })();\n\n // A camera retry only makes sense for a hardware/permission failure —\n // not for upload-side rejections or an insecure (non-HTTPS) context.\n const canRetryCamera =\n !isUploadOnly &&\n errorKind !== 'file-invalid-type' &&\n errorKind !== 'file-too-large' &&\n errorKind !== 'insecure-context';\n\n // The upload affordance is always reachable: shown in idle/error for\n // auto + camera-only, primary in upload-only, and the recovery path on\n // any hard camera error.\n const showUploadFallback =\n !disabled &&\n (captureMode === 'auto' ||\n captureMode === 'upload-only' ||\n phase === 'error');\n\n const uploadAffordance = (\n <FileUpload\n variant=\"button\"\n accept={accept}\n maxSize={maxSize}\n multiple={false}\n maxFiles={1}\n disabled={disabled}\n showPreview={false}\n onDrop={(acceptedFiles) => {\n void handleUploadDrop(acceptedFiles);\n }}\n onReject={handleUploadReject}\n />\n );\n\n /* ---- Render ---- */\n const showViewport =\n phase === 'idle' ||\n phase === 'requesting' ||\n phase === 'streaming' ||\n phase === 'error';\n\n return (\n <div\n role=\"group\"\n aria-label={regionLabel}\n aria-disabled={disabled || undefined}\n className={[rootVariants({ size }), className]\n .filter(Boolean)\n .join(' ')}\n data-component=\"document-scanner\"\n data-component-id={id}\n data-phase={phase}\n >\n {/* Polite live region — announces every phase change to SR users. */}\n <span\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"ds:sr-only\"\n data-testid=\"document-scanner-live\"\n >\n {statusText}\n </span>\n\n {phase === 'captured' && capture ? (\n /* ---- Captured preview ---- */\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className={viewportVariants({ frame: documentType })}>\n <img\n src={capture.dataUrl}\n alt={t('documentScanner.previewAlt')}\n className={mediaVariants()}\n data-testid=\"document-scanner-preview\"\n />\n {seededRef.current ? (\n <span className=\"ds:absolute ds:top-[var(--spacing-sm)] ds:start-[var(--spacing-sm)] ds:rounded-[var(--radius-full)] ds:border ds:border-[color:color-mix(in_srgb,var(--foreground)_15%,transparent)] ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)] ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-2xs)] type-meta\">\n {t('documentScanner.onFileBadge')}\n </span>\n ) : null}\n </div>\n <div className={controlBarVariants()}>\n <Button\n intent=\"secondary\"\n size=\"md\"\n // Button's md variant is h-10 (40px) with no min-target\n // compensation — pin to --min-target-size (44/48px) to clear\n // WCAG 2.5.5, matching SignatureCapture's action buttons.\n className=\"ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]\"\n startIcon={<RotateCcw aria-hidden=\"true\" />}\n onClick={retake}\n disabled={disabled}\n >\n {t('documentScanner.retake')}\n </Button>\n {/* Seeded \"already on file\" images need no Confirm — they are\n already persisted; the only action is Retake. */}\n {seededRef.current ? null : (\n <Button\n ref={confirmBtnRef}\n intent=\"primary\"\n size=\"md\"\n className=\"ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]\"\n startIcon={<Check aria-hidden=\"true\" />}\n onClick={confirm}\n disabled={disabled || capture == null}\n >\n {t('documentScanner.confirm')}\n </Button>\n )}\n </div>\n </div>\n ) : null}\n\n {showViewport ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Viewport — only meaningful while streaming/requesting; in\n idle/error it is a neutral placeholder behind the controls. */}\n {!isUploadOnly && phase !== 'error' ? (\n <div\n ref={viewportRef}\n className={viewportVariants({ frame: documentType })}\n aria-busy={phase === 'requesting' || undefined}\n >\n <video\n ref={videoRef}\n autoPlay\n playsInline\n muted\n aria-label={t('documentScanner.videoLabel')}\n className={mediaVariants()}\n onLoadedMetadata={handleVideoReady}\n onCanPlay={handleVideoReady}\n data-testid=\"document-scanner-video\"\n />\n {phase === 'requesting' ? (\n <div className=\"ds:absolute ds:inset-0 ds:flex ds:items-center ds:justify-center ds:bg-[color-mix(in_srgb,var(--foreground)_20%,transparent)]\">\n <LoaderCircle\n aria-hidden=\"true\"\n className=\"ds:size-8 ds:animate-spin ds:text-[var(--background)] ds:motion-reduce:animate-none\"\n />\n </div>\n ) : null}\n {/* Decorative alignment frame + corner guides. */}\n <div\n aria-hidden=\"true\"\n className={frameOverlayVariants()}\n data-testid=\"document-scanner-frame\"\n >\n <span\n className={[\n cornerVariants(),\n 'ds:top-0 ds:start-0 ds:border-t-2 ds:border-s-2 ds:rounded-ss-[var(--radius-sm)]',\n ].join(' ')}\n />\n <span\n className={[\n cornerVariants(),\n 'ds:top-0 ds:end-0 ds:border-t-2 ds:border-e-2 ds:rounded-se-[var(--radius-sm)]',\n ].join(' ')}\n />\n <span\n className={[\n cornerVariants(),\n 'ds:bottom-0 ds:start-0 ds:border-b-2 ds:border-s-2 ds:rounded-es-[var(--radius-sm)]',\n ].join(' ')}\n />\n <span\n className={[\n cornerVariants(),\n 'ds:bottom-0 ds:end-0 ds:border-b-2 ds:border-e-2 ds:rounded-ee-[var(--radius-sm)]',\n ].join(' ')}\n />\n </div>\n </div>\n ) : null}\n\n {phase === 'streaming' ? (\n <p id={hintId} className={hintVariants()}>\n {hintText}\n </p>\n ) : null}\n\n {/* Error block — Alert pattern with the upload recovery path. */}\n {phase === 'error' && errorKind ? (\n <Alert variant=\"error\" live=\"assertive\">\n <Alert.Description>\n {t(ERROR_KEY[errorKind], { maxSizeMb })}\n </Alert.Description>\n <Alert.Action>\n {/* The camera-retry button is the focus target on a\n hardware/permission error; for upload-side or\n insecure-context errors there is nothing to retry and\n the upload affordance is the recovery path. */}\n {canRetryCamera ? (\n <Button\n ref={recoveryRef}\n intent=\"secondary\"\n size=\"sm\"\n onClick={() => {\n void startCamera();\n }}\n disabled={disabled}\n >\n {t('documentScanner.retry')}\n </Button>\n ) : null}\n {showUploadFallback ? uploadAffordance : null}\n </Alert.Action>\n </Alert>\n ) : null}\n\n {/* Primary control bar (no hard error). */}\n {phase !== 'error' ? (\n <div className={controlBarVariants()}>\n {phase === 'streaming' ? (\n <Button\n ref={shutterBtnRef}\n intent=\"primary\"\n size=\"lg\"\n startIcon={<Camera aria-hidden=\"true\" />}\n onClick={() => {\n void capturePhoto();\n }}\n disabled={disabled || !streamReady}\n aria-describedby={hintId}\n aria-label={t('documentScanner.capture')}\n >\n {t('documentScanner.capture')}\n </Button>\n ) : null}\n\n {(phase === 'idle' || phase === 'requesting') &&\n !isUploadOnly ? (\n <Button\n ref={useCameraBtnRef}\n intent=\"primary\"\n size=\"md\"\n className=\"ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]\"\n loading={phase === 'requesting'}\n startIcon={<Camera aria-hidden=\"true\" />}\n onClick={() => {\n void startCamera();\n }}\n disabled={disabled}\n >\n {t('documentScanner.useCamera')}\n </Button>\n ) : null}\n\n {decoding ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-[var(--muted-foreground)]\">\n <LoaderCircle\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:animate-spin ds:motion-reduce:animate-none\"\n />\n {t('documentScanner.state.uploading')}\n </span>\n ) : showUploadFallback && phase !== 'streaming' ? (\n uploadAffordance\n ) : null}\n\n {/* In streaming, upload stays reachable as a low-emphasis\n fallback below the shutter. */}\n {phase === 'streaming' && captureMode !== 'camera-only'\n ? uploadAffordance\n : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n },\n);\n\nDocumentScanner.displayName = 'DocumentScanner';\n\nexport {\n rootVariants as documentScannerRootVariants,\n viewportVariants as documentScannerViewportVariants,\n};\n"],"names":["documentScannerAgent","handle","rootVariants","cva","viewportVariants","mediaVariants","frameOverlayVariants","cornerVariants","controlBarVariants","hintVariants","toHex","bytes","out","i","sha256Hex","buffer","g","_a","copy","digest","classifyMediaError","err","name","mediaDevicesAvailable","HINT_KEY","ERROR_KEY","DocumentScanner","forwardRef","id","value","defaultValue","onConfirm","onRetake","onError","documentType","captureMode","accept","maxSize","facingMode","outputType","outputQuality","cropToFrame","disabled","size","ariaLabel","className","ref","t","useTranslation","hintId","useId","capture","setCapture","useControllableState","seededRef","useRef","phase","setPhase","useState","errorKind","setErrorKind","streamReady","setStreamReady","decoding","setDecoding","videoRef","viewportRef","streamRef","unmountedRef","confirmBtnRef","shutterBtnRef","useCameraBtnRef","recoveryRef","onErrorRef","onConfirmRef","onRetakeRef","useEffect","isControlled","isUploadOnly","stopStream","useCallback","held","track","video","reportError","kind","startCamera","stream","playResult","handleVideoReady","interval","stopAfter","capturePhoto","vw","vh","sx","sy","sw","sh","insetX","insetY","canvas","ctx","blob","resolve","b","dataUrl","arrayBuffer","sha256","next","handleUploadDrop","accepted","file","objectUrl","dimensions","reject","img","reader","handleUploadReject","rejections","confirm","focusUseCameraRef","retake","_b","_c","onKeyDown","event","onVisibility","agentHandle","useMemo","useImperativeHandle","useAgentRegistration","regionLabel","hintText","maxSizeMb","statusText","canRetryCamera","showUploadFallback","uploadAffordance","jsx","FileUpload","acceptedFiles","showViewport","jsxs","Button","RotateCcw","Check","LoaderCircle","Alert","Camera"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"info-tip-Do3RFt60.js","sources":["../../src/components/info-tip/info-tip.agent.ts","../../src/components/info-tip/info-tip.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { InfoTipHandle } from './info-tip';\n\nexport const infoTipAgent: AgentAdapter<InfoTipHandle> = {\n id: 'info-tip',\n capabilities: ['open', 'close'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.infoTip.state.isOpen',\n description: 'True when the info tip card is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.infoTip.actions.open',\n description:\n 'Open the info tip card (including its formula and Learn more link, when set).',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.infoTip.actions.close',\n description: 'Close the info tip card.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'info-tip',\n description: 'Marks the InfoTip trigger button.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on InfoTip.',\n },\n },\n};\n","import {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Info } from 'lucide-react';\nimport { Popover } from '../popover';\nimport { Link } from '../link';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useAgentRegistration } from '../../agent';\nimport { infoTipAgent } from './info-tip.agent';\n\n/* -------------------------------------------------------------------- */\n/* Trigger — a small circular, branded affordance: card surface inside */\n/* the circle, accent ring + accent \"i\" glyph, and a soft drop shadow. */\n/* The accent alias is safe here: `--accent` resolves to magenta-700 in */\n/* light mode (the AA-safe interactive step) and the dark accent on dark */\n/* surfaces — never reference a raw magenta ramp step. */\n/* -------------------------------------------------------------------- */\n\nconst infoTipTriggerVariants = cva(\n [\n 'ds:relative ds:inline-flex ds:shrink-0 ds:items-center ds:justify-center',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--card)]',\n 'ds:text-[var(--accent)]',\n // Single ring: the Lucide Info glyph draws its own accent circle, so the\n // trigger carries NO CSS border of its own (a border would read as a\n // second, concentric ring). The white circle comes from `bg-card` showing\n // through the glyph, lifted by the drop shadow.\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:cursor-pointer',\n 'ds:transition-[color,box-shadow] ds:motion-reduce:transition-none',\n 'ds:hover:text-[var(--accent-hover)] ds:hover:shadow-[var(--shadow-md)]',\n 'ds:data-[state=open]:text-[var(--accent-hover)] ds:data-[state=open]:shadow-[var(--shadow-md)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n // Both diameters sit below `--min-target-size` (44/48px), so each\n // re-uses IconButton's invisible `::before` hit-area expansion to a\n // full touch target on touch / small screens. From the `sm:`\n // breakpoint up the pointer is precise, so the expansion relaxes —\n // but the interactive target must never fall below WCAG 2.5.8's 24px:\n // • md (24px visual) already meets the 24px floor, so its `::before`\n // is hidden on desktop and the 24px circle IS the target.\n // • sm (20px visual) would fall to 20px if hidden — below the floor\n // — so instead of hiding, its `::before` shrinks to a persistent\n // `--spacing-lg` (24px) minimum that holds on desktop too.\n sm: 'ds:w-5 ds:h-5 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:inset-x-[calc((var(--spacing-lg)-100%)/-2)] ds:sm:before:inset-y-[calc((var(--spacing-lg)-100%)/-2)]',\n md: 'ds:w-6 ds:h-6 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:hidden',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\n// Curated agent-readiness handle — see info-tip.agent.ts.\nexport interface InfoTipHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface InfoTipProps {\n /** Body of the tip — explanatory text shown in the floating card. */\n content: ReactNode;\n /** Optional heading rendered above the body. */\n heading?: ReactNode;\n /**\n * Trigger diameter. Also maps the floating card width:\n * `sm` → `--popover-size-sm`, `md` → `--popover-size-md`.\n */\n size?: 'sm' | 'md';\n /** Logical side the card opens on. Default `'top'`. */\n side?: 'start' | 'top' | 'end' | 'bottom';\n /** Alignment along the side axis. Default `'center'`. */\n align?: 'start' | 'center' | 'end';\n /**\n * Accessible name for the trigger. Defaults to the translated\n * \"More information\" chrome string.\n */\n 'aria-label'?: string;\n /**\n * Opaque instance id — emitted as `data-component-id` on the trigger and\n * used to register the instance with the host agent registry.\n */\n id?: string;\n /** Extra classes merged onto the trigger button. */\n className?: string;\n /**\n * A formula written in words, shown below `content` in a quiet block, e.g.\n * \"Net revenue = invoices issued − credit notes\". It is part of the card's\n * description, so screen readers hear it.\n */\n formula?: ReactNode;\n /**\n * When set, the card gains a footer \"Learn more\" link to this URL and\n * becomes interactive: Tab from the open trigger moves to the link,\n * Shift+Tab returns, Escape closes and refocuses the trigger. Without it the\n * card stays explanatory text only and focus never leaves the trigger.\n */\n learnMoreHref?: string;\n /** Link text. Defaults to the translated \"Learn more\" chrome string. */\n learnMoreLabel?: string;\n /**\n * Called when the link is activated. An SPA can call `event.preventDefault()`\n * and route client-side; the anchor keeps its real `href` either way.\n */\n onLearnMore?: (event: ReactMouseEvent<HTMLAnchorElement>) => void;\n}\n\n/**\n * InfoTip — a deliberate, branded \"more information\" affordance: a small\n * circular trigger that reveals an explanatory card on hover **and** click\n * (click also serves touch devices). Composes the kit Popover in\n * `openOn=\"hover-or-click\"` mode — hover intent, keyboard focus, Escape and\n * focus-return are all handled by the Popover/Radix layer.\n */\nexport const InfoTip = forwardRef<HTMLButtonElement, InfoTipProps>(\n (\n {\n content,\n heading,\n size = 'md',\n side = 'top',\n align = 'center',\n 'aria-label': ariaLabelProp,\n id,\n className,\n formula,\n learnMoreHref,\n learnMoreLabel,\n onLearnMore,\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const [open, setOpen] = useState(false);\n\n // Agent handle.\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const agentHandle = useMemo<InfoTipHandle>(\n () => ({\n getIsOpen: () => openRef.current,\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [],\n );\n useAgentRegistration(infoTipAgent, agentHandle, id);\n\n // Press bookkeeping. In hover-or-click mode the Popover opens as soon as\n // the trigger receives focus — which happens on pointerdown, BEFORE the\n // click event that Radix uses to toggle. Without intervention every\n // click/tap on a closed tip opens it (focus) and instantly toggles it\n // closed again (click). So each press (pointerdown, or Enter/Space)\n // snapshots the open state and the click handler consumes it: if the\n // press itself opened the card, swallow Radix's toggle so the card stays\n // open; if it was already open, let the toggle close it.\n //\n // `null` means \"no press recorded for this click\" — an orphan click\n // (programmatic .click(), or assistive tech dispatching click with no\n // pointer/key event). Those must fall through to Radix's default toggle\n // rather than read a stale snapshot, so the guard treats `null` as\n // \"don't suppress\" and every click clears the snapshot back to `null`.\n const pressStateRef = useRef<boolean | null>(null);\n const handlePressStart = () => {\n pressStateRef.current = openRef.current;\n };\n\n const hasLink = learnMoreHref != null;\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const composedTriggerRef = useMemo(\n () => composeRefs<HTMLButtonElement>(ref, triggerRef),\n [ref],\n );\n const linkRef = useRef<HTMLAnchorElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n\n const ariaLabel =\n ariaLabelProp ?? t('infoTip.triggerLabel', 'More information');\n\n return (\n <Popover openOn=\"hover-or-click\" open={open} onOpenChange={setOpen}>\n <Popover.Trigger\n ref={composedTriggerRef}\n aria-label={ariaLabel}\n className={infoTipTriggerVariants({ size, className })}\n data-component=\"info-tip\"\n data-component-id={id}\n onPointerDown={handlePressStart}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n handlePressStart();\n }\n // The card is portalled, so native Tab order would skip it. With a\n // link, Tab from the open trigger goes straight to the link.\n if (\n hasLink &&\n event.key === 'Tab' &&\n !event.shiftKey &&\n openRef.current &&\n linkRef.current\n ) {\n event.preventDefault();\n linkRef.current.focus();\n }\n }}\n onClick={(event) => {\n // Consume this click's press snapshot. A genuine pointer/keyboard\n // press recorded `false`/`true` on press-start; an orphan click\n // with no preceding pointerdown/keydown finds `null` and is left\n // to Radix's default toggle.\n const wasOpenAtPressStart = pressStateRef.current;\n pressStateRef.current = null;\n if (wasOpenAtPressStart === false && openRef.current) {\n // This press opened the card via focus — keep it open and\n // skip Radix's click toggle.\n event.preventDefault();\n }\n }}\n >\n <Info\n aria-hidden=\"true\"\n // Fills the circle so the glyph's own ring IS the trigger's\n // visible edge and the drop shadow hugs it.\n className={size === 'sm' ? 'ds:size-5' : 'ds:size-6'}\n />\n </Popover.Trigger>\n <Popover.Content\n ref={contentRef}\n side={side}\n align={align}\n size={size === 'sm' ? 'sm' : 'md'}\n // The card is a Radix `role=\"dialog\"` surface, which axe requires\n // to have an accessible name (aria-dialog-name). With a heading,\n // Popover wires aria-labelledby; without one, fall back to the\n // trigger's label.\n aria-label={heading == null ? ariaLabel : undefined}\n // Toggletip focus contract: the card is explanatory text, never\n // interactive, so focus stays on the trigger for the whole\n // open/close cycle. Preventing the open move also keeps Escape\n // reliable — if Radix pulled focus into the card, closing would\n // refocus the trigger and re-fire the hover-mode focus handler,\n // reopening the card it just closed. Preventing the close move\n // keeps an unhover-close from stealing focus mid-task.\n //\n // With a learn-more link the card is interactive, but the same\n // contract holds: focus is never pulled in on open, only Tab moves\n // it to the link. Escape from inside the card is handled below so\n // focus returns to the trigger without re-firing its focus-open.\n onOpenAutoFocus={(event) => event.preventDefault()}\n onCloseAutoFocus={(event) => event.preventDefault()}\n onEscapeKeyDown={(event) => {\n // Focus anywhere inside the card (the link, or the card itself\n // after a click on its text) goes back to the trigger.\n const active = document.activeElement;\n if (active && contentRef.current?.contains(active)) {\n event.preventDefault();\n triggerRef.current?.focus();\n setOpen(false);\n }\n }}\n >\n {heading != null && <Popover.Heading>{heading}</Popover.Heading>}\n <Popover.Description>\n {content}\n {formula != null && (\n <div\n data-slot=\"formula\"\n className=\"type-body-sm ds:mt-[var(--spacing-sm)] ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)] ds:text-[var(--foreground)] ds:tabular-nums\"\n >\n <span className=\"ds:sr-only\">\n {t('infoTip.formula', 'Formula')}:{' '}\n </span>\n {formula}\n </div>\n )}\n </Popover.Description>\n {hasLink && (\n <div\n data-slot=\"footer\"\n className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:justify-end\"\n >\n <Link\n ref={linkRef}\n href={learnMoreHref}\n onClick={onLearnMore}\n weight=\"strong\"\n className=\"type-body-sm\"\n >\n {learnMoreLabel ?? t('infoTip.learnMore', 'Learn more')}\n </Link>\n </div>\n )}\n </Popover.Content>\n </Popover>\n );\n },\n);\n\nInfoTip.displayName = 'InfoTip';\n"],"names":["infoTipAgent","handle","infoTipTriggerVariants","cva","InfoTip","forwardRef","content","heading","size","side","align","ariaLabelProp","id","className","formula","learnMoreHref","learnMoreLabel","onLearnMore","ref","t","useTranslation","open","setOpen","useState","openRef","useRef","useEffect","agentHandle","useMemo","useAgentRegistration","pressStateRef","handlePressStart","hasLink","triggerRef","composedTriggerRef","composeRefs","linkRef","contentRef","ariaLabel","Popover","jsx","event","wasOpenAtPressStart","Info","jsxs","active","_a","_b","Link"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"map-view--c9bJDRw.js","sources":["../../src/components/map-view/map-view.agent.ts","../../src/components/map-view/map-view.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — MapView. */\n/* */\n/* Read-safety actions on the kit's Google Maps wrapper. State is the */\n/* current centre / zoom / selected marker; actions pan, zoom, and */\n/* select markers programmatically. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { MapViewHandle, MapLatLng } from './map-view';\n\nexport const mapViewAgent: AgentAdapter<MapViewHandle> = {\n id: 'map-view',\n // pan → scroll (viewport move); set_zoom → set_value; select_marker → pick\n // (NON-persisting marker focus, no value state slot).\n capabilities: ['scroll', 'set_value', 'pick'],\n // Every action routes through the imperative bridge, which only exists\n // once the map has loaded: consent granted (the default is\n // `consentGranted={false}`) and Google Maps finished loading. Until then\n // all three actions are silent no-ops. `consentGranted` says whether the\n // gate is passed, and a null `center` after it means the map is still\n // loading. `center` / `zoom` are read off the live\n // map because Google clamps zoom and animates pans, so requested is not\n // applied; `selectedMarkerId` is the only confirmation the host accepted\n // a `select_marker` proposal.\n //\n // A9: marker ids only (`MapMarker.id` is a stable opaque id). Never\n // `MapMarker.label`, never the `address` prop (consumer-supplied free\n // text, PII in any patient-address deployment), never `apiKey`.\n state: {\n consentGranted: {\n type: 'boolean',\n descriptionKey: 'ui.agent.mapView.state.consentGranted',\n description:\n 'True when the GDPR consent gate has been passed. Read this FIRST: while it is false every action is a silent no-op against a placeholder, and nothing else in the surface says so. When it is true but `center` is still null, Google Maps is loading; wait for `center` before acting.',\n read: (handle) => handle.isConsentGranted(),\n },\n markerCount: {\n type: 'number',\n descriptionKey: 'ui.agent.mapView.state.markerCount',\n description:\n 'Number of markers the consumer passed. Zero means there is nothing for `select_marker` to select. A count only — no ids, labels or positions.',\n read: (handle) => handle.getMarkerCount(),\n },\n selectedMarkerId: {\n type: 'string | null',\n descriptionKey: 'ui.agent.mapView.state.selectedMarkerId',\n description:\n 'Id of the marker the host currently holds as selected, or null. Selection is fully controlled by the consumer, so `select_marker` only proposes — this slot is the only way to see whether the proposal was accepted.',\n read: (handle) => handle.getSelectedMarkerId(),\n },\n center: {\n type: '{ lat: number; lng: number } | null',\n descriptionKey: 'ui.agent.mapView.state.center',\n description:\n 'Live map centre in lat/lng, or null until the map has loaded (consent not granted, or Google Maps still loading). The read-back for `pan_to`, and the sign that the map is ready.',\n read: (handle) => handle.getCenter(),\n },\n zoom: {\n type: 'number | null',\n descriptionKey: 'ui.agent.mapView.state.zoom',\n description:\n \"Live zoom level, or null until the map has loaded. Google clamps zoom to the map type's range, so this is not necessarily the value last passed to `set_zoom`.\",\n read: (handle) => handle.getZoom(),\n },\n },\n actions: {\n pan_to: {\n // Ephemeral viewport move, no data loss → read.\n safety: 'read',\n argsType: '{ position: { lat: number; lng: number } }',\n argsSchema: {\n type: 'object',\n properties: {\n position: {\n type: 'object',\n properties: {\n lat: { type: 'number', description: 'Latitude in degrees.' },\n lng: { type: 'number', description: 'Longitude in degrees.' },\n },\n required: ['lat', 'lng'],\n },\n },\n required: ['position'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.mapView.actions.panTo',\n description:\n 'Pan the map to a new centre without changing zoom. Read the `center` slot back to confirm — Google animates the pan, so the applied centre settles after the call.',\n errors: [\n 'Silent no-op until the map has loaded: while `consentGranted` is false (only the consent placeholder shows) or while `center` is still null (Google Maps is loading).',\n ],\n invoke: (handle, args: { position: MapLatLng }) => {\n handle.panTo(args.position);\n },\n },\n set_zoom: {\n // Ephemeral viewport zoom, no data loss → read.\n safety: 'read',\n argsType: '{ zoom: number }',\n argsSchema: {\n type: 'object',\n properties: {\n zoom: {\n type: 'number',\n description: 'Zoom level, typical range 1–20.',\n },\n },\n required: ['zoom'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.mapView.actions.setZoom',\n description:\n 'Set the map zoom level (typical range 1–20). Read the `zoom` slot back — Google clamps the request to the map type’s supported range, so requested and applied can differ.',\n errors: [\n 'Silent no-op until the map has loaded: while `consentGranted` is false (only the consent placeholder shows) or while `center` is still null (Google Maps is loading).',\n \"Requested zoom is clamped to the map type's range; `zoom` reports what was actually applied.\",\n ],\n invoke: (handle, args: { zoom: number }) => {\n handle.setZoom(args.zoom);\n },\n },\n select_marker: {\n // Ephemeral marker focus, no data loss → read.\n safety: 'read',\n argsType: '{ id: string | null }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: ['string', 'null'],\n description: 'Marker id to select, or null to clear the selection.',\n },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.mapView.actions.selectMarker',\n description:\n \"Propose a marker selection by id, or pass null to clear it. Fires the host's `onMarkerClick`; selection is controlled by the host, so read the `selectedMarkerId` slot back to see whether it accepted.\",\n errors: [\n 'Silent no-op until the map has loaded: while `consentGranted` is false (only the consent placeholder shows) or while `center` is still null (Google Maps is loading).',\n 'The host owns `selectedMarkerId` and may ignore the proposal; `selectedMarkerId` is unchanged when it does.',\n ],\n invoke: (handle, args: { id: string | null }) => {\n handle.selectMarker(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'map-view',\n description: 'Marks the element as a kit MapView.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* MapView — kit wrapper over @vis.gl/react-google-maps. */\n/* */\n/* - Loads the Google Maps JS API on demand via the library's */\n/* `APIProvider`; consumer supplies the key (no kit-side cache). */\n/* - Defaults to a CONSENT-GATED placeholder (`consentGranted={false}`) */\n/* so the third-party load never happens before the consumer flips */\n/* the opt-in. GDPR-safe by default. */\n/* - Theme-reactive: the Google Maps `styles` JSON re-resolves on every */\n/* `documentElement.class` mutation (same pattern as Sparkline). */\n/* Consumers may pass `mapId` to switch to a cloud-styled map */\n/* instead, in which case `styles` is ignored. */\n/* - `data-component=\"map-view\"` lives on the outer span; the inner */\n/* `<Map>` mounts inside it. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { MapPin, ExternalLink } from 'lucide-react';\nimport {\n APIProvider,\n Map as GoogleMap,\n AdvancedMarker,\n Marker,\n Pin,\n useApiIsLoaded,\n useMap,\n useMapsLibrary,\n} from '@vis.gl/react-google-maps';\nimport { Button } from '../button';\nimport { Skeleton } from '../skeleton';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { ErrorBoundary } from '../error-boundary';\nimport { MapsCoreGate } from '../_shared/maps-core-gate';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { mapViewAgent } from './map-view.agent';\nimport { lengthTokenPx } from '../_shared/length-token';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface MapLatLng {\n lat: number;\n lng: number;\n}\n\nexport interface MapBounds {\n north: number;\n south: number;\n east: number;\n west: number;\n}\n\nexport interface MapBoundsChangeDetails {\n /** False for initial load, resizing, fitting and imperative camera moves. */\n userInteraction: boolean;\n}\n\n/**\n * A point to fit the camera to. `id` is its identity (a result id): it\n * decides whether a new set only added points to the old one. Without\n * it the coordinates stand in, so two results at one address count as\n * one.\n */\nexport interface MapFitPoint extends MapLatLng {\n id?: string;\n}\n\nexport interface MapMarker {\n /** Stable id — used for keyed re-rendering and `onMarkerClick`. */\n id: string;\n /** Position in lat/lng. */\n position: MapLatLng;\n /** Optional accessible label — falls back to the id. */\n label?: string;\n}\n\nexport interface MapViewHandle {\n /** Pan the map to a new centre without changing zoom. */\n panTo: (position: MapLatLng) => void;\n /** Set zoom (typical range 1–20). */\n setZoom: (zoom: number) => void;\n /** Programmatically select a marker (fires `onMarkerClick`). */\n selectMarker: (id: string | null) => void;\n /* ---- read-back ------------------------------------------------- */\n /**\n * True once the consent gate has been passed. The map may still be\n * loading: the three actions above stay silent no-ops until\n * `getCenter` returns a value.\n */\n isConsentGranted: () => boolean;\n /** Live map centre, or `null` until the map has loaded. */\n getCenter: () => MapLatLng | null;\n /**\n * Live zoom level, or `null` until the map has loaded.\n * Google clamps to the map type's range, so this is not necessarily\n * the value last passed to `setZoom`.\n */\n getZoom: () => number | null;\n /**\n * The controlled `selectedMarkerId` prop as the host currently holds\n * it. `selectMarker` only proposes a selection — the host is free to\n * ignore it, and this is the only way to see whether it did.\n */\n getSelectedMarkerId: () => string | null;\n /** Number of markers passed to the component. Count only, no ids. */\n getMarkerCount: () => number;\n}\n\n/**\n * The slice of `MapViewHandle` that needs a live `google.maps.Map`.\n * Built inside the `APIProvider` subtree by `MapImperativeBridge`; the\n * outer component composes it with the props-derived getters, and holds\n * `null` whenever the subtree is unmounted.\n */\ntype MapBridgeHandle = Pick<\n MapViewHandle,\n 'panTo' | 'setZoom' | 'selectMarker' | 'getCenter' | 'getZoom'\n> & {\n /** Set centre and zoom in one step, never animated. Internal. */\n jumpTo: (center: MapLatLng, zoom: number) => void;\n};\n\nexport interface MapViewProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'onClick'>,\n VariantProps<typeof mapViewVariants> {\n /** Opaque instance id — emitted as `data-component-id`. */\n id?: string;\n /** Google Maps JS API key. Consumer-owned; never cached by the kit. */\n apiKey: string;\n /** Map centre (lat/lng). Required so the consent placeholder can also use it. */\n center: MapLatLng;\n /** Initial zoom. Default 15 (city-block detail, matches booking site). */\n zoom?: number;\n /**\n * Markers to render. The first marker auto-selects when no\n * `selectedMarkerId` is given.\n */\n markers?: MapMarker[];\n /** Controlled selection — fires `onMarkerClick` with the new id (or null on map click). */\n selectedMarkerId?: string | null;\n /** Fires when a marker is clicked, or `null` when the map background is clicked. */\n onMarkerClick?: (id: string | null) => void;\n /**\n * The visible viewport once the map settles, including its first bounds.\n * Fires only when bounds change. `userInteraction` is true after patient\n * input that pans or zooms, never for a kit-initiated camera move.\n * Silent until the consented map has loaded.\n */\n onBoundsChange?: (bounds: MapBounds, details: MapBoundsChangeDetails) => void;\n /**\n * GDPR consent gate. When `false` (default) the component renders a\n * placeholder with a translated CTA — the Maps JS API is **not**\n * loaded. Flip to `true` once the consumer has captured opt-in.\n */\n consentGranted?: boolean;\n /** Fires when the consumer clicks the \"Load map\" CTA in the placeholder. */\n onConsentRequest?: () => void;\n /**\n * Optional address string shown in the consent placeholder so the\n * surface is useful before the map loads. Also used to build the\n * fallback \"Open in Google Maps\" link target.\n */\n address?: string;\n /**\n * Cloud-styled-map id. When set, takes precedence over the JSON\n * `styles` array and disables the theme-bridge re-fire. Use when\n * you've provisioned a styled map in Google Cloud Console.\n */\n mapId?: string;\n /**\n * Override the consent-placeholder description text. The default\n * (`t('mapView.consentDescription')`) is a generic IP-disclosure\n * line. Consumers operating under specific GDPR / ePrivacy\n * disclosures (jurisdiction, named controller, policy link) should\n * supply their own text via this prop. Pass any `ReactNode` — a\n * paragraph, a localised `<Trans>` instance, etc.\n */\n consentDescription?: ReactNode;\n /**\n * Replace the kit-rendered \"Load map\" button with custom CTA chrome.\n * Use when the consent dialog needs a policy link, a specific\n * jurisdiction phrasing, or a different surface (Tooltip-wrapped\n * button, link to a settings page, etc.). When omitted the kit\n * renders its own `<Button>` — that button calls `onConsentRequest`\n * if provided, otherwise flips MapView's internal opt-in state so\n * the map loads inline.\n */\n consentCta?: ReactNode;\n /**\n * Visual surface. Default `bordered` (current behaviour: 1px\n * `--border` outline + `--radius-md`). `elevated` replaces the\n * border with `--shadow-card`, matching `<Card variant=\"elevated\">`.\n * `bare` drops both — map is flush against the page canvas.\n */\n surface?: 'bordered' | 'elevated' | 'bare';\n /** Accessible label for the map region. Falls back to `t('mapView.label')`. */\n ariaLabel?: string;\n /**\n * Points the camera fits into view, with a margin, once the map has\n * loaded, and again whenever `fitKey` changes. Use it to show every pin\n * of a result list without the patient moving the map.\n *\n * - One point (or several at the same place) centres on it at\n * `fitMaxZoom`.\n * - No points: no fit, the camera shows `center` / `zoom`. If the\n * points run out after a fit, or the prop is removed, the camera\n * goes back there in one step.\n * - Between key changes nothing refits, so a map the patient has\n * panned or zoomed stays where they left it.\n * - A key change that only adds points (a \"load more\": every fitted\n * point is still there, compared by `id`) refits only if the patient\n * has not moved the map. Any other change refits. Give each point the\n * `id` of its result: two results can share an address.\n * - The camera is set in one step, never animated.\n * - While there are points to fit, the fit owns the camera: later\n * changes to `center` or `zoom` do not move it.\n */\n fitToPoints?: MapFitPoint[];\n /**\n * Identity of the fitted set: the camera refits only when this\n * changes. Pass the ids of the listed results, so re-sorting the same\n * results does not refit. Defaults to the points themselves, in any\n * order.\n */\n fitKey?: string;\n /**\n * The closest a fit may zoom in, so one result does not open at street\n * level. Default 15.\n */\n fitMaxZoom?: number;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst mapViewVariants = cva(\n ['ds:relative ds:overflow-hidden ds:block', 'ds:bg-[var(--muted)]'].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:[--map-block-size:14rem]',\n md: 'ds:[--map-block-size:20rem]',\n lg: 'ds:[--map-block-size:28rem]',\n // `fill` defers sizing to the parent. The outer takes\n // `block-size: 100%` so the inner (also 100%) has something\n // to inherit from. Use inside a viewport-locked column —\n // `<PracticeResults variant=\"map-first\">` wires this through\n // automatically; standalone consumers must give the parent\n // a constrained block-size or the map collapses to 0.\n fill: 'ds:[block-size:100%]',\n },\n surface: {\n bordered:\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n elevated:\n 'ds:rounded-[var(--radius-md)] ds:shadow-[var(--shadow-card)] ds:[:where(&)]:border-[length:var(--surface-border-width,var(--border-width-sm))] ds:border-[color:var(--card-border)]',\n bare: 'ds:rounded-none ds:border-0',\n },\n },\n defaultVariants: { size: 'md', surface: 'bordered' },\n },\n);\n\n// Inner block-size: percentage when `size=\"fill\"`, rem-token otherwise.\n// Splitting this out (instead of compound-variants) keeps the size\n// switch readable and avoids enumerating every (size × surface) pair.\nconst innerSurfaceVariants = cva('ds:block ds:inline-size-full', {\n variants: {\n size: {\n sm: 'ds:[block-size:var(--map-block-size)]',\n md: 'ds:[block-size:var(--map-block-size)]',\n lg: 'ds:[block-size:var(--map-block-size)]',\n fill: 'ds:[block-size:100%]',\n },\n },\n defaultVariants: { size: 'md' },\n});\n\nconst consentChromeVariants = cva(\n [\n 'ds:absolute ds:inset-0',\n 'ds:flex ds:flex-col ds:items-center ds:justify-center',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:p-[var(--spacing-md)]',\n 'ds:bg-[var(--muted)] ds:text-[var(--foreground)]',\n 'ds:text-center',\n ].join(' '),\n);\n\nconst consentTitleVariants = cva('type-heading-3 ds:m-0');\n\nconst consentDescriptionVariants = cva(\n 'type-body-sm ds:text-[var(--muted-foreground)] ds:[max-inline-size:28rem] ds:m-0',\n);\n\n/* ------------------------------------------------------------------ */\n/* Inner imperative bridge */\n/* */\n/* `useMap()` only resolves inside the APIProvider tree, so the */\n/* imperative actions live in a tiny inner component that the outer */\n/* `MapView` mounts conditionally. It exposes the `panTo` / `setZoom` */\n/* etc. to the forwardRef via a `useImperativeHandle` callback prop. */\n/* ------------------------------------------------------------------ */\n\ninterface MapImperativeBridgeProps {\n /** Called with the live handle on mount, and with `null` on unmount. */\n onHandleReady: (handle: MapBridgeHandle | null) => void;\n onMarkerSelect: (id: string | null) => void;\n onCameraMove: () => void;\n}\n\nfunction MapImperativeBridge({\n onHandleReady,\n onMarkerSelect,\n onCameraMove,\n}: MapImperativeBridgeProps): null {\n const map = useMap();\n useEffect(() => {\n if (!map) return;\n onHandleReady({\n panTo: (position) => {\n onCameraMove();\n map.panTo(position);\n },\n setZoom: (zoom) => {\n onCameraMove();\n map.setZoom(zoom);\n },\n jumpTo: (center, zoom) => {\n onCameraMove();\n map.moveCamera({ center, zoom });\n },\n selectMarker: (id) => onMarkerSelect(id),\n // Read straight off the live map: Google clamps `setZoom` to the\n // map type's range and animates `panTo`, so requested and applied\n // are not the same value.\n getCenter: () => map.getCenter()?.toJSON() ?? null,\n getZoom: () => map.getZoom() ?? null,\n });\n // Drop the handle when the subtree unmounts (consent revoked, or the\n // component tears down) so the outer getters answer `null` instead of\n // reporting a dead map's last known position.\n return () => onHandleReady(null);\n }, [map, onHandleReady, onMarkerSelect, onCameraMove]);\n return null;\n}\n\n/** Report once per settled viewport, with patient input kept separate from camera state. */\nfunction MapBoundsBridge({\n onBoundsChange,\n userInteraction,\n}: {\n onBoundsChange: NonNullable<MapViewProps['onBoundsChange']>;\n userInteraction: MutableRefObject<MapInteraction>;\n}): null {\n const map = useMap();\n const callback = useRef(onBoundsChange);\n callback.current = onBoundsChange;\n\n useEffect(() => {\n if (!map) return undefined;\n const div = map.getDiv();\n let previous: {\n bounds: MapBounds;\n center: MapLatLng;\n zoom: number;\n } | null = null;\n const resetInteraction = (): void => {\n userInteraction.current = {\n pendingInput: false,\n moved: false,\n programmatic: false,\n };\n };\n resetInteraction();\n let inputExpiry: ReturnType<typeof setTimeout> | undefined;\n const touchPointers = new Set<number>();\n const markInput = (event: Event): void => {\n if (event instanceof PointerEvent && event.pointerType === 'touch') {\n if (event.type === 'pointerdown') touchPointers.add(event.pointerId);\n if (event.type === 'pointerup' || event.type === 'pointercancel') {\n touchPointers.delete(event.pointerId);\n return;\n }\n }\n if (\n event instanceof PointerEvent &&\n event.type === 'pointermove' &&\n event.buttons === 0 &&\n event.pointerType !== 'touch'\n )\n return;\n if (\n event instanceof KeyboardEvent &&\n ![\n 'ArrowUp',\n 'ArrowDown',\n 'ArrowLeft',\n 'ArrowRight',\n '+',\n '=',\n '-',\n '_',\n 'Enter',\n ' ',\n 'PageUp',\n 'PageDown',\n ].includes(event.key)\n )\n return;\n // A short panTo can keep animating after the imperative call has\n // returned. Ordinary scrolling or clicking the map must not claim\n // that animation. A real camera gesture can interrupt it.\n const fullscreen = document.fullscreenElement;\n const fullscreenMap = Boolean(\n fullscreen && (fullscreen.contains(div) || div.contains(fullscreen)),\n );\n let cameraInput = event.type === 'dblclick';\n if (event instanceof PointerEvent && event.type === 'pointermove')\n cameraInput =\n event.pointerType !== 'touch' ||\n touchPointers.size >= 2 ||\n fullscreenMap;\n if (event.type === 'touchmove')\n cameraInput =\n (event as TouchEvent).touches.length >= 2 || fullscreenMap;\n if (event instanceof KeyboardEvent)\n cameraInput = event.key !== 'Enter' && event.key !== ' ';\n if (event instanceof WheelEvent)\n cameraInput = event.ctrlKey || event.metaKey || fullscreenMap;\n if (event.type === 'click')\n cameraInput =\n event.target instanceof Element &&\n event.target.closest('button, [role=\"button\"]') != null;\n if (cameraInput) userInteraction.current.programmatic = false;\n userInteraction.current.pendingInput = true;\n clearTimeout(inputExpiry);\n // Controls normally start moving the camera immediately. Expire an\n // input that did nothing; once movement starts it stays attributed\n // until idle, including a long drag or zoom animation.\n inputExpiry = setTimeout(() => {\n userInteraction.current.pendingInput = false;\n }, 250);\n };\n const markCameraChange = (): void => {\n if (\n userInteraction.current.pendingInput &&\n !userInteraction.current.programmatic\n )\n userInteraction.current.moved = true;\n };\n const report = (): void => {\n const bounds = map.getBounds()?.toJSON();\n const center = map.getCenter()?.toJSON();\n const zoom = map.getZoom();\n const fromInput = userInteraction.current.moved;\n resetInteraction();\n clearTimeout(inputExpiry);\n if (!bounds || !center || zoom == null) return;\n const changed =\n !previous ||\n (Object.keys(bounds) as (keyof MapBounds)[]).some(\n (key) => bounds[key] !== previous!.bounds[key],\n );\n const moved =\n previous != null &&\n (zoom !== previous.zoom ||\n center.lat !== previous.center.lat ||\n center.lng !== previous.center.lng);\n previous = { bounds, center, zoom };\n if (changed)\n callback.current(bounds, { userInteraction: fromInput && moved });\n };\n // Camera events alone include initial load, refits and resizes. Input\n // also covers touch, keyboard and Google's zoom controls, without\n // preventing their defaults or depending on vendor DOM selectors.\n const inputEvents = [\n 'pointerdown',\n 'pointermove',\n 'pointerup',\n 'pointercancel',\n 'touchstart',\n 'touchmove',\n 'click',\n 'dblclick',\n 'wheel',\n 'keydown',\n ] as const;\n inputEvents.forEach((event) =>\n div.addEventListener(event, markInput, { capture: true, passive: true }),\n );\n const listeners = [\n map.addListener('dragstart', () => {\n userInteraction.current.programmatic = false;\n userInteraction.current.moved = true;\n }),\n map.addListener('center_changed', markCameraChange),\n map.addListener('zoom_changed', markCameraChange),\n map.addListener('idle', report),\n ];\n report();\n return () => {\n listeners.forEach((listener) => listener.remove());\n inputEvents.forEach((event) =>\n div.removeEventListener(event, markInput, true),\n );\n clearTimeout(inputExpiry);\n resetInteraction();\n };\n }, [map, userInteraction]);\n return null;\n}\n\ninterface MapInteraction {\n pendingInput: boolean;\n moved: boolean;\n programmatic: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* Fit to points */\n/* */\n/* Lives inside <GoogleMap>, so it only runs once the `maps` library */\n/* has arrived and `useMap()` holds a real map: the load-race rule */\n/* below applies to it too. The camera is computed here (Web Mercator) */\n/* and set in one step, rather than through fitBounds: fitBounds takes */\n/* no zoom limit, and capping it afterwards needs an `idle` event that */\n/* Google may never send when the view does not change, so the cap */\n/* could fire on the patient's next zoom instead. Setting the camera */\n/* directly is synchronous and never animates (reduced motion). */\n/* */\n/* A map in a hidden column or a sheet still opening has no size yet, */\n/* so the fit waits for the map to be laid out. */\n/* ------------------------------------------------------------------ */\n\n/** Google's world is 256px wide at zoom 0. */\nconst WORLD_PX = 256;\n\nconst toRadians = (degrees: number): number => (degrees * Math.PI) / 180;\n\n/** Web Mercator y of a latitude: the world spans -π..π. */\nfunction mercatorY(lat: number): number {\n const sin = Math.min(Math.max(Math.sin(toRadians(lat)), -0.9999), 0.9999);\n return Math.log((1 + sin) / (1 - sin)) / 2;\n}\n\nconst latitudeOf = (y: number): number =>\n (Math.atan(Math.sinh(y)) * 180) / Math.PI;\n\n/** The box round `points` (not antimeridian-aware: the kit maps Europe). */\nfunction boundsOfPoints(points: MapLatLng[]): google.maps.LatLngBoundsLiteral {\n let north = -90;\n let south = 90;\n let east = -180;\n let west = 180;\n for (const { lat, lng } of points) {\n north = Math.max(north, lat);\n south = Math.min(south, lat);\n east = Math.max(east, lng);\n west = Math.min(west, lng);\n }\n return { north, south, east, west };\n}\n\n/**\n * The centre and the closest whole zoom that shows every point inside a\n * `width` x `height` map, `padding` px in from each edge, no closer than\n * `maxZoom`. Exported for tests.\n */\nexport function cameraForPoints(\n points: MapLatLng[],\n width: number,\n height: number,\n padding: number,\n maxZoom: number,\n): { center: MapLatLng; zoom: number } {\n const { north, south, east, west } = boundsOfPoints(points);\n if (north === south && east === west) {\n return { center: { lat: north, lng: east }, zoom: maxZoom };\n }\n const top = mercatorY(north);\n const bottom = mercatorY(south);\n const center = {\n lat: latitudeOf((top + bottom) / 2),\n lng: (east + west) / 2,\n };\n const fit = (px: number, fraction: number): number =>\n fraction > 0 ? Math.log2(Math.max(px, 1) / WORLD_PX / fraction) : maxZoom;\n const zoom = Math.min(\n fit(width - 2 * padding, (east - west) / 360),\n fit(height - 2 * padding, (top - bottom) / (2 * Math.PI)),\n maxZoom,\n );\n return { center, zoom: Math.max(0, Math.floor(zoom)) };\n}\n\n/** A fit point's identity: its id, or else its coordinates. */\nconst pointKey = ({ id, lat, lng }: MapFitPoint): string =>\n id != null ? `id:${id}` : `at:${lat},${lng}`;\n\ninterface MapFitterProps {\n points: MapFitPoint[];\n fitKey: string;\n maxZoom: number;\n onCameraMove: () => void;\n}\n\nfunction MapFitter({\n points,\n fitKey,\n maxZoom,\n onCameraMove,\n}: MapFitterProps): null {\n const map = useMap();\n const fitted = useRef<{\n map: google.maps.Map;\n key: string;\n points: Set<string>;\n } | null>(null);\n // Whether the patient has panned or zoomed since the last fit: any\n // camera the kit did not set counts. Comparing with the camera the kit\n // last set (rather than flagging the kit's own call) holds whether\n // Google reports the change at once or later, and catches keyboard and\n // control-button pans, which fire no `dragstart`.\n const userMoved = useRef(false);\n const ownCamera = useRef<{ center: MapLatLng; zoom: number } | null>(null);\n\n useEffect(() => {\n if (!map) return undefined;\n const check = (): void => {\n const own = ownCamera.current;\n const center = map.getCenter()?.toJSON();\n const zoom = map.getZoom();\n const same =\n own != null &&\n zoom === own.zoom &&\n center != null &&\n Math.abs(center.lat - own.center.lat) < 1e-6 &&\n Math.abs(center.lng - own.center.lng) < 1e-6;\n if (!same) userMoved.current = true;\n };\n const listeners = [\n map.addListener('dragstart', () => {\n userMoved.current = true;\n }),\n map.addListener('center_changed', check),\n map.addListener('zoom_changed', check),\n ];\n return () => listeners.forEach((listener) => listener.remove());\n }, [map]);\n\n useEffect(() => {\n if (!map) return undefined;\n const last = fitted.current?.map === map ? fitted.current : null;\n if (last?.key === fitKey) return undefined;\n const keys = new Set(points.map(pointKey));\n const moveCamera = (center: MapLatLng, zoom: number): void => {\n ownCamera.current = { center, zoom };\n onCameraMove();\n // One step, never animated.\n map.moveCamera({ center, zoom });\n userMoved.current = false;\n };\n\n if (points.length === 0) {\n // Nothing to fit. MapView returns the camera to center/zoom when\n // fitting ends. Recording the empty set means the same results\n // coming back later count as a change and fit again.\n fitted.current = { map, key: fitKey, points: keys };\n return undefined;\n }\n\n // More of the same results (\"load more\"): every point already fitted\n // is still listed, by identity. If the patient has moved the map,\n // their view wins. A result replaced by another at the same address\n // is a different id, so that set refits.\n const grewOnly =\n last != null &&\n last.points.size > 0 &&\n [...last.points].every((point) => keys.has(point));\n if (grewOnly && userMoved.current) {\n fitted.current = { map, key: fitKey, points: keys };\n return undefined;\n }\n\n const div = map.getDiv();\n // Only a fake map has no element; there is nothing to measure.\n if (!(div instanceof Element)) return undefined;\n const fit = (): void => {\n fitted.current = { map, key: fitKey, points: keys };\n // Never more than a quarter of either side, so a small map still\n // has room to fit the points rather than zooming out to the world.\n const padding = Math.min(\n lengthTokenPx('--spacing-2xl', div, 48),\n div.clientWidth / 4,\n div.clientHeight / 4,\n );\n const { center, zoom } = cameraForPoints(\n points,\n div.clientWidth,\n div.clientHeight,\n padding,\n maxZoom,\n );\n moveCamera(center, zoom);\n };\n const laidOut = (): boolean => div.clientWidth > 0 && div.clientHeight > 0;\n if (laidOut() || typeof ResizeObserver === 'undefined') {\n fit();\n return undefined;\n }\n const observer = new ResizeObserver(() => {\n if (!laidOut()) return;\n observer.disconnect();\n fit();\n });\n observer.observe(div);\n return () => observer.disconnect();\n }, [map, fitKey, points, maxZoom, onCameraMove]);\n return null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Library gates */\n/* */\n/* APIProvider reports LOADED as soon as `google.maps.importLibrary` */\n/* exists when another loader installed it (Google's bootstrap, a host */\n/* Places loader), before the `maps` library itself has arrived. <Map> */\n/* would then run `new google.maps.Map` and throw, taking the host's */\n/* React tree down. The map waits for `maps`, and the markers for */\n/* `marker`, whoever loaded the API. Before the API loads, <Map> only */\n/* renders its empty container, and once a constructor exists nothing */\n/* can throw, so both pass straight through as they always did. */\n/* ------------------------------------------------------------------ */\n\ntype GoogleMapsGlobal = {\n google?: { maps?: { Map?: unknown; Marker?: unknown } };\n};\nconst hasConstructor = (name: 'Map' | 'Marker'): boolean =>\n typeof (globalThis as GoogleMapsGlobal).google?.maps?.[name] === 'function';\n\n/** What the map area shows while Google's map library is on its way.\n * Exported for its story; not part of the public API. */\nexport function MapViewLoading(): ReactNode {\n const { t } = useTranslation('ui');\n return (\n <div\n role=\"status\"\n data-testid=\"map-view-loading\"\n className=\"ds:[inline-size:100%] ds:[block-size:100%]\"\n >\n <Skeleton variant=\"rectangular\" width=\"100%\" height=\"100%\" />\n <VisuallyHidden>{t('common.loading')}</VisuallyHidden>\n </div>\n );\n}\n\nfunction MapsLibraryGate({ children }: { children: ReactNode }): ReactNode {\n const apiIsLoaded = useApiIsLoaded();\n const maps = useMapsLibrary('maps');\n if (maps || !apiIsLoaded || hasConstructor('Map')) return children;\n return <MapViewLoading />;\n}\n\nfunction MarkerLibraryGate({ children }: { children: ReactNode }): ReactNode {\n const marker = useMapsLibrary('marker');\n return marker || hasConstructor('Marker') ? children : null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Consent placeholder */\n/* ------------------------------------------------------------------ */\n\ninterface ConsentPlaceholderProps {\n address: string | undefined;\n description: ReactNode;\n /**\n * Click handler for the \"Load map\" button. Always rendered. When the\n * consumer provides `onConsentRequest` it owns the state transition\n * (typically: open a GDPR dialog, then flip `consentGranted` to true\n * after acceptance). When omitted, the kit's `MapView` falls back to\n * its own internal opt-in toggle — clicking grants consent for this\n * MapView instance only, no consumer plumbing required. This default\n * fixes a regression where the button was conditionally rendered and\n * any consumer omitting `onConsentRequest` left the patient with no\n * way to load the map (booking-website 0.31.0 hit this).\n */\n onLoadMap: () => void;\n openInGoogleMapsHref: string;\n /**\n * Custom CTA — replaces the kit-rendered `<Button>` when the consumer\n * needs a different surface (e.g. a Tooltip-wrapped button with a\n * policy link). The kit's button is still the recommended path; this\n * slot exists for consumers operating under specific compliance UX\n * requirements (jurisdiction, named controller, policy link). Pass\n * any `ReactNode`.\n */\n consentCta: ReactNode | undefined;\n}\n\nfunction ConsentPlaceholder({\n address,\n description,\n onLoadMap,\n openInGoogleMapsHref,\n consentCta,\n}: ConsentPlaceholderProps): ReactNode {\n const { t } = useTranslation('ui');\n return (\n <div className={consentChromeVariants()} data-testid=\"map-view-consent\">\n <MapPin\n aria-hidden=\"true\"\n className=\"ds:size-6 ds:text-[var(--muted-foreground)]\"\n />\n <p className={consentTitleVariants()}>{t('mapView.consentTitle')}</p>\n {address ? (\n <p\n className={consentDescriptionVariants()}\n data-testid=\"map-view-address\"\n >\n {address}\n </p>\n ) : null}\n <p className={consentDescriptionVariants()}>{description}</p>\n <div className=\"ds:flex ds:gap-[var(--spacing-sm)] ds:flex-wrap ds:items-center ds:justify-center\">\n {consentCta ?? (\n <Button\n type=\"button\"\n intent=\"primary\"\n size=\"sm\"\n onClick={onLoadMap}\n data-testid=\"map-view-load-cta\"\n >\n {t('mapView.consentCta')}\n </Button>\n )}\n <a\n href={openInGoogleMapsHref}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:text-[var(--primary-readable)] ds:underline ds:underline-offset-2\"\n >\n {t('mapView.openInGoogleMaps')}\n <ExternalLink aria-hidden=\"true\" className=\"ds:size-3\" />\n </a>\n </div>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* MapView */\n/* ------------------------------------------------------------------ */\n\nexport const MapView = forwardRef<MapViewHandle, MapViewProps>(\n (\n {\n id,\n apiKey,\n center,\n zoom = 15,\n markers,\n selectedMarkerId,\n onMarkerClick,\n onBoundsChange,\n consentGranted = false,\n onConsentRequest,\n address,\n consentDescription,\n consentCta,\n mapId,\n size,\n surface,\n ariaLabel,\n fitToPoints,\n fitKey,\n fitMaxZoom = 15,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const fitPoints = useMemo(() => fitToPoints ?? [], [fitToPoints]);\n // Identity and place: a result that keeps its id but moves (a\n // corrected address) still refits. \"Only grew\" uses identity alone.\n const resolvedFitKey = useMemo(\n () =>\n fitKey ??\n fitPoints\n .map((point) => `${pointKey(point)}@${point.lat},${point.lng}`)\n .sort()\n .join('|'),\n [fitKey, fitPoints],\n );\n // While there are points, the fit owns the camera (see `fitToPoints`).\n const fitting = fitPoints.length > 0;\n const wasFitting = useRef(fitting);\n const rawId = useId();\n const instanceId = useMemo(\n () => `map-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}`,\n [rawId],\n );\n\n // Reduced-motion gating. Google's own pan / zoom animations\n // happen inside the Maps JS API and the kit can't reach into\n // those — but the kit's own programmatic `panTo` calls (triggered\n // by prop changes via the controlled-sync effect below) can be\n // suppressed. When `prefers-reduced-motion: reduce` is set, we\n // skip the synthetic `panTo` so the consumer's prop change\n // results in a hard recenter rather than an animated glide.\n const [reducedMotion, setReducedMotion] = useState(false);\n useEffect(() => {\n if (typeof window === 'undefined') return undefined;\n const mql = window.matchMedia('(prefers-reduced-motion: reduce)');\n const sync = (): void => setReducedMotion(mql.matches);\n sync();\n mql.addEventListener('change', sync);\n return () => mql.removeEventListener('change', sync);\n }, []);\n\n // The \"Open in Google Maps\" fallback link — works without any\n // third-party script load. Uses the modern `?api=1&query=…` form\n // which the booking site already employs.\n const openInGoogleMapsHref = useMemo(() => {\n const query = address\n ? encodeURIComponent(address)\n : `${center.lat},${center.lng}`;\n return `https://www.google.com/maps/search/?api=1&query=${query}`;\n }, [address, center.lat, center.lng]);\n\n // 0.33.5: removed the kit's `getGoogleMapsTheme()` JSON-styles\n // override. Previously, when `mapId` was absent the kit painted\n // water / roads / landscape with kit tokens — a calm muted-grey\n // palette that diverged from the standard Google Maps appearance\n // users expect in every other maps surface they touch. Google's\n // default (blue water, beige land, named-road colours) is more\n // familiar and reads as a \"real map\" rather than a stylised one.\n //\n // Consumers wanting brand-themed colours opt in via `mapId` and\n // configure the palette in Google Cloud Console — that's the\n // Google-recommended path. The `getGoogleMapsTheme` export stays\n // in `src/tokens/google-maps-theme.ts` so consumers wanting the\n // old behaviour can apply the styles themselves, but the kit\n // does NOT install them by default any more.\n //\n // Side benefit: dropped the MutationObserver that previously\n // watched documentElement.class for theme switches — no more\n // observer churn on every theme toggle.\n\n // Imperative handle plumbing — populated by the inner bridge once\n // the APIProvider tree resolves a `Map` instance.\n const handleRef = useRef<MapBridgeHandle | null>(null);\n const userInteraction = useRef<MapInteraction>({\n pendingInput: false,\n moved: false,\n programmatic: false,\n });\n const onCameraMove = useCallback(() => {\n userInteraction.current = {\n pendingInput: false,\n moved: false,\n programmatic: true,\n };\n }, []);\n const handleMarkerClick = useCallback(\n (markerId: string | null) => {\n onCameraMove();\n onMarkerClick?.(markerId);\n },\n [onCameraMove, onMarkerClick],\n );\n const onHandleReady = useCallback((handle: MapBridgeHandle | null) => {\n handleRef.current = handle;\n }, []);\n\n // Read in the OUTER component, not through `handleRef` — these three\n // must still answer when the map subtree is unmounted, which is\n // exactly the situation an agent needs explaining. Assigned during\n // render, below, once `effectiveConsent` exists.\n const consentRef = useRef(false);\n const selectedMarkerIdRef = useRef<string | null>(null);\n const markerCountRef = useRef(0);\n\n const buildHandle = useCallback(\n (): MapViewHandle => ({\n panTo: (position) => handleRef.current?.panTo(position),\n setZoom: (z) => handleRef.current?.setZoom(z),\n selectMarker: (markerId) => handleRef.current?.selectMarker(markerId),\n // Without `isConsentGranted` an agent has no way to learn that\n // its pan / zoom / select was swallowed by the GDPR gate rather\n // than applied: under the default (`consentGranted={false}`) the\n // whole Maps subtree is unmounted and every action optional-chains\n // into nothing.\n isConsentGranted: () => consentRef.current,\n getCenter: () => handleRef.current?.getCenter() ?? null,\n getZoom: () => handleRef.current?.getZoom() ?? null,\n getSelectedMarkerId: () => selectedMarkerIdRef.current,\n getMarkerCount: () => markerCountRef.current,\n }),\n [],\n );\n useImperativeHandle(ref, buildHandle, [buildHandle]);\n\n const agentHandle = useMemo<MapViewHandle>(\n () => buildHandle(),\n [buildHandle],\n );\n useAgentRegistration(mapViewAgent, agentHandle, id);\n\n // Controlled-feeling propagation: vis.gl's `<Map>` reads `center`\n // and `zoom` as initial values only (via `defaultCenter` /\n // `defaultZoom`). To honour the documented \"live prop\" contract\n // we shim post-mount sync through the imperative bridge — a\n // parent that swaps offices by changing `center` re-centres the\n // map. User drag does NOT trigger this because the prop doesn't\n // change on user gesture, so the effect doesn't fire and the\n // map stays where the user left it.\n //\n // While fitting, the fit owns the camera and both syncs stand down.\n // `fitting` is a dependency, so when fitting ends (the points run out\n // or `fitToPoints` is removed) the camera returns to `center` / `zoom`\n // even if neither changed. That return is one step, not animated, so\n // it applies under reduced motion too.\n useEffect(() => {\n const fitEnded = wasFitting.current && !fitting;\n wasFitting.current = fitting;\n if (fitting) return;\n if (fitEnded) {\n handleRef.current?.jumpTo(center, zoom);\n return;\n }\n // Skip the animated pan under reduced-motion preference; the\n // map will still recentre on the next render via the agent\n // handle's `panTo`, but Google's own glide animation runs\n // either way (kit can't reach inside it). At least the kit's\n // own initiated pan is gated.\n if (reducedMotion) return;\n handleRef.current?.panTo(center);\n // Including `center` (the object reference) instead of\n // `center.lat`/`center.lng` would fire on every parent render\n // even when the coordinates are identical, fighting user drag.\n // `zoom` is read only when fitting ends; its own sync is below.\n // The destructured deps are intentional.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [center.lat, center.lng, reducedMotion, fitting]);\n useEffect(() => {\n if (fitting) return;\n handleRef.current?.setZoom(zoom);\n }, [zoom, fitting]);\n\n // Internal opt-in fallback. The `consentGranted` prop is the\n // controlled path — consumer flips it after capturing GDPR\n // acceptance through their own dialog and re-renders. When the\n // consumer omits `onConsentRequest` they're opting out of that\n // workflow, so the kit needs a sensible default click handler on\n // the placeholder's button. `internalConsent` tracks that opt-in\n // for this instance only; the map renders when either signal is\n // truthy. The 0.31.0 regression was conditionally rendering the\n // button on `onConsentRequest` — patients of consumers without the\n // hook saw the placeholder with no way to proceed.\n const [internalConsent, setInternalConsent] = useState(false);\n const effectiveConsent = consentGranted || internalConsent;\n // Mirror the three props-derived agent state slots. Assigned during\n // render so a read immediately after a prop change sees the settled\n // value. Ids and a count only — never `MapMarker.label`, never the\n // `address` prop (consumer-supplied free text, PII in any\n // patient-address deployment), never `apiKey`.\n consentRef.current = effectiveConsent;\n selectedMarkerIdRef.current = selectedMarkerId ?? null;\n markerCountRef.current = (markers ?? []).length;\n const handleLoadMap = useCallback(() => {\n if (onConsentRequest) {\n onConsentRequest();\n // The consumer typically flips `consentGranted` to true on the\n // next render. Flip the internal state too so the map still\n // loads if the consumer forgets to update its prop (the\n // common-case footgun this fallback exists to defuse).\n setInternalConsent(true);\n return;\n }\n setInternalConsent(true);\n }, [onConsentRequest]);\n\n return (\n <div\n className={mapViewVariants({ size, surface, className })}\n data-component=\"map-view\"\n data-component-id={id ?? instanceId}\n role=\"region\"\n aria-label={ariaLabel ?? t('mapView.label')}\n {...rest}\n >\n <div className={innerSurfaceVariants({ size })}>\n {effectiveConsent ? (\n // A provider failure shows the consent placeholder (its \"Open in\n // Google Maps\" link needs no script) with \"Load map\" as the\n // retry, instead of unmounting the host's React tree. The gate\n // starts the provider only once Google's `core` and `maps`\n // libraries have arrived.\n <ErrorBoundary\n fallback={({ reset }) => (\n <ConsentPlaceholder\n address={address}\n description={\n consentDescription ?? t('mapView.consentDescription')\n }\n onLoadMap={reset}\n // Always the kit button: a host's own CTA would not call\n // `reset`, so with consent already granted it would do\n // nothing and the patient could not retry.\n consentCta={undefined}\n openInGoogleMapsHref={openInGoogleMapsHref}\n />\n )}\n >\n <MapsCoreGate libraries={['maps']} pending={<MapViewLoading />}>\n <APIProvider\n apiKey={apiKey}\n // Pull the active i18next locale through so map UI text\n // (zoom controls, attribution) localises to match the\n // surrounding kit chrome.\n language={i18n.language}\n >\n <MapsLibraryGate>\n <GoogleMap\n defaultCenter={center}\n defaultZoom={zoom}\n mapId={mapId}\n gestureHandling=\"cooperative\"\n disableDefaultUI={false}\n onClick={() => handleMarkerClick(null)}\n // `<Map>` reads its own bounding rect for tile sizing.\n // Without explicit dimensions it collapses to 0×0, so\n // we pass kit-class sizing through `className` — vis.gl\n // forwards `className` straight to the rendered root.\n className=\"ds:[inline-size:100%] ds:[block-size:100%]\"\n >\n <MapImperativeBridge\n onHandleReady={onHandleReady}\n onMarkerSelect={handleMarkerClick}\n onCameraMove={onCameraMove}\n />\n {onBoundsChange ? (\n <MapBoundsBridge\n onBoundsChange={onBoundsChange}\n userInteraction={userInteraction}\n />\n ) : null}\n {fitToPoints ? (\n <MapFitter\n points={fitPoints}\n fitKey={resolvedFitKey}\n maxZoom={fitMaxZoom}\n onCameraMove={onCameraMove}\n />\n ) : null}\n <MarkerLibraryGate>\n {(markers ?? []).map((marker) => {\n // Selection state is exposed to the consumer via\n // `data-selected` on the marker root so consumers can\n // style their own InfoWindow / sidebar highlight from\n // it. The kit does NOT swap the Pin's fill colour on\n // selection — `--accent` (magenta-500 in light theme)\n // fails AA on white per 05-accessibility.mdx, and the\n // alternative tokens that pass (`--info`, `--success`)\n // carry semantic baggage. Visual selection state is\n // the consumer's call.\n const isSelected =\n selectedMarkerId != null &&\n selectedMarkerId === marker.id;\n const accessibleLabel = t('mapView.markerLabel', {\n label: marker.label ?? marker.id,\n });\n // Pin implementation switches on whether the\n // consumer supplied `mapId`. Google's\n // AdvancedMarkerElement requires the Map instance to\n // be initialised with a valid Map ID — without one\n // the API logs an error (\"La mappa è stata\n // inizializzata senza un ID mappa valido\") and any\n // AdvancedMarker rendered against that map fails to\n // appear. Cloud Map IDs are an opt-in feature; many\n // consumers (booking-website env without\n // GOOGLE_MAPS_MAP_ID, the OSS demo, etc.) legitimately\n // omit it.\n //\n // Fall back to the classic <Marker> (a thin wrapper\n // around google.maps.Marker) when mapId is absent.\n // Google has formally deprecated google.maps.Marker\n // but it still renders cleanly and produces no\n // console errors; the only loss is the brand-tinted\n // <Pin> chrome (which Marker doesn't accept as a\n // child). When a consumer wants the styled pin they\n // can opt back in by supplying `mapId`.\n if (mapId) {\n return (\n <AdvancedMarker\n key={marker.id}\n position={marker.position}\n // `title` becomes the HTML `title` attribute on\n // Google's marker wrapper — that's a tooltip, not\n // a reliable accessible name. The wrapper also\n // receives `aria-label` which Google honours as\n // the SR-announced name. Both are set so sighted\n // hover tooltips and SR labels stay aligned.\n title={accessibleLabel}\n aria-label={accessibleLabel}\n data-selected={isSelected ? 'true' : 'false'}\n onClick={() => handleMarkerClick(marker.id)}\n >\n <Pin\n background={'var(--primary)'}\n borderColor={'var(--primary)'}\n glyphColor={'var(--primary-foreground)'}\n />\n </AdvancedMarker>\n );\n }\n return (\n <Marker\n key={marker.id}\n position={marker.position}\n title={accessibleLabel}\n onClick={() => handleMarkerClick(marker.id)}\n />\n );\n })}\n </MarkerLibraryGate>\n </GoogleMap>\n </MapsLibraryGate>\n </APIProvider>\n </MapsCoreGate>\n </ErrorBoundary>\n ) : (\n <ConsentPlaceholder\n address={address}\n description={\n consentDescription ?? t('mapView.consentDescription')\n }\n onLoadMap={handleLoadMap}\n consentCta={consentCta}\n openInGoogleMapsHref={openInGoogleMapsHref}\n />\n )}\n </div>\n </div>\n );\n },\n);\nMapView.displayName = 'MapView';\n"],"names":["mapViewAgent","handle","args","mapViewVariants","cva","innerSurfaceVariants","consentChromeVariants","consentTitleVariants","consentDescriptionVariants","MapImperativeBridge","onHandleReady","onMarkerSelect","onCameraMove","map","useMap","useEffect","position","zoom","center","id","_a","MapBoundsBridge","onBoundsChange","userInteraction","callback","useRef","div","previous","resetInteraction","inputExpiry","touchPointers","markInput","event","fullscreen","fullscreenMap","cameraInput","markCameraChange","report","bounds","_b","fromInput","changed","key","moved","inputEvents","listeners","listener","WORLD_PX","toRadians","degrees","mercatorY","lat","sin","latitudeOf","y","boundsOfPoints","points","north","south","east","west","lng","cameraForPoints","width","height","padding","maxZoom","top","bottom","fit","px","fraction","pointKey","MapFitter","fitKey","fitted","userMoved","ownCamera","check","own","last","keys","moveCamera","point","lengthTokenPx","laidOut","observer","hasConstructor","name","MapViewLoading","t","useTranslation","jsxs","jsx","Skeleton","VisuallyHidden","MapsLibraryGate","children","apiIsLoaded","useApiIsLoaded","useMapsLibrary","MarkerLibraryGate","ConsentPlaceholder","address","description","onLoadMap","openInGoogleMapsHref","consentCta","MapPin","Button","ExternalLink","MapView","forwardRef","apiKey","markers","selectedMarkerId","onMarkerClick","consentGranted","onConsentRequest","consentDescription","mapId","size","surface","ariaLabel","fitToPoints","fitMaxZoom","className","rest","ref","i18n","fitPoints","useMemo","resolvedFitKey","fitting","wasFitting","rawId","useId","instanceId","reducedMotion","setReducedMotion","useState","mql","sync","handleRef","useCallback","handleMarkerClick","markerId","consentRef","selectedMarkerIdRef","markerCountRef","buildHandle","z","useImperativeHandle","agentHandle","useAgentRegistration","fitEnded","internalConsent","setInternalConsent","effectiveConsent","handleLoadMap","ErrorBoundary","reset","MapsCoreGate","APIProvider","GoogleMap","marker","isSelected","accessibleLabel","AdvancedMarker","Pin","Marker"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"multi-select-i5MFRpXg.js","sources":["../../src/components/multi-select/multi-select.agent.ts","../../src/components/multi-select/multi-select.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { MultiSelectHandle } from './multi-select';\n\nexport const multiSelectAgent: AgentAdapter<MultiSelectHandle> = {\n id: 'multi-select',\n // Persisted multi-choice (selection state + set_selection) → select_multiple,\n // plus type-to-filter and open/close of the option list.\n capabilities: ['select_multiple', 'filter', 'open', 'close'],\n state: {\n selection: {\n type: 'string[]',\n descriptionKey: 'ui.agent.multiSelect.state.selection',\n description: 'Values of currently-selected options.',\n read: (handle) => handle.getSelection(),\n },\n query: {\n type: 'string',\n descriptionKey: 'ui.agent.multiSelect.state.query',\n description: 'Current filter query.',\n read: (handle) => handle.getQuery(),\n },\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.multiSelect.state.isOpen',\n description: 'True when the option list is visible.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n set_selection: {\n // Persists the user's chosen options — reversible via the same UI.\n safety: 'write',\n argsType: '{ values: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n values: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Option values to select (replaces the current selection).',\n },\n },\n required: ['values'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.setSelection',\n description:\n 'Replace the current selection with the given list of values.',\n examples: [\n {\n args: { values: ['a', 'b'] },\n note: 'Select exactly options \"a\" and \"b\".',\n },\n ],\n invoke: (handle, args: { values: string[] }) => {\n handle.setSelection(args.values);\n },\n },\n clear_selection: {\n // Discards the persisted selection — destructive (loses the choices).\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.clearSelection',\n description: 'Clear the current selection.',\n invoke: (handle) => {\n handle.clearSelection();\n },\n },\n apply_filter: {\n // Pure ephemeral filter of the visible options — no persisted change.\n safety: 'read',\n argsType: '{ query: string }',\n argsSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Filter text for the list.' },\n },\n required: ['query'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.applyFilter',\n description: 'Set the filter query for the option list.',\n invoke: (handle, args: { query: string }) => {\n handle.setQuery(args.query);\n },\n },\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.open',\n description: 'Open the option list.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.close',\n description: 'Close the option list.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'multi-select' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-option-id',\n description: 'Each option emits its value as data-option-id.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type Ref,\n} from 'react';\nimport * as Popover from '@radix-ui/react-popover';\nimport { Command } from 'cmdk';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Check, X } from 'lucide-react';\nimport {\n FormFieldContext,\n useFormField,\n useFormFieldControlRef,\n} from '../form-field/form-field-context';\nimport { Tooltip } from '../tooltip';\nimport type { OptionShape } from '../_shared/option';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { groupOptions } from '../_shared/group-options';\nimport { MENU_ROW_HIGHLIGHT } from '../_shared/menu-row';\nimport {\n OPTION_BODY_CLASSES,\n OPTION_END_CLASSES,\n OPTION_LABEL_ROW_CLASSES,\n optionDescriptionVariants,\n optionLabelVariants,\n} from '../_shared/option-row';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_TEXT,\n} from '../_shared/input-surface';\nimport { useAgentRegistration } from '../../agent';\nimport { multiSelectAgent } from './multi-select.agent';\n\n// MultiSelect uses `min-h-*` (not `h-*`) because the wrapper grows vertically\n// as chips wrap to additional lines. The height floor per size mirrors the\n// other inputs' fixed heights in _shared/input-surface.ts.\nconst multiSelectVariants = cva(\n [\n 'ds:inline-flex ds:flex-wrap ds:items-center ds:gap-1 ds:w-full',\n INPUT_SURFACE_CHROME,\n 'ds:aria-[invalid=true]:border-destructive',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50',\n ],\n {\n variants: {\n size: {\n sm: `ds:min-h-8 ds:ps-2 ds:pe-2 ds:py-1 ${INPUT_SURFACE_TEXT.sm}`,\n md: `ds:min-h-[var(--min-target-size)] ds:ps-3 ds:pe-3 ds:py-1.5 ${INPUT_SURFACE_TEXT.md}`,\n lg: `ds:min-h-12 ds:ps-4 ds:pe-4 ds:py-2 ${INPUT_SURFACE_TEXT.lg}`,\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst chipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-1',\n 'ds:rounded-[var(--radius-sm)] ds:border ds:border-border ds:bg-muted',\n 'ds:text-foreground ds:select-none',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ],\n {\n variants: {\n size: {\n sm: 'ds:ps-2 ds:pe-1 ds:py-0.5 ds:text-[length:var(--font-size-xs)]',\n md: 'ds:ps-2 ds:pe-1 ds:py-0.5 ds:text-[length:var(--font-size-sm)]',\n lg: 'ds:ps-3 ds:pe-1.5 ds:py-1 ds:text-[length:var(--font-size-base)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst chipDismissClasses = [\n 'ds:inline-flex ds:items-center ds:justify-center ds:shrink-0',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-muted-foreground ds:hover:text-foreground',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:size-4',\n 'ds:relative ds:before:absolute ds:before:inset-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"]',\n].join(' ');\n\nconst popoverContentClasses = [\n 'ds:z-[var(--z-dropdown)] ds:overflow-hidden',\n // At least as wide as the field, at most as wide as the screen allows: a\n // long option wraps or ends in an ellipsis instead of running off the\n // edge. The floor gives way to the cap on a field wider than that.\n 'ds:min-w-[min(var(--radix-popover-trigger-width),var(--radix-popover-content-available-width))]',\n 'ds:max-w-[var(--radix-popover-content-available-width)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-border ds:bg-background ds:text-foreground',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:animate-in ds:fade-in ds:zoom-in-95',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out',\n 'ds:data-[state=closed]:zoom-out-95',\n 'ds:data-[side=bottom]:slide-in-from-top-2',\n 'ds:data-[side=top]:slide-in-from-bottom-2',\n 'ds:motion-reduce:animate-none',\n].join(' ');\n\nconst commandItemClasses = [\n 'ds:relative ds:flex ds:cursor-pointer ds:items-center',\n 'ds:rounded-[var(--radius-sm)] ds:ps-2 ds:pe-2 ds:py-1.5',\n 'ds:text-[var(--font-size-sm)] ds:text-foreground ds:outline-none ds:select-none',\n MENU_ROW_HIGHLIGHT.selected,\n 'ds:aria-[disabled=true]:pointer-events-none ds:aria-[disabled=true]:opacity-50',\n 'ds:data-[disabled=true]:pointer-events-none ds:data-[disabled=true]:opacity-50',\n].join(' ');\n\nconst actionItemClasses = [\n 'ds:relative ds:flex ds:cursor-pointer ds:items-center',\n 'ds:rounded-[var(--radius-sm)] ds:ps-2 ds:pe-2 ds:py-1.5',\n 'ds:text-[var(--font-size-sm)] ds:font-medium ds:text-primary ds:outline-none ds:select-none',\n MENU_ROW_HIGHLIGHT.selected,\n].join(' ');\n\nconst SELECT_ALL_VALUE = '__ui-multiselect-select-all__';\nconst CLEAR_ALL_VALUE = '__ui-multiselect-clear-all__';\n\ntype HTMLDivAttributes = HTMLAttributes<HTMLDivElement>;\n\n// Curated agent-readiness handle — see multi-select.agent.ts.\nexport interface MultiSelectHandle {\n getSelection: () => string[];\n getQuery: () => string;\n getIsOpen: () => boolean;\n setSelection: (values: string[]) => void;\n clearSelection: () => void;\n setQuery: (query: string) => void;\n open: () => void;\n close: () => void;\n}\n\nexport interface MultiSelectProps<T extends string = string>\n extends\n Omit<HTMLDivAttributes, 'onChange'>,\n VariantProps<typeof multiSelectVariants> {\n options: OptionShape<T>[];\n value?: T[];\n defaultValue?: T[];\n onChange?: (next: T[]) => void;\n onComplete?: (values: T[]) => void;\n placeholder?: string;\n maxSelections?: number;\n allowSelectAll?: boolean;\n allowClear?: boolean;\n filter?: (query: string, option: OptionShape<T>) => boolean;\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n /**\n * Let a long option label wrap onto a second line instead of ending in an\n * ellipsis. Longer still, it is clipped after two lines. Off by default.\n * An option's `description` always sits on its own line under the label.\n */\n wrapOptionLabels?: boolean;\n}\n\nconst MultiSelectImpl = forwardRef<HTMLDivElement, MultiSelectProps>(\n function MultiSelect(\n {\n options,\n value,\n defaultValue,\n onChange,\n onComplete,\n placeholder,\n maxSelections,\n allowSelectAll = false,\n allowClear = false,\n filter,\n size = 'md',\n disabled,\n wrapOptionLabels = false,\n className,\n id,\n // Pull `aria-label` out of the div spread so it names the combobox\n // INPUT (the interactive control) rather than the wrapper div. Lets a\n // consumer give the trigger a meaningful name when there's no visible\n // label or FormField (e.g. a data-table floating filter naming itself\n // after its column). Untouched callers fall back to the placeholder.\n // Inside a FormField the field's label names the input and this is\n // ignored, so it can never override the visible text (WCAG 2.5.3).\n 'aria-label': ariaLabel,\n ...divProps\n },\n ref,\n ) {\n const { t } = useTranslation('ui');\n const ctx = useFormField();\n const inFormField = useContext(FormFieldContext) !== null;\n\n const [currentValueRaw, setMultiSelectValue] = useControllableState<\n string[]\n >({\n value,\n defaultValue: defaultValue ?? [],\n onChange,\n });\n const currentValue = currentValueRaw ?? [];\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const inputRef = useRef<HTMLInputElement>(null);\n const counterId = `${useId()}-count`;\n const chipRefs = useRef<Array<HTMLSpanElement | null>>([]);\n const triggerRef = useRef<HTMLDivElement>(null);\n const composedRef = composeRefs<HTMLDivElement>(ref, triggerRef);\n\n // Chips are spans: a disabled ancestor fieldset does not reach them.\n const [inDisabledFieldset, setInDisabledFieldset] = useState(false);\n useIsomorphicLayoutEffect(() => {\n setInDisabledFieldset(\n Boolean(triggerRef.current?.closest('fieldset:disabled')),\n );\n });\n const effectiveDisabled =\n (inFormField && ctx.disabled) || Boolean(disabled) || inDisabledFieldset;\n const effectiveRequired = inFormField && ctx.required;\n const effectiveInvalid = inFormField && ctx.invalid;\n const describedBy =\n inFormField && ctx.describedBy ? ctx.describedBy : undefined;\n const triggerId = id ?? (inFormField ? ctx.id : undefined);\n /* cmdk writes its own id on the input, so the field's label follows\n that one. */\n useFormFieldControlRef(ctx, inputRef);\n\n const labelByValue = useMemo(() => {\n const map = new Map<string, string>();\n for (const option of options) map.set(option.value, option.label);\n return map;\n }, [options]);\n const dirByValue = useMemo(() => {\n const map = new Map<string, OptionShape['dir']>();\n for (const option of options) map.set(option.value, option.dir);\n return map;\n }, [options]);\n\n const atCap =\n typeof maxSelections === 'number' && currentValue.length >= maxSelections;\n\n const commit = (next: string[]): void => {\n setMultiSelectValue(next);\n };\n\n const toggle = (val: string): void => {\n if (currentValue.includes(val)) {\n commit(currentValue.filter((v) => v !== val));\n return;\n }\n if (atCap) return;\n commit([...currentValue, val]);\n };\n\n const removeAt = (index: number): string[] => {\n const next = currentValue.filter((_, i) => i !== index);\n commit(next);\n return next;\n };\n\n const handleSelectAll = (): void => {\n const selectable = options.filter((o) => !o.disabled).map((o) => o.value);\n const cap =\n typeof maxSelections === 'number' ? maxSelections : selectable.length;\n commit(selectable.slice(0, cap));\n };\n\n const handleClearAll = (): void => {\n commit([]);\n };\n\n // Agent handle — refs for fresh reads from the memoized handle.\n const valueRef = useRef<string[]>(currentValue);\n useEffect(() => {\n valueRef.current = currentValue;\n }, [currentValue]);\n const queryRef = useRef<string>(query);\n useEffect(() => {\n queryRef.current = query;\n }, [query]);\n const openRef = useRef<boolean>(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const commitStable = useCallback(\n (next: string[]) => {\n setMultiSelectValue(next);\n },\n [setMultiSelectValue],\n );\n\n const agentHandle = useMemo<MultiSelectHandle>(\n () => ({\n getSelection: () => [...valueRef.current],\n getQuery: () => queryRef.current,\n getIsOpen: () => openRef.current,\n setSelection: (values) => commitStable(values),\n clearSelection: () => commitStable([]),\n setQuery: (next) => setQuery(next),\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [commitStable],\n );\n useAgentRegistration(multiSelectAgent, agentHandle, id);\n\n const resolvedPlaceholder =\n placeholder ?? t('inputs.multiSelect.placeholder', 'Select…');\n\n const filteredOptions = useMemo(() => {\n if (!query) return options;\n const needle = query.toLowerCase();\n return options.filter((option) => {\n if (filter) return filter(query, option);\n return option.label.toLowerCase().includes(needle);\n });\n }, [options, query, filter]);\n\n const groups = useMemo(\n () => groupOptions(filteredOptions),\n [filteredOptions],\n );\n\n const handleInputKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {\n const target = e.currentTarget;\n if (e.key === 'Backspace' && query === '' && currentValue.length > 0) {\n e.preventDefault();\n const removedIndex = currentValue.length - 1;\n const next = removeAt(removedIndex);\n const newLast = next.length - 1;\n if (newLast >= 0) {\n requestAnimationFrame(() => {\n chipRefs.current[newLast]?.focus();\n });\n }\n return;\n }\n const caretAtStart =\n target.selectionStart === 0 && target.selectionEnd === 0;\n if (\n (e.key === 'ArrowLeft' || e.key === 'ArrowRight') &&\n caretAtStart &&\n currentValue.length > 0\n ) {\n const isRTL = document.dir === 'rtl' || target.dir === 'rtl';\n const shouldNavigate =\n (isRTL && e.key === 'ArrowRight') ||\n (!isRTL && e.key === 'ArrowLeft');\n if (shouldNavigate) {\n e.preventDefault();\n const lastIdx = currentValue.length - 1;\n chipRefs.current[lastIdx]?.focus();\n }\n return;\n }\n if (e.key === 'Escape') {\n setOpen(false);\n return;\n }\n if (!open && (e.key === 'ArrowDown' || e.key === 'Enter')) {\n setOpen(true);\n }\n };\n\n const handleChipKeyDown =\n (index: number) =>\n (e: KeyboardEvent<HTMLSpanElement>): void => {\n if (\n e.key === 'Backspace' ||\n e.key === 'Delete' ||\n e.key === 'Enter' ||\n e.key === ' '\n ) {\n e.preventDefault();\n e.stopPropagation();\n const next = removeAt(index);\n if (next.length === 0) {\n requestAnimationFrame(() => inputRef.current?.focus());\n return;\n }\n const focusIdx = Math.min(index, next.length - 1);\n requestAnimationFrame(() => {\n chipRefs.current[focusIdx]?.focus();\n });\n return;\n }\n const isRTL = document.dir === 'rtl';\n const prevKey = isRTL ? 'ArrowRight' : 'ArrowLeft';\n const nextKey = isRTL ? 'ArrowLeft' : 'ArrowRight';\n if (e.key === prevKey) {\n e.preventDefault();\n const newIdx = Math.max(0, index - 1);\n chipRefs.current[newIdx]?.focus();\n return;\n }\n if (e.key === nextKey) {\n e.preventDefault();\n if (index < currentValue.length - 1) {\n chipRefs.current[index + 1]?.focus();\n } else {\n inputRef.current?.focus();\n }\n return;\n }\n if (e.key === 'Escape') {\n setOpen(false);\n inputRef.current?.focus();\n }\n };\n\n // ----- Chip overflow measurement -----\n // The measurement must read the FULL chip row, never the collapsed one.\n // Counting only the rendered (collapsed) chips is self-referential: hiding\n // the overflow behind \"+N more\" leaves a subset that trivially fits row 1,\n // the next measure concludes \"everything fits\", it expands, re-wraps, and\n // the ResizeObserver oscillates every frame (the visible flicker).\n //\n // Instead we run a two-pass cycle driven by `measureNonce`: a request first\n // renders every chip (visibleCount → ∞), then the layout effect measures\n // that complete row and sets the collapsed count. Both passes are layout\n // effects, so React flushes them before paint — the browser only ever shows\n // the settled, single-line result, with no full-row flash.\n const [visibleCount, setVisibleCount] = useState<number>(\n Number.POSITIVE_INFINITY,\n );\n const [measureNonce, setMeasureNonce] = useState<number>(0);\n const lastWidthRef = useRef<number>(-1);\n\n const requestMeasure = useCallback((): void => {\n setVisibleCount(Number.POSITIVE_INFINITY);\n setMeasureNonce((n) => n + 1);\n }, []);\n\n // Pass two: the \"show all\" render has committed — measure the true wrap\n // point off the complete chip row and collapse to it. Runs once per request\n // (keyed on measureNonce); collapsing does not bump the nonce, so it settles.\n useIsomorphicLayoutEffect(() => {\n const el = triggerRef.current;\n if (!el) return;\n const chipEls = Array.from(\n el.querySelectorAll<HTMLElement>('[data-ui-chip=\"true\"]'),\n );\n if (chipEls.length === 0) {\n setVisibleCount(Number.POSITIVE_INFINITY);\n return;\n }\n const firstTop = chipEls[0].offsetTop;\n let firstRowCount = 0;\n for (const chip of chipEls) {\n if (chip.offsetTop === firstTop) firstRowCount++;\n else break;\n }\n setVisibleCount(\n firstRowCount === chipEls.length\n ? Number.POSITIVE_INFINITY\n : Math.max(1, firstRowCount - 1),\n );\n }, [measureNonce]);\n\n // Re-measure whenever the selected set or the size variant changes.\n useIsomorphicLayoutEffect(() => {\n requestMeasure();\n }, [currentValue.length, size, requestMeasure]);\n\n // Re-measure on a real width change only. Collapsing shrinks the trigger's\n // height, not its width, so a width guard keeps that from re-triggering the\n // cycle — the ResizeObserver never chases its own output.\n useIsomorphicLayoutEffect(() => {\n const el = triggerRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n const width = Math.round(\n entries[0]?.contentRect.width ?? el.clientWidth,\n );\n if (width === lastWidthRef.current) return;\n lastWidthRef.current = width;\n requestMeasure();\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [requestMeasure]);\n\n const chips = currentValue.map((val) => ({\n value: val,\n label: labelByValue.get(val) ?? val,\n }));\n\n const showAllChips =\n visibleCount === Number.POSITIVE_INFINITY || visibleCount >= chips.length;\n const visibleChips = showAllChips ? chips : chips.slice(0, visibleCount);\n const overflowChips = showAllChips ? [] : chips.slice(visibleCount);\n const overflowCount = overflowChips.length;\n\n const handleTriggerClick = (event: MouseEvent<HTMLDivElement>): void => {\n if (effectiveDisabled) return;\n // Ignore clicks on chips/buttons so they can manage their own focus.\n const target = event.target as HTMLElement;\n if (target.closest('[data-ui-chip=\"true\"]')) return;\n if (target.closest('[data-ui-chip-dismiss=\"true\"]')) return;\n setOpen(true);\n inputRef.current?.focus();\n };\n\n const handleOpenChange = (next: boolean): void => {\n if (effectiveDisabled) {\n setOpen(false);\n return;\n }\n setOpen(next);\n if (!next) {\n setQuery('');\n onComplete?.(currentValue);\n }\n };\n\n const hasActionRow = allowSelectAll || allowClear;\n\n const counterMessage = t('inputs.multiSelect.selected', {\n count: currentValue.length,\n defaultValue: `${currentValue.length} selected`,\n });\n\n /* cmdk writes `aria-labelledby` on the input after the props it is\n given, pointing at its own hidden `<label cmdk-label>` whose text is\n the Command root's `label`. So that label is the input's name: the\n host's `aria-label`, else the placeholder, so the input is never\n unnamed. The count of chosen options describes the input rather than\n naming it. */\n const accessibleName =\n (inFormField ? ctx.label || ariaLabel : ariaLabel) || resolvedPlaceholder;\n const inputDescribedBy = [counterId, describedBy].filter(Boolean).join(' ');\n\n /* Inside a FormField the name is the field's own `<label>`, read whole,\n as for every other control: its labelStart and labelEnd marks and\n \"(optional)\" join it, and the host's `aria-label` never overrides\n that visible text. cmdk's hidden label holds the label string only,\n so the input is pointed at the field's label instead. React leaves\n the attribute alone afterwards: cmdk's prop for it never changes. */\n const fieldLabelId = inFormField ? `${ctx.id}-label` : undefined;\n const cmdkLabelledBy = useRef<string | null>(null);\n useIsomorphicLayoutEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const current = input.getAttribute('aria-labelledby');\n if (fieldLabelId) {\n if (current === fieldLabelId) return;\n cmdkLabelledBy.current = current;\n input.setAttribute('aria-labelledby', fieldLabelId);\n } else if (cmdkLabelledBy.current !== null) {\n // Out of the field again: back to cmdk's own label.\n input.setAttribute('aria-labelledby', cmdkLabelledBy.current);\n cmdkLabelledBy.current = null;\n }\n });\n\n const { onClick: onClickProp, ...restDivProps } = divProps;\n\n return (\n <Command shouldFilter={false} label={accessibleName}>\n <Popover.Root open={open} onOpenChange={handleOpenChange}>\n <Popover.Anchor asChild>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -- compound input shell; keyboard handling lives on the inner searchable input which is always rendered */}\n <div\n ref={composedRef}\n className={multiSelectVariants({ size, className })}\n aria-disabled={effectiveDisabled || undefined}\n aria-invalid={effectiveInvalid || undefined}\n data-component=\"multi-select\"\n data-component-id={id}\n onClick={(event) => {\n onClickProp?.(event);\n handleTriggerClick(event);\n }}\n {...restDivProps}\n >\n {visibleChips.map((chip, idx) => (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- chip pill receives focus via roving tabindex; chip removal uses an inner button\n <span\n key={chip.value}\n ref={(el) => {\n chipRefs.current[idx] = el;\n }}\n tabIndex={effectiveDisabled ? -1 : 0}\n data-ui-chip=\"true\"\n className={chipVariants({ size })}\n onKeyDown={handleChipKeyDown(idx)}\n aria-label={chip.label}\n >\n <span dir={dirByValue.get(chip.value)}>{chip.label}</span>\n <button\n type=\"button\"\n tabIndex={-1}\n data-ui-chip-dismiss=\"true\"\n aria-label={t('inputs.multiSelect.remove', {\n label: chip.label,\n defaultValue: `Remove ${chip.label}`,\n })}\n disabled={effectiveDisabled}\n onClick={(event) => {\n event.stopPropagation();\n removeAt(idx);\n requestAnimationFrame(() => inputRef.current?.focus());\n }}\n className={chipDismissClasses}\n >\n <X aria-hidden=\"true\" className=\"ds:size-3.5\" />\n </button>\n </span>\n ))}\n {overflowCount > 0 ? (\n <Tooltip\n label={overflowChips.map((c) => c.label).join(', ')}\n delayDuration={200}\n >\n <span\n className={chipVariants({ size })}\n tabIndex={effectiveDisabled ? -1 : 0}\n role=\"button\"\n aria-label={t('inputs.multiSelect.overflow', {\n count: overflowCount,\n defaultValue: `+${overflowCount} more`,\n })}\n >\n <span>\n {t('inputs.multiSelect.overflow', {\n count: overflowCount,\n defaultValue: `+${overflowCount} more`,\n })}\n </span>\n </span>\n </Tooltip>\n ) : null}\n <Command.Input\n ref={inputRef}\n value={query}\n onValueChange={setQuery}\n onKeyDown={handleInputKeyDown}\n onFocus={() => {\n if (!effectiveDisabled) setOpen(true);\n }}\n placeholder={\n currentValue.length === 0 ? resolvedPlaceholder : ''\n }\n id={triggerId}\n // The name comes from the Command root's `label` above, or\n // from the FormField's label: cmdk writes `aria-labelledby`\n // after these props, and a layout effect above re-points it.\n aria-describedby={inputDescribedBy}\n aria-invalid={effectiveInvalid || undefined}\n aria-required={effectiveRequired || undefined}\n disabled={effectiveDisabled}\n className={[\n 'ds:flex-1 ds:min-w-[6rem] ds:bg-transparent ds:outline-none',\n 'ds:placeholder:text-muted-foreground ds:text-start',\n 'ds:disabled:cursor-not-allowed',\n ].join(' ')}\n />\n {/* Hidden: read only as the input's description, not as stray\n text on the page. */}\n <span id={counterId} hidden>\n {counterMessage}\n </span>\n </div>\n </Popover.Anchor>\n <Popover.Portal>\n {/* Portalled to <body>, so the list carries its own bounding\n marker: the kit's cascade reset — and a host's shield against\n its own bare-element CSS — scope to [data-component]. */}\n <Popover.Content\n data-component=\"multi-select-list\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n onCloseAutoFocus={(e) => e.preventDefault()}\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n className={popoverContentClasses}\n >\n <Command.List\n role=\"listbox\"\n aria-multiselectable=\"true\"\n // cmdk writes its own aria-label after ours, \"Suggestions\"\n // in English unless it gets `label`.\n label={accessibleName}\n className=\"ds:max-h-[20rem] ds:overflow-y-auto ds:p-1\"\n >\n {hasActionRow ? (\n <Command.Group>\n {allowSelectAll ? (\n <Command.Item\n value={SELECT_ALL_VALUE}\n onSelect={handleSelectAll}\n className={actionItemClasses}\n >\n {t('inputs.multiSelect.selectAll', 'Select all')}\n </Command.Item>\n ) : null}\n {allowClear ? (\n <Command.Item\n value={CLEAR_ALL_VALUE}\n onSelect={handleClearAll}\n className={actionItemClasses}\n >\n {t('inputs.multiSelect.clearAll', 'Clear all')}\n </Command.Item>\n ) : null}\n </Command.Group>\n ) : null}\n <Command.Empty className=\"ds:ps-2 ds:pe-2 ds:py-2 type-body-sm ds:text-muted-foreground\">\n {t('inputs.multiSelect.noOptions', 'No options found')}\n </Command.Empty>\n {groups.map(({ group, items }, gi) => {\n const body = items.map((option) => {\n const isSelected = currentValue.includes(option.value);\n const isCapped = !isSelected && atCap;\n const isDisabled = Boolean(option.disabled) || isCapped;\n const item = (\n <Command.Item\n key={option.value}\n value={option.value}\n // Agent DOM hook — see multi-select.agent.ts item.\n data-option-id={option.value}\n disabled={isDisabled}\n onSelect={() => {\n if (isDisabled) return;\n toggle(option.value);\n }}\n aria-selected={isSelected}\n aria-disabled={isDisabled || undefined}\n className={commandItemClasses}\n >\n <span\n // Off, the box is a state indicator, so its edge is\n // the 3:1 --control-border (WCAG 1.4.11), as on\n // Checkbox.\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center ds:me-[var(--spacing-xs)] ds:shrink-0',\n 'ds:size-4 ds:rounded-[var(--radius-sm)] ds:border',\n isSelected\n ? 'ds:bg-primary ds:border-primary ds:text-primary-foreground'\n : 'ds:bg-background ds:border-[color:var(--control-border)]',\n ].join(' ')}\n aria-hidden=\"true\"\n >\n {isSelected ? (\n <Check className=\"ds:size-3.5\" />\n ) : null}\n </span>\n {option.startAdornment ? (\n // Decorative by contract — the accessible name comes\n // from the option label.\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:shrink-0 ds:me-[var(--spacing-xs)]\"\n >\n {option.startAdornment}\n </span>\n ) : null}\n {option.description || wrapOptionLabels ? (\n // Stacked, as in Combobox: the label and its end\n // content on one row, the description under them.\n // The option's name reads in that order.\n <span className={OPTION_BODY_CLASSES}>\n <span className={OPTION_LABEL_ROW_CLASSES}>\n <span\n dir={option.dir}\n className={optionLabelVariants({\n wrap: wrapOptionLabels,\n className: 'ds:flex-1 ds:text-start',\n })}\n >\n {option.label}\n </span>\n {option.endContent ? (\n // Announced, as below.\n <span className={OPTION_END_CLASSES}>\n {option.endContent}\n </span>\n ) : null}\n </span>\n {option.description ? (\n <span\n className={optionDescriptionVariants({\n tone: option.descriptionTone,\n className: 'ds:text-start',\n })}\n >\n {option.description}\n </span>\n ) : null}\n </span>\n ) : (\n <>\n {/* `min-w-0 truncate` matches Combobox and Select.\n Without it a long service name cannot be\n clipped, so it pushes the trailing content and\n overflows the row instead of the name\n ellipsing — the CJK and long-label case. */}\n <span\n dir={option.dir}\n className=\"ds:flex-1 ds:min-w-0 ds:truncate ds:text-start\"\n >\n {option.label}\n </span>\n {option.endContent ? (\n // Deliberately NOT aria-hidden — unlike\n // `startAdornment`, this slot carries meaning\n // (a price, a count) and must reach the\n // option's accessible name. `ms-auto` pins it\n // to the inline-end and flips under RTL.\n <span className=\"ds:inline-flex ds:items-center ds:ms-auto ds:shrink-0 ds:ps-[var(--spacing-xs)]\">\n {option.endContent}\n </span>\n ) : null}\n </>\n )}\n </Command.Item>\n );\n if (isCapped) {\n return (\n <Tooltip\n key={option.value}\n label={t('inputs.multiSelect.maxReached', {\n count: maxSelections,\n defaultValue: `Maximum ${maxSelections} selections`,\n })}\n delayDuration={200}\n >\n {item}\n </Tooltip>\n );\n }\n return item;\n });\n if (!group) {\n return (\n <Command.Group key={`group-${gi}`}>{body}</Command.Group>\n );\n }\n return (\n <Command.Group\n key={`group-${group}`}\n heading={group}\n className=\"ds:[&_[cmdk-group-heading]]:ps-2 ds:[&_[cmdk-group-heading]]:pe-2 ds:[&_[cmdk-group-heading]]:py-1 ds:[&_[cmdk-group-heading]]:type-eyebrow ds:[&_[cmdk-group-heading]]:text-muted-foreground\"\n >\n {body}\n </Command.Group>\n );\n })}\n </Command.List>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n </Command>\n );\n },\n);\nMultiSelectImpl.displayName = 'MultiSelect';\n\ninterface MultiSelectComponent {\n <T extends string = string>(\n props: MultiSelectProps<T> & { ref?: Ref<HTMLDivElement> },\n ): ReactElement | null;\n displayName?: string;\n}\n\nexport const MultiSelect = MultiSelectImpl as unknown as MultiSelectComponent;\n\nexport { multiSelectVariants };\n"],"names":["multiSelectAgent","handle","args","multiSelectVariants","cva","INPUT_SURFACE_CHROME","INPUT_SURFACE_TEXT","chipVariants","chipDismissClasses","popoverContentClasses","commandItemClasses","MENU_ROW_HIGHLIGHT","actionItemClasses","SELECT_ALL_VALUE","CLEAR_ALL_VALUE","MultiSelectImpl","forwardRef","options","value","defaultValue","onChange","onComplete","placeholder","maxSelections","allowSelectAll","allowClear","filter","size","disabled","wrapOptionLabels","className","id","ariaLabel","divProps","ref","t","useTranslation","ctx","useFormField","inFormField","useContext","FormFieldContext","currentValueRaw","setMultiSelectValue","useControllableState","currentValue","open","setOpen","useState","query","setQuery","inputRef","useRef","counterId","useId","chipRefs","triggerRef","composedRef","composeRefs","inDisabledFieldset","setInDisabledFieldset","useIsomorphicLayoutEffect","_a","effectiveDisabled","effectiveRequired","effectiveInvalid","describedBy","triggerId","useFormFieldControlRef","labelByValue","useMemo","map","option","dirByValue","atCap","commit","next","toggle","val","v","removeAt","index","_","i","handleSelectAll","selectable","o","cap","handleClearAll","valueRef","useEffect","queryRef","openRef","commitStable","useCallback","agentHandle","values","useAgentRegistration","resolvedPlaceholder","filteredOptions","needle","groups","groupOptions","handleInputKeyDown","target","removedIndex","newLast","caretAtStart","isRTL","lastIdx","handleChipKeyDown","e","focusIdx","prevKey","nextKey","newIdx","_b","_c","_d","visibleCount","setVisibleCount","measureNonce","setMeasureNonce","lastWidthRef","requestMeasure","n","el","chipEls","firstTop","firstRowCount","chip","ro","entries","width","chips","showAllChips","visibleChips","overflowChips","overflowCount","handleTriggerClick","event","handleOpenChange","hasActionRow","counterMessage","accessibleName","inputDescribedBy","fieldLabelId","cmdkLabelledBy","input","current","onClickProp","restDivProps","jsx","Command","jsxs","Popover","idx","X","Tooltip","c","group","items","gi","body","isSelected","isCapped","isDisabled","item","Check","OPTION_BODY_CLASSES","OPTION_LABEL_ROW_CLASSES","optionLabelVariants","OPTION_END_CLASSES","optionDescriptionVariants","Fragment","MultiSelect"],"mappings":"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"}