@alfadocs/ui-kit-debug 1.56.0 → 1.58.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/{address-fields-BfjxS05Z.js → address-fields-CJtu7LQU.js} +2 -2
- package/dist/_chunks/{address-fields-BfjxS05Z.js.map → address-fields-CJtu7LQU.js.map} +1 -1
- package/dist/_chunks/{ai-credits-notice-BoNJtOuE.js → ai-credits-notice-ktklr8fy.js} +2 -2
- package/dist/_chunks/{ai-credits-notice-BoNJtOuE.js.map → ai-credits-notice-ktklr8fy.js.map} +1 -1
- package/dist/_chunks/ai-permission-notice-DyuEGwAt.js +206 -0
- package/dist/_chunks/ai-permission-notice-DyuEGwAt.js.map +1 -0
- package/dist/_chunks/alia-sidebar-dybRpWml.js +1284 -0
- package/dist/_chunks/alia-sidebar-dybRpWml.js.map +1 -0
- package/dist/_chunks/{anamnesis-summary-rows-CQ-XGr0T.js → anamnesis-summary-rows-M-FUkw9p.js} +6 -6
- package/dist/_chunks/{anamnesis-summary-rows-CQ-XGr0T.js.map → anamnesis-summary-rows-M-FUkw9p.js.map} +1 -1
- package/dist/_chunks/{app-frame-B-0O9CrU.js → app-frame-CqmDh2v5.js} +2 -2
- package/dist/_chunks/{app-frame-B-0O9CrU.js.map → app-frame-CqmDh2v5.js.map} +1 -1
- package/dist/_chunks/{appointment-peek-BIZaDeCi.js → appointment-peek-WvNbE4JG.js} +2 -2
- package/dist/_chunks/{appointment-peek-BIZaDeCi.js.map → appointment-peek-WvNbE4JG.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-DmqYEIT9.js → appointment-timeline-Z0494xO-.js} +2 -2
- package/dist/_chunks/{appointment-timeline-DmqYEIT9.js.map → appointment-timeline-Z0494xO-.js.map} +1 -1
- package/dist/_chunks/{balance-badge-cell-DmDcXw0c.js → balance-badge-cell-CGoJZlKf.js} +3 -3
- package/dist/_chunks/{balance-badge-cell-DmDcXw0c.js.map → balance-badge-cell-CGoJZlKf.js.map} +1 -1
- package/dist/_chunks/{booking-WyNGKPE2.js → booking-CiFSAMR-.js} +4 -4
- package/dist/_chunks/{booking-WyNGKPE2.js.map → booking-CiFSAMR-.js.map} +1 -1
- package/dist/_chunks/{calculator-dialog-pCPWta7h.js → calculator-dialog-CzQv03p0.js} +2 -2
- package/dist/_chunks/{calculator-dialog-pCPWta7h.js.map → calculator-dialog-CzQv03p0.js.map} +1 -1
- package/dist/_chunks/{calendar-workspace-Du2ryaI-.js → calendar-workspace-DNHzjG7O.js} +19 -19
- package/dist/_chunks/calendar-workspace-DNHzjG7O.js.map +1 -0
- package/dist/_chunks/{care-plan-card-Ddjh5Doc.js → care-plan-card-DxrRLRdW.js} +2 -2
- package/dist/_chunks/{care-plan-card-Ddjh5Doc.js.map → care-plan-card-DxrRLRdW.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-DUX_SVvF.js → care-plan-header-BMwZIgHJ.js} +2 -2
- package/dist/_chunks/{care-plan-header-DUX_SVvF.js.map → care-plan-header-BMwZIgHJ.js.map} +1 -1
- package/dist/_chunks/{chart-HsF1KHbx.js → chart-ZMkX-Gqy.js} +338 -341
- package/dist/_chunks/chart-ZMkX-Gqy.js.map +1 -0
- package/dist/_chunks/{city-input-BC_nYINn.js → city-input-3J3bz9EO.js} +2 -2
- package/dist/_chunks/{city-input-BC_nYINn.js.map → city-input-3J3bz9EO.js.map} +1 -1
- package/dist/_chunks/{clinical-note-card-14JIoUR0.js → clinical-note-card-hx939bvw.js} +2 -2
- package/dist/_chunks/{clinical-note-card-14JIoUR0.js.map → clinical-note-card-hx939bvw.js.map} +1 -1
- package/dist/_chunks/{color-picker-BRQ4Y9SO.js → color-picker-BsggJovx.js} +128 -123
- package/dist/_chunks/color-picker-BsggJovx.js.map +1 -0
- package/dist/_chunks/{contact-card-CmK05vNb.js → contact-card-fHBMwEsx.js} +2 -2
- package/dist/_chunks/{contact-card-CmK05vNb.js.map → contact-card-fHBMwEsx.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-Ci8lBQ6a.js → contact-profile-card-CMyBYgRR.js} +2 -2
- package/dist/_chunks/{contact-profile-card-Ci8lBQ6a.js.map → contact-profile-card-CMyBYgRR.js.map} +1 -1
- package/dist/_chunks/{control-room-rail-Tx2jW250.js → control-room-rail-CJ85HkS2.js} +2 -2
- package/dist/_chunks/{control-room-rail-Tx2jW250.js.map → control-room-rail-CJ85HkS2.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-Dgfqr4Q4.js → cycle-calculator-Cww9DzIa.js} +2 -2
- package/dist/_chunks/{cycle-calculator-Dgfqr4Q4.js.map → cycle-calculator-Cww9DzIa.js.map} +1 -1
- package/dist/_chunks/dashboard-grid-Cs7cJAsA.js +933 -0
- package/dist/_chunks/dashboard-grid-Cs7cJAsA.js.map +1 -0
- package/dist/_chunks/{data-table-D8fuhqO1.js → data-table-Yn5xiGzs.js} +3 -3
- package/dist/_chunks/{data-table-D8fuhqO1.js.map → data-table-Yn5xiGzs.js.map} +1 -1
- package/dist/_chunks/{data-table-tabs-Xhg5G0gU.js → data-table-tabs-CHYAAeHy.js} +2 -2
- package/dist/_chunks/{data-table-tabs-Xhg5G0gU.js.map → data-table-tabs-CHYAAeHy.js.map} +1 -1
- package/dist/_chunks/{date-picker-wRAcq2lt.js → date-picker-BSZuKo13.js} +69 -62
- package/dist/_chunks/date-picker-BSZuKo13.js.map +1 -0
- package/dist/_chunks/{date-range-picker-CtUOI38x.js → date-range-picker-CFk-5O3R.js} +176 -171
- package/dist/_chunks/date-range-picker-CFk-5O3R.js.map +1 -0
- package/dist/_chunks/{date-time-picker-CLeLKuv9.js → date-time-picker-CjxTkblD.js} +92 -85
- package/dist/_chunks/date-time-picker-CjxTkblD.js.map +1 -0
- package/dist/_chunks/{dialog-CUzbnKLw.js → dialog-Dn-iQ0Jp.js} +2 -2
- package/dist/_chunks/{dialog-CUzbnKLw.js.map → dialog-Dn-iQ0Jp.js.map} +1 -1
- package/dist/_chunks/{document-preview-uoTekVR7.js → document-preview-CHGGG0l_.js} +2 -2
- package/dist/_chunks/{document-preview-uoTekVR7.js.map → document-preview-CHGGG0l_.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-CSjklbyw.js → due-date-calculator-D_qFUiHp.js} +2 -2
- package/dist/_chunks/{due-date-calculator-CSjklbyw.js.map → due-date-calculator-D_qFUiHp.js.map} +1 -1
- package/dist/_chunks/{entity-summary-DcB0fIiv.js → entity-summary-CWcCSThK.js} +2 -2
- package/dist/_chunks/{entity-summary-DcB0fIiv.js.map → entity-summary-CWcCSThK.js.map} +1 -1
- package/dist/_chunks/{face-scheme-BicuUA2K.js → face-scheme-DSKDdIsb.js} +2 -2
- package/dist/_chunks/{face-scheme-BicuUA2K.js.map → face-scheme-DSKDdIsb.js.map} +1 -1
- package/dist/_chunks/{file-manager-Cc_uO8r2.js → file-manager-DEtkQR1F.js} +4 -4
- package/dist/_chunks/{file-manager-Cc_uO8r2.js.map → file-manager-DEtkQR1F.js.map} +1 -1
- package/dist/_chunks/{forgot-password-form-DEx-M_QR.js → forgot-password-form-CEqOmNuX.js} +2 -2
- package/dist/_chunks/{forgot-password-form-DEx-M_QR.js.map → forgot-password-form-CEqOmNuX.js.map} +1 -1
- package/dist/_chunks/{gestational-age-calculator-DqVeJke2.js → gestational-age-calculator-CZi43xKG.js} +2 -2
- package/dist/_chunks/{gestational-age-calculator-DqVeJke2.js.map → gestational-age-calculator-CZi43xKG.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-BIYyI2Yo.js → hcg-doubling-Ccvh7OaU.js} +2 -2
- package/dist/_chunks/{hcg-doubling-BIYyI2Yo.js.map → hcg-doubling-Ccvh7OaU.js.map} +1 -1
- package/dist/_chunks/{header-settings-ge_3gYEq.js → header-settings-BMcCx2LC.js} +2 -2
- package/dist/_chunks/{header-settings-ge_3gYEq.js.map → header-settings-BMcCx2LC.js.map} +1 -1
- package/dist/_chunks/{heatmap-Gf9r7Tn1.js → heatmap-DiyOSQk9.js} +2 -2
- package/dist/_chunks/{heatmap-Gf9r7Tn1.js.map → heatmap-DiyOSQk9.js.map} +1 -1
- package/dist/_chunks/{help-me-write-templates-fV-Apf72.js → help-me-write-templates-CM1p6qkm.js} +3 -3
- package/dist/_chunks/{help-me-write-templates-fV-Apf72.js.map → help-me-write-templates-CM1p6qkm.js.map} +1 -1
- package/dist/_chunks/{hover-card-BnTueNS2.js → hover-card-U_ZYoh1n.js} +201 -187
- package/dist/_chunks/hover-card-U_ZYoh1n.js.map +1 -0
- package/dist/_chunks/{icon-picker-DWrqmI1c.js → icon-picker-rOFTawXk.js} +3 -3
- package/dist/_chunks/{icon-picker-DWrqmI1c.js.map → icon-picker-rOFTawXk.js.map} +1 -1
- package/dist/_chunks/{info-tip-B0jmIt6M.js → info-tip-CJpNpzZe.js} +2 -2
- package/dist/_chunks/{info-tip-B0jmIt6M.js.map → info-tip-CJpNpzZe.js.map} +1 -1
- package/dist/_chunks/{kit-extensions-Byfxy6sy.js → kit-extensions-DYVxWcqv.js} +4 -4
- package/dist/_chunks/{kit-extensions-Byfxy6sy.js.map → kit-extensions-DYVxWcqv.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-TeJNvymP.js → link-cell-renderer-C1wOyxDF.js} +3 -3
- package/dist/_chunks/{link-cell-renderer-TeJNvymP.js.map → link-cell-renderer-C1wOyxDF.js.map} +1 -1
- package/dist/_chunks/link-gRw3NtOt.js +137 -0
- package/dist/_chunks/link-gRw3NtOt.js.map +1 -0
- package/dist/_chunks/{list-RRN2TJ_7.js → list-CNnn7DOD.js} +75 -73
- package/dist/_chunks/list-CNnn7DOD.js.map +1 -0
- package/dist/_chunks/{locale-picker-DfNSdOpy.js → locale-picker-BGfrZyTw.js} +2 -2
- package/dist/_chunks/{locale-picker-DfNSdOpy.js.map → locale-picker-BGfrZyTw.js.map} +1 -1
- package/dist/_chunks/{login-dev-card-DmZ1B0lB.js → login-dev-card-CIim81VB.js} +2 -2
- package/dist/_chunks/{login-dev-card-DmZ1B0lB.js.map → login-dev-card-CIim81VB.js.map} +1 -1
- package/dist/_chunks/marketplace-app-shell-CSDmGLPW.js +613 -0
- package/dist/_chunks/marketplace-app-shell-CSDmGLPW.js.map +1 -0
- package/dist/_chunks/{message-tray-BB95DA82.js → message-tray-DmU0poD7.js} +76 -69
- package/dist/_chunks/message-tray-DmU0poD7.js.map +1 -0
- package/dist/_chunks/{nav-grid-BqCPH8sm.js → nav-grid-Byx8PxuB.js} +2 -2
- package/dist/_chunks/{nav-grid-BqCPH8sm.js.map → nav-grid-Byx8PxuB.js.map} +1 -1
- package/dist/_chunks/navigation-dismiss-B1mcW1CT.js +9 -0
- package/dist/_chunks/navigation-dismiss-B1mcW1CT.js.map +1 -0
- package/dist/_chunks/non-modal-tab-exit-j3CPOuE3.js +89 -0
- package/dist/_chunks/non-modal-tab-exit-j3CPOuE3.js.map +1 -0
- package/dist/_chunks/{note-attachment-I1NLoeRZ.js → note-attachment-Bt2cddsZ.js} +2 -2
- package/dist/_chunks/{note-attachment-I1NLoeRZ.js.map → note-attachment-Bt2cddsZ.js.map} +1 -1
- package/dist/_chunks/{note-timeline-CsY8YOE7.js → note-timeline-CX9nAgAR.js} +2 -2
- package/dist/_chunks/{note-timeline-CsY8YOE7.js.map → note-timeline-CX9nAgAR.js.map} +1 -1
- package/dist/_chunks/{notes-panel-DceRhthG.js → notes-panel-DHLHsxpW.js} +4 -4
- package/dist/_chunks/{notes-panel-DceRhthG.js.map → notes-panel-DHLHsxpW.js.map} +1 -1
- package/dist/_chunks/{notification-tray-__sJXnsz.js → notification-tray-DPU-Xg0i.js} +83 -76
- package/dist/_chunks/notification-tray-DPU-Xg0i.js.map +1 -0
- package/dist/_chunks/{panel-subview-BT-Apwgb.js → panel-subview-D4o6ar6_.js} +61 -47
- package/dist/_chunks/panel-subview-D4o6ar6_.js.map +1 -0
- package/dist/_chunks/{patient-details-DsTtjpuX.js → patient-details-BCaVuaXz.js} +2 -2
- package/dist/_chunks/{patient-details-DsTtjpuX.js.map → patient-details-BCaVuaXz.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-BvZ9luz-.js → patient-field-row-jcRSTrp4.js} +7 -7
- package/dist/_chunks/{patient-field-row-BvZ9luz-.js.map → patient-field-row-jcRSTrp4.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-9nQWTQf6.js → patient-summary-card-kQIfPQOE.js} +4 -4
- package/dist/_chunks/{patient-summary-card-9nQWTQf6.js.map → patient-summary-card-kQIfPQOE.js.map} +1 -1
- package/dist/_chunks/{payment-automation-upsell-DiHovmUL.js → payment-automation-upsell-C4wHOxsp.js} +2 -2
- package/dist/_chunks/{payment-automation-upsell-DiHovmUL.js.map → payment-automation-upsell-C4wHOxsp.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-CwDpwXUC.js → payment-request-card-DAniJNLX.js} +2 -2
- package/dist/_chunks/{payment-request-card-CwDpwXUC.js.map → payment-request-card-DAniJNLX.js.map} +1 -1
- package/dist/_chunks/{pdf-viewer-C3minW5b.js → pdf-viewer-CNQxa4tv.js} +396 -391
- package/dist/_chunks/pdf-viewer-CNQxa4tv.js.map +1 -0
- package/dist/_chunks/{phone-input-DxkHMYmu.js → phone-input-O9camxkq.js} +156 -151
- package/dist/_chunks/phone-input-O9camxkq.js.map +1 -0
- package/dist/_chunks/popover-BG75rYjN.js +367 -0
- package/dist/_chunks/popover-BG75rYjN.js.map +1 -0
- package/dist/_chunks/{practice-results-Dhbo-fc_.js → practice-results-D07wgCqV.js} +2 -2
- package/dist/_chunks/{practice-results-Dhbo-fc_.js.map → practice-results-D07wgCqV.js.map} +1 -1
- package/dist/_chunks/{pregnancy-dating-Bfu0Cq4H.js → pregnancy-dating-BFzv9g1N.js} +2 -2
- package/dist/_chunks/{pregnancy-dating-Bfu0Cq4H.js.map → pregnancy-dating-BFzv9g1N.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-BSSiGGG4.js → product-hub-panel-DCYX0rPG.js} +103 -96
- package/dist/_chunks/product-hub-panel-DCYX0rPG.js.map +1 -0
- package/dist/_chunks/{public-footer-CxpG6J1M.js → public-footer-ZWTEG1Rq.js} +2 -2
- package/dist/_chunks/{public-footer-CxpG6J1M.js.map → public-footer-ZWTEG1Rq.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-pr2hyiND.js → public-header.agent-C1SlVSYt.js} +2 -2
- package/dist/_chunks/{public-header.agent-pr2hyiND.js.map → public-header.agent-C1SlVSYt.js.map} +1 -1
- package/dist/_chunks/{radiograph-panel.agent-DkUokbEa.js → radiograph-panel.agent-DyqbTECc.js} +4 -4
- package/dist/_chunks/{radiograph-panel.agent-DkUokbEa.js.map → radiograph-panel.agent-DyqbTECc.js.map} +1 -1
- package/dist/_chunks/{registration-form-D7iNqMBF.js → registration-form-DrSR9Sjk.js} +4 -4
- package/dist/_chunks/{registration-form-D7iNqMBF.js.map → registration-form-DrSR9Sjk.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-CkFfmA3v.js → rich-text-editor-UgXri8h6.js} +490 -485
- package/dist/_chunks/rich-text-editor-UgXri8h6.js.map +1 -0
- package/dist/_chunks/{scroll-area-ZtFCv9K7.js → scroll-area-CY5SLYNw.js} +104 -74
- package/dist/_chunks/scroll-area-CY5SLYNw.js.map +1 -0
- package/dist/_chunks/{search-bar-DQJS0wJN.js → search-bar-mA4bPe3t.js} +294 -255
- package/dist/_chunks/search-bar-mA4bPe3t.js.map +1 -0
- package/dist/_chunks/{sheet-C7SwIxwB.js → sheet-Dtjk0CVv.js} +3 -3
- package/dist/_chunks/{sheet-C7SwIxwB.js.map → sheet-Dtjk0CVv.js.map} +1 -1
- package/dist/_chunks/sidebar-D4Wllqfz.js +2029 -0
- package/dist/_chunks/sidebar-D4Wllqfz.js.map +1 -0
- package/dist/_chunks/{sign-document-B6HlyCGV.js → sign-document-D4iHS_Ug.js} +2 -2
- package/dist/_chunks/{sign-document-B6HlyCGV.js.map → sign-document-D4iHS_Ug.js.map} +1 -1
- package/dist/_chunks/{signature-request-DhbpB9N9.js → signature-request-dAVgE0_5.js} +3 -3
- package/dist/_chunks/{signature-request-DhbpB9N9.js.map → signature-request-dAVgE0_5.js.map} +1 -1
- package/dist/_chunks/{signed-out-frame-B2GTIeqA.js → signed-out-frame-DOJpobp8.js} +3 -3
- package/dist/_chunks/{signed-out-frame-B2GTIeqA.js.map → signed-out-frame-DOJpobp8.js.map} +1 -1
- package/dist/_chunks/{state-backed-text-input-DECQy5aA.js → state-backed-text-input-Cgh4ms3p.js} +2 -2
- package/dist/_chunks/{state-backed-text-input-DECQy5aA.js.map → state-backed-text-input-Cgh4ms3p.js.map} +1 -1
- package/dist/_chunks/{task-editor-ByyRu29Y.js → task-editor-BflEZmcF.js} +7 -6
- package/dist/_chunks/task-editor-BflEZmcF.js.map +1 -0
- package/dist/_chunks/{tool-rail-Bwyuw_Ot.js → tool-rail-CTq1KwxW.js} +115 -114
- package/dist/_chunks/{tool-rail-Bwyuw_Ot.js.map → tool-rail-CTq1KwxW.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-JsDM48tf.js → use-appointment-details-read-izwoXh-G.js} +8 -8
- package/dist/_chunks/{use-appointment-details-read-JsDM48tf.js.map → use-appointment-details-read-izwoXh-G.js.map} +1 -1
- package/dist/_chunks/use-state-backed-input-DhRQo6gM.js +57 -0
- package/dist/_chunks/use-state-backed-input-DhRQo6gM.js.map +1 -0
- package/dist/_chunks/{voice-control-panel-Bg1eklL0.js → voice-control-panel-an-bpQfF.js} +3 -3
- package/dist/_chunks/{voice-control-panel-Bg1eklL0.js.map → voice-control-panel-an-bpQfF.js.map} +1 -1
- package/dist/_chunks/{widget-picker-DXYBMTfe.js → widget-picker-DlJOgYrZ.js} +80 -57
- package/dist/_chunks/widget-picker-DlJOgYrZ.js.map +1 -0
- package/dist/agent-catalog.json +3 -3
- package/dist/agent-i18n/en.json +1 -1
- package/dist/components/_shared/navigation-dismiss.d.ts +8 -0
- package/dist/components/_shared/navigation-dismiss.d.ts.map +1 -0
- package/dist/components/_shared/non-modal-tab-exit.d.ts +15 -4
- package/dist/components/_shared/non-modal-tab-exit.d.ts.map +1 -1
- package/dist/components/_shared/use-state-backed-input.d.ts +3 -2
- package/dist/components/_shared/use-state-backed-input.d.ts.map +1 -1
- package/dist/components/address-fields/index.js +1 -1
- package/dist/components/ai-credits-notice/index.js +1 -1
- package/dist/components/ai-permission-notice/ai-permission-notice.d.ts +32 -0
- package/dist/components/ai-permission-notice/ai-permission-notice.d.ts.map +1 -1
- package/dist/components/ai-permission-notice/index.d.ts +1 -1
- package/dist/components/ai-permission-notice/index.d.ts.map +1 -1
- package/dist/components/ai-permission-notice/index.js +1 -1
- package/dist/components/app-frame/index.js +1 -1
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/appointment-peek/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/calculator-dialog/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/chart/chart.d.ts +5 -5
- package/dist/components/chart/chart.d.ts.map +1 -1
- package/dist/components/chart/index.js +1 -1
- package/dist/components/city-input/index.js +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/color-picker/color-picker.d.ts.map +1 -1
- package/dist/components/color-picker/index.js +1 -1
- package/dist/components/contact-card/index.js +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/cycle-calculator/index.js +1 -1
- package/dist/components/dashboard-grid/dashboard-grid.d.ts +33 -8
- package/dist/components/dashboard-grid/dashboard-grid.d.ts.map +1 -1
- package/dist/components/dashboard-grid/index.js +1 -1
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/data-table-tabs/index.js +1 -1
- package/dist/components/date-picker/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/date-range-picker/date-range-picker.d.ts.map +1 -1
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/date-time-picker/date-time-picker.d.ts.map +1 -1
- package/dist/components/date-time-picker/index.js +1 -1
- package/dist/components/dialog/index.js +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/face-scheme/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/hcg-doubling/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/heatmap/index.js +1 -1
- package/dist/components/hover-card/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card/index.js +1 -1
- package/dist/components/icon-picker/index.js +1 -1
- package/dist/components/info-tip/index.js +1 -1
- package/dist/components/link/index.js +1 -1
- package/dist/components/link/link.d.ts +5 -3
- package/dist/components/link/link.d.ts.map +1 -1
- package/dist/components/list/index.js +1 -1
- package/dist/components/list/list.d.ts.map +1 -1
- package/dist/components/locale-picker/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/message-tray/message-tray.d.ts.map +1 -1
- package/dist/components/nav-grid/index.js +1 -1
- package/dist/components/note-timeline/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/notification-tray/notification-tray.d.ts.map +1 -1
- package/dist/components/panel-subview/index.js +1 -1
- package/dist/components/panel-subview/panel-subview.d.ts.map +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/pdf-viewer/index.js +1 -1
- package/dist/components/pdf-viewer/pdf-viewer.d.ts.map +1 -1
- package/dist/components/phone-input/index.js +1 -1
- package/dist/components/phone-input/phone-input.d.ts.map +1 -1
- package/dist/components/popover/index.js +1 -1
- package/dist/components/popover/popover.d.ts +1 -1
- 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/product-hub-tray/index.js +1 -1
- package/dist/components/product-hub-tray/product-hub-tray.d.ts.map +1 -1
- package/dist/components/public-footer/index.js +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/rich-text-editor/editor-toolbar.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +2 -2
- package/dist/components/scroll-area/index.js +1 -1
- package/dist/components/scroll-area/scroll-area.d.ts +6 -5
- package/dist/components/scroll-area/scroll-area.d.ts.map +1 -1
- package/dist/components/search-bar/index.js +1 -1
- package/dist/components/search-bar/search-bar.d.ts +1 -1
- package/dist/components/search-bar/search-bar.d.ts.map +1 -1
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sidebar/index.d.ts +1 -1
- package/dist/components/sidebar/index.d.ts.map +1 -1
- package/dist/components/sidebar/index.js +1 -1
- package/dist/components/sidebar/sidebar-move.d.ts +88 -0
- package/dist/components/sidebar/sidebar-move.d.ts.map +1 -0
- package/dist/components/sidebar/sidebar.d.ts +26 -1
- package/dist/components/sidebar/sidebar.d.ts.map +1 -1
- package/dist/components/sign-document/index.js +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/task-editor/task-editor.d.ts.map +1 -1
- package/dist/components/tool-rail/index.js +1 -1
- package/dist/components/tool-rail/tool-rail.d.ts.map +1 -1
- package/dist/components/voice-control-panel/index.js +1 -1
- package/dist/components/widget-picker/index.js +1 -1
- package/dist/components/widget-picker/widget-picker.d.ts.map +1 -1
- package/dist/host-compat.css +2 -1
- package/dist/i18n/locales/ar.d.ts +24 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +26 -2
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +24 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +26 -2
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +24 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +26 -2
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +24 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +26 -2
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +24 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +26 -2
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +24 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +26 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +24 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +26 -2
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +24 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +26 -2
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +24 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +26 -2
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +24 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +26 -2
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +24 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +26 -2
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +24 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +26 -2
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +24 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +26 -2
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +24 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +26 -2
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +24 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +26 -2
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +24 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +26 -2
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +24 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +26 -2
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +24 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +26 -2
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +204 -203
- package/dist/locales/ar.json +26 -2
- package/dist/locales/de.json +26 -2
- package/dist/locales/el.json +26 -2
- package/dist/locales/en.json +26 -2
- package/dist/locales/es.json +26 -2
- package/dist/locales/fr.json +26 -2
- package/dist/locales/hi.json +26 -2
- package/dist/locales/it.json +26 -2
- package/dist/locales/ja.json +26 -2
- package/dist/locales/nl.json +26 -2
- package/dist/locales/pl.json +26 -2
- package/dist/locales/pt.json +26 -2
- package/dist/locales/ro.json +26 -2
- package/dist/locales/ru.json +26 -2
- package/dist/locales/sq.json +26 -2
- package/dist/locales/sv.json +26 -2
- package/dist/locales/tr.json +26 -2
- package/dist/locales/zh.json +26 -2
- package/dist/patterns/alia-assistant/alia-asteroid-icon.d.ts +10 -13
- package/dist/patterns/alia-assistant/alia-asteroid-icon.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/alia-chat-surface.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/alia-popout.d.ts +5 -3
- package/dist/patterns/alia-assistant/alia-popout.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/index.d.ts +2 -0
- package/dist/patterns/alia-assistant/index.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/index.js +6 -5
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/forgot-password-form/index.js +1 -1
- package/dist/patterns/help-me-write-templates/index.js +1 -1
- package/dist/patterns/login-form/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 +40 -10
- package/dist/patterns/marketplace-app-shell/marketplace-app-shell.d.ts.map +1 -1
- package/dist/patterns/payment-automation-upsell/index.js +1 -1
- package/dist/patterns/registration-form/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/patterns/signed-out-frame/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/ai-permission-notice-5vpblPCx.js +0 -171
- package/dist/_chunks/ai-permission-notice-5vpblPCx.js.map +0 -1
- package/dist/_chunks/alia-sidebar-DOei4Iyu.js +0 -1183
- package/dist/_chunks/alia-sidebar-DOei4Iyu.js.map +0 -1
- package/dist/_chunks/calendar-workspace-Du2ryaI-.js.map +0 -1
- package/dist/_chunks/chart-HsF1KHbx.js.map +0 -1
- package/dist/_chunks/color-picker-BRQ4Y9SO.js.map +0 -1
- package/dist/_chunks/dashboard-grid-DfEY2qci.js +0 -844
- package/dist/_chunks/dashboard-grid-DfEY2qci.js.map +0 -1
- package/dist/_chunks/date-picker-wRAcq2lt.js.map +0 -1
- package/dist/_chunks/date-range-picker-CtUOI38x.js.map +0 -1
- package/dist/_chunks/date-time-picker-CLeLKuv9.js.map +0 -1
- package/dist/_chunks/hover-card-BnTueNS2.js.map +0 -1
- package/dist/_chunks/link-2HokYuIi.js +0 -130
- package/dist/_chunks/link-2HokYuIi.js.map +0 -1
- package/dist/_chunks/list-RRN2TJ_7.js.map +0 -1
- package/dist/_chunks/marketplace-app-shell-Dcx-JEjg.js +0 -541
- package/dist/_chunks/marketplace-app-shell-Dcx-JEjg.js.map +0 -1
- package/dist/_chunks/message-tray-BB95DA82.js.map +0 -1
- package/dist/_chunks/non-modal-tab-exit-D2Bd93Bq.js +0 -65
- package/dist/_chunks/non-modal-tab-exit-D2Bd93Bq.js.map +0 -1
- package/dist/_chunks/notification-tray-__sJXnsz.js.map +0 -1
- package/dist/_chunks/panel-subview-BT-Apwgb.js.map +0 -1
- package/dist/_chunks/pdf-viewer-C3minW5b.js.map +0 -1
- package/dist/_chunks/phone-input-DxkHMYmu.js.map +0 -1
- package/dist/_chunks/popover-BI3oV3eY.js +0 -305
- package/dist/_chunks/popover-BI3oV3eY.js.map +0 -1
- package/dist/_chunks/product-hub-panel-BSSiGGG4.js.map +0 -1
- package/dist/_chunks/rich-text-editor-CkFfmA3v.js.map +0 -1
- package/dist/_chunks/scroll-area-ZtFCv9K7.js.map +0 -1
- package/dist/_chunks/search-bar-DQJS0wJN.js.map +0 -1
- package/dist/_chunks/sidebar-DLsG2AIk.js +0 -1349
- package/dist/_chunks/sidebar-DLsG2AIk.js.map +0 -1
- package/dist/_chunks/task-editor-ByyRu29Y.js.map +0 -1
- package/dist/_chunks/use-state-backed-input-C7ESmxKB.js +0 -59
- package/dist/_chunks/use-state-backed-input-C7ESmxKB.js.map +0 -1
- package/dist/_chunks/widget-picker-DXYBMTfe.js.map +0 -1
|
@@ -2,7 +2,7 @@ import { jsxs as c, jsx as e } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as S, useRef as k, useState as _, useEffect as A } from "react";
|
|
3
3
|
import { c as a } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as y } from "react-i18next";
|
|
5
|
-
import { S as E } from "./scroll-area-
|
|
5
|
+
import { S as E } from "./scroll-area-CY5SLYNw.js";
|
|
6
6
|
const L = a(
|
|
7
7
|
[
|
|
8
8
|
"ds:h-dvh ds:w-full",
|
|
@@ -131,4 +131,4 @@ z.displayName = "AppFrame";
|
|
|
131
131
|
export {
|
|
132
132
|
z as A
|
|
133
133
|
};
|
|
134
|
-
//# sourceMappingURL=app-frame-
|
|
134
|
+
//# sourceMappingURL=app-frame-CqmDh2v5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-frame-B-0O9CrU.js","sources":["../../src/components/app-frame/app-frame.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* AppFrame — the always-present application shell. */\n/* */\n/* Layout */\n/* ------ */\n/* */\n/* ┌───────────────────────────────────────────────────────────┐ */\n/* │ Header (100% inline-size, block-start) │ */\n/* ├──────────┬──────────────────────────────────┬──────────────┤ */\n/* │ Sidebar │ Main (<main>) │ endSidebar │ */\n/* │ │ │ (optional) │ */\n/* │ │ │ │ */\n/* ├──────────┴──────────────────────────────────┴──────────────┤ */\n/* │ Footer (optional) │ */\n/* └───────────────────────────────────────────────────────────┘ */\n/* */\n/* Header spans the full inline-size of the shell. Sidebar sits beneath */\n/* the header on the inline-start edge and shares the row with <main>. */\n/* `endSidebar`, when provided, sits on the inline-end edge of the same */\n/* row — used for co-pilot / assistant panels (e.g. AliaSidebar) that */\n/* should dock opposite the nav rail. Footer, when provided, spans the */\n/* full inline-size at the block-end. */\n/* */\n/* Responsive behaviour */\n/* --------------------- */\n/* ≥ md viewports: the sidebar slot renders inline-start of the row */\n/* below the header, sticky to the header's block-end, full remaining */\n/* viewport height. */\n/* < md viewports: the sidebar slot is hidden from the inline flow. */\n/* Consumers should control their sidebar's `state` to `'overlay'` */\n/* on small viewports (the Sidebar portals via Radix Dialog so it */\n/* renders outside AppFrame's subtree in that mode) and wire the */\n/* `<HeaderMenuButton>` to toggle it. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ScrollArea } from '../scroll-area/scroll-area';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n// Canonical app-shell layout: the root is a VIEWPORT-SIZED flex-col with\n// its own overflow clamp. Header and the row fill it together. The only\n// thing that scrolls is the content region — a kit ScrollArea nested inside\n// <main> — so the header never leaves the top and the sidebar never needs\n// position: sticky. (Using a ScrollArea rather than letting <main> scroll\n// natively gives the main content the same 8px branded overlay scrollbar as\n// the Sidebar and ToolRail, instead of the wider OS-native bar.) This matches\n// the way Gmail / Linear / Notion frame their app surfaces and avoids the\n// flex-item-sticky edge cases that position: sticky has inside a\n// column-flex container.\n//\n// Because the viewport itself never scrolls in this model, the Header's\n// built-in IntersectionObserver (which watches a sentinel against the\n// viewport) cannot detect scroll. AppFrame instead tracks the main\n// ScrollArea viewport's scrollTop, reflects it onto the root via\n// `data-app-scrolled`, and the descendant selectors below drive the\n// `<header role=\"banner\">` border and shadow — producing the same elevation\n// the Header would show in a viewport-scroll context.\nconst rootVariants = cva(\n [\n 'ds:h-dvh ds:w-full',\n 'ds:flex ds:flex-col',\n 'ds:overflow-hidden',\n 'ds:bg-[var(--background)] ds:text-[color:var(--foreground)]',\n // Elevation cascade driven by main's scrollTop (data-app-scrolled).\n // Mirrors the Header's native scroll-linked recipe (see `Brand/Shadows`\n // — one tier up from rest, never two) so the banner looks identical\n // whether it's in a viewport-scroll context (sticky) or slotted into\n // AppFrame where <main> owns the scroll.\n 'ds:data-[app-scrolled=true]:[&_[role=banner]]:shadow-[var(--shadow-md)]',\n 'ds:data-[app-scrolled=true]:[&_[role=banner]]:[border-block-end-color:var(--border)]',\n // Forced-colors: UA strips box-shadow, so the border is the only\n // separation cue. Always render it.\n 'ds:forced-colors:[&_[role=banner]]:[border-block-end-color:CanvasText]',\n // Print: strip shadow, keep border so the banner still reads on paper.\n 'ds:print:[&_[role=banner]]:shadow-none',\n 'ds:print:[&_[role=banner]]:[border-block-end-color:var(--border)]',\n ].join(' '),\n);\n\nconst rowVariants = cva(\n ['ds:flex ds:flex-1 ds:items-stretch ds:min-h-0'].join(' '),\n);\n\nconst sidebarSlotVariants = cva(\n [\n // Hidden in the inline flow on mobile — consumers should flip their\n // Sidebar into overlay mode at narrow viewports, where it portals via\n // Radix Dialog and therefore renders outside AppFrame entirely.\n 'ds:hidden ds:md:flex',\n 'ds:shrink-0',\n // The rail fills the row's full height because the row is `flex\n // items-stretch`. No sticky needed — the row itself never scrolls.\n 'ds:h-full',\n ].join(' '),\n);\n\n// Inline-end slot — same hide-on-mobile behaviour as the nav rail because\n// a 22rem co-pilot panel can't share a phone viewport. Consuming apps\n// should flip Alia (or any inline-end panel) to its overlay/popout mode\n// at narrow viewports.\nconst endSidebarSlotVariants = cva(\n ['ds:hidden ds:md:flex', 'ds:shrink-0', 'ds:h-full'].join(' '),\n);\n\n// <main> is the landmark + skip-link target, but it NO LONGER owns the scroll.\n// A kit `ScrollArea` inside it owns the scroll instead, so the main content's\n// scrollbar is the same 8px branded overlay as the Sidebar and ToolRail\n// (both ScrollArea) rather than the wider OS-native bar that made \"the general\n// scroll area look bigger\". <main> is a flex-col so the ScrollArea (flex-1\n// min-h-0) fills its height; the body still never scrolls — only the viewport.\nconst mainVariants = cva(\n [\n 'ds:flex-1 ds:min-w-0',\n 'ds:flex ds:flex-col ds:min-h-0',\n // Focusable via the header's SkipLink — tabIndex={-1} is on the\n // element itself so keyboard users land inside the main region.\n 'ds:focus:outline-none',\n ].join(' '),\n);\n\n// Inner content wrapper INSIDE the ScrollArea viewport. It owns the `padded`\n// inset so the scrollbar sits at the viewport's true edge (matching the\n// ScrollArea convention used by the rail/sidebar) and the padding scrolls\n// with the content.\nconst mainContentVariants = cva('', {\n variants: {\n padded: {\n true: [\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n ].join(' '),\n false: '',\n },\n },\n defaultVariants: { padded: true },\n});\n\nconst footerSlotVariants = cva('ds:shrink-0');\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport interface AppFrameProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>,\n VariantProps<typeof mainContentVariants> {\n /** `<Header>` instance rendered full-width at the block-start of the shell. */\n header: ReactNode;\n /** `<Sidebar>` instance rendered inline-start of the row beneath the header on ≥ md viewports. */\n sidebar: ReactNode;\n /** Main content — rendered inside a `<main>` landmark. */\n children: ReactNode;\n /** Optional inline-end docked panel (typically `<AliaSidebar />`) sharing the same row as the main region on ≥ md viewports. Hidden on narrow viewports — consumers should flip to an overlay/popout mode there. */\n endSidebar?: ReactNode;\n /** Optional block-end footer — renders full-width below the sidebar + main row. */\n footer?: ReactNode;\n /**\n * Id applied to the `<main>` element so `<HeaderSkipLink href=\"#{mainId}\" />`\n * can target it. Must be a valid HTML id (letters, digits, `-`, `_`, no\n * spaces). Defaults to `'main-content'`.\n */\n mainId?: string;\n /**\n * Override the landmark's accessible name. Defaults to the i18n'd\n * `ui.navigation.main.label` (\"Main content\").\n */\n mainAriaLabel?: string;\n /** Extra classes applied to the `<main>` landmark. */\n mainClassName?: string;\n}\n\nexport const AppFrame = forwardRef<HTMLDivElement, AppFrameProps>(\n (\n {\n header,\n sidebar,\n children,\n endSidebar,\n footer,\n mainId = 'main-content',\n mainAriaLabel,\n padded = true,\n className,\n mainClassName,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const mainLabel =\n mainAriaLabel ?? t('navigation.main.label', 'Main content');\n\n // The ScrollArea inside <main> owns the scroll, so the header-elevation\n // cascade (data-app-scrolled) is driven off the ScrollArea's viewport\n // rather than <main>. ScrollArea forwards its ref to that viewport.\n const mainViewportRef = useRef<HTMLDivElement>(null);\n const [mainScrolled, setMainScrolled] = useState(false);\n useEffect(() => {\n const viewport = mainViewportRef.current;\n if (!viewport) return;\n const sync = () => {\n const next = viewport.scrollTop > 0;\n setMainScrolled((prev) => (prev === next ? prev : next));\n };\n sync();\n viewport.addEventListener('scroll', sync, { passive: true });\n return () => viewport.removeEventListener('scroll', sync);\n }, []);\n\n return (\n <div\n ref={ref}\n data-app-scrolled={mainScrolled ? 'true' : undefined}\n data-component=\"app-frame\"\n className={rootVariants({ className })}\n {...rest}\n >\n {/* Header is rendered as a direct flex child — NOT wrapped in a slot\n div — so it sits at the block-start of the shell. The root's\n `overflow-hidden` keeps it pinned; no `position: sticky` needed. */}\n {header}\n <div className={rowVariants()} data-app-frame-slot=\"row\">\n <div className={sidebarSlotVariants()} data-app-frame-slot=\"sidebar\">\n {sidebar}\n </div>\n <main\n id={mainId}\n tabIndex={-1}\n aria-label={mainLabel}\n className={mainVariants({ className: mainClassName })}\n >\n {/* A tab stop for keyboard scrolling, named by the landmark. A group,\n not a region: an <aside> in the content must sit directly under\n <main> (axe landmark-complementary-is-top-level). */}\n <ScrollArea\n ref={mainViewportRef}\n orientation=\"vertical\"\n role=\"group\"\n aria-labelledby={mainId}\n className=\"ds:flex-1 ds:min-h-0\"\n >\n <div className={mainContentVariants({ padded })}>{children}</div>\n </ScrollArea>\n </main>\n {endSidebar ? (\n <div\n className={endSidebarSlotVariants()}\n data-app-frame-slot=\"end-sidebar\"\n >\n {endSidebar}\n </div>\n ) : null}\n </div>\n {footer ? (\n <div className={footerSlotVariants()} data-app-frame-slot=\"footer\">\n {footer}\n </div>\n ) : null}\n </div>\n );\n },\n);\nAppFrame.displayName = 'AppFrame';\n"],"names":["rootVariants","cva","rowVariants","sidebarSlotVariants","endSidebarSlotVariants","mainVariants","mainContentVariants","footerSlotVariants","AppFrame","forwardRef","header","sidebar","children","endSidebar","footer","mainId","mainAriaLabel","padded","className","mainClassName","rest","ref","t","useTranslation","mainLabel","mainViewportRef","useRef","mainScrolled","setMainScrolled","useState","useEffect","viewport","sync","next","prev","jsxs","jsx","ScrollArea"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-frame-CqmDh2v5.js","sources":["../../src/components/app-frame/app-frame.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* AppFrame — the always-present application shell. */\n/* */\n/* Layout */\n/* ------ */\n/* */\n/* ┌───────────────────────────────────────────────────────────┐ */\n/* │ Header (100% inline-size, block-start) │ */\n/* ├──────────┬──────────────────────────────────┬──────────────┤ */\n/* │ Sidebar │ Main (<main>) │ endSidebar │ */\n/* │ │ │ (optional) │ */\n/* │ │ │ │ */\n/* ├──────────┴──────────────────────────────────┴──────────────┤ */\n/* │ Footer (optional) │ */\n/* └───────────────────────────────────────────────────────────┘ */\n/* */\n/* Header spans the full inline-size of the shell. Sidebar sits beneath */\n/* the header on the inline-start edge and shares the row with <main>. */\n/* `endSidebar`, when provided, sits on the inline-end edge of the same */\n/* row — used for co-pilot / assistant panels (e.g. AliaSidebar) that */\n/* should dock opposite the nav rail. Footer, when provided, spans the */\n/* full inline-size at the block-end. */\n/* */\n/* Responsive behaviour */\n/* --------------------- */\n/* ≥ md viewports: the sidebar slot renders inline-start of the row */\n/* below the header, sticky to the header's block-end, full remaining */\n/* viewport height. */\n/* < md viewports: the sidebar slot is hidden from the inline flow. */\n/* Consumers should control their sidebar's `state` to `'overlay'` */\n/* on small viewports (the Sidebar portals via Radix Dialog so it */\n/* renders outside AppFrame's subtree in that mode) and wire the */\n/* `<HeaderMenuButton>` to toggle it. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ScrollArea } from '../scroll-area/scroll-area';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n// Canonical app-shell layout: the root is a VIEWPORT-SIZED flex-col with\n// its own overflow clamp. Header and the row fill it together. The only\n// thing that scrolls is the content region — a kit ScrollArea nested inside\n// <main> — so the header never leaves the top and the sidebar never needs\n// position: sticky. (Using a ScrollArea rather than letting <main> scroll\n// natively gives the main content the same 8px branded overlay scrollbar as\n// the Sidebar and ToolRail, instead of the wider OS-native bar.) This matches\n// the way Gmail / Linear / Notion frame their app surfaces and avoids the\n// flex-item-sticky edge cases that position: sticky has inside a\n// column-flex container.\n//\n// Because the viewport itself never scrolls in this model, the Header's\n// built-in IntersectionObserver (which watches a sentinel against the\n// viewport) cannot detect scroll. AppFrame instead tracks the main\n// ScrollArea viewport's scrollTop, reflects it onto the root via\n// `data-app-scrolled`, and the descendant selectors below drive the\n// `<header role=\"banner\">` border and shadow — producing the same elevation\n// the Header would show in a viewport-scroll context.\nconst rootVariants = cva(\n [\n 'ds:h-dvh ds:w-full',\n 'ds:flex ds:flex-col',\n 'ds:overflow-hidden',\n 'ds:bg-[var(--background)] ds:text-[color:var(--foreground)]',\n // Elevation cascade driven by main's scrollTop (data-app-scrolled).\n // Mirrors the Header's native scroll-linked recipe (see `Brand/Shadows`\n // — one tier up from rest, never two) so the banner looks identical\n // whether it's in a viewport-scroll context (sticky) or slotted into\n // AppFrame where <main> owns the scroll.\n 'ds:data-[app-scrolled=true]:[&_[role=banner]]:shadow-[var(--shadow-md)]',\n 'ds:data-[app-scrolled=true]:[&_[role=banner]]:[border-block-end-color:var(--border)]',\n // Forced-colors: UA strips box-shadow, so the border is the only\n // separation cue. Always render it.\n 'ds:forced-colors:[&_[role=banner]]:[border-block-end-color:CanvasText]',\n // Print: strip shadow, keep border so the banner still reads on paper.\n 'ds:print:[&_[role=banner]]:shadow-none',\n 'ds:print:[&_[role=banner]]:[border-block-end-color:var(--border)]',\n ].join(' '),\n);\n\nconst rowVariants = cva(\n ['ds:flex ds:flex-1 ds:items-stretch ds:min-h-0'].join(' '),\n);\n\nconst sidebarSlotVariants = cva(\n [\n // Hidden in the inline flow on mobile — consumers should flip their\n // Sidebar into overlay mode at narrow viewports, where it portals via\n // Radix Dialog and therefore renders outside AppFrame entirely.\n 'ds:hidden ds:md:flex',\n 'ds:shrink-0',\n // The rail fills the row's full height because the row is `flex\n // items-stretch`. No sticky needed — the row itself never scrolls.\n 'ds:h-full',\n ].join(' '),\n);\n\n// Inline-end slot — same hide-on-mobile behaviour as the nav rail because\n// a 22rem co-pilot panel can't share a phone viewport. Consuming apps\n// should flip Alia (or any inline-end panel) to its overlay/popout mode\n// at narrow viewports.\nconst endSidebarSlotVariants = cva(\n ['ds:hidden ds:md:flex', 'ds:shrink-0', 'ds:h-full'].join(' '),\n);\n\n// <main> is the landmark + skip-link target, but it NO LONGER owns the scroll.\n// A kit `ScrollArea` inside it owns the scroll instead, so the main content's\n// scrollbar is the same 8px branded overlay as the Sidebar and ToolRail\n// (both ScrollArea) rather than the wider OS-native bar that made \"the general\n// scroll area look bigger\". <main> is a flex-col so the ScrollArea (flex-1\n// min-h-0) fills its height; the body still never scrolls — only the viewport.\nconst mainVariants = cva(\n [\n 'ds:flex-1 ds:min-w-0',\n 'ds:flex ds:flex-col ds:min-h-0',\n // Focusable via the header's SkipLink — tabIndex={-1} is on the\n // element itself so keyboard users land inside the main region.\n 'ds:focus:outline-none',\n ].join(' '),\n);\n\n// Inner content wrapper INSIDE the ScrollArea viewport. It owns the `padded`\n// inset so the scrollbar sits at the viewport's true edge (matching the\n// ScrollArea convention used by the rail/sidebar) and the padding scrolls\n// with the content.\nconst mainContentVariants = cva('', {\n variants: {\n padded: {\n true: [\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n ].join(' '),\n false: '',\n },\n },\n defaultVariants: { padded: true },\n});\n\nconst footerSlotVariants = cva('ds:shrink-0');\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport interface AppFrameProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'children'>,\n VariantProps<typeof mainContentVariants> {\n /** `<Header>` instance rendered full-width at the block-start of the shell. */\n header: ReactNode;\n /** `<Sidebar>` instance rendered inline-start of the row beneath the header on ≥ md viewports. */\n sidebar: ReactNode;\n /** Main content — rendered inside a `<main>` landmark. */\n children: ReactNode;\n /** Optional inline-end docked panel (typically `<AliaSidebar />`) sharing the same row as the main region on ≥ md viewports. Hidden on narrow viewports — consumers should flip to an overlay/popout mode there. */\n endSidebar?: ReactNode;\n /** Optional block-end footer — renders full-width below the sidebar + main row. */\n footer?: ReactNode;\n /**\n * Id applied to the `<main>` element so `<HeaderSkipLink href=\"#{mainId}\" />`\n * can target it. Must be a valid HTML id (letters, digits, `-`, `_`, no\n * spaces). Defaults to `'main-content'`.\n */\n mainId?: string;\n /**\n * Override the landmark's accessible name. Defaults to the i18n'd\n * `ui.navigation.main.label` (\"Main content\").\n */\n mainAriaLabel?: string;\n /** Extra classes applied to the `<main>` landmark. */\n mainClassName?: string;\n}\n\nexport const AppFrame = forwardRef<HTMLDivElement, AppFrameProps>(\n (\n {\n header,\n sidebar,\n children,\n endSidebar,\n footer,\n mainId = 'main-content',\n mainAriaLabel,\n padded = true,\n className,\n mainClassName,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const mainLabel =\n mainAriaLabel ?? t('navigation.main.label', 'Main content');\n\n // The ScrollArea inside <main> owns the scroll, so the header-elevation\n // cascade (data-app-scrolled) is driven off the ScrollArea's viewport\n // rather than <main>. ScrollArea forwards its ref to that viewport.\n const mainViewportRef = useRef<HTMLDivElement>(null);\n const [mainScrolled, setMainScrolled] = useState(false);\n useEffect(() => {\n const viewport = mainViewportRef.current;\n if (!viewport) return;\n const sync = () => {\n const next = viewport.scrollTop > 0;\n setMainScrolled((prev) => (prev === next ? prev : next));\n };\n sync();\n viewport.addEventListener('scroll', sync, { passive: true });\n return () => viewport.removeEventListener('scroll', sync);\n }, []);\n\n return (\n <div\n ref={ref}\n data-app-scrolled={mainScrolled ? 'true' : undefined}\n data-component=\"app-frame\"\n className={rootVariants({ className })}\n {...rest}\n >\n {/* Header is rendered as a direct flex child — NOT wrapped in a slot\n div — so it sits at the block-start of the shell. The root's\n `overflow-hidden` keeps it pinned; no `position: sticky` needed. */}\n {header}\n <div className={rowVariants()} data-app-frame-slot=\"row\">\n <div className={sidebarSlotVariants()} data-app-frame-slot=\"sidebar\">\n {sidebar}\n </div>\n <main\n id={mainId}\n tabIndex={-1}\n aria-label={mainLabel}\n className={mainVariants({ className: mainClassName })}\n >\n {/* A tab stop for keyboard scrolling, named by the landmark. A group,\n not a region: an <aside> in the content must sit directly under\n <main> (axe landmark-complementary-is-top-level). */}\n <ScrollArea\n ref={mainViewportRef}\n orientation=\"vertical\"\n role=\"group\"\n aria-labelledby={mainId}\n className=\"ds:flex-1 ds:min-h-0\"\n >\n <div className={mainContentVariants({ padded })}>{children}</div>\n </ScrollArea>\n </main>\n {endSidebar ? (\n <div\n className={endSidebarSlotVariants()}\n data-app-frame-slot=\"end-sidebar\"\n >\n {endSidebar}\n </div>\n ) : null}\n </div>\n {footer ? (\n <div className={footerSlotVariants()} data-app-frame-slot=\"footer\">\n {footer}\n </div>\n ) : null}\n </div>\n );\n },\n);\nAppFrame.displayName = 'AppFrame';\n"],"names":["rootVariants","cva","rowVariants","sidebarSlotVariants","endSidebarSlotVariants","mainVariants","mainContentVariants","footerSlotVariants","AppFrame","forwardRef","header","sidebar","children","endSidebar","footer","mainId","mainAriaLabel","padded","className","mainClassName","rest","ref","t","useTranslation","mainLabel","mainViewportRef","useRef","mainScrolled","setMainScrolled","useState","useEffect","viewport","sync","next","prev","jsxs","jsx","ScrollArea"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { c as V } from "./index-D2ZczOXr.js";
|
|
|
4
4
|
import { useTranslation as y } from "react-i18next";
|
|
5
5
|
import { A as z } from "./avatar-WZY3eGE7.js";
|
|
6
6
|
import { D as l } from "./description-list-DkLeHiew.js";
|
|
7
|
-
import { H as E } from "./hover-card-
|
|
7
|
+
import { H as E } from "./hover-card-U_ZYoh1n.js";
|
|
8
8
|
import { a as H } from "./workflow-status-BT27_fQp.js";
|
|
9
9
|
import { C as I } from "./clock-Drd4Wtis.js";
|
|
10
10
|
import { V as S } from "./video-BheNGvsu.js";
|
|
@@ -120,4 +120,4 @@ T.displayName = "AppointmentPeek";
|
|
|
120
120
|
export {
|
|
121
121
|
T as A
|
|
122
122
|
};
|
|
123
|
-
//# sourceMappingURL=appointment-peek-
|
|
123
|
+
//# sourceMappingURL=appointment-peek-WvNbE4JG.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appointment-peek-BIZaDeCi.js","sources":["../../src/components/appointment-peek/appointment-peek.tsx"],"sourcesContent":["import {\n forwardRef,\n isValidElement,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { Armchair, Clock, EyeOff, Video } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Avatar } from '../avatar';\nimport { DescriptionList } from '../description-list';\nimport { HoverCard } from '../hover-card';\nimport { WorkflowStatusDisplay } from '../workflow-status';\nimport {\n appointmentStateWorkflow,\n type AppointmentState,\n} from '../_shared/entity-card';\n\n/* -------------------------------------------------------------------- */\n/* AppointmentPeek */\n/* */\n/* The body of a calendar hover card: who, when, where, and the status */\n/* in the kit's one status face. Renders inside `HoverCard.Content`; its */\n/* name is a `HoverCard.Heading`, so the card takes its accessible name */\n/* from the patient without the host wiring it. */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n 'ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-sm)]',\n);\n\nexport interface AppointmentPeekDetail {\n /** Leading glyph, decorative. */\n icon?: ReactNode;\n /** The term, already translated: \"Care\", \"Operator\". */\n label: string;\n value: ReactNode;\n}\n\nexport interface AppointmentPeekProps extends HTMLAttributes<HTMLDivElement> {\n /** Patient name, or the event title for an appointment with no patient. */\n name: string;\n /** Photo for the avatar; initials are drawn from `name` without one. */\n avatarSrc?: string;\n /** Host-formatted time range, e.g. \"09:30–11:00\". */\n time: string;\n /** Chair or room, already translated. With `telehealth`, the visit type. */\n location?: string;\n /** Swaps the chair glyph for a video camera. */\n telehealth?: boolean;\n /**\n * Appointment status, shown through `WorkflowStatusDisplay`. Leave it out\n * when the host has none recorded: no status is not the same as\n * confirmed, so the card shows no status face at all.\n */\n status?: AppointmentState;\n /**\n * Override the status caption, e.g. \"Arrived · waiting 12 min\". Still shown\n * under `privacy`, so keep it free of patient data. Ignored without\n * `status`.\n */\n statusLabel?: string;\n /** Extra rows after time and location: care, operator. */\n details?: AppointmentPeekDetail[];\n /** Event suffix fallback when appointment metadata is absent. Hidden in privacy. */\n treatment?: string;\n /** Indicator chips (Badges): booked online, anamnesis. Never status. */\n flags?: ReactNode;\n /**\n * Masks the name and drops everything personal: avatar, details and\n * flags. Time, place and status stay; they\n * are not patient data.\n */\n privacy?: boolean;\n}\n\nexport const AppointmentPeek = forwardRef<HTMLDivElement, AppointmentPeekProps>(\n (\n {\n name,\n avatarSrc,\n time,\n location,\n telehealth = false,\n status,\n statusLabel,\n details,\n treatment,\n flags,\n privacy = false,\n className,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const workflow = status ? appointmentStateWorkflow(status) : null;\n const StatusIcon = workflow?.Icon;\n\n const LocationIcon = telehealth ? Video : Armchair;\n const showClinical = !privacy;\n\n const rows: {\n icon: ReactElement | null;\n label: string;\n value: ReactNode;\n }[] = [\n { icon: <Clock />, label: t('appointmentPeek.time'), value: time },\n ...(location\n ? [\n {\n icon: <LocationIcon />,\n label: t('appointmentPeek.location'),\n value: location,\n },\n ]\n : []),\n ...(showClinical && treatment\n ? [\n {\n icon: null,\n label: t('calendarWorkspace.details.care'),\n value: treatment,\n },\n ]\n : []),\n ...(showClinical && details\n ? details.map((detail) => ({\n icon: isValidElement(detail.icon) ? detail.icon : null,\n label: detail.label,\n value: detail.value,\n }))\n : []),\n ];\n\n return (\n <div\n ref={ref}\n data-component=\"appointment-peek\"\n data-status={status}\n className={rootVariants({ className })}\n {...props}\n >\n {/* Avatar, name and the indicator chips together, every fact on its\n own row below, status last: the same identity block as\n PatientDetails. */}\n <div className=\"ds:flex ds:min-w-0 ds:items-start ds:gap-[var(--spacing-sm)]\">\n {privacy ? null : (\n <Avatar\n size=\"sm\"\n name={name}\n src={avatarSrc}\n aria-hidden=\"true\"\n className=\"ds:shrink-0\"\n />\n )}\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <HoverCard.Heading className=\"ds:min-w-0\">\n {privacy ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <EyeOff\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0\"\n />\n {t('appointmentPeek.hiddenName')}\n </span>\n ) : (\n name\n )}\n </HoverCard.Heading>\n {showClinical && flags ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {flags}\n </div>\n ) : null}\n </div>\n </div>\n\n <DescriptionList\n layout=\"inline\"\n density=\"compact\"\n divider=\"none\"\n // Label icons in the accent, as in PatientDetails.\n className=\"ds:[--description-list-icon-color:var(--accent)]\"\n >\n {rows.map((row, index) => (\n <DescriptionList.Row key={index} icon={row.icon}>\n <DescriptionList.Term>{row.label}</DescriptionList.Term>\n <DescriptionList.Detail>{row.value}</DescriptionList.Detail>\n </DescriptionList.Row>\n ))}\n </DescriptionList>\n\n {/* The kit's one status face: the same display the details panel,\n AppointmentCard and the history use, so a status never reads\n differently on the grid. Last, so the card reads who, what, then\n where it stands. Nothing at all when none is recorded. */}\n {status && workflow && StatusIcon ? (\n <div data-slot=\"workflow\">\n <WorkflowStatusDisplay\n size=\"sm\"\n value={status}\n option={{\n value: status,\n label: statusLabel ?? t(`appointmentCard.state.${status}`),\n icon: <StatusIcon aria-hidden=\"true\" />,\n tone: workflow.tone,\n }}\n />\n </div>\n ) : null}\n </div>\n );\n },\n);\nAppointmentPeek.displayName = 'AppointmentPeek';\n"],"names":["rootVariants","cva","AppointmentPeek","forwardRef","name","avatarSrc","time","location","telehealth","status","statusLabel","details","treatment","flags","privacy","className","props","ref","t","useTranslation","workflow","appointmentStateWorkflow","StatusIcon","LocationIcon","Video","Armchair","showClinical","rows","jsx","Clock","detail","isValidElement","jsxs","Avatar","HoverCard","EyeOff","DescriptionList","row","index","WorkflowStatusDisplay"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"appointment-peek-WvNbE4JG.js","sources":["../../src/components/appointment-peek/appointment-peek.tsx"],"sourcesContent":["import {\n forwardRef,\n isValidElement,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { Armchair, Clock, EyeOff, Video } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Avatar } from '../avatar';\nimport { DescriptionList } from '../description-list';\nimport { HoverCard } from '../hover-card';\nimport { WorkflowStatusDisplay } from '../workflow-status';\nimport {\n appointmentStateWorkflow,\n type AppointmentState,\n} from '../_shared/entity-card';\n\n/* -------------------------------------------------------------------- */\n/* AppointmentPeek */\n/* */\n/* The body of a calendar hover card: who, when, where, and the status */\n/* in the kit's one status face. Renders inside `HoverCard.Content`; its */\n/* name is a `HoverCard.Heading`, so the card takes its accessible name */\n/* from the patient without the host wiring it. */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n 'ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-sm)]',\n);\n\nexport interface AppointmentPeekDetail {\n /** Leading glyph, decorative. */\n icon?: ReactNode;\n /** The term, already translated: \"Care\", \"Operator\". */\n label: string;\n value: ReactNode;\n}\n\nexport interface AppointmentPeekProps extends HTMLAttributes<HTMLDivElement> {\n /** Patient name, or the event title for an appointment with no patient. */\n name: string;\n /** Photo for the avatar; initials are drawn from `name` without one. */\n avatarSrc?: string;\n /** Host-formatted time range, e.g. \"09:30–11:00\". */\n time: string;\n /** Chair or room, already translated. With `telehealth`, the visit type. */\n location?: string;\n /** Swaps the chair glyph for a video camera. */\n telehealth?: boolean;\n /**\n * Appointment status, shown through `WorkflowStatusDisplay`. Leave it out\n * when the host has none recorded: no status is not the same as\n * confirmed, so the card shows no status face at all.\n */\n status?: AppointmentState;\n /**\n * Override the status caption, e.g. \"Arrived · waiting 12 min\". Still shown\n * under `privacy`, so keep it free of patient data. Ignored without\n * `status`.\n */\n statusLabel?: string;\n /** Extra rows after time and location: care, operator. */\n details?: AppointmentPeekDetail[];\n /** Event suffix fallback when appointment metadata is absent. Hidden in privacy. */\n treatment?: string;\n /** Indicator chips (Badges): booked online, anamnesis. Never status. */\n flags?: ReactNode;\n /**\n * Masks the name and drops everything personal: avatar, details and\n * flags. Time, place and status stay; they\n * are not patient data.\n */\n privacy?: boolean;\n}\n\nexport const AppointmentPeek = forwardRef<HTMLDivElement, AppointmentPeekProps>(\n (\n {\n name,\n avatarSrc,\n time,\n location,\n telehealth = false,\n status,\n statusLabel,\n details,\n treatment,\n flags,\n privacy = false,\n className,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const workflow = status ? appointmentStateWorkflow(status) : null;\n const StatusIcon = workflow?.Icon;\n\n const LocationIcon = telehealth ? Video : Armchair;\n const showClinical = !privacy;\n\n const rows: {\n icon: ReactElement | null;\n label: string;\n value: ReactNode;\n }[] = [\n { icon: <Clock />, label: t('appointmentPeek.time'), value: time },\n ...(location\n ? [\n {\n icon: <LocationIcon />,\n label: t('appointmentPeek.location'),\n value: location,\n },\n ]\n : []),\n ...(showClinical && treatment\n ? [\n {\n icon: null,\n label: t('calendarWorkspace.details.care'),\n value: treatment,\n },\n ]\n : []),\n ...(showClinical && details\n ? details.map((detail) => ({\n icon: isValidElement(detail.icon) ? detail.icon : null,\n label: detail.label,\n value: detail.value,\n }))\n : []),\n ];\n\n return (\n <div\n ref={ref}\n data-component=\"appointment-peek\"\n data-status={status}\n className={rootVariants({ className })}\n {...props}\n >\n {/* Avatar, name and the indicator chips together, every fact on its\n own row below, status last: the same identity block as\n PatientDetails. */}\n <div className=\"ds:flex ds:min-w-0 ds:items-start ds:gap-[var(--spacing-sm)]\">\n {privacy ? null : (\n <Avatar\n size=\"sm\"\n name={name}\n src={avatarSrc}\n aria-hidden=\"true\"\n className=\"ds:shrink-0\"\n />\n )}\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <HoverCard.Heading className=\"ds:min-w-0\">\n {privacy ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <EyeOff\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0\"\n />\n {t('appointmentPeek.hiddenName')}\n </span>\n ) : (\n name\n )}\n </HoverCard.Heading>\n {showClinical && flags ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {flags}\n </div>\n ) : null}\n </div>\n </div>\n\n <DescriptionList\n layout=\"inline\"\n density=\"compact\"\n divider=\"none\"\n // Label icons in the accent, as in PatientDetails.\n className=\"ds:[--description-list-icon-color:var(--accent)]\"\n >\n {rows.map((row, index) => (\n <DescriptionList.Row key={index} icon={row.icon}>\n <DescriptionList.Term>{row.label}</DescriptionList.Term>\n <DescriptionList.Detail>{row.value}</DescriptionList.Detail>\n </DescriptionList.Row>\n ))}\n </DescriptionList>\n\n {/* The kit's one status face: the same display the details panel,\n AppointmentCard and the history use, so a status never reads\n differently on the grid. Last, so the card reads who, what, then\n where it stands. Nothing at all when none is recorded. */}\n {status && workflow && StatusIcon ? (\n <div data-slot=\"workflow\">\n <WorkflowStatusDisplay\n size=\"sm\"\n value={status}\n option={{\n value: status,\n label: statusLabel ?? t(`appointmentCard.state.${status}`),\n icon: <StatusIcon aria-hidden=\"true\" />,\n tone: workflow.tone,\n }}\n />\n </div>\n ) : null}\n </div>\n );\n },\n);\nAppointmentPeek.displayName = 'AppointmentPeek';\n"],"names":["rootVariants","cva","AppointmentPeek","forwardRef","name","avatarSrc","time","location","telehealth","status","statusLabel","details","treatment","flags","privacy","className","props","ref","t","useTranslation","workflow","appointmentStateWorkflow","StatusIcon","LocationIcon","Video","Armchair","showClinical","rows","jsx","Clock","detail","isValidElement","jsxs","Avatar","HoverCard","EyeOff","DescriptionList","row","index","WorkflowStatusDisplay"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { useTranslation as Ae } from "react-i18next";
|
|
|
5
5
|
import { A as ne } from "./appointment-card-Dh3fAcyf.js";
|
|
6
6
|
import { B as P } from "./button-Bn16lcFM.js";
|
|
7
7
|
import { B as Be } from "./button-group-CWlwR-A5.js";
|
|
8
|
-
import { D as Ke } from "./date-picker-
|
|
8
|
+
import { D as Ke } from "./date-picker-BSZuKo13.js";
|
|
9
9
|
import { P as Ee } from "./panel-header-D_mTdhUp.js";
|
|
10
10
|
import { S as Ye } from "./skeleton-B1KTdJ4N.js";
|
|
11
11
|
import { E as $e } from "./empty-state-gNG3qYCX.js";
|
|
@@ -449,4 +449,4 @@ export {
|
|
|
449
449
|
Ze as A,
|
|
450
450
|
Oe as a
|
|
451
451
|
};
|
|
452
|
-
//# sourceMappingURL=appointment-timeline-
|
|
452
|
+
//# sourceMappingURL=appointment-timeline-Z0494xO-.js.map
|
package/dist/_chunks/{appointment-timeline-DmqYEIT9.js.map → appointment-timeline-Z0494xO-.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appointment-timeline-DmqYEIT9.js","sources":["../../src/components/appointment-timeline/appointment-timeline.agent.ts","../../src/components/appointment-timeline/appointment-timeline.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — AppointmentTimeline. */\n/* */\n/* Timeline surface: read appointment ids + lifecycle state (never */\n/* patient names / treatments), activate a row through the curated handle, */\n/* and re-anchor the scroll on today. In-page (no open/close). */\n/* `showPatient` is presentation only — it changes which name each row */\n/* leads with, never what the adapter reads or exposes. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AppointmentTimelineHandle } from './appointment-timeline';\n\nexport const appointmentTimelineAgent: AgentAdapter<AppointmentTimelineHandle> =\n {\n id: 'appointment-timeline',\n // 'pick' backs select_item (non-persisting activation through\n // onOpenAppointment); 'scroll' backs jump_to_today, which re-anchors the\n // scroll viewport (mirrors practice-results' scroll_to_result).\n capabilities: ['scroll', 'pick'],\n state: {\n items: {\n type: 'Array<{ id: string; state: string }>',\n descriptionKey: 'ui.agent.appointmentTimeline.state.items',\n description:\n 'Currently-rendered appointments. Ids + lifecycle state only — never patient identity.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\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.appointmentTimeline.actions.selectItem',\n description: 'Activate the appointment with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n jump_to_today: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.appointmentTimeline.actions.jumpToToday',\n description: \"Re-anchor the timeline scroll on today's appointments.\",\n invoke: (handle) => {\n handle.jumpToToday();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'appointment-timeline',\n description: 'Marks the AppointmentTimeline wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific timeline from the agent.',\n },\n item: {\n attr: 'data-appointment-id',\n description:\n 'Stable appointment id emitted on each rendered AppointmentCard inside the timeline.',\n },\n },\n };\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { CalendarDays } from 'lucide-react';\nimport { AppointmentCard, type AppointmentItem } from '../appointment-card';\nimport { Button } from '../button';\nimport { ButtonGroup } from '../button-group';\nimport { DatePicker } from '../date-picker';\nimport { PanelHeader } from '../panel-header';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { usePrefersReducedMotion } from '../../hooks/use-prefers-reduced-motion';\nimport { REFLOW_ROW_CLASS, useListReflow } from '../../hooks/use-list-reflow';\nimport { useExitTransition } from '../../hooks/use-exit-transition';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { appointmentTimelineAgent } from './appointment-timeline.agent';\n\n/* -------------------------------------------------------------------- */\n/* AppointmentTimeline */\n/* */\n/* A vertical, day-grouped appointment timeline for the Control Room */\n/* rail. Unlike AppointmentTray (a bordered card of a flat list), this */\n/* fills the rail edge-to-edge: appointments are grouped under day */\n/* headers, the scroll is anchored on TODAY, and it scrolls infinitely */\n/* into the past and future — the consumer feeds more via onLoadEarlier */\n/* / onLoadLater as either edge is reached (scroll position is preserved */\n/* when earlier items prepend). Date-filter presets + a jump-to-date */\n/* picker re-anchor the scroll. Top + bottom transparent gradient fades */\n/* (a block-axis mask) signal more content beyond each edge. */\n/* */\n/* Each row reuses AppointmentCard (care-plan + chair chips included). */\n/* All visible text flows through useTranslation('ui') against the */\n/* `appointmentTimeline.*` namespace; no PHI reaches the agent adapter. */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to an edge before the matching load callback fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Curated imperative handle — identifiers + lifecycle state only. */\nexport interface AppointmentTimelineHandle {\n getItems: () => Array<{ id: string; state: string }>;\n selectItem: (id: string) => void;\n jumpToToday: () => void;\n}\n\nexport interface AppointmentTimelineProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Appointments to render — any order; grouped + sorted internally. */\n items: AppointmentItem[];\n /**\n * ISO-8601 \"now\" anchor — the timeline scrolls to this day on mount and the\n * \"Today\" preset returns to it. Defaults to the current instant. Stories pass\n * a fixed value for deterministic snapshots.\n */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Appointments\". */\n title?: string;\n /** BCP-47 locale override for day headers + each AppointmentCard. */\n locale?: string;\n /** ISO-4217 currency code passed to each AppointmentCard. */\n currency?: string;\n /** Visual density passed to each AppointmentCard. */\n size?: 'sm' | 'md';\n /**\n * Lead each row with the PATIENT (avatar + name as the row title) rather\n * than the operator. Default `false`: the timeline was built for a\n * patient-scoped rail, where repeating the name on every row is noise. A\n * clinic-wide agenda — \"who is coming in next\" across the practice —\n * passes `true`, and rows with no patient read as \"No patient\".\n */\n showPatient?: boolean;\n /** Fires when a row is activated. */\n onOpenAppointment?: (item: AppointmentItem) => void;\n /**\n * The id of the currently selected appointment. The matching card\n * renders with `selected` (info-tinted accent + `aria-current`) so the\n * eye keeps its place in the list after a click.\n */\n selectedId?: string;\n\n /* ----- Infinite scroll ----- */\n /** Load earlier (past) appointments — fired when the top edge is reached. */\n onLoadEarlier?: () => void;\n /** Load later (future) appointments — fired when the bottom edge is reached. */\n onLoadLater?: () => void;\n /** Whether more past appointments exist. Defaults to `true` when `onLoadEarlier` is set. */\n hasMoreEarlier?: boolean;\n /** Whether more future appointments exist. Defaults to `true` when `onLoadLater` is set. */\n hasMoreLater?: boolean;\n /** Show a loading row at the top edge. */\n loadingEarlier?: boolean;\n /** Show a loading row at the bottom edge. */\n loadingLater?: boolean;\n\n /* ----- Filters ----- */\n /** Show the date-filter row (presets + jump-to-date). Default `true`. */\n showFilters?: boolean;\n /**\n * Fired when a jump-to-date / preset targets a day outside the loaded range,\n * so the consumer can load it. The timeline scrolls to the nearest rendered\n * day until then.\n */\n onJumpToDate?: (dateIso: string) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n\n /**\n * Content rendered between the header/filter row and the scroll region —\n * a summary strip, a \"happening now\" band, anything the host needs\n * ahead of the day-grouped list. Omitted by default (no change to\n * today's layout). Not part of the scroll region: it stays fixed like\n * the header above it.\n */\n headerExtra?: ReactNode;\n /**\n * Forwarded to every row's `AppointmentCard`: withhold the lifecycle\n * badge for the default/expected state (`confirmed`). Default `false`\n * (today's behaviour — every state shows its badge).\n */\n hideDefaultStatus?: boolean;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n { variants: { size: { sm: '', md: '' } }, defaultVariants: { size: 'sm' } },\n);\n\n/* Scroll region with a block-axis fade mask. The CSS custom properties flip to\n `transparent` at whichever edge has more content (data-fade-top /\n data-fade-bottom), mirroring the TabBar edge-mask technique on the Y axis.\n Disabled under reduced-motion, the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n 'ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:[--atl-mask-top:black] ds:[--atl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--atl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--atl-mask-bottom:transparent]',\n 'ds:[mask-image:var(--accessible-off,linear-gradient(to_bottom,var(--atl-mask-top)_0,black_var(--atl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--atl-fade-distance,var(--spacing-lg))),var(--atl-mask-bottom)_100%))]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:[outline-offset:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* -------------------------------------------------------------------- */\n/* Day grouping + header labels */\n/* -------------------------------------------------------------------- */\n\ninterface DayGroup {\n key: string;\n date: Date;\n items: AppointmentItem[];\n}\n\n/** Local calendar day key (`YYYY-MM-DD`) — sorts chronologically as a string. */\nfunction localDayKey(d: Date): string {\n const m = `${d.getMonth() + 1}`.padStart(2, '0');\n const day = `${d.getDate()}`.padStart(2, '0');\n return `${d.getFullYear()}-${m}-${day}`;\n}\n\nfunction groupByDay(items: AppointmentItem[]): DayGroup[] {\n const sorted = [...items].sort(\n (a, b) => +new Date(a.startIso) - +new Date(b.startIso),\n );\n const map = new Map<string, DayGroup>();\n for (const item of sorted) {\n const d = new Date(item.startIso);\n const key = localDayKey(d);\n let group = map.get(key);\n if (!group) {\n group = {\n key,\n date: new Date(d.getFullYear(), d.getMonth(), d.getDate()),\n items: [],\n };\n map.set(key, group);\n }\n group.items.push(item);\n }\n return [...map.values()];\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const AppointmentTimeline = forwardRef<\n HTMLElement,\n AppointmentTimelineProps\n>(\n (\n {\n id,\n items,\n nowIso,\n title,\n locale,\n currency,\n size = 'sm',\n showPatient = false,\n onOpenAppointment,\n selectedId,\n onLoadEarlier,\n onLoadLater,\n hasMoreEarlier,\n hasMoreLater,\n loadingEarlier = false,\n loadingLater = false,\n showFilters = true,\n onJumpToDate,\n emptyTitle,\n emptyDescription,\n className,\n 'aria-label': ariaLabel,\n headerExtra,\n hideDefaultStatus = false,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const jumpId = useId();\n const prefersReducedMotion = usePrefersReducedMotion();\n const resolvedLocale = locale ?? i18n.language;\n\n const heading = title ?? t('appointmentTimeline.title');\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n const groups = useMemo(() => groupByDay(items), [items]);\n\n /* Reflow + exit transitions — the same pair notes and tasks use. When\n an appointment is added or removed, surviving cards slide to their\n new positions instead of snapping; a removed card fades out in place\n before the host drops it, so the removal reads as a removal. */\n const reduceMotion = prefersReducedMotion || undefined;\n const flatItemIds = useMemo(\n () => groups.flatMap((g) => g.items.map((i) => i.id)).join(),\n [groups],\n );\n const { containerRef: reflowRef } = useListReflow<HTMLOListElement>({\n key: flatItemIds,\n reduceMotion,\n });\n const exitTransition = useExitTransition({ reduceMotion });\n\n /* Track removed items so they can fade out in place. The previous\n items array is diffed against the current one; removed ids are held\n in `leavingItems` and rendered after the live groups, faded, until\n the exit transition elapses and drops them. */\n const prevItemsRef = useRef(items);\n const [leavingItems, setLeavingItems] = useState<AppointmentItem[]>([]);\n useEffect(() => {\n const prev = prevItemsRef.current;\n if (prev === items) return;\n const currentIds = new Set(items.map((i) => i.id));\n const removed = prev.filter((i) => !currentIds.has(i.id));\n if (removed.length > 0) {\n setLeavingItems((prev) => [...prev, ...removed]);\n removed.forEach((item) => {\n exitTransition.leave(item.id, () => {\n setLeavingItems((prev) => prev.filter((i) => i.id !== item.id));\n });\n });\n }\n prevItemsRef.current = items;\n }, [items, exitTransition]);\n\n const moreEarlier = hasMoreEarlier ?? !!onLoadEarlier;\n const moreLater = hasMoreLater ?? !!onLoadLater;\n\n /* The day to anchor on: today if present, else the nearest upcoming day,\n else the last day we have. */\n const anchorKey = useMemo(() => {\n if (groups.length === 0) return undefined;\n const todayKey = localDayKey(now);\n const keys = groups.map((g) => g.key);\n if (keys.includes(todayKey)) return todayKey;\n return keys.find((k) => k >= todayKey) ?? keys[keys.length - 1];\n }, [groups, now]);\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const dayElRefs = useRef<Map<string, HTMLElement>>(new Map());\n const hasAnchored = useRef(false);\n const prevFirstKey = useRef<string | undefined>(undefined);\n const prevScrollHeight = useRef(0);\n\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n /* Scroll a day into view at the top of the region. Falls back to the\n nearest rendered day on/after the target (presets may land on an empty\n day). Uses getBoundingClientRect so it is offsetParent-agnostic. */\n const scrollToKey = useCallback(\n (targetKey: string, smooth: boolean) => {\n const region = scrollRef.current;\n if (!region) return;\n let el = dayElRefs.current.get(targetKey);\n if (!el) {\n const keys = [...dayElRefs.current.keys()].sort();\n const next =\n keys.find((k) => k >= targetKey) ?? keys[keys.length - 1];\n el = next ? dayElRefs.current.get(next) : undefined;\n }\n if (!el) return;\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({\n top: region.scrollTop + delta,\n behavior: smooth && !prefersReducedMotion ? 'smooth' : 'auto',\n });\n },\n [prefersReducedMotion],\n );\n\n /* Anchor on mount; preserve the viewport when earlier days prepend. */\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region) return;\n const firstKey = groups[0]?.key;\n if (!hasAnchored.current) {\n if (groups.length > 0 && anchorKey) {\n scrollToKey(anchorKey, false);\n hasAnchored.current = true;\n }\n } else if (\n prevFirstKey.current &&\n firstKey &&\n firstKey < prevFirstKey.current\n ) {\n const grew = region.scrollHeight - prevScrollHeight.current;\n if (grew > 0) region.scrollTop += grew;\n }\n prevFirstKey.current = firstKey;\n prevScrollHeight.current = region.scrollHeight;\n updateEdges();\n }, [groups, anchorKey, scrollToKey, updateEdges]);\n\n /* Recompute the fades when the region resizes. */\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadEarlier &&\n moreEarlier &&\n !loadingEarlier &&\n scrollTop <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadEarlier();\n }\n if (\n onLoadLater &&\n moreLater &&\n !loadingLater &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadLater();\n }\n }, [\n updateEdges,\n onLoadEarlier,\n onLoadLater,\n moreEarlier,\n moreLater,\n loadingEarlier,\n loadingLater,\n ]);\n\n /* ----- Filter actions ----- */\n const jumpTo = useCallback(\n (date: Date) => {\n const key = localDayKey(date);\n const known = dayElRefs.current.has(key);\n scrollToKey(key, true);\n if (!known) onJumpToDate?.(date.toISOString());\n },\n [scrollToKey, onJumpToDate],\n );\n\n const handleToday = useCallback(() => jumpTo(now), [jumpTo, now]);\n const handleThisWeek = useCallback(() => {\n const start = new Date(now);\n const dow = (start.getDay() + 6) % 7; // Monday-based week start\n start.setDate(start.getDate() - dow);\n jumpTo(start);\n }, [jumpTo, now]);\n const handleThisMonth = useCallback(() => {\n jumpTo(new Date(now.getFullYear(), now.getMonth(), 1));\n }, [jumpTo, now]);\n\n /* ----- Agent handle ----- */\n const itemsRef = useRef<AppointmentItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<AppointmentTimelineHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({ id: i.id, state: i.state })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenAppointment?.(found);\n },\n jumpToToday: () => scrollToKey(localDayKey(now), true),\n }),\n [onOpenAppointment, scrollToKey, now],\n );\n useAgentRegistration(appointmentTimelineAgent, handle, id);\n\n const isEmpty = groups.length === 0 && !loadingEarlier && !loadingLater;\n\n const loadingRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n return (\n <section\n ref={innerRef}\n data-component=\"appointment-timeline\"\n data-component-id={id}\n aria-label={ariaLabel ?? heading}\n className={rootVariants({ size, className })}\n {...rest}\n >\n {/* Shared rail header: title + (optional) filter row + divider. This\n panel owns its own scroll/fill, so the header stays a fixed band\n (sticky={false}). The rail injects the favourite/close cluster via\n PanelHeaderActionsProvider; standalone it renders none. */}\n <PanelHeader\n icon={<CalendarDays />}\n title={heading}\n filters={\n showFilters ? (\n <>\n <ButtonGroup label={t('appointmentTimeline.filtersLabel')}>\n <Button intent=\"outline\" size=\"sm\" onClick={handleToday}>\n {t('appointmentTimeline.today')}\n </Button>\n <Button intent=\"outline\" size=\"sm\" onClick={handleThisWeek}>\n {t('appointmentTimeline.thisWeek')}\n </Button>\n <Button intent=\"outline\" size=\"sm\" onClick={handleThisMonth}>\n {t('appointmentTimeline.thisMonth')}\n </Button>\n </ButtonGroup>\n <label htmlFor={jumpId} className=\"ds:sr-only\">\n {t('appointmentTimeline.jumpToDate')}\n </label>\n <DatePicker\n id={jumpId}\n size=\"sm\"\n placeholder={t('appointmentTimeline.jumpToDate')}\n onChange={(date) => {\n if (date) jumpTo(date);\n }}\n />\n </>\n ) : undefined\n }\n />\n\n {headerExtra}\n\n {isEmpty ? (\n <div className=\"ds:flex-1 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('appointmentTimeline.empty.title')}\n description={\n emptyDescription ?? t('appointmentTimeline.empty.description')\n }\n />\n </div>\n ) : (\n <div\n ref={scrollRef}\n // The scroll region must be keyboard-focusable so arrow / Home /\n // End can drive it (axe scrollable-region-focusable); jsx-a11y's\n // generic rule doesn't know this element scrolls.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n {loadingEarlier ? loadingRow('loading-earlier') : null}\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" is NOT redundant: WebKit drops implicit list semantics when list-style is none */}\n <ol\n ref={reflowRef}\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\"\n >\n {groups.map((group) => (\n <li\n key={group.key}\n ref={(node) => {\n if (node) dayElRefs.current.set(group.key, node);\n else dayElRefs.current.delete(group.key);\n }}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <DayHeader\n date={group.date}\n now={now}\n locale={resolvedLocale}\n todayLabel={t('appointmentTimeline.today')}\n tomorrowLabel={t('appointmentTimeline.tomorrow')}\n yesterdayLabel={t('appointmentTimeline.yesterday')}\n />\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" is NOT redundant: WebKit drops implicit list semantics when list-style is none */}\n <ul\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\"\n >\n {group.items.map((item) => (\n <AppointmentCard\n key={item.id}\n item={item}\n size={size}\n surface=\"elevated\"\n showPatient={showPatient}\n locale={resolvedLocale}\n currency={currency}\n onActivate={onOpenAppointment}\n selected={item.id === selectedId}\n hideDefaultStatus={hideDefaultStatus}\n data-appointment-id={item.id}\n data-reflow-id={item.id}\n className={REFLOW_ROW_CLASS}\n />\n ))}\n </ul>\n </li>\n ))}\n {/* Leaving cards: removed from state but held for the exit\n fade. Rendered without `data-reflow-id` so the reflow hook\n ignores them; faded via `data-leaving`. */}\n {leavingItems.length > 0\n ? leavingItems.map((item) => (\n <AppointmentCard\n key={`leaving-${item.id}`}\n item={item}\n size={size}\n surface=\"elevated\"\n showPatient={showPatient}\n locale={resolvedLocale}\n currency={currency}\n aria-hidden=\"true\"\n data-leaving\n className={[\n 'ds:opacity-0',\n 'ds:transition-opacity',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:ease-[var(--ease-out)]',\n 'ds:motion-reduce:transition-none',\n ].join(' ')}\n />\n ))\n : null}\n </ol>\n {loadingLater ? loadingRow('loading-later') : null}\n </div>\n )}\n </section>\n );\n },\n);\n\nAppointmentTimeline.displayName = 'AppointmentTimeline';\n\n/* -------------------------------------------------------------------- */\n/* Day header — sticky label per day group */\n/* -------------------------------------------------------------------- */\n\ninterface DayHeaderProps {\n date: Date;\n now: Date;\n locale: string | undefined;\n todayLabel: string;\n tomorrowLabel: string;\n yesterdayLabel: string;\n}\n\nfunction DayHeader({\n date,\n now,\n locale,\n todayLabel,\n tomorrowLabel,\n yesterdayLabel,\n}: DayHeaderProps): ReactNode {\n const key = localDayKey(date);\n const todayKey = localDayKey(now);\n const tomorrow = new Date(now);\n tomorrow.setDate(now.getDate() + 1);\n const yesterday = new Date(now);\n yesterday.setDate(now.getDate() - 1);\n\n const isToday = key === todayKey;\n\n let label: string;\n if (isToday) label = todayLabel;\n else if (key === localDayKey(tomorrow)) label = tomorrowLabel;\n else if (key === localDayKey(yesterday)) label = yesterdayLabel;\n else {\n const sameYear = date.getFullYear() === now.getFullYear();\n label = new Intl.DateTimeFormat(locale, {\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n ...(sameYear ? {} : { year: 'numeric' }),\n }).format(date);\n }\n\n // Today's group is marked with the brand colour + a leading dot so the\n // current day reads at a glance. `--primary` clears AA on the card in every\n // theme (violet-500 light, magenta on dark); the dot is decorative.\n return (\n <div\n data-today={isToday ? 'true' : undefined}\n className={[\n 'ds:sticky ds:top-0 ds:z-[1] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n isToday\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]',\n ].join(' ')}\n >\n {isToday ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type AppointmentTimelineSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["appointmentTimelineAgent","handle","args","EDGE_LOAD_THRESHOLD","rootVariants","cva","scrollRegionClasses","localDayKey","d","m","day","groupByDay","items","sorted","a","b","map","item","key","group","AppointmentTimeline","forwardRef","id","nowIso","title","locale","currency","size","showPatient","onOpenAppointment","selectedId","onLoadEarlier","onLoadLater","hasMoreEarlier","hasMoreLater","loadingEarlier","loadingLater","showFilters","onJumpToDate","emptyTitle","emptyDescription","className","ariaLabel","headerExtra","hideDefaultStatus","rest","ref","t","i18n","useTranslation","jumpId","useId","prefersReducedMotion","usePrefersReducedMotion","resolvedLocale","heading","now","useMemo","groups","reduceMotion","flatItemIds","g","i","reflowRef","useListReflow","exitTransition","useExitTransition","prevItemsRef","useRef","leavingItems","setLeavingItems","useState","useEffect","prev","currentIds","removed","moreEarlier","moreLater","anchorKey","todayKey","keys","k","scrollRef","dayElRefs","hasAnchored","prevFirstKey","prevScrollHeight","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","useCallback","region","scrollTop","scrollHeight","clientHeight","scrollToKey","targetKey","smooth","el","next","delta","useIsomorphicLayoutEffect","firstKey","_a","grew","observer","handleScroll","jumpTo","date","known","handleToday","handleThisWeek","start","dow","handleThisMonth","itemsRef","innerRef","useImperativeHandle","targetId","found","useAgentRegistration","isEmpty","loadingRow","jsx","Skeleton","jsxs","PanelHeader","CalendarDays","Fragment","ButtonGroup","Button","DatePicker","EmptyState","node","DayHeader","AppointmentCard","REFLOW_ROW_CLASS","todayLabel","tomorrowLabel","yesterdayLabel","tomorrow","yesterday","isToday","label","sameYear"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"appointment-timeline-Z0494xO-.js","sources":["../../src/components/appointment-timeline/appointment-timeline.agent.ts","../../src/components/appointment-timeline/appointment-timeline.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — AppointmentTimeline. */\n/* */\n/* Timeline surface: read appointment ids + lifecycle state (never */\n/* patient names / treatments), activate a row through the curated handle, */\n/* and re-anchor the scroll on today. In-page (no open/close). */\n/* `showPatient` is presentation only — it changes which name each row */\n/* leads with, never what the adapter reads or exposes. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AppointmentTimelineHandle } from './appointment-timeline';\n\nexport const appointmentTimelineAgent: AgentAdapter<AppointmentTimelineHandle> =\n {\n id: 'appointment-timeline',\n // 'pick' backs select_item (non-persisting activation through\n // onOpenAppointment); 'scroll' backs jump_to_today, which re-anchors the\n // scroll viewport (mirrors practice-results' scroll_to_result).\n capabilities: ['scroll', 'pick'],\n state: {\n items: {\n type: 'Array<{ id: string; state: string }>',\n descriptionKey: 'ui.agent.appointmentTimeline.state.items',\n description:\n 'Currently-rendered appointments. Ids + lifecycle state only — never patient identity.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\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.appointmentTimeline.actions.selectItem',\n description: 'Activate the appointment with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n jump_to_today: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.appointmentTimeline.actions.jumpToToday',\n description: \"Re-anchor the timeline scroll on today's appointments.\",\n invoke: (handle) => {\n handle.jumpToToday();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'appointment-timeline',\n description: 'Marks the AppointmentTimeline wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific timeline from the agent.',\n },\n item: {\n attr: 'data-appointment-id',\n description:\n 'Stable appointment id emitted on each rendered AppointmentCard inside the timeline.',\n },\n },\n };\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { CalendarDays } from 'lucide-react';\nimport { AppointmentCard, type AppointmentItem } from '../appointment-card';\nimport { Button } from '../button';\nimport { ButtonGroup } from '../button-group';\nimport { DatePicker } from '../date-picker';\nimport { PanelHeader } from '../panel-header';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { usePrefersReducedMotion } from '../../hooks/use-prefers-reduced-motion';\nimport { REFLOW_ROW_CLASS, useListReflow } from '../../hooks/use-list-reflow';\nimport { useExitTransition } from '../../hooks/use-exit-transition';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { appointmentTimelineAgent } from './appointment-timeline.agent';\n\n/* -------------------------------------------------------------------- */\n/* AppointmentTimeline */\n/* */\n/* A vertical, day-grouped appointment timeline for the Control Room */\n/* rail. Unlike AppointmentTray (a bordered card of a flat list), this */\n/* fills the rail edge-to-edge: appointments are grouped under day */\n/* headers, the scroll is anchored on TODAY, and it scrolls infinitely */\n/* into the past and future — the consumer feeds more via onLoadEarlier */\n/* / onLoadLater as either edge is reached (scroll position is preserved */\n/* when earlier items prepend). Date-filter presets + a jump-to-date */\n/* picker re-anchor the scroll. Top + bottom transparent gradient fades */\n/* (a block-axis mask) signal more content beyond each edge. */\n/* */\n/* Each row reuses AppointmentCard (care-plan + chair chips included). */\n/* All visible text flows through useTranslation('ui') against the */\n/* `appointmentTimeline.*` namespace; no PHI reaches the agent adapter. */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to an edge before the matching load callback fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Curated imperative handle — identifiers + lifecycle state only. */\nexport interface AppointmentTimelineHandle {\n getItems: () => Array<{ id: string; state: string }>;\n selectItem: (id: string) => void;\n jumpToToday: () => void;\n}\n\nexport interface AppointmentTimelineProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Appointments to render — any order; grouped + sorted internally. */\n items: AppointmentItem[];\n /**\n * ISO-8601 \"now\" anchor — the timeline scrolls to this day on mount and the\n * \"Today\" preset returns to it. Defaults to the current instant. Stories pass\n * a fixed value for deterministic snapshots.\n */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Appointments\". */\n title?: string;\n /** BCP-47 locale override for day headers + each AppointmentCard. */\n locale?: string;\n /** ISO-4217 currency code passed to each AppointmentCard. */\n currency?: string;\n /** Visual density passed to each AppointmentCard. */\n size?: 'sm' | 'md';\n /**\n * Lead each row with the PATIENT (avatar + name as the row title) rather\n * than the operator. Default `false`: the timeline was built for a\n * patient-scoped rail, where repeating the name on every row is noise. A\n * clinic-wide agenda — \"who is coming in next\" across the practice —\n * passes `true`, and rows with no patient read as \"No patient\".\n */\n showPatient?: boolean;\n /** Fires when a row is activated. */\n onOpenAppointment?: (item: AppointmentItem) => void;\n /**\n * The id of the currently selected appointment. The matching card\n * renders with `selected` (info-tinted accent + `aria-current`) so the\n * eye keeps its place in the list after a click.\n */\n selectedId?: string;\n\n /* ----- Infinite scroll ----- */\n /** Load earlier (past) appointments — fired when the top edge is reached. */\n onLoadEarlier?: () => void;\n /** Load later (future) appointments — fired when the bottom edge is reached. */\n onLoadLater?: () => void;\n /** Whether more past appointments exist. Defaults to `true` when `onLoadEarlier` is set. */\n hasMoreEarlier?: boolean;\n /** Whether more future appointments exist. Defaults to `true` when `onLoadLater` is set. */\n hasMoreLater?: boolean;\n /** Show a loading row at the top edge. */\n loadingEarlier?: boolean;\n /** Show a loading row at the bottom edge. */\n loadingLater?: boolean;\n\n /* ----- Filters ----- */\n /** Show the date-filter row (presets + jump-to-date). Default `true`. */\n showFilters?: boolean;\n /**\n * Fired when a jump-to-date / preset targets a day outside the loaded range,\n * so the consumer can load it. The timeline scrolls to the nearest rendered\n * day until then.\n */\n onJumpToDate?: (dateIso: string) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n\n /**\n * Content rendered between the header/filter row and the scroll region —\n * a summary strip, a \"happening now\" band, anything the host needs\n * ahead of the day-grouped list. Omitted by default (no change to\n * today's layout). Not part of the scroll region: it stays fixed like\n * the header above it.\n */\n headerExtra?: ReactNode;\n /**\n * Forwarded to every row's `AppointmentCard`: withhold the lifecycle\n * badge for the default/expected state (`confirmed`). Default `false`\n * (today's behaviour — every state shows its badge).\n */\n hideDefaultStatus?: boolean;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n { variants: { size: { sm: '', md: '' } }, defaultVariants: { size: 'sm' } },\n);\n\n/* Scroll region with a block-axis fade mask. The CSS custom properties flip to\n `transparent` at whichever edge has more content (data-fade-top /\n data-fade-bottom), mirroring the TabBar edge-mask technique on the Y axis.\n Disabled under reduced-motion, the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n 'ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:[--atl-mask-top:black] ds:[--atl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--atl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--atl-mask-bottom:transparent]',\n 'ds:[mask-image:var(--accessible-off,linear-gradient(to_bottom,var(--atl-mask-top)_0,black_var(--atl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--atl-fade-distance,var(--spacing-lg))),var(--atl-mask-bottom)_100%))]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:[outline-offset:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* -------------------------------------------------------------------- */\n/* Day grouping + header labels */\n/* -------------------------------------------------------------------- */\n\ninterface DayGroup {\n key: string;\n date: Date;\n items: AppointmentItem[];\n}\n\n/** Local calendar day key (`YYYY-MM-DD`) — sorts chronologically as a string. */\nfunction localDayKey(d: Date): string {\n const m = `${d.getMonth() + 1}`.padStart(2, '0');\n const day = `${d.getDate()}`.padStart(2, '0');\n return `${d.getFullYear()}-${m}-${day}`;\n}\n\nfunction groupByDay(items: AppointmentItem[]): DayGroup[] {\n const sorted = [...items].sort(\n (a, b) => +new Date(a.startIso) - +new Date(b.startIso),\n );\n const map = new Map<string, DayGroup>();\n for (const item of sorted) {\n const d = new Date(item.startIso);\n const key = localDayKey(d);\n let group = map.get(key);\n if (!group) {\n group = {\n key,\n date: new Date(d.getFullYear(), d.getMonth(), d.getDate()),\n items: [],\n };\n map.set(key, group);\n }\n group.items.push(item);\n }\n return [...map.values()];\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const AppointmentTimeline = forwardRef<\n HTMLElement,\n AppointmentTimelineProps\n>(\n (\n {\n id,\n items,\n nowIso,\n title,\n locale,\n currency,\n size = 'sm',\n showPatient = false,\n onOpenAppointment,\n selectedId,\n onLoadEarlier,\n onLoadLater,\n hasMoreEarlier,\n hasMoreLater,\n loadingEarlier = false,\n loadingLater = false,\n showFilters = true,\n onJumpToDate,\n emptyTitle,\n emptyDescription,\n className,\n 'aria-label': ariaLabel,\n headerExtra,\n hideDefaultStatus = false,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const jumpId = useId();\n const prefersReducedMotion = usePrefersReducedMotion();\n const resolvedLocale = locale ?? i18n.language;\n\n const heading = title ?? t('appointmentTimeline.title');\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n const groups = useMemo(() => groupByDay(items), [items]);\n\n /* Reflow + exit transitions — the same pair notes and tasks use. When\n an appointment is added or removed, surviving cards slide to their\n new positions instead of snapping; a removed card fades out in place\n before the host drops it, so the removal reads as a removal. */\n const reduceMotion = prefersReducedMotion || undefined;\n const flatItemIds = useMemo(\n () => groups.flatMap((g) => g.items.map((i) => i.id)).join(),\n [groups],\n );\n const { containerRef: reflowRef } = useListReflow<HTMLOListElement>({\n key: flatItemIds,\n reduceMotion,\n });\n const exitTransition = useExitTransition({ reduceMotion });\n\n /* Track removed items so they can fade out in place. The previous\n items array is diffed against the current one; removed ids are held\n in `leavingItems` and rendered after the live groups, faded, until\n the exit transition elapses and drops them. */\n const prevItemsRef = useRef(items);\n const [leavingItems, setLeavingItems] = useState<AppointmentItem[]>([]);\n useEffect(() => {\n const prev = prevItemsRef.current;\n if (prev === items) return;\n const currentIds = new Set(items.map((i) => i.id));\n const removed = prev.filter((i) => !currentIds.has(i.id));\n if (removed.length > 0) {\n setLeavingItems((prev) => [...prev, ...removed]);\n removed.forEach((item) => {\n exitTransition.leave(item.id, () => {\n setLeavingItems((prev) => prev.filter((i) => i.id !== item.id));\n });\n });\n }\n prevItemsRef.current = items;\n }, [items, exitTransition]);\n\n const moreEarlier = hasMoreEarlier ?? !!onLoadEarlier;\n const moreLater = hasMoreLater ?? !!onLoadLater;\n\n /* The day to anchor on: today if present, else the nearest upcoming day,\n else the last day we have. */\n const anchorKey = useMemo(() => {\n if (groups.length === 0) return undefined;\n const todayKey = localDayKey(now);\n const keys = groups.map((g) => g.key);\n if (keys.includes(todayKey)) return todayKey;\n return keys.find((k) => k >= todayKey) ?? keys[keys.length - 1];\n }, [groups, now]);\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const dayElRefs = useRef<Map<string, HTMLElement>>(new Map());\n const hasAnchored = useRef(false);\n const prevFirstKey = useRef<string | undefined>(undefined);\n const prevScrollHeight = useRef(0);\n\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n /* Scroll a day into view at the top of the region. Falls back to the\n nearest rendered day on/after the target (presets may land on an empty\n day). Uses getBoundingClientRect so it is offsetParent-agnostic. */\n const scrollToKey = useCallback(\n (targetKey: string, smooth: boolean) => {\n const region = scrollRef.current;\n if (!region) return;\n let el = dayElRefs.current.get(targetKey);\n if (!el) {\n const keys = [...dayElRefs.current.keys()].sort();\n const next =\n keys.find((k) => k >= targetKey) ?? keys[keys.length - 1];\n el = next ? dayElRefs.current.get(next) : undefined;\n }\n if (!el) return;\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({\n top: region.scrollTop + delta,\n behavior: smooth && !prefersReducedMotion ? 'smooth' : 'auto',\n });\n },\n [prefersReducedMotion],\n );\n\n /* Anchor on mount; preserve the viewport when earlier days prepend. */\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region) return;\n const firstKey = groups[0]?.key;\n if (!hasAnchored.current) {\n if (groups.length > 0 && anchorKey) {\n scrollToKey(anchorKey, false);\n hasAnchored.current = true;\n }\n } else if (\n prevFirstKey.current &&\n firstKey &&\n firstKey < prevFirstKey.current\n ) {\n const grew = region.scrollHeight - prevScrollHeight.current;\n if (grew > 0) region.scrollTop += grew;\n }\n prevFirstKey.current = firstKey;\n prevScrollHeight.current = region.scrollHeight;\n updateEdges();\n }, [groups, anchorKey, scrollToKey, updateEdges]);\n\n /* Recompute the fades when the region resizes. */\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadEarlier &&\n moreEarlier &&\n !loadingEarlier &&\n scrollTop <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadEarlier();\n }\n if (\n onLoadLater &&\n moreLater &&\n !loadingLater &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadLater();\n }\n }, [\n updateEdges,\n onLoadEarlier,\n onLoadLater,\n moreEarlier,\n moreLater,\n loadingEarlier,\n loadingLater,\n ]);\n\n /* ----- Filter actions ----- */\n const jumpTo = useCallback(\n (date: Date) => {\n const key = localDayKey(date);\n const known = dayElRefs.current.has(key);\n scrollToKey(key, true);\n if (!known) onJumpToDate?.(date.toISOString());\n },\n [scrollToKey, onJumpToDate],\n );\n\n const handleToday = useCallback(() => jumpTo(now), [jumpTo, now]);\n const handleThisWeek = useCallback(() => {\n const start = new Date(now);\n const dow = (start.getDay() + 6) % 7; // Monday-based week start\n start.setDate(start.getDate() - dow);\n jumpTo(start);\n }, [jumpTo, now]);\n const handleThisMonth = useCallback(() => {\n jumpTo(new Date(now.getFullYear(), now.getMonth(), 1));\n }, [jumpTo, now]);\n\n /* ----- Agent handle ----- */\n const itemsRef = useRef<AppointmentItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<AppointmentTimelineHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({ id: i.id, state: i.state })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenAppointment?.(found);\n },\n jumpToToday: () => scrollToKey(localDayKey(now), true),\n }),\n [onOpenAppointment, scrollToKey, now],\n );\n useAgentRegistration(appointmentTimelineAgent, handle, id);\n\n const isEmpty = groups.length === 0 && !loadingEarlier && !loadingLater;\n\n const loadingRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n return (\n <section\n ref={innerRef}\n data-component=\"appointment-timeline\"\n data-component-id={id}\n aria-label={ariaLabel ?? heading}\n className={rootVariants({ size, className })}\n {...rest}\n >\n {/* Shared rail header: title + (optional) filter row + divider. This\n panel owns its own scroll/fill, so the header stays a fixed band\n (sticky={false}). The rail injects the favourite/close cluster via\n PanelHeaderActionsProvider; standalone it renders none. */}\n <PanelHeader\n icon={<CalendarDays />}\n title={heading}\n filters={\n showFilters ? (\n <>\n <ButtonGroup label={t('appointmentTimeline.filtersLabel')}>\n <Button intent=\"outline\" size=\"sm\" onClick={handleToday}>\n {t('appointmentTimeline.today')}\n </Button>\n <Button intent=\"outline\" size=\"sm\" onClick={handleThisWeek}>\n {t('appointmentTimeline.thisWeek')}\n </Button>\n <Button intent=\"outline\" size=\"sm\" onClick={handleThisMonth}>\n {t('appointmentTimeline.thisMonth')}\n </Button>\n </ButtonGroup>\n <label htmlFor={jumpId} className=\"ds:sr-only\">\n {t('appointmentTimeline.jumpToDate')}\n </label>\n <DatePicker\n id={jumpId}\n size=\"sm\"\n placeholder={t('appointmentTimeline.jumpToDate')}\n onChange={(date) => {\n if (date) jumpTo(date);\n }}\n />\n </>\n ) : undefined\n }\n />\n\n {headerExtra}\n\n {isEmpty ? (\n <div className=\"ds:flex-1 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('appointmentTimeline.empty.title')}\n description={\n emptyDescription ?? t('appointmentTimeline.empty.description')\n }\n />\n </div>\n ) : (\n <div\n ref={scrollRef}\n // The scroll region must be keyboard-focusable so arrow / Home /\n // End can drive it (axe scrollable-region-focusable); jsx-a11y's\n // generic rule doesn't know this element scrolls.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n {loadingEarlier ? loadingRow('loading-earlier') : null}\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" is NOT redundant: WebKit drops implicit list semantics when list-style is none */}\n <ol\n ref={reflowRef}\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\"\n >\n {groups.map((group) => (\n <li\n key={group.key}\n ref={(node) => {\n if (node) dayElRefs.current.set(group.key, node);\n else dayElRefs.current.delete(group.key);\n }}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <DayHeader\n date={group.date}\n now={now}\n locale={resolvedLocale}\n todayLabel={t('appointmentTimeline.today')}\n tomorrowLabel={t('appointmentTimeline.tomorrow')}\n yesterdayLabel={t('appointmentTimeline.yesterday')}\n />\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" is NOT redundant: WebKit drops implicit list semantics when list-style is none */}\n <ul\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\"\n >\n {group.items.map((item) => (\n <AppointmentCard\n key={item.id}\n item={item}\n size={size}\n surface=\"elevated\"\n showPatient={showPatient}\n locale={resolvedLocale}\n currency={currency}\n onActivate={onOpenAppointment}\n selected={item.id === selectedId}\n hideDefaultStatus={hideDefaultStatus}\n data-appointment-id={item.id}\n data-reflow-id={item.id}\n className={REFLOW_ROW_CLASS}\n />\n ))}\n </ul>\n </li>\n ))}\n {/* Leaving cards: removed from state but held for the exit\n fade. Rendered without `data-reflow-id` so the reflow hook\n ignores them; faded via `data-leaving`. */}\n {leavingItems.length > 0\n ? leavingItems.map((item) => (\n <AppointmentCard\n key={`leaving-${item.id}`}\n item={item}\n size={size}\n surface=\"elevated\"\n showPatient={showPatient}\n locale={resolvedLocale}\n currency={currency}\n aria-hidden=\"true\"\n data-leaving\n className={[\n 'ds:opacity-0',\n 'ds:transition-opacity',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:ease-[var(--ease-out)]',\n 'ds:motion-reduce:transition-none',\n ].join(' ')}\n />\n ))\n : null}\n </ol>\n {loadingLater ? loadingRow('loading-later') : null}\n </div>\n )}\n </section>\n );\n },\n);\n\nAppointmentTimeline.displayName = 'AppointmentTimeline';\n\n/* -------------------------------------------------------------------- */\n/* Day header — sticky label per day group */\n/* -------------------------------------------------------------------- */\n\ninterface DayHeaderProps {\n date: Date;\n now: Date;\n locale: string | undefined;\n todayLabel: string;\n tomorrowLabel: string;\n yesterdayLabel: string;\n}\n\nfunction DayHeader({\n date,\n now,\n locale,\n todayLabel,\n tomorrowLabel,\n yesterdayLabel,\n}: DayHeaderProps): ReactNode {\n const key = localDayKey(date);\n const todayKey = localDayKey(now);\n const tomorrow = new Date(now);\n tomorrow.setDate(now.getDate() + 1);\n const yesterday = new Date(now);\n yesterday.setDate(now.getDate() - 1);\n\n const isToday = key === todayKey;\n\n let label: string;\n if (isToday) label = todayLabel;\n else if (key === localDayKey(tomorrow)) label = tomorrowLabel;\n else if (key === localDayKey(yesterday)) label = yesterdayLabel;\n else {\n const sameYear = date.getFullYear() === now.getFullYear();\n label = new Intl.DateTimeFormat(locale, {\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n ...(sameYear ? {} : { year: 'numeric' }),\n }).format(date);\n }\n\n // Today's group is marked with the brand colour + a leading dot so the\n // current day reads at a glance. `--primary` clears AA on the card in every\n // theme (violet-500 light, magenta on dark); the dot is decorative.\n return (\n <div\n data-today={isToday ? 'true' : undefined}\n className={[\n 'ds:sticky ds:top-0 ds:z-[1] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n isToday\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]',\n ].join(' ')}\n >\n {isToday ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type AppointmentTimelineSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["appointmentTimelineAgent","handle","args","EDGE_LOAD_THRESHOLD","rootVariants","cva","scrollRegionClasses","localDayKey","d","m","day","groupByDay","items","sorted","a","b","map","item","key","group","AppointmentTimeline","forwardRef","id","nowIso","title","locale","currency","size","showPatient","onOpenAppointment","selectedId","onLoadEarlier","onLoadLater","hasMoreEarlier","hasMoreLater","loadingEarlier","loadingLater","showFilters","onJumpToDate","emptyTitle","emptyDescription","className","ariaLabel","headerExtra","hideDefaultStatus","rest","ref","t","i18n","useTranslation","jumpId","useId","prefersReducedMotion","usePrefersReducedMotion","resolvedLocale","heading","now","useMemo","groups","reduceMotion","flatItemIds","g","i","reflowRef","useListReflow","exitTransition","useExitTransition","prevItemsRef","useRef","leavingItems","setLeavingItems","useState","useEffect","prev","currentIds","removed","moreEarlier","moreLater","anchorKey","todayKey","keys","k","scrollRef","dayElRefs","hasAnchored","prevFirstKey","prevScrollHeight","fadeTop","setFadeTop","fadeBottom","setFadeBottom","updateEdges","useCallback","region","scrollTop","scrollHeight","clientHeight","scrollToKey","targetKey","smooth","el","next","delta","useIsomorphicLayoutEffect","firstKey","_a","grew","observer","handleScroll","jumpTo","date","known","handleToday","handleThisWeek","start","dow","handleThisMonth","itemsRef","innerRef","useImperativeHandle","targetId","found","useAgentRegistration","isEmpty","loadingRow","jsx","Skeleton","jsxs","PanelHeader","CalendarDays","Fragment","ButtonGroup","Button","DatePicker","EmptyState","node","DayHeader","AppointmentCard","REFLOW_ROW_CLASS","todayLabel","tomorrowLabel","yesterdayLabel","tomorrow","yesterday","isToday","label","sameYear"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { jsx as C, jsxs as M } from "react/jsx-runtime";
|
|
2
2
|
import { createElement as G, useRef as k, useEffect as ae, useCallback as K, forwardRef as be, useState as ie, useImperativeHandle as ge, useMemo as X } from "react";
|
|
3
3
|
import { useTranslation as Y } from "react-i18next";
|
|
4
|
-
import { a as b, T as g, D as S, d as Ce } from "./data-table-
|
|
4
|
+
import { a as b, T as g, D as S, d as Ce } from "./data-table-Yn5xiGzs.js";
|
|
5
5
|
import { A as ve, a as re } from "./actions-cell-renderer-Dj1ZkvJj.js";
|
|
6
6
|
import { S as Te } from "./select-Ce5RMk93.js";
|
|
7
7
|
import { u as we } from "./registry-DvAUVLHh.js";
|
|
8
|
-
import { I as Ne, L as Fe, b as z, a as H, c as $, N as j, d as w, S as N, T as le, D as Q, g as Re, f as Ie, U as ye, e as Pe, h as Se } from "./link-cell-renderer-
|
|
8
|
+
import { I as Ne, L as Fe, b as z, a as H, c as $, N as j, d as w, S as N, T as le, D as Q, g as Re, f as Ie, U as ye, e as Pe, h as Se } from "./link-cell-renderer-C1wOyxDF.js";
|
|
9
9
|
import { T as We } from "./transaction-chip-CohY6sTA.js";
|
|
10
10
|
import { B as oe } from "./badge-hnBt8o7n.js";
|
|
11
11
|
import { c as Ae } from "./index-D2ZczOXr.js";
|
|
@@ -1179,4 +1179,4 @@ export {
|
|
|
1179
1179
|
se as g,
|
|
1180
1180
|
nt as u
|
|
1181
1181
|
};
|
|
1182
|
-
//# sourceMappingURL=balance-badge-cell-
|
|
1182
|
+
//# sourceMappingURL=balance-badge-cell-CGoJZlKf.js.map
|