@alfadocs/ui-kit-debug 0.72.2 → 0.75.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.
- package/dist/_chunks/actions-cell-renderer-DLrcSTK_.js +1546 -0
- package/dist/_chunks/actions-cell-renderer-DLrcSTK_.js.map +1 -0
- package/dist/_chunks/{agenda-tray-loL2A3Cx.js → agenda-tray-CVf-jfWU.js} +3 -3
- package/dist/_chunks/{agenda-tray-loL2A3Cx.js.map → agenda-tray-CVf-jfWU.js.map} +1 -1
- package/dist/_chunks/{ai-consent-banner-Bke9m8VS.js → ai-consent-banner-DUhr1yNj.js} +2 -2
- package/dist/_chunks/{ai-consent-banner-Bke9m8VS.js.map → ai-consent-banner-DUhr1yNj.js.map} +1 -1
- package/dist/_chunks/{ai-prompt-input-TVI95hJD.js → ai-prompt-input-DziJCGLe.js} +3 -3
- package/dist/_chunks/{ai-prompt-input-TVI95hJD.js.map → ai-prompt-input-DziJCGLe.js.map} +1 -1
- package/dist/_chunks/{alia-sidebar-BV5lBSFR.js → alia-sidebar-w6B0TEx7.js} +8 -8
- package/dist/_chunks/{alia-sidebar-BV5lBSFR.js.map → alia-sidebar-w6B0TEx7.js.map} +1 -1
- package/dist/_chunks/{anamnesis-card-CWO4Ui9c.js → anamnesis-card-CJ5MNbkc.js} +2 -2
- package/dist/_chunks/{anamnesis-card-CWO4Ui9c.js.map → anamnesis-card-CJ5MNbkc.js.map} +1 -1
- package/dist/_chunks/{antenatal-schedule-timeline-CY-VsLok.js → antenatal-schedule-timeline-BzJZqS-8.js} +3 -3
- package/dist/_chunks/{antenatal-schedule-timeline-CY-VsLok.js.map → antenatal-schedule-timeline-BzJZqS-8.js.map} +1 -1
- package/dist/_chunks/{appointment-card-Cy4FOkGP.js → appointment-card-DgKI5QKD.js} +2 -2
- package/dist/_chunks/{appointment-card-Cy4FOkGP.js.map → appointment-card-DgKI5QKD.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-BWAPPk8F.js → appointment-timeline-DQTG0btW.js} +6 -6
- package/dist/_chunks/{appointment-timeline-BWAPPk8F.js.map → appointment-timeline-DQTG0btW.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-D3mk04TT.js → appointment-tray-ezyCZN8v.js} +4 -4
- package/dist/_chunks/{appointment-tray-D3mk04TT.js.map → appointment-tray-ezyCZN8v.js.map} +1 -1
- package/dist/_chunks/{ar-BOqyIfoY.js → ar-B1GhtlBP.js} +2 -2
- package/dist/_chunks/{ar-BOqyIfoY.js.map → ar-B1GhtlBP.js.map} +1 -1
- package/dist/_chunks/{columns-2-8lq4-b8e.js → arrow-up-right-C2v_MKsK.js} +5 -5
- package/dist/_chunks/arrow-up-right-C2v_MKsK.js.map +1 -0
- package/dist/_chunks/{audio-recorder-BbjG55dP.js → audio-recorder-Cc3KuL9y.js} +4 -4
- package/dist/_chunks/{audio-recorder-BbjG55dP.js.map → audio-recorder-Cc3KuL9y.js.map} +1 -1
- package/dist/_chunks/{benefit-card-Xnxj4Gmo.js → benefit-card-DB1Kdrmc.js} +4 -2
- package/dist/_chunks/benefit-card-DB1Kdrmc.js.map +1 -0
- package/dist/_chunks/{bishop-score-C6eoak_j.js → bishop-score-DDW5-gb9.js} +3 -3
- package/dist/_chunks/{bishop-score-C6eoak_j.js.map → bishop-score-DDW5-gb9.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-BmQfoEGP.js → bmi-calculator-Bk2GAju7.js} +2 -2
- package/dist/_chunks/{bmi-calculator-BmQfoEGP.js.map → bmi-calculator-Bk2GAju7.js.map} +1 -1
- package/dist/_chunks/{booking-B62CMY5k.js → booking-B1Qkcl3c.js} +9 -9
- package/dist/_chunks/{booking-B62CMY5k.js.map → booking-B1Qkcl3c.js.map} +1 -1
- package/dist/_chunks/{button-DD_0Xdmr.js → button-CPGiR_bH.js} +56 -35
- package/dist/_chunks/button-CPGiR_bH.js.map +1 -0
- package/dist/_chunks/button-group-DzV5wgnx.js +289 -0
- package/dist/_chunks/button-group-DzV5wgnx.js.map +1 -0
- package/dist/_chunks/camera-VSklPDCv.js +21 -0
- package/dist/_chunks/camera-VSklPDCv.js.map +1 -0
- package/dist/_chunks/{care-plan-card-DhXbfGzE.js → care-plan-card-BrwhyIJI.js} +3 -3
- package/dist/_chunks/{care-plan-card-DhXbfGzE.js.map → care-plan-card-BrwhyIJI.js.map} +1 -1
- package/dist/_chunks/{care-plan-entry-card-D3YGD6rj.js → care-plan-entry-card-DWEdCQM3.js} +3 -3
- package/dist/_chunks/{care-plan-entry-card-D3YGD6rj.js.map → care-plan-entry-card-DWEdCQM3.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-DtQxyfOb.js → care-plan-header-BXvRpGG8.js} +2 -2
- package/dist/_chunks/{care-plan-header-DtQxyfOb.js.map → care-plan-header-BXvRpGG8.js.map} +1 -1
- package/dist/_chunks/{carousel.agent-j7hWxJWr.js → carousel.agent-CtAAdsAd.js} +2 -2
- package/dist/_chunks/{carousel.agent-j7hWxJWr.js.map → carousel.agent-CtAAdsAd.js.map} +1 -1
- package/dist/_chunks/{chat-container-BVCoN06N.js → chat-container-HlFnoEIl.js} +4 -2
- package/dist/_chunks/{chat-container-BVCoN06N.js.map → chat-container-HlFnoEIl.js.map} +1 -1
- package/dist/_chunks/{chat-input-Btq_uuMZ.js → chat-input-BTCDqUDX.js} +2 -2
- package/dist/_chunks/{chat-input-Btq_uuMZ.js.map → chat-input-BTCDqUDX.js.map} +1 -1
- package/dist/_chunks/{chat-message-DXjjM8z9.js → chat-message-CdjWqZjo.js} +3 -3
- package/dist/_chunks/{chat-message-DXjjM8z9.js.map → chat-message-CdjWqZjo.js.map} +1 -1
- package/dist/_chunks/{code-block-Cwi7e3HM.js → code-block-BwanBjRh.js} +2 -2
- package/dist/_chunks/{code-block-Cwi7e3HM.js.map → code-block-BwanBjRh.js.map} +1 -1
- package/dist/_chunks/{connection-status-0HajXMXM.js → connection-status-oEUyrvev.js} +3 -3
- package/dist/_chunks/{connection-status-0HajXMXM.js.map → connection-status-oEUyrvev.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-IggiUVpN.js → contact-profile-card-veMV3W4J.js} +2 -2
- package/dist/_chunks/{contact-profile-card-IggiUVpN.js.map → contact-profile-card-veMV3W4J.js.map} +1 -1
- package/dist/_chunks/{control-room-rail-DaGcsdZ6.js → control-room-rail-CdfrZ6Vr.js} +3 -3
- package/dist/_chunks/{control-room-rail-DaGcsdZ6.js.map → control-room-rail-CdfrZ6Vr.js.map} +1 -1
- package/dist/_chunks/{copy-field-PAp0-Wr5.js → copy-field-DBc9QquW.js} +2 -2
- package/dist/_chunks/{copy-field-PAp0-Wr5.js.map → copy-field-DBc9QquW.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-BNILyVas.js → cycle-calculator-OQp8Ik5U.js} +4 -4
- package/dist/_chunks/{cycle-calculator-BNILyVas.js.map → cycle-calculator-OQp8Ik5U.js.map} +1 -1
- package/dist/_chunks/data-table-tabs-BEUXiRlu.js +710 -0
- package/dist/_chunks/data-table-tabs-BEUXiRlu.js.map +1 -0
- package/dist/_chunks/{date-picker-CVkD_lOi.js → date-picker-DzQS8mvt.js} +2 -2
- package/dist/_chunks/{date-picker-CVkD_lOi.js.map → date-picker-DzQS8mvt.js.map} +1 -1
- package/dist/_chunks/{date-picker-variants-DLg-ZrIo.js → date-picker-variants-CYQAm1Gk.js} +116 -115
- package/dist/_chunks/{date-picker-variants-DLg-ZrIo.js.map → date-picker-variants-CYQAm1Gk.js.map} +1 -1
- package/dist/_chunks/{date-range-picker-Dw12DgV8.js → date-range-picker-Cbz1SKhm.js} +3 -3
- package/dist/_chunks/{date-range-picker-Dw12DgV8.js.map → date-range-picker-Cbz1SKhm.js.map} +1 -1
- package/dist/_chunks/{date-time-picker-Cd_OJtOy.js → date-time-picker-B5IpU-nd.js} +2 -2
- package/dist/_chunks/{date-time-picker-Cd_OJtOy.js.map → date-time-picker-B5IpU-nd.js.map} +1 -1
- package/dist/_chunks/{de-DFLsUxeV.js → de-DETDHQ0o.js} +2 -2
- package/dist/_chunks/{de-DFLsUxeV.js.map → de-DETDHQ0o.js.map} +1 -1
- package/dist/_chunks/{description-list-CmBVxIF5.js → description-list-ClNLdRMy.js} +2 -2
- package/dist/_chunks/{description-list-CmBVxIF5.js.map → description-list-ClNLdRMy.js.map} +1 -1
- package/dist/_chunks/document-preview-CGSM_au9.js +181 -0
- package/dist/_chunks/document-preview-CGSM_au9.js.map +1 -0
- package/dist/_chunks/{document-scanner-B23j4w7X.js → document-scanner-B6h1Ir56.js} +198 -230
- package/dist/_chunks/document-scanner-B6h1Ir56.js.map +1 -0
- package/dist/_chunks/{due-date-calculator-CmdAl_JO.js → due-date-calculator-DASNRgnH.js} +4 -4
- package/dist/_chunks/{due-date-calculator-CmdAl_JO.js.map → due-date-calculator-DASNRgnH.js.map} +1 -1
- package/dist/_chunks/{editable-currency-cell-renderer-z9fJFw6Z.js → editable-currency-cell-renderer-GwfA9tTR.js} +3 -3
- package/dist/_chunks/{editable-currency-cell-renderer-z9fJFw6Z.js.map → editable-currency-cell-renderer-GwfA9tTR.js.map} +1 -1
- package/dist/_chunks/{editor-overlay-BIOzr8v7.js → editor-overlay-DE3esyio.js} +2 -2
- package/dist/_chunks/{editor-overlay-BIOzr8v7.js.map → editor-overlay-DE3esyio.js.map} +1 -1
- package/dist/_chunks/{el-OVjBKytp.js → el-HV3jOI0z.js} +2 -2
- package/dist/_chunks/{el-OVjBKytp.js.map → el-HV3jOI0z.js.map} +1 -1
- package/dist/_chunks/{empty-state-BLy7tigq.js → empty-state-CrLsi0XI.js} +2 -2
- package/dist/_chunks/{empty-state-BLy7tigq.js.map → empty-state-CrLsi0XI.js.map} +1 -1
- package/dist/_chunks/{entity-summary-DpGziDv5.js → entity-summary--vP698Jn.js} +3 -3
- package/dist/_chunks/{entity-summary-DpGziDv5.js.map → entity-summary--vP698Jn.js.map} +1 -1
- package/dist/_chunks/eraser-CHOGQfVv.js +21 -0
- package/dist/_chunks/eraser-CHOGQfVv.js.map +1 -0
- package/dist/_chunks/{es-DKDNrHXG.js → es-Dpo7Olwo.js} +2 -2
- package/dist/_chunks/{es-DKDNrHXG.js.map → es-Dpo7Olwo.js.map} +1 -1
- package/dist/_chunks/face-scheme-C0rk21gg.js +3146 -0
- package/dist/_chunks/face-scheme-C0rk21gg.js.map +1 -0
- package/dist/_chunks/{fetal-weight-CVAH8sJ3.js → fetal-weight-1F9N4IMx.js} +2 -2
- package/dist/_chunks/{fetal-weight-CVAH8sJ3.js.map → fetal-weight-1F9N4IMx.js.map} +1 -1
- package/dist/_chunks/{field-array-CDzc3hTM.js → field-array-DH3Mb1i8.js} +3 -3
- package/dist/_chunks/{field-array-CDzc3hTM.js.map → field-array-DH3Mb1i8.js.map} +1 -1
- package/dist/_chunks/{field-value-Dj3i52H2.js → field-value-DHG6gEKS.js} +5 -5
- package/dist/_chunks/{field-value-Dj3i52H2.js.map → field-value-DHG6gEKS.js.map} +1 -1
- package/dist/_chunks/file-Cwe9VC1A.js +40 -0
- package/dist/_chunks/file-Cwe9VC1A.js.map +1 -0
- package/dist/_chunks/file-manager-UF8dkQF1.js +1776 -0
- package/dist/_chunks/file-manager-UF8dkQF1.js.map +1 -0
- package/dist/_chunks/{file-upload-Kw1rdvFw.js → file-upload-DENvuhfs.js} +101 -139
- package/dist/_chunks/file-upload-DENvuhfs.js.map +1 -0
- package/dist/_chunks/{finished-terminal-Di4gtZ50.js → finished-terminal-C0_mefrf.js} +11 -11
- package/dist/_chunks/finished-terminal-C0_mefrf.js.map +1 -0
- package/dist/_chunks/{fiscal-code-input-DKNXFXs3.js → fiscal-code-input-DWA6C8x8.js} +2 -2
- package/dist/_chunks/{fiscal-code-input-DKNXFXs3.js.map → fiscal-code-input-DWA6C8x8.js.map} +1 -1
- package/dist/_chunks/{fr-BfMvQh-v.js → fr-CgD4Jvtq.js} +2 -2
- package/dist/_chunks/{fr-BfMvQh-v.js.map → fr-CgD4Jvtq.js.map} +1 -1
- package/dist/_chunks/{freemium-paywall-DFoeedwh.js → freemium-paywall-CmV642PA.js} +7 -3
- package/dist/_chunks/freemium-paywall-CmV642PA.js.map +1 -0
- package/dist/_chunks/{gestational-age-calculator-BwCBPAGX.js → gestational-age-calculator-BpYw-WF-.js} +7 -7
- package/dist/_chunks/{gestational-age-calculator-BwCBPAGX.js.map → gestational-age-calculator-BpYw-WF-.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-CSsWxEJc.js → hcg-doubling-Dqj-EqMT.js} +3 -3
- package/dist/_chunks/{hcg-doubling-CSsWxEJc.js.map → hcg-doubling-Dqj-EqMT.js.map} +1 -1
- package/dist/_chunks/{header-DaXWDw0M.js → header-CjwasYnn.js} +88 -79
- package/dist/_chunks/header-CjwasYnn.js.map +1 -0
- package/dist/_chunks/{header-settings-B0G_u-wV.js → header-settings-4cwQzeFc.js} +4 -4
- package/dist/_chunks/{header-settings-B0G_u-wV.js.map → header-settings-4cwQzeFc.js.map} +1 -1
- package/dist/_chunks/{hi-C0GEMwlD.js → hi-Bf8CAP6b.js} +2 -2
- package/dist/_chunks/{hi-C0GEMwlD.js.map → hi-Bf8CAP6b.js.map} +1 -1
- package/dist/_chunks/highlighter-DSkckT2Q.js +15 -0
- package/dist/_chunks/highlighter-DSkckT2Q.js.map +1 -0
- package/dist/_chunks/{icon-button-LqoiKcUN.js → icon-button-C_kbcd7I.js} +2 -2
- package/dist/_chunks/{icon-button-LqoiKcUN.js.map → icon-button-C_kbcd7I.js.map} +1 -1
- package/dist/_chunks/icon-button-group-C_lqXTAj.js +391 -0
- package/dist/_chunks/icon-button-group-C_lqXTAj.js.map +1 -0
- package/dist/_chunks/{icon-picker-Di6uYDG-.js → icon-picker-CM9ubkew.js} +3 -3
- package/dist/_chunks/{icon-picker-Di6uYDG-.js.map → icon-picker-CM9ubkew.js.map} +1 -1
- package/dist/_chunks/{image-cropper-CdmWFrMC.js → image-cropper-DKe4AORY.js} +2 -2
- package/dist/_chunks/{image-cropper-CdmWFrMC.js.map → image-cropper-DKe4AORY.js.map} +1 -1
- package/dist/_chunks/{insert-result-C7xSDb8q.js → insert-result-D074GtHX.js} +58 -68
- package/dist/_chunks/insert-result-D074GtHX.js.map +1 -0
- package/dist/_chunks/{isSameWeek-HddDAyJG.js → isSameWeek-BYl5poz_.js} +2 -2
- package/dist/_chunks/{isSameWeek-HddDAyJG.js.map → isSameWeek-BYl5poz_.js.map} +1 -1
- package/dist/_chunks/{it-5f4hiT2e.js → it-mt1V2DFS.js} +3 -3
- package/dist/_chunks/{it-5f4hiT2e.js.map → it-mt1V2DFS.js.map} +1 -1
- package/dist/_chunks/{ja-U0_2inl_.js → ja-CbOHn2TO.js} +2 -2
- package/dist/_chunks/{ja-U0_2inl_.js.map → ja-CbOHn2TO.js.map} +1 -1
- package/dist/_chunks/{key-value-pair-Byyyc_9J.js → key-value-pair-LHKfDT_9.js} +2 -2
- package/dist/_chunks/{key-value-pair-Byyyc_9J.js.map → key-value-pair-LHKfDT_9.js.map} +1 -1
- package/dist/_chunks/link-cell-renderer-BQGUs45d.js +711 -0
- package/dist/_chunks/link-cell-renderer-BQGUs45d.js.map +1 -0
- package/dist/_chunks/{locale-picker-DzF7Q5Y8.js → locale-picker-GNF3lo8K.js} +3 -3
- package/dist/_chunks/{locale-picker-DzF7Q5Y8.js.map → locale-picker-GNF3lo8K.js.map} +1 -1
- package/dist/_chunks/{map-view-ByPvWG_9.js → map-view-CsaHfoo6.js} +2 -2
- package/dist/_chunks/{map-view-ByPvWG_9.js.map → map-view-CsaHfoo6.js.map} +1 -1
- package/dist/_chunks/{marketplace-app-shell-BCYiOvKZ.js → marketplace-app-shell-D_1tF4La.js} +6 -6
- package/dist/_chunks/marketplace-app-shell-D_1tF4La.js.map +1 -0
- package/dist/_chunks/{message-card-BZnnffyB.js → message-card-ievotOFa.js} +3 -3
- package/dist/_chunks/{message-card-BZnnffyB.js.map → message-card-ievotOFa.js.map} +1 -1
- package/dist/_chunks/{message-tray-cUHOCdU0.js → message-tray-BFlu8clI.js} +4 -4
- package/dist/_chunks/{message-tray-cUHOCdU0.js.map → message-tray-BFlu8clI.js.map} +1 -1
- package/dist/_chunks/{muscle-scheme-B9MIkuj0.js → muscle-scheme-CFBE2dme.js} +6 -14
- package/dist/_chunks/{muscle-scheme-B9MIkuj0.js.map → muscle-scheme-CFBE2dme.js.map} +1 -1
- package/dist/_chunks/{nl-CDVnnx1U.js → nl-C6Y0QXnm.js} +2 -2
- package/dist/_chunks/{nl-CDVnnx1U.js.map → nl-C6Y0QXnm.js.map} +1 -1
- package/dist/_chunks/{notes-panel-CMyjUXD4.js → notes-panel-Cvdp818a.js} +3 -3
- package/dist/_chunks/{notes-panel-CMyjUXD4.js.map → notes-panel-Cvdp818a.js.map} +1 -1
- package/dist/_chunks/{notification-card-BHJ07FkH.js → notification-card-D29_sVA1.js} +3 -3
- package/dist/_chunks/{notification-card-BHJ07FkH.js.map → notification-card-D29_sVA1.js.map} +1 -1
- package/dist/_chunks/{notification-tray-Dzm1c3Wy.js → notification-tray-CzIzz3bX.js} +4 -4
- package/dist/_chunks/{notification-tray-Dzm1c3Wy.js.map → notification-tray-CzIzz3bX.js.map} +1 -1
- package/dist/_chunks/optical-prescription-BEjYQjiO.js +1260 -0
- package/dist/_chunks/optical-prescription-BEjYQjiO.js.map +1 -0
- package/dist/_chunks/{patient-details-pU_E5xM2.js → patient-details-DP4wKyq4.js} +7 -7
- package/dist/_chunks/{patient-details-pU_E5xM2.js.map → patient-details-DP4wKyq4.js.map} +1 -1
- package/dist/_chunks/{patient-search-X9SUZGpy.js → patient-search-BaUJ_Y-N.js} +47 -45
- package/dist/_chunks/patient-search-BaUJ_Y-N.js.map +1 -0
- package/dist/_chunks/{patient-summary-card--t3BjTdU.js → patient-summary-card-D6kgdTNn.js} +4 -4
- package/dist/_chunks/{patient-summary-card--t3BjTdU.js.map → patient-summary-card-D6kgdTNn.js.map} +1 -1
- package/dist/_chunks/{patient-table-BgWgNIMf.js → patient-table-DweKjiXg.js} +122 -118
- package/dist/_chunks/patient-table-DweKjiXg.js.map +1 -0
- package/dist/_chunks/{payment-request-card-2ts7ITxd.js → payment-request-card-C0fqlKqO.js} +25 -24
- package/dist/_chunks/{payment-request-card-2ts7ITxd.js.map → payment-request-card-C0fqlKqO.js.map} +1 -1
- package/dist/_chunks/pen-line-D0De5zdl.js +21 -0
- package/dist/_chunks/pen-line-D0De5zdl.js.map +1 -0
- package/dist/_chunks/periodontal-chart-D8hOFmde.js +1173 -0
- package/dist/_chunks/periodontal-chart-D8hOFmde.js.map +1 -0
- package/dist/_chunks/{periodontal-chart-card-6c6Lt4ws.js → periodontal-chart-card-WVjJAheq.js} +2 -2
- package/dist/_chunks/{periodontal-chart-card-6c6Lt4ws.js.map → periodontal-chart-card-WVjJAheq.js.map} +1 -1
- package/dist/_chunks/periodontal-diagnosis-cco40xTa.js +345 -0
- package/dist/_chunks/periodontal-diagnosis-cco40xTa.js.map +1 -0
- package/dist/_chunks/periodontal-risk-chart-bUGkMwDg.js +334 -0
- package/dist/_chunks/periodontal-risk-chart-bUGkMwDg.js.map +1 -0
- package/dist/_chunks/{pl-BWNumNrg.js → pl-BdazJAOp.js} +3 -3
- package/dist/_chunks/{pl-BWNumNrg.js.map → pl-BdazJAOp.js.map} +1 -1
- package/dist/_chunks/{popover-uJ6BvEU3.js → popover-Cc0a69sw.js} +32 -29
- package/dist/_chunks/{popover-uJ6BvEU3.js.map → popover-Cc0a69sw.js.map} +1 -1
- package/dist/_chunks/{practice-results-CSEHTH2V.js → practice-results-BCr7jMt1.js} +5 -5
- package/dist/_chunks/{practice-results-CSEHTH2V.js.map → practice-results-BCr7jMt1.js.map} +1 -1
- package/dist/_chunks/{pregnancy-dating-CxVAA6_4.js → pregnancy-dating-msMl_6wz.js} +7 -7
- package/dist/_chunks/{pregnancy-dating-CxVAA6_4.js.map → pregnancy-dating-msMl_6wz.js.map} +1 -1
- package/dist/_chunks/{pregnancy-weight-gain-C7zyrwow.js → pregnancy-weight-gain-B-CkVYnU.js} +2 -2
- package/dist/_chunks/{pregnancy-weight-gain-C7zyrwow.js.map → pregnancy-weight-gain-B-CkVYnU.js.map} +1 -1
- package/dist/_chunks/{privacy-lock-DrRmK8C7.js → privacy-lock-YYBiI_bY.js} +3 -3
- package/dist/_chunks/{privacy-lock-DrRmK8C7.js.map → privacy-lock-YYBiI_bY.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-CaZqttvm.js → product-hub-panel-CTld1r5V.js} +3 -3
- package/dist/_chunks/{product-hub-panel-CaZqttvm.js.map → product-hub-panel-CTld1r5V.js.map} +1 -1
- package/dist/_chunks/{pt-zqdQuryr.js → pt-B3UKvhHp.js} +2 -2
- package/dist/_chunks/{pt-zqdQuryr.js.map → pt-B3UKvhHp.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-C-opZaOw.js → public-header.agent-rX_VA6hd.js} +107 -103
- package/dist/_chunks/public-header.agent-rX_VA6hd.js.map +1 -0
- package/dist/_chunks/{radiograph-panel.agent-D1x33moc.js → radiograph-panel.agent-CxF9pVxd.js} +40 -57
- package/dist/_chunks/radiograph-panel.agent-CxF9pVxd.js.map +1 -0
- package/dist/_chunks/{reviews-panel-liUj6OPX.js → reviews-panel-DmOjvmyH.js} +4 -4
- package/dist/_chunks/{reviews-panel-liUj6OPX.js.map → reviews-panel-DmOjvmyH.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-DUgznqOf.js → rich-text-editor-CCWjNkbx.js} +26 -26
- package/dist/_chunks/rich-text-editor-CCWjNkbx.js.map +1 -0
- package/dist/_chunks/{ro-CornQr64.js → ro-DVTEQpPK.js} +2 -2
- package/dist/_chunks/{ro-CornQr64.js.map → ro-DVTEQpPK.js.map} +1 -1
- package/dist/_chunks/{ru-CKAXNYVD.js → ru-C-Mp40SC.js} +3 -3
- package/dist/_chunks/{ru-CKAXNYVD.js.map → ru-C-Mp40SC.js.map} +1 -1
- package/dist/_chunks/{select-BmCbJMJS.js → select-BW5ecXlX.js} +13 -13
- package/dist/_chunks/{select-BmCbJMJS.js.map → select-BW5ecXlX.js.map} +1 -1
- package/dist/_chunks/{session-countdown-qr8EO5QY.js → session-countdown-C8AsE072.js} +2 -2
- package/dist/_chunks/{session-countdown-qr8EO5QY.js.map → session-countdown-C8AsE072.js.map} +1 -1
- package/dist/_chunks/{sheet-B_X54aZo.js → sheet-D5K0LB3q.js} +2 -2
- package/dist/_chunks/{sheet-B_X54aZo.js.map → sheet-D5K0LB3q.js.map} +1 -1
- package/dist/_chunks/{sidebar-B0OBmJrC.js → sidebar-C0PbwJBc.js} +375 -335
- package/dist/_chunks/sidebar-C0PbwJBc.js.map +1 -0
- package/dist/_chunks/{sign-document-nK03S73h.js → sign-document-Bfk0WpWV.js} +2 -2
- package/dist/_chunks/{sign-document-nK03S73h.js.map → sign-document-Bfk0WpWV.js.map} +1 -1
- package/dist/_chunks/{sign-in-with-alfadocs-button-LppxjlFt.js → sign-in-with-alfadocs-button-UlYefZpI.js} +2 -2
- package/dist/_chunks/{sign-in-with-alfadocs-button-LppxjlFt.js.map → sign-in-with-alfadocs-button-UlYefZpI.js.map} +1 -1
- package/dist/_chunks/{signature-capture-Ct_4Md4e.js → signature-capture-DN52VNKL.js} +206 -189
- package/dist/_chunks/signature-capture-DN52VNKL.js.map +1 -0
- package/dist/_chunks/{signature-field-jgwYgUhO.js → signature-field-0rFODJlW.js} +47 -41
- package/dist/_chunks/signature-field-0rFODJlW.js.map +1 -0
- package/dist/_chunks/signature-request-C-mskXwi.js +318 -0
- package/dist/_chunks/signature-request-C-mskXwi.js.map +1 -0
- package/dist/_chunks/{slot-grid-FsqumOaS.js → slot-grid-CQSULZjd.js} +4 -4
- package/dist/_chunks/{slot-grid-FsqumOaS.js.map → slot-grid-CQSULZjd.js.map} +1 -1
- package/dist/_chunks/{sq-CIIvqXZv.js → sq-DierVlw-.js} +2 -2
- package/dist/_chunks/{sq-CIIvqXZv.js.map → sq-DierVlw-.js.map} +1 -1
- package/dist/_chunks/{streaming-text-Cedc05ya.js → streaming-text-C5bYz7LL.js} +2 -2
- package/dist/_chunks/{streaming-text-Cedc05ya.js.map → streaming-text-C5bYz7LL.js.map} +1 -1
- package/dist/_chunks/subDays-DIKRViZm.js +8 -0
- package/dist/_chunks/{subDays-DGSOp9d9.js.map → subDays-DIKRViZm.js.map} +1 -1
- package/dist/_chunks/{sv-Kpk1pzjz.js → sv-gQWo_19z.js} +2 -2
- package/dist/_chunks/{sv-Kpk1pzjz.js.map → sv-gQWo_19z.js.map} +1 -1
- package/dist/_chunks/{tabs-DVQ941Sj.js → tabs-CVTukWRD.js} +2 -2
- package/dist/_chunks/{tabs-DVQ941Sj.js.map → tabs-CVTukWRD.js.map} +1 -1
- package/dist/_chunks/{task-tray-DP5A3Qnc.js → task-tray-Br3vc0O1.js} +3 -3
- package/dist/_chunks/{task-tray-DP5A3Qnc.js.map → task-tray-Br3vc0O1.js.map} +1 -1
- package/dist/_chunks/{tasks-panel-BuxaYtEF.js → tasks-panel-CjGAhIN8.js} +6 -6
- package/dist/_chunks/{tasks-panel-BuxaYtEF.js.map → tasks-panel-CjGAhIN8.js.map} +1 -1
- package/dist/_chunks/{theme-toggle-dtdy5EaL.js → theme-toggle-BJCz_UOi.js} +3 -3
- package/dist/_chunks/{theme-toggle-dtdy5EaL.js.map → theme-toggle-BJCz_UOi.js.map} +1 -1
- package/dist/_chunks/{toast.agent-BSxl057x.js → toast.agent-uV8CeAy6.js} +2 -2
- package/dist/_chunks/{toast.agent-BSxl057x.js.map → toast.agent-uV8CeAy6.js.map} +1 -1
- package/dist/_chunks/{token-insert-menu-Pok4nExI.js → token-insert-menu-BYv6yoZI.js} +2 -2
- package/dist/_chunks/{token-insert-menu-Pok4nExI.js.map → token-insert-menu-BYv6yoZI.js.map} +1 -1
- package/dist/_chunks/{tool-rail-BZx0-yIr.js → tool-rail-AaTqxkIM.js} +2 -2
- package/dist/_chunks/{tool-rail-BZx0-yIr.js.map → tool-rail-AaTqxkIM.js.map} +1 -1
- package/dist/_chunks/tooth-data-BwuoKFf4.js +660 -0
- package/dist/_chunks/tooth-data-BwuoKFf4.js.map +1 -0
- package/dist/_chunks/tooth-scheme-BzJ6rcte.js +1483 -0
- package/dist/_chunks/tooth-scheme-BzJ6rcte.js.map +1 -0
- package/dist/_chunks/{tr-DHaeLFxG.js → tr-Btm6M3Km.js} +2 -2
- package/dist/_chunks/{tr-DHaeLFxG.js.map → tr-Btm6M3Km.js.map} +1 -1
- package/dist/_chunks/{transaction-chip-B6iWoVmU.js → transaction-chip-DJCstquX.js} +41 -51
- package/dist/_chunks/transaction-chip-DJCstquX.js.map +1 -0
- package/dist/_chunks/type-ggmfVs23.js +16 -0
- package/dist/_chunks/type-ggmfVs23.js.map +1 -0
- package/dist/_chunks/{unit-converter-fEqluT8b.js → unit-converter-CSLWFDQh.js} +3 -3
- package/dist/_chunks/{unit-converter-fEqluT8b.js.map → unit-converter-CSLWFDQh.js.map} +1 -1
- package/dist/_chunks/upload-BfT2hzMg.js +16 -0
- package/dist/_chunks/upload-BfT2hzMg.js.map +1 -0
- package/dist/_chunks/use-priority-overflow-c9SjxZkZ.js +101 -0
- package/dist/_chunks/use-priority-overflow-c9SjxZkZ.js.map +1 -0
- package/dist/_chunks/use-visual-viewport-pin-ChurOsHM.js +31 -0
- package/dist/_chunks/use-visual-viewport-pin-ChurOsHM.js.map +1 -0
- package/dist/_chunks/{warning-stack-BaMI7-n7.js → warning-stack-BlG_Ujy3.js} +3 -3
- package/dist/_chunks/{warning-stack-BaMI7-n7.js.map → warning-stack-BlG_Ujy3.js.map} +1 -1
- package/dist/_chunks/{workflow-map-qWsgCldq.js → workflow-map-C643Q43h.js} +5 -5
- package/dist/_chunks/{workflow-map-qWsgCldq.js.map → workflow-map-C643Q43h.js.map} +1 -1
- package/dist/_chunks/{zh-CN-BncsTBwM.js → zh-CN-DkVN4vsB.js} +3 -3
- package/dist/_chunks/{zh-CN-BncsTBwM.js.map → zh-CN-DkVN4vsB.js.map} +1 -1
- package/dist/agent-catalog.json +4081 -3201
- package/dist/agent-i18n/en.json +121 -69
- package/dist/brand/product-lockup/product-lockup.d.ts +1 -1
- package/dist/components/_shared/calendar-class-names.d.ts.map +1 -1
- package/dist/components/_shared/entity-card/entity-card.d.ts +1 -1
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/ai-consent-banner/index.js +1 -1
- package/dist/components/ai-prompt-input/index.js +1 -1
- package/dist/components/anamnesis-card/anamnesis-card.d.ts +1 -1
- package/dist/components/anamnesis-card/index.js +1 -1
- package/dist/components/appointment-card/appointment-card.d.ts +1 -1
- package/dist/components/appointment-card/index.js +2 -2
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/audio-recorder/index.js +1 -1
- package/dist/components/benefit-card/benefit-card.d.ts.map +1 -1
- package/dist/components/benefit-card/index.js +1 -1
- package/dist/components/bishop-score/index.js +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/button/button.d.ts +8 -1
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/index.js +2 -2
- package/dist/components/button-group/button-group.d.ts +16 -0
- package/dist/components/button-group/button-group.d.ts.map +1 -1
- package/dist/components/button-group/index.js +1 -1
- package/dist/components/card/card.d.ts +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-entry-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/carousel/index.js +1 -1
- package/dist/components/chat-container/chat-container.d.ts.map +1 -1
- package/dist/components/chat-container/index.js +1 -1
- package/dist/components/chat-input/index.js +1 -1
- package/dist/components/chat-message/index.js +1 -1
- package/dist/components/clinical-note-card/clinical-note-card.d.ts +1 -1
- package/dist/components/connection-status/index.js +1 -1
- package/dist/components/contact-profile-card/contact-profile-card.d.ts +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/control-room-rail/index.js +1 -1
- package/dist/components/copy-field/index.js +1 -1
- package/dist/components/counter/counter.d.ts +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/data-table/data-table.d.ts +2 -8
- package/dist/components/data-table/data-table.d.ts.map +1 -1
- package/dist/components/data-table/filters/number-filter.d.ts.map +1 -1
- package/dist/components/data-table/index.js +35 -34
- package/dist/components/data-table/index.js.map +1 -1
- package/dist/components/data-table/toolbar.d.ts +5 -11
- package/dist/components/data-table/toolbar.d.ts.map +1 -1
- package/dist/components/data-table-tabs/data-table-tabs.agent.d.ts +4 -0
- package/dist/components/data-table-tabs/data-table-tabs.agent.d.ts.map +1 -0
- package/dist/components/data-table-tabs/data-table-tabs.d.ts +93 -0
- package/dist/components/data-table-tabs/data-table-tabs.d.ts.map +1 -0
- package/dist/components/data-table-tabs/index.d.ts +5 -0
- package/dist/components/data-table-tabs/index.d.ts.map +1 -0
- package/dist/components/data-table-tabs/index.js +8 -0
- package/dist/components/data-table-tabs/use-data-table-filter-tabs.d.ts +63 -0
- package/dist/components/data-table-tabs/use-data-table-filter-tabs.d.ts.map +1 -0
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/date-time-picker/index.js +1 -1
- package/dist/components/description-list/index.js +1 -1
- package/dist/components/document-preview/document-preview.agent.d.ts +4 -0
- package/dist/components/document-preview/document-preview.agent.d.ts.map +1 -0
- package/dist/components/document-preview/document-preview.d.ts +41 -0
- package/dist/components/document-preview/document-preview.d.ts.map +1 -0
- package/dist/components/document-preview/index.d.ts +4 -0
- package/dist/components/document-preview/index.d.ts.map +1 -0
- package/dist/components/document-preview/index.js +6 -0
- package/dist/components/document-preview/index.js.map +1 -0
- package/dist/components/document-scanner/document-scanner.d.ts.map +1 -1
- package/dist/components/document-scanner/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +2 -2
- package/dist/components/editor-overlay/index.js +1 -1
- package/dist/components/empty-state/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/face-scheme/face-scheme-data.d.ts +167 -0
- package/dist/components/face-scheme/face-scheme-data.d.ts.map +1 -1
- package/dist/components/face-scheme/face-scheme.agent.d.ts.map +1 -1
- package/dist/components/face-scheme/face-scheme.d.ts +112 -2
- package/dist/components/face-scheme/face-scheme.d.ts.map +1 -1
- package/dist/components/face-scheme/index.d.ts +2 -2
- package/dist/components/face-scheme/index.d.ts.map +1 -1
- package/dist/components/face-scheme/index.js +25 -14
- package/dist/components/fetal-weight/index.js +1 -1
- package/dist/components/field-array/index.js +1 -1
- package/dist/components/file-manager/dialogs.d.ts +48 -0
- package/dist/components/file-manager/dialogs.d.ts.map +1 -0
- package/dist/components/file-manager/file-manager.agent.d.ts +4 -0
- package/dist/components/file-manager/file-manager.agent.d.ts.map +1 -0
- package/dist/components/file-manager/file-manager.d.ts +82 -0
- package/dist/components/file-manager/file-manager.d.ts.map +1 -0
- package/dist/components/file-manager/folder-tree.d.ts +12 -0
- package/dist/components/file-manager/folder-tree.d.ts.map +1 -0
- package/dist/components/file-manager/index.d.ts +5 -0
- package/dist/components/file-manager/index.d.ts.map +1 -0
- package/dist/components/file-manager/index.js +6 -0
- package/dist/components/file-manager/index.js.map +1 -0
- package/dist/components/file-manager/list-view.d.ts +49 -0
- package/dist/components/file-manager/list-view.d.ts.map +1 -0
- package/dist/components/file-manager/toolbar.d.ts +15 -0
- package/dist/components/file-manager/toolbar.d.ts.map +1 -0
- package/dist/components/file-manager/types.d.ts +167 -0
- package/dist/components/file-manager/types.d.ts.map +1 -0
- package/dist/components/file-manager/utils.d.ts +34 -0
- package/dist/components/file-manager/utils.d.ts.map +1 -0
- package/dist/components/file-upload/file-upload.d.ts +1 -0
- package/dist/components/file-upload/file-upload.d.ts.map +1 -1
- package/dist/components/file-upload/index.d.ts +1 -1
- package/dist/components/file-upload/index.d.ts.map +1 -1
- package/dist/components/file-upload/index.js +4 -3
- package/dist/components/finished-terminal/finished-terminal.d.ts.map +1 -1
- package/dist/components/finished-terminal/index.js +1 -1
- package/dist/components/fiscal-code-input/index.js +1 -1
- package/dist/components/flag/flag.d.ts +1 -1
- package/dist/components/freemium-paywall/freemium-paywall.d.ts.map +1 -1
- package/dist/components/freemium-paywall/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/hcg-doubling/index.js +1 -1
- package/dist/components/header/header.d.ts.map +1 -1
- package/dist/components/header/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/icon-button/index.js +1 -1
- package/dist/components/icon-button-group/icon-button-group.d.ts +6 -0
- package/dist/components/icon-button-group/icon-button-group.d.ts.map +1 -1
- package/dist/components/icon-button-group/index.js +1 -1
- package/dist/components/icon-picker/index.js +1 -1
- package/dist/components/image-cropper/index.js +1 -1
- package/dist/components/index.d.ts +7 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/key-value-pair/index.js +1 -1
- package/dist/components/link/link.d.ts +1 -1
- package/dist/components/locale-picker/index.js +1 -1
- package/dist/components/map-view/index.js +1 -1
- package/dist/components/matrix-rain/matrix-rain.d.ts +1 -1
- package/dist/components/message-card/index.js +1 -1
- package/dist/components/message-card/message-card.d.ts +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/muscle-scheme/index.js +1 -1
- package/dist/components/muscle-scheme/muscle-scheme.d.ts.map +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notification-card/index.js +1 -1
- package/dist/components/notification-card/notification-card.d.ts +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/operator-hero/operator-hero.d.ts +1 -1
- package/dist/components/optical-prescription/index.d.ts +4 -2
- package/dist/components/optical-prescription/index.d.ts.map +1 -1
- package/dist/components/optical-prescription/index.js +29 -26
- package/dist/components/optical-prescription/optical-prescription-charts.d.ts +78 -0
- package/dist/components/optical-prescription/optical-prescription-charts.d.ts.map +1 -0
- package/dist/components/optical-prescription/optical-prescription-data.d.ts +29 -0
- package/dist/components/optical-prescription/optical-prescription-data.d.ts.map +1 -1
- package/dist/components/optical-prescription/optical-prescription.agent.d.ts.map +1 -1
- package/dist/components/optical-prescription/optical-prescription.d.ts +9 -0
- package/dist/components/optical-prescription/optical-prescription.d.ts.map +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/patient-search/patient-search.d.ts.map +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-summary-card/patient-summary-card.d.ts +1 -1
- package/dist/components/patient-table/columns.d.ts.map +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/payment-card/payment-card.d.ts +1 -1
- package/dist/components/payment-card/payment-request-card.d.ts +1 -1
- package/dist/components/periodontal-chart/index.d.ts +6 -0
- package/dist/components/periodontal-chart/index.d.ts.map +1 -0
- package/dist/components/periodontal-chart/index.js +22 -0
- package/dist/components/periodontal-chart/index.js.map +1 -0
- package/dist/components/periodontal-chart/periodontal-chart-data.d.ts +119 -0
- package/dist/components/periodontal-chart/periodontal-chart-data.d.ts.map +1 -0
- package/dist/components/periodontal-chart/periodontal-chart.agent.d.ts +4 -0
- package/dist/components/periodontal-chart/periodontal-chart.agent.d.ts.map +1 -0
- package/dist/components/periodontal-chart/periodontal-chart.d.ts +69 -0
- package/dist/components/periodontal-chart/periodontal-chart.d.ts.map +1 -0
- package/dist/components/periodontal-chart-card/index.js +1 -1
- package/dist/components/periodontal-chart-card/periodontal-chart-card.d.ts +1 -1
- package/dist/components/periodontal-diagnosis/index.d.ts +6 -0
- package/dist/components/periodontal-diagnosis/index.d.ts.map +1 -0
- package/dist/components/periodontal-diagnosis/index.js +13 -0
- package/dist/components/periodontal-diagnosis/index.js.map +1 -0
- package/dist/components/periodontal-diagnosis/periodontal-diagnosis-data.d.ts +30 -0
- package/dist/components/periodontal-diagnosis/periodontal-diagnosis-data.d.ts.map +1 -0
- package/dist/components/periodontal-diagnosis/periodontal-diagnosis.agent.d.ts +4 -0
- package/dist/components/periodontal-diagnosis/periodontal-diagnosis.agent.d.ts.map +1 -0
- package/dist/components/periodontal-diagnosis/periodontal-diagnosis.d.ts +44 -0
- package/dist/components/periodontal-diagnosis/periodontal-diagnosis.d.ts.map +1 -0
- package/dist/components/periodontal-risk-chart/index.d.ts +6 -0
- package/dist/components/periodontal-risk-chart/index.d.ts.map +1 -0
- package/dist/components/periodontal-risk-chart/index.js +9 -0
- package/dist/components/periodontal-risk-chart/index.js.map +1 -0
- package/dist/components/periodontal-risk-chart/periodontal-risk-chart.agent.d.ts +4 -0
- package/dist/components/periodontal-risk-chart/periodontal-risk-chart.agent.d.ts.map +1 -0
- package/dist/components/periodontal-risk-chart/periodontal-risk-chart.d.ts +28 -0
- package/dist/components/periodontal-risk-chart/periodontal-risk-chart.d.ts.map +1 -0
- package/dist/components/periodontal-risk-chart/periodontal-risk-data.d.ts +47 -0
- package/dist/components/periodontal-risk-chart/periodontal-risk-data.d.ts.map +1 -0
- package/dist/components/popover/index.js +1 -1
- package/dist/components/popover/popover.d.ts +1 -0
- package/dist/components/popover/popover.d.ts.map +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/privacy-lock/index.js +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/product-hub-tray/product-hub-panel.d.ts +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/public-header/public-header.d.ts +1 -1
- package/dist/components/public-header/public-header.d.ts.map +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/radiograph-panel/radiograph-panel.d.ts +2 -2
- package/dist/components/radiograph-panel/radiograph-panel.d.ts.map +1 -1
- package/dist/components/reviews-panel/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/select/index.js +1 -1
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/session-countdown/index.js +1 -1
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sidebar/index.js +1 -1
- package/dist/components/sidebar/sidebar.d.ts +9 -0
- package/dist/components/sidebar/sidebar.d.ts.map +1 -1
- package/dist/components/sign-document/index.js +1 -1
- package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
- package/dist/components/signature-capture/index.js +1 -1
- package/dist/components/signature-capture/signature-capture.d.ts.map +1 -1
- package/dist/components/signature-field/index.js +1 -1
- package/dist/components/signature-field/signature-field.d.ts +7 -0
- package/dist/components/signature-field/signature-field.d.ts.map +1 -1
- package/dist/components/skeleton-scheme/index.js +1186 -0
- package/dist/components/skeleton-scheme/index.js.map +1 -0
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/components/stat/stat.d.ts +1 -1
- package/dist/components/streaming-text/index.js +1 -1
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/toast/index.js +1 -1
- package/dist/components/token-insert-menu/index.js +1 -1
- package/dist/components/tool-rail/index.js +1 -1
- package/dist/components/tooth-scheme/index.js +29 -28
- package/dist/components/tooth-scheme/index.js.map +1 -1
- package/dist/components/transaction-chip/index.js +1 -1
- package/dist/components/unit-converter/index.js +1 -1
- package/dist/components/warning-stack/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +40 -35
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/use-priority-overflow.d.ts +63 -0
- package/dist/hooks/use-priority-overflow.d.ts.map +1 -0
- package/dist/hooks/use-visual-viewport-pin.d.ts +32 -0
- package/dist/hooks/use-visual-viewport-pin.d.ts.map +1 -0
- package/dist/i18n/locales/ar.d.ts +490 -9
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +493 -12
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +490 -9
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +493 -12
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +490 -9
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +493 -12
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +490 -9
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +493 -12
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +490 -9
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +493 -12
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +490 -9
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +493 -12
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +490 -9
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +493 -12
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +490 -9
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +493 -12
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +490 -9
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +493 -12
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +490 -9
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +493 -12
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +490 -9
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +493 -12
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +490 -9
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +493 -12
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +490 -9
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +493 -12
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +490 -9
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +493 -12
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +490 -9
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +493 -12
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +490 -9
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +493 -12
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +490 -9
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +493 -12
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +490 -9
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +493 -12
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +872 -809
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +493 -12
- package/dist/locales/de.json +493 -12
- package/dist/locales/el.json +493 -12
- package/dist/locales/en.json +493 -12
- package/dist/locales/es.json +493 -12
- package/dist/locales/fr.json +493 -12
- package/dist/locales/hi.json +493 -12
- package/dist/locales/it.json +493 -12
- package/dist/locales/ja.json +493 -12
- package/dist/locales/nl.json +493 -12
- package/dist/locales/pl.json +493 -12
- package/dist/locales/pt.json +493 -12
- package/dist/locales/ro.json +493 -12
- package/dist/locales/ru.json +493 -12
- package/dist/locales/sq.json +493 -12
- package/dist/locales/sv.json +493 -12
- package/dist/locales/tr.json +493 -12
- package/dist/locales/zh.json +493 -12
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/marketplace-app-shell.d.ts +1 -1
- package/dist/patterns/signature-request/index.d.ts +3 -0
- package/dist/patterns/signature-request/index.d.ts.map +1 -0
- package/dist/patterns/signature-request/index.js +5 -0
- package/dist/patterns/signature-request/index.js.map +1 -0
- package/dist/patterns/signature-request/signature-request.d.ts +81 -0
- package/dist/patterns/signature-request/signature-request.d.ts.map +1 -0
- package/dist/tokens.css +2 -2
- package/package.json +32 -4
- package/dist/_chunks/benefit-card-Xnxj4Gmo.js.map +0 -1
- package/dist/_chunks/button-DD_0Xdmr.js.map +0 -1
- package/dist/_chunks/button-group-CvEnVzY7.js +0 -119
- package/dist/_chunks/button-group-CvEnVzY7.js.map +0 -1
- package/dist/_chunks/columns-2-8lq4-b8e.js.map +0 -1
- package/dist/_chunks/document-scanner-B23j4w7X.js.map +0 -1
- package/dist/_chunks/face-scheme-BT9_KdL0.js +0 -1450
- package/dist/_chunks/face-scheme-BT9_KdL0.js.map +0 -1
- package/dist/_chunks/file-upload-Kw1rdvFw.js.map +0 -1
- package/dist/_chunks/finished-terminal-Di4gtZ50.js.map +0 -1
- package/dist/_chunks/freemium-paywall-DFoeedwh.js.map +0 -1
- package/dist/_chunks/header-DaXWDw0M.js.map +0 -1
- package/dist/_chunks/icon-button-group-C48khLE0.js +0 -206
- package/dist/_chunks/icon-button-group-C48khLE0.js.map +0 -1
- package/dist/_chunks/insert-result-C7xSDb8q.js.map +0 -1
- package/dist/_chunks/link-cell-renderer-BCppbMec.js +0 -2185
- package/dist/_chunks/link-cell-renderer-BCppbMec.js.map +0 -1
- package/dist/_chunks/marketplace-app-shell-BCYiOvKZ.js.map +0 -1
- package/dist/_chunks/optical-prescription-Bmlbuopi.js +0 -653
- package/dist/_chunks/optical-prescription-Bmlbuopi.js.map +0 -1
- package/dist/_chunks/patient-search-X9SUZGpy.js.map +0 -1
- package/dist/_chunks/patient-shell-oiIRqEAl.js +0 -162
- package/dist/_chunks/patient-shell-oiIRqEAl.js.map +0 -1
- package/dist/_chunks/patient-table-BgWgNIMf.js.map +0 -1
- package/dist/_chunks/public-header.agent-C-opZaOw.js.map +0 -1
- package/dist/_chunks/radiograph-panel.agent-D1x33moc.js.map +0 -1
- package/dist/_chunks/rich-text-editor-DUgznqOf.js.map +0 -1
- package/dist/_chunks/sidebar-B0OBmJrC.js.map +0 -1
- package/dist/_chunks/signature-capture-Ct_4Md4e.js.map +0 -1
- package/dist/_chunks/signature-field-jgwYgUhO.js.map +0 -1
- package/dist/_chunks/subDays-DGSOp9d9.js +0 -8
- package/dist/_chunks/tooth-scheme-D_rso4uu.js +0 -2133
- package/dist/_chunks/tooth-scheme-D_rso4uu.js.map +0 -1
- package/dist/_chunks/transaction-chip-B6iWoVmU.js.map +0 -1
- package/dist/patterns/patient-shell/index.d.ts +0 -12
- package/dist/patterns/patient-shell/index.d.ts.map +0 -1
- package/dist/patterns/patient-shell/index.js +0 -5
- package/dist/patterns/patient-shell/patient-shell.d.ts +0 -62
- package/dist/patterns/patient-shell/patient-shell.d.ts.map +0 -1
- /package/dist/{patterns/patient-shell → components/data-table-tabs}/index.js.map +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"patient-table-BgWgNIMf.js","sources":["../../node_modules/lucide-react/dist/esm/icons/message-square.mjs","../../src/components/patient-table/cell-renderers/balance-badge-cell.tsx","../../src/components/patient-table/cell-renderers/care-plan-status-cell.tsx","../../src/components/patient-table/cell-renderers/next-appointment-cell.tsx","../../src/components/patient-table/columns.ts","../../src/components/patient-table/use-responsive-columns.ts","../../src/components/patient-table/patient-table.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z\",\n key: \"18887p\"\n }\n ]\n];\nconst MessageSquare = createLucideIcon(\"message-square\", __iconNode);\n\nexport { __iconNode, MessageSquare as default };\n//# sourceMappingURL=message-square.mjs.map\n","import type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '../../badge/badge';\nimport type { PatientRow } from '../types';\n\n/**\n * patient-table — BalanceBadgeCell\n * ----------------------------------------------------------------------------\n * Threshold-coloured unpaid-balance badge for the patient grid.\n *\n * Reads {@link PatientRow.unpaidAmount} (integer cents), formats it to the\n * display currency via `Intl.NumberFormat` (cents → major unit at the render\n * boundary — see types.ts), and wraps the result in a kit {@link Badge} whose\n * semantic variant buckets by outstanding-balance threshold:\n *\n * | cents bucket | meaning | Badge variant |\n * | ----------------------- | ------------------ | ------------- |\n * | `0` | settled | `success` |\n * | `> 0` and `<= 50000` | small balance | `warning` |\n * | `> 50000` | overdue / large | `error` |\n *\n * NOTE on the variant name: the task brief calls the red bucket\n * `destructive`; the kit `Badge` exposes that semantic tier as the `error`\n * variant (backed by the `--destructive` / `--error-foreground` tokens). There\n * is no `destructive` Badge variant, so `error` is the correct destructive-tier\n * mapping — recorded here so the brief↔code discrepancy is intentional.\n *\n * The bucket meaning is colour-coded, so it is also surfaced as an sr-only\n * status word inside the badge (alongside the `withDot` indicator) — the\n * threshold tier is never conveyed by colour alone.\n *\n * Returns `null` when `unpaidAmount` is missing / non-finite (empty cell), per\n * the data-table renderer convention.\n */\n\n/** Display + threshold-classification result for a single balance value. */\ntype BalanceBucket = {\n variant: 'success' | 'warning' | 'error';\n /** i18n key suffix under `ui.patientTable.balance.status.*`. */\n statusKey: 'settled' | 'pending' | 'overdue';\n};\n\n/** Cents at or below which a non-zero balance is treated as a small balance. */\nconst SMALL_BALANCE_CENTS_MAX = 50000;\n\nfunction classifyBalance(cents: number): BalanceBucket {\n if (cents === 0) return { variant: 'success', statusKey: 'settled' };\n if (cents <= SMALL_BALANCE_CENTS_MAX)\n return { variant: 'warning', statusKey: 'pending' };\n return { variant: 'error', statusKey: 'overdue' };\n}\n\nfunction readUnpaidCents(value: unknown): number | null {\n if (value == null || value === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\nexport interface BalanceBadgeCellParams {\n /** ISO 4217 currency code used to format the balance. Default `'EUR'`. */\n currency?: string;\n /**\n * `Intl.NumberFormat` escape hatch, merged on top of the currency defaults.\n * E.g. `{ maximumFractionDigits: 0 }` for whole-currency display.\n */\n options?: Intl.NumberFormatOptions;\n}\n\nexport function BalanceBadgeCell(\n props: CustomCellRendererProps<PatientRow> & BalanceBadgeCellParams,\n) {\n const { value, currency = 'EUR', options } = props;\n const { t, i18n } = useTranslation('ui');\n\n const cents = readUnpaidCents(value);\n if (cents === null) return null;\n\n const locale = i18n.language || 'en';\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...options,\n }).format(cents / 100);\n\n const { variant, statusKey } = classifyBalance(cents);\n const status = t(`patientTable.balance.status.${statusKey}`);\n\n return (\n <Badge variant={variant} withDot size=\"sm\" className=\"ds:tabular-nums\">\n {/* Visible: the formatted amount. The threshold meaning is colour-coded,\n so the status word is surfaced to AT as sr-only text — the bucket is\n never conveyed by colour alone. */}\n <span>{formatted}</span>\n <span className=\"ds:sr-only\">{status}</span>\n </Badge>\n );\n}\n","/**\n * care-plan-status-cell — patient-table cell renderer\n * ----------------------------------------------------------------------------\n * A thin domain preset over the data-table `StatusCellRenderer` / kit `Badge`:\n * it bakes the patient care-plan lifecycle `variantMap` so consumers don't have\n * to re-declare it on every column, and localises the label via the `ui`\n * namespace (`ui.patientTable.carePlanStatus.*`).\n *\n * Reads `PatientRow.carePlanStatus` (preferring `data.carePlanStatus`, falling\n * back to AG Grid's resolved `value`), maps it to a Badge variant:\n *\n * accepted → success estimate → info none → neutral (muted)\n *\n * GROUND-TRUTH NOTES (vs. the task brief):\n * • `StatusCellRenderer` is not exported from a barrel and is a tiny wrapper\n * around `Badge`; this preset composes `Badge` directly (same primitive,\n * no extra indirection) rather than wrapping the wrapper.\n * • The brand says the \"muted\" variant is `none`; `Badge`'s neutral variant is\n * already the muted grey chip, so `none → 'neutral'`.\n * • No event handling: a status badge is presentational, so there are no\n * provided callbacks to wire.\n */\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '../../badge/badge';\nimport type { PatientCarePlanStatus, PatientRow } from '../types';\n\n/** Badge variant baked per care-plan lifecycle state. */\ntype CarePlanBadgeVariant = 'success' | 'info' | 'neutral';\n\n/**\n * Lifecycle → Badge-variant map. Frozen so it can't be mutated by a consumer\n * holding the reference.\n */\nconst CARE_PLAN_VARIANT_MAP: Readonly<\n Record<PatientCarePlanStatus, CarePlanBadgeVariant>\n> = {\n accepted: 'success',\n estimate: 'info',\n none: 'neutral',\n};\n\n/**\n * `cellRendererParams` for `CarePlanStatusCell`.\n *\n * The lifecycle status, label source and variant map are all baked in, so the\n * only knob is the Badge size — defaults to the compact `sm` chip that fits the\n * standard AG Grid row height.\n */\nexport interface CarePlanStatusCellParams {\n /** Badge size. Defaults to `'sm'` to fit the standard row height. */\n size?: 'sm' | 'md' | 'lg';\n}\n\nfunction isCarePlanStatus(value: unknown): value is PatientCarePlanStatus {\n return value === 'accepted' || value === 'estimate' || value === 'none';\n}\n\n/**\n * Patient care-plan lifecycle badge cell.\n *\n * Pass as `cellRenderer` on the `carePlanStatus` column; the patient\n * `variantMap` and localisation are handled internally.\n */\nexport function CarePlanStatusCell(\n props: CustomCellRendererProps<PatientRow, PatientCarePlanStatus> &\n CarePlanStatusCellParams,\n) {\n const { t } = useTranslation('ui');\n const { data, value, size = 'sm' } = props;\n\n // Prefer the typed row field; fall back to AG Grid's resolved cell value.\n const raw = data?.carePlanStatus ?? value;\n if (!isCarePlanStatus(raw)) return null;\n\n const variant = CARE_PLAN_VARIANT_MAP[raw];\n\n return (\n <Badge variant={variant} withDot size={size}>\n {t(`patientTable.carePlanStatus.${raw}`)}\n </Badge>\n );\n}\n","/**\n * next-appointment-cell — patient-table cell renderer\n * ----------------------------------------------------------------------------\n * Smart upcoming-appointment cell. Renders `PatientRow.nextAppointment` as a\n * locale-aware *relative* phrase (\"in 3 days\", \"tomorrow\") via the kit\n * `Timestamp`, mirroring the `relative` preset of the data-table\n * `DateCellRenderer`. When the appointment falls within a configurable window\n * (default 7 days from now), the cell takes a token-bound emphasis treatment so\n * imminent visits stand out at a glance. When `nextAppointment` is absent it\n * renders a muted \"no upcoming\" empty-state label.\n *\n * Reads `PatientRow.nextAppointment` (preferring the typed `data.nextAppointment`\n * field, falling back to AG Grid's resolved `value`).\n *\n * GROUND-TRUTH NOTES (vs. the task brief):\n * • The brief asked for a highlight \"within 7 days\". That window is exposed as\n * `soonWithinDays` (default 7) so a column can tune it without a new renderer,\n * matching the param-driven shape of the other patient renderers.\n * • The brief named `Avatar`, `Tag`, `Icon`, `IconButton`, `Tooltip` as\n * candidate primitives. This cell is purely presentational (a date + optional\n * emphasis), so it composes only `Timestamp` plus a decorative lucide glyph —\n * the same minimal-primitive approach the analogous `CarePlanStatusCell`\n * takes. There is no `Icon`/`IconButton` standalone component in the kit\n * (renderers use `lucide-react` glyphs directly), and no row callback is\n * provided, so no interactive affordance is wired.\n * • The emphasis is a CVA `tone` variant bound entirely to design tokens\n * (`--warning-foreground`); NO colour is hardcoded and nothing is pushed into\n * AG Grid `cellStyle`/`cellClass`.\n * • PHI rule (PRS 26 §6): no row field reaches a DOM `data-*` attribute here.\n */\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { CalendarClock } from 'lucide-react';\nimport type { CustomCellRendererProps } from 'ag-grid-react';\nimport { useTranslation } from 'react-i18next';\nimport { Timestamp } from '../../timestamp';\nimport type { PatientRow } from '../types';\n\n/* ------------------------------------------------------------------ */\n/* CVA — cell wrapper */\n/* */\n/* `tone` is the only stylistic axis: `soon` lifts the row to a */\n/* token-bound warning emphasis, `default` inherits the cell colour. */\n/* ------------------------------------------------------------------ */\n\nconst nextAppointmentVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] ds:whitespace-nowrap',\n {\n variants: {\n tone: {\n default: '',\n // Imminent visit: warning foreground token + medium weight. Fully\n // token-bound — no literal colour, no AG Grid cellStyle.\n soon: 'ds:text-[color:var(--warning-foreground)] ds:font-medium',\n // Absent appointment: muted empty state.\n empty: 'ds:text-[color:var(--muted-foreground)]',\n },\n },\n defaultVariants: { tone: 'default' },\n },\n);\n\ntype NextAppointmentVariantProps = VariantProps<typeof nextAppointmentVariants>;\n\n/* ------------------------------------------------------------------ */\n/* Params */\n/* ------------------------------------------------------------------ */\n\n/**\n * `cellRendererParams` for {@link NextAppointmentCell}.\n *\n * Localisation and the relative-date formatting are handled internally; the\n * only knob is the imminence window.\n */\nexport interface NextAppointmentCellParams {\n /**\n * Highlight the cell when the appointment is at most this many days away\n * (and not in the past). Defaults to `7`. A value `<= 0` disables the\n * highlight.\n */\n soonWithinDays?: number;\n}\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst DEFAULT_SOON_WITHIN_DAYS = 7;\n\nfunction toTime(value: unknown): number | null {\n if (value == null || value === '') return null;\n const t =\n value instanceof Date\n ? value.getTime()\n : typeof value === 'number'\n ? value\n : new Date(String(value)).getTime();\n return Number.isNaN(t) ? null : t;\n}\n\n/**\n * Resolve the emphasis tone for a parsed appointment time. `soon` covers any\n * upcoming visit within the window (including today); past appointments fall\n * back to `default`.\n */\nfunction resolveTone(\n time: number,\n soonWithinDays: number,\n): NonNullable<NextAppointmentVariantProps['tone']> {\n if (soonWithinDays <= 0) return 'default';\n const deltaMs = time - Date.now();\n if (deltaMs < 0) return 'default';\n return deltaMs <= soonWithinDays * DAY_MS ? 'soon' : 'default';\n}\n\n/* ------------------------------------------------------------------ */\n/* NextAppointmentCell */\n/* ------------------------------------------------------------------ */\n\n/**\n * Smart upcoming-appointment cell.\n *\n * Pass as `cellRenderer` on the `nextAppointment` column; the relative\n * formatting, imminence emphasis and empty state are handled internally.\n */\nexport function NextAppointmentCell(\n props: CustomCellRendererProps<PatientRow, string> &\n NextAppointmentCellParams,\n) {\n const { t } = useTranslation('ui');\n const { data, value, soonWithinDays = DEFAULT_SOON_WITHIN_DAYS } = props;\n\n // Prefer the typed row field; fall back to AG Grid's resolved cell value.\n const time = toTime(data?.nextAppointment ?? value);\n\n if (time === null) {\n return (\n <span className={nextAppointmentVariants({ tone: 'empty' })}>\n {t('patientTable.nextAppointment.none')}\n </span>\n );\n }\n\n const tone = resolveTone(time, soonWithinDays);\n\n return (\n <span className={nextAppointmentVariants({ tone })}>\n {tone === 'soon' ? (\n <CalendarClock aria-hidden=\"true\" className=\"ds:size-3.5 ds:shrink-0\" />\n ) : null}\n <Timestamp value={time} format=\"relative\" shape=\"bare\" />\n </span>\n );\n}\n","/**\n * patient-table — column definitions\n * ----------------------------------------------------------------------------\n * `buildPatientColumns(t, opts)` returns the ordered `ColDef<PatientRow>[]` for\n * the patient grid. Every patient field is its OWN column — sortable, filterable\n * and individually hideable via ColumnToggle — rather than several fields jumbled\n * into one composite cell. Each column wires the right kit cell renderer + the\n * right kit filter + floatingFilter, a localised `headerName` (from\n * `ui.patientTable.column.*`) and a stable `colId`.\n *\n * Identity is SPLIT across three pinned-start columns (the spec's\n * \"Avatar · First · Last\"):\n * • `avatar` — ImageCellRenderer (photo, initials fallback), sr-only header.\n * • `firstName` — plain text.\n * • `lastName` — LinkCellRenderer (the patient-detail link, `identityHref`).\n * All three are pinned-start P0 anchors and never auto-hide.\n *\n * COLUMN VISIBILITY\n * -----------------\n * `●` default-visible columns carry a `responsiveTier`; the responsive hook hides\n * them by tier as the grid narrows. Every other (grouped) column ships\n * `hide: true` and NO tier, so the hook leaves it alone and a user ColumnToggle\n * override wins. The anchors (avatar / firstName / lastName / actions) omit a\n * tier so they are never auto-hidden.\n *\n * RESPONSIVE TIER MECHANISM\n * -------------------------\n * Each column may carry a custom `responsiveTier` (`P0`–`P3`) property. AG Grid's\n * `ColDef` is an open/extensible shape — extra properties pass through untouched\n * at runtime — but its TS type is closed, so we type each entry as\n * `PatientColDefWithTier` and read the tier back via {@link getResponsiveTier}\n * (no `any`, no reliance on AG Grid's loose `context`).\n *\n * CUSTOM FIELDS\n * -------------\n * `opts.customFields` appends one dynamic column per descriptor after the\n * standard columns: `colId: \\`custom:${fieldName}\\``, a LITERAL `headerName`\n * (the practice-defined label — never i18n-keyed), a `valueGetter` reading\n * `row.customFields?.[fieldName]`, and a renderer + filter chosen by `type`\n * (`text` → plain text · `checkbox` → ✓/— · `dropdown` → Tag chip). All ship\n * `hide: true` and no tier.\n *\n * CONSTRAINTS:\n * • No colour / spacing / radius / font literal in any `cellStyle`/`cellClass`\n * here — only token-bound `ds:` utility classes — so the AG Grid theme bridge\n * stays in control of theming.\n * • CSS logical properties only.\n * • PHI rule (PRS 26 §6): no `PatientRow` field other than `id` is ever placed\n * in a DOM `data-*` attribute. Renderers surface name/contact/DOB as text\n * content only; these defs pass values, not attributes.\n */\nimport type { TFunction } from 'i18next';\nimport { Eye, Mail, MessageSquare, Pencil, Trash2, Users } from 'lucide-react';\nimport { createElement } from 'react';\nimport {\n ActionsCellRenderer,\n actionsColumnWidth,\n CurrencyCellRenderer,\n DateCellRenderer,\n DateRangeFilter,\n DateRangeFloatingFilter,\n ImageCellRenderer,\n LinkCellRenderer,\n NumberFilter,\n NumberFloatingFilter,\n SelectFilter,\n SelectFloatingFilter,\n StatusCellRenderer,\n TagListCellRenderer,\n TextFilter,\n TextFloatingFilter,\n TypeaheadFilter,\n TypeaheadFloatingFilter,\n UserCellRenderer,\n type ActionDef,\n type StatusCellRendererParams,\n type UserCellValue,\n} from '../data-table';\nimport { BalanceBadgeCell } from './cell-renderers/balance-badge-cell';\nimport { CarePlanStatusCell } from './cell-renderers/care-plan-status-cell';\nimport { NextAppointmentCell } from './cell-renderers/next-appointment-cell';\nimport type {\n PatientColDef,\n PatientColumnDef,\n PatientColumnId,\n PatientCustomFieldDef,\n PatientRow,\n PatientRowAction,\n ResponsiveTier,\n} from './types';\n\n/* -------------------------------------------------------------------------- */\n/* Responsive-tier extension */\n/* -------------------------------------------------------------------------- */\n\n/**\n * A patient leaf column carrying its responsive-priority tier. AG Grid passes\n * the extra `responsiveTier` key through untouched; we keep it strongly typed\n * (no `any`, no reliance on AG Grid's `context: any`) so the responsive hook can\n * read it back via {@link getResponsiveTier}.\n */\nexport type PatientColDefWithTier = PatientColDef & {\n /**\n * Responsive priority. Lower numbers survive longer as the grid narrows:\n * `P0` always visible, `P3` first to hide. Consumed by `useResponsiveColumns`.\n */\n responsiveTier?: ResponsiveTier;\n};\n\n/**\n * Read the responsive tier off a column definition. Returns `undefined` for\n * columns that opt out of responsive toggling — the pinned anchors and every\n * `hide: true` grouped column deliberately omit a tier so they are never\n * auto-managed by the responsive hook.\n */\nexport function getResponsiveTier(\n colDef: PatientColumnDef,\n): ResponsiveTier | undefined {\n return (colDef as PatientColDefWithTier).responsiveTier;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Options */\n/* -------------------------------------------------------------------------- */\n\n/** Options threaded into {@link buildPatientColumns}. */\nexport interface BuildPatientColumnsOptions {\n /**\n * Mask sensitive contact details (email) — when `true` the `email` column\n * ships hidden. Forwarded from `PatientTable`'s `hidePatientDetails`. Default\n * `false`.\n */\n hideDetails?: boolean;\n /**\n * Live getter for the actions-column density. When it returns `true`, the\n * `ActionsCellRenderer` collapses its inline buttons into a single \"…\" overflow\n * menu (the spec's 180→88px compact density). Reading via a getter lets a\n * density toggle flip without rebuilding column defs (preserves column state) —\n * call `api.refreshCells({ force: true })` after flipping the backing value.\n * Defaults to a getter that always returns `false`.\n */\n getActionsCompact?: () => boolean;\n /**\n * Invoked when a per-row action button is activated, with the resolved action\n * descriptor and the patient row. Only `row.id` ever leaves this boundary into\n * persistence / agent surfaces — never PHI.\n */\n onRowAction?: (action: PatientRowAction, patient: PatientRow) => void;\n /**\n * Derive the patient-detail href for the `lastName` link column, e.g.\n * `(row) => \\`/patients/${row.id}\\``. When omitted the lastName cell renders a\n * button that calls `onRowAction` with the `show` action instead.\n */\n identityHref?: string | ((row: PatientRow) => string | undefined);\n /**\n * Per-practice custom-field descriptors. Each appends one dynamic `custom:*`\n * column (hidden by default) after the standard columns. See\n * {@link PatientCustomFieldDef}.\n */\n customFields?: PatientCustomFieldDef[];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Row actions */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The fixed number of per-row actions the patient grid builds (show · edit ·\n * email reminder · sms reminder · reassign · delete — see {@link buildRowActions}).\n * Exposed so the component can size the actions column to its EXPANDED footprint\n * (`actionsColumnWidth(PATIENT_ROW_ACTION_COUNT)`) when flipping the runtime\n * compact-actions toggle off, without rebuilding the column defs. Keep in sync\n * with the array {@link buildRowActions} returns.\n */\nexport const PATIENT_ROW_ACTION_COUNT = 6;\n\n/**\n * Build the per-row `ActionDef`s for the actions column. Each is mapped from the\n * spec's closed action set; `hidden` / `disabled` predicates encode the spec's\n * per-row rules (e.g. `sendEmailReminder` hidden when `!emailEnabled`).\n *\n * Bridges the kit `ActionDef<PatientRow>` shape (icon/label/onClick) to the\n * patient `onRowAction(action, patient)` contract by re-deriving a\n * `PatientRowAction` descriptor on click.\n */\nfunction buildRowActions(\n t: TFunction,\n onRowAction: BuildPatientColumnsOptions['onRowAction'],\n): ActionDef<PatientRow>[] {\n const dispatch =\n (action: PatientRowAction) =>\n (patient: PatientRow): void => {\n onRowAction?.(action, patient);\n };\n\n // Each entry pairs the kit ActionDef (what the renderer needs) with the\n // patient-typed descriptor handed back to `onRowAction`.\n const make = (\n action: PatientRowAction,\n overrides: Omit<ActionDef<PatientRow>, 'label' | 'onClick' | 'icon'>,\n ): ActionDef<PatientRow> => ({\n icon: action.icon,\n label: action.label,\n variant: action.variant,\n onClick: dispatch(action),\n ...overrides,\n });\n\n return [\n make(\n {\n id: 'show',\n label: t('patientTable.actions.show'),\n icon: createElement(Eye, { 'aria-hidden': 'true' }),\n },\n {},\n ),\n make(\n {\n id: 'edit',\n label: t('patientTable.actions.edit'),\n icon: createElement(Pencil, { 'aria-hidden': 'true' }),\n },\n {},\n ),\n make(\n {\n id: 'sendEmailReminder',\n label: t('patientTable.actions.sendEmailReminder'),\n icon: createElement(Mail, { 'aria-hidden': 'true' }),\n },\n // Hidden when the patient has email contact disabled (spec).\n { hidden: (patient) => !patient.emailEnabled },\n ),\n make(\n {\n id: 'sendSmsReminder',\n label: t('patientTable.actions.sendSmsReminder'),\n icon: createElement(MessageSquare, { 'aria-hidden': 'true' }),\n },\n // Hidden when no phone number is SMS-enabled (spec).\n {\n hidden: (patient) =>\n !(patient.phoneNumbers ?? []).some((p) => p.smsEnabled),\n },\n ),\n make(\n {\n id: 'reassign',\n label: t('patientTable.actions.reassign'),\n icon: createElement(Users, { 'aria-hidden': 'true' }),\n },\n {},\n ),\n make(\n {\n id: 'delete',\n label: t('patientTable.actions.delete'),\n icon: createElement(Trash2, { 'aria-hidden': 'true' }),\n variant: 'destructive',\n },\n // Disabled (with a reason) for archived patients — the row model's\n // closest \"cannot delete\" signal. Surfaced as the inline tooltip.\n {\n disabled: (patient) => Boolean(patient.isArchived),\n disabledReason: t('patientTable.actions.deleteLocked'),\n },\n ),\n ];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------------- */\n\nconst NO = () => false;\n\n/** Glyph for boolean / eligibility valueFormatter (✓ when true, — otherwise). */\nconst CHECK = '✓';\nconst DASH = '—';\n\n/** Compute integer age (years) from an ISO date-of-birth string. */\nfunction ageFromDob(dob: string | undefined): number | null {\n if (!dob) return null;\n const birth = new Date(dob);\n const ms = birth.getTime();\n if (Number.isNaN(ms)) return null;\n const now = new Date();\n let age = now.getFullYear() - birth.getFullYear();\n const m = now.getMonth() - birth.getMonth();\n if (m < 0 || (m === 0 && now.getDate() < birth.getDate())) age -= 1;\n return age >= 0 ? age : null;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Custom-field columns */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Build the dynamic `custom:*` columns from the practice descriptors. Each is\n * appended hidden (no tier) after the standard columns: a literal `headerName`\n * (the descriptor's `label`, never i18n-keyed), a `valueGetter` reading\n * `row.customFields?.[fieldName]`, and a renderer + filter chosen by `type`.\n */\nfunction buildCustomFieldColumns(\n fields: PatientCustomFieldDef[],\n): PatientColDefWithTier[] {\n return fields.map((field): PatientColDefWithTier => {\n const colId: PatientColumnId = `custom:${field.fieldName}`;\n const base: PatientColDefWithTier = {\n colId,\n headerName: field.label,\n hide: true,\n // No tier — custom fields are opt-in via ColumnToggle only.\n };\n\n if (field.type === 'checkbox') {\n return {\n ...base,\n valueGetter: (params) =>\n params.data?.customFields?.[field.fieldName] === true,\n valueFormatter: (params) => (params.value === true ? CHECK : DASH),\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n { value: true, label: CHECK },\n { value: false, label: DASH },\n ],\n },\n minWidth: 110,\n width: 130,\n };\n }\n\n if (field.type === 'dropdown') {\n return {\n ...base,\n // TagListCellRenderer expects an array; wrap the single value.\n valueGetter: (params) => {\n const raw = params.data?.customFields?.[field.fieldName];\n return typeof raw === 'string' && raw ? [raw] : [];\n },\n cellRenderer: TagListCellRenderer,\n filterValueGetter: (params) => {\n const raw = params.data?.customFields?.[field.fieldName];\n return typeof raw === 'string' ? raw : '';\n },\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: (field.options ?? []).map((opt) => ({\n value: opt,\n label: opt,\n })),\n },\n sortable: false,\n minWidth: 130,\n width: 160,\n };\n }\n\n // text\n return {\n ...base,\n valueGetter: (params) => {\n const raw = params.data?.customFields?.[field.fieldName];\n return typeof raw === 'string' ? raw : '';\n },\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 140,\n width: 170,\n };\n });\n}\n\n/* -------------------------------------------------------------------------- */\n/* buildPatientColumns */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Build the ordered patient-grid column definitions — one field per column.\n *\n * @param t `react-i18next` translation fn (default `ui` namespace).\n * @param opts See {@link BuildPatientColumnsOptions} — density getter, row-action\n * callback, detail masking, identity href, custom fields.\n * @returns Ordered `PatientColumnDef[]`. Default-visible columns carry a\n * `responsiveTier` (read via {@link getResponsiveTier}); the pinned\n * anchors and every grouped (`hide: true`) column omit it so they are\n * never auto-hidden.\n */\nexport function buildPatientColumns(\n t: TFunction,\n opts: BuildPatientColumnsOptions = {},\n): PatientColumnDef[] {\n const {\n hideDetails = false,\n getActionsCompact = NO,\n onRowAction,\n identityHref,\n customFields = [],\n } = opts;\n\n const actions = buildRowActions(t, onRowAction);\n\n const genderLabels: Record<NonNullable<PatientRow['gender']>, string> = {\n m: t('patientTable.gender.m'),\n f: t('patientTable.gender.f'),\n x: t('patientTable.gender.x'),\n };\n\n // Tri-state marketing-consent → label + Badge variant (StatusCellRenderer).\n const consentLabels = {\n yes: t('patientTable.consent.yes'),\n no: t('patientTable.consent.no'),\n notSpecified: t('patientTable.consent.notSpecified'),\n };\n const consentVariantMap: StatusCellRendererParams['variantMap'] = {\n [consentLabels.yes]: 'success',\n [consentLabels.no]: 'error',\n [consentLabels.notSpecified]: 'neutral',\n };\n\n const header = (id: PatientColumnId): string =>\n t(`patientTable.column.${id}`);\n\n const columns: PatientColDefWithTier[] = [\n /* ── Avatar (P0, pinned-start) ─────────────────────────────────── */\n {\n colId: 'avatar',\n // sr-only header — the photo column needs no visible label, but AG Grid\n // and AT still want a name. `headerName` reads \"Photo\"; the visible header\n // TEXT is clipped via the kit's `sr-only-th` convention (clips only\n // `.ag-header-cell-text`, keeping the header-cell box in the grid chrome\n // and the name in the a11y tree — see ag-grid-theme.css).\n headerName: header('avatar'),\n headerClass: 'sr-only-th',\n pinned: 'left',\n cellRenderer: ImageCellRenderer,\n cellRendererParams: {\n srcField: 'avatarUrl',\n fallbackField: 'lastName',\n size: 'sm',\n shape: 'circle',\n },\n sortable: false,\n filter: false,\n resizable: false,\n // Hug the 32px (size=\"sm\") avatar + cell padding — a tight fixed column,\n // not a wide empty one. width === minWidth === maxWidth pins it to size so\n // the pinned group can't stretch it (pinned columns never flex).\n width: 52,\n minWidth: 52,\n maxWidth: 52,\n // Anchor — never auto-hidden (no tier).\n },\n\n /* ── First name (P0, pinned-start) — plain text ────────────────── */\n {\n colId: 'firstName',\n headerName: header('firstName'),\n pinned: 'left',\n field: 'firstName',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n // Size to content: width === minWidth so the pinned column sits tight with\n // no dead space before the next pinned column (pinned columns can't flex).\n width: 140,\n minWidth: 120,\n // Anchor — never auto-hidden (no tier).\n },\n\n /* ── Last name (P0, pinned-start) — the patient-detail link ────── */\n {\n colId: 'lastName',\n headerName: header('lastName'),\n pinned: 'left',\n field: 'lastName',\n cellRenderer: LinkCellRenderer,\n cellRendererParams: {\n href: identityHref,\n // When no detail href is supplied the cell renders a button; route its\n // click through the same `show` row action.\n onClick: onRowAction\n ? (row: PatientRow) =>\n onRowAction(\n { id: 'show', label: t('patientTable.actions.show') },\n row,\n )\n : undefined,\n },\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n // Size to content: a modest pinned width with no stretched default, so the\n // avatar + first + last group ends tight against the scrollable columns.\n width: 150,\n minWidth: 130,\n // Anchor — never auto-hidden (no tier).\n },\n\n /* ── Phone (P1) ────────────────────────────────────────────────── */\n {\n colId: 'phone',\n headerName: header('phone'),\n responsiveTier: 'P1',\n // The primary phone number string (prefix + number).\n valueGetter: (params) => params.data?.phoneNumbers?.[0]?.number ?? '',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 160,\n width: 180,\n },\n\n /* ── Next appointment (P1) ─────────────────────────────────────── */\n {\n colId: 'nextAppointment',\n headerName: header('nextAppointment'),\n responsiveTier: 'P1',\n field: 'nextAppointment',\n cellRenderer: NextAppointmentCell,\n filter: DateRangeFilter,\n floatingFilterComponent: DateRangeFloatingFilter,\n minWidth: 160,\n width: 180,\n },\n\n /* ── Unpaid balance (P1) ───────────────────────────────────────── */\n {\n colId: 'unpaidBalance',\n headerName: header('unpaidBalance'),\n responsiveTier: 'P1',\n field: 'unpaidAmount',\n type: 'numericColumn',\n cellRenderer: BalanceBadgeCell,\n filter: NumberFilter,\n floatingFilterComponent: NumberFloatingFilter,\n // Money is integer cents; the inRange filter compares cents directly.\n filterParams: { defaultOperator: 'inRange', min: 0 },\n minWidth: 150,\n width: 170,\n },\n\n /* ── Email (P2) — hidden when masking ──────────────────────────── */\n {\n colId: 'email',\n headerName: header('email'),\n responsiveTier: 'P2',\n field: 'email',\n // Emit `hide` ONLY when masking (never a literal `hide: false`). A static\n // `hide: false` is re-applied by AG Grid on every `columnDefs` reconcile,\n // clobbering a runtime hide from the ViewSwitcher / responsive hook.\n hide: hideDetails || undefined,\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 200,\n width: 240,\n },\n\n /* ── Care-plan status (P2) ─────────────────────────────────────── */\n {\n colId: 'carePlanStatus',\n headerName: header('carePlanStatus'),\n responsiveTier: 'P2',\n field: 'carePlanStatus',\n cellRenderer: CarePlanStatusCell,\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n {\n value: 'accepted',\n label: t('patientTable.carePlanStatus.accepted'),\n },\n {\n value: 'estimate',\n label: t('patientTable.carePlanStatus.estimate'),\n },\n { value: 'none', label: t('patientTable.carePlanStatus.none') },\n ],\n },\n sortable: false,\n minWidth: 130,\n width: 150,\n },\n\n /* ── Fiscal code (P3, text) ────────────────────────────────────── */\n {\n colId: 'fiscalCode',\n headerName: header('fiscalCode'),\n responsiveTier: 'P3',\n field: 'italianFiscalCode',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 160,\n width: 180,\n },\n\n /* ── Age (P3, derived numeric) ─────────────────────────────────── */\n {\n colId: 'age',\n headerName: header('age'),\n responsiveTier: 'P3',\n // Left-aligned like the text columns — `numericColumn` (which right-aligns\n // header + cell) is for ledger figures, not a 2-digit age. Sort stays\n // numeric because the valueGetter returns a number.\n valueGetter: (params) =>\n ageFromDob(params.data?.dateOfBirth) ?? undefined,\n filter: NumberFilter,\n floatingFilterComponent: NumberFloatingFilter,\n minWidth: 90,\n width: 110,\n },\n\n /* ── Gender (P3) ───────────────────────────────────────────────── */\n {\n colId: 'gender',\n headerName: header('gender'),\n responsiveTier: 'P3',\n // Map the raw code to a localised label for both cell + set filter.\n valueGetter: (params) =>\n params.data?.gender ? genderLabels[params.data.gender] : DASH,\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n { value: genderLabels.m, label: genderLabels.m },\n { value: genderLabels.f, label: genderLabels.f },\n { value: genderLabels.x, label: genderLabels.x },\n ],\n },\n minWidth: 110,\n width: 130,\n },\n\n /* ── Source (P3) ───────────────────────────────────────────────── */\n {\n colId: 'source',\n headerName: header('source'),\n responsiveTier: 'P3',\n // TagListCellRenderer expects an array; wrap the resolved source string.\n valueGetter: (params) => {\n const s = params.data?.source ?? params.data?.customSource;\n return s ? [s] : [];\n },\n cellRenderer: TagListCellRenderer,\n filterValueGetter: (params) =>\n params.data?.source ?? params.data?.customSource ?? '',\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n sortable: false,\n minWidth: 120,\n width: 150,\n },\n\n /* ── Grouped: Identity — hidden by default ─────────────────────── */\n {\n colId: 'dateOfBirth',\n headerName: header('dateOfBirth'),\n hide: true,\n field: 'dateOfBirth',\n cellRenderer: DateCellRenderer,\n cellRendererParams: { format: 'date' },\n filter: DateRangeFilter,\n floatingFilterComponent: DateRangeFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n {\n colId: 'placeOfBirth',\n headerName: header('placeOfBirth'),\n hide: true,\n field: 'placeOfBirth',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n {\n colId: 'countryOfBirth',\n headerName: header('countryOfBirth'),\n hide: true,\n field: 'countryOfBirth',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 130,\n width: 150,\n },\n\n /* ── Grouped: Contact — hidden by default ──────────────────────── */\n {\n colId: 'smsReminders',\n headerName: header('smsReminders'),\n hide: true,\n valueGetter: (params) => Boolean(params.data?.smsReminderEligible),\n valueFormatter: (params) => (params.value === true ? CHECK : DASH),\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n { value: true, label: CHECK },\n { value: false, label: DASH },\n ],\n },\n minWidth: 120,\n width: 140,\n },\n {\n colId: 'emailReminders',\n headerName: header('emailReminders'),\n hide: true,\n valueGetter: (params) => Boolean(params.data?.emailReminderEligible),\n valueFormatter: (params) => (params.value === true ? CHECK : DASH),\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n { value: true, label: CHECK },\n { value: false, label: DASH },\n ],\n },\n minWidth: 120,\n width: 140,\n },\n {\n colId: 'pec',\n headerName: header('pec'),\n hide: true,\n field: 'pecAddress',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 200,\n width: 240,\n },\n\n /* ── Grouped: Appointments — hidden by default ─────────────────── */\n {\n colId: 'lastVisit',\n headerName: header('lastVisit'),\n hide: true,\n field: 'lastAppointment',\n cellRenderer: DateCellRenderer,\n cellRendererParams: { format: 'relative' },\n filter: DateRangeFilter,\n floatingFilterComponent: DateRangeFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n\n /* ── Grouped: Financial — hidden by default ────────────────────── */\n {\n colId: 'billableAmount',\n headerName: header('billableAmount'),\n hide: true,\n type: 'numericColumn',\n cellRenderer: CurrencyCellRenderer,\n // Cents → major unit at the render boundary. No `field` — the valueGetter\n // takes precedence over `field` in AG Grid for both cell + sort, so a\n // `field: 'billableAmount'` would be dead (and misleadingly imply the raw\n // cents drive the renderer).\n valueGetter: (params) =>\n params.data ? params.data.billableAmount / 100 : undefined,\n filter: NumberFilter,\n floatingFilterComponent: NumberFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n {\n colId: 'discount',\n headerName: header('discount'),\n hide: true,\n field: 'defaultDiscount',\n type: 'numericColumn',\n valueFormatter: (params) =>\n params.value == null ? '' : `${params.value}%`,\n filter: NumberFilter,\n floatingFilterComponent: NumberFloatingFilter,\n minWidth: 110,\n width: 130,\n },\n\n /* ── Grouped: Clinical — hidden by default ─────────────────────── */\n {\n colId: 'diagnosis',\n headerName: header('diagnosis'),\n hide: true,\n field: 'diagnosis',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 180,\n width: 220,\n },\n {\n colId: 'insurance',\n headerName: header('insurance'),\n hide: true,\n field: 'defaultInsurance',\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n {\n colId: 'assignedTo',\n headerName: header('assignedTo'),\n hide: true,\n cellRenderer: UserCellRenderer,\n valueGetter: (params) =>\n params.data?.personalAssistant\n ? ({ name: params.data.personalAssistant } satisfies UserCellValue)\n : null,\n comparator: (a: UserCellValue | null, b: UserCellValue | null) =>\n (a?.name ?? '').localeCompare(b?.name ?? ''),\n filterValueGetter: (params) => params.data?.personalAssistant ?? '',\n filter: TypeaheadFilter,\n floatingFilterComponent: TypeaheadFloatingFilter,\n minWidth: 160,\n width: 180,\n },\n {\n colId: 'job',\n headerName: header('job'),\n hide: true,\n field: 'job',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n\n /* ── Grouped: Admin — hidden by default ────────────────────────── */\n {\n colId: 'marketingConsent',\n headerName: header('marketingConsent'),\n hide: true,\n cellRenderer: StatusCellRenderer,\n cellRendererParams: {\n variantMap: consentVariantMap,\n } satisfies StatusCellRendererParams,\n valueGetter: (params) => {\n switch (params.data?.marketingConsent) {\n case 1:\n return consentLabels.yes;\n case 0:\n return consentLabels.no;\n default:\n return consentLabels.notSpecified;\n }\n },\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n { value: consentLabels.yes, label: consentLabels.yes },\n { value: consentLabels.no, label: consentLabels.no },\n {\n value: consentLabels.notSpecified,\n label: consentLabels.notSpecified,\n },\n ],\n },\n sortable: false,\n minWidth: 150,\n width: 170,\n },\n {\n colId: 'patientNumber',\n headerName: header('patientNumber'),\n hide: true,\n // `YYYY/N` yearly numbering.\n valueGetter: (params) => {\n const year = params.data?.yearlyNumberingYear;\n const num = params.data?.yearlyNumberingNumber;\n return year != null && num != null ? `${year}/${num}` : '';\n },\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 120,\n width: 140,\n },\n {\n colId: 'portal',\n headerName: header('portal'),\n hide: true,\n valueGetter: (params) => Boolean(params.data?.mydentista),\n valueFormatter: (params) => (params.value === true ? CHECK : DASH),\n filter: SelectFilter,\n floatingFilterComponent: SelectFloatingFilter,\n filterParams: {\n options: [\n { value: true, label: CHECK },\n { value: false, label: DASH },\n ],\n },\n minWidth: 110,\n width: 130,\n },\n {\n colId: 'createdAt',\n headerName: header('createdAt'),\n hide: true,\n field: 'createdAt',\n cellRenderer: DateCellRenderer,\n cellRendererParams: { format: 'date' },\n filter: DateRangeFilter,\n floatingFilterComponent: DateRangeFloatingFilter,\n minWidth: 140,\n width: 160,\n },\n\n /* ── Grouped: Address — hidden by default ──────────────────────── */\n {\n colId: 'city',\n headerName: header('city'),\n hide: true,\n field: 'city',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 120,\n width: 150,\n },\n {\n colId: 'province',\n headerName: header('province'),\n hide: true,\n field: 'province',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 100,\n width: 120,\n },\n {\n colId: 'postcode',\n headerName: header('postcode'),\n hide: true,\n field: 'postcode',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 110,\n width: 130,\n },\n {\n colId: 'country',\n headerName: header('country'),\n hide: true,\n field: 'countryCode',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 110,\n width: 130,\n },\n {\n colId: 'street',\n headerName: header('street'),\n hide: true,\n field: 'street',\n filter: TextFilter,\n floatingFilterComponent: TextFloatingFilter,\n minWidth: 180,\n width: 220,\n },\n\n /* ── Custom fields (per-practice, dynamic) — appended, hidden ──── */\n ...buildCustomFieldColumns(customFields),\n\n /* ── Actions (P0, pinned-end) ──────────────────────────────────── */\n {\n colId: 'actions',\n headerName: header('actions'),\n // Pinned to the inline-end edge so actions stay reachable while the field\n // columns scroll. AG Grid `pinned` is physical — the grid's `enableRtl`\n // flips this to the start edge under RTL.\n pinned: 'right',\n // Header + action group left-aligned (justify-start), consistent with every\n // other column — no right-aligned header (the actions still sit at the\n // pinned inline-end edge, the group just starts at the cell's leading edge).\n cellClass: 'ds:justify-start',\n cellRenderer: ActionsCellRenderer,\n cellRendererParams: {\n actions,\n intent: 'ghost',\n group: true,\n label: t('patientTable.actions.group'),\n collapsed: getActionsCompact,\n },\n sortable: false,\n filter: false,\n resizable: false,\n // The renderer collapses to a single overflow trigger via\n // `getActionsCompact`; the expanded width is DERIVED from the action count\n // so a row showing every action can't clip — 88px collapsed → fits-all.\n width: actionsColumnWidth(actions.length),\n minWidth: 88,\n // Anchor — never auto-hidden (no tier).\n },\n ];\n\n return columns;\n}\n","/**\n * patient-table — responsive column hook\n * ----------------------------------------------------------------------------\n * `useResponsiveColumns(handleRef, opts)` toggles column visibility by the\n * `responsiveTier` (`P0`–`P3`) baked onto each `ColDef` by `buildPatientColumns`,\n * driven by the *grid container's* width — measured with a `ResizeObserver`, NOT\n * the viewport — so the table responds correctly when embedded in a narrow panel,\n * split pane or sidebar rather than only at browser-window breakpoints.\n *\n * BREAKPOINTS (container inline-size → highest tier kept visible):\n *\n * < 640px → P0 only (pinned avatar / firstName / lastName / actions)\n * < 900px → P0 + P1 (+ phone, nextAppointment, balance)\n * < 1200px → P0 + P1 + P2 (+ email, carePlanStatus)\n * ≥ 1200px → all tiers (P0–P3) (+ fiscalCode, age, gender, source)\n *\n * Columns without a tier (the pinned avatar / firstName / lastName / actions\n * anchors, and every grouped `hide: true` column) are never touched — the\n * anchors stay visible at every width; the grouped columns are owned by\n * ColumnToggle only.\n *\n * RESPONSIVE ↔ PERSISTENCE RECONCILIATION\n * ---------------------------------------\n * `data-table.tsx` persists the full AG Grid column state to\n * `localStorage[\"data-table-col-state:<gridId>\"]` (load on grid-ready, save on\n * unmount). A user's explicit `ColumnToggle` choice lives in that persisted state\n * and MUST win over — and survive — the responsive baseline. Reconciliation:\n *\n * 1. The responsive baseline is exactly that — a *baseline*. We only auto\n * show/hide a column the user has NOT manually toggled this session.\n * 2. We track a `Set<colId>` of user-touched columns. We learn of a manual\n * toggle from the grid's `columnVisible` event: any such event whose\n * `source` is NOT `'api'` is user-driven (ColumnToggle tool panel, column\n * menu, context menu, drag), so we add those colIds to the set. Our own\n * responsive calls go through `setColumnsVisible(..., 'api')`, so they never\n * pollute the set (and we additionally guard with a re-entrancy flag).\n * 3. Once a column is user-touched, the hook leaves it alone forever this\n * session — its visibility is whatever the user chose, which is what\n * `data-table.tsx` then persists on unmount. The persisted choice therefore\n * wins on the next mount too: we seed the user-touched set from the saved\n * column state so a previously hidden/shown column is treated as a manual\n * override and not clobbered by the baseline on re-entry.\n *\n * CONSTRAINTS: no `any` (AG Grid's `ColumnEventType` is read off the typed event,\n * tier read via the typed `getResponsiveTier` helper). No DOM `data-*` attribute\n * is written here (PHI rule is moot — this hook only reads colIds and widths).\n */\nimport { useCallback, useEffect, useRef, type RefObject } from 'react';\nimport type { Column, ColumnVisibleEvent } from 'ag-grid-community';\nimport { getResponsiveTier } from './columns';\nimport type { PatientRow, PatientTableHandle, ResponsiveTier } from './types';\n\n/* -------------------------------------------------------------------------- */\n/* Breakpoint model */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Container inline-size breakpoints. Each entry is the *minimum* container width\n * (px) at which the named tier becomes visible. Below the first threshold only\n * `P0` shows; at or above the last, everything shows.\n */\ninterface Breakpoint {\n /** Minimum container inline-size (px) for this tier to be shown. */\n minWidth: number;\n /** The tier this breakpoint reveals. */\n tier: ResponsiveTier;\n}\n\nconst DEFAULT_BREAKPOINTS: readonly Breakpoint[] = [\n { minWidth: 0, tier: 'P0' },\n { minWidth: 640, tier: 'P1' },\n { minWidth: 900, tier: 'P2' },\n { minWidth: 1200, tier: 'P3' },\n];\n\n/** Resolve the set of tiers that should be visible at a given container width. */\nfunction visibleTiersForWidth(\n width: number,\n breakpoints: readonly Breakpoint[],\n): Set<ResponsiveTier> {\n const visible = new Set<ResponsiveTier>();\n for (const bp of breakpoints) {\n if (width >= bp.minWidth) visible.add(bp.tier);\n }\n // P0 is always visible regardless of width.\n visible.add('P0');\n return visible;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Options */\n/* -------------------------------------------------------------------------- */\n\nexport interface UseResponsiveColumnsOptions {\n /**\n * The grid container element to observe. The hook measures THIS element's\n * inline-size (not the viewport) so it works embedded. When the ref is unset\n * the hook is inert.\n */\n containerRef: RefObject<HTMLElement | null>;\n /**\n * Disable responsive toggling entirely (the `responsive={false}` escape hatch\n * on `PatientTable`). When `false` the hook unobserves and makes no visibility\n * changes — column visibility is left entirely to persistence / ColumnToggle.\n * Default `true`.\n */\n enabled?: boolean;\n /**\n * Override the container-width breakpoints. Ordered low→high `minWidth`; each\n * reveals its `tier`. Defaults to 640 / 900 / 1200 (P1 / P2 / P3).\n */\n breakpoints?: readonly Breakpoint[];\n}\n\n/* -------------------------------------------------------------------------- */\n/* Return shape */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Imperative surface returned by {@link useResponsiveColumns}. The responsive\n * effect runs internally; `lockColumns` lets a caller (the view switcher) mark\n * columns as user-touched so the responsive baseline stops auto-managing them.\n */\nexport interface UseResponsiveColumnsResult {\n /**\n * Mark the given colIds as \"user-touched\" so the responsive baseline leaves\n * their visibility alone from here on — exactly as if the user had toggled\n * them via `ColumnToggle`. The view switcher calls this when it applies a\n * view's column visibility, so its programmatic (`source: 'api'`) visibility\n * writes are not immediately re-hidden/re-shown by the next responsive\n * reconcile pass. No-op (with the colIds still recorded for a later mount of\n * the effect) when the hook is disabled.\n */\n lockColumns: (colIds: readonly string[]) => void;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Hook */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Wire responsive, tier-driven column visibility to the patient grid.\n *\n * @param handleRef The `PatientTable` imperative handle ref — the hook reaches\n * the raw AG Grid API via `handleRef.current.getRawApi()`.\n * @param opts Container ref to observe, plus enable flag / breakpoint\n * overrides. See {@link UseResponsiveColumnsOptions}.\n * @returns {@link UseResponsiveColumnsResult} — `lockColumns(colIds)`\n * to mark columns user-touched (see the view-switcher\n * coordination note in patient-table.tsx).\n */\nexport function useResponsiveColumns(\n handleRef: RefObject<PatientTableHandle | null>,\n opts: UseResponsiveColumnsOptions,\n): UseResponsiveColumnsResult {\n const {\n containerRef,\n enabled = true,\n breakpoints = DEFAULT_BREAKPOINTS,\n } = opts;\n\n // colIds the user has explicitly toggled this session — responsive auto-toggle\n // must never override these (their persisted visibility wins). A ref, not\n // state: mutating it must not re-run the effect or re-render. Shared between\n // the responsive effect (which seeds + grows it from `columnVisible` events)\n // and the exported `lockColumns` (which the view switcher uses to register a\n // view-driven visibility change as a user override).\n const userTouchedRef = useRef<Set<string>>(new Set());\n // Re-entrancy guard: true while WE are applying a responsive change, so the\n // resulting `columnVisible` event is not misread as a user toggle even if a\n // future AG Grid version reports a non-`api` source for it.\n const applyingRef = useRef(false);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!enabled || !container) return;\n\n // Resolve the live API lazily on each tick — the grid may not be ready on\n // the first observer callback.\n const getApi = () => handleRef.current?.getRawApi();\n\n /**\n * Record a user-driven visibility change so the column is left alone from\n * here on. `source: 'api'` is the only programmatic source the hook itself\n * uses; everything else (tool panel, column menu, context menu, drag) is the\n * user. The re-entrancy flag covers our own calls defensively.\n */\n const onColumnVisible = (event: ColumnVisibleEvent<PatientRow>) => {\n if (applyingRef.current) return;\n if (event.source === 'api') return;\n const touched = event.columns ?? (event.column ? [event.column] : []);\n for (const col of touched) {\n userTouchedRef.current.add(col.getColId());\n }\n };\n\n // The grid API is frequently not ready on the first effect tick (AG Grid\n // mounts asynchronously). `wired` ensures the one-time seed + listener\n // attach happens the first time we actually have an API, no matter whether\n // that is here on mount or later from a ResizeObserver tick.\n let wired = false;\n\n /**\n * One-time wiring once the API is live: seed the user-touched set from the\n * persisted/current column state, then subscribe to `columnVisible` so later\n * manual toggles are recorded. Seeding treats an already-hidden tiered\n * column that *would* be visible at the current width as a deliberate user\n * hide (restored from localStorage by data-table.tsx) so the baseline does\n * not clobber it. We only positively detect *hidden* overrides — auto-show\n * would otherwise fight a deliberate hide.\n */\n const ensureWired = (api: NonNullable<ReturnType<typeof getApi>>) => {\n if (wired) return;\n wired = true;\n const cols = api.getColumns();\n const width = container.getBoundingClientRect().width;\n const visibleTiers = visibleTiersForWidth(width, breakpoints);\n if (cols) {\n for (const col of cols) {\n const tier = getResponsiveTier(col.getColDef());\n if (tier && !col.isVisible() && visibleTiers.has(tier)) {\n userTouchedRef.current.add(col.getColId());\n }\n }\n }\n api.addEventListener('columnVisible', onColumnVisible);\n };\n\n /** Apply the responsive baseline for the current container width. */\n const reconcile = () => {\n const api = getApi();\n if (!api) return;\n ensureWired(api);\n const columns = api.getColumns();\n if (!columns) return;\n\n const width = container.getBoundingClientRect().width;\n const visibleTiers = visibleTiersForWidth(width, breakpoints);\n\n // Compute the show / hide buckets, skipping user-touched and untiered\n // columns. Batch the calls so AG Grid fires one event per direction.\n const toShow: Column[] = [];\n const toHide: Column[] = [];\n\n for (const col of columns) {\n const colId = col.getColId();\n // The user owns this column's visibility — never auto-manage it.\n if (userTouchedRef.current.has(colId)) continue;\n\n const tier = getResponsiveTier(col.getColDef());\n // No tier ⇒ anchor column (Identity / Actions): always left visible.\n if (!tier) continue;\n\n const shouldShow = visibleTiers.has(tier);\n if (shouldShow && !col.isVisible()) toShow.push(col);\n else if (!shouldShow && col.isVisible()) toHide.push(col);\n }\n\n if (toShow.length === 0 && toHide.length === 0) return;\n\n applyingRef.current = true;\n try {\n // AG Grid tags API-driven changes with `source: 'api'`, so the\n // resulting `columnVisible` events are ignored by `onColumnVisible`\n // (they are the baseline, not user intent). `applyingRef` is the belt\n // to that braces in case a future version reports a different source.\n if (toShow.length > 0) api.setColumnsVisible(toShow, true);\n if (toHide.length > 0) api.setColumnsVisible(toHide, false);\n } finally {\n applyingRef.current = false;\n }\n };\n\n // Observe the GRID CONTAINER (not the viewport) so embedded tables respond\n // to their own box. The first observer tick fires synchronously on observe,\n // and `reconcile` lazily wires + seeds the moment the grid API is live.\n const observer = new ResizeObserver(() => reconcile());\n observer.observe(container);\n reconcile();\n\n return () => {\n observer.disconnect();\n // The API may have torn down already on unmount; guard the removal.\n getApi()?.removeEventListener('columnVisible', onColumnVisible);\n };\n }, [containerRef, enabled, breakpoints, handleRef]);\n\n // Stable across renders — `userTouchedRef` is a ref, so adding to it never\n // re-runs the responsive effect. Recording a colId here makes the next\n // `reconcile` pass skip it (it `continue`s on `userTouchedRef.has(colId)`),\n // which is exactly how a manual ColumnToggle override is honoured. The view\n // switcher calls this for every column it shows/hides so the responsive\n // baseline doesn't immediately fight the applied view.\n const lockColumns = useCallback((colIds: readonly string[]) => {\n for (const id of colIds) userTouchedRef.current.add(id);\n }, []);\n\n return { lockColumns };\n}\n","/**\n * patient-table — Domain-Specific component\n * ----------------------------------------------------------------------------\n * `PatientTable` is a thin composition over the kit's `data-table` engine\n * (AG Grid Community) specialised for the AlfaDocs patient list. It bakes in:\n *\n * • `buildPatientColumns(t, …)` (one field per column — split identity,\n * grouped hidden columns, dynamic custom fields) merged with a\n * consumer-supplied `columns` override.\n * • the kit data-table built-in renderers (Image / Link / Date / Currency /\n * Status / TagList / User) plus the three patient renderers kept for the\n * domain columns (NextAppointment / BalanceBadge / CarePlanStatus).\n * • a default toolbar — `QuickSearch` + `FilterChips` + `ColumnToggle` +\n * `ExportMenu` + a `BulkAction` per `props.bulkActions` — overridable\n * wholesale via `props.toolbar`.\n * • `useResponsiveColumns` (container-width column-priority tiers) when\n * `props.responsive` (default `true`).\n * • multiple row selection, pagination, archived-row tint, loading / empty\n * overlays.\n * • `useAgentRegistration(dataTableAgent, handle, gridId)` — the SAME agent\n * adapter `data-table` registers, keyed by `gridId`.\n *\n * The `forwardRef` exposes the inner `DataTableHandle<PatientRow>` so consumers\n * (e.g. the `patients` pattern's WarningStack \"View\" actions) can drive the\n * grid imperatively — `setFilter`, `setSort`, `getSelection`, etc.\n *\n * CONSTRAINTS (CI-blocking — src/docs/23-constraints.mdx, 26-agent-readiness.mdx):\n * • No hardcoded colour / spacing / radius / shadow / font — token-bound `ds:`\n * utilities only. Row tint goes through the token-bound\n * `data-table-row-archived` class on the AG Grid theme bridge, never an\n * inline `cellStyle`.\n * • CSS logical properties only (`ms/me/ps/pe`, `text-start/text-end`).\n * • All user-visible strings via `useTranslation('ui')` → `ui.patientTable.*`.\n * • TypeScript strict — no `any`. `forwardRef` exposes the curated handle.\n * • PHI rule (PRS 26 §6): only `row.id` reaches DOM `data-*`. This component\n * writes no PHI attribute; AG Grid surfaces ids via its native `row-id`.\n */\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { GetRowIdParams, RowClassParams } from 'ag-grid-community';\nimport {\n actionsColumnWidth,\n DataTable,\n dataTableAgent,\n type DataTableHandle,\n} from '../data-table';\nimport { Select } from '../select';\nimport { useAgentRegistration } from '../../agent';\nimport {\n buildPatientColumns,\n getResponsiveTier,\n PATIENT_ROW_ACTION_COUNT,\n type BuildPatientColumnsOptions,\n} from './columns';\nimport {\n useResponsiveColumns,\n type UseResponsiveColumnsResult,\n} from './use-responsive-columns';\nimport type {\n PatientBulkAction,\n PatientColumnDef,\n PatientCustomFieldDef,\n PatientRow,\n PatientRowAction,\n PatientTableHandle,\n PatientView,\n} from './types';\n\n/* -------------------------------------------------------------------------- */\n/* Props */\n/* -------------------------------------------------------------------------- */\n\nexport interface PatientTableProps {\n /**\n * Row data. `undefined` ⇒ the grid renders its loading overlay (the\n * data-table contract: `rowData === undefined` is the loading sentinel). Pass\n * `[]` for an explicit empty state.\n */\n rowData?: PatientRow[];\n /**\n * Override / extend the baked patient columns. When provided, these column\n * definitions REPLACE the kit defaults entirely (the consumer is expected to\n * compose `buildPatientColumns(t, …)` — re-exported from the barrel — with\n * their own additions). When omitted, the kit's `buildPatientColumns` output\n * is used.\n */\n columns?: PatientColumnDef[];\n /**\n * REQUIRED. Persistence key (column state → `localStorage`) AND the agent\n * instance address (`data-component-id`). Two tables on one page need\n * distinct `gridId`s.\n */\n gridId: string;\n /** Row-height preset. Defaults to the engine default (`'default'`). */\n density?: 'compact' | 'default' | 'expanded';\n /**\n * Collapse the per-row actions column into a single \"…\" overflow trigger\n * independently of row `density`. When `true` the actions cells render the\n * collapsed menu and the column shrinks to its 88px compact footprint; when\n * `false` they render the inline button group at the full expanded width.\n * When `undefined` (the default) compactness FOLLOWS `density` — `compact`\n * density collapses the actions, every other density keeps them inline — so\n * existing consumers are unaffected. Flipping this at runtime re-reads the\n * actions cells via a stable ref-backed getter (no `columnDefs` rebuild, so\n * column state is preserved) and resizes the actions column to match.\n */\n actionsCompact?: boolean;\n /**\n * Grid height — forwarded to the underlying `DataTable.heightClass` (a Tailwind\n * height class). Pass `\"ds:h-full\"` to fill a sized parent, or an explicit\n * value like `\"ds:h-[75vh]\"`. Omit to use the engine default (`ds:h-[500px]`).\n */\n heightClass?: string;\n /**\n * Enable container-width column-priority responsiveness (lower-priority\n * columns hide as the grid narrows). Default `true`. Set `false` to leave\n * column visibility entirely to persistence / `ColumnToggle`.\n */\n responsive?: boolean;\n /**\n * Saved column/filter/sort presets. When non-empty AND no custom `toolbar`\n * is supplied, the default toolbar renders a `Select`-based view switcher in\n * the FilterBar; choosing a view applies its column visibility (via the\n * responsive-hook lock so the choice is honoured like a manual ColumnToggle),\n * `filterModel` (`setFilter`) and `sortModel` (`setSort`). Omitted entirely\n * when empty / undefined or when `toolbar` is supplied (a custom toolbar owns\n * its own view UI).\n */\n views?: PatientView[];\n /**\n * Invoked when a per-row action button is activated, with the resolved action\n * descriptor and the patient row. Only `row.id` ever leaves this boundary into\n * persistence / agent surfaces — never PHI.\n */\n onRowAction?: (action: PatientRowAction, patient: PatientRow) => void;\n /**\n * Toolbar bulk actions (operate on the current selection). Each renders a\n * `DataTable.Toolbar.BulkAction` that surfaces only while rows are selected;\n * its `onSelect` receives the selected row ids (never PHI).\n */\n bulkActions?: PatientBulkAction[];\n /**\n * Force the loading overlay independently of `rowData`. When `true` the grid\n * shows the loading skeleton even if `rowData` is an array (e.g. a background\n * refresh). `rowData === undefined` also triggers loading.\n */\n loading?: boolean;\n /**\n * Replace the default toolbar wholesale. Pass a `<DataTable.Toolbar>…</…>`\n * tree (it has access to the same toolbar context). When omitted the default\n * QuickSearch + FilterChips + ColumnToggle + ExportMenu + BulkActions toolbar\n * is rendered.\n */\n toolbar?: ReactNode;\n /**\n * Omit the `QuickSearch` field from the DEFAULT toolbar. The rest of the\n * default toolbar (view switcher when `views` is supplied, FilterChips,\n * ColumnToggle, ExportMenu, BulkActions) is unaffected. Ignored when a custom\n * `toolbar` is supplied (that toolbar owns its own composition). Default\n * `false` (search shown). Use for surfaces that provide their own search\n * affordance elsewhere on the page.\n */\n hideQuickSearch?: boolean;\n /**\n * Enable the grid's client-side pagination. When `false`, every row loads into\n * a single virtualised, scrollable view and filter / sort act over the WHOLE\n * set (no pager) — the right model for a \"load and filter all\" list. Default\n * `true`.\n */\n pagination?: boolean;\n /**\n * Page-size dropdown options shown in the pagination panel — forwarded to the\n * underlying `DataTable.paginationPageSizeSelector`. Pass `false` to hide the\n * page-size chooser entirely (pagination navigation is unaffected). Default\n * `[10, 25, 50, 100]` (the engine default).\n */\n paginationPageSizeSelector?: number[] | false;\n /**\n * Mask sensitive contact details (email) in the Contact / Email columns.\n * Forwarded to `buildPatientColumns`' `hideDetails`. Ignored when `columns`\n * is supplied (the consumer owns their columns then). Default `false`.\n */\n hideDetails?: boolean;\n /**\n * Derive the patient-detail href for the Identity cell, e.g.\n * `(row) => \\`/patients/${row.id}\\``. Forwarded to `buildPatientColumns`.\n * Ignored when `columns` is supplied. When omitted the Identity cell routes\n * its click through `onRowAction` with the `show` action.\n */\n identityHref?: BuildPatientColumnsOptions['identityHref'];\n /**\n * Per-practice custom-field descriptors. Each appends one dynamic `custom:*`\n * column (hidden by default, toggleable via ColumnToggle) after the standard\n * columns. Forwarded to `buildPatientColumns`. Ignored when `columns` is\n * supplied (the consumer owns their columns then).\n */\n customFields?: PatientCustomFieldDef[];\n /** Override the default region aria-label (`ui.patientTable.regionLabel`). */\n 'aria-label'?: string;\n /** Extra class names merged onto the inner grid wrapper. */\n className?: string;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Row class — archived tint */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Token-bound archived-row tint. The class is defined on the AG Grid theme\n * bridge (`src/tokens/ag-grid-theme.css` → `.data-table-row-archived`) so the\n * recessive muted fill stays under token control — no colour ever enters a\n * `cellStyle` / `cellClass` literal here.\n */\nfunction getPatientRowClass(\n params: RowClassParams<PatientRow>,\n): string | undefined {\n return params.data?.isArchived ? 'data-table-row-archived' : undefined;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Row id — key selection / bulk actions on the real patient id */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Use the stable `PatientRow.id` as AG Grid's node id. Without this AG Grid\n * keys nodes by row index, so `getSelectedNodes().map(n => n.id)`,\n * `setSelection(ids)`, the bulk-action bridge and the agent adapter would all\n * receive index strings (`\"0\"`, `\"1\"`) instead of patient ids. Forwarded to the\n * engine via `gridOptions.getRowId` (the path `data-table.tsx` spreads through\n * untouched). `id` is the ONLY field permitted on a DOM hook (PHI rule).\n */\nfunction getPatientRowId(params: GetRowIdParams<PatientRow>): string {\n return params.data.id;\n}\n\n/* -------------------------------------------------------------------------- */\n/* View switcher — default-toolbar control for the `views` prop */\n/* -------------------------------------------------------------------------- */\n\ninterface ViewSwitcherProps {\n /** Saved views to choose from (already known non-empty by the caller). */\n views: PatientView[];\n /** The live patient-table handle ref (filter / sort / raw API access). */\n handleRef: RefObject<PatientTableHandle | null>;\n /**\n * Mark a view's visibility writes as user-touched so `useResponsiveColumns`\n * stops auto-managing them — see the coordination note at the call site.\n */\n lockColumns: UseResponsiveColumnsResult['lockColumns'];\n /** Accessible label for the control (`ui.patientTable.views.label`). */\n label: string;\n}\n\n/**\n * A minimal, accessible saved-view switcher rendered in the DEFAULT toolbar's\n * FilterBar. Uses the kit `Select` (convenience `options` form) — a small,\n * labelled single-choice control that fits the toolbar's compact density and\n * carries Radix's listbox a11y for free.\n *\n * On selection it applies the chosen {@link PatientView} through the patient\n * handle + raw AG Grid API:\n * • column visibility — show the view's listed toggleable columns, hide the\n * rest of the toggleable (tiered) ones. Untiered columns (the pinned\n * Identity / Actions anchors) are NEVER hidden.\n * • `filterModel` via `handle.setFilter`.\n * • `sortModel` via `handle.setSort`.\n *\n * RESPONSIVE COORDINATION (critical): a view-applied visibility change must not\n * be immediately re-hidden/re-shown by `useResponsiveColumns`. We route every\n * colId we touch through `lockColumns(colIds)`, which adds them to the same\n * `userTouchedRef` set the hook grows from non-`api` `columnVisible` events —\n * so from then on the responsive baseline treats them as a user override and\n * leaves them alone, exactly as a manual ColumnToggle would.\n */\nfunction ViewSwitcher({\n views,\n handleRef,\n lockColumns,\n label,\n}: ViewSwitcherProps) {\n const [activeViewId, setActiveViewId] = useState<string>('');\n\n const options = useMemo(\n () => views.map((view) => ({ value: view.id, label: view.label })),\n [views],\n );\n\n const applyView = useCallback(\n (viewId: string) => {\n const view = views.find((v) => v.id === viewId);\n const handle = handleRef.current;\n if (!view || !handle) return;\n\n const api = handle.getRawApi();\n if (api) {\n const wanted = new Set<string>(view.columns);\n const toShow: string[] = [];\n const toHide: string[] = [];\n for (const col of api.getColumns() ?? []) {\n // Only the tiered (auto-hideable) field columns participate; the\n // pinned Identity / Actions anchors carry no tier and are never\n // hidden by a view.\n if (getResponsiveTier(col.getColDef()) === undefined) continue;\n const colId = col.getColId();\n if (wanted.has(colId)) toShow.push(colId);\n else toHide.push(colId);\n }\n // Lock BEFORE the visibility write so a synchronous responsive\n // reconcile (e.g. a ResizeObserver tick triggered by the layout shift)\n // already sees these colIds as user-touched.\n lockColumns([...toShow, ...toHide]);\n if (toShow.length > 0) api.setColumnsVisible(toShow, true);\n if (toHide.length > 0) api.setColumnsVisible(toHide, false);\n }\n\n handle.setFilter(view.filterModel);\n handle.setSort(view.sortModel);\n api?.onFilterChanged();\n },\n [views, handleRef, lockColumns],\n );\n\n const handleValueChange = useCallback(\n (next: string) => {\n setActiveViewId(next);\n if (next) applyView(next);\n },\n [applyView],\n );\n\n return (\n // Width-constraining wrapper (same pattern as the toolbar's QuickSearch) so\n // the Select's intrinsic `w-full` trigger sizes to a compact, legible width\n // instead of absorbing the whole FilterBar row.\n <div className=\"ds:w-[12rem] ds:max-w-full ds:min-w-0 ds:shrink-0\">\n <Select\n options={options}\n value={activeViewId}\n onValueChange={handleValueChange}\n size=\"sm\"\n aria-label={label}\n />\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* PatientTable */\n/* -------------------------------------------------------------------------- */\n\nexport const PatientTable = forwardRef<PatientTableHandle, PatientTableProps>(\n function PatientTable(\n {\n rowData,\n columns,\n gridId,\n density,\n actionsCompact,\n heightClass,\n responsive = true,\n views,\n onRowAction,\n bulkActions,\n loading = false,\n toolbar,\n hideQuickSearch = false,\n pagination = true,\n paginationPageSizeSelector,\n hideDetails = false,\n identityHref,\n customFields,\n 'aria-label': ariaLabel,\n className,\n },\n ref,\n ) {\n const { t } = useTranslation('ui');\n\n // Internal handle ref forwarded BOTH to the consumer's ref (below) and to\n // `useResponsiveColumns`, which reaches the live AG Grid API via\n // `handle.getRawApi()`.\n const handleRef = useRef<PatientTableHandle | null>(null);\n\n // Container the responsive hook observes (its inline-size drives the\n // column-priority tiers). Observing the grid's own box — not the viewport —\n // is what makes the table responsive when embedded in a narrow panel.\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // Mirror the handle into state once the inner DataTable mounts so the\n // agent-registration effect (which keys off `handle` reactively) fires with\n // a live handle. A bare ref mutation would not re-run the effect.\n const [registrableHandle, setRegistrableHandle] =\n useState<PatientTableHandle | null>(null);\n\n // Expose the inner DataTable handle to the consumer ref. Re-runs when the\n // mirrored handle becomes available so a consumer reading the ref in an\n // effect sees the live handle, not the initial `null`.\n useImperativeHandle(\n ref,\n () => (registrableHandle ?? handleRef.current) as PatientTableHandle,\n [registrableHandle],\n );\n\n // Responsive column-priority tiers, driven by the grid container's width.\n // Inert when `responsive` is false (the hook unobserves and makes no calls).\n // The container ref is widened to the hook's `HTMLElement` param at the call\n // site (RefObject is invariant on its element type) — same cast pattern as\n // `useDirection` in tooltip.tsx. `lockColumns` lets the ViewSwitcher mark a\n // view's visibility writes as user-touched (see ViewSwitcher's coordination\n // note) — called before the hook value is consumed in the default toolbar.\n const { lockColumns } = useResponsiveColumns(handleRef, {\n containerRef: containerRef as RefObject<HTMLElement | null>,\n enabled: responsive,\n });\n\n // Actions-column compactness. Explicit `actionsCompact` wins; otherwise it\n // follows `density` (`compact` collapses, every other density stays inline)\n // — the legacy coupling, preserved as the default so existing consumers are\n // unaffected.\n const compact = actionsCompact ?? density === 'compact';\n\n // Ref-backed live getter for the compactness flag. The actions cell renderer\n // calls this every render, so flipping `compact` need only update the ref +\n // refresh the cells — it never rebuilds `columnDefs` (which would discard the\n // user's column state). The getter identity is stable, so it is NOT a\n // `columnDefs` dependency.\n const actionsCompactRef = useRef(compact);\n const getActionsCompact = useCallback(() => actionsCompactRef.current, []);\n\n // On a `compact` change — OR once the grid handle first becomes live — sync\n // the ref the renderer reads, then drive the LIVE grid: set the actions\n // column to its collapsed (88px) or expanded (derived from the row-action\n // count) width and force the actions cells to re-read the getter. Depending\n // on `registrableHandle` makes the initial compact state apply as soon as the\n // DataTable mirrors its handle in (the api is null on first paint), so a\n // page mounting already-compact lands at 88px without a column-defs rebuild.\n useEffect(() => {\n actionsCompactRef.current = compact;\n const api = handleRef.current?.getRawApi();\n if (!api) return;\n api.setColumnWidths([\n {\n key: 'actions',\n newWidth: compact ? 88 : actionsColumnWidth(PATIENT_ROW_ACTION_COUNT),\n },\n ]);\n api.refreshCells({ force: true });\n }, [compact, registrableHandle]);\n\n // Columns: consumer override wins wholesale; otherwise the baked patient\n // columns. Memoised on the inputs the builder reads — `density` is NO LONGER\n // among them: the actions column reads its compactness through the stable\n // `getActionsCompact` getter, so a density (or `actionsCompact`) flip resizes\n // + refreshes the live grid without rebuilding the defs (preserving column\n // state). `density` still drives row height via the DataTable prop below.\n const columnDefs = useMemo<PatientColumnDef[]>(\n () =>\n columns ??\n buildPatientColumns(t, {\n hideDetails,\n onRowAction,\n identityHref,\n customFields,\n getActionsCompact,\n }),\n [\n columns,\n t,\n hideDetails,\n onRowAction,\n identityHref,\n customFields,\n getActionsCompact,\n ],\n );\n\n // Default toolbar — an optional ViewSwitcher + QuickSearch + FilterChips\n // (FilterBar slot) and ColumnToggle + ExportMenu + one BulkAction per\n // `bulkActions` (Actions slot). Overridable wholesale via `props.toolbar`;\n // when a custom `toolbar` is supplied the ViewSwitcher is NOT injected — a\n // custom toolbar owns its own view UI. The switcher is also omitted when\n // `views` is empty / undefined. All toolbar parts translate their own labels\n // through the `dataTable.*` namespace; the BulkAction labels come from the\n // consumer-supplied descriptors.\n const hasViews = (views?.length ?? 0) > 0;\n const defaultToolbar = (\n <DataTable.Toolbar>\n <DataTable.Toolbar.FilterBar>\n {hasViews && views ? (\n <ViewSwitcher\n views={views}\n handleRef={handleRef}\n lockColumns={lockColumns}\n label={t('patientTable.views.label')}\n />\n ) : null}\n {hideQuickSearch ? null : <DataTable.Toolbar.QuickSearch />}\n <DataTable.Toolbar.FilterChips />\n </DataTable.Toolbar.FilterBar>\n <DataTable.Toolbar.Actions>\n {bulkActions?.map((action) => (\n <DataTable.Toolbar.BulkAction\n key={action.id}\n label={action.label}\n icon={action.icon}\n variant={action.variant}\n onClick={(api) => {\n // Resolve the selection via the live grid API → row ids only\n // (never PHI). Falls back to an empty list if the API is unset.\n const ids =\n api\n ?.getSelectedNodes()\n .map((node) => node.id)\n .filter((id): id is string => id != null) ?? [];\n action.onSelect(ids);\n }}\n />\n ))}\n <DataTable.Toolbar.ColumnToggle />\n <DataTable.Toolbar.ExportMenu />\n </DataTable.Toolbar.Actions>\n </DataTable.Toolbar>\n );\n\n const toolbarContent = toolbar ?? defaultToolbar;\n\n // `rowData === undefined` is the data-table loading sentinel; `loading`\n // forces it independently (e.g. a background refresh over existing rows).\n const effectiveRowData = loading ? undefined : rowData;\n\n // Stable `gridOptions` forwarding `getRowId` so AG Grid keys nodes by the\n // real `PatientRow.id` (see getPatientRowId) — selection, bulk actions and\n // the agent adapter all then return patient ids, not row-index strings.\n const gridOptions = useMemo(() => ({ getRowId: getPatientRowId }), []);\n\n // Register the data-table agent adapter keyed by `gridId` — the same\n // adapter `data-table` registers internally. Idempotent overwrite with the\n // identical handle under the same `(adapterId, gridId)` key; both share the\n // unmount lifecycle so the dedup is harmless and the registration stays\n // addressable as `patient-table`'s `gridId` for the duration.\n useAgentRegistration(\n dataTableAgent,\n registrableHandle as DataTableHandle | null,\n gridId,\n );\n\n return (\n <div\n ref={containerRef}\n role=\"region\"\n aria-label={ariaLabel ?? t('patientTable.regionLabel')}\n data-component=\"patient-table\"\n data-component-id={gridId}\n className=\"ds:flex ds:w-full ds:min-h-0 ds:flex-1 ds:flex-col\"\n >\n <DataTable<PatientRow>\n ref={(instance) => {\n handleRef.current = instance;\n // Mirror into state once (or when the instance identity changes) so\n // the registration effect picks up the live handle.\n setRegistrableHandle((prev) =>\n prev === instance ? prev : instance,\n );\n }}\n gridId={gridId}\n columnDefs={columnDefs}\n rowData={effectiveRowData}\n rowSelection=\"multiple\"\n pagination={pagination}\n {...(heightClass !== undefined ? { heightClass } : {})}\n {...(paginationPageSizeSelector !== undefined\n ? { paginationPageSizeSelector }\n : {})}\n density={density}\n getRowClass={getPatientRowClass}\n gridOptions={gridOptions}\n className={className}\n >\n {toolbarContent}\n </DataTable>\n </div>\n );\n },\n);\n\nPatientTable.displayName = 'PatientTable';\n"],"names":["__iconNode","MessageSquare","createLucideIcon","SMALL_BALANCE_CENTS_MAX","classifyBalance","cents","readUnpaidCents","value","n","BalanceBadgeCell","props","currency","options","t","i18n","useTranslation","locale","formatted","variant","statusKey","status","jsxs","Badge","jsx","CARE_PLAN_VARIANT_MAP","isCarePlanStatus","CarePlanStatusCell","data","size","raw","nextAppointmentVariants","cva","DAY_MS","DEFAULT_SOON_WITHIN_DAYS","toTime","resolveTone","time","soonWithinDays","deltaMs","NextAppointmentCell","tone","CalendarClock","Timestamp","getResponsiveTier","colDef","PATIENT_ROW_ACTION_COUNT","buildRowActions","onRowAction","dispatch","action","patient","make","overrides","createElement","Eye","Pencil","Mail","p","Users","Trash2","NO","CHECK","DASH","ageFromDob","dob","birth","ms","now","age","m","buildCustomFieldColumns","fields","field","base","params","_b","_a","SelectFilter","SelectFloatingFilter","TagListCellRenderer","opt","TextFilter","TextFloatingFilter","buildPatientColumns","opts","hideDetails","getActionsCompact","identityHref","customFields","actions","genderLabels","consentLabels","consentVariantMap","header","id","ImageCellRenderer","LinkCellRenderer","row","_c","DateRangeFilter","DateRangeFloatingFilter","NumberFilter","NumberFloatingFilter","s","DateCellRenderer","CurrencyCellRenderer","UserCellRenderer","a","b","TypeaheadFilter","TypeaheadFloatingFilter","StatusCellRenderer","year","num","ActionsCellRenderer","actionsColumnWidth","DEFAULT_BREAKPOINTS","visibleTiersForWidth","width","breakpoints","visible","bp","useResponsiveColumns","handleRef","containerRef","enabled","userTouchedRef","useRef","applyingRef","useEffect","container","getApi","onColumnVisible","event","touched","col","wired","ensureWired","api","cols","visibleTiers","tier","reconcile","columns","toShow","toHide","colId","shouldShow","observer","useCallback","colIds","getPatientRowClass","getPatientRowId","ViewSwitcher","views","lockColumns","label","activeViewId","setActiveViewId","useState","useMemo","view","applyView","viewId","v","handle","wanted","handleValueChange","next","Select","PatientTable","forwardRef","rowData","gridId","density","actionsCompact","heightClass","responsive","bulkActions","loading","toolbar","hideQuickSearch","pagination","paginationPageSizeSelector","ariaLabel","className","ref","registrableHandle","setRegistrableHandle","useImperativeHandle","compact","actionsCompactRef","columnDefs","hasViews","defaultToolbar","DataTable","ids","node","toolbarContent","effectiveRowData","gridOptions","useAgentRegistration","dataTableAgent","instance","prev"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"public-header.agent-C-opZaOw.js","sources":["../../src/components/public-header/public-header.tsx","../../src/components/public-header/public-header.agent.ts"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* PublicHeader — anonymous / pre-auth site header. */\n/* */\n/* Distinct from the kit's `<Header>` (authenticated app shell): this */\n/* one is for booking-website, signature-website, marketing surfaces — */\n/* anywhere the chrome should read as continuous with `alfadocs.com`, */\n/* not as the logged-in app. */\n/* */\n/* DOM (default / transparent / dark / brand variants): */\n/* <header role=banner data-component=public-header data-stuck=…> */\n/* <a aria-label=homeLabel>{logo}</a> */\n/* <Radix.NavigationMenu>…{navSlot}</Radix.NavigationMenu> ≥ md */\n/* <div class=actions>{actionsSlot}</div> ≥ md only */\n/* <IconButton menu trigger /> ↔ Sheet (partial drawer) < md only */\n/* </header> */\n/* */\n/* DOM (pill variant — matches alfadocs.com floating-pill header): */\n/* <header role=banner data-component=public-header> transparent */\n/* <div data-component=public-header-container> rounded */\n/* …same children as flat variants… */\n/* </div> */\n/* </header> */\n/* ------------------------------------------------------------------ */\n\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useImperativeHandle,\n useRef,\n useState,\n type AnchorHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronDown, Menu, X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';\nimport { IconButton } from '../button/icon-button';\nimport { Sheet } from '../sheet';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface PublicHeaderHandle {\n openMenu: () => void;\n closeMenu: () => void;\n getMenuOpen: () => boolean;\n}\n\nexport interface PublicHeaderProps\n extends\n Omit<ComponentPropsWithoutRef<'header'>, 'children'>,\n VariantProps<typeof rootVariants> {\n /** Logo lockup, typically `<Logo variant=\"wordmark\" tone=\"primary\" size=\"md\" />`. */\n logo: ReactNode;\n /** Optional href for the logo link. Defaults to `/`. */\n homeHref?: string;\n /** Accessible label for the logo link (falls back to `t('publicHeader.homeLabel')`). */\n homeLabel?: string;\n /** Primary nav links rendered inline ≥ md, collapsed into the mobile sheet below md. */\n navSlot?: ReactNode;\n /** Right-side actions (sign-in / register / role-switch CTAs). */\n actionsSlot?: ReactNode;\n /** Sticky behaviour. Default `none`. */\n sticky?: 'none' | 'top' | 'scroll-up';\n /** Pixel offset above which `sticky=\"scroll-up\"` engages and `transparent` fades to default. */\n stickyOffset?: number;\n /** Override the mobile menu trigger's accessible label (`t('publicHeader.openMenu')`). */\n menuLabel?: string;\n /** Override the navigation landmark label (`t('publicHeader.primaryNavLabel')`). */\n navLabel?: string;\n /**\n * Keep `actionsSlot` visible inline at every breakpoint instead of\n * collapsing it into the mobile menu. When there is no `navSlot`, the\n * mobile menu trigger is omitted entirely (nothing left to collapse) — use\n * this for a header whose only action is a single always-relevant control,\n * e.g. a public signer's \"Sign out\". Default `false`.\n */\n persistActions?: boolean;\n /** Consumer-supplied instance id, surfaced as `data-component-id`. */\n id?: string;\n}\n\nexport interface PublicHeaderNavLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n href: string;\n active?: boolean;\n children: ReactNode;\n}\n\nexport interface PublicHeaderNavDropdownProps {\n /** Trigger label (the visible nav item text). */\n label: ReactNode;\n /**\n * `false` (default) renders a single-card dropdown anchored near the trigger\n * (Settori-style). `true` renders a wide multi-card mega-menu spanning the\n * pill's full inline width (Soluzioni-style).\n */\n wide?: boolean;\n /** Cards / content inside the dropdown panel. */\n children: ReactNode;\n /** Optional id; not required — used only for analytics / test selectors. */\n id?: string;\n}\n\nexport interface PublicHeaderDropdownCardProps {\n /**\n * Optional href — when provided the card title becomes a clickable\n * anchor with a `→` arrow indicator. Without href, the title is\n * a static heading (Settori-style).\n */\n href?: string;\n title: ReactNode;\n /** Optional subtitle / muted helper text under the title. */\n subtitle?: ReactNode;\n /** Sub-list contents (typically PublicHeader.DropdownLink children). */\n children?: ReactNode;\n}\n\nexport interface PublicHeaderDropdownLinkProps extends Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n 'children'\n> {\n href: string;\n active?: boolean;\n children: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Context — drives the rendering surface for nav subcomponents. */\n/* */\n/* The same navSlot is rendered twice: once inside the desktop Radix */\n/* NavigationMenu (≥ md, flyout mode) and once inside the mobile Sheet */\n/* drawer (< md, disclosure mode). NavLink / NavDropdown / DropdownCard */\n/* / DropdownLink switch their rendering off this flag so the mobile */\n/* tree doesn't depend on the Radix Root being present. */\n/* ------------------------------------------------------------------ */\n\ntype PublicHeaderSurface = 'desktop' | 'mobile';\n\nconst PublicHeaderSurfaceContext =\n createContext<PublicHeaderSurface>('desktop');\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst rootVariants = cva(\n [\n 'ds:w-full ds:z-[var(--z-sticky)]',\n 'ds:transition-[background-color,box-shadow,transform] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n variant: {\n // Transparent fades to a solid pill chrome once data-stuck=\"true\"\n // (set by the rAF scroll listener). The fade is handled via the\n // same background utility so `data-stuck` swaps cleanly between\n // states.\n transparent: [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)]',\n 'ds:h-14 ds:md:h-16',\n 'ds:bg-transparent ds:text-[var(--foreground)]',\n 'ds:data-[stuck=true]:bg-[var(--card)]',\n 'ds:data-[stuck=true]:shadow-[var(--shadow-md)]',\n // Once stuck, pair the elevation shadow with a tokenized\n // block-end border so the header has a clear edge against the\n // page below it — shadow alone fades to a faint halo on dark\n // surfaces, leaving the bar reading as unbounded.\n 'ds:data-[stuck=true]:border-block-end ds:data-[stuck=true]:border-[color:var(--border)]',\n 'ds:forced-colors:border-b ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n // `dark` flips its own scope into the dark token set so nav\n // links + buttons inside read off-white text on the dark\n // surface. Without the `theme-dark` scope the children inherit\n // the light-theme `--foreground` and fail color-contrast at\n // ~1.3:1. `--background` already resolves to a dark step under\n // `theme-dark`, so we compose the surface from the standard\n // theme token rather than locking to a raw ramp step.\n dark: [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)]',\n 'ds:h-14 ds:md:h-16',\n 'theme-dark ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n ].join(' '),\n // brand: on-primary bar for public signer/marketing surfaces —\n // e.g. sign.alfadocs.com signing nav. Tokens only; logo should be\n // <Logo variant=\"monochrome\" tone=\"inherit\" /> to read on the\n // primary fill.\n brand: [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)]',\n 'ds:h-14 ds:md:h-16',\n 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]',\n ].join(' '),\n // `pill` matches alfadocs.com's floating rounded-pill header.\n // The outer header is fully transparent (no border, no bg) and\n // simply provides a top-side gutter so the inner container reads\n // as floating. The inner `data-component=\"public-header-container\"`\n // div is the visible chrome — border, rounded, card background.\n pill: [\n 'ds:bg-transparent',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pt-[var(--spacing-md)]',\n 'ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)] ds:sm:pt-[var(--spacing-md)]',\n ].join(' '),\n },\n sticky: {\n none: '',\n top: 'ds:sticky ds:top-0',\n // `scroll-up` is sticky but translates off-screen when scrolling\n // down past `stickyOffset` (handled by data-hidden=\"true\") and\n // slides back in when scrolling up.\n 'scroll-up': [\n 'ds:sticky ds:top-0',\n 'ds:data-[hidden=true]:-translate-y-full',\n ].join(' '),\n },\n },\n defaultVariants: { variant: 'pill', sticky: 'none' },\n },\n);\n\n// Inner pill chrome — only rendered when variant === 'pill'. The actual\n// \"header look\" (rounded, border, card surface) lives here so the outer\n// <header> can stay transparent and provide just the floating offset.\nconst pillContainerClasses = [\n 'ds:flex ds:items-center ds:gap-[var(--spacing-md)]',\n 'ds:w-full ds:max-w-[1400px] ds:mx-auto',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:sm:ps-[var(--spacing-lg)] ds:sm:pe-[var(--spacing-lg)]',\n // 76px isn't a kit token; the closest is h-16 (64px) which reads tight\n // against alfadocs.com's chrome — keep an explicit min-block-size so\n // the pill reads as substantial without bloating beyond live reference.\n 'ds:min-h-16 ds:md:min-h-[76px]',\n 'ds:bg-[var(--card)] ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-lg)]',\n // Surface-border hairline shared with `Card`. Tuned to ~14% black\n // (light) / 16% white (dark) at the token level so the edge stays\n // visible against tinted page backgrounds — see `--card-border` in\n // `src/tokens/index.css`. Matches alfadocs.com's slate-200 reference\n // pill border without introducing a pill-specific token.\n 'ds:border ds:border-[color:var(--card-border)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n].join(' ');\n\nconst navLinkVariants = cva(\n [\n 'ds:inline-flex ds:items-center',\n 'type-body-sm ds:font-medium',\n // Muted-foreground reads as secondary text and matches alfadocs.com's\n // nav-link colour (the reference's slate-grey). `--foreground` was too\n // dark vs the ref.\n 'ds:text-[var(--muted-foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:py-[var(--spacing-xs)]',\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:hover:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:data-[active=true]:text-[var(--primary)]',\n 'ds:data-[active=true]:[box-shadow:inset_0_-2px_0_var(--primary)]',\n ].join(' '),\n);\n\n// Trigger styling shares the link look + adds the chevron rotation hook.\nconst dropdownTriggerClasses = [\n 'ds:group ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]',\n 'type-body-sm ds:font-medium',\n // Mirror the navLinkVariants colour + inline padding so triggers and\n // plain links share weight, colour and target size.\n 'ds:text-[var(--muted-foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:bg-transparent ds:border-0 ds:cursor-pointer',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:py-[var(--spacing-xs)]',\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:hover:text-[var(--primary)]',\n 'ds:data-[state=open]:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\nconst dropdownChevronClasses = [\n 'ds:size-3 ds:shrink-0',\n 'ds:transition-transform ds:duration-[var(--animation-duration)]',\n 'ds:group-data-[state=open]:rotate-180',\n 'ds:motion-reduce:transition-none',\n].join(' ');\n\nconst dropdownContentVariants = cva(\n [\n // Radix portals Content into the Viewport; sizing + position is\n // governed by the Viewport — keep Content's own paint to padding\n // + inner layout so motion / position stay consistent across\n // trigger placements.\n 'ds:data-[motion=from-start]:animate-in ds:data-[motion=from-start]:fade-in-0',\n 'ds:data-[motion=from-end]:animate-in ds:data-[motion=from-end]:fade-in-0',\n 'ds:data-[motion=to-start]:animate-out ds:data-[motion=to-start]:fade-out-0',\n 'ds:data-[motion=to-end]:animate-out ds:data-[motion=to-end]:fade-out-0',\n 'ds:motion-reduce:animate-none',\n ].join(' '),\n {\n variants: {\n wide: {\n true: [\n 'ds:grid ds:grid-cols-2 ds:lg:grid-cols-4',\n 'ds:gap-[var(--spacing-lg)]',\n 'ds:p-[var(--spacing-lg)]',\n 'ds:w-screen ds:max-w-[1400px]',\n ].join(' '),\n false: ['ds:p-[var(--spacing-md)]', 'ds:min-w-[280px]'].join(' '),\n },\n },\n defaultVariants: { wide: false },\n },\n);\n\nconst viewportClasses = [\n // Position the Viewport flush below the pill / nav row. Radix sets\n // `--radix-navigation-menu-viewport-width` and `…-height` so the\n // panel sizes itself to whichever Content is currently active.\n 'ds:absolute ds:top-full ds:start-1/2 ds:-translate-x-1/2',\n 'ds:mt-[var(--spacing-sm)]',\n 'ds:w-[var(--radix-navigation-menu-viewport-width)]',\n 'ds:h-[var(--radix-navigation-menu-viewport-height)]',\n 'ds:overflow-hidden',\n 'ds:bg-[var(--card)] ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-lg)] ds:border ds:border-[color:var(--border)]',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=open]:fade-in-0 ds:data-[state=closed]:fade-out-0',\n 'ds:data-[state=open]:zoom-in-95 ds:data-[state=closed]:zoom-out-95',\n 'ds:origin-top ds:transition-[width,height] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:animate-none ds:motion-reduce:transition-none',\n].join(' ');\n\nconst cardLinkClasses = [\n 'ds:flex ds:items-start ds:justify-between ds:gap-[var(--spacing-sm)]',\n 'ds:no-underline ds:text-[var(--foreground)]',\n 'ds:pb-[var(--spacing-sm)]',\n // alfadocs.com renders the card header flush against the sub-list with\n // no separator rule — match that by dropping the border-b that earlier\n // versions of this component carried.\n 'ds:rounded-[var(--radius-sm)]',\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:hover:[&_[data-card-title]]:text-[var(--primary)]',\n 'ds:hover:[&_[data-card-arrow]]:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:group/cardlink',\n].join(' ');\n\nconst cardHeaderStaticClasses = [\n 'ds:pb-[var(--spacing-sm)]',\n // Match the linked-card variant: no separator rule under the title.\n].join(' ');\n\nconst subLinkClasses = [\n 'ds:block ds:no-underline',\n 'type-body-sm ds:font-medium ds:text-[var(--muted-foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:hover:bg-[var(--muted)]/30 ds:hover:text-[var(--primary)]',\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:data-[active=true]:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\n/* ------------------------------------------------------------------ */\n/* Reduced motion */\n/* ------------------------------------------------------------------ */\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return false;\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n });\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return;\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)');\n const onChange = (): void => setReduced(mq.matches);\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n return reduced;\n}\n\n/* ------------------------------------------------------------------ */\n/* Scroll listener */\n/* */\n/* rAF-throttled tracker for two flags on the header root: */\n/* - `data-stuck`: scrollY > stickyOffset (drives the transparent → */\n/* solid fade + the scroll-up shadow lift). */\n/* - `data-hidden`: scrolling DOWN past stickyOffset hides the header */\n/* via transform; scrolling UP slides it back. Only emitted when */\n/* `sticky === 'scroll-up'`. */\n/* ------------------------------------------------------------------ */\n\nfunction useHeaderScrollState(\n enabled: boolean,\n sticky: NonNullable<PublicHeaderProps['sticky']>,\n stickyOffset: number,\n): {\n stuck: boolean;\n hidden: boolean;\n} {\n const [stuck, setStuck] = useState(false);\n const [hidden, setHidden] = useState(false);\n const lastYRef = useRef(0);\n const tickingRef = useRef(false);\n\n useEffect(() => {\n if (!enabled || typeof window === 'undefined') return;\n lastYRef.current = window.scrollY;\n\n const update = (): void => {\n const y = window.scrollY;\n setStuck(y > stickyOffset);\n if (sticky === 'scroll-up') {\n const delta = y - lastYRef.current;\n // Hide on a meaningful downward delta past the offset; show on\n // any upward delta. 4px deadband keeps minor wheel inertia from\n // flapping the bar.\n if (delta > 4 && y > stickyOffset) setHidden(true);\n else if (delta < -4 || y <= stickyOffset) setHidden(false);\n }\n lastYRef.current = y;\n tickingRef.current = false;\n };\n const onScroll = (): void => {\n if (tickingRef.current) return;\n tickingRef.current = true;\n window.requestAnimationFrame(update);\n };\n window.addEventListener('scroll', onScroll, { passive: true });\n // Initial sync so we don't miss state when mounted past the offset.\n update();\n return () => {\n window.removeEventListener('scroll', onScroll);\n };\n }, [enabled, sticky, stickyOffset]);\n\n return { stuck, hidden };\n}\n\n/* ------------------------------------------------------------------ */\n/* Inner content (shared between flat + pill variants) */\n/* ------------------------------------------------------------------ */\n\ninterface InnerContentProps {\n logo: ReactNode;\n homeHref: string;\n resolvedHomeLabel: string;\n resolvedNavLabel: string;\n resolvedMenuLabel: string;\n navSlot?: ReactNode;\n actionsSlot?: ReactNode;\n persistActions: boolean;\n menuOpen: boolean;\n setMenuOpen: (open: boolean) => void;\n sheetId: string;\n}\n\nfunction InnerContent({\n logo,\n homeHref,\n resolvedHomeLabel,\n resolvedNavLabel,\n resolvedMenuLabel,\n navSlot,\n actionsSlot,\n persistActions,\n menuOpen,\n setMenuOpen,\n sheetId,\n}: InnerContentProps): React.JSX.Element {\n // The mobile menu only needs to exist when something would otherwise be\n // hidden on small screens: the nav (always collapses) or — unless the\n // consumer pins them — the actions. With persisted actions and no nav there\n // is nothing to collapse, so no hamburger renders at all.\n const showMobileMenu =\n Boolean(navSlot) || (Boolean(actionsSlot) && !persistActions);\n return (\n <>\n <a\n href={homeHref}\n aria-label={resolvedHomeLabel}\n className=\"ds:inline-flex ds:items-center ds:rounded-[var(--radius-sm)] 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 >\n {logo}\n </a>\n\n {navSlot ? (\n <PublicHeaderSurfaceContext.Provider value=\"desktop\">\n <NavigationMenuPrimitive.Root\n aria-label={resolvedNavLabel}\n // Radix wraps the List in an unstyled `<div>` between Root and\n // <ul>. The `[&>div:first-of-type]:flex` arbitrary selector\n // forces that wrapper into flex so the List's flex-1 actually\n // stretches it across the available width.\n className=\"ds:hidden ds:md:flex ds:relative ds:items-center ds:ms-[var(--spacing-lg)] ds:flex-1 ds:[&>div:first-of-type]:flex ds:[&>div:first-of-type]:flex-1\"\n delayDuration={150}\n >\n <NavigationMenuPrimitive.List className=\"ds:flex ds:flex-1 ds:items-center ds:justify-center ds:gap-[var(--spacing-md)] ds:list-none ds:m-0 ds:ps-0\">\n {navSlot}\n </NavigationMenuPrimitive.List>\n {/* Viewport renders the active panel below the nav row. The\n wrapper centres it horizontally relative to the trigger row;\n Radix sets viewport-width/-height vars so the panel sizes\n to whichever Content is open. */}\n <div className=\"ds:absolute ds:top-full ds:start-0 ds:end-0 ds:flex ds:justify-center ds:pointer-events-none\">\n <div className=\"ds:pointer-events-auto\">\n <NavigationMenuPrimitive.Viewport className={viewportClasses} />\n </div>\n </div>\n </NavigationMenuPrimitive.Root>\n </PublicHeaderSurfaceContext.Provider>\n ) : null}\n\n {actionsSlot ? (\n <div\n className={[\n // Pinned actions stay inline at every breakpoint; otherwise they\n // are hidden < md and collapse into the mobile menu below.\n persistActions ? 'ds:flex' : 'ds:hidden ds:md:flex',\n 'ds:items-center ds:gap-[var(--spacing-sm)] ds:ms-auto',\n ].join(' ')}\n >\n {actionsSlot}\n </div>\n ) : null}\n\n {/* Mobile menu trigger (< md). Wired to a Sheet (partial drawer\n from inline-end) so navSlot + actionsSlot collapse there. Omitted\n entirely when there is nothing left to collapse (persisted actions,\n no nav). */}\n {showMobileMenu ? (\n <Sheet open={menuOpen} onOpenChange={setMenuOpen}>\n <Sheet.Trigger asChild>\n <IconButton\n size=\"md\"\n intent=\"ghost\"\n className=\"ds:ms-auto ds:md:hidden\"\n icon={\n menuOpen ? (\n <X aria-hidden=\"true\" />\n ) : (\n <Menu aria-hidden=\"true\" />\n )\n }\n aria-controls={sheetId}\n aria-expanded={menuOpen}\n aria-label={resolvedMenuLabel}\n />\n </Sheet.Trigger>\n <Sheet.Content side=\"end\" size=\"md\" id={sheetId}>\n <Sheet.Header>\n <Sheet.Title>{resolvedNavLabel}</Sheet.Title>\n </Sheet.Header>\n <Sheet.Body>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {navSlot ? (\n <PublicHeaderSurfaceContext.Provider value=\"mobile\">\n <nav\n aria-label={resolvedNavLabel}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n data-mobile-nav=\"true\"\n >\n {navSlot}\n </nav>\n </PublicHeaderSurfaceContext.Provider>\n ) : null}\n {actionsSlot && !persistActions ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:mt-[var(--spacing-md)]\">\n {actionsSlot}\n </div>\n ) : null}\n </div>\n </Sheet.Body>\n </Sheet.Content>\n </Sheet>\n ) : null}\n </>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderRoot = forwardRef<HTMLElement, PublicHeaderProps>(\n (\n {\n logo,\n homeHref = '/',\n homeLabel,\n navSlot,\n actionsSlot,\n variant = 'pill',\n sticky = 'none',\n stickyOffset = 80,\n menuLabel,\n navLabel,\n persistActions = false,\n id,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const reduced = usePrefersReducedMotion();\n const autoId = useId();\n const sheetId = `${id ?? autoId}-sheet`;\n const [menuOpen, setMenuOpen] = useState(false);\n\n // Scroll listener is only active when `transparent` or `scroll-up`\n // need it. Hidden state is disabled under reduced motion (the bar\n // stays visible — translating off-screen is precisely the motion\n // class of user the preference targets).\n const scrollEnabled = variant === 'transparent' || sticky === 'scroll-up';\n const { stuck, hidden } = useHeaderScrollState(\n scrollEnabled,\n sticky,\n stickyOffset,\n );\n const effectiveHidden = reduced ? false : hidden;\n\n const openMenu = useCallback((): void => setMenuOpen(true), []);\n const closeMenu = useCallback((): void => setMenuOpen(false), []);\n\n useImperativeHandle(\n ref as React.Ref<PublicHeaderHandle> | null | undefined,\n () => ({\n openMenu,\n closeMenu,\n getMenuOpen: () => menuOpen,\n }),\n [openMenu, closeMenu, menuOpen],\n );\n\n const resolvedHomeLabel =\n homeLabel ?? t('publicHeader.homeLabel', 'AlfaDocs — home');\n const resolvedNavLabel =\n navLabel ?? t('publicHeader.primaryNavLabel', 'Primary');\n const resolvedMenuLabel =\n menuLabel ??\n (menuOpen\n ? t('publicHeader.closeMenu', 'Close menu')\n : t('publicHeader.openMenu', 'Open menu'));\n\n const innerProps: InnerContentProps = {\n logo,\n homeHref,\n resolvedHomeLabel,\n resolvedNavLabel,\n resolvedMenuLabel,\n navSlot,\n actionsSlot,\n persistActions,\n menuOpen,\n setMenuOpen,\n sheetId,\n };\n\n return (\n <header\n {...rest}\n data-component=\"public-header\"\n data-component-id={id}\n data-variant={variant}\n data-stuck={stuck ? 'true' : undefined}\n data-hidden={effectiveHidden ? 'true' : undefined}\n data-state={reduced ? 'reduced-motion' : undefined}\n className={rootVariants({ variant, sticky, className })}\n >\n {variant === 'pill' ? (\n <div\n data-component=\"public-header-container\"\n className={pillContainerClasses}\n >\n <InnerContent {...innerProps} />\n </div>\n ) : (\n <InnerContent {...innerProps} />\n )}\n </header>\n );\n },\n);\nPublicHeaderRoot.displayName = 'PublicHeader';\n\n/* ------------------------------------------------------------------ */\n/* NavLink */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderNavLink = forwardRef<\n HTMLAnchorElement,\n PublicHeaderNavLinkProps\n>(({ active, className, children, ...rest }, ref) => {\n const surface = useContext(PublicHeaderSurfaceContext);\n // Desktop: NavigationMenu.Item + .Link give Radix the keyboard / focus\n // semantics across the trigger row. We render the actual <a> via\n // asChild so consumers can swap in router links transparently.\n // Mobile: plain <a> inside the Sheet's <nav> — no Radix Root in scope,\n // so we render outside the NavigationMenu primitive.\n if (surface === 'mobile') {\n return (\n <a\n ref={ref}\n {...rest}\n data-active={active ? 'true' : undefined}\n aria-current={active ? 'page' : undefined}\n className={[\n 'ds:block ds:no-underline',\n 'type-body-sm ds:font-medium',\n 'ds:text-[var(--foreground)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-sm)]',\n 'ds:hover:bg-[var(--muted)]/30 ds:hover:text-[var(--primary)]',\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:data-[active=true]:text-[var(--primary)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {children}\n </a>\n );\n }\n return (\n <NavigationMenuPrimitive.Item>\n <NavigationMenuPrimitive.Link asChild active={active}>\n <a\n ref={ref}\n {...rest}\n data-active={active ? 'true' : undefined}\n aria-current={active ? 'page' : undefined}\n className={[navLinkVariants(), className].filter(Boolean).join(' ')}\n >\n {children}\n </a>\n </NavigationMenuPrimitive.Link>\n </NavigationMenuPrimitive.Item>\n );\n});\nPublicHeaderNavLink.displayName = 'PublicHeader.NavLink';\n\n/* ------------------------------------------------------------------ */\n/* NavDropdown */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderNavDropdown = forwardRef<\n ElementRef<typeof NavigationMenuPrimitive.Trigger>,\n PublicHeaderNavDropdownProps\n>(({ label, wide = false, children, id }, ref) => {\n const surface = useContext(PublicHeaderSurfaceContext);\n if (surface === 'mobile') {\n // <details>/<summary> gives semantic disclosure for free —\n // Enter/Space toggles, summary is focusable, content collapses\n // when not open. No JS needed.\n return (\n <details\n id={id}\n data-component=\"public-header-nav-dropdown\"\n className=\"ds:group ds:border-b ds:border-[color:var(--border)]\"\n >\n <summary\n className={[\n 'ds:flex ds:items-center ds:justify-between ds:cursor-pointer',\n 'type-body-sm ds:font-medium ds:text-[var(--foreground)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-sm)]',\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:list-none ds:[&::-webkit-details-marker]:hidden',\n ].join(' ')}\n >\n <span>{label}</span>\n <ChevronDown\n aria-hidden=\"true\"\n className=\"ds:size-3 ds:shrink-0 ds:transition-transform ds:duration-[var(--animation-duration)] ds:group-[[open]]:rotate-180 ds:motion-reduce:transition-none\"\n />\n </summary>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:py-[var(--spacing-sm)]\">\n {children}\n </div>\n </details>\n );\n }\n return (\n <NavigationMenuPrimitive.Item data-component=\"public-header-nav-dropdown\">\n <NavigationMenuPrimitive.Trigger\n ref={ref}\n id={id}\n className={dropdownTriggerClasses}\n // Radix already wires aria-expanded + aria-controls. The\n // group / data-state hooks let the chevron rotate via Tailwind.\n >\n {label}\n <ChevronDown aria-hidden=\"true\" className={dropdownChevronClasses} />\n </NavigationMenuPrimitive.Trigger>\n <NavigationMenuPrimitive.Content\n className={dropdownContentVariants({ wide })}\n >\n {children}\n </NavigationMenuPrimitive.Content>\n </NavigationMenuPrimitive.Item>\n );\n});\nPublicHeaderNavDropdown.displayName = 'PublicHeader.NavDropdown';\n\n/* ------------------------------------------------------------------ */\n/* DropdownCard */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderDropdownCard = forwardRef<\n HTMLDivElement,\n PublicHeaderDropdownCardProps\n>(({ href, title, subtitle, children }, ref) => {\n const surface = useContext(PublicHeaderSurfaceContext);\n // The Card header. In mobile we render a plain <a> when href is set —\n // no Radix Link wrapper because the NavigationMenu root isn't in scope\n // inside the Sheet.\n const titleNode = (\n <span\n data-card-title\n className=\"type-title-card ds:text-[var(--foreground)] ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none\"\n >\n {title}\n </span>\n );\n const subtitleNode = subtitle ? (\n <span className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {subtitle}\n </span>\n ) : null;\n\n const arrow = (\n <span\n data-card-arrow\n aria-hidden=\"true\"\n className=\"ds:flex-none ds:text-[var(--muted-foreground)] ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none ds:rtl:-scale-x-100\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </svg>\n </span>\n );\n\n const linkInner = (\n <>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n {titleNode}\n {subtitleNode}\n </div>\n {arrow}\n </>\n );\n\n let header: React.JSX.Element;\n if (href) {\n if (surface === 'mobile') {\n header = (\n <a href={href} className={cardLinkClasses}>\n {linkInner}\n </a>\n );\n } else {\n header = (\n <NavigationMenuPrimitive.Link asChild>\n <a href={href} className={cardLinkClasses}>\n {linkInner}\n </a>\n </NavigationMenuPrimitive.Link>\n );\n }\n } else {\n header = (\n <div className={cardHeaderStaticClasses}>\n {titleNode}\n {subtitle ? (\n <span className=\"ds:block type-body-sm ds:text-[var(--muted-foreground)] ds:mt-[var(--spacing-xs)]\">\n {subtitle}\n </span>\n ) : null}\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n data-component=\"public-header-dropdown-card\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n {header}\n {children ? (\n <ul className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:list-none ds:m-0 ds:ps-0\">\n {children}\n </ul>\n ) : null}\n </div>\n );\n});\nPublicHeaderDropdownCard.displayName = 'PublicHeader.DropdownCard';\n\n/* ------------------------------------------------------------------ */\n/* DropdownLink */\n/* ------------------------------------------------------------------ */\n\nconst PublicHeaderDropdownLink = forwardRef<\n HTMLAnchorElement,\n PublicHeaderDropdownLinkProps\n>(({ active, className, children, ...rest }, ref) => {\n const surface = useContext(PublicHeaderSurfaceContext);\n const anchor = (\n <a\n ref={ref}\n {...rest}\n data-active={active ? 'true' : undefined}\n aria-current={active ? 'page' : undefined}\n className={[subLinkClasses, className].filter(Boolean).join(' ')}\n >\n {children}\n </a>\n );\n return (\n <li data-component=\"public-header-dropdown-link\">\n {surface === 'mobile' ? (\n anchor\n ) : (\n <NavigationMenuPrimitive.Link asChild active={active}>\n {anchor}\n </NavigationMenuPrimitive.Link>\n )}\n </li>\n );\n});\nPublicHeaderDropdownLink.displayName = 'PublicHeader.DropdownLink';\n\n/* ------------------------------------------------------------------ */\n/* Public surface */\n/* ------------------------------------------------------------------ */\n\nexport const PublicHeader = Object.assign(PublicHeaderRoot, {\n NavLink: PublicHeaderNavLink,\n NavDropdown: PublicHeaderNavDropdown,\n DropdownCard: PublicHeaderDropdownCard,\n DropdownLink: PublicHeaderDropdownLink,\n});\n","import type { AgentAdapter } from '../../agent/types';\nimport type { PublicHeaderHandle } from './public-header';\n\nexport const publicHeaderAgent: AgentAdapter<PublicHeaderHandle> = {\n id: 'public-header',\n capabilities: ['open', 'close'],\n state: {\n menuOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.publicHeader.state.menuOpen',\n description: 'Whether the mobile drawer is currently open.',\n read: (handle) => handle.getMenuOpen(),\n },\n },\n actions: {\n open_menu: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.publicHeader.actions.openMenu',\n description: 'Open the mobile drawer.',\n invoke: (handle) => {\n handle.openMenu();\n },\n },\n close_menu: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.publicHeader.actions.closeMenu',\n description: 'Close the mobile drawer.',\n invoke: (handle) => {\n handle.closeMenu();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'public-header' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on PublicHeader.',\n },\n },\n};\n"],"names":["PublicHeaderSurfaceContext","createContext","rootVariants","cva","pillContainerClasses","navLinkVariants","dropdownTriggerClasses","dropdownChevronClasses","dropdownContentVariants","viewportClasses","cardLinkClasses","cardHeaderStaticClasses","subLinkClasses","usePrefersReducedMotion","reduced","setReduced","useState","useEffect","mq","onChange","useHeaderScrollState","enabled","sticky","stickyOffset","stuck","setStuck","hidden","setHidden","lastYRef","useRef","tickingRef","update","y","delta","onScroll","InnerContent","logo","homeHref","resolvedHomeLabel","resolvedNavLabel","resolvedMenuLabel","navSlot","actionsSlot","persistActions","menuOpen","setMenuOpen","sheetId","showMobileMenu","jsxs","Fragment","jsx","NavigationMenuPrimitive","Sheet","IconButton","X","Menu","PublicHeaderRoot","forwardRef","homeLabel","variant","menuLabel","navLabel","id","className","rest","ref","t","useTranslation","autoId","useId","scrollEnabled","effectiveHidden","openMenu","useCallback","closeMenu","useImperativeHandle","innerProps","PublicHeaderNavLink","active","children","useContext","PublicHeaderNavDropdown","label","wide","ChevronDown","PublicHeaderDropdownCard","href","title","subtitle","surface","titleNode","linkInner","header","PublicHeaderDropdownLink","anchor","PublicHeader","publicHeaderAgent","handle"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"radiograph-panel.agent-D1x33moc.js","sources":["../../node_modules/lucide-react/dist/esm/icons/git-compare-arrows.mjs","../../node_modules/lucide-react/dist/esm/icons/radiation.mjs","../../src/components/radiograph-panel/radiograph-panel.tsx","../../src/components/radiograph-panel/radiograph-panel.agent.ts"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"5\", cy: \"6\", r: \"3\", key: \"1qnov2\" }],\n [\"path\", { d: \"M12 6h5a2 2 0 0 1 2 2v7\", key: \"1yj91y\" }],\n [\"path\", { d: \"m15 9-3-3 3-3\", key: \"1lwv8l\" }],\n [\"circle\", { cx: \"19\", cy: \"18\", r: \"3\", key: \"1qljk2\" }],\n [\"path\", { d: \"M12 18H7a2 2 0 0 1-2-2V9\", key: \"16sdep\" }],\n [\"path\", { d: \"m9 15 3 3-3 3\", key: \"1m3kbl\" }]\n];\nconst GitCompareArrows = createLucideIcon(\"git-compare-arrows\", __iconNode);\n\nexport { __iconNode, GitCompareArrows as default };\n//# sourceMappingURL=git-compare-arrows.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 12h.01\", key: \"1mp3jc\" }],\n [\n \"path\",\n {\n d: \"M14 15.4641a4 4 0 0 1-4 0L7.52786 19.74597 A 1 1 0 0 0 7.99303 21.16211 10 10 0 0 0 16.00697 21.16211 1 1 0 0 0 16.47214 19.74597z\",\n key: \"1y4lzb\"\n }\n ],\n [\n \"path\",\n {\n d: \"M16 12a4 4 0 0 0-2-3.464l2.472-4.282a1 1 0 0 1 1.46-.305 10 10 0 0 1 4.006 6.94A1 1 0 0 1 21 12z\",\n key: \"163ggk\"\n }\n ],\n [\n \"path\",\n {\n d: \"M8 12a4 4 0 0 1 2-3.464L7.528 4.254a1 1 0 0 0-1.46-.305 10 10 0 0 0-4.006 6.94A1 1 0 0 0 3 12z\",\n key: \"1l9i0b\"\n }\n ]\n];\nconst Radiation = createLucideIcon(\"radiation\", __iconNode);\n\nexport { __iconNode, Radiation as default };\n//# sourceMappingURL=radiation.mjs.map\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactElement,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Upload,\n ZoomIn,\n ZoomOut,\n ChevronLeft,\n ChevronRight,\n Trash2,\n Eye,\n GitCompareArrows,\n Radiation,\n} from 'lucide-react';\nimport type { FdiId, Radiograph, RadiographKind } from '../tooth-scheme';\nimport { Dialog } from '../dialog';\nimport { Button } from '../button';\nimport { IconButton } from '../icon-button';\nimport { Badge } from '../badge';\nimport { FormField } from '../form-field';\nimport { TextArea } from '../text-area';\nimport { FileUpload } from '../file-upload';\nimport { DatePicker } from '../date-picker';\nimport { DateRangePicker, type DateRangeValue } from '../date-range-picker';\nimport { EmptyState } from '../empty-state';\nimport { PanelHeader } from '../panel-header';\n\n/* ------------------------------------------------------------------ */\n/* RadiographPanel — the Imaging tool for the Control Room rail. */\n/* */\n/* Shows one tooth's radiographs (x-rays / endorali): an upload */\n/* composer, a sortable + date-filtered history, and a fullscreen */\n/* viewer that zooms / steps / compares films. Drops into a */\n/* `ControlRoomRail` tool `panel`, the patient profile, or a care-plan */\n/* editor — anywhere a selected tooth's imaging belongs. The host owns */\n/* the films (`radiographs`) and persistence (`onAddRadiograph` / */\n/* `onDeleteRadiograph`); the panel owns only view state. The chart */\n/* drives selection via `ToothScheme.onOpenRadiographs(toothId)`. */\n/* */\n/* Image urls are opaque / consumer-hosted — never bundled. Real */\n/* radiographs are PHI; stories use synthetic placeholders only. */\n/* ------------------------------------------------------------------ */\n\nconst ZOOM_CLASS = ['ds:scale-100', 'ds:scale-150', 'ds:scale-200'] as const;\n\n/** Sort films newest-first (or oldest-first); undated films sink to the end in\n * BOTH directions — mirrors `ToothScheme.sortByDateDesc`. */\nfunction sortByDate(films: Radiograph[], desc: boolean): Radiograph[] {\n return [...films].sort((a, b) => {\n if (a.date === b.date) return 0;\n if (!a.date) return 1;\n if (!b.date) return -1;\n return (a.date < b.date ? -1 : 1) * (desc ? -1 : 1);\n });\n}\n\n/** Date-range membership. ISO `YYYY-MM-DD` is parsed at LOCAL midnight (the\n * `+'T00:00:00'`) so the filter agrees with the local-midnight `Date` objects\n * the DateRangePicker emits — without it, films are off-by-one west of UTC. */\nfunction inRange(film: Radiograph, range: DateRangeValue): boolean {\n if (!film.date) return !range.from && !range.to;\n const d = new Date(`${film.date}T00:00:00`);\n if (range.from && d < range.from) return false;\n if (range.to && d > range.to) return false;\n return true;\n}\n\n/** Local `YYYY-MM-DD` — avoids the UTC shift `Date.toISOString()` introduces\n * west of UTC for the local-midnight Date the DatePicker emits. */\nfunction toLocalIsoDate(d: Date): string {\n const pad = (n: number) => String(n).padStart(2, '0');\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n}\n\nexport interface RadiographPanelHandle {\n /** Read the films currently shown (after the host's `radiographs` prop). */\n getRadiographs: () => Radiograph[];\n /** Open the fullscreen viewer on a film by id. */\n openViewer: (id: string) => void;\n /** Close the fullscreen viewer. */\n closeViewer: () => void;\n}\n\nexport interface RadiographPanelProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'title' | 'children'\n> {\n /** Instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** The tooth whose films are shown (FDI id). Null → a \"select a tooth\" prompt. */\n toothId?: FdiId | null;\n /** Display label for the selected tooth. Defaults to the localised \"Tooth {{id}}\". */\n toothLabel?: string;\n /** The selected tooth's films. The panel sorts + filters; order in is irrelevant. */\n radiographs?: Radiograph[];\n /** Commit a new film (the host persists it). Omit to hide the upload composer. */\n onAddRadiograph?: (draft: {\n fileName: string;\n date?: string;\n note?: string;\n }) => void;\n /** Remove a film by id. Omit to hide the delete affordance. */\n onDeleteRadiograph?: (id: string) => void;\n /** Panel heading. Defaults to the localised \"Imaging\". */\n title?: string;\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\nfunction KindBadge({ kind }: { kind: RadiographKind }): ReactElement {\n const { t } = useTranslation();\n const label = t(`radiographPanel.kind.${kind}`, {\n defaultValue: {\n periapical: 'Periapical',\n bitewing: 'Bitewing',\n panoramic: 'Panoramic',\n other: 'Other',\n }[kind],\n });\n return (\n <Badge variant=\"neutral\" size=\"sm\">\n {label}\n </Badge>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Fullscreen viewer — lightbox + compare */\n/* ------------------------------------------------------------------ */\n\ninterface ViewerState {\n films: Radiograph[];\n index: number;\n compare: boolean;\n}\n\nfunction RadiographViewer({\n state,\n toothLabel,\n onClose,\n onIndexChange,\n}: {\n state: ViewerState | null;\n toothLabel: string;\n onClose: () => void;\n onIndexChange: (index: number) => void;\n}): ReactElement {\n const { t } = useTranslation();\n const [zoom, setZoom] = useState(0);\n // Reset zoom when the viewed film changes (prev/next) or the mode flips, so a\n // user doesn't carry one film's zoom into the next.\n useEffect(() => {\n setZoom(0);\n }, [state?.index, state?.compare]);\n const films = state?.films ?? [];\n const current = state ? films[state.index] : undefined;\n\n return (\n <Dialog.Root\n open={state !== null}\n onOpenChange={(next) => {\n if (!next) {\n setZoom(0);\n onClose();\n }\n }}\n >\n <Dialog.Content size=\"fullscreen\" aria-describedby={undefined}>\n <Dialog.Header>\n <Dialog.Title>\n {state?.compare\n ? t('radiographPanel.viewer.compareTitle', {\n defaultValue: '{{tooth}} — comparison',\n tooth: toothLabel,\n })\n : t('radiographPanel.viewer.title', {\n defaultValue: '{{tooth}} — radiograph',\n tooth: toothLabel,\n })}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n {state?.compare ? (\n <div className=\"ds:grid ds:grid-cols-2 ds:gap-[var(--spacing-md)]\">\n {films.slice(0, 2).map((film) => (\n <figure\n key={film.id}\n className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n <div className=\"ds:flex ds:items-center ds:justify-center ds:overflow-hidden ds:rounded-[var(--radius-md)] ds:bg-[var(--muted)] ds:p-[var(--spacing-xs)]\">\n <img\n src={film.thumbnailUrl ?? film.url}\n alt={film.alt ?? toothLabel}\n className=\"ds:max-h-full ds:max-w-full ds:object-contain\"\n />\n </div>\n <figcaption className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {film.date}\n </figcaption>\n </figure>\n ))}\n </div>\n ) : (\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:max-h-full ds:items-center ds:justify-center ds:overflow-hidden ds:rounded-[var(--radius-md)] ds:bg-[var(--muted)] ds:p-[var(--spacing-sm)]\">\n <img\n src={current?.thumbnailUrl ?? current?.url}\n alt={current?.alt ?? toothLabel}\n className={[\n 'ds:max-h-full ds:max-w-full ds:object-contain',\n 'ds:origin-center ds:transition-transform ds:motion-reduce:transition-none',\n ZOOM_CLASS[zoom],\n ].join(' ')}\n />\n </div>\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <IconButton\n icon={<ChevronLeft aria-hidden=\"true\" />}\n aria-label={t('radiographPanel.viewer.prev', {\n defaultValue: 'Previous radiograph',\n })}\n size=\"sm\"\n flipIconInRtl\n disabled={!state || state.index === 0}\n onClick={() =>\n state && onIndexChange(Math.max(0, state.index - 1))\n }\n />\n <span\n aria-live=\"polite\"\n className=\"type-meta ds:text-[color:var(--muted-foreground)]\"\n >\n {t('radiographPanel.viewer.position', {\n defaultValue: '{{current}} / {{total}}',\n current: (state?.index ?? 0) + 1,\n total: films.length,\n })}\n </span>\n <IconButton\n icon={<ChevronRight aria-hidden=\"true\" />}\n aria-label={t('radiographPanel.viewer.next', {\n defaultValue: 'Next radiograph',\n })}\n size=\"sm\"\n flipIconInRtl\n disabled={!state || state.index >= films.length - 1}\n onClick={() =>\n state &&\n onIndexChange(Math.min(films.length - 1, state.index + 1))\n }\n />\n <span\n aria-hidden=\"true\"\n className=\"ds:ms-[var(--spacing-xs)] ds:me-[var(--spacing-xs)] ds:h-[var(--spacing-md)] ds:w-px ds:bg-[var(--border)]\"\n />\n <IconButton\n icon={<ZoomOut aria-hidden=\"true\" />}\n aria-label={t('radiographPanel.viewer.zoomOut', {\n defaultValue: 'Zoom out',\n })}\n size=\"sm\"\n disabled={zoom === 0}\n onClick={() => setZoom((z) => Math.max(0, z - 1))}\n />\n <IconButton\n icon={<ZoomIn aria-hidden=\"true\" />}\n aria-label={t('radiographPanel.viewer.zoomIn', {\n defaultValue: 'Zoom in',\n })}\n size=\"sm\"\n disabled={zoom === ZOOM_CLASS.length - 1}\n onClick={() =>\n setZoom((z) => Math.min(ZOOM_CLASS.length - 1, z + 1))\n }\n />\n </div>\n {current?.note ? (\n <p className=\"type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {current.note}\n </p>\n ) : null}\n </div>\n )}\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* RadiographPanel */\n/* ------------------------------------------------------------------ */\n\nexport const RadiographPanel = forwardRef<\n RadiographPanelHandle,\n RadiographPanelProps\n>(function RadiographPanel(\n {\n id,\n toothId,\n toothLabel: toothLabelProp,\n radiographs = [],\n onAddRadiograph,\n onDeleteRadiograph,\n title,\n 'aria-label': ariaLabel,\n className,\n ...rest\n },\n ref,\n) {\n const { t } = useTranslation();\n\n const [viewer, setViewer] = useState<ViewerState | null>(null);\n const [compareIds, setCompareIds] = useState<string[]>([]);\n const [sortDesc, setSortDesc] = useState(true);\n const [range, setRange] = useState<DateRangeValue>({});\n const [pendingFile, setPendingFile] = useState<string | null>(null);\n const [date, setDate] = useState<Date | undefined>(undefined);\n const [note, setNote] = useState('');\n\n // Stable, current snapshot for the imperative handle.\n const filmsRef = useRef<Radiograph[]>(radiographs);\n filmsRef.current = radiographs;\n\n useImperativeHandle(\n ref,\n () => ({\n getRadiographs: () => filmsRef.current,\n openViewer: (filmId) => {\n const index = filmsRef.current.findIndex((f) => f.id === filmId);\n if (index >= 0) {\n setViewer({ films: filmsRef.current, index, compare: false });\n }\n },\n closeViewer: () => setViewer(null),\n }),\n [],\n );\n\n const heading =\n title ?? t('radiographPanel.title', { defaultValue: 'Imaging' });\n const toothLabel =\n toothLabelProp ??\n (toothId\n ? t('radiographPanel.toothLabel', {\n defaultValue: 'Tooth {{id}}',\n id: toothId,\n })\n : '');\n\n const visible = useMemo(\n () =>\n sortByDate(\n radiographs.filter((f) => inRange(f, range)),\n sortDesc,\n ),\n [radiographs, range, sortDesc],\n );\n\n const toggleCompare = useCallback((filmId: string) => {\n setCompareIds((ids) =>\n ids.includes(filmId)\n ? ids.filter((x) => x !== filmId)\n : [...ids, filmId].slice(-2),\n );\n }, []);\n\n const handleUpload = useCallback(() => {\n if (!pendingFile || !onAddRadiograph) return;\n onAddRadiograph({\n fileName: pendingFile,\n date: date ? toLocalIsoDate(date) : undefined,\n note: note || undefined,\n });\n setPendingFile(null);\n setNote('');\n setDate(undefined);\n }, [pendingFile, date, note, onAddRadiograph]);\n\n // History filter controls — pinned in the PanelHeader's filters row (only\n // meaningful once a tooth is selected) so they stay put as the list scrolls.\n const historyFilters = toothId ? (\n <>\n <FormField\n label={t('radiographPanel.history.range', {\n defaultValue: 'Date range',\n })}\n >\n <DateRangePicker value={range} onChange={setRange} />\n </FormField>\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <Button intent=\"ghost\" size=\"sm\" onClick={() => setSortDesc((s) => !s)}>\n {sortDesc\n ? t('radiographPanel.history.sortNewest', {\n defaultValue: 'Newest first',\n })\n : t('radiographPanel.history.sortOldest', {\n defaultValue: 'Oldest first',\n })}\n </Button>\n <Button\n intent=\"ghost\"\n size=\"sm\"\n startIcon={<GitCompareArrows aria-hidden=\"true\" />}\n disabled={compareIds.length !== 2}\n onClick={() => {\n const films = radiographs.filter((f) => compareIds.includes(f.id));\n if (films.length === 2) {\n setViewer({ films, index: 0, compare: true });\n }\n }}\n >\n {t('radiographPanel.history.compare', {\n defaultValue: 'Compare',\n })}\n </Button>\n </div>\n </>\n ) : undefined;\n\n return (\n <section\n data-component=\"radiograph-panel\"\n data-component-id={id}\n data-tooth={toothId ?? undefined}\n aria-label={ariaLabel ?? heading}\n className={['ds:flex ds:flex-col', className].filter(Boolean).join(' ')}\n {...rest}\n >\n {/* Shared rail-panel header: title + film-count badge, history filters\n pinned beneath, divider, sticky so it stays visible as the list\n scrolls. The rail injects favourite/close into the action cluster. */}\n <PanelHeader\n sticky\n icon={<Radiation aria-hidden=\"true\" />}\n title={\n <>\n {toothId ? toothLabel : heading}\n {toothId ? (\n <Badge variant=\"info\" size=\"sm\">\n {radiographs.length}\n </Badge>\n ) : null}\n </>\n }\n filters={historyFilters}\n />\n\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]\">\n {!toothId ? (\n <EmptyState\n variant=\"first-use\"\n title={t('radiographPanel.noTooth.title', {\n defaultValue: 'No tooth selected',\n })}\n description={t('radiographPanel.noTooth.body', {\n defaultValue:\n 'Select a tooth on the chart to view its radiographs.',\n })}\n />\n ) : (\n <>\n {/* Upload */}\n {onAddRadiograph ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <FormField\n label={t('radiographPanel.upload.file', {\n defaultValue: 'Image file',\n })}\n >\n <FileUpload\n accept={{ 'image/*': ['.png', '.jpg', '.jpeg', '.webp'] }}\n variant=\"both\"\n showPreview\n onDrop={(accepted) =>\n setPendingFile(accepted[0]?.name ?? null)\n }\n />\n </FormField>\n <FormField\n label={t('radiographPanel.upload.date', {\n defaultValue: 'Acquisition date',\n })}\n >\n <DatePicker value={date} onChange={(d) => setDate(d)} />\n </FormField>\n <FormField\n label={t('radiographPanel.upload.note', {\n defaultValue: 'Note (optional)',\n })}\n >\n <TextArea\n rows={2}\n value={note}\n onChange={(e) => setNote(e.target.value)}\n placeholder={t('radiographPanel.upload.notePlaceholder', {\n defaultValue: 'E.g. routine check, apical lesion…',\n })}\n />\n </FormField>\n <Button\n intent=\"primary\"\n size=\"sm\"\n startIcon={<Upload aria-hidden=\"true\" />}\n disabled={!pendingFile}\n onClick={handleUpload}\n className=\"ds:self-start\"\n >\n {t('radiographPanel.upload.submit', {\n defaultValue: 'Upload',\n })}\n </Button>\n </div>\n ) : null}\n\n {/* History */}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {visible.length === 0 ? (\n <EmptyState\n variant=\"first-use\"\n title={t('radiographPanel.history.emptyTitle', {\n defaultValue: 'No radiographs yet',\n })}\n description={t('radiographPanel.history.emptyBody', {\n defaultValue: 'Upload the first film for this tooth.',\n })}\n />\n ) : (\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-xs)] ds:p-0\">\n {visible.map((film, visibleIndex) => {\n const selected = compareIds.includes(film.id);\n // Disambiguate the repeated row actions for screen readers by\n // the film's date (falls back to its 1-based position).\n const filmLabel = film.date ?? String(visibleIndex + 1);\n return (\n <li\n key={film.id}\n data-radiograph-id={film.id}\n data-selected={selected}\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--card-border)] ds:bg-[var(--card)] ds:p-[var(--spacing-xs)] ds:data-[selected=true]:border-[color:var(--info-foreground)]\"\n >\n <img\n src={film.thumbnailUrl ?? film.url}\n alt={film.alt ?? ''}\n className=\"ds:h-16 ds:w-12 ds:shrink-0 ds:rounded-[var(--radius-sm)] ds:object-cover\"\n />\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <span className=\"type-body-sm ds:text-[color:var(--foreground)]\">\n {film.date}\n </span>\n <KindBadge kind={film.kind ?? 'periapical'} />\n </div>\n <IconButton\n icon={<Eye aria-hidden=\"true\" />}\n aria-label={t('radiographPanel.history.view', {\n defaultValue: 'View radiograph {{film}}',\n film: filmLabel,\n })}\n size=\"sm\"\n intent=\"ghost\"\n // Step the viewer through the FILTERED + sorted list the\n // user is looking at, not every film on the tooth.\n onClick={() =>\n setViewer({\n films: visible,\n index: visibleIndex,\n compare: false,\n })\n }\n />\n <IconButton\n icon={<GitCompareArrows aria-hidden=\"true\" />}\n aria-label={\n selected\n ? t('radiographPanel.history.compareRemove', {\n defaultValue:\n 'Remove {{film}} from comparison',\n film: filmLabel,\n })\n : t('radiographPanel.history.compareAdd', {\n defaultValue:\n 'Select {{film}} for comparison',\n film: filmLabel,\n })\n }\n aria-pressed={selected}\n size=\"sm\"\n intent={selected ? 'secondary' : 'ghost'}\n onClick={() => toggleCompare(film.id)}\n />\n {onDeleteRadiograph ? (\n <IconButton\n icon={<Trash2 aria-hidden=\"true\" />}\n aria-label={t('radiographPanel.history.delete', {\n defaultValue: 'Delete radiograph {{film}}',\n film: filmLabel,\n })}\n size=\"sm\"\n intent=\"ghost\"\n onClick={() => onDeleteRadiograph(film.id)}\n />\n ) : null}\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </>\n )}\n </div>\n\n <RadiographViewer\n state={viewer}\n toothLabel={toothLabel}\n onClose={() => setViewer(null)}\n onIndexChange={(index) => setViewer((v) => (v ? { ...v, index } : v))}\n />\n </section>\n );\n});\n\n// `Radiation` is the conventional X-ray / imaging glyph — re-exported so a host\n// registering the Control Room tool can use the same icon as the panel.\nexport { Radiation as RadiographPanelIcon };\n","import type { AgentAdapter } from '../../agent/types';\nimport type { RadiographPanelHandle } from './radiograph-panel';\nimport type { Radiograph } from '../tooth-scheme';\n\n/**\n * The Imaging panel for the Control Room rail. It DISPLAYS the selected tooth's\n * radiographs and drives the fullscreen viewer; uploads and deletes are the\n * host's responsibility (the `onAddRadiograph` / `onDeleteRadiograph` props),\n * so they are not exposed here — the consuming pattern/app owns those `write` /\n * `destructive` workflows and their `radiograph.*` API contracts.\n */\nexport const radiographPanelAgent: AgentAdapter<RadiographPanelHandle> = {\n id: 'radiograph-panel',\n // pick — open a specific film in the viewer; view_change — the viewer is a\n // view surface over the host-owned films.\n capabilities: ['pick', 'view_change'],\n state: {\n radiographs: {\n // A9: structural refs only (id + kind) — never the free-text `note`,\n // service dates, or consumer-hosted image URLs in the always-on snapshot.\n type: 'Array<{ id: string; kind?: string }>',\n descriptionKey: 'ui.agent.radiographPanel.state.radiographs',\n description:\n 'Structural references (id + kind) to the films shown for the selected tooth.',\n read: (handle) =>\n handle\n .getRadiographs()\n .map((film) => ({ id: film.id, kind: film.kind ?? 'periapical' })),\n },\n },\n actions: {\n view_radiograph: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.radiographPanel.actions.viewRadiograph',\n description: 'Open a film in the fullscreen viewer by id.',\n invoke: (handle, args: { id: string }) => {\n handle.openViewer(args.id);\n },\n },\n close_viewer: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.radiographPanel.actions.closeViewer',\n description: 'Close the fullscreen radiograph viewer.',\n invoke: (handle) => {\n handle.closeViewer();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'radiograph-panel' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-radiograph-id',\n description:\n \"Each film row (`<li>`) carries its radiograph id as `data-radiograph-id`. The panel root additionally carries the selected tooth's FDI id as `data-tooth`.\",\n },\n },\n};\n\n// Re-exported for callers building typed reads against the adapter.\nexport type { Radiograph };\n"],"names":["__iconNode","GitCompareArrows","createLucideIcon","Radiation","ZOOM_CLASS","sortByDate","films","desc","a","b","inRange","film","range","d","toLocalIsoDate","pad","n","KindBadge","kind","t","useTranslation","label","Badge","RadiographViewer","state","toothLabel","onClose","onIndexChange","zoom","setZoom","useState","useEffect","current","jsx","Dialog","next","jsxs","IconButton","ChevronLeft","ChevronRight","ZoomOut","z","ZoomIn","RadiographPanel","forwardRef","id","toothId","toothLabelProp","radiographs","onAddRadiograph","onDeleteRadiograph","title","ariaLabel","className","rest","ref","viewer","setViewer","compareIds","setCompareIds","sortDesc","setSortDesc","setRange","pendingFile","setPendingFile","date","setDate","note","setNote","filmsRef","useRef","useImperativeHandle","filmId","index","f","heading","visible","useMemo","toggleCompare","useCallback","ids","x","handleUpload","historyFilters","Fragment","FormField","DateRangePicker","Button","s","PanelHeader","FileUpload","accepted","_a","DatePicker","TextArea","e","Upload","EmptyState","visibleIndex","selected","filmLabel","Eye","Trash2","v","radiographPanelAgent","handle","args"],"mappings":"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","x_google_ignoreList":[0,1]}
|