@alfadocs/ui-kit-debug 1.133.0 → 1.134.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/{agenda-card-B8hV3dZV.js → agenda-card-B9wgX_Ed.js} +2 -2
- package/dist/_chunks/{agenda-card-B8hV3dZV.js.map → agenda-card-B9wgX_Ed.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-Bu46s3dI.js → agenda-tray-CGcS_qoM.js} +2 -2
- package/dist/_chunks/{agenda-tray-Bu46s3dI.js.map → agenda-tray-CGcS_qoM.js.map} +1 -1
- package/dist/_chunks/appointment-card-DG3m9yN-.js +504 -0
- package/dist/_chunks/appointment-card-DG3m9yN-.js.map +1 -0
- package/dist/_chunks/{appointment-peek-DZa6xyUb.js → appointment-peek-BK0tDs4C.js} +2 -2
- package/dist/_chunks/{appointment-peek-DZa6xyUb.js.map → appointment-peek-BK0tDs4C.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-DQePqpyH.js → appointment-timeline-BiI2riRZ.js} +2 -2
- package/dist/_chunks/{appointment-timeline-DQePqpyH.js.map → appointment-timeline-BiI2riRZ.js.map} +1 -1
- package/dist/_chunks/appointment-tray-ClJCtYQj.js +200 -0
- package/dist/_chunks/appointment-tray-ClJCtYQj.js.map +1 -0
- package/dist/_chunks/{appointment-workflow-status-DMjuIK90.js → appointment-workflow-status-S-lx81Yz.js} +2 -2
- package/dist/_chunks/{appointment-workflow-status-DMjuIK90.js.map → appointment-workflow-status-S-lx81Yz.js.map} +1 -1
- package/dist/_chunks/ban-CiSCCcOE.js +15 -0
- package/dist/_chunks/ban-CiSCCcOE.js.map +1 -0
- package/dist/_chunks/{calendar-BIoOeBTT.js → calendar-CyLtLBNP.js} +2 -2
- package/dist/_chunks/{calendar-BIoOeBTT.js.map → calendar-CyLtLBNP.js.map} +1 -1
- package/dist/_chunks/{calendar-appointment-editor-dialog-BHx6kUhX.js → calendar-appointment-editor-dialog-BSkIYGlW.js} +13 -13
- package/dist/_chunks/{calendar-appointment-editor-dialog-BHx6kUhX.js.map → calendar-appointment-editor-dialog-BSkIYGlW.js.map} +1 -1
- package/dist/_chunks/{calendar-event-card-BNEzkjm-.js → calendar-event-card-BJifpYZQ.js} +7 -6
- package/dist/_chunks/{calendar-event-card-BNEzkjm-.js.map → calendar-event-card-BJifpYZQ.js.map} +1 -1
- package/dist/_chunks/{care-plan-card-DKScH9Ss.js → care-plan-card-CjHq6PLo.js} +6 -6
- package/dist/_chunks/{care-plan-card-DKScH9Ss.js.map → care-plan-card-CjHq6PLo.js.map} +1 -1
- package/dist/_chunks/{care-plan-entry-card-AG1y3nyW.js → care-plan-entry-card-DY1toF6E.js} +2 -2
- package/dist/_chunks/{care-plan-entry-card-AG1y3nyW.js.map → care-plan-entry-card-DY1toF6E.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-Dx5OMkc9.js → care-plan-header-CeFXUDnL.js} +6 -6
- package/dist/_chunks/{care-plan-header-Dx5OMkc9.js.map → care-plan-header-CeFXUDnL.js.map} +1 -1
- package/dist/_chunks/check-in-documents-CEVcgcYZ.js +136 -0
- package/dist/_chunks/check-in-documents-CEVcgcYZ.js.map +1 -0
- package/dist/_chunks/{clinical-note-card-pPaeWWnu.js → clinical-note-card-D--IwbZa.js} +2 -2
- package/dist/_chunks/{clinical-note-card-pPaeWWnu.js.map → clinical-note-card-D--IwbZa.js.map} +1 -1
- package/dist/_chunks/document-preview-DLVIrOYV.js +385 -0
- package/dist/_chunks/document-preview-DLVIrOYV.js.map +1 -0
- package/dist/_chunks/{entity-card-fpm-KUKc.js → entity-card-p-LANpYt.js} +18 -17
- package/dist/_chunks/{entity-card-fpm-KUKc.js.map → entity-card-p-LANpYt.js.map} +1 -1
- package/dist/_chunks/{error-page-B0fGNTRB.js → error-page-WLhmWUTq.js} +100 -115
- package/dist/_chunks/error-page-WLhmWUTq.js.map +1 -0
- package/dist/_chunks/finished-terminal-unDnXT4j.js +191 -0
- package/dist/_chunks/finished-terminal-unDnXT4j.js.map +1 -0
- package/dist/_chunks/house-DGCypGTo.js +21 -0
- package/dist/_chunks/house-DGCypGTo.js.map +1 -0
- package/dist/_chunks/is-safe-url-CEy9CEml.js +8 -0
- package/dist/_chunks/is-safe-url-CEy9CEml.js.map +1 -0
- package/dist/_chunks/keypad-DBH_keVs.js +152 -0
- package/dist/_chunks/keypad-DBH_keVs.js.map +1 -0
- package/dist/_chunks/keypad-button-mOaPQRrH.js +114 -0
- package/dist/_chunks/keypad-button-mOaPQRrH.js.map +1 -0
- package/dist/_chunks/{message-card-BG3_3nN1.js → message-card-Bw_q1qKx.js} +2 -2
- package/dist/_chunks/{message-card-BG3_3nN1.js.map → message-card-Bw_q1qKx.js.map} +1 -1
- package/dist/_chunks/{message-tray-BjZv0Fsk.js → message-tray-pLGgLmoG.js} +2 -2
- package/dist/_chunks/{message-tray-BjZv0Fsk.js.map → message-tray-pLGgLmoG.js.map} +1 -1
- package/dist/_chunks/{note-attachment-MNTIqdSz.js → note-attachment-JTIy9iXN.js} +2 -2
- package/dist/_chunks/{note-attachment-MNTIqdSz.js.map → note-attachment-JTIy9iXN.js.map} +1 -1
- package/dist/_chunks/{note-timeline-BQeW0VZY.js → note-timeline-BbjHMhkL.js} +2 -2
- package/dist/_chunks/{note-timeline-BQeW0VZY.js.map → note-timeline-BbjHMhkL.js.map} +1 -1
- package/dist/_chunks/{notes-panel-Cm-_pCRJ.js → notes-panel-BAyPOr8N.js} +2 -2
- package/dist/_chunks/{notes-panel-Cm-_pCRJ.js.map → notes-panel-BAyPOr8N.js.map} +1 -1
- package/dist/_chunks/{operator-hero-CnfWckNQ.js → operator-hero-D4wfVu2l.js} +2 -2
- package/dist/_chunks/{operator-hero-CnfWckNQ.js.map → operator-hero-D4wfVu2l.js.map} +1 -1
- package/dist/_chunks/otp-input-BNOTlxq3.js +342 -0
- package/dist/_chunks/otp-input-BNOTlxq3.js.map +1 -0
- package/dist/_chunks/patient-account-settings-BkAtIxJW.js +546 -0
- package/dist/_chunks/patient-account-settings-BkAtIxJW.js.map +1 -0
- package/dist/_chunks/patient-card-DTh3QTyS.js +125 -0
- package/dist/_chunks/patient-card-DTh3QTyS.js.map +1 -0
- package/dist/_chunks/patient-check-in-resume-xhqjC6gf.js +742 -0
- package/dist/_chunks/patient-check-in-resume-xhqjC6gf.js.map +1 -0
- package/dist/_chunks/patient-sign-in-pin-CDBqV254.js +432 -0
- package/dist/_chunks/patient-sign-in-pin-CDBqV254.js.map +1 -0
- package/dist/_chunks/patient-sign-in-steps-C2JSqlok.js +199 -0
- package/dist/_chunks/patient-sign-in-steps-C2JSqlok.js.map +1 -0
- package/dist/_chunks/{patient-summary-card-BUcZ-gaL.js → patient-summary-card-Bl2NknPe.js} +2 -2
- package/dist/_chunks/{patient-summary-card-BUcZ-gaL.js.map → patient-summary-card-Bl2NknPe.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-Dv4WbRBe.js → payment-request-card-CNW00DCx.js} +6 -6
- package/dist/_chunks/{payment-request-card-Dv4WbRBe.js.map → payment-request-card-CNW00DCx.js.map} +1 -1
- package/dist/_chunks/{pdf-viewer-BnBKdx0y.js → pdf-viewer-TRC5jEm5.js} +472 -425
- package/dist/_chunks/pdf-viewer-TRC5jEm5.js.map +1 -0
- package/dist/_chunks/pin-entry-BugWQMOS.js +219 -0
- package/dist/_chunks/pin-entry-BugWQMOS.js.map +1 -0
- package/dist/_chunks/pin-indicator-Cb-n40UI.js +124 -0
- package/dist/_chunks/pin-indicator-Cb-n40UI.js.map +1 -0
- package/dist/_chunks/portal-details-CTEsm705.js +478 -0
- package/dist/_chunks/portal-details-CTEsm705.js.map +1 -0
- package/dist/_chunks/portal-documents-D8skew0h.js +902 -0
- package/dist/_chunks/portal-documents-D8skew0h.js.map +1 -0
- package/dist/_chunks/portal-parts-BdR29P7z.js +285 -0
- package/dist/_chunks/portal-parts-BdR29P7z.js.map +1 -0
- package/dist/_chunks/{privacy-mask-DJ1gee4c.js → privacy-mask-C19dJFMk.js} +5 -5
- package/dist/_chunks/{privacy-mask-DJ1gee4c.js.map → privacy-mask-C19dJFMk.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-a8wdVOUt.js → product-hub-panel-K4QbULG7.js} +2 -2
- package/dist/_chunks/{product-hub-panel-a8wdVOUt.js.map → product-hub-panel-K4QbULG7.js.map} +1 -1
- package/dist/_chunks/{registration-form-CwbhtKcy.js → registration-form-DS3RuKHu.js} +2 -2
- package/dist/_chunks/{registration-form-CwbhtKcy.js.map → registration-form-DS3RuKHu.js.map} +1 -1
- package/dist/_chunks/{reserved.agent-W8mR179D.js → reserved.agent-DOzOBUW7.js} +2 -2
- package/dist/_chunks/{reserved.agent-W8mR179D.js.map → reserved.agent-DOzOBUW7.js.map} +1 -1
- package/dist/_chunks/session-countdown-DOx1IBUB.js +232 -0
- package/dist/_chunks/session-countdown-DOx1IBUB.js.map +1 -0
- package/dist/_chunks/{sign-document-CQZVzfpk.js → sign-document-DDZbmYHu.js} +2 -2
- package/dist/_chunks/{sign-document-CQZVzfpk.js.map → sign-document-DDZbmYHu.js.map} +1 -1
- package/dist/_chunks/{signature-field-DjabvRZm.js → signature-field-BjlY_yXH.js} +39 -34
- package/dist/_chunks/signature-field-BjlY_yXH.js.map +1 -0
- package/dist/_chunks/{signature-request-4pGq3YBe.js → signature-request-CHsM_iWi.js} +2 -2
- package/dist/_chunks/{signature-request-4pGq3YBe.js.map → signature-request-CHsM_iWi.js.map} +1 -1
- package/dist/_chunks/{signature-status-chip-pIoQjvH8.js → signature-status-chip-DS9hHwIt.js} +66 -69
- package/dist/_chunks/signature-status-chip-DS9hHwIt.js.map +1 -0
- package/dist/_chunks/signing-end-screen-an9P8DOT.js +1041 -0
- package/dist/_chunks/signing-end-screen-an9P8DOT.js.map +1 -0
- package/dist/_chunks/sms-code-entry-Dgp4GwlM.js +316 -0
- package/dist/_chunks/sms-code-entry-Dgp4GwlM.js.map +1 -0
- package/dist/_chunks/step-up-dialog-C2JqJmCA.js +132 -0
- package/dist/_chunks/step-up-dialog-C2JqJmCA.js.map +1 -0
- package/dist/_chunks/{task-editor-BL2hHxNz.js → task-editor-g1AGfxhr.js} +38 -38
- package/dist/_chunks/{task-editor-BL2hHxNz.js.map → task-editor-g1AGfxhr.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-_b7FRB1x.js → use-appointment-details-read-Dzc6fEzG.js} +6 -6
- package/dist/_chunks/{use-appointment-details-read-_b7FRB1x.js.map → use-appointment-details-read-Dzc6fEzG.js.map} +1 -1
- package/dist/_chunks/use-zoom-drilldown-Cr1baU5X.js +221 -0
- package/dist/_chunks/use-zoom-drilldown-Cr1baU5X.js.map +1 -0
- package/dist/_chunks/{user-x-DYszNtIg.js → user-x-BJZg4kaP.js} +8 -19
- package/dist/_chunks/user-x-BJZg4kaP.js.map +1 -0
- package/dist/_chunks/{verify-identity-types-CxtrBXsZ.js → verify-identity-types-C6Bam8v6.js} +2 -2
- package/dist/_chunks/{verify-identity-types-CxtrBXsZ.js.map → verify-identity-types-C6Bam8v6.js.map} +1 -1
- package/dist/agent-catalog.json +723 -364
- package/dist/agent-i18n/en.json +75 -18
- package/dist/browser-support.js +1 -1
- package/dist/components/_shared/is-safe-url.d.ts +3 -1
- package/dist/components/_shared/is-safe-url.d.ts.map +1 -1
- package/dist/components/agenda-card/index.js +2 -2
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/appointment-card/appointment-card.d.ts +45 -0
- package/dist/components/appointment-card/appointment-card.d.ts.map +1 -1
- package/dist/components/appointment-card/appointment-tray.agent.d.ts.map +1 -1
- package/dist/components/appointment-card/appointment-tray.d.ts +11 -0
- package/dist/components/appointment-card/appointment-tray.d.ts.map +1 -1
- package/dist/components/appointment-card/index.js +3 -3
- 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/calendar/index.js +1 -1
- package/dist/components/calendar-event-card/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-entry-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/document-preview/document-preview.agent.d.ts.map +1 -1
- package/dist/components/document-preview/document-preview.d.ts +61 -7
- package/dist/components/document-preview/document-preview.d.ts.map +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/finished-terminal/finished-terminal.d.ts +63 -6
- package/dist/components/finished-terminal/finished-terminal.d.ts.map +1 -1
- package/dist/components/finished-terminal/index.d.ts +1 -1
- package/dist/components/finished-terminal/index.d.ts.map +1 -1
- package/dist/components/finished-terminal/index.js +1 -1
- package/dist/components/index.d.ts +12 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/keypad/index.d.ts +3 -0
- package/dist/components/keypad/index.d.ts.map +1 -0
- package/dist/components/keypad/index.js +6 -0
- package/dist/components/keypad/index.js.map +1 -0
- package/dist/components/keypad/keypad.d.ts +54 -0
- package/dist/components/keypad/keypad.d.ts.map +1 -0
- package/dist/components/keypad-button/index.d.ts +3 -0
- package/dist/components/keypad-button/index.d.ts.map +1 -0
- package/dist/components/keypad-button/index.js +6 -0
- package/dist/components/keypad-button/index.js.map +1 -0
- package/dist/components/keypad-button/keypad-button.d.ts +33 -0
- package/dist/components/keypad-button/keypad-button.d.ts.map +1 -0
- package/dist/components/message-card/index.js +2 -2
- package/dist/components/message-tray/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/operator-hero/index.js +1 -1
- package/dist/components/otp-input/index.js +1 -1
- package/dist/components/otp-input/otp-input.d.ts +11 -0
- package/dist/components/otp-input/otp-input.d.ts.map +1 -1
- package/dist/components/patient-summary-card/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.agent.d.ts.map +1 -1
- package/dist/components/pdf-viewer/pdf-viewer.d.ts +7 -0
- package/dist/components/pdf-viewer/pdf-viewer.d.ts.map +1 -1
- package/dist/components/pin-entry/index.d.ts +3 -0
- package/dist/components/pin-entry/index.d.ts.map +1 -0
- package/dist/components/pin-entry/index.js +5 -0
- package/dist/components/pin-entry/index.js.map +1 -0
- package/dist/components/pin-entry/pin-entry.agent.d.ts +4 -0
- package/dist/components/pin-entry/pin-entry.agent.d.ts.map +1 -0
- package/dist/components/pin-entry/pin-entry.d.ts +64 -0
- package/dist/components/pin-entry/pin-entry.d.ts.map +1 -0
- package/dist/components/pin-indicator/index.d.ts +3 -0
- package/dist/components/pin-indicator/index.d.ts.map +1 -0
- package/dist/components/pin-indicator/index.js +9 -0
- package/dist/components/pin-indicator/index.js.map +1 -0
- package/dist/components/pin-indicator/pin-indicator.d.ts +34 -0
- package/dist/components/pin-indicator/pin-indicator.d.ts.map +1 -0
- package/dist/components/product-hub-tray/index.js +2 -2
- package/dist/components/session-countdown/index.js +1 -1
- package/dist/components/session-countdown/session-countdown.d.ts +19 -0
- package/dist/components/session-countdown/session-countdown.d.ts.map +1 -1
- package/dist/components/sign-document/index.js +1 -1
- package/dist/components/signature-field/index.js +1 -1
- package/dist/components/signature-field/signature-field.d.ts +17 -6
- package/dist/components/signature-field/signature-field.d.ts.map +1 -1
- package/dist/components/signature-status-chip/index.js +1 -1
- package/dist/components/signature-status-chip/signature-status-chip.d.ts +3 -2
- package/dist/components/signature-status-chip/signature-status-chip.d.ts.map +1 -1
- package/dist/components/sms-code-entry/index.d.ts +3 -0
- package/dist/components/sms-code-entry/index.d.ts.map +1 -0
- package/dist/components/sms-code-entry/index.js +5 -0
- package/dist/components/sms-code-entry/index.js.map +1 -0
- package/dist/components/sms-code-entry/sms-code-entry.agent.d.ts +4 -0
- package/dist/components/sms-code-entry/sms-code-entry.agent.d.ts.map +1 -0
- package/dist/components/sms-code-entry/sms-code-entry.d.ts +156 -0
- package/dist/components/sms-code-entry/sms-code-entry.d.ts.map +1 -0
- package/dist/components/step-up-dialog/index.d.ts +3 -0
- package/dist/components/step-up-dialog/index.d.ts.map +1 -0
- package/dist/components/step-up-dialog/index.js +5 -0
- package/dist/components/step-up-dialog/index.js.map +1 -0
- package/dist/components/step-up-dialog/step-up-dialog.d.ts +108 -0
- package/dist/components/step-up-dialog/step-up-dialog.d.ts.map +1 -0
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/workflow-status/index.js +1 -1
- package/dist/core.css +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/use-signing-session.d.ts +7 -2
- package/dist/hooks/use-signing-session.d.ts.map +1 -1
- package/dist/host-compat.css +10 -1
- package/dist/i18n/locales/ar.d.ts +512 -1
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +509 -3
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +512 -1
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +517 -4
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +512 -1
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +512 -4
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +514 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +520 -4
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +512 -1
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +510 -4
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +512 -1
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +510 -4
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +512 -1
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +510 -4
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +512 -1
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +517 -4
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +512 -1
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +510 -4
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +512 -1
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +517 -4
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +512 -1
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +517 -4
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +512 -1
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +517 -4
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +512 -1
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +517 -4
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +512 -1
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +509 -3
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +512 -1
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +510 -4
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +512 -1
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +510 -4
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +512 -1
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +512 -4
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +512 -1
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +510 -4
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +1271 -1204
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +513 -2
- package/dist/locales/de.json +514 -3
- package/dist/locales/el.json +514 -3
- package/dist/locales/en.json +514 -3
- package/dist/locales/es.json +514 -3
- package/dist/locales/fr.json +514 -3
- package/dist/locales/hi.json +514 -3
- package/dist/locales/it.json +514 -3
- package/dist/locales/ja.json +514 -3
- package/dist/locales/nl.json +514 -3
- package/dist/locales/pl.json +514 -3
- package/dist/locales/pt.json +514 -3
- package/dist/locales/ro.json +514 -3
- package/dist/locales/ru.json +513 -2
- package/dist/locales/sq.json +514 -3
- package/dist/locales/sv.json +514 -3
- package/dist/locales/tr.json +514 -3
- package/dist/locales/zh.json +514 -3
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/check-in-documents/check-in-documents.d.ts +61 -0
- package/dist/patterns/check-in-documents/check-in-documents.d.ts.map +1 -0
- package/dist/patterns/check-in-documents/check-in-signable-document.d.ts +32 -0
- package/dist/patterns/check-in-documents/check-in-signable-document.d.ts.map +1 -0
- package/dist/patterns/check-in-documents/index.d.ts +4 -0
- package/dist/patterns/check-in-documents/index.d.ts.map +1 -0
- package/dist/patterns/check-in-documents/index.js +5 -0
- package/dist/patterns/check-in-documents/index.js.map +1 -0
- package/dist/patterns/error-page/index.js +1 -1
- package/dist/patterns/patient-account-settings/index.d.ts +4 -0
- package/dist/patterns/patient-account-settings/index.d.ts.map +1 -0
- package/dist/patterns/patient-account-settings/index.js +5 -0
- package/dist/patterns/patient-account-settings/index.js.map +1 -0
- package/dist/patterns/patient-account-settings/patient-account-settings-panels.d.ts +36 -0
- package/dist/patterns/patient-account-settings/patient-account-settings-panels.d.ts.map +1 -0
- package/dist/patterns/patient-account-settings/patient-account-settings.d.ts +94 -0
- package/dist/patterns/patient-account-settings/patient-account-settings.d.ts.map +1 -0
- package/dist/patterns/patient-account-settings/patient-account-settings.types.d.ts +91 -0
- package/dist/patterns/patient-account-settings/patient-account-settings.types.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/index.d.ts +20 -0
- package/dist/patterns/patient-check-in/index.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/index.js +13 -0
- package/dist/patterns/patient-check-in/index.js.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-changed.d.ts +33 -0
- package/dist/patterns/patient-check-in/patient-check-in-changed.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-connection-notice.d.ts +29 -0
- package/dist/patterns/patient-check-in/patient-check-in-connection-notice.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-done.d.ts +25 -0
- package/dist/patterns/patient-check-in/patient-check-in-done.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-entry.d.ts +29 -0
- package/dist/patterns/patient-check-in/patient-check-in-entry.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-hub-empty.d.ts +23 -0
- package/dist/patterns/patient-check-in/patient-check-in-hub-empty.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-hub.d.ts +61 -0
- package/dist/patterns/patient-check-in/patient-check-in-hub.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-personal-data.d.ts +73 -0
- package/dist/patterns/patient-check-in/patient-check-in-personal-data.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-privacy.d.ts +9 -0
- package/dist/patterns/patient-check-in/patient-check-in-privacy.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-resume.d.ts +29 -0
- package/dist/patterns/patient-check-in/patient-check-in-resume.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-shell.d.ts +60 -0
- package/dist/patterns/patient-check-in/patient-check-in-shell.d.ts.map +1 -0
- package/dist/patterns/patient-check-in/patient-check-in-types.d.ts +92 -0
- package/dist/patterns/patient-check-in/patient-check-in-types.d.ts.map +1 -0
- package/dist/patterns/patient-portal/index.d.ts +12 -0
- package/dist/patterns/patient-portal/index.d.ts.map +1 -0
- package/dist/patterns/patient-portal/index.js +13 -0
- package/dist/patterns/patient-portal/index.js.map +1 -0
- package/dist/patterns/patient-portal/portal-appointments.d.ts +70 -0
- package/dist/patterns/patient-portal/portal-appointments.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-details.d.ts +148 -0
- package/dist/patterns/patient-portal/portal-details.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-documents.d.ts +74 -0
- package/dist/patterns/patient-portal/portal-documents.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-format.d.ts +14 -0
- package/dist/patterns/patient-portal/portal-format.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-home.d.ts +71 -0
- package/dist/patterns/patient-portal/portal-home.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-parts.d.ts +107 -0
- package/dist/patterns/patient-portal/portal-parts.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-shell.d.ts +84 -0
- package/dist/patterns/patient-portal/portal-shell.d.ts.map +1 -0
- package/dist/patterns/patient-portal/portal-types.d.ts +157 -0
- package/dist/patterns/patient-portal/portal-types.d.ts.map +1 -0
- package/dist/patterns/patient-sign-in/index.d.ts +7 -0
- package/dist/patterns/patient-sign-in/index.d.ts.map +1 -0
- package/dist/patterns/patient-sign-in/index.js +15 -0
- package/dist/patterns/patient-sign-in/index.js.map +1 -0
- package/dist/patterns/patient-sign-in/patient-card.d.ts +74 -0
- package/dist/patterns/patient-sign-in/patient-card.d.ts.map +1 -0
- package/dist/patterns/patient-sign-in/patient-sign-in-email.d.ts +109 -0
- package/dist/patterns/patient-sign-in/patient-sign-in-email.d.ts.map +1 -0
- package/dist/patterns/patient-sign-in/patient-sign-in-pin.d.ts +157 -0
- package/dist/patterns/patient-sign-in/patient-sign-in-pin.d.ts.map +1 -0
- package/dist/patterns/patient-sign-in/patient-sign-in-steps.d.ts +143 -0
- package/dist/patterns/patient-sign-in/patient-sign-in-steps.d.ts.map +1 -0
- package/dist/patterns/registration-form/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/patterns/signing/index.d.ts +25 -0
- package/dist/patterns/signing/index.d.ts.map +1 -0
- package/dist/patterns/signing/index.js +16 -0
- package/dist/patterns/signing/index.js.map +1 -0
- package/dist/patterns/signing/multi-field-signer.d.ts +117 -0
- package/dist/patterns/signing/multi-field-signer.d.ts.map +1 -0
- package/dist/patterns/signing/signing-awaiting-screen.d.ts +25 -0
- package/dist/patterns/signing/signing-awaiting-screen.d.ts.map +1 -0
- package/dist/patterns/signing/signing-chrome.d.ts +30 -0
- package/dist/patterns/signing/signing-chrome.d.ts.map +1 -0
- package/dist/patterns/signing/signing-document-screen.d.ts +87 -0
- package/dist/patterns/signing/signing-document-screen.d.ts.map +1 -0
- package/dist/patterns/signing/signing-end-screen.d.ts +27 -0
- package/dist/patterns/signing/signing-end-screen.d.ts.map +1 -0
- package/dist/patterns/signing/signing-finished-screen.d.ts +34 -0
- package/dist/patterns/signing/signing-finished-screen.d.ts.map +1 -0
- package/dist/patterns/signing/signing-footer.d.ts +56 -0
- package/dist/patterns/signing/signing-footer.d.ts.map +1 -0
- package/dist/patterns/signing/signing-handoff-screen.d.ts +37 -0
- package/dist/patterns/signing/signing-handoff-screen.d.ts.map +1 -0
- package/dist/patterns/signing/signing-message-dialog.d.ts +29 -0
- package/dist/patterns/signing/signing-message-dialog.d.ts.map +1 -0
- package/dist/patterns/signing/signing-progress-chip.d.ts +27 -0
- package/dist/patterns/signing/signing-progress-chip.d.ts.map +1 -0
- package/dist/patterns/signing/signing-roster.d.ts +44 -0
- package/dist/patterns/signing/signing-roster.d.ts.map +1 -0
- package/dist/patterns/signing/signing-staff-id-confirmation.d.ts +49 -0
- package/dist/patterns/signing/signing-staff-id-confirmation.d.ts.map +1 -0
- package/dist/patterns/verify-identity/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +49 -1
- package/dist/_chunks/appointment-card-OAOur8lH.js +0 -434
- package/dist/_chunks/appointment-card-OAOur8lH.js.map +0 -1
- package/dist/_chunks/appointment-tray-DSFqO5Rm.js +0 -193
- package/dist/_chunks/appointment-tray-DSFqO5Rm.js.map +0 -1
- package/dist/_chunks/document-preview-_kQ9QvZV.js +0 -291
- package/dist/_chunks/document-preview-_kQ9QvZV.js.map +0 -1
- package/dist/_chunks/error-page-B0fGNTRB.js.map +0 -1
- package/dist/_chunks/finished-terminal-FR8uc_Ws.js +0 -122
- package/dist/_chunks/finished-terminal-FR8uc_Ws.js.map +0 -1
- package/dist/_chunks/is-safe-url-DkETxeHz.js +0 -7
- package/dist/_chunks/is-safe-url-DkETxeHz.js.map +0 -1
- package/dist/_chunks/otp-input-gV1446Dw.js +0 -301
- package/dist/_chunks/otp-input-gV1446Dw.js.map +0 -1
- package/dist/_chunks/pdf-viewer-BnBKdx0y.js.map +0 -1
- package/dist/_chunks/session-countdown-C4tzbJVc.js +0 -223
- package/dist/_chunks/session-countdown-C4tzbJVc.js.map +0 -1
- package/dist/_chunks/signature-field-DjabvRZm.js.map +0 -1
- package/dist/_chunks/signature-status-chip-pIoQjvH8.js.map +0 -1
- package/dist/_chunks/use-zoom-drilldown-qCX34w9I.js +0 -210
- package/dist/_chunks/use-zoom-drilldown-qCX34w9I.js.map +0 -1
- package/dist/_chunks/user-x-DYszNtIg.js.map +0 -1
|
@@ -2,7 +2,8 @@ import { jsx as a, jsxs as f, Fragment as K } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as re } from "react";
|
|
3
3
|
import { useTranslation as de } from "react-i18next";
|
|
4
4
|
import { c as s } from "./index-D2ZczOXr.js";
|
|
5
|
-
import { U as se,
|
|
5
|
+
import { U as se, T as te } from "./user-x-BJZg4kaP.js";
|
|
6
|
+
import { B as ie } from "./ban-CiSCCcOE.js";
|
|
6
7
|
import { C as le } from "./check-DrFSN__t.js";
|
|
7
8
|
import { S as ce } from "./stethoscope-sZXGC43m.js";
|
|
8
9
|
import { C as oe } from "./clock-Drd4Wtis.js";
|
|
@@ -34,18 +35,18 @@ function xe([t, d, n]) {
|
|
|
34
35
|
const e = (i) => i <= 0.03928 ? i / 12.92 : Math.pow((i + 0.055) / 1.055, 2.4);
|
|
35
36
|
return 0.2126 * e(t) + 0.7152 * e(d) + 0.0722 * e(n);
|
|
36
37
|
}
|
|
37
|
-
function
|
|
38
|
+
function ln(t, d, n) {
|
|
38
39
|
}
|
|
39
40
|
function ye(t) {
|
|
40
41
|
const d = be(t);
|
|
41
42
|
return d ? xe(d) > 0.1791 ? "on-light" : "on-dark" : null;
|
|
42
43
|
}
|
|
43
44
|
const ke = {
|
|
44
|
-
confirmed:
|
|
45
|
+
confirmed: te,
|
|
45
46
|
waiting: oe,
|
|
46
47
|
in_care: ce,
|
|
47
48
|
done: le,
|
|
48
|
-
cancelled:
|
|
49
|
+
cancelled: ie,
|
|
49
50
|
absent: se
|
|
50
51
|
}, _e = "ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]", Se = "ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none", Ne = {
|
|
51
52
|
success: "ds:text-[color:var(--success-foreground)]",
|
|
@@ -608,6 +609,6 @@ export {
|
|
|
608
609
|
ze as E,
|
|
609
610
|
ke as S,
|
|
610
611
|
O as a,
|
|
611
|
-
|
|
612
|
+
ln as w
|
|
612
613
|
};
|
|
613
|
-
//# sourceMappingURL=calendar-event-card-
|
|
614
|
+
//# sourceMappingURL=calendar-event-card-BJifpYZQ.js.map
|
package/dist/_chunks/{calendar-event-card-BNEzkjm-.js.map → calendar-event-card-BJifpYZQ.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar-event-card-BNEzkjm-.js","sources":["../../src/components/_shared/contrast-warning.ts","../../src/components/calendar-event-card/calendar-event-card.tsx"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* Shared contrast guardrail — Calendar + CalendarEventCard */\n/* */\n/* The consuming app supplies runtime hex pairs at several surfaces: */\n/* - event.backgroundColor / event.textColor (+ event.borderColor) */\n/* - modeBannerColor / modeBannerTextColor */\n/* - resource.color / resource.shortTitleTextColor */\n/* */\n/* When the text half of the pair is also a hex (i.e. both halves come */\n/* from the caller), we can validate them synchronously and warn the */\n/* consuming-app developer during DEV if the pair fails WCAG AA normal */\n/* text (4.5:1). When only the background half is supplied, */\n/* `resolveInk` derives a provably AA-safe black/white ink for it. */\n/* Every helper is a no-op in production builds. */\n/* ------------------------------------------------------------------ */\n\n/* Module-level dedup set — keyed on the (bg, fg, context) tuple so the\n same bad pair moving around the calendar only warns once per session.\n Exposed via `resetContrastWarnings()` for test isolation. */\nconst warnedTuples = new Set<string>();\n\n/** Reset the dedup set — intended for use between tests. */\nexport function resetContrastWarnings(): void {\n warnedTuples.clear();\n}\n\n/**\n * Parse a 3-char or 6-char `#RRGGBB` hex string into a linear sRGB\n * triple in the [0,1] range. Returns `null` for any input the caller\n * can't parse (malformed prefix, bad length, non-hex characters) —\n * the helper stays silent in that case rather than emitting noise.\n */\nfunction parseHex(hex: string): [number, number, number] | null {\n if (typeof hex !== 'string') return null;\n const trimmed = hex.trim();\n if (!trimmed.startsWith('#')) return null;\n const body = trimmed.slice(1);\n let r: number;\n let g: number;\n let b: number;\n if (body.length === 3) {\n if (!/^[0-9a-f]{3}$/i.test(body)) return null;\n r = parseInt(body[0] + body[0], 16);\n g = parseInt(body[1] + body[1], 16);\n b = parseInt(body[2] + body[2], 16);\n } else if (body.length === 6) {\n if (!/^[0-9a-f]{6}$/i.test(body)) return null;\n r = parseInt(body.slice(0, 2), 16);\n g = parseInt(body.slice(2, 4), 16);\n b = parseInt(body.slice(4, 6), 16);\n } else {\n return null;\n }\n return [r / 255, g / 255, b / 255];\n}\n\n/**\n * WCAG 2.1 relative luminance. Each channel is gamma-corrected then\n * weighted against the CIE photopic sensitivity of the human eye.\n * https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const lin = (c: number): number =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);\n}\n\n/**\n * WCAG 2.1 contrast ratio. Always returns a value in [1, 21]; the\n * relative-luminance lighter-over-darker convention is applied here.\n */\nfunction contrastRatio(\n bg: [number, number, number],\n fg: [number, number, number],\n): number {\n const l1 = relativeLuminance(bg);\n const l2 = relativeLuminance(fg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * DEV-only WCAG AA guardrail for caller-supplied hex pairs.\n *\n * - No-op when `import.meta.env.DEV` is false.\n * - No-op when either half of the pair is missing (the \"fg missing →\n * inherits DS token\" case is a docs concern; the DS token isn't a\n * hex at runtime so we can't check it here).\n * - No-op when either hex can't be parsed (silent — not the helper's\n * concern to police malformed input).\n * - Deduplicated by `(bgHex, fgHex, contextLabel)` tuple so moving a\n * ratio-bad event around the calendar doesn't spam the console.\n *\n * @param bgHex - Caller-supplied background hex (e.g. `'#c2185b'`)\n * @param fgHex - Caller-supplied foreground hex (e.g. `'#ffffff'`)\n * @param contextLabel - Short description for the warning (e.g. `'event e1'`).\n */\nexport function warnLowContrast(\n bgHex: string | undefined,\n fgHex: string | undefined,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (!bgHex || !fgHex) return;\n\n const bg = parseHex(bgHex);\n const fg = parseHex(fgHex);\n if (!bg || !fg) return;\n\n const ratio = contrastRatio(bg, fg);\n if (ratio >= 4.5) return;\n\n const key = `${bgHex}|${fgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n /* `bg` parsed successfully above, so `resolveInk(bgHex)` is guaranteed\n to produce a compliant ink — the omit-textColor hint is always valid\n at this point. */\n console.warn(\n `[Calendar] Low contrast on ${contextLabel}: ${bgHex} / ${fgHex} (ratio ${ratio.toFixed(\n 2,\n )}, target 4.5). Pass a matching textColor/fgHex, pick a higher-contrast background, or omit textColor to let the kit choose a compliant ink.`,\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Ink derivation — bg-only caller colours */\n/* ------------------------------------------------------------------ */\n\nexport type EventInk = 'on-light' | 'on-dark';\n\n/**\n * Pick the ink for an arbitrary opaque bg hex. Returns `null` when the\n * input can't be parsed (`#rgb` / `#rrggbb` only).\n *\n * The threshold 0.1791 is the relative luminance at which\n * `contrast(bg, #fff) === contrast(bg, #000)`; the better of the two\n * always yields ≥ 4.58:1 (the minimum, at a mid-grey ≈ `#757575`) —\n * provably WCAG AA-safe for any opaque background.\n */\nexport function resolveInk(bgHex: string): EventInk | null {\n const bg = parseHex(bgHex);\n if (!bg) return null;\n // threshold where contrast(bg, #fff) === contrast(bg, #000)\n return relativeLuminance(bg) > 0.1791 ? 'on-light' : 'on-dark';\n}\n\n/**\n * DEV-only, one-shot warning for a caller `backgroundColor` the kit can't\n * parse (`rgb(…)`, keywords, malformed hex). The browser can still paint\n * it, but the text falls back to the token default and contrast can't be\n * verified. Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnUnparseableBackground(\n bgHex: string,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (parseHex(bgHex)) return;\n\n const key = `unparseable|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Unparseable backgroundColor on ${contextLabel}: \"${bgHex}\". ` +\n `Expected #rgb or #rrggbb — contrast cannot be verified and the text ` +\n `colour falls back to the token default.`,\n );\n}\n\n/**\n * DEV-only, one-shot warning for a near-white `backgroundColor`\n * (relative luminance > 0.9) supplied without a `borderColor` — the\n * event may be invisible against the calendar grid. The kit warns, it\n * does not repaint (delineation is decorative under WCAG 1.4.11 and the\n * consumer owns the picker colour). Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnLowDelineation(bgHex: string, contextLabel: string): void {\n if (!import.meta.env.DEV) return;\n\n const bg = parseHex(bgHex);\n if (!bg) return;\n if (relativeLuminance(bg) <= 0.9) return;\n\n const key = `delineation|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Light backgroundColor without borderColor on ${contextLabel}: ` +\n `${bgHex} may be invisible against the grid — pass a borderColor ` +\n `(the platform convention sends a light-grey border for white backgrounds).`,\n );\n}\n","/* ------------------------------------------------------------------ */\n/* CalendarEventCard — the single painted surface of a calendar event. */\n/* */\n/* Colour model (platform parity): the caller's picker hex */\n/* (backgroundColor / textColor / borderColor) is the ONLY thing that */\n/* paints the card. `status` never paints the surface — it selects an */\n/* icon and (for `cancelled`) a line-through. When no picker colour */\n/* is supplied the surface falls back to the theme's --primary / */\n/* --primary-foreground pair. */\n/* */\n/* Non-interactive by design: inside FullCalendar the outer harness */\n/* anchor owns click/drag/focus; standalone consumers wrap the card in */\n/* their own button/link. No onClick in the contract. */\n/* ------------------------------------------------------------------ */\n\nimport { forwardRef } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport {\n ThumbsUp,\n Clock,\n Stethoscope,\n Check,\n Ban,\n UserX,\n Globe,\n TriangleAlert,\n HeartPulse,\n Euro,\n Video,\n Repeat,\n EyeOff,\n ClipboardCheck,\n type LucideIcon,\n} from 'lucide-react';\n// Type-only import — erased at build, no runtime cycle with calendar.tsx's\n// runtime import of this card. Do NOT convert to a value import.\nimport type { CalendarEventStatus } from '../calendar/calendar';\nimport {\n warnLowContrast,\n resolveInk,\n warnUnparseableBackground,\n warnLowDelineation,\n} from '../_shared/contrast-warning';\n\n/* ------------------------------------------------------------------ */\n/* Status lookups */\n/* ------------------------------------------------------------------ */\n\nexport const STATUS_ICON: Record<CalendarEventStatus, LucideIcon> = {\n confirmed: ThumbsUp,\n waiting: Clock,\n in_care: Stethoscope,\n done: Check,\n cancelled: Ban,\n absent: UserX,\n};\n\n/* Status → i18n key lookup. Kept as a literal object (not a template)\n so static-analysis extractors can find every key. Keys already exist\n in all 18 locale bundles — do not add new ones here. */\n/* Indicator DISC — option D of the design review: each glyph in a small\n circle on the plain card surface (hairline border + row-lift shadow)\n with the SEMANTIC colour as icon ink. Chip-grade contrast on any\n picker colour without a plate; ink tokens mirror Badge's variants so\n the vocabulary stays one system. */\nconst INDICATOR_DISC_BASE =\n 'ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]';\n\n/* DETAILS-PENDING bar — the Skeleton component's own classes, inlined on\n a <span>: Skeleton renders a <div>, which cannot live inside the card's\n inline text cell. Decorative (aria-hidden) because the composed\n aria-label already carries the localised \"loading details\" word. */\nconst PENDING_BAR_CLASS =\n 'ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none';\n\ntype IndicatorTone = 'success' | 'info' | 'warning' | 'error' | 'accent';\n\nconst INDICATOR_DISC_TONE: Record<IndicatorTone, string> = {\n success: 'ds:text-[color:var(--success-foreground)]',\n info: 'ds:text-[color:var(--info-foreground)]',\n warning: 'ds:text-[color:var(--warning-foreground)]',\n error: 'ds:text-[color:var(--error-foreground)]',\n // Same AA-clearing accent mix Badge's accentSoft uses for its ink.\n accent:\n 'ds:text-[color:color-mix(in_srgb,var(--accent)_40%,var(--foreground))]',\n};\n\n/* Status → disc tone — the same semantic mapping as the accent bar. */\nconst STATUS_DISC_TONE: Record<CalendarEventStatus, IndicatorTone> = {\n confirmed: 'success',\n waiting: 'info',\n in_care: 'accent',\n done: 'success',\n cancelled: 'error',\n absent: 'warning',\n};\n\nexport const STATUS_LABEL_KEYS: Record<CalendarEventStatus, string> = {\n confirmed: 'calendar.status.confirmed',\n waiting: 'calendar.status.waiting',\n in_care: 'calendar.status.inCare',\n done: 'calendar.status.done',\n cancelled: 'calendar.status.cancelled',\n absent: 'calendar.status.absent',\n};\n\nexport const EVENT_FLAGS = [\n {\n field: 'hasUnassignedPatient',\n Icon: TriangleAlert,\n labelKey: 'calendarWorkspace.details.indicators.unassignedPatient',\n tone: 'warning',\n },\n {\n field: 'hasHighlightedAnamnesis',\n Icon: HeartPulse,\n labelKey: 'calendarWorkspace.details.indicators.anamnesis',\n tone: 'accent',\n },\n {\n field: 'hasBillableAmount',\n Icon: Euro,\n labelKey: 'calendarWorkspace.details.indicators.billable',\n tone: 'warning',\n },\n {\n field: 'isBookedOnline',\n Icon: Globe,\n labelKey: 'calendarWorkspace.details.indicators.bookedOnline',\n tone: 'info',\n },\n {\n field: 'isTelehealth',\n Icon: Video,\n labelKey: 'calendarWorkspace.details.indicators.telehealth',\n tone: 'info',\n },\n {\n field: 'isRecurring',\n Icon: Repeat,\n labelKey: 'calendarWorkspace.details.indicators.recurring',\n tone: 'info',\n },\n] as const;\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst calendarEventCardVariants = cva(\n [\n // FullCalendar supplies the box. The card is the `eventcard` size\n // container: the `ds:eventcard-*` tier variants (declared in\n // src/styles.css) read its width and height to prioritise identity,\n // then treatment, time and markers.\n 'calendar-event-card ds:relative ds:block ds:[container-name:eventcard]',\n 'ds:w-full',\n 'ds:ps-[var(--spacing-2xs)] ds:pe-[var(--spacing-2xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n // The type-role alias, so the text (and with it every em tier\n // threshold) grows one step under .theme-accessible.\n 'ds:text-[length:var(--type-body-sm-size)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:leading-tight ds:text-start',\n 'ds:overflow-hidden',\n // kept verbatim from the former base (inert on a non-focusable div\n // inside FC; harmless)\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n // SINGLE PAINTED SURFACE — always present, never conditional. One\n // declaration per paint channel; value chain = \"caller custom prop,\n // else token\". This structurally eliminates the CVA-vs-override\n // specificity race (the old double-paint bug) — stylesheet order\n // becomes irrelevant.\n 'ds:[background-color:var(--calendar-event-bg,var(--primary))]',\n 'ds:[color:var(--calendar-event-text,var(--primary-foreground))]',\n 'ds:border ds:[border-color:var(--calendar-event-border,transparent)]',\n ].join(' '),\n {\n variants: {\n layout: {\n // Timed grids: FullCalendar supplies a definite block size. A\n // standalone card with no height falls back to two lines.\n grid: [\n 'ds:h-full ds:[container-type:size] ds:[min-block-size:0]',\n 'ds:[contain-intrinsic-block-size:calc(var(--type-body-sm-size)*var(--calendar-event-line-height)*2)]',\n ].join(' '),\n // Month cells: exactly one line.\n month: [\n 'calendar-event-card--month ds:[container-type:size]',\n 'ds:[block-size:calc(var(--type-body-sm-size)*var(--calendar-event-line-height)_+_var(--spacing-2xs))]',\n ].join(' '),\n // Lists and timelines size from content: width tiers only.\n flow: [\n 'calendar-event-card--flow ds:[container-type:inline-size]',\n 'ds:[min-block-size:calc(var(--type-body-sm-size)*var(--calendar-event-line-height))]',\n ].join(' '),\n },\n // Do not add colour classes to this axis — status is icon + aria\n // only; a unit test asserts identical computed background\n // across all six statuses.\n status: {\n none: '',\n confirmed: '',\n waiting: '',\n in_care: '',\n done: '',\n cancelled: 'ds:line-through',\n absent: '',\n },\n bookedOnline: {\n // class name kept as a stable inert DOM hook; the stripe paint\n // lives here (moved from fullcalendar-theme.css) so it works in\n // the card's own stories, outside .fc-theme-alfadocs.\n // currentcolor = resolved ink, so stripes stay visible over any\n // picker colour.\n true: 'event-booked-online ds:bg-[image:repeating-linear-gradient(45deg,transparent,transparent_4px,color-mix(in_srgb,currentcolor_10%,transparent)_4px,color-mix(in_srgb,currentcolor_10%,transparent)_8px)]',\n false: '',\n },\n // Task treatment: CUSTOM-PROPERTY assignments only — the consuming\n // background-color / color / border-color declarations stay in the\n // base above, so this cannot re-open the CVA-vs-override specificity\n // race, and a caller's inline picker hex (set as the same custom\n // properties via `style`) still wins. `border-dashed` is a\n // border-style declaration — no property collision either.\n kind: {\n // The appointment's COLOUR IDENTITY edge — a thick start border\n // in the event colour, platform-agenda style, so the colour\n // reads even on sliver-height cards. Tasks keep the 1px edge:\n // muted to-dos carry no colour identity.\n appointment: 'ds:border-s-4',\n // Draft treatment — an appointment being COMPOSED, not yet saved\n // (the slot a user just picked, mirrored on the grid while the\n // editor is open). Same custom-property-only discipline as\n // `task`: dashed outline over a light primary tint, so the\n // placeholder reads as pending rather than as a booked slot.\n draft: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--primary)_10%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--primary)]',\n ].join(' '),\n // Details pending — the block IS a booked appointment, so it\n // keeps the colour-identity edge and assigns no paint of its own.\n // Only the NAME is missing; the bar above stands in for it.\n 'pending-details': 'ds:border-s-4',\n task: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:var(--muted)]',\n 'ds:[--calendar-event-text:var(--muted-foreground)]',\n 'ds:[--calendar-event-border:color-mix(in_srgb,currentcolor_45%,transparent)]',\n ].join(' '),\n },\n // Tinted colour scheme — the chip-family look: the picker colour\n // becomes a SOLID BORDER over a light tint of itself (theme-aware\n // via color-mix with --card), text on the theme's foreground\n // tokens. Custom-property assignments only — the painted\n // declarations stay in the base. The runtime hex arrives as\n // `--calendar-event-accent` (inline). Never combined with the task\n // variant: the component forces `solid` for tasks so exactly one\n // class-level assignment of each property exists per render.\n colorStyle: {\n solid: '',\n tinted: [\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_12%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--calendar-event-accent,var(--primary))]',\n ].join(' '),\n // Faded: a lighter tint than `tinted` with muted text, for a card\n // that stays visible but steps back (a shown cancelled\n // appointment). Colour, never opacity, so the text keeps its AA\n // ratio. Same custom-property-only rule as `tinted`.\n faded: [\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_5%,var(--card))]',\n 'ds:[--calendar-event-text:var(--muted-foreground)]',\n 'ds:[--calendar-event-border:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_45%,var(--card))]',\n ].join(' '),\n },\n },\n defaultVariants: {\n layout: 'grid',\n status: 'none',\n bookedOnline: false,\n kind: 'appointment',\n colorStyle: 'solid',\n },\n },\n);\n\n/* Card slots. The `event-card-*` class names are inert DOM hooks for tests\n and hosts; every style is a `ds:` utility. Tier variants apply to timed\n grids; month and flow replace the ones they override (see each slot). */\n\nconst cardContent = [\n 'event-card-content ds:grid ds:grid-cols-[minmax(0,1fr)_auto] ds:items-start',\n 'ds:gap-x-[var(--spacing-2xs)] ds:leading-[var(--calendar-event-line-height)]',\n // Stretch, so a secondary line is as wide as the card and a long word\n // wraps inside it rather than running past the edge.\n 'ds:eventcard-narrow:flex ds:eventcard-narrow:flex-col ds:eventcard-narrow:items-stretch',\n // A 15-minute compact tile: the meta size on a tight line.\n 'ds:eventcard-tiny:text-[length:var(--type-meta-size)] ds:eventcard-tiny:leading-[var(--calendar-event-compact-line-height)]',\n].join(' ');\n\nconst cardHeading = [\n 'event-card-heading ds:flex ds:items-baseline ds:gap-[var(--spacing-2xs)] ds:min-w-0',\n 'ds:eventcard-narrow:w-full',\n 'ds:eventcard-narrow-tall:flex-col ds:eventcard-narrow-tall:items-stretch ds:eventcard-narrow-tall:gap-0',\n].join(' ');\n\nconst cardName = cva(\n [\n 'event-card-name ds:min-w-0 ds:flex-1 ds:font-[var(--font-weight-semibold)]',\n // Wrap at spaces first; break inside a word only when it cannot fit.\n 'ds:wrap-break-word',\n 'ds:eventcard-narrow:pe-[var(--spacing-xs)]',\n ].join(' '),\n {\n variants: {\n layout: {\n grid: [\n 'ds:line-clamp-1 ds:eventcard-h3:line-clamp-2',\n // Tall slivers: the name runs down the card.\n 'ds:eventcard-sliver-tall:block ds:eventcard-sliver-tall:[writing-mode:vertical-rl] ds:eventcard-sliver-tall:[text-orientation:mixed]',\n 'ds:eventcard-sliver-tall:whitespace-nowrap ds:eventcard-sliver-tall:text-ellipsis ds:eventcard-sliver-tall:flex-none ds:eventcard-sliver-tall:pe-0',\n 'ds:eventcard-sliver-tall:[max-inline-size:calc(100cqmax_-_var(--spacing-md))]',\n 'ds:eventcard-sliver-h2:line-clamp-2 ds:eventcard-sliver-h2:pe-0',\n // Too thin for a legible line: colour and the priority marker.\n 'ds:eventcard-hairline:hidden',\n ].join(' '),\n month: 'ds:line-clamp-1',\n flow: 'ds:line-clamp-2',\n },\n // Room for the one-line \"marker +N\" cluster that sits over the end:\n // sized in em of the card text, like the cluster it clears.\n hiddenMarkers: {\n true: 'ds:eventcard-narrow-count:pe-[2.25em]',\n false: '',\n },\n },\n },\n);\n\n/* With a surname to show, slivers swap the full title for it. */\nconst cardFullTitle = cva('event-card-full-title', {\n variants: {\n hasShortTitle: { true: 'ds:eventcard-sliver:hidden', false: '' },\n },\n});\n\nconst cardKindIcon =\n 'event-card-kind-icon ds:inline ds:size-[1em] ds:me-[var(--spacing-2xs)] ds:align-text-bottom';\n\nconst cardTime = cva(\n 'event-card-time ds:hidden ds:shrink-0 ds:whitespace-nowrap ds:text-[length:var(--type-meta-size)]',\n {\n variants: {\n layout: {\n // Wide cards, and tall cards from 112px, show the time; tall narrow\n // cards put the start under the name.\n grid: 'ds:eventcard-w176:inline ds:eventcard-tall:inline ds:eventcard-narrow-tall:block',\n month: 'ds:eventcard-w176:inline',\n flow: 'ds:eventcard-w176:inline',\n },\n },\n },\n);\n\nconst cardStart = cva('event-card-start', {\n variants: {\n layout: {\n grid: 'ds:eventcard-w256:hidden',\n month: '',\n flow: 'ds:eventcard-w256:hidden',\n },\n },\n});\n\nconst cardRange = cva('event-card-range', {\n variants: {\n layout: {\n grid: 'ds:hidden ds:eventcard-w256:inline',\n month: 'ds:hidden',\n flow: 'ds:hidden ds:eventcard-w256:inline',\n },\n },\n});\n\nconst secondaryLine =\n 'ds:col-span-full ds:overflow-hidden ds:text-[length:var(--type-meta-size)] ds:wrap-break-word';\n\nconst cardSuffix = cva(`event-card-suffix ${secondaryLine}`, {\n variants: {\n layout: {\n grid: [\n 'ds:hidden ds:eventcard-h2:line-clamp-1',\n 'ds:eventcard-narrow:order-2 ds:eventcard-narrow-h2:hidden ds:eventcard-narrow-h5:line-clamp-1',\n 'ds:eventcard-sliver:hidden ds:eventcard-h7-mid:line-clamp-2',\n ].join(' '),\n month: 'ds:hidden',\n flow: 'ds:line-clamp-1 ds:eventcard-narrow:order-2',\n },\n },\n});\n\nconst cardContext = cva(`event-card-context ${secondaryLine}`, {\n variants: {\n layout: {\n grid: 'ds:hidden ds:eventcard-narrow:order-3 ds:eventcard-context:line-clamp-1',\n month: 'ds:hidden',\n flow: 'ds:hidden',\n },\n },\n});\n\n/* One-line narrow cards: the cluster sits over the end of the name. */\nconst NARROW_OVERLAY_MARKERS =\n 'ds:eventcard-narrow:absolute ds:eventcard-narrow:end-0 ds:eventcard-narrow:[inset-block-end:0] ds:eventcard-narrow:gap-0';\n\nconst cardMarkers = cva(\n 'event-card-markers ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:col-[2] ds:row-[1]',\n {\n variants: {\n layout: {\n grid: [\n NARROW_OVERLAY_MARKERS,\n 'ds:eventcard-narrow-h2:static ds:eventcard-narrow-h2:gap-[var(--spacing-2xs)] ds:eventcard-narrow-h2:order-1',\n 'ds:eventcard-tall:row-auto ds:eventcard-tall:col-span-full',\n ].join(' '),\n month: NARROW_OVERLAY_MARKERS,\n // Lists and timelines have no height tiers, so a narrow flow card\n // keeps its markers in the column, between name and treatment,\n // instead of laying them over the treatment line. The row wraps so\n // a slim card's dot never falls off the edge.\n flow: 'ds:eventcard-narrow:order-1 ds:eventcard-narrow:flex-wrap',\n },\n },\n },\n);\n\n/* Marker visibility by priority rank: the first always shows; later ones\n join as the card widens, and all show on tall wide cards. Month shows\n the first only. */\nconst cardMarker = cva(\n `event-card-marker ${INDICATOR_DISC_BASE} ds:size-[1em] ds:[&_svg]:size-[0.75em] ds:eventcard-narrow:size-[0.75em] ds:eventcard-narrow-h2:size-[1em]`,\n {\n variants: {\n rank: {\n first: 'ds:inline-flex',\n second: 'ds:hidden',\n third: 'ds:hidden',\n rest: 'ds:hidden',\n },\n layout: { grid: '', month: '', flow: '' },\n },\n compoundVariants: [\n {\n layout: ['grid', 'flow'],\n rank: 'second',\n class: 'ds:eventcard-w256:inline-flex',\n },\n {\n layout: ['grid', 'flow'],\n rank: 'third',\n class: 'ds:eventcard-w352:inline-flex',\n },\n {\n layout: ['grid', 'flow'],\n rank: ['second', 'third', 'rest'],\n class: 'ds:eventcard-tall-wide:inline-flex',\n },\n ],\n },\n);\n\nconst MARKER_RANK = ['first', 'second', 'third'] as const;\n\n/* \"+N\" after the first `capacity` markers; at most one shows per tier. */\nconst cardMore = cva(\n 'event-card-more ds:text-[length:var(--type-meta-size)] ds:whitespace-nowrap',\n {\n variants: {\n capacity: {\n 1: 'event-card-more-1',\n 2: 'event-card-more-2 ds:hidden',\n 3: 'event-card-more-3 ds:hidden',\n },\n layout: { grid: '', month: '', flow: '' },\n },\n compoundVariants: [\n { layout: 'month', capacity: 1, class: 'ds:inline' },\n {\n layout: 'grid',\n capacity: 1,\n class: [\n 'ds:inline ds:eventcard-w256:hidden ds:eventcard-narrow:hidden',\n 'ds:eventcard-narrow-count:inline ds:eventcard-narrow-h2:inline ds:eventcard-tall-wide:hidden',\n ].join(' '),\n },\n // Flow keeps narrow markers in the column, with room to count from\n // 64px; slimmer flow cards fall back to the dot.\n {\n layout: 'flow',\n capacity: 1,\n class:\n 'ds:inline ds:@max-[64px]/eventcard:hidden ds:eventcard-w256:hidden',\n },\n {\n layout: ['grid', 'flow'],\n capacity: 2,\n class:\n 'ds:eventcard-w256:inline ds:eventcard-w352:hidden ds:eventcard-tall-wide:hidden',\n },\n {\n layout: ['grid', 'flow'],\n capacity: 3,\n class: 'ds:eventcard-w352:inline ds:eventcard-tall-wide:hidden',\n },\n ],\n },\n);\n\n/* The sliver cue: a dot saying \"more markers than shown\", where \"+N\" does\n not fit. Rendered only when markers are actually hidden. Month always\n counts, so it has none. */\nconst sliverCue = cva(\n 'event-card-sliver-cue ds:hidden ds:items-center ds:text-[length:var(--type-meta-size)]',\n {\n variants: {\n layout: {\n grid: 'ds:eventcard-narrow:flex ds:eventcard-narrow-count:hidden ds:eventcard-narrow-h2:hidden',\n month: '',\n flow: 'ds:@max-[64px]/eventcard:flex',\n },\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\n/**\n * The single painted surface of a calendar event.\n *\n * Colour model (platform parity): the caller's picker hex\n * (`backgroundColor` / `textColor` / `borderColor`) is the ONLY thing that\n * paints the card. `status` never paints the surface — it selects an icon\n * and (for `cancelled`) a line-through.\n *\n * Non-interactive by design: inside FullCalendar the outer harness anchor\n * owns click/drag/focus; standalone consumers wrap the card in their own\n * button/link. No onClick in the contract.\n */\nexport interface CalendarEventCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /**\n * Primary line. Pass the ALREADY-MASKED title when privacy applies — the\n * card never receives a name it must not render, so it cannot leak it\n * (visually or via the composed aria-label).\n */\n title: string;\n /** Optional surname/short form for slivers. Ignored when privacyMasked. */\n shortTitle?: string;\n /** Localised start time for narrow cards. No parsing of rangeText. */\n startText?: string;\n /** Month keeps one line; flow preserves intrinsic height in lists/timelines. */\n layout?: 'grid' | 'month' | 'flow';\n /** Opposite resource axis: operator initials or chair, on tall cards. */\n contextLabel?: string;\n /**\n * Full name behind `contextLabel`, used in the accessible name instead of\n * it, so initials such as \"DA\" are not read out letter by letter. Never\n * rendered visually.\n */\n contextName?: string;\n /**\n * Secondary description, clamped to the lines the card can hold. Note: the\n * Calendar's privacy mode does NOT mask the suffix (current behaviour,\n * preserved deliberately).\n */\n suffix?: string;\n /**\n * Pre-formatted, localised time range (e.g. \"09:00 – 09:45\"). The\n * Calendar adapter computes it via Intl.DateTimeFormat.formatRange.\n * Included in the composed aria-label whenever present (even when the\n * visual time line is suppressed via showTime/allDay — matches today's\n * Calendar behaviour byte-for-byte).\n */\n rangeText?: string;\n /**\n * Gates the VISUAL time line only (aria keeps rangeText). Mirrors\n * CalendarProps.showTime. @default true\n */\n showTime?: boolean;\n /**\n * All-day events suppress the visual time line (aria keeps rangeText).\n * @default false\n */\n allDay?: boolean;\n\n /**\n * Lifecycle state (6-state, matches the platform DoctorAppointment\n * lifecycle) → status icon + line-through for `cancelled` +\n * localised label in the aria-label. NEVER paints the\n * card surface.\n */\n status?: CalendarEventStatus;\n\n /**\n * Runtime hex (#rgb or #rrggbb) from the consumer's colour picker — THE\n * painted surface. Injected as `--calendar-event-bg` via the sanctioned\n * inline custom-property pattern (23-constraints §inline-style exception).\n */\n backgroundColor?: string;\n /**\n * Runtime hex paired with backgroundColor. When omitted while\n * backgroundColor is set, the card auto-derives black/white ink by\n * luminance (provably WCAG AA ≥ 4.58:1 for any opaque colour).\n */\n textColor?: string;\n /**\n * Runtime hex border for delineating light surfaces. The platform sends\n * '#cccccc' when backgroundColor is '#ffffff' and omits it otherwise.\n * Falls back to transparent; appointments have a 4px start edge and\n * a 1px border elsewhere (tasks and drafts have 1px on every side), so toggling never shifts layout and event boundaries\n * survive forced-colors / Windows High Contrast for free.\n */\n borderColor?: string;\n\n /* Indicator icons — names identical to CalendarEvent fields (1:1 map). */\n /** Globe icon + diagonal stripe overlay. */\n isBookedOnline?: boolean;\n /** AlertTriangle icon. */\n hasUnassignedPatient?: boolean;\n /** HeartPulse icon. */\n hasHighlightedAnamnesis?: boolean;\n /** Euro icon. */\n hasBillableAmount?: boolean;\n /** Video icon. */\n isTelehealth?: boolean;\n /**\n * Repeat icon — this event belongs to a REPEATING SERIES. Set it on\n * every occurrence, not only the first: the flag answers \"will moving\n * or deleting this touch other appointments?\", which is true of a\n * modified occurrence too. Series ROLE (which row owns the rule) is a\n * separate concern — see `CalendarEvent.isRecurrenceParent`.\n */\n isRecurring?: boolean;\n /**\n * Task treatment — a calendar-scheduled to-do renders distinctly from an\n * appointment: dashed outline (derived from the resolved ink when no\n * `borderColor` is supplied), muted default surface (an explicit\n * `backgroundColor`/`textColor` still wins), a leading clipboard glyph,\n * and a localised \"task\" word appended to the accessible name. Emitted as\n * `data-kind=\"task\"` for DOM hooks.\n */\n isTask?: boolean;\n /**\n * Draft treatment — a placeholder for an appointment being composed:\n * the slot the user just picked, mirrored on the grid while the editor\n * is open. Dashed outline over a light primary tint, with a localised\n * \"draft\" word appended to the accessible name. Emitted as\n * `data-kind=\"draft\"`. Takes precedence over `isTask`, and like a task\n * it forces the solid paint path so exactly one class-level assignment\n * of each paint custom property exists per render.\n */\n isDraft?: boolean;\n /**\n * Details-pending treatment — a REAL booked appointment an\n * occupancy-first host drew from the slot it occupies while it still\n * fetches whose it is. The card keeps its colour and size and renders an\n * `aria-hidden` skeleton bar where the title goes, with the localised\n * \"loading details\" word in the accessible name and\n * `data-kind=\"pending-details\"` as the hook. Wins over `isDraft`/`isTask`.\n */\n detailsPending?: boolean;\n /**\n * Colour scheme for the picker colour. `'solid'` (default) is the\n * platform model — the hex paints the whole surface, ink auto-derived.\n * `'tinted'` is the chip-family scheme: the hex becomes a SOLID BORDER\n * over a light tint of itself (theme-aware via color-mix with `--card`),\n * with text on the theme's foreground tokens — `textColor` and\n * `borderColor` are ignored under it. Tasks keep their muted dashed\n * treatment regardless.\n */\n colorStyle?: 'solid' | 'tinted';\n /**\n * Steps the card back: a light tint of the picker colour with muted text\n * and a softer border, whatever `colorStyle` says. Colour only, no\n * opacity, so the text stays readable. The calendar sets it on a shown\n * cancelled appointment. Tasks and drafts keep their own treatment.\n * @default false\n */\n faded?: boolean;\n\n /**\n * Resource title (chair/operator) woven into the composed aria-label\n * only — never rendered visually. The Calendar adapter resolves\n * resourceId → title before passing it.\n */\n resourceLabel?: string;\n /**\n * The title is a privacy MASK (the Calendar's privacy mode swapped the\n * patient name for `privacyModeTitle`). Renders a crossed-out-eye glyph\n * beside the mask so the redaction is legible as deliberate, with its\n * own breathing room after the time.\n */\n privacyMasked?: boolean;\n /**\n * Stable event id → emitted as `data-event-id` (Calendar.focusEvent\n * targets it) and used as the contrast-warning dedup context.\n */\n eventId?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const CalendarEventCard = forwardRef<\n HTMLDivElement,\n CalendarEventCardProps\n>(\n (\n {\n title,\n shortTitle,\n startText,\n layout = 'grid',\n contextLabel,\n contextName,\n suffix,\n rangeText,\n showTime = true,\n allDay = false,\n status,\n backgroundColor,\n textColor,\n borderColor,\n isBookedOnline = false,\n hasUnassignedPatient,\n hasHighlightedAnamnesis,\n hasBillableAmount,\n isTelehealth,\n isRecurring,\n isTask = false,\n isDraft = false,\n detailsPending = false,\n colorStyle = 'solid',\n faded = false,\n resourceLabel,\n privacyMasked = false,\n eventId,\n className,\n style,\n 'aria-label': ariaLabelProp,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n const markers = [\n ...(status\n ? [\n {\n id: 'status',\n Icon: STATUS_ICON[status],\n label: t(STATUS_LABEL_KEYS[status]),\n tone: STATUS_DISC_TONE[status],\n },\n ]\n : []),\n ...EVENT_FLAGS.filter(({ field }) =>\n Boolean(\n {\n hasUnassignedPatient,\n hasHighlightedAnamnesis,\n hasBillableAmount,\n isBookedOnline,\n isTelehealth,\n isRecurring,\n }[field],\n ),\n ).map(({ field, Icon, labelKey, tone }) => ({\n id: field,\n Icon,\n label: t(labelKey),\n tone,\n })),\n ];\n const statusLabel = status ? t(STATUS_LABEL_KEYS[status]) : undefined;\n const kindLabel = detailsPending\n ? t('calendar.eventKind.pendingDetails')\n : isDraft\n ? t('calendar.eventKind.draft')\n : isTask\n ? t('calendar.eventKind.task')\n : undefined;\n\n /* Accessible name — the Calendar's historical composition, with the\n localised \"task\" word appended for task cards so screen-reader users\n get the same appointment-vs-task distinction the dashed outline and\n clipboard glyph carry visually. An explicit consumer-supplied\n aria-label wins. rangeText is always included when present, even when\n the visual time line is hidden. */\n const ariaLabel =\n ariaLabelProp ??\n [\n title,\n rangeText,\n suffix,\n resourceLabel,\n // A blank name falls back to the visible label rather than\n // silencing the context altogether.\n contextName?.trim() ? contextName : contextLabel,\n statusLabel,\n kindLabel,\n ...markers\n .filter((marker) => marker.id !== 'status')\n .map((marker) => marker.label),\n ]\n .filter(Boolean)\n .join(', ');\n\n const kind = detailsPending\n ? 'pending-details'\n : isDraft\n ? 'draft'\n : isTask\n ? 'task'\n : 'appointment';\n\n /* Tasks force the solid path — their muted variant owns the paint\n custom properties, so the tinted class must never co-assign them. */\n const isFaded = !isTask && !isDraft && faded;\n const tinted = !isTask && !isDraft && (colorStyle === 'tinted' || isFaded);\n\n /* Ink derivation — solid scheme only, when the caller paints the\n surface without pairing a text colour. */\n const ink =\n !tinted && !textColor && backgroundColor\n ? resolveInk(backgroundColor)\n : null;\n\n /* DEV-only guardrails — every helper no-ops in production and dedupes\n per session, so calling during render is safe. The tinted scheme\n paints text on theme tokens over a 12% tint, so the solid-scheme\n pair checks don't apply there. */\n const warnContext = eventId ? `event ${eventId}` : 'calendar-event-card';\n if (!tinted) {\n warnLowContrast(backgroundColor, textColor, warnContext);\n if (backgroundColor && !textColor) {\n // no-ops when the hex is parseable (i.e. when resolveInk succeeded)\n warnUnparseableBackground(backgroundColor, warnContext);\n }\n if (backgroundColor && !borderColor) {\n // no-ops unless the background is near-white (luminance > 0.9)\n warnLowDelineation(backgroundColor, warnContext);\n }\n }\n\n /* Per-event colour override: the consuming app passes runtime hex from\n its colour picker. 23-constraints permits inline `style` only as a\n CSS custom-property setter for runtime values that can't be\n enumerated at build time — the consuming background-color / color /\n border-color declarations live in the CVA base as Tailwind arbitrary\n values with token fallbacks. */\n const colourOverrides: CSSProperties | undefined = tinted\n ? backgroundColor\n ? ({ '--calendar-event-accent': backgroundColor } as CSSProperties)\n : undefined\n : backgroundColor || textColor || borderColor\n ? ({\n ...(backgroundColor\n ? { '--calendar-event-bg': backgroundColor }\n : {}),\n ...(textColor\n ? { '--calendar-event-text': textColor }\n : ink === 'on-light'\n ? { '--calendar-event-text': 'var(--event-ink-on-light)' }\n : ink === 'on-dark'\n ? { '--calendar-event-text': 'var(--event-ink-on-dark)' }\n : {}),\n ...(borderColor ? { '--calendar-event-border': borderColor } : {}),\n } as CSSProperties)\n : undefined;\n\n const mergedStyle: CSSProperties | undefined =\n style || colourOverrides ? { ...style, ...colourOverrides } : undefined;\n\n /* A surname for slivers, never under privacy. */\n const showShortTitle = Boolean(\n !privacyMasked && shortTitle?.trim() && shortTitle !== title,\n );\n\n return (\n <div\n ref={ref}\n role=\"group\"\n {...rest}\n className={calendarEventCardVariants({\n layout,\n status: status ?? 'none',\n bookedOnline: isBookedOnline,\n kind,\n colorStyle: isFaded ? 'faded' : tinted ? 'tinted' : 'solid',\n className,\n })}\n // eslint-disable-next-line react/forbid-dom-props -- caller-supplied event bg/text/border hex injected via CSS variables (23-constraints §inline-style exception)\n style={mergedStyle}\n aria-label={ariaLabel}\n data-component=\"calendar-event-card\"\n data-event-id={eventId}\n data-kind={kind}\n data-status={status ?? 'none'}\n data-contrast={\n tinted ? 'tinted' : textColor ? 'custom' : (ink ?? 'default')\n }\n >\n <span className={cardContent} aria-hidden=\"true\">\n <span className={cardHeading}>\n <span\n className={cardName({\n layout,\n hiddenMarkers: markers.length > 1,\n })}\n >\n {detailsPending ? (\n <span aria-hidden=\"true\" className={PENDING_BAR_CLASS} />\n ) : (\n <>\n {isTask ? <ClipboardCheck className={cardKindIcon} /> : null}\n {privacyMasked ? <EyeOff className={cardKindIcon} /> : null}\n <span\n className={cardFullTitle({\n hasShortTitle: showShortTitle,\n })}\n >\n {title}\n </span>\n {showShortTitle ? (\n <span className=\"event-card-short-title ds:hidden ds:eventcard-sliver:inline\">\n {shortTitle}\n </span>\n ) : null}\n </>\n )}\n </span>\n {showTime && !allDay && rangeText ? (\n <span className={cardTime({ layout })}>\n {startText ? (\n <>\n <span className={cardStart({ layout })}>{startText}</span>\n <span className={cardRange({ layout })}>{rangeText}</span>\n </>\n ) : (\n rangeText\n )}\n </span>\n ) : null}\n </span>\n {suffix ? (\n <span className={cardSuffix({ layout })}>{suffix}</span>\n ) : null}\n {contextLabel ? (\n <span className={cardContext({ layout })}>{contextLabel}</span>\n ) : null}\n {markers.length > 0 ? (\n <span className={cardMarkers({ layout })}>\n {markers.map(({ id, Icon, tone }, index) => (\n <span\n key={id}\n data-marker={id}\n aria-hidden=\"true\"\n className={cardMarker({\n rank: MARKER_RANK[index] ?? 'rest',\n layout,\n className: INDICATOR_DISC_TONE[tone],\n })}\n >\n <Icon aria-hidden=\"true\" />\n </span>\n ))}\n {([1, 2, 3] as const).map((capacity) =>\n markers.length > capacity ? (\n <span\n key={capacity}\n className={cardMore({ capacity, layout })}\n >\n {t('calendar.card.more', {\n number: markers.length - capacity,\n })}\n </span>\n ) : null,\n )}\n {markers.length > 1 && layout !== 'month' ? (\n <span className={sliverCue({ layout })}>·</span>\n ) : null}\n </span>\n ) : null}\n </span>\n </div>\n );\n },\n);\nCalendarEventCard.displayName = 'CalendarEventCard';\n"],"names":["parseHex","hex","trimmed","body","r","g","b","relativeLuminance","lin","c","warnLowContrast","bgHex","fgHex","contextLabel","resolveInk","bg","STATUS_ICON","ThumbsUp","Clock","Stethoscope","Check","Ban","UserX","INDICATOR_DISC_BASE","PENDING_BAR_CLASS","INDICATOR_DISC_TONE","STATUS_DISC_TONE","STATUS_LABEL_KEYS","EVENT_FLAGS","TriangleAlert","HeartPulse","Euro","Globe","Video","Repeat","calendarEventCardVariants","cva","cardContent","cardHeading","cardName","cardFullTitle","cardKindIcon","cardTime","cardStart","cardRange","secondaryLine","cardSuffix","cardContext","NARROW_OVERLAY_MARKERS","cardMarkers","cardMarker","MARKER_RANK","cardMore","sliverCue","CalendarEventCard","forwardRef","title","shortTitle","startText","layout","contextName","suffix","rangeText","showTime","allDay","status","backgroundColor","textColor","borderColor","isBookedOnline","hasUnassignedPatient","hasHighlightedAnamnesis","hasBillableAmount","isTelehealth","isRecurring","isTask","isDraft","detailsPending","colorStyle","faded","resourceLabel","privacyMasked","eventId","className","style","ariaLabelProp","rest","ref","t","useTranslation","markers","field","Icon","labelKey","tone","statusLabel","kindLabel","ariaLabel","marker","kind","isFaded","tinted","ink","colourOverrides","mergedStyle","showShortTitle","jsx","jsxs","Fragment","ClipboardCheck","EyeOff","id","index","capacity"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"calendar-event-card-BJifpYZQ.js","sources":["../../src/components/_shared/contrast-warning.ts","../../src/components/calendar-event-card/calendar-event-card.tsx"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* Shared contrast guardrail — Calendar + CalendarEventCard */\n/* */\n/* The consuming app supplies runtime hex pairs at several surfaces: */\n/* - event.backgroundColor / event.textColor (+ event.borderColor) */\n/* - modeBannerColor / modeBannerTextColor */\n/* - resource.color / resource.shortTitleTextColor */\n/* */\n/* When the text half of the pair is also a hex (i.e. both halves come */\n/* from the caller), we can validate them synchronously and warn the */\n/* consuming-app developer during DEV if the pair fails WCAG AA normal */\n/* text (4.5:1). When only the background half is supplied, */\n/* `resolveInk` derives a provably AA-safe black/white ink for it. */\n/* Every helper is a no-op in production builds. */\n/* ------------------------------------------------------------------ */\n\n/* Module-level dedup set — keyed on the (bg, fg, context) tuple so the\n same bad pair moving around the calendar only warns once per session.\n Exposed via `resetContrastWarnings()` for test isolation. */\nconst warnedTuples = new Set<string>();\n\n/** Reset the dedup set — intended for use between tests. */\nexport function resetContrastWarnings(): void {\n warnedTuples.clear();\n}\n\n/**\n * Parse a 3-char or 6-char `#RRGGBB` hex string into a linear sRGB\n * triple in the [0,1] range. Returns `null` for any input the caller\n * can't parse (malformed prefix, bad length, non-hex characters) —\n * the helper stays silent in that case rather than emitting noise.\n */\nfunction parseHex(hex: string): [number, number, number] | null {\n if (typeof hex !== 'string') return null;\n const trimmed = hex.trim();\n if (!trimmed.startsWith('#')) return null;\n const body = trimmed.slice(1);\n let r: number;\n let g: number;\n let b: number;\n if (body.length === 3) {\n if (!/^[0-9a-f]{3}$/i.test(body)) return null;\n r = parseInt(body[0] + body[0], 16);\n g = parseInt(body[1] + body[1], 16);\n b = parseInt(body[2] + body[2], 16);\n } else if (body.length === 6) {\n if (!/^[0-9a-f]{6}$/i.test(body)) return null;\n r = parseInt(body.slice(0, 2), 16);\n g = parseInt(body.slice(2, 4), 16);\n b = parseInt(body.slice(4, 6), 16);\n } else {\n return null;\n }\n return [r / 255, g / 255, b / 255];\n}\n\n/**\n * WCAG 2.1 relative luminance. Each channel is gamma-corrected then\n * weighted against the CIE photopic sensitivity of the human eye.\n * https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n */\nfunction relativeLuminance([r, g, b]: [number, number, number]): number {\n const lin = (c: number): number =>\n c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);\n}\n\n/**\n * WCAG 2.1 contrast ratio. Always returns a value in [1, 21]; the\n * relative-luminance lighter-over-darker convention is applied here.\n */\nfunction contrastRatio(\n bg: [number, number, number],\n fg: [number, number, number],\n): number {\n const l1 = relativeLuminance(bg);\n const l2 = relativeLuminance(fg);\n const lighter = Math.max(l1, l2);\n const darker = Math.min(l1, l2);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\n/**\n * DEV-only WCAG AA guardrail for caller-supplied hex pairs.\n *\n * - No-op when `import.meta.env.DEV` is false.\n * - No-op when either half of the pair is missing (the \"fg missing →\n * inherits DS token\" case is a docs concern; the DS token isn't a\n * hex at runtime so we can't check it here).\n * - No-op when either hex can't be parsed (silent — not the helper's\n * concern to police malformed input).\n * - Deduplicated by `(bgHex, fgHex, contextLabel)` tuple so moving a\n * ratio-bad event around the calendar doesn't spam the console.\n *\n * @param bgHex - Caller-supplied background hex (e.g. `'#c2185b'`)\n * @param fgHex - Caller-supplied foreground hex (e.g. `'#ffffff'`)\n * @param contextLabel - Short description for the warning (e.g. `'event e1'`).\n */\nexport function warnLowContrast(\n bgHex: string | undefined,\n fgHex: string | undefined,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (!bgHex || !fgHex) return;\n\n const bg = parseHex(bgHex);\n const fg = parseHex(fgHex);\n if (!bg || !fg) return;\n\n const ratio = contrastRatio(bg, fg);\n if (ratio >= 4.5) return;\n\n const key = `${bgHex}|${fgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n /* `bg` parsed successfully above, so `resolveInk(bgHex)` is guaranteed\n to produce a compliant ink — the omit-textColor hint is always valid\n at this point. */\n console.warn(\n `[Calendar] Low contrast on ${contextLabel}: ${bgHex} / ${fgHex} (ratio ${ratio.toFixed(\n 2,\n )}, target 4.5). Pass a matching textColor/fgHex, pick a higher-contrast background, or omit textColor to let the kit choose a compliant ink.`,\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Ink derivation — bg-only caller colours */\n/* ------------------------------------------------------------------ */\n\nexport type EventInk = 'on-light' | 'on-dark';\n\n/**\n * Pick the ink for an arbitrary opaque bg hex. Returns `null` when the\n * input can't be parsed (`#rgb` / `#rrggbb` only).\n *\n * The threshold 0.1791 is the relative luminance at which\n * `contrast(bg, #fff) === contrast(bg, #000)`; the better of the two\n * always yields ≥ 4.58:1 (the minimum, at a mid-grey ≈ `#757575`) —\n * provably WCAG AA-safe for any opaque background.\n */\nexport function resolveInk(bgHex: string): EventInk | null {\n const bg = parseHex(bgHex);\n if (!bg) return null;\n // threshold where contrast(bg, #fff) === contrast(bg, #000)\n return relativeLuminance(bg) > 0.1791 ? 'on-light' : 'on-dark';\n}\n\n/**\n * DEV-only, one-shot warning for a caller `backgroundColor` the kit can't\n * parse (`rgb(…)`, keywords, malformed hex). The browser can still paint\n * it, but the text falls back to the token default and contrast can't be\n * verified. Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnUnparseableBackground(\n bgHex: string,\n contextLabel: string,\n): void {\n if (!import.meta.env.DEV) return;\n if (parseHex(bgHex)) return;\n\n const key = `unparseable|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Unparseable backgroundColor on ${contextLabel}: \"${bgHex}\". ` +\n `Expected #rgb or #rrggbb — contrast cannot be verified and the text ` +\n `colour falls back to the token default.`,\n );\n}\n\n/**\n * DEV-only, one-shot warning for a near-white `backgroundColor`\n * (relative luminance > 0.9) supplied without a `borderColor` — the\n * event may be invisible against the calendar grid. The kit warns, it\n * does not repaint (delineation is decorative under WCAG 1.4.11 and the\n * consumer owns the picker colour). Deduplicated by `(bgHex, contextLabel)`.\n */\nexport function warnLowDelineation(bgHex: string, contextLabel: string): void {\n if (!import.meta.env.DEV) return;\n\n const bg = parseHex(bgHex);\n if (!bg) return;\n if (relativeLuminance(bg) <= 0.9) return;\n\n const key = `delineation|${bgHex}|${contextLabel}`;\n if (warnedTuples.has(key)) return;\n warnedTuples.add(key);\n\n console.warn(\n `[Calendar] Light backgroundColor without borderColor on ${contextLabel}: ` +\n `${bgHex} may be invisible against the grid — pass a borderColor ` +\n `(the platform convention sends a light-grey border for white backgrounds).`,\n );\n}\n","/* ------------------------------------------------------------------ */\n/* CalendarEventCard — the single painted surface of a calendar event. */\n/* */\n/* Colour model (platform parity): the caller's picker hex */\n/* (backgroundColor / textColor / borderColor) is the ONLY thing that */\n/* paints the card. `status` never paints the surface — it selects an */\n/* icon and (for `cancelled`) a line-through. When no picker colour */\n/* is supplied the surface falls back to the theme's --primary / */\n/* --primary-foreground pair. */\n/* */\n/* Non-interactive by design: inside FullCalendar the outer harness */\n/* anchor owns click/drag/focus; standalone consumers wrap the card in */\n/* their own button/link. No onClick in the contract. */\n/* ------------------------------------------------------------------ */\n\nimport { forwardRef } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport {\n ThumbsUp,\n Clock,\n Stethoscope,\n Check,\n Ban,\n UserX,\n Globe,\n TriangleAlert,\n HeartPulse,\n Euro,\n Video,\n Repeat,\n EyeOff,\n ClipboardCheck,\n type LucideIcon,\n} from 'lucide-react';\n// Type-only import — erased at build, no runtime cycle with calendar.tsx's\n// runtime import of this card. Do NOT convert to a value import.\nimport type { CalendarEventStatus } from '../calendar/calendar';\nimport {\n warnLowContrast,\n resolveInk,\n warnUnparseableBackground,\n warnLowDelineation,\n} from '../_shared/contrast-warning';\n\n/* ------------------------------------------------------------------ */\n/* Status lookups */\n/* ------------------------------------------------------------------ */\n\nexport const STATUS_ICON: Record<CalendarEventStatus, LucideIcon> = {\n confirmed: ThumbsUp,\n waiting: Clock,\n in_care: Stethoscope,\n done: Check,\n cancelled: Ban,\n absent: UserX,\n};\n\n/* Status → i18n key lookup. Kept as a literal object (not a template)\n so static-analysis extractors can find every key. Keys already exist\n in all 18 locale bundles — do not add new ones here. */\n/* Indicator DISC — option D of the design review: each glyph in a small\n circle on the plain card surface (hairline border + row-lift shadow)\n with the SEMANTIC colour as icon ink. Chip-grade contrast on any\n picker colour without a plate; ink tokens mirror Badge's variants so\n the vocabulary stays one system. */\nconst INDICATOR_DISC_BASE =\n 'ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-full)] ds:bg-[color:var(--card)] ds:border ds:border-[color:var(--border)] ds:shadow-[var(--shadow-sm)]';\n\n/* DETAILS-PENDING bar — the Skeleton component's own classes, inlined on\n a <span>: Skeleton renders a <div>, which cannot live inside the card's\n inline text cell. Decorative (aria-hidden) because the composed\n aria-label already carries the localised \"loading details\" word. */\nconst PENDING_BAR_CLASS =\n 'ds:inline-block ds:h-3 ds:w-[6ch] ds:align-middle ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:animate-[skeleton-pulse_calc(var(--animation-duration)*8)_ease-in-out_infinite] ds:motion-reduce:animate-none ds:forced-colors:bg-[GrayText] ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText] ds:forced-colors:animate-none';\n\ntype IndicatorTone = 'success' | 'info' | 'warning' | 'error' | 'accent';\n\nconst INDICATOR_DISC_TONE: Record<IndicatorTone, string> = {\n success: 'ds:text-[color:var(--success-foreground)]',\n info: 'ds:text-[color:var(--info-foreground)]',\n warning: 'ds:text-[color:var(--warning-foreground)]',\n error: 'ds:text-[color:var(--error-foreground)]',\n // Same AA-clearing accent mix Badge's accentSoft uses for its ink.\n accent:\n 'ds:text-[color:color-mix(in_srgb,var(--accent)_40%,var(--foreground))]',\n};\n\n/* Status → disc tone — the same semantic mapping as the accent bar. */\nconst STATUS_DISC_TONE: Record<CalendarEventStatus, IndicatorTone> = {\n confirmed: 'success',\n waiting: 'info',\n in_care: 'accent',\n done: 'success',\n cancelled: 'error',\n absent: 'warning',\n};\n\nexport const STATUS_LABEL_KEYS: Record<CalendarEventStatus, string> = {\n confirmed: 'calendar.status.confirmed',\n waiting: 'calendar.status.waiting',\n in_care: 'calendar.status.inCare',\n done: 'calendar.status.done',\n cancelled: 'calendar.status.cancelled',\n absent: 'calendar.status.absent',\n};\n\nexport const EVENT_FLAGS = [\n {\n field: 'hasUnassignedPatient',\n Icon: TriangleAlert,\n labelKey: 'calendarWorkspace.details.indicators.unassignedPatient',\n tone: 'warning',\n },\n {\n field: 'hasHighlightedAnamnesis',\n Icon: HeartPulse,\n labelKey: 'calendarWorkspace.details.indicators.anamnesis',\n tone: 'accent',\n },\n {\n field: 'hasBillableAmount',\n Icon: Euro,\n labelKey: 'calendarWorkspace.details.indicators.billable',\n tone: 'warning',\n },\n {\n field: 'isBookedOnline',\n Icon: Globe,\n labelKey: 'calendarWorkspace.details.indicators.bookedOnline',\n tone: 'info',\n },\n {\n field: 'isTelehealth',\n Icon: Video,\n labelKey: 'calendarWorkspace.details.indicators.telehealth',\n tone: 'info',\n },\n {\n field: 'isRecurring',\n Icon: Repeat,\n labelKey: 'calendarWorkspace.details.indicators.recurring',\n tone: 'info',\n },\n] as const;\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst calendarEventCardVariants = cva(\n [\n // FullCalendar supplies the box. The card is the `eventcard` size\n // container: the `ds:eventcard-*` tier variants (declared in\n // src/styles.css) read its width and height to prioritise identity,\n // then treatment, time and markers.\n 'calendar-event-card ds:relative ds:block ds:[container-name:eventcard]',\n 'ds:w-full',\n 'ds:ps-[var(--spacing-2xs)] ds:pe-[var(--spacing-2xs)]',\n 'ds:rounded-[var(--radius-sm)]',\n // The type-role alias, so the text (and with it every em tier\n // threshold) grows one step under .theme-accessible.\n 'ds:text-[length:var(--type-body-sm-size)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:leading-tight ds:text-start',\n 'ds:overflow-hidden',\n // kept verbatim from the former base (inert on a non-focusable div\n // inside FC; harmless)\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n // SINGLE PAINTED SURFACE — always present, never conditional. One\n // declaration per paint channel; value chain = \"caller custom prop,\n // else token\". This structurally eliminates the CVA-vs-override\n // specificity race (the old double-paint bug) — stylesheet order\n // becomes irrelevant.\n 'ds:[background-color:var(--calendar-event-bg,var(--primary))]',\n 'ds:[color:var(--calendar-event-text,var(--primary-foreground))]',\n 'ds:border ds:[border-color:var(--calendar-event-border,transparent)]',\n ].join(' '),\n {\n variants: {\n layout: {\n // Timed grids: FullCalendar supplies a definite block size. A\n // standalone card with no height falls back to two lines.\n grid: [\n 'ds:h-full ds:[container-type:size] ds:[min-block-size:0]',\n 'ds:[contain-intrinsic-block-size:calc(var(--type-body-sm-size)*var(--calendar-event-line-height)*2)]',\n ].join(' '),\n // Month cells: exactly one line.\n month: [\n 'calendar-event-card--month ds:[container-type:size]',\n 'ds:[block-size:calc(var(--type-body-sm-size)*var(--calendar-event-line-height)_+_var(--spacing-2xs))]',\n ].join(' '),\n // Lists and timelines size from content: width tiers only.\n flow: [\n 'calendar-event-card--flow ds:[container-type:inline-size]',\n 'ds:[min-block-size:calc(var(--type-body-sm-size)*var(--calendar-event-line-height))]',\n ].join(' '),\n },\n // Do not add colour classes to this axis — status is icon + aria\n // only; a unit test asserts identical computed background\n // across all six statuses.\n status: {\n none: '',\n confirmed: '',\n waiting: '',\n in_care: '',\n done: '',\n cancelled: 'ds:line-through',\n absent: '',\n },\n bookedOnline: {\n // class name kept as a stable inert DOM hook; the stripe paint\n // lives here (moved from fullcalendar-theme.css) so it works in\n // the card's own stories, outside .fc-theme-alfadocs.\n // currentcolor = resolved ink, so stripes stay visible over any\n // picker colour.\n true: 'event-booked-online ds:bg-[image:repeating-linear-gradient(45deg,transparent,transparent_4px,color-mix(in_srgb,currentcolor_10%,transparent)_4px,color-mix(in_srgb,currentcolor_10%,transparent)_8px)]',\n false: '',\n },\n // Task treatment: CUSTOM-PROPERTY assignments only — the consuming\n // background-color / color / border-color declarations stay in the\n // base above, so this cannot re-open the CVA-vs-override specificity\n // race, and a caller's inline picker hex (set as the same custom\n // properties via `style`) still wins. `border-dashed` is a\n // border-style declaration — no property collision either.\n kind: {\n // The appointment's COLOUR IDENTITY edge — a thick start border\n // in the event colour, platform-agenda style, so the colour\n // reads even on sliver-height cards. Tasks keep the 1px edge:\n // muted to-dos carry no colour identity.\n appointment: 'ds:border-s-4',\n // Draft treatment — an appointment being COMPOSED, not yet saved\n // (the slot a user just picked, mirrored on the grid while the\n // editor is open). Same custom-property-only discipline as\n // `task`: dashed outline over a light primary tint, so the\n // placeholder reads as pending rather than as a booked slot.\n draft: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--primary)_10%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--primary)]',\n ].join(' '),\n // Details pending — the block IS a booked appointment, so it\n // keeps the colour-identity edge and assigns no paint of its own.\n // Only the NAME is missing; the bar above stands in for it.\n 'pending-details': 'ds:border-s-4',\n task: [\n 'ds:border-dashed',\n 'ds:[--calendar-event-bg:var(--muted)]',\n 'ds:[--calendar-event-text:var(--muted-foreground)]',\n 'ds:[--calendar-event-border:color-mix(in_srgb,currentcolor_45%,transparent)]',\n ].join(' '),\n },\n // Tinted colour scheme — the chip-family look: the picker colour\n // becomes a SOLID BORDER over a light tint of itself (theme-aware\n // via color-mix with --card), text on the theme's foreground\n // tokens. Custom-property assignments only — the painted\n // declarations stay in the base. The runtime hex arrives as\n // `--calendar-event-accent` (inline). Never combined with the task\n // variant: the component forces `solid` for tasks so exactly one\n // class-level assignment of each property exists per render.\n colorStyle: {\n solid: '',\n tinted: [\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_12%,var(--card))]',\n 'ds:[--calendar-event-text:var(--foreground)]',\n 'ds:[--calendar-event-border:var(--calendar-event-accent,var(--primary))]',\n ].join(' '),\n // Faded: a lighter tint than `tinted` with muted text, for a card\n // that stays visible but steps back (a shown cancelled\n // appointment). Colour, never opacity, so the text keeps its AA\n // ratio. Same custom-property-only rule as `tinted`.\n faded: [\n 'ds:[--calendar-event-bg:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_5%,var(--card))]',\n 'ds:[--calendar-event-text:var(--muted-foreground)]',\n 'ds:[--calendar-event-border:color-mix(in_srgb,var(--calendar-event-accent,var(--primary))_45%,var(--card))]',\n ].join(' '),\n },\n },\n defaultVariants: {\n layout: 'grid',\n status: 'none',\n bookedOnline: false,\n kind: 'appointment',\n colorStyle: 'solid',\n },\n },\n);\n\n/* Card slots. The `event-card-*` class names are inert DOM hooks for tests\n and hosts; every style is a `ds:` utility. Tier variants apply to timed\n grids; month and flow replace the ones they override (see each slot). */\n\nconst cardContent = [\n 'event-card-content ds:grid ds:grid-cols-[minmax(0,1fr)_auto] ds:items-start',\n 'ds:gap-x-[var(--spacing-2xs)] ds:leading-[var(--calendar-event-line-height)]',\n // Stretch, so a secondary line is as wide as the card and a long word\n // wraps inside it rather than running past the edge.\n 'ds:eventcard-narrow:flex ds:eventcard-narrow:flex-col ds:eventcard-narrow:items-stretch',\n // A 15-minute compact tile: the meta size on a tight line.\n 'ds:eventcard-tiny:text-[length:var(--type-meta-size)] ds:eventcard-tiny:leading-[var(--calendar-event-compact-line-height)]',\n].join(' ');\n\nconst cardHeading = [\n 'event-card-heading ds:flex ds:items-baseline ds:gap-[var(--spacing-2xs)] ds:min-w-0',\n 'ds:eventcard-narrow:w-full',\n 'ds:eventcard-narrow-tall:flex-col ds:eventcard-narrow-tall:items-stretch ds:eventcard-narrow-tall:gap-0',\n].join(' ');\n\nconst cardName = cva(\n [\n 'event-card-name ds:min-w-0 ds:flex-1 ds:font-[var(--font-weight-semibold)]',\n // Wrap at spaces first; break inside a word only when it cannot fit.\n 'ds:wrap-break-word',\n 'ds:eventcard-narrow:pe-[var(--spacing-xs)]',\n ].join(' '),\n {\n variants: {\n layout: {\n grid: [\n 'ds:line-clamp-1 ds:eventcard-h3:line-clamp-2',\n // Tall slivers: the name runs down the card.\n 'ds:eventcard-sliver-tall:block ds:eventcard-sliver-tall:[writing-mode:vertical-rl] ds:eventcard-sliver-tall:[text-orientation:mixed]',\n 'ds:eventcard-sliver-tall:whitespace-nowrap ds:eventcard-sliver-tall:text-ellipsis ds:eventcard-sliver-tall:flex-none ds:eventcard-sliver-tall:pe-0',\n 'ds:eventcard-sliver-tall:[max-inline-size:calc(100cqmax_-_var(--spacing-md))]',\n 'ds:eventcard-sliver-h2:line-clamp-2 ds:eventcard-sliver-h2:pe-0',\n // Too thin for a legible line: colour and the priority marker.\n 'ds:eventcard-hairline:hidden',\n ].join(' '),\n month: 'ds:line-clamp-1',\n flow: 'ds:line-clamp-2',\n },\n // Room for the one-line \"marker +N\" cluster that sits over the end:\n // sized in em of the card text, like the cluster it clears.\n hiddenMarkers: {\n true: 'ds:eventcard-narrow-count:pe-[2.25em]',\n false: '',\n },\n },\n },\n);\n\n/* With a surname to show, slivers swap the full title for it. */\nconst cardFullTitle = cva('event-card-full-title', {\n variants: {\n hasShortTitle: { true: 'ds:eventcard-sliver:hidden', false: '' },\n },\n});\n\nconst cardKindIcon =\n 'event-card-kind-icon ds:inline ds:size-[1em] ds:me-[var(--spacing-2xs)] ds:align-text-bottom';\n\nconst cardTime = cva(\n 'event-card-time ds:hidden ds:shrink-0 ds:whitespace-nowrap ds:text-[length:var(--type-meta-size)]',\n {\n variants: {\n layout: {\n // Wide cards, and tall cards from 112px, show the time; tall narrow\n // cards put the start under the name.\n grid: 'ds:eventcard-w176:inline ds:eventcard-tall:inline ds:eventcard-narrow-tall:block',\n month: 'ds:eventcard-w176:inline',\n flow: 'ds:eventcard-w176:inline',\n },\n },\n },\n);\n\nconst cardStart = cva('event-card-start', {\n variants: {\n layout: {\n grid: 'ds:eventcard-w256:hidden',\n month: '',\n flow: 'ds:eventcard-w256:hidden',\n },\n },\n});\n\nconst cardRange = cva('event-card-range', {\n variants: {\n layout: {\n grid: 'ds:hidden ds:eventcard-w256:inline',\n month: 'ds:hidden',\n flow: 'ds:hidden ds:eventcard-w256:inline',\n },\n },\n});\n\nconst secondaryLine =\n 'ds:col-span-full ds:overflow-hidden ds:text-[length:var(--type-meta-size)] ds:wrap-break-word';\n\nconst cardSuffix = cva(`event-card-suffix ${secondaryLine}`, {\n variants: {\n layout: {\n grid: [\n 'ds:hidden ds:eventcard-h2:line-clamp-1',\n 'ds:eventcard-narrow:order-2 ds:eventcard-narrow-h2:hidden ds:eventcard-narrow-h5:line-clamp-1',\n 'ds:eventcard-sliver:hidden ds:eventcard-h7-mid:line-clamp-2',\n ].join(' '),\n month: 'ds:hidden',\n flow: 'ds:line-clamp-1 ds:eventcard-narrow:order-2',\n },\n },\n});\n\nconst cardContext = cva(`event-card-context ${secondaryLine}`, {\n variants: {\n layout: {\n grid: 'ds:hidden ds:eventcard-narrow:order-3 ds:eventcard-context:line-clamp-1',\n month: 'ds:hidden',\n flow: 'ds:hidden',\n },\n },\n});\n\n/* One-line narrow cards: the cluster sits over the end of the name. */\nconst NARROW_OVERLAY_MARKERS =\n 'ds:eventcard-narrow:absolute ds:eventcard-narrow:end-0 ds:eventcard-narrow:[inset-block-end:0] ds:eventcard-narrow:gap-0';\n\nconst cardMarkers = cva(\n 'event-card-markers ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:col-[2] ds:row-[1]',\n {\n variants: {\n layout: {\n grid: [\n NARROW_OVERLAY_MARKERS,\n 'ds:eventcard-narrow-h2:static ds:eventcard-narrow-h2:gap-[var(--spacing-2xs)] ds:eventcard-narrow-h2:order-1',\n 'ds:eventcard-tall:row-auto ds:eventcard-tall:col-span-full',\n ].join(' '),\n month: NARROW_OVERLAY_MARKERS,\n // Lists and timelines have no height tiers, so a narrow flow card\n // keeps its markers in the column, between name and treatment,\n // instead of laying them over the treatment line. The row wraps so\n // a slim card's dot never falls off the edge.\n flow: 'ds:eventcard-narrow:order-1 ds:eventcard-narrow:flex-wrap',\n },\n },\n },\n);\n\n/* Marker visibility by priority rank: the first always shows; later ones\n join as the card widens, and all show on tall wide cards. Month shows\n the first only. */\nconst cardMarker = cva(\n `event-card-marker ${INDICATOR_DISC_BASE} ds:size-[1em] ds:[&_svg]:size-[0.75em] ds:eventcard-narrow:size-[0.75em] ds:eventcard-narrow-h2:size-[1em]`,\n {\n variants: {\n rank: {\n first: 'ds:inline-flex',\n second: 'ds:hidden',\n third: 'ds:hidden',\n rest: 'ds:hidden',\n },\n layout: { grid: '', month: '', flow: '' },\n },\n compoundVariants: [\n {\n layout: ['grid', 'flow'],\n rank: 'second',\n class: 'ds:eventcard-w256:inline-flex',\n },\n {\n layout: ['grid', 'flow'],\n rank: 'third',\n class: 'ds:eventcard-w352:inline-flex',\n },\n {\n layout: ['grid', 'flow'],\n rank: ['second', 'third', 'rest'],\n class: 'ds:eventcard-tall-wide:inline-flex',\n },\n ],\n },\n);\n\nconst MARKER_RANK = ['first', 'second', 'third'] as const;\n\n/* \"+N\" after the first `capacity` markers; at most one shows per tier. */\nconst cardMore = cva(\n 'event-card-more ds:text-[length:var(--type-meta-size)] ds:whitespace-nowrap',\n {\n variants: {\n capacity: {\n 1: 'event-card-more-1',\n 2: 'event-card-more-2 ds:hidden',\n 3: 'event-card-more-3 ds:hidden',\n },\n layout: { grid: '', month: '', flow: '' },\n },\n compoundVariants: [\n { layout: 'month', capacity: 1, class: 'ds:inline' },\n {\n layout: 'grid',\n capacity: 1,\n class: [\n 'ds:inline ds:eventcard-w256:hidden ds:eventcard-narrow:hidden',\n 'ds:eventcard-narrow-count:inline ds:eventcard-narrow-h2:inline ds:eventcard-tall-wide:hidden',\n ].join(' '),\n },\n // Flow keeps narrow markers in the column, with room to count from\n // 64px; slimmer flow cards fall back to the dot.\n {\n layout: 'flow',\n capacity: 1,\n class:\n 'ds:inline ds:@max-[64px]/eventcard:hidden ds:eventcard-w256:hidden',\n },\n {\n layout: ['grid', 'flow'],\n capacity: 2,\n class:\n 'ds:eventcard-w256:inline ds:eventcard-w352:hidden ds:eventcard-tall-wide:hidden',\n },\n {\n layout: ['grid', 'flow'],\n capacity: 3,\n class: 'ds:eventcard-w352:inline ds:eventcard-tall-wide:hidden',\n },\n ],\n },\n);\n\n/* The sliver cue: a dot saying \"more markers than shown\", where \"+N\" does\n not fit. Rendered only when markers are actually hidden. Month always\n counts, so it has none. */\nconst sliverCue = cva(\n 'event-card-sliver-cue ds:hidden ds:items-center ds:text-[length:var(--type-meta-size)]',\n {\n variants: {\n layout: {\n grid: 'ds:eventcard-narrow:flex ds:eventcard-narrow-count:hidden ds:eventcard-narrow-h2:hidden',\n month: '',\n flow: 'ds:@max-[64px]/eventcard:flex',\n },\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Props */\n/* ------------------------------------------------------------------ */\n\n/**\n * The single painted surface of a calendar event.\n *\n * Colour model (platform parity): the caller's picker hex\n * (`backgroundColor` / `textColor` / `borderColor`) is the ONLY thing that\n * paints the card. `status` never paints the surface — it selects an icon\n * and (for `cancelled`) a line-through.\n *\n * Non-interactive by design: inside FullCalendar the outer harness anchor\n * owns click/drag/focus; standalone consumers wrap the card in their own\n * button/link. No onClick in the contract.\n */\nexport interface CalendarEventCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /**\n * Primary line. Pass the ALREADY-MASKED title when privacy applies — the\n * card never receives a name it must not render, so it cannot leak it\n * (visually or via the composed aria-label).\n */\n title: string;\n /** Optional surname/short form for slivers. Ignored when privacyMasked. */\n shortTitle?: string;\n /** Localised start time for narrow cards. No parsing of rangeText. */\n startText?: string;\n /** Month keeps one line; flow preserves intrinsic height in lists/timelines. */\n layout?: 'grid' | 'month' | 'flow';\n /** Opposite resource axis: operator initials or chair, on tall cards. */\n contextLabel?: string;\n /**\n * Full name behind `contextLabel`, used in the accessible name instead of\n * it, so initials such as \"DA\" are not read out letter by letter. Never\n * rendered visually.\n */\n contextName?: string;\n /**\n * Secondary description, clamped to the lines the card can hold. Note: the\n * Calendar's privacy mode does NOT mask the suffix (current behaviour,\n * preserved deliberately).\n */\n suffix?: string;\n /**\n * Pre-formatted, localised time range (e.g. \"09:00 – 09:45\"). The\n * Calendar adapter computes it via Intl.DateTimeFormat.formatRange.\n * Included in the composed aria-label whenever present (even when the\n * visual time line is suppressed via showTime/allDay — matches today's\n * Calendar behaviour byte-for-byte).\n */\n rangeText?: string;\n /**\n * Gates the VISUAL time line only (aria keeps rangeText). Mirrors\n * CalendarProps.showTime. @default true\n */\n showTime?: boolean;\n /**\n * All-day events suppress the visual time line (aria keeps rangeText).\n * @default false\n */\n allDay?: boolean;\n\n /**\n * Lifecycle state (6-state, matches the platform DoctorAppointment\n * lifecycle) → status icon + line-through for `cancelled` +\n * localised label in the aria-label. NEVER paints the\n * card surface.\n */\n status?: CalendarEventStatus;\n\n /**\n * Runtime hex (#rgb or #rrggbb) from the consumer's colour picker — THE\n * painted surface. Injected as `--calendar-event-bg` via the sanctioned\n * inline custom-property pattern (23-constraints §inline-style exception).\n */\n backgroundColor?: string;\n /**\n * Runtime hex paired with backgroundColor. When omitted while\n * backgroundColor is set, the card auto-derives black/white ink by\n * luminance (provably WCAG AA ≥ 4.58:1 for any opaque colour).\n */\n textColor?: string;\n /**\n * Runtime hex border for delineating light surfaces. The platform sends\n * '#cccccc' when backgroundColor is '#ffffff' and omits it otherwise.\n * Falls back to transparent; appointments have a 4px start edge and\n * a 1px border elsewhere (tasks and drafts have 1px on every side), so toggling never shifts layout and event boundaries\n * survive forced-colors / Windows High Contrast for free.\n */\n borderColor?: string;\n\n /* Indicator icons — names identical to CalendarEvent fields (1:1 map). */\n /** Globe icon + diagonal stripe overlay. */\n isBookedOnline?: boolean;\n /** AlertTriangle icon. */\n hasUnassignedPatient?: boolean;\n /** HeartPulse icon. */\n hasHighlightedAnamnesis?: boolean;\n /** Euro icon. */\n hasBillableAmount?: boolean;\n /** Video icon. */\n isTelehealth?: boolean;\n /**\n * Repeat icon — this event belongs to a REPEATING SERIES. Set it on\n * every occurrence, not only the first: the flag answers \"will moving\n * or deleting this touch other appointments?\", which is true of a\n * modified occurrence too. Series ROLE (which row owns the rule) is a\n * separate concern — see `CalendarEvent.isRecurrenceParent`.\n */\n isRecurring?: boolean;\n /**\n * Task treatment — a calendar-scheduled to-do renders distinctly from an\n * appointment: dashed outline (derived from the resolved ink when no\n * `borderColor` is supplied), muted default surface (an explicit\n * `backgroundColor`/`textColor` still wins), a leading clipboard glyph,\n * and a localised \"task\" word appended to the accessible name. Emitted as\n * `data-kind=\"task\"` for DOM hooks.\n */\n isTask?: boolean;\n /**\n * Draft treatment — a placeholder for an appointment being composed:\n * the slot the user just picked, mirrored on the grid while the editor\n * is open. Dashed outline over a light primary tint, with a localised\n * \"draft\" word appended to the accessible name. Emitted as\n * `data-kind=\"draft\"`. Takes precedence over `isTask`, and like a task\n * it forces the solid paint path so exactly one class-level assignment\n * of each paint custom property exists per render.\n */\n isDraft?: boolean;\n /**\n * Details-pending treatment — a REAL booked appointment an\n * occupancy-first host drew from the slot it occupies while it still\n * fetches whose it is. The card keeps its colour and size and renders an\n * `aria-hidden` skeleton bar where the title goes, with the localised\n * \"loading details\" word in the accessible name and\n * `data-kind=\"pending-details\"` as the hook. Wins over `isDraft`/`isTask`.\n */\n detailsPending?: boolean;\n /**\n * Colour scheme for the picker colour. `'solid'` (default) is the\n * platform model — the hex paints the whole surface, ink auto-derived.\n * `'tinted'` is the chip-family scheme: the hex becomes a SOLID BORDER\n * over a light tint of itself (theme-aware via color-mix with `--card`),\n * with text on the theme's foreground tokens — `textColor` and\n * `borderColor` are ignored under it. Tasks keep their muted dashed\n * treatment regardless.\n */\n colorStyle?: 'solid' | 'tinted';\n /**\n * Steps the card back: a light tint of the picker colour with muted text\n * and a softer border, whatever `colorStyle` says. Colour only, no\n * opacity, so the text stays readable. The calendar sets it on a shown\n * cancelled appointment. Tasks and drafts keep their own treatment.\n * @default false\n */\n faded?: boolean;\n\n /**\n * Resource title (chair/operator) woven into the composed aria-label\n * only — never rendered visually. The Calendar adapter resolves\n * resourceId → title before passing it.\n */\n resourceLabel?: string;\n /**\n * The title is a privacy MASK (the Calendar's privacy mode swapped the\n * patient name for `privacyModeTitle`). Renders a crossed-out-eye glyph\n * beside the mask so the redaction is legible as deliberate, with its\n * own breathing room after the time.\n */\n privacyMasked?: boolean;\n /**\n * Stable event id → emitted as `data-event-id` (Calendar.focusEvent\n * targets it) and used as the contrast-warning dedup context.\n */\n eventId?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const CalendarEventCard = forwardRef<\n HTMLDivElement,\n CalendarEventCardProps\n>(\n (\n {\n title,\n shortTitle,\n startText,\n layout = 'grid',\n contextLabel,\n contextName,\n suffix,\n rangeText,\n showTime = true,\n allDay = false,\n status,\n backgroundColor,\n textColor,\n borderColor,\n isBookedOnline = false,\n hasUnassignedPatient,\n hasHighlightedAnamnesis,\n hasBillableAmount,\n isTelehealth,\n isRecurring,\n isTask = false,\n isDraft = false,\n detailsPending = false,\n colorStyle = 'solid',\n faded = false,\n resourceLabel,\n privacyMasked = false,\n eventId,\n className,\n style,\n 'aria-label': ariaLabelProp,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n const markers = [\n ...(status\n ? [\n {\n id: 'status',\n Icon: STATUS_ICON[status],\n label: t(STATUS_LABEL_KEYS[status]),\n tone: STATUS_DISC_TONE[status],\n },\n ]\n : []),\n ...EVENT_FLAGS.filter(({ field }) =>\n Boolean(\n {\n hasUnassignedPatient,\n hasHighlightedAnamnesis,\n hasBillableAmount,\n isBookedOnline,\n isTelehealth,\n isRecurring,\n }[field],\n ),\n ).map(({ field, Icon, labelKey, tone }) => ({\n id: field,\n Icon,\n label: t(labelKey),\n tone,\n })),\n ];\n const statusLabel = status ? t(STATUS_LABEL_KEYS[status]) : undefined;\n const kindLabel = detailsPending\n ? t('calendar.eventKind.pendingDetails')\n : isDraft\n ? t('calendar.eventKind.draft')\n : isTask\n ? t('calendar.eventKind.task')\n : undefined;\n\n /* Accessible name — the Calendar's historical composition, with the\n localised \"task\" word appended for task cards so screen-reader users\n get the same appointment-vs-task distinction the dashed outline and\n clipboard glyph carry visually. An explicit consumer-supplied\n aria-label wins. rangeText is always included when present, even when\n the visual time line is hidden. */\n const ariaLabel =\n ariaLabelProp ??\n [\n title,\n rangeText,\n suffix,\n resourceLabel,\n // A blank name falls back to the visible label rather than\n // silencing the context altogether.\n contextName?.trim() ? contextName : contextLabel,\n statusLabel,\n kindLabel,\n ...markers\n .filter((marker) => marker.id !== 'status')\n .map((marker) => marker.label),\n ]\n .filter(Boolean)\n .join(', ');\n\n const kind = detailsPending\n ? 'pending-details'\n : isDraft\n ? 'draft'\n : isTask\n ? 'task'\n : 'appointment';\n\n /* Tasks force the solid path — their muted variant owns the paint\n custom properties, so the tinted class must never co-assign them. */\n const isFaded = !isTask && !isDraft && faded;\n const tinted = !isTask && !isDraft && (colorStyle === 'tinted' || isFaded);\n\n /* Ink derivation — solid scheme only, when the caller paints the\n surface without pairing a text colour. */\n const ink =\n !tinted && !textColor && backgroundColor\n ? resolveInk(backgroundColor)\n : null;\n\n /* DEV-only guardrails — every helper no-ops in production and dedupes\n per session, so calling during render is safe. The tinted scheme\n paints text on theme tokens over a 12% tint, so the solid-scheme\n pair checks don't apply there. */\n const warnContext = eventId ? `event ${eventId}` : 'calendar-event-card';\n if (!tinted) {\n warnLowContrast(backgroundColor, textColor, warnContext);\n if (backgroundColor && !textColor) {\n // no-ops when the hex is parseable (i.e. when resolveInk succeeded)\n warnUnparseableBackground(backgroundColor, warnContext);\n }\n if (backgroundColor && !borderColor) {\n // no-ops unless the background is near-white (luminance > 0.9)\n warnLowDelineation(backgroundColor, warnContext);\n }\n }\n\n /* Per-event colour override: the consuming app passes runtime hex from\n its colour picker. 23-constraints permits inline `style` only as a\n CSS custom-property setter for runtime values that can't be\n enumerated at build time — the consuming background-color / color /\n border-color declarations live in the CVA base as Tailwind arbitrary\n values with token fallbacks. */\n const colourOverrides: CSSProperties | undefined = tinted\n ? backgroundColor\n ? ({ '--calendar-event-accent': backgroundColor } as CSSProperties)\n : undefined\n : backgroundColor || textColor || borderColor\n ? ({\n ...(backgroundColor\n ? { '--calendar-event-bg': backgroundColor }\n : {}),\n ...(textColor\n ? { '--calendar-event-text': textColor }\n : ink === 'on-light'\n ? { '--calendar-event-text': 'var(--event-ink-on-light)' }\n : ink === 'on-dark'\n ? { '--calendar-event-text': 'var(--event-ink-on-dark)' }\n : {}),\n ...(borderColor ? { '--calendar-event-border': borderColor } : {}),\n } as CSSProperties)\n : undefined;\n\n const mergedStyle: CSSProperties | undefined =\n style || colourOverrides ? { ...style, ...colourOverrides } : undefined;\n\n /* A surname for slivers, never under privacy. */\n const showShortTitle = Boolean(\n !privacyMasked && shortTitle?.trim() && shortTitle !== title,\n );\n\n return (\n <div\n ref={ref}\n role=\"group\"\n {...rest}\n className={calendarEventCardVariants({\n layout,\n status: status ?? 'none',\n bookedOnline: isBookedOnline,\n kind,\n colorStyle: isFaded ? 'faded' : tinted ? 'tinted' : 'solid',\n className,\n })}\n // eslint-disable-next-line react/forbid-dom-props -- caller-supplied event bg/text/border hex injected via CSS variables (23-constraints §inline-style exception)\n style={mergedStyle}\n aria-label={ariaLabel}\n data-component=\"calendar-event-card\"\n data-event-id={eventId}\n data-kind={kind}\n data-status={status ?? 'none'}\n data-contrast={\n tinted ? 'tinted' : textColor ? 'custom' : (ink ?? 'default')\n }\n >\n <span className={cardContent} aria-hidden=\"true\">\n <span className={cardHeading}>\n <span\n className={cardName({\n layout,\n hiddenMarkers: markers.length > 1,\n })}\n >\n {detailsPending ? (\n <span aria-hidden=\"true\" className={PENDING_BAR_CLASS} />\n ) : (\n <>\n {isTask ? <ClipboardCheck className={cardKindIcon} /> : null}\n {privacyMasked ? <EyeOff className={cardKindIcon} /> : null}\n <span\n className={cardFullTitle({\n hasShortTitle: showShortTitle,\n })}\n >\n {title}\n </span>\n {showShortTitle ? (\n <span className=\"event-card-short-title ds:hidden ds:eventcard-sliver:inline\">\n {shortTitle}\n </span>\n ) : null}\n </>\n )}\n </span>\n {showTime && !allDay && rangeText ? (\n <span className={cardTime({ layout })}>\n {startText ? (\n <>\n <span className={cardStart({ layout })}>{startText}</span>\n <span className={cardRange({ layout })}>{rangeText}</span>\n </>\n ) : (\n rangeText\n )}\n </span>\n ) : null}\n </span>\n {suffix ? (\n <span className={cardSuffix({ layout })}>{suffix}</span>\n ) : null}\n {contextLabel ? (\n <span className={cardContext({ layout })}>{contextLabel}</span>\n ) : null}\n {markers.length > 0 ? (\n <span className={cardMarkers({ layout })}>\n {markers.map(({ id, Icon, tone }, index) => (\n <span\n key={id}\n data-marker={id}\n aria-hidden=\"true\"\n className={cardMarker({\n rank: MARKER_RANK[index] ?? 'rest',\n layout,\n className: INDICATOR_DISC_TONE[tone],\n })}\n >\n <Icon aria-hidden=\"true\" />\n </span>\n ))}\n {([1, 2, 3] as const).map((capacity) =>\n markers.length > capacity ? (\n <span\n key={capacity}\n className={cardMore({ capacity, layout })}\n >\n {t('calendar.card.more', {\n number: markers.length - capacity,\n })}\n </span>\n ) : null,\n )}\n {markers.length > 1 && layout !== 'month' ? (\n <span className={sliverCue({ layout })}>·</span>\n ) : null}\n </span>\n ) : null}\n </span>\n </div>\n );\n },\n);\nCalendarEventCard.displayName = 'CalendarEventCard';\n"],"names":["parseHex","hex","trimmed","body","r","g","b","relativeLuminance","lin","c","warnLowContrast","bgHex","fgHex","contextLabel","resolveInk","bg","STATUS_ICON","ThumbsUp","Clock","Stethoscope","Check","Ban","UserX","INDICATOR_DISC_BASE","PENDING_BAR_CLASS","INDICATOR_DISC_TONE","STATUS_DISC_TONE","STATUS_LABEL_KEYS","EVENT_FLAGS","TriangleAlert","HeartPulse","Euro","Globe","Video","Repeat","calendarEventCardVariants","cva","cardContent","cardHeading","cardName","cardFullTitle","cardKindIcon","cardTime","cardStart","cardRange","secondaryLine","cardSuffix","cardContext","NARROW_OVERLAY_MARKERS","cardMarkers","cardMarker","MARKER_RANK","cardMore","sliverCue","CalendarEventCard","forwardRef","title","shortTitle","startText","layout","contextName","suffix","rangeText","showTime","allDay","status","backgroundColor","textColor","borderColor","isBookedOnline","hasUnassignedPatient","hasHighlightedAnamnesis","hasBillableAmount","isTelehealth","isRecurring","isTask","isDraft","detailsPending","colorStyle","faded","resourceLabel","privacyMasked","eventId","className","style","ariaLabelProp","rest","ref","t","useTranslation","markers","field","Icon","labelKey","tone","statusLabel","kindLabel","ariaLabel","marker","kind","isFaded","tinted","ink","colourOverrides","mergedStyle","showShortTitle","jsx","jsxs","Fragment","ClipboardCheck","EyeOff","id","index","capacity"],"mappings":"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"}
|
|
@@ -7,10 +7,10 @@ import { P as A } from "./progress-D_g_Sl2g.js";
|
|
|
7
7
|
import { T as C } from "./timestamp-DPLDWdxA.js";
|
|
8
8
|
import { T as L } from "./transaction-chip-CkYd-3ky.js";
|
|
9
9
|
import { A as O, b as G, c as Y, a as $ } from "./accordion-Ch3xp0mX.js";
|
|
10
|
-
import { C as q } from "./care-plan-entry-card-
|
|
10
|
+
import { C as q } from "./care-plan-entry-card-DY1toF6E.js";
|
|
11
11
|
import { u as J } from "./registry-DvAUVLHh.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { i as Q } from "./is-safe-url-CEy9CEml.js";
|
|
13
|
+
import { C as W, e as X } from "./entity-card-p-LANpYt.js";
|
|
14
14
|
const Z = {
|
|
15
15
|
id: "care-plan-card",
|
|
16
16
|
// `expand` is host-delegated: the treatment-line list is an in-component
|
|
@@ -85,7 +85,7 @@ const Z = {
|
|
|
85
85
|
);
|
|
86
86
|
const K = d(`carePlanCard.state.${o}`, {
|
|
87
87
|
defaultValue: ae[o]
|
|
88
|
-
}), R =
|
|
88
|
+
}), R = W[o], U = !!u && Q(u), k = !!m && m.length > 0, i = s == null ? void 0 : s.dueCents, p = s == null ? void 0 : s.billedAmountCents, h = s == null ? void 0 : s.overdueDays, z = typeof h == "number" && h > 0 && typeof i == "number" && i > 0, y = /* @__PURE__ */ e(
|
|
89
89
|
"h3",
|
|
90
90
|
{
|
|
91
91
|
id: x,
|
|
@@ -104,7 +104,7 @@ const Z = {
|
|
|
104
104
|
"data-component-id": l,
|
|
105
105
|
"data-state": o,
|
|
106
106
|
id: l,
|
|
107
|
-
className:
|
|
107
|
+
className: X({ surface: I, className: D }),
|
|
108
108
|
...S,
|
|
109
109
|
children: /* @__PURE__ */ t("div", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]", children: [
|
|
110
110
|
/* @__PURE__ */ t("div", { className: "ds:flex ds:items-start ds:gap-[var(--spacing-sm)]", children: [
|
|
@@ -253,4 +253,4 @@ export {
|
|
|
253
253
|
de as C,
|
|
254
254
|
Z as c
|
|
255
255
|
};
|
|
256
|
-
//# sourceMappingURL=care-plan-card-
|
|
256
|
+
//# sourceMappingURL=care-plan-card-CjHq6PLo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"care-plan-card-DKScH9Ss.js","sources":["../../src/components/care-plan-card/care-plan-card.agent.ts","../../src/components/care-plan-card/care-plan-card.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — CarePlanCard. */\n/* */\n/* Read-only surface: expose the plan's lifecycle state and line-progress */\n/* counts so an agent can introspect a care plan's status. State enum + */\n/* counts only — never the plan name, operator, treatment names, or any */\n/* patient identity. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { CarePlanCardHandle } from './care-plan-card';\n\nexport const carePlanCardAgent: AgentAdapter<CarePlanCardHandle> = {\n id: 'care-plan-card',\n // `expand` is host-delegated: the treatment-line list is an in-component\n // Accordion the user (or a host) drives directly — there is no handle\n // method for it, so no backing action is registered. `view_change` was\n // dropped: the card has no view modes to switch between.\n capabilities: ['expand'],\n state: {\n state: {\n type: \"'estimate' | 'accepted' | 'discarded' | 'closed'\",\n descriptionKey: 'ui.agent.carePlanCard.state.state',\n description:\n 'The plan lifecycle state. Enum value only — never the localised label or any PHI.',\n read: (handle) => handle.getState(),\n },\n progress: {\n type: '{ done: number; total: number }',\n descriptionKey: 'ui.agent.carePlanCard.state.progress',\n description:\n 'Line progress as done / total counts. Counts only — never treatment names or operator identity.',\n read: (handle) => handle.getProgress(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'care-plan-card',\n description: 'Marks the CarePlanCard root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop. Addresses a specific plan.',\n },\n },\n};\n","import { forwardRef, useId, type HTMLAttributes } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '../badge/badge';\nimport { Link } from '../link/link';\nimport { Progress } from '../progress/progress';\nimport { Timestamp } from '../timestamp/timestamp';\nimport { TransactionChip } from '../transaction-chip/transaction-chip';\nimport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from '../accordion/accordion';\nimport {\n CarePlanEntryCard,\n type CarePlanEntryCardProps,\n} from '../care-plan-entry-card';\nimport {\n entitySurfaceVariants,\n CARE_PLAN_STATE_BADGE,\n isSafeEntityUrl,\n type CarePlanState,\n} from '../_shared/entity-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { carePlanCardAgent } from './care-plan-card.agent';\n\n/* -------------------------------------------------------------------- */\n/* CarePlanCard */\n/* */\n/* The summary card for a whole care plan / estimate (\"preventivo\"). */\n/* Replaces the hand-rolled platform care-plan header that interleaves */\n/* the plan number + name, a lifecycle badge, the financial figures */\n/* (billed / due / overdue), an acceptance/closure date, a phase- */\n/* progress bar, an optional deep link, and an expandable list of the */\n/* plan's treatment lines. */\n/* */\n/* Composes: entitySurfaceVariants (shared card surface) + Badge */\n/* (lifecycle state) + TransactionChip (money) + Progress (done/total) */\n/* + Timestamp (dates) + Link (deep link) + Accordion (entries rendered */\n/* as <CarePlanEntryCard> rows). */\n/* */\n/* All visible text flows through useTranslation('ui') against the */\n/* `carePlanCard.*` namespace — the lifecycle state is ALWAYS shown as a */\n/* localised label, never the raw server string. Identifiers + structural */\n/* state only reach the agent layer — never patient identity. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\n/**\n * A single treatment line within the plan. Each ref is forwarded straight\n * to a `<CarePlanEntryCard>` rendered inside the Accordion. `entryId` keys\n * the row and surfaces as the line's `data-component-id`.\n */\nexport interface CarePlanEntryRef extends Omit<\n CarePlanEntryCardProps,\n 'id' | 'surface'\n> {\n /** Stable line id — identifier only, never PHI. */\n entryId: string;\n}\n\n/** Financial figures for the plan, all amounts in integer cents. */\nexport interface CarePlanAmounts {\n /** Full list price in cents (non-negative). */\n priceCents?: number;\n /** Discounted / agreed price in cents (non-negative). */\n discountedPriceCents?: number;\n /** Amount already invoiced in cents (non-negative). */\n billedAmountCents?: number;\n /** Outstanding amount still due in cents (non-negative). */\n dueCents?: number;\n /** How many days the due amount is overdue (non-negative). */\n overdueDays?: number;\n}\n\n/** Phase / line progress for the plan. */\nexport interface CarePlanProgress {\n /** Number of executed / completed lines. */\n done: number;\n /** Total number of lines. */\n total: number;\n}\n\n/** Lifecycle dates for the plan, all ISO-8601 strings. */\nexport interface CarePlanDates {\n /** When the plan was accepted. */\n acceptedIso?: string;\n /** When the plan was closed. */\n closedIso?: string;\n /** When the plan was discarded / rejected. */\n discardedIso?: string;\n}\n\n/** Curated read-only handle exposed to the agent registry. */\nexport interface CarePlanCardHandle {\n /** The plan's lifecycle state. */\n getState: () => CarePlanState;\n /** Line progress as `{ done, total }` — counts only, no PHI. */\n getProgress: () => { done: number; total: number };\n}\n\nexport interface CarePlanCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'aria-label' | 'title' | 'children'\n> {\n /**\n * Stable instance id — surfaced as `data-component-id` for the agent\n * registry and mirrored to the DOM `id`; also wires the heading ↔ region\n * relationship.\n */\n id?: string;\n /** Plan number (e.g. estimate number). Rendered beside the name. */\n number: string | number;\n /** Plan name / title. Rendered as the card heading. */\n name?: string;\n /** Lifecycle state — drives a localised Badge label. */\n state: CarePlanState;\n /** Optional deep link to the full plan. Guarded by `isSafeEntityUrl`. */\n url?: string;\n /** Financial figures (billed / due / overdue …). */\n amounts?: CarePlanAmounts;\n /** Line progress (done / total). */\n progress?: CarePlanProgress;\n /** Lifecycle dates (accepted / closed / discarded). */\n dates?: CarePlanDates;\n /** Reason the plan was discarded — shown only when `state === 'discarded'`. */\n discardReason?: string;\n /**\n * Dentition the plan applies to — forwarded to each entry card's tooth\n * display where relevant. Structural only.\n */\n dentitionMode?: 'permanent' | 'deciduous';\n /** Treatment lines — rendered as `<CarePlanEntryCard>` rows in an Accordion. */\n entries?: CarePlanEntryRef[];\n /** BCP 47 locale override for dates / currency. Defaults to i18n.language. */\n locale?: string;\n /** ISO 4217 currency code for the money chips. Defaults to `EUR`. */\n currency?: string;\n /**\n * `elevated` (default) paints the kit card chrome; `flat` drops it for use\n * inside an existing Card / Sheet.\n */\n surface?: 'flat' | 'elevated';\n /** Fires when the plan deep link / heading is activated. */\n onActivate?: () => void;\n /** Accessible label override for the plan region. */\n 'aria-label'?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------- */\n\nconst DEFAULT_CURRENCY = 'EUR';\n\n/**\n * English fallbacks for the lifecycle-state labels. The canonical strings\n * live in the `ui.carePlanCard.state.*` bundle; these inline defaults guard\n * against a stale / not-yet-wired bundle so a raw key never reaches the UI.\n */\nconst STATE_LABEL_FALLBACK: Record<CarePlanState, string> = {\n estimate: 'Estimate',\n accepted: 'Accepted',\n discarded: 'Discarded',\n closed: 'Closed',\n};\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const CarePlanCard = forwardRef<HTMLDivElement, CarePlanCardProps>(\n (\n {\n id,\n number,\n name,\n state,\n url,\n amounts,\n progress,\n dates,\n discardReason,\n dentitionMode: _dentitionMode,\n entries,\n locale,\n currency = DEFAULT_CURRENCY,\n surface = 'elevated',\n onActivate,\n 'aria-label': ariaLabel,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const headingId = useId();\n const progressLabelId = useId();\n const activeLocale = locale ?? i18n.language ?? 'en';\n\n useAgentRegistration(\n carePlanCardAgent,\n {\n getState: () => state,\n getProgress: () => ({\n done: progress?.done ?? 0,\n total: progress?.total ?? 0,\n }),\n },\n id,\n );\n\n const stateLabel = t(`carePlanCard.state.${state}`, {\n defaultValue: STATE_LABEL_FALLBACK[state],\n });\n const stateBadgeVariant = CARE_PLAN_STATE_BADGE[state];\n const hasSafeUrl = !!url && isSafeEntityUrl(url);\n const hasEntries = !!entries && entries.length > 0;\n\n // Money: prefer the outstanding \"due\" chip; mark it overdue when it has\n // run past its term. Anything billed shows a settled chip alongside.\n const dueCents = amounts?.dueCents;\n const billedCents = amounts?.billedAmountCents;\n const overdueDays = amounts?.overdueDays;\n const isOverdue =\n typeof overdueDays === 'number' &&\n overdueDays > 0 &&\n typeof dueCents === 'number' &&\n dueCents > 0;\n\n const headingNode = (\n <h3\n id={headingId}\n className=\"type-title-card ds:m-0 ds:text-[color:var(--foreground)]\"\n >\n {name ?? t('carePlanCard.untitled', 'Untitled plan')}\n </h3>\n );\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabel ? undefined : headingId}\n data-component=\"care-plan-card\"\n data-component-id={id}\n data-state={state}\n id={id}\n className={entitySurfaceVariants({ surface, className })}\n {...rest}\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Heading row: number + name + lifecycle badge */}\n <div className=\"ds:flex ds:items-start ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)] ds:tabular-nums\">\n {t('carePlanCard.number', {\n number,\n defaultValue: 'Plan #{{number}}',\n })}\n </span>\n {hasSafeUrl ? (\n <Link\n href={url as string}\n weight=\"strong\"\n onClick={(event) => {\n if (\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey\n ) {\n return;\n }\n onActivate?.();\n }}\n >\n {headingNode}\n </Link>\n ) : (\n headingNode\n )}\n </div>\n\n <Badge\n variant={stateBadgeVariant}\n size=\"sm\"\n withDot\n className=\"ds:shrink-0\"\n >\n {stateLabel}\n </Badge>\n </div>\n\n {/* Discard reason — only when discarded */}\n {state === 'discarded' && discardReason ? (\n <p className=\"type-body-sm ds:m-0 ds:text-[color:var(--muted-foreground)]\">\n <span className=\"ds:font-medium ds:text-[color:var(--foreground)]\">\n {t('carePlanCard.discardReasonLabel', 'Discard reason:')}\n </span>{' '}\n {discardReason}\n </p>\n ) : null}\n\n {/* Lifecycle date line */}\n {dates ? (\n <div className=\"type-body-sm ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-md)] ds:text-[color:var(--muted-foreground)]\">\n {dates.acceptedIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('carePlanCard.date.accepted', 'Accepted')}</span>\n <Timestamp\n value={dates.acceptedIso}\n format=\"absolute\"\n locale={activeLocale}\n />\n </span>\n ) : null}\n {dates.closedIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('carePlanCard.date.closed', 'Closed')}</span>\n <Timestamp\n value={dates.closedIso}\n format=\"absolute\"\n locale={activeLocale}\n />\n </span>\n ) : null}\n {dates.discardedIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('carePlanCard.date.discarded', 'Discarded')}</span>\n <Timestamp\n value={dates.discardedIso}\n format=\"absolute\"\n locale={activeLocale}\n />\n </span>\n ) : null}\n </div>\n ) : null}\n\n {/* Money: due / overdue / billed chips */}\n {typeof dueCents === 'number' || typeof billedCents === 'number' ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {typeof dueCents === 'number' && dueCents > 0 ? (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <TransactionChip\n state=\"debt\"\n amount={dueCents / 100}\n currency={currency}\n locale={activeLocale}\n showLabel\n size=\"md\"\n />\n {isOverdue ? (\n <Badge variant=\"error\" size=\"sm\" withDot>\n {t('carePlanCard.overdue', {\n count: overdueDays,\n defaultValue: 'Overdue {{count}}d',\n })}\n </Badge>\n ) : null}\n </div>\n ) : null}\n {typeof billedCents === 'number' && billedCents > 0 ? (\n <TransactionChip\n state=\"settled\"\n amount={billedCents / 100}\n currency={currency}\n locale={activeLocale}\n showLabel\n size=\"md\"\n />\n ) : null}\n </div>\n ) : null}\n\n {/* Line / phase progress */}\n {progress && progress.total > 0 ? (\n <Progress\n value={progress.done}\n max={progress.total}\n size=\"sm\"\n aria-label={t('carePlanCard.progressLabel', {\n done: progress.done,\n total: progress.total,\n defaultValue: 'Progress: {{done}} of {{total}} completed',\n })}\n >\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <Progress.Label id={progressLabelId}>\n {t('carePlanCard.progressHeading', 'Progress')}\n </Progress.Label>\n <span className=\"type-body-sm ds:tabular-nums ds:text-[color:var(--muted-foreground)]\">\n {t('carePlanCard.progressCount', {\n done: progress.done,\n total: progress.total,\n defaultValue: '{{done}} / {{total}}',\n })}\n </span>\n </div>\n </Progress>\n ) : null}\n\n {/* Entries — expandable list of treatment lines */}\n {hasEntries ? (\n <Accordion type=\"single\" collapsible variant=\"separated\">\n <AccordionItem value=\"entries\">\n <AccordionTrigger>\n {t('carePlanCard.entries.toggle', {\n count: entries.length,\n defaultValue: 'Treatment lines ({{count}})',\n })}\n </AccordionTrigger>\n <AccordionContent>\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\">\n {entries.map(({ entryId, ...entry }) => (\n <li key={entryId}>\n <CarePlanEntryCard\n id={entryId}\n surface=\"flat\"\n locale={activeLocale}\n currency={currency}\n {...entry}\n />\n </li>\n ))}\n </ul>\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n ) : null}\n </div>\n </div>\n );\n },\n);\n\nCarePlanCard.displayName = 'CarePlanCard';\n\nexport type CarePlanCardSurface = NonNullable<\n VariantProps<typeof entitySurfaceVariants>['surface']\n>;\n\n/** The dentition the plan applies to. */\nexport type CarePlanCardDentition = NonNullable<\n CarePlanCardProps['dentitionMode']\n>;\n\n/* Re-export the shared lifecycle-state type for downstream typing. */\nexport type { CarePlanState } from '../_shared/entity-card';\n"],"names":["carePlanCardAgent","handle","DEFAULT_CURRENCY","STATE_LABEL_FALLBACK","CarePlanCard","forwardRef","id","number","name","state","url","amounts","progress","dates","discardReason","_dentitionMode","entries","locale","currency","surface","onActivate","ariaLabel","className","rest","ref","t","i18n","useTranslation","headingId","useId","progressLabelId","activeLocale","useAgentRegistration","stateLabel","stateBadgeVariant","CARE_PLAN_STATE_BADGE","hasSafeUrl","isSafeEntityUrl","hasEntries","dueCents","billedCents","overdueDays","isOverdue","headingNode","jsx","entitySurfaceVariants","jsxs","Link","event","Badge","Timestamp","TransactionChip","Progress","Accordion","AccordionItem","AccordionTrigger","AccordionContent","entryId","entry","CarePlanEntryCard"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"care-plan-card-CjHq6PLo.js","sources":["../../src/components/care-plan-card/care-plan-card.agent.ts","../../src/components/care-plan-card/care-plan-card.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — CarePlanCard. */\n/* */\n/* Read-only surface: expose the plan's lifecycle state and line-progress */\n/* counts so an agent can introspect a care plan's status. State enum + */\n/* counts only — never the plan name, operator, treatment names, or any */\n/* patient identity. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { CarePlanCardHandle } from './care-plan-card';\n\nexport const carePlanCardAgent: AgentAdapter<CarePlanCardHandle> = {\n id: 'care-plan-card',\n // `expand` is host-delegated: the treatment-line list is an in-component\n // Accordion the user (or a host) drives directly — there is no handle\n // method for it, so no backing action is registered. `view_change` was\n // dropped: the card has no view modes to switch between.\n capabilities: ['expand'],\n state: {\n state: {\n type: \"'estimate' | 'accepted' | 'discarded' | 'closed'\",\n descriptionKey: 'ui.agent.carePlanCard.state.state',\n description:\n 'The plan lifecycle state. Enum value only — never the localised label or any PHI.',\n read: (handle) => handle.getState(),\n },\n progress: {\n type: '{ done: number; total: number }',\n descriptionKey: 'ui.agent.carePlanCard.state.progress',\n description:\n 'Line progress as done / total counts. Counts only — never treatment names or operator identity.',\n read: (handle) => handle.getProgress(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'care-plan-card',\n description: 'Marks the CarePlanCard root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop. Addresses a specific plan.',\n },\n },\n};\n","import { forwardRef, useId, type HTMLAttributes } from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '../badge/badge';\nimport { Link } from '../link/link';\nimport { Progress } from '../progress/progress';\nimport { Timestamp } from '../timestamp/timestamp';\nimport { TransactionChip } from '../transaction-chip/transaction-chip';\nimport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from '../accordion/accordion';\nimport {\n CarePlanEntryCard,\n type CarePlanEntryCardProps,\n} from '../care-plan-entry-card';\nimport {\n entitySurfaceVariants,\n CARE_PLAN_STATE_BADGE,\n isSafeEntityUrl,\n type CarePlanState,\n} from '../_shared/entity-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { carePlanCardAgent } from './care-plan-card.agent';\n\n/* -------------------------------------------------------------------- */\n/* CarePlanCard */\n/* */\n/* The summary card for a whole care plan / estimate (\"preventivo\"). */\n/* Replaces the hand-rolled platform care-plan header that interleaves */\n/* the plan number + name, a lifecycle badge, the financial figures */\n/* (billed / due / overdue), an acceptance/closure date, a phase- */\n/* progress bar, an optional deep link, and an expandable list of the */\n/* plan's treatment lines. */\n/* */\n/* Composes: entitySurfaceVariants (shared card surface) + Badge */\n/* (lifecycle state) + TransactionChip (money) + Progress (done/total) */\n/* + Timestamp (dates) + Link (deep link) + Accordion (entries rendered */\n/* as <CarePlanEntryCard> rows). */\n/* */\n/* All visible text flows through useTranslation('ui') against the */\n/* `carePlanCard.*` namespace — the lifecycle state is ALWAYS shown as a */\n/* localised label, never the raw server string. Identifiers + structural */\n/* state only reach the agent layer — never patient identity. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\n/**\n * A single treatment line within the plan. Each ref is forwarded straight\n * to a `<CarePlanEntryCard>` rendered inside the Accordion. `entryId` keys\n * the row and surfaces as the line's `data-component-id`.\n */\nexport interface CarePlanEntryRef extends Omit<\n CarePlanEntryCardProps,\n 'id' | 'surface'\n> {\n /** Stable line id — identifier only, never PHI. */\n entryId: string;\n}\n\n/** Financial figures for the plan, all amounts in integer cents. */\nexport interface CarePlanAmounts {\n /** Full list price in cents (non-negative). */\n priceCents?: number;\n /** Discounted / agreed price in cents (non-negative). */\n discountedPriceCents?: number;\n /** Amount already invoiced in cents (non-negative). */\n billedAmountCents?: number;\n /** Outstanding amount still due in cents (non-negative). */\n dueCents?: number;\n /** How many days the due amount is overdue (non-negative). */\n overdueDays?: number;\n}\n\n/** Phase / line progress for the plan. */\nexport interface CarePlanProgress {\n /** Number of executed / completed lines. */\n done: number;\n /** Total number of lines. */\n total: number;\n}\n\n/** Lifecycle dates for the plan, all ISO-8601 strings. */\nexport interface CarePlanDates {\n /** When the plan was accepted. */\n acceptedIso?: string;\n /** When the plan was closed. */\n closedIso?: string;\n /** When the plan was discarded / rejected. */\n discardedIso?: string;\n}\n\n/** Curated read-only handle exposed to the agent registry. */\nexport interface CarePlanCardHandle {\n /** The plan's lifecycle state. */\n getState: () => CarePlanState;\n /** Line progress as `{ done, total }` — counts only, no PHI. */\n getProgress: () => { done: number; total: number };\n}\n\nexport interface CarePlanCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'aria-label' | 'title' | 'children'\n> {\n /**\n * Stable instance id — surfaced as `data-component-id` for the agent\n * registry and mirrored to the DOM `id`; also wires the heading ↔ region\n * relationship.\n */\n id?: string;\n /** Plan number (e.g. estimate number). Rendered beside the name. */\n number: string | number;\n /** Plan name / title. Rendered as the card heading. */\n name?: string;\n /** Lifecycle state — drives a localised Badge label. */\n state: CarePlanState;\n /** Optional deep link to the full plan. Guarded by `isSafeEntityUrl`. */\n url?: string;\n /** Financial figures (billed / due / overdue …). */\n amounts?: CarePlanAmounts;\n /** Line progress (done / total). */\n progress?: CarePlanProgress;\n /** Lifecycle dates (accepted / closed / discarded). */\n dates?: CarePlanDates;\n /** Reason the plan was discarded — shown only when `state === 'discarded'`. */\n discardReason?: string;\n /**\n * Dentition the plan applies to — forwarded to each entry card's tooth\n * display where relevant. Structural only.\n */\n dentitionMode?: 'permanent' | 'deciduous';\n /** Treatment lines — rendered as `<CarePlanEntryCard>` rows in an Accordion. */\n entries?: CarePlanEntryRef[];\n /** BCP 47 locale override for dates / currency. Defaults to i18n.language. */\n locale?: string;\n /** ISO 4217 currency code for the money chips. Defaults to `EUR`. */\n currency?: string;\n /**\n * `elevated` (default) paints the kit card chrome; `flat` drops it for use\n * inside an existing Card / Sheet.\n */\n surface?: 'flat' | 'elevated';\n /** Fires when the plan deep link / heading is activated. */\n onActivate?: () => void;\n /** Accessible label override for the plan region. */\n 'aria-label'?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------- */\n\nconst DEFAULT_CURRENCY = 'EUR';\n\n/**\n * English fallbacks for the lifecycle-state labels. The canonical strings\n * live in the `ui.carePlanCard.state.*` bundle; these inline defaults guard\n * against a stale / not-yet-wired bundle so a raw key never reaches the UI.\n */\nconst STATE_LABEL_FALLBACK: Record<CarePlanState, string> = {\n estimate: 'Estimate',\n accepted: 'Accepted',\n discarded: 'Discarded',\n closed: 'Closed',\n};\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const CarePlanCard = forwardRef<HTMLDivElement, CarePlanCardProps>(\n (\n {\n id,\n number,\n name,\n state,\n url,\n amounts,\n progress,\n dates,\n discardReason,\n dentitionMode: _dentitionMode,\n entries,\n locale,\n currency = DEFAULT_CURRENCY,\n surface = 'elevated',\n onActivate,\n 'aria-label': ariaLabel,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const headingId = useId();\n const progressLabelId = useId();\n const activeLocale = locale ?? i18n.language ?? 'en';\n\n useAgentRegistration(\n carePlanCardAgent,\n {\n getState: () => state,\n getProgress: () => ({\n done: progress?.done ?? 0,\n total: progress?.total ?? 0,\n }),\n },\n id,\n );\n\n const stateLabel = t(`carePlanCard.state.${state}`, {\n defaultValue: STATE_LABEL_FALLBACK[state],\n });\n const stateBadgeVariant = CARE_PLAN_STATE_BADGE[state];\n const hasSafeUrl = !!url && isSafeEntityUrl(url);\n const hasEntries = !!entries && entries.length > 0;\n\n // Money: prefer the outstanding \"due\" chip; mark it overdue when it has\n // run past its term. Anything billed shows a settled chip alongside.\n const dueCents = amounts?.dueCents;\n const billedCents = amounts?.billedAmountCents;\n const overdueDays = amounts?.overdueDays;\n const isOverdue =\n typeof overdueDays === 'number' &&\n overdueDays > 0 &&\n typeof dueCents === 'number' &&\n dueCents > 0;\n\n const headingNode = (\n <h3\n id={headingId}\n className=\"type-title-card ds:m-0 ds:text-[color:var(--foreground)]\"\n >\n {name ?? t('carePlanCard.untitled', 'Untitled plan')}\n </h3>\n );\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabel ? undefined : headingId}\n data-component=\"care-plan-card\"\n data-component-id={id}\n data-state={state}\n id={id}\n className={entitySurfaceVariants({ surface, className })}\n {...rest}\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Heading row: number + name + lifecycle badge */}\n <div className=\"ds:flex ds:items-start ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)] ds:tabular-nums\">\n {t('carePlanCard.number', {\n number,\n defaultValue: 'Plan #{{number}}',\n })}\n </span>\n {hasSafeUrl ? (\n <Link\n href={url as string}\n weight=\"strong\"\n onClick={(event) => {\n if (\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey\n ) {\n return;\n }\n onActivate?.();\n }}\n >\n {headingNode}\n </Link>\n ) : (\n headingNode\n )}\n </div>\n\n <Badge\n variant={stateBadgeVariant}\n size=\"sm\"\n withDot\n className=\"ds:shrink-0\"\n >\n {stateLabel}\n </Badge>\n </div>\n\n {/* Discard reason — only when discarded */}\n {state === 'discarded' && discardReason ? (\n <p className=\"type-body-sm ds:m-0 ds:text-[color:var(--muted-foreground)]\">\n <span className=\"ds:font-medium ds:text-[color:var(--foreground)]\">\n {t('carePlanCard.discardReasonLabel', 'Discard reason:')}\n </span>{' '}\n {discardReason}\n </p>\n ) : null}\n\n {/* Lifecycle date line */}\n {dates ? (\n <div className=\"type-body-sm ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-md)] ds:text-[color:var(--muted-foreground)]\">\n {dates.acceptedIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('carePlanCard.date.accepted', 'Accepted')}</span>\n <Timestamp\n value={dates.acceptedIso}\n format=\"absolute\"\n locale={activeLocale}\n />\n </span>\n ) : null}\n {dates.closedIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('carePlanCard.date.closed', 'Closed')}</span>\n <Timestamp\n value={dates.closedIso}\n format=\"absolute\"\n locale={activeLocale}\n />\n </span>\n ) : null}\n {dates.discardedIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('carePlanCard.date.discarded', 'Discarded')}</span>\n <Timestamp\n value={dates.discardedIso}\n format=\"absolute\"\n locale={activeLocale}\n />\n </span>\n ) : null}\n </div>\n ) : null}\n\n {/* Money: due / overdue / billed chips */}\n {typeof dueCents === 'number' || typeof billedCents === 'number' ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n {typeof dueCents === 'number' && dueCents > 0 ? (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <TransactionChip\n state=\"debt\"\n amount={dueCents / 100}\n currency={currency}\n locale={activeLocale}\n showLabel\n size=\"md\"\n />\n {isOverdue ? (\n <Badge variant=\"error\" size=\"sm\" withDot>\n {t('carePlanCard.overdue', {\n count: overdueDays,\n defaultValue: 'Overdue {{count}}d',\n })}\n </Badge>\n ) : null}\n </div>\n ) : null}\n {typeof billedCents === 'number' && billedCents > 0 ? (\n <TransactionChip\n state=\"settled\"\n amount={billedCents / 100}\n currency={currency}\n locale={activeLocale}\n showLabel\n size=\"md\"\n />\n ) : null}\n </div>\n ) : null}\n\n {/* Line / phase progress */}\n {progress && progress.total > 0 ? (\n <Progress\n value={progress.done}\n max={progress.total}\n size=\"sm\"\n aria-label={t('carePlanCard.progressLabel', {\n done: progress.done,\n total: progress.total,\n defaultValue: 'Progress: {{done}} of {{total}} completed',\n })}\n >\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <Progress.Label id={progressLabelId}>\n {t('carePlanCard.progressHeading', 'Progress')}\n </Progress.Label>\n <span className=\"type-body-sm ds:tabular-nums ds:text-[color:var(--muted-foreground)]\">\n {t('carePlanCard.progressCount', {\n done: progress.done,\n total: progress.total,\n defaultValue: '{{done}} / {{total}}',\n })}\n </span>\n </div>\n </Progress>\n ) : null}\n\n {/* Entries — expandable list of treatment lines */}\n {hasEntries ? (\n <Accordion type=\"single\" collapsible variant=\"separated\">\n <AccordionItem value=\"entries\">\n <AccordionTrigger>\n {t('carePlanCard.entries.toggle', {\n count: entries.length,\n defaultValue: 'Treatment lines ({{count}})',\n })}\n </AccordionTrigger>\n <AccordionContent>\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\">\n {entries.map(({ entryId, ...entry }) => (\n <li key={entryId}>\n <CarePlanEntryCard\n id={entryId}\n surface=\"flat\"\n locale={activeLocale}\n currency={currency}\n {...entry}\n />\n </li>\n ))}\n </ul>\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n ) : null}\n </div>\n </div>\n );\n },\n);\n\nCarePlanCard.displayName = 'CarePlanCard';\n\nexport type CarePlanCardSurface = NonNullable<\n VariantProps<typeof entitySurfaceVariants>['surface']\n>;\n\n/** The dentition the plan applies to. */\nexport type CarePlanCardDentition = NonNullable<\n CarePlanCardProps['dentitionMode']\n>;\n\n/* Re-export the shared lifecycle-state type for downstream typing. */\nexport type { CarePlanState } from '../_shared/entity-card';\n"],"names":["carePlanCardAgent","handle","DEFAULT_CURRENCY","STATE_LABEL_FALLBACK","CarePlanCard","forwardRef","id","number","name","state","url","amounts","progress","dates","discardReason","_dentitionMode","entries","locale","currency","surface","onActivate","ariaLabel","className","rest","ref","t","i18n","useTranslation","headingId","useId","progressLabelId","activeLocale","useAgentRegistration","stateLabel","stateBadgeVariant","CARE_PLAN_STATE_BADGE","hasSafeUrl","isSafeEntityUrl","hasEntries","dueCents","billedCents","overdueDays","isOverdue","headingNode","jsx","entitySurfaceVariants","jsxs","Link","event","Badge","Timestamp","TransactionChip","Progress","Accordion","AccordionItem","AccordionTrigger","AccordionContent","entryId","entry","CarePlanEntryCard"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { T as J } from "./tooth-scheme-BtnFgugP.js";
|
|
|
10
10
|
import { C as Q, b as X, a as Z } from "./collapsible-DVPM46bq.js";
|
|
11
11
|
import { u as ee } from "./registry-DvAUVLHh.js";
|
|
12
12
|
import { C as ae } from "./chevron-down-DWE7GSq9.js";
|
|
13
|
-
import { e as te } from "./entity-card-
|
|
13
|
+
import { e as te } from "./entity-card-p-LANpYt.js";
|
|
14
14
|
const re = {
|
|
15
15
|
id: "care-plan-entry-card",
|
|
16
16
|
// `expand` is host-delegated: the per-phase breakdown is an in-component
|
|
@@ -319,4 +319,4 @@ export {
|
|
|
319
319
|
le as C,
|
|
320
320
|
re as c
|
|
321
321
|
};
|
|
322
|
-
//# sourceMappingURL=care-plan-entry-card-
|
|
322
|
+
//# sourceMappingURL=care-plan-entry-card-DY1toF6E.js.map
|