@alfadocs/ui-kit-debug 1.112.2 → 1.114.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/{anamnesis-card-BzuluoD1.js → anamnesis-card-Ddnrdfx3.js} +2 -2
- package/dist/_chunks/{anamnesis-card-BzuluoD1.js.map → anamnesis-card-Ddnrdfx3.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-card-DdTRdNrQ.js → anamnesis-summary-card-S1H_AARG.js} +2 -2
- package/dist/_chunks/{anamnesis-summary-card-DdTRdNrQ.js.map → anamnesis-summary-card-S1H_AARG.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-DfDulR_c.js → anamnesis-summary-rows-DaS-j8Jd.js} +2 -2
- package/dist/_chunks/{anamnesis-summary-rows-DfDulR_c.js.map → anamnesis-summary-rows-DaS-j8Jd.js.map} +1 -1
- package/dist/_chunks/{antenatal-schedule-timeline-DmsY5g28.js → antenatal-schedule-timeline-DmlXxevC.js} +2 -2
- package/dist/_chunks/{antenatal-schedule-timeline-DmsY5g28.js.map → antenatal-schedule-timeline-DmlXxevC.js.map} +1 -1
- package/dist/_chunks/{bishop-score-CnIft4eV.js → bishop-score-QJu-sM1y.js} +2 -2
- package/dist/_chunks/{bishop-score-CnIft4eV.js.map → bishop-score-QJu-sM1y.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-NMkXc079.js → bmi-calculator-Ba4yoR31.js} +2 -2
- package/dist/_chunks/{bmi-calculator-NMkXc079.js.map → bmi-calculator-Ba4yoR31.js.map} +1 -1
- package/dist/_chunks/{calendar-appointment-editor-dialog-FvdoKZ54.js → calendar-appointment-editor-dialog-iyh9QqNw.js} +6 -6
- package/dist/_chunks/{calendar-appointment-editor-dialog-FvdoKZ54.js.map → calendar-appointment-editor-dialog-iyh9QqNw.js.map} +1 -1
- package/dist/_chunks/{card-C85_Ndhb.js → card-DVO3x8E-.js} +23 -19
- package/dist/_chunks/{card-C85_Ndhb.js.map → card-DVO3x8E-.js.map} +1 -1
- package/dist/_chunks/{clinical-note-card-BVkxGiGl.js → clinical-note-card-Zz5_GEz-.js} +2 -2
- package/dist/_chunks/{clinical-note-card-BVkxGiGl.js.map → clinical-note-card-Zz5_GEz-.js.map} +1 -1
- package/dist/_chunks/{connection-status-CWSU3eiq.js → connection-status-DjarASoU.js} +2 -2
- package/dist/_chunks/{connection-status-CWSU3eiq.js.map → connection-status-DjarASoU.js.map} +1 -1
- package/dist/_chunks/{contact-card-CymtNvy3.js → contact-card-Cv-Nwvac.js} +2 -2
- package/dist/_chunks/{contact-card-CymtNvy3.js.map → contact-card-Cv-Nwvac.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-CAL66GaH.js → contact-profile-card-DMXWBBkU.js} +2 -2
- package/dist/_chunks/{contact-profile-card-CAL66GaH.js.map → contact-profile-card-DMXWBBkU.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-ZMDvToIm.js → cycle-calculator-Dd-XbKmZ.js} +2 -2
- package/dist/_chunks/{cycle-calculator-ZMDvToIm.js.map → cycle-calculator-Dd-XbKmZ.js.map} +1 -1
- package/dist/_chunks/{document-preview-5xs64jME.js → document-preview-WvJKHJOP.js} +2 -2
- package/dist/_chunks/{document-preview-5xs64jME.js.map → document-preview-WvJKHJOP.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-Dr2cDa64.js → due-date-calculator-Dl6SyMHO.js} +3 -3
- package/dist/_chunks/{due-date-calculator-Dr2cDa64.js.map → due-date-calculator-Dl6SyMHO.js.map} +1 -1
- package/dist/_chunks/email-input-DxwbREpx.js +156 -0
- package/dist/_chunks/email-input-DxwbREpx.js.map +1 -0
- package/dist/_chunks/{entity-summary-BbqqYqF1.js → entity-summary-DGCBQDt1.js} +2 -2
- package/dist/_chunks/{entity-summary-BbqqYqF1.js.map → entity-summary-DGCBQDt1.js.map} +1 -1
- package/dist/_chunks/{face-scheme-e2M2HJGz.js → face-scheme-DlcQaQVR.js} +2 -2
- package/dist/_chunks/{face-scheme-e2M2HJGz.js.map → face-scheme-DlcQaQVR.js.map} +1 -1
- package/dist/_chunks/{fetal-weight-CkIwJgiH.js → fetal-weight-DmZzMRzB.js} +2 -2
- package/dist/_chunks/{fetal-weight-CkIwJgiH.js.map → fetal-weight-DmZzMRzB.js.map} +1 -1
- package/dist/_chunks/{finished-terminal-DXVAfhRr.js → finished-terminal-BKTFUk3S.js} +2 -2
- package/dist/_chunks/{finished-terminal-DXVAfhRr.js.map → finished-terminal-BKTFUk3S.js.map} +1 -1
- package/dist/_chunks/{forgot-password-form-vfCO2-Tt.js → forgot-password-form-Bc_UPax6.js} +9 -8
- package/dist/_chunks/{forgot-password-form-vfCO2-Tt.js.map → forgot-password-form-Bc_UPax6.js.map} +1 -1
- package/dist/_chunks/{gestational-age-calculator-Dv3IePb-.js → gestational-age-calculator-DmzYdW5e.js} +3 -3
- package/dist/_chunks/{gestational-age-calculator-Dv3IePb-.js.map → gestational-age-calculator-DmzYdW5e.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-DdyUt4gz.js → hcg-doubling-Tr72PetS.js} +2 -2
- package/dist/_chunks/{hcg-doubling-DdyUt4gz.js.map → hcg-doubling-Tr72PetS.js.map} +1 -1
- package/dist/_chunks/{heatmap-BiwC7Gdx.js → heatmap-CNxCDl0D.js} +2 -2
- package/dist/_chunks/{heatmap-BiwC7Gdx.js.map → heatmap-CNxCDl0D.js.map} +1 -1
- package/dist/_chunks/isEmail-BfVspSvV.js +248 -0
- package/dist/_chunks/isEmail-BfVspSvV.js.map +1 -0
- package/dist/_chunks/{kit-extensions-BOsUgWnE.js → kit-extensions-DZJRmDI6.js} +7 -7
- package/dist/_chunks/{kit-extensions-BOsUgWnE.js.map → kit-extensions-DZJRmDI6.js.map} +1 -1
- package/dist/_chunks/{login-dev-card-Cz1Clugq.js → login-dev-card-D7orCfJT.js} +48 -47
- package/dist/_chunks/{login-dev-card-Cz1Clugq.js.map → login-dev-card-D7orCfJT.js.map} +1 -1
- package/dist/_chunks/map-view-Bny79cWa.js +856 -0
- package/dist/_chunks/map-view-Bny79cWa.js.map +1 -0
- package/dist/_chunks/{marketplace-app-shell-C-4QF6mp.js → marketplace-app-shell-CPNVBVLH.js} +2 -2
- package/dist/_chunks/{marketplace-app-shell-C-4QF6mp.js.map → marketplace-app-shell-CPNVBVLH.js.map} +1 -1
- package/dist/_chunks/motion-is-off-BvAuNV5O.js +15 -0
- package/dist/_chunks/motion-is-off-BvAuNV5O.js.map +1 -0
- package/dist/_chunks/{notes-panel-Cz621DWV.js → notes-panel-DXMTObBv.js} +3 -3
- package/dist/_chunks/{notes-panel-Cz621DWV.js.map → notes-panel-DXMTObBv.js.map} +1 -1
- package/dist/_chunks/{operator-hero-BELhrv9o.js → operator-hero-BWayX73x.js} +71 -62
- package/dist/_chunks/{operator-hero-BELhrv9o.js.map → operator-hero-BWayX73x.js.map} +1 -1
- package/dist/_chunks/{patient-details-BwkDIm4D.js → patient-details-DdtXBNjt.js} +3 -3
- package/dist/_chunks/{patient-details-BwkDIm4D.js.map → patient-details-DdtXBNjt.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-CBba7w9V.js → patient-field-row-D9rb-QJH.js} +2 -2
- package/dist/_chunks/{patient-field-row-CBba7w9V.js.map → patient-field-row-D9rb-QJH.js.map} +1 -1
- package/dist/_chunks/{patient-search-CxuqVUTB.js → patient-search-DDRDCjZi.js} +439 -482
- package/dist/_chunks/patient-search-DDRDCjZi.js.map +1 -0
- package/dist/_chunks/{patient-summary-card-DtYTo9w_.js → patient-summary-card-CGHz-Bvm.js} +3 -3
- package/dist/_chunks/{patient-summary-card-DtYTo9w_.js.map → patient-summary-card-CGHz-Bvm.js.map} +1 -1
- package/dist/_chunks/{payment-automation-upsell-u5EuFyCY.js → payment-automation-upsell-D7yaD4u1.js} +3 -3
- package/dist/_chunks/{payment-automation-upsell-u5EuFyCY.js.map → payment-automation-upsell-D7yaD4u1.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-IR83TJax.js → payment-request-card-BmV2pLoM.js} +2 -2
- package/dist/_chunks/{payment-request-card-IR83TJax.js.map → payment-request-card-BmV2pLoM.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-DqdUEFxK.js → periodontal-chart-Bjz7O4wT.js} +2 -2
- package/dist/_chunks/{periodontal-chart-DqdUEFxK.js.map → periodontal-chart-Bjz7O4wT.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-card-CCkzStlm.js → periodontal-chart-card-CxEXHl2x.js} +2 -2
- package/dist/_chunks/{periodontal-chart-card-CCkzStlm.js.map → periodontal-chart-card-CxEXHl2x.js.map} +1 -1
- package/dist/_chunks/{periodontal-diagnosis-CF1d_0yl.js → periodontal-diagnosis-xheWfi4g.js} +2 -2
- package/dist/_chunks/{periodontal-diagnosis-CF1d_0yl.js.map → periodontal-diagnosis-xheWfi4g.js.map} +1 -1
- package/dist/_chunks/{periodontal-risk-chart-D2zyID0H.js → periodontal-risk-chart-BBPB9wf1.js} +2 -2
- package/dist/_chunks/{periodontal-risk-chart-D2zyID0H.js.map → periodontal-risk-chart-BBPB9wf1.js.map} +1 -1
- package/dist/_chunks/{practice-profile-hero-Bb4YyxHA.js → practice-profile-hero-Cw4NZp0A.js} +2 -2
- package/dist/_chunks/{practice-profile-hero-Bb4YyxHA.js.map → practice-profile-hero-Cw4NZp0A.js.map} +1 -1
- package/dist/_chunks/practice-results-BlxfBx-D.js +2181 -0
- package/dist/_chunks/practice-results-BlxfBx-D.js.map +1 -0
- package/dist/_chunks/{pregnancy-dating-Cs8xpZA8.js → pregnancy-dating-BvorzHrd.js} +3 -3
- package/dist/_chunks/{pregnancy-dating-Cs8xpZA8.js.map → pregnancy-dating-BvorzHrd.js.map} +1 -1
- package/dist/_chunks/{pregnancy-weight-gain-B_Zldlzq.js → pregnancy-weight-gain-DQoOM8QV.js} +2 -2
- package/dist/_chunks/{pregnancy-weight-gain-B_Zldlzq.js.map → pregnancy-weight-gain-DQoOM8QV.js.map} +1 -1
- package/dist/_chunks/{privacy-mask-DbEKI-Jv.js → privacy-mask-Dc3kdkCR.js} +2 -2
- package/dist/_chunks/{privacy-mask-DbEKI-Jv.js.map → privacy-mask-Dc3kdkCR.js.map} +1 -1
- package/dist/_chunks/{public-footer-DGjLTtNK.js → public-footer-CB7ruuLI.js} +295 -260
- package/dist/_chunks/public-footer-CB7ruuLI.js.map +1 -0
- package/dist/_chunks/{public-header.agent-_ArDD1Xr.js → public-header.agent-Db4wm6_S.js} +203 -193
- package/dist/_chunks/public-header.agent-Db4wm6_S.js.map +1 -0
- package/dist/_chunks/{registration-form-DEyUFysm.js → registration-form-Lw9T7IXr.js} +7 -6
- package/dist/_chunks/{registration-form-DEyUFysm.js.map → registration-form-Lw9T7IXr.js.map} +1 -1
- package/dist/_chunks/{reserved.agent-W_Zgj564.js → reserved.agent-D2jwJPac.js} +22 -32
- package/dist/_chunks/reserved.agent-D2jwJPac.js.map +1 -0
- package/dist/_chunks/{reset-password-form-B0acanDD.js → reset-password-form-C93SH0Tx.js} +3 -3
- package/dist/_chunks/{reset-password-form-B0acanDD.js.map → reset-password-form-C93SH0Tx.js.map} +1 -1
- package/dist/_chunks/{reviews-panel-B03auSpQ.js → reviews-panel-CfJPEkH7.js} +2 -2
- package/dist/_chunks/{reviews-panel-B03auSpQ.js.map → reviews-panel-CfJPEkH7.js.map} +1 -1
- package/dist/_chunks/{section-card-D1sV4Voz.js → section-card-DFr2wGal.js} +2 -2
- package/dist/_chunks/{section-card-D1sV4Voz.js.map → section-card-DFr2wGal.js.map} +1 -1
- package/dist/_chunks/{send-registration-link-form-Nn0jf65G.js → send-registration-link-form-DfbTjrEK.js} +9 -8
- package/dist/_chunks/{send-registration-link-form-Nn0jf65G.js.map → send-registration-link-form-DfbTjrEK.js.map} +1 -1
- package/dist/_chunks/{signed-out-frame-CPow3aCZ.js → signed-out-frame-bh7fn_Px.js} +2 -2
- package/dist/_chunks/{signed-out-frame-CPow3aCZ.js.map → signed-out-frame-bh7fn_Px.js.map} +1 -1
- package/dist/_chunks/{stat-BFKZV50y.js → stat-WGLdn5Vn.js} +113 -107
- package/dist/_chunks/stat-WGLdn5Vn.js.map +1 -0
- package/dist/_chunks/{task-card-TSJjuuDe.js → task-card-DqVoitRk.js} +2 -2
- package/dist/_chunks/{task-card-TSJjuuDe.js.map → task-card-DqVoitRk.js.map} +1 -1
- package/dist/_chunks/{task-editor-gqWF1jI6.js → task-editor-D--LwVrg.js} +2 -2
- package/dist/_chunks/{task-editor-gqWF1jI6.js.map → task-editor-D--LwVrg.js.map} +1 -1
- package/dist/_chunks/{task-tray-DrXfMCuf.js → task-tray-C6j8HVMv.js} +2 -2
- package/dist/_chunks/{task-tray-DrXfMCuf.js.map → task-tray-C6j8HVMv.js.map} +1 -1
- package/dist/_chunks/{tasks-panel-OuIaydK5.js → tasks-panel-D6PuF4MQ.js} +2 -2
- package/dist/_chunks/{tasks-panel-OuIaydK5.js.map → tasks-panel-D6PuF4MQ.js.map} +1 -1
- package/dist/_chunks/{timeline-CKUaBZOx.js → timeline-AMqE-c2T.js} +2 -2
- package/dist/_chunks/{timeline-CKUaBZOx.js.map → timeline-AMqE-c2T.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-DYyCYI9f.js → use-appointment-details-read-BK_Gw1GG.js} +5 -5
- package/dist/_chunks/{use-appointment-details-read-DYyCYI9f.js.map → use-appointment-details-read-BK_Gw1GG.js.map} +1 -1
- package/dist/_chunks/verify-identity-types-C85EXNzy.js +707 -0
- package/dist/_chunks/verify-identity-types-C85EXNzy.js.map +1 -0
- package/dist/_chunks/{workflow-map-DWk-rZse.js → workflow-map-B4XkcET0.js} +2 -2
- package/dist/_chunks/{workflow-map-DWk-rZse.js.map → workflow-map-B4XkcET0.js.map} +1 -1
- package/dist/_chunks/{workflow-webhook-action-DILFqAVd.js → workflow-webhook-action-CtBn5JvO.js} +2 -2
- package/dist/_chunks/{workflow-webhook-action-DILFqAVd.js.map → workflow-webhook-action-CtBn5JvO.js.map} +1 -1
- package/dist/agent-catalog.json +111 -7
- package/dist/agent-i18n/en.json +13 -2
- package/dist/components/_shared/motion-is-off.d.ts +7 -0
- package/dist/components/_shared/motion-is-off.d.ts.map +1 -0
- package/dist/components/anamnesis-card/index.js +1 -1
- package/dist/components/anamnesis-summary-card/index.js +1 -1
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/bishop-score/index.js +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/booking/step-focus.d.ts +0 -6
- package/dist/components/booking/step-focus.d.ts.map +1 -1
- package/dist/components/card/card.d.ts.map +1 -1
- package/dist/components/card/index.js +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/connection-status/index.js +1 -1
- package/dist/components/contact-card/index.js +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +2 -2
- package/dist/components/email-input/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/face-scheme/index.js +1 -1
- package/dist/components/fetal-weight/index.js +1 -1
- package/dist/components/finished-terminal/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/hcg-doubling/index.js +1 -1
- package/dist/components/heatmap/index.js +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/map-view/index.js +1 -1
- package/dist/components/map-view/map-view.d.ts +16 -0
- package/dist/components/map-view/map-view.d.ts.map +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/operator-hero/index.js +1 -1
- package/dist/components/operator-hero/operator-hero.d.ts.map +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/patient-search/patient-search.d.ts +6 -2
- package/dist/components/patient-search/patient-search.d.ts.map +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/periodontal-chart/index.js +1 -1
- package/dist/components/periodontal-chart-card/index.js +1 -1
- package/dist/components/periodontal-diagnosis/index.js +1 -1
- package/dist/components/periodontal-risk-chart/index.js +1 -1
- package/dist/components/practice-profile-hero/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/practice-results/practice-results.agent.d.ts.map +1 -1
- package/dist/components/practice-results/practice-results.d.ts +43 -2
- package/dist/components/practice-results/practice-results.d.ts.map +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/public-footer/index.js +1 -1
- package/dist/components/public-footer/public-footer.d.ts +23 -0
- package/dist/components/public-footer/public-footer.d.ts.map +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/public-header/public-header.d.ts +7 -0
- package/dist/components/public-header/public-header.d.ts.map +1 -1
- package/dist/components/reviews-panel/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/section-card/index.js +1 -1
- package/dist/components/stat/index.js +1 -1
- package/dist/components/stat/stat.d.ts +7 -0
- package/dist/components/stat/stat.d.ts.map +1 -1
- package/dist/components/task-card/index.js +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/timeline/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/core.css +1 -1
- package/dist/host-compat.css +4 -1
- package/dist/i18n/locales/ar.d.ts +68 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +70 -2
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +68 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +70 -2
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +68 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +70 -2
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +68 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +68 -0
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +68 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +70 -2
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +68 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +70 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +68 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +70 -2
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +68 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +70 -2
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +68 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +70 -2
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +68 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +70 -2
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +68 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +70 -2
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +68 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +70 -2
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +68 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +70 -2
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +68 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +70 -2
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +68 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +70 -2
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +68 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +70 -2
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +68 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +70 -2
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +68 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +70 -2
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +373 -368
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +70 -2
- package/dist/locales/de.json +70 -2
- package/dist/locales/el.json +70 -2
- package/dist/locales/en.json +68 -0
- package/dist/locales/es.json +70 -2
- package/dist/locales/fr.json +70 -2
- package/dist/locales/hi.json +70 -2
- package/dist/locales/it.json +70 -2
- package/dist/locales/ja.json +70 -2
- package/dist/locales/nl.json +70 -2
- package/dist/locales/pl.json +70 -2
- package/dist/locales/pt.json +70 -2
- package/dist/locales/ro.json +70 -2
- package/dist/locales/ru.json +70 -2
- package/dist/locales/sq.json +70 -2
- package/dist/locales/sv.json +70 -2
- package/dist/locales/tr.json +70 -2
- package/dist/locales/zh.json +70 -2
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/forgot-password-form/index.js +1 -1
- package/dist/patterns/login-form/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/payment-automation-upsell/index.js +1 -1
- package/dist/patterns/registration-form/index.js +1 -1
- package/dist/patterns/reset-password-form/index.js +1 -1
- package/dist/patterns/send-registration-link-form/index.js +1 -1
- package/dist/patterns/signed-out-frame/index.js +1 -1
- package/dist/patterns/verify-identity/change-email-dialog.d.ts +26 -0
- package/dist/patterns/verify-identity/change-email-dialog.d.ts.map +1 -0
- package/dist/patterns/verify-identity/index.d.ts +7 -0
- package/dist/patterns/verify-identity/index.d.ts.map +1 -0
- package/dist/patterns/verify-identity/index.js +8 -0
- package/dist/patterns/verify-identity/index.js.map +1 -0
- package/dist/patterns/verify-identity/use-countdown.d.ts +12 -0
- package/dist/patterns/verify-identity/use-countdown.d.ts.map +1 -0
- package/dist/patterns/verify-identity/verify-identity-steps.d.ts +21 -0
- package/dist/patterns/verify-identity/verify-identity-steps.d.ts.map +1 -0
- package/dist/patterns/verify-identity/verify-identity-types.d.ts +47 -0
- package/dist/patterns/verify-identity/verify-identity-types.d.ts.map +1 -0
- package/dist/patterns/verify-identity/verify-identity.d.ts +54 -0
- package/dist/patterns/verify-identity/verify-identity.d.ts.map +1 -0
- package/dist/patterns/workflow-webhook-action/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +5 -1
- package/dist/_chunks/email-input-BEO3vonE.js +0 -399
- package/dist/_chunks/email-input-BEO3vonE.js.map +0 -1
- package/dist/_chunks/map-view-Dn7aXZJw.js +0 -731
- package/dist/_chunks/map-view-Dn7aXZJw.js.map +0 -1
- package/dist/_chunks/patient-search-CxuqVUTB.js.map +0 -1
- package/dist/_chunks/practice-results-BOpaPaav.js +0 -1923
- package/dist/_chunks/practice-results-BOpaPaav.js.map +0 -1
- package/dist/_chunks/public-footer-DGjLTtNK.js.map +0 -1
- package/dist/_chunks/public-header.agent-_ArDD1Xr.js.map +0 -1
- package/dist/_chunks/reserved.agent-W_Zgj564.js.map +0 -1
- package/dist/_chunks/stat-BFKZV50y.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsxs as p, jsx as s } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import { c as
|
|
2
|
+
import { forwardRef as re, useId as ae, useCallback as O, useRef as ne, useMemo as ie } from "react";
|
|
3
|
+
import { c as j } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as P } from "react-i18next";
|
|
5
|
-
import { u as
|
|
6
|
-
const U =
|
|
5
|
+
import { u as de } from "./use-count-up-BLLetaZ8.js";
|
|
6
|
+
const U = j("ds:flex ds:flex-col ds:h-full", {
|
|
7
7
|
variants: {
|
|
8
8
|
variant: {
|
|
9
9
|
default: "ds:gap-[var(--spacing-xs)]",
|
|
@@ -54,7 +54,7 @@ const U = V("ds:flex ds:flex-col ds:h-full", {
|
|
|
54
54
|
size: "md",
|
|
55
55
|
align: "start"
|
|
56
56
|
}
|
|
57
|
-
}),
|
|
57
|
+
}), le = j("type-metric", {
|
|
58
58
|
variants: {
|
|
59
59
|
size: {
|
|
60
60
|
sm: "ds:[--type-metric-size:var(--font-size-xl)]",
|
|
@@ -106,7 +106,7 @@ const U = V("ds:flex ds:flex-col ds:h-full", {
|
|
|
106
106
|
variant: "default",
|
|
107
107
|
intent: "foreground"
|
|
108
108
|
}
|
|
109
|
-
}),
|
|
109
|
+
}), oe = j(
|
|
110
110
|
"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-label",
|
|
111
111
|
{
|
|
112
112
|
variants: {
|
|
@@ -122,159 +122,171 @@ const U = V("ds:flex ds:flex-col ds:h-full", {
|
|
|
122
122
|
tone: "neutral"
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
-
),
|
|
125
|
+
), ce = { up: "↑", down: "↓", flat: "→" }, ue = {
|
|
126
126
|
up: "stat.trend.up",
|
|
127
127
|
down: "stat.trend.down",
|
|
128
128
|
flat: "stat.trend.flat"
|
|
129
129
|
};
|
|
130
130
|
function K({
|
|
131
|
-
trend:
|
|
132
|
-
delta:
|
|
131
|
+
trend: l,
|
|
132
|
+
delta: t,
|
|
133
133
|
deltaFormat: u = "decimal",
|
|
134
134
|
locale: o,
|
|
135
|
-
polarity:
|
|
135
|
+
polarity: e = "higher-is-better"
|
|
136
136
|
}) {
|
|
137
|
-
const { t:
|
|
137
|
+
const { t: n, i18n: m } = P("ui"), i = typeof t == "string" ? t : new Intl.NumberFormat(o ?? m.language, {
|
|
138
138
|
style: u === "percent" ? "percent" : "decimal"
|
|
139
|
-
}).format(u === "percent" ?
|
|
140
|
-
return /* @__PURE__ */ p("span", { className:
|
|
141
|
-
/* @__PURE__ */ s("span", { "aria-hidden": "true", children:
|
|
142
|
-
/* @__PURE__ */ s("span", { className: "ds:sr-only", children:
|
|
143
|
-
|
|
139
|
+
}).format(u === "percent" ? t / 100 : t), r = l === "flat" || e === "neutral" ? "neutral" : l === "up" == (e === "higher-is-better") ? "better" : "worse";
|
|
140
|
+
return /* @__PURE__ */ p("span", { className: oe({ tone: r }), "data-trend-tone": r, children: [
|
|
141
|
+
/* @__PURE__ */ s("span", { "aria-hidden": "true", children: ce[l] }),
|
|
142
|
+
/* @__PURE__ */ s("span", { className: "ds:sr-only", children: n(ue[l]) }),
|
|
143
|
+
i,
|
|
144
144
|
r === "neutral" ? null : /* @__PURE__ */ p("span", { className: "ds:sr-only", children: [
|
|
145
145
|
" ",
|
|
146
|
-
|
|
146
|
+
n(r === "better" ? "stat.trend.better" : "stat.trend.worse")
|
|
147
147
|
] })
|
|
148
148
|
] });
|
|
149
149
|
}
|
|
150
|
-
function
|
|
151
|
-
const u =
|
|
150
|
+
function me(l, t) {
|
|
151
|
+
const u = l.trim();
|
|
152
152
|
if (u === "") return null;
|
|
153
|
-
let o = "",
|
|
154
|
-
|
|
155
|
-
let
|
|
156
|
-
const m =
|
|
157
|
-
m && (
|
|
158
|
-
let
|
|
153
|
+
let o = "", e = u;
|
|
154
|
+
e.startsWith("+") ? (o = "+", e = e.slice(1).trimStart()) : (e.startsWith("-") || e.startsWith("−")) && (o = "-", e = e.slice(1).trimStart());
|
|
155
|
+
let n = "";
|
|
156
|
+
const m = e.match(/[KMB]$/i);
|
|
157
|
+
m && (n = m[0], e = e.slice(0, -1).trimEnd());
|
|
158
|
+
let i = "", r = ".";
|
|
159
159
|
try {
|
|
160
|
-
const
|
|
161
|
-
for (const
|
|
162
|
-
|
|
160
|
+
const h = new Intl.NumberFormat(t).formatToParts(12345.6);
|
|
161
|
+
for (const c of h)
|
|
162
|
+
c.type === "group" ? i = c.value : c.type === "decimal" && (r = c.value);
|
|
163
163
|
} catch {
|
|
164
164
|
}
|
|
165
|
-
const g =
|
|
166
|
-
if (g && !(g[2].length === 3 &&
|
|
167
|
-
const
|
|
168
|
-
if (Number.isFinite(
|
|
169
|
-
return { target:
|
|
165
|
+
const g = e.match(/^(\d+)\.(\d+)$/);
|
|
166
|
+
if (g && !(g[2].length === 3 && i === ".")) {
|
|
167
|
+
const c = Number.parseFloat(e);
|
|
168
|
+
if (Number.isFinite(c))
|
|
169
|
+
return { target: c, sign: o, suffix: n };
|
|
170
170
|
}
|
|
171
|
-
let a =
|
|
172
|
-
|
|
171
|
+
let a = e;
|
|
172
|
+
i !== "" && (a = a.split(i).join("")), r !== "." && (a = a.split(r).join(".")), a = a.replace(/[\s\u00A0\u202F]/g, "");
|
|
173
173
|
const v = Number.parseFloat(a);
|
|
174
|
-
return Number.isFinite(v) ? { target: v, sign: o, suffix:
|
|
174
|
+
return Number.isFinite(v) ? { target: v, sign: o, suffix: n } : null;
|
|
175
175
|
}
|
|
176
|
-
const
|
|
176
|
+
const fe = re(
|
|
177
177
|
({
|
|
178
|
-
label:
|
|
179
|
-
value:
|
|
178
|
+
label: l,
|
|
179
|
+
value: t,
|
|
180
180
|
format: u,
|
|
181
181
|
currency: o,
|
|
182
|
-
locale:
|
|
183
|
-
trend:
|
|
182
|
+
locale: e,
|
|
183
|
+
trend: n,
|
|
184
184
|
trendPolarity: m,
|
|
185
|
-
delta:
|
|
185
|
+
delta: i,
|
|
186
186
|
deltaFormat: r = "decimal",
|
|
187
187
|
icon: g,
|
|
188
188
|
info: a,
|
|
189
189
|
trendInfo: v,
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
labelPosition: h = "above",
|
|
191
|
+
loading: c = !1,
|
|
192
|
+
animate: w = !1,
|
|
192
193
|
animateOnEveryView: Y = !1,
|
|
193
194
|
animateDurationMs: _ = 1600,
|
|
194
195
|
animateLocale: q,
|
|
195
|
-
animateSeparators:
|
|
196
|
-
variant:
|
|
197
|
-
size:
|
|
196
|
+
animateSeparators: x,
|
|
197
|
+
variant: z = "default",
|
|
198
|
+
size: F = "md",
|
|
198
199
|
align: M = "start",
|
|
199
|
-
intent:
|
|
200
|
-
className:
|
|
201
|
-
...
|
|
200
|
+
intent: H = "foreground",
|
|
201
|
+
className: k,
|
|
202
|
+
...I
|
|
202
203
|
}, R) => {
|
|
203
|
-
const { i18n:
|
|
204
|
-
if (typeof
|
|
204
|
+
const { i18n: J } = P("ui"), T = ae(), f = e ?? J.language, Q = O(() => {
|
|
205
|
+
if (typeof t == "string") return t;
|
|
205
206
|
switch (u) {
|
|
206
207
|
case "currency":
|
|
207
208
|
return new Intl.NumberFormat(f, {
|
|
208
209
|
style: "currency",
|
|
209
210
|
currency: o ?? "USD"
|
|
210
|
-
}).format(
|
|
211
|
+
}).format(t);
|
|
211
212
|
case "percent":
|
|
212
213
|
return new Intl.NumberFormat(f, { style: "percent" }).format(
|
|
213
|
-
|
|
214
|
+
t
|
|
214
215
|
);
|
|
215
216
|
case "decimal":
|
|
216
217
|
return new Intl.NumberFormat(f, { style: "decimal" }).format(
|
|
217
|
-
|
|
218
|
+
t
|
|
218
219
|
);
|
|
219
220
|
default:
|
|
220
|
-
return new Intl.NumberFormat(f).format(
|
|
221
|
+
return new Intl.NumberFormat(f).format(t);
|
|
221
222
|
}
|
|
222
|
-
}, [
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
(
|
|
223
|
+
}, [t, u, f, o])(), y = q ?? f;
|
|
224
|
+
ne(!1);
|
|
225
|
+
const d = ie(() => w ? typeof t == "number" ? Number.isFinite(t) ? { target: t, sign: "", suffix: "" } : null : me(t, y) : null, [w, t, y]), X = w && d !== null, Z = (d == null ? void 0 : d.target) ?? 0, S = (d == null ? void 0 : d.sign) ?? "", $ = (d == null ? void 0 : d.suffix) ?? "", ee = O(
|
|
226
|
+
(N) => {
|
|
226
227
|
const E = (() => {
|
|
227
228
|
try {
|
|
228
|
-
return new Intl.NumberFormat(
|
|
229
|
+
return new Intl.NumberFormat(y, {
|
|
229
230
|
useGrouping: !0
|
|
230
231
|
});
|
|
231
232
|
} catch {
|
|
232
233
|
return null;
|
|
233
234
|
}
|
|
234
235
|
})();
|
|
235
|
-
let
|
|
236
|
+
let b;
|
|
236
237
|
if (E)
|
|
237
|
-
if (
|
|
238
|
-
const A = Math.abs(
|
|
238
|
+
if (x) {
|
|
239
|
+
const A = Math.abs(N), D = Math.trunc(A), G = A - D, te = x.thousand ?? "", V = String(D).replace(
|
|
239
240
|
/\B(?=(\d{3})+(?!\d))/g,
|
|
240
|
-
|
|
241
|
+
te
|
|
241
242
|
);
|
|
242
243
|
if (G === 0)
|
|
243
|
-
|
|
244
|
+
b = V;
|
|
244
245
|
else {
|
|
245
|
-
const L = G.toFixed(6).replace(/0+$/, "").slice(2),
|
|
246
|
-
|
|
246
|
+
const L = G.toFixed(6).replace(/0+$/, "").slice(2), se = x.decimal ?? ".";
|
|
247
|
+
b = L ? V + se + L : V;
|
|
247
248
|
}
|
|
248
249
|
} else
|
|
249
|
-
|
|
250
|
+
b = E.format(Math.abs(N));
|
|
250
251
|
else
|
|
251
|
-
|
|
252
|
-
let W =
|
|
253
|
-
return
|
|
252
|
+
b = String(Math.abs(N));
|
|
253
|
+
let W = S;
|
|
254
|
+
return S === "" && N < 0 && (W = "-"), `${W}${b}${$}`;
|
|
254
255
|
},
|
|
255
|
-
[
|
|
256
|
-
),
|
|
257
|
-
to:
|
|
256
|
+
[y, x, S, $]
|
|
257
|
+
), B = de({
|
|
258
|
+
to: Z,
|
|
258
259
|
from: 0,
|
|
259
260
|
durationMs: _,
|
|
260
261
|
startOnVisible: !0,
|
|
261
262
|
retriggerOnReEntry: Y,
|
|
262
263
|
// `formatter` is the only path we use — it owns both the locale
|
|
263
264
|
// formatting and the sign/suffix re-application.
|
|
264
|
-
formatter:
|
|
265
|
-
})
|
|
266
|
-
|
|
265
|
+
formatter: ee
|
|
266
|
+
}), C = [
|
|
267
|
+
le({ size: F, variant: z, intent: H }),
|
|
268
|
+
h === "below" ? "ds:order-first" : ""
|
|
269
|
+
].filter(Boolean).join(" ");
|
|
270
|
+
return c ? /* @__PURE__ */ p(
|
|
267
271
|
"div",
|
|
268
272
|
{
|
|
269
273
|
ref: R,
|
|
270
274
|
role: "group",
|
|
271
275
|
"aria-busy": "true",
|
|
272
|
-
"aria-label":
|
|
276
|
+
"aria-label": l,
|
|
273
277
|
"data-component": "stat",
|
|
274
|
-
className: U({ variant:
|
|
275
|
-
...
|
|
278
|
+
className: U({ variant: z, size: F, align: M, className: k }),
|
|
279
|
+
...I,
|
|
276
280
|
children: [
|
|
277
|
-
/* @__PURE__ */ s(
|
|
281
|
+
/* @__PURE__ */ s(
|
|
282
|
+
"div",
|
|
283
|
+
{
|
|
284
|
+
className: [
|
|
285
|
+
"ds:h-[var(--skeleton-label-h)] ds:w-[var(--skeleton-label-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]",
|
|
286
|
+
h === "below" ? "ds:order-last" : ""
|
|
287
|
+
].filter(Boolean).join(" ")
|
|
288
|
+
}
|
|
289
|
+
),
|
|
278
290
|
/* @__PURE__ */ s("div", { className: "ds:h-[var(--skeleton-value-h)] ds:w-[var(--skeleton-value-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]" })
|
|
279
291
|
]
|
|
280
292
|
}
|
|
@@ -285,13 +297,15 @@ const ut = st(
|
|
|
285
297
|
role: "group",
|
|
286
298
|
"aria-labelledby": T,
|
|
287
299
|
"data-component": "stat",
|
|
288
|
-
className: U({ variant:
|
|
289
|
-
...
|
|
300
|
+
className: U({ variant: z, size: F, align: M, className: k }),
|
|
301
|
+
...I,
|
|
290
302
|
children: [
|
|
291
303
|
/* @__PURE__ */ p(
|
|
292
304
|
"span",
|
|
293
305
|
{
|
|
294
|
-
className:
|
|
306
|
+
className: [
|
|
307
|
+
a == null ? "ds:inline-flex ds:items-center" : "ds:inline-flex ds:flex-wrap ds:items-center"
|
|
308
|
+
].filter(Boolean).join(" "),
|
|
295
309
|
children: [
|
|
296
310
|
g && /* @__PURE__ */ s(
|
|
297
311
|
"span",
|
|
@@ -314,7 +328,7 @@ const ut = st(
|
|
|
314
328
|
{
|
|
315
329
|
id: T,
|
|
316
330
|
className: "type-label ds:text-[var(--muted-foreground)]",
|
|
317
|
-
children:
|
|
331
|
+
children: l
|
|
318
332
|
}
|
|
319
333
|
),
|
|
320
334
|
a != null && /* @__PURE__ */ s(
|
|
@@ -328,39 +342,31 @@ const ut = st(
|
|
|
328
342
|
]
|
|
329
343
|
}
|
|
330
344
|
),
|
|
331
|
-
|
|
345
|
+
X ? (
|
|
332
346
|
// The animated number is wrapped in an `aria-live="off"` span
|
|
333
347
|
// so screen readers don't announce every interpolated frame.
|
|
334
348
|
// The `role="group"` ancestor (with `aria-labelledby` pointing
|
|
335
349
|
// at the label) carries the final accessible reading — the
|
|
336
350
|
// animated frames are decorative only.
|
|
337
|
-
/* @__PURE__ */ s(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
ref: C.ref,
|
|
341
|
-
"aria-live": "off",
|
|
342
|
-
className: B({ size: N, variant: y, intent: k }),
|
|
343
|
-
children: C.value
|
|
344
|
-
}
|
|
345
|
-
)
|
|
346
|
-
) : /* @__PURE__ */ s("span", { className: B({ size: N, variant: y, intent: k }), children: J }),
|
|
347
|
-
i != null && d != null && (v == null ? /* @__PURE__ */ s(
|
|
351
|
+
/* @__PURE__ */ s("span", { ref: B.ref, "aria-live": "off", className: C, children: B.value })
|
|
352
|
+
) : /* @__PURE__ */ s("span", { className: C, children: Q }),
|
|
353
|
+
n != null && i != null && (v == null ? /* @__PURE__ */ s(
|
|
348
354
|
K,
|
|
349
355
|
{
|
|
350
|
-
trend:
|
|
351
|
-
delta:
|
|
356
|
+
trend: n,
|
|
357
|
+
delta: i,
|
|
352
358
|
deltaFormat: r,
|
|
353
|
-
locale:
|
|
359
|
+
locale: e,
|
|
354
360
|
polarity: m
|
|
355
361
|
}
|
|
356
362
|
) : /* @__PURE__ */ p("span", { className: "ds:inline-flex ds:flex-wrap ds:items-center", children: [
|
|
357
363
|
/* @__PURE__ */ s(
|
|
358
364
|
K,
|
|
359
365
|
{
|
|
360
|
-
trend:
|
|
361
|
-
delta:
|
|
366
|
+
trend: n,
|
|
367
|
+
delta: i,
|
|
362
368
|
deltaFormat: r,
|
|
363
|
-
locale:
|
|
369
|
+
locale: e,
|
|
364
370
|
polarity: m
|
|
365
371
|
}
|
|
366
372
|
),
|
|
@@ -378,8 +384,8 @@ const ut = st(
|
|
|
378
384
|
);
|
|
379
385
|
}
|
|
380
386
|
);
|
|
381
|
-
|
|
387
|
+
fe.displayName = "Stat";
|
|
382
388
|
export {
|
|
383
|
-
|
|
389
|
+
fe as S
|
|
384
390
|
};
|
|
385
|
-
//# sourceMappingURL=stat-
|
|
391
|
+
//# sourceMappingURL=stat-WGLdn5Vn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stat-WGLdn5Vn.js","sources":["../../src/components/stat/stat.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useId,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useCountUp } from '../../hooks/use-count-up';\n\n/* ------------------------------------------------------------------ */\n/* CVA — stat root */\n/* ------------------------------------------------------------------ */\n\n// `h-full` lets Stats grow to fill a flex / grid parent's cell, so a\n// row paired with taller cards (BenefitCard, Card, etc.) reads as a\n// matching set instead of mismatched heights. In a non-stretching\n// parent (block flow, inline) it's a no-op — block-size defers to\n// content as before. The flex-col inside still pins label/icon row\n// at the top and the number below, so growing the card adds the\n// extra space below the number instead of inserting it between\n// label and value.\nconst statVariants = cva('ds:flex ds:flex-col ds:h-full', {\n variants: {\n variant: {\n default: 'ds:gap-[var(--spacing-xs)]',\n outlined: [\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:border ds:border-[color:var(--border)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n ].join(' '),\n // White card surface with the shared card shadow + border —\n // matches `Card variant=\"elevated\"` and `BenefitCard.elevated`\n // tokens (`--card`, `--card-border`, `--shadow-card`,\n // `--radius-lg`) so a grid of elevated Stats reads as a set of\n // shaded panels without nesting a Card around each one. The\n // border is essential in dark mode: shadow alone on a dark\n // surface loses contrast and the card boundary disappears.\n // `--surface-border-width` bumps it to 2px in the accessible themes,\n // matching Card / BenefitCard's 0.31.5 accessibility uplift.\n elevated: [\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:bg-[var(--card)]',\n 'ds:text-[var(--card-foreground)]',\n 'ds:[:where(&)]:border-[length:var(--surface-border-width,var(--border-width-sm))] ds:border-[color:var(--card-border)]',\n 'ds:shadow-[var(--shadow-card)]',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]',\n // Forced-colors: UA strips shadow, so render a border as the\n // separation cue — mirrors Card's forced-colors behaviour.\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n compact: 'ds:gap-[var(--spacing-none)]',\n },\n size: {\n sm: '',\n md: '',\n lg: '',\n },\n align: {\n start: 'ds:items-start ds:text-start',\n center: 'ds:items-center ds:text-center',\n end: 'ds:items-end ds:text-end',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n align: 'start',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — value element */\n/* ------------------------------------------------------------------ */\n\nconst valueVariants = cva('type-metric', {\n variants: {\n size: {\n sm: 'ds:[--type-metric-size:var(--font-size-xl)]',\n md: 'ds:[--type-metric-size:var(--font-size-3xl)]',\n lg: 'ds:[--type-metric-size:var(--font-size-5xl)]',\n },\n variant: {\n default: '',\n outlined: '',\n elevated: '',\n compact: '',\n },\n // Colour of the headline metric value. Defaults to `--foreground`\n // (the existing render). `primary` / `accent` are the brand intents\n // — use for hero / marketing stats where the number IS the visual\n // marker. `success` / `destructive` / `info` / `warning` map to the\n // semantic tokens for KPI tiles that want to signal status via the\n // value colour itself (e.g. revenue green, debt red). The trend\n // chevron and the label colour are independent of this prop.\n intent: {\n foreground: 'ds:text-[var(--foreground)]',\n primary: 'ds:text-[var(--primary)]',\n accent: 'ds:text-[var(--accent)]',\n success: 'ds:text-[var(--success)]',\n destructive: 'ds:text-[var(--destructive)]',\n info: 'ds:text-[var(--info)]',\n warning: 'ds:text-[var(--warning)]',\n },\n },\n compoundVariants: [\n {\n variant: 'compact',\n size: 'sm',\n className: 'ds:[--type-metric-size:var(--font-size-lg)]',\n },\n {\n variant: 'compact',\n size: 'md',\n className: 'ds:[--type-metric-size:var(--font-size-xl)]',\n },\n {\n variant: 'compact',\n size: 'lg',\n className: 'ds:[--type-metric-size:var(--font-size-2xl)]',\n },\n ],\n defaultVariants: {\n size: 'md',\n variant: 'default',\n intent: 'foreground',\n },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — trend element */\n/* ------------------------------------------------------------------ */\n\nconst trendVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-label',\n {\n variants: {\n // Whether the change is good news, not which way it went: with\n // `trendPolarity=\"lower-is-better\"` a fall is `better`.\n tone: {\n better: 'ds:text-[var(--success)]',\n worse: 'ds:text-[var(--destructive)]',\n neutral: 'ds:text-[var(--muted-foreground)]',\n },\n },\n defaultVariants: {\n tone: 'neutral',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* StatTrend (internal — not exported) */\n/* ------------------------------------------------------------------ */\n\n/**\n * Which way is good news for a metric's trend. `neutral` is for a metric\n * where neither direction is good or bad news (a patient mix, a share).\n */\nexport type StatTrendPolarity =\n | 'higher-is-better'\n | 'lower-is-better'\n | 'neutral';\n\ninterface StatTrendProps {\n trend: 'up' | 'down' | 'flat';\n delta: number | string;\n deltaFormat?: 'decimal' | 'percent';\n locale?: string;\n polarity?: StatTrendPolarity;\n}\n\nconst ARROW = { up: '↑', down: '↓', flat: '→' } as const;\nconst TREND_KEY = {\n up: 'stat.trend.up',\n down: 'stat.trend.down',\n flat: 'stat.trend.flat',\n} as const;\n\nfunction StatTrend({\n trend,\n delta,\n deltaFormat = 'decimal',\n locale,\n polarity = 'higher-is-better',\n}: StatTrendProps) {\n const { t, i18n } = useTranslation('ui');\n\n const formattedDelta =\n typeof delta === 'string'\n ? delta\n : new Intl.NumberFormat(locale ?? i18n.language, {\n style: deltaFormat === 'percent' ? 'percent' : 'decimal',\n }).format(deltaFormat === 'percent' ? delta / 100 : delta);\n\n // The arrow follows the number; the colour and the spoken \"better\" or\n // \"worse\" follow the polarity, so the meaning never rests on colour.\n const tone =\n trend === 'flat' || polarity === 'neutral'\n ? 'neutral'\n : (trend === 'up') === (polarity === 'higher-is-better')\n ? 'better'\n : 'worse';\n\n return (\n <span className={trendVariants({ tone })} data-trend-tone={tone}>\n <span aria-hidden=\"true\">{ARROW[trend]}</span>\n <span className=\"ds:sr-only\">{t(TREND_KEY[trend])}</span>\n {formattedDelta}\n {tone === 'neutral' ? null : (\n <span className=\"ds:sr-only\">\n {' '}\n {t(tone === 'better' ? 'stat.trend.better' : 'stat.trend.worse')}\n </span>\n )}\n </span>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a string value into a numeric target for the count-up */\n/* ------------------------------------------------------------------ */\n\ntype ParsedValue = {\n /** Numeric target for the count-up. */\n target: number;\n /** Leading sign captured from the input string (e.g. \"+\" / \"-\"). */\n sign: '' | '+' | '-';\n /** Trailing shorthand suffix (e.g. \"K\" / \"M\" / \"B\") to re-append. */\n suffix: string;\n};\n\n/**\n * Strip locale-aware separators, a leading sign, and the K/M/B\n * shorthand suffix from a pre-formatted string so the count-up has a\n * pure numeric target to animate towards. Returns `null` for any input\n * that can't be parsed — the caller short-circuits to static rendering\n * in that case.\n */\nfunction parseStatValue(raw: string, locale: string): ParsedValue | null {\n const trimmed = raw.trim();\n if (trimmed === '') return null;\n\n // Capture leading sign so we can re-attach it every frame. Stat's\n // marketing usage (\"+500.000\", \"-12\") often relies on it.\n let sign: '' | '+' | '-' = '';\n let body = trimmed;\n if (body.startsWith('+')) {\n sign = '+';\n body = body.slice(1).trimStart();\n } else if (body.startsWith('-') || body.startsWith('−')) {\n // Hyphen-minus or the typographic minus sign — both treated as -.\n sign = '-';\n body = body.slice(1).trimStart();\n }\n\n // Trailing K / M / B shorthand (case-insensitive). Re-append verbatim\n // so \"+1.5K\" renders as \"+1.5K\" at every frame.\n let suffix = '';\n const suffixMatch = body.match(/[KMB]$/i);\n if (suffixMatch) {\n suffix = suffixMatch[0];\n body = body.slice(0, -1).trimEnd();\n }\n\n // Discover the locale's group + decimal glyphs from a probe value.\n // formatToParts is the canonical way; we fall back to `.` decimal /\n // `,` group if Intl can't tell us (no-locale envs).\n let group = '';\n let decimal = '.';\n try {\n const probe = new Intl.NumberFormat(locale).formatToParts(12345.6);\n for (const part of probe) {\n if (part.type === 'group') group = part.value;\n else if (part.type === 'decimal') decimal = part.value;\n }\n } catch {\n /* swallow — defaults already set */\n }\n\n // Heuristic for input strings that look like JS-native decimals\n // (e.g. `\"1500.25\"`) regardless of the requested locale: if the body\n // is a clean US-style decimal AND the fraction after the `.` is NOT\n // a three-digit thousands group in a locale that uses `.` as the\n // group separator, treat it as a direct numeric literal. This covers\n // the common case where a caller types `value=\"1500.25\"` and expects\n // the count-up to land on 1500.25 even though the output locale is\n // it-IT (which uses `.` for thousands).\n const usStyleMatch = body.match(/^(\\d+)\\.(\\d+)$/);\n if (usStyleMatch) {\n const fractionLen = usStyleMatch[2].length;\n if (!(fractionLen === 3 && group === '.')) {\n const direct = Number.parseFloat(body);\n if (Number.isFinite(direct)) {\n return { target: direct, sign, suffix };\n }\n }\n }\n\n // Strip every group separator we discovered, then normalise the\n // decimal separator to `.` so JS can parseFloat the result.\n // Note: when the locale's group separator is empty (e.g. some\n // numbering systems) the replace is a no-op.\n let normalised = body;\n if (group !== '') {\n normalised = normalised.split(group).join('');\n }\n if (decimal !== '.') {\n normalised = normalised.split(decimal).join('.');\n }\n\n // Defence-in-depth: strip whitespace plus NBSP (U+00A0) and NARROW\n // NO-BREAK SPACE (U+202F) that some locales (fr-FR, it-IT) use as\n // thousand separators. Hex escapes keep this source ASCII-clean.\n normalised = normalised.replace(/[\\s\\u00A0\\u202F]/g, '');\n\n const numeric = Number.parseFloat(normalised);\n if (!Number.isFinite(numeric)) return null;\n\n return { target: numeric, sign, suffix };\n}\n\n/* ------------------------------------------------------------------ */\n/* StatProps */\n/* ------------------------------------------------------------------ */\n\nexport interface StatProps\n extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof statVariants> {\n /** Metric label rendered above the value. */\n label: string;\n /** Numeric or pre-formatted string value. */\n value: number | string;\n /** Number formatting style. Omit to use default decimal formatting. */\n format?: 'decimal' | 'currency' | 'percent';\n /** ISO 4217 currency code — required when format=\"currency\". */\n currency?: string;\n /** BCP 47 locale override. Defaults to the active i18n language. */\n locale?: string;\n /** Trend direction. Requires `delta` to render the trend row. */\n trend?: 'up' | 'down' | 'flat';\n /** Trend delta magnitude, e.g. 12 for \"↑ 12%\". */\n delta?: number | string;\n /**\n * Which way is good news. `higher-is-better` (default) shows a rise in\n * the success colour; `lower-is-better` (a no-show or cancellation rate,\n * a waiting time) shows a fall in it instead. The arrow always points the\n * way the number moved, and screen readers hear \"better\" or \"worse\".\n * `neutral` keeps the arrow and delta in the muted colour, and screen\n * readers hear only the direction (\"Increased by +3.4 pts\").\n */\n trendPolarity?: StatTrendPolarity;\n /** Number formatting style for the delta. Default \"decimal\". */\n deltaFormat?: 'decimal' | 'percent';\n /** Optional leading icon rendered at the start of the label row. */\n icon?: ReactNode;\n /**\n * Optional trailing affordance at the end of the label row, vertically\n * centred with the label. Intended for `<InfoTip size=\"sm\" … />` so the\n * figure can explain how it is calculated. Interactive content is allowed:\n * it sits outside the label element, so it never becomes part of the\n * group's accessible name. Omit for the unchanged render.\n */\n info?: ReactNode;\n /**\n * Optional trailing affordance at the end of the trend row, for an\n * `<InfoTip size=\"sm\" … />` that explains the change (\"how is this\n * compared?\"). Renders only with the trend row (`trend` and `delta`).\n * Like `info`, it sits outside the label, so it never joins the group's\n * accessible name. Omit for the unchanged render.\n */\n trendInfo?: ReactNode;\n /**\n * Colour of the headline value. Defaults to `foreground`. Brand\n * intents (`primary`, `accent`) are for hero / marketing stats where\n * the number is the visual marker. Semantic intents\n * (`success`, `destructive`, `info`, `warning`) signal status via\n * the value colour itself — e.g. revenue green, debt red on KPI\n * tiles. Trend chevron and label colour are independent.\n */\n intent?:\n | 'foreground'\n | 'primary'\n | 'accent'\n | 'success'\n | 'destructive'\n | 'info'\n | 'warning';\n /**\n * Where the label sits. `above` (default) puts it over the value. `below`\n * puts it under the value, as in a marketing counter (\"+1.100\" then\n * \"studi medici\"). With a trend the order is value, label, trend. Reading\n * order for screen readers does not change: the group is still named by the label.\n */\n labelPosition?: 'above' | 'below';\n /** Renders animated skeleton placeholders instead of content. */\n loading?: boolean;\n /**\n * Animate the numeric value from 0 (or from the captured leading\n * sign) to the final value when the Stat first scrolls into view.\n * Default `false`. Marketing surfaces opt in; dashboards leave it\n * off so live metrics render immediately.\n */\n animate?: boolean;\n /**\n * When `true`, the count-up re-plays every time the Stat scrolls\n * out of view and back in. Default `false` — animate once per\n * element per session, matching the booking-website hero pattern.\n * Ignored under `prefers-reduced-motion: reduce`.\n */\n animateOnEveryView?: boolean;\n /** Animation duration in milliseconds. Default 1600. */\n animateDurationMs?: number;\n /**\n * BCP 47 locale used for the per-frame count-up formatting. Falls\n * back to `locale`, then to the active i18n language.\n */\n animateLocale?: string;\n /**\n * Override the locale's thousand / decimal glyphs for the count-up.\n * Wins over locale defaults. Pass partial overrides — `decimal`\n * alone is valid; the unspecified separator stays at the locale\n * default.\n */\n animateSeparators?: {\n thousand?: string;\n decimal?: string;\n };\n}\n\n/* ------------------------------------------------------------------ */\n/* Stat */\n/* ------------------------------------------------------------------ */\n\nexport const Stat = forwardRef<HTMLDivElement, StatProps>(\n (\n {\n label,\n value,\n format,\n currency,\n locale,\n trend,\n trendPolarity,\n delta,\n deltaFormat = 'decimal',\n icon,\n info,\n trendInfo,\n labelPosition = 'above',\n loading = false,\n animate = false,\n animateOnEveryView = false,\n animateDurationMs = 1600,\n animateLocale,\n animateSeparators,\n variant = 'default',\n size = 'md',\n align = 'start',\n intent = 'foreground',\n className,\n ...props\n },\n ref,\n ) => {\n const { i18n } = useTranslation('ui');\n const labelId = useId();\n const lang = locale ?? i18n.language;\n\n /* -------------------------------------------------- */\n /* Static formatting — the value as it would appear */\n /* in the non-animated (or post-animation) state. */\n /* -------------------------------------------------- */\n\n const formatValue = useCallback((): string => {\n if (typeof value === 'string') return value;\n\n switch (format) {\n case 'currency':\n return new Intl.NumberFormat(lang, {\n style: 'currency',\n currency: currency ?? 'USD',\n }).format(value);\n case 'percent':\n return new Intl.NumberFormat(lang, { style: 'percent' }).format(\n value,\n );\n case 'decimal':\n return new Intl.NumberFormat(lang, { style: 'decimal' }).format(\n value,\n );\n default:\n return new Intl.NumberFormat(lang).format(value);\n }\n }, [value, format, lang, currency]);\n\n const staticValue = formatValue();\n\n /* -------------------------------------------------- */\n /* Parse the value into a numeric target for the */\n /* count-up. Numeric values use `value` directly; */\n /* string values are stripped of sign / shorthand / */\n /* locale separators and re-decorated each frame. */\n /* -------------------------------------------------- */\n\n const animationLocale = animateLocale ?? lang;\n const hasWarnedRef = useRef<boolean>(false);\n\n const parsed = useMemo<ParsedValue | null>(() => {\n if (!animate) return null;\n if (typeof value === 'number') {\n // Numeric: target is the number itself; no sign / suffix to\n // re-attach.\n return Number.isFinite(value)\n ? { target: value, sign: '', suffix: '' }\n : null;\n }\n return parseStatValue(value, animationLocale);\n }, [animate, value, animationLocale]);\n\n // Dev-mode warning when an animate-flagged Stat has an unparseable\n // string value. Render static, no throw — one warn per component.\n if (\n animate &&\n typeof value === 'string' &&\n parsed === null &&\n import.meta.env.DEV &&\n !hasWarnedRef.current\n ) {\n hasWarnedRef.current = true;\n console.warn(\n `Stat: value=\"${value}\" couldn't be parsed for the count-up animation. Rendering static.`,\n );\n }\n\n const shouldAnimate = animate && parsed !== null;\n\n /* -------------------------------------------------- */\n /* Wire the hook unconditionally — rules-of-hooks. */\n /* When `shouldAnimate` is false the hook still runs */\n /* but `to === from` so it's a no-op visually. */\n /* -------------------------------------------------- */\n\n const target = parsed?.target ?? 0;\n const sign = parsed?.sign ?? '';\n const suffix = parsed?.suffix ?? '';\n\n // Wrap the count-up formatter so the captured sign + suffix are\n // re-applied every frame. The hook hands us the locale-formatted\n // magnitude; we own the decoration around it.\n const formatter = useCallback(\n (n: number) => {\n // Use the absolute value for the magnitude so the captured\n // sign is the sole source of the rendered sign. Negative\n // numbers passed in (e.g. `to: -12`) come through unsigned;\n // we re-apply via `sign`. Always force `useGrouping: true` so\n // ICU's locale-default `min2` doesn't suppress the thousand\n // glyph on 4-digit values like 1.000 (it-IT). The user wrote\n // a stat value — they want it grouped.\n const magnitudeNF = (() => {\n try {\n return new Intl.NumberFormat(animationLocale, {\n useGrouping: true,\n });\n } catch {\n return null;\n }\n })();\n\n let magnitudeStr: string;\n if (magnitudeNF) {\n if (animateSeparators) {\n // Hand-build the grouped magnitude so we don't depend on\n // ICU's locale-by-locale grouping defaults (which differ\n // between engines and can drop the group at 4-digit\n // thresholds even with `useGrouping: true`). Locale only\n // influences sign handling, which we apply separately.\n const abs = Math.abs(n);\n const intPart = Math.trunc(abs);\n const fracPart = abs - intPart;\n const groupGlyph = animateSeparators.thousand ?? '';\n const intStr = String(intPart).replace(\n /\\B(?=(\\d{3})+(?!\\d))/g,\n groupGlyph,\n );\n if (fracPart === 0) {\n magnitudeStr = intStr;\n } else {\n const fracStr = fracPart.toFixed(6).replace(/0+$/, '').slice(2);\n const decimalGlyph = animateSeparators.decimal ?? '.';\n magnitudeStr = fracStr ? intStr + decimalGlyph + fracStr : intStr;\n }\n } else {\n magnitudeStr = magnitudeNF.format(Math.abs(n));\n }\n } else {\n magnitudeStr = String(Math.abs(n));\n }\n\n // Re-derive the sign every frame: the captured sign wins, but\n // a negative `to` with no leading sign in the source still\n // renders with a leading \"-\" so the final formatted output\n // matches locale conventions.\n let resolvedSign: string = sign;\n if (sign === '' && n < 0) resolvedSign = '-';\n\n return `${resolvedSign}${magnitudeStr}${suffix}`;\n },\n [animationLocale, animateSeparators, sign, suffix],\n );\n\n const countUp = useCountUp({\n to: target,\n from: 0,\n durationMs: animateDurationMs,\n startOnVisible: true,\n retriggerOnReEntry: animateOnEveryView,\n // `formatter` is the only path we use — it owns both the locale\n // formatting and the sign/suffix re-application.\n formatter,\n });\n\n // `below`: the value moves first on screen (value, label, trend). Visual order\n // only: the DOM order (label first) stays, so the group is still named by it.\n const valueClass = [\n valueVariants({ size, variant, intent }),\n labelPosition === 'below' ? 'ds:order-first' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n /* -------------------------------------------------- */\n /* Loading state */\n /* -------------------------------------------------- */\n\n if (loading) {\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-busy=\"true\"\n aria-label={label}\n data-component=\"stat\"\n className={statVariants({ variant, size, align, className })}\n {...props}\n >\n <div\n className={[\n 'ds:h-[var(--skeleton-label-h)] ds:w-[var(--skeleton-label-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]',\n labelPosition === 'below' ? 'ds:order-last' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n />\n <div className=\"ds:h-[var(--skeleton-value-h)] ds:w-[var(--skeleton-value-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]\" />\n </div>\n );\n }\n\n /* -------------------------------------------------- */\n /* Render */\n /* -------------------------------------------------- */\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-labelledby={labelId}\n data-component=\"stat\"\n className={statVariants({ variant, size, align, className })}\n {...props}\n >\n <span\n className={[\n info == null\n ? 'ds:inline-flex ds:items-center'\n : 'ds:inline-flex ds:flex-wrap ds:items-center',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {icon && (\n <span\n aria-hidden=\"true\"\n className={[\n 'ds:me-[var(--spacing-xs)] ds:inline-flex ds:shrink-0',\n // Accent tint on the leading icon. The icon is decorative\n // (aria-hidden), so magenta-500's 3.2:1 contrast on white\n // is acceptable here — the Stat label + value still\n // carry the accessible name at `--foreground`.\n 'ds:text-[color:var(--accent)]',\n 'ds:forced-colors:text-[CanvasText]',\n ].join(' ')}\n >\n {icon}\n </span>\n )}\n <span\n id={labelId}\n className=\"type-label ds:text-[var(--muted-foreground)]\"\n >\n {label}\n </span>\n {info != null && (\n <span\n data-slot=\"info\"\n className=\"ds:ms-[var(--spacing-xs)] ds:inline-flex ds:shrink-0 ds:items-center\"\n >\n {info}\n </span>\n )}\n </span>\n {shouldAnimate ? (\n // The animated number is wrapped in an `aria-live=\"off\"` span\n // so screen readers don't announce every interpolated frame.\n // The `role=\"group\"` ancestor (with `aria-labelledby` pointing\n // at the label) carries the final accessible reading — the\n // animated frames are decorative only.\n <span ref={countUp.ref} aria-live=\"off\" className={valueClass}>\n {countUp.value}\n </span>\n ) : (\n <span className={valueClass}>{staticValue}</span>\n )}\n {trend != null &&\n delta != null &&\n (trendInfo == null ? (\n <StatTrend\n trend={trend}\n delta={delta}\n deltaFormat={deltaFormat}\n locale={locale}\n polarity={trendPolarity}\n />\n ) : (\n <span className=\"ds:inline-flex ds:flex-wrap ds:items-center\">\n <StatTrend\n trend={trend}\n delta={delta}\n deltaFormat={deltaFormat}\n locale={locale}\n polarity={trendPolarity}\n />\n <span\n data-slot=\"trend-info\"\n className=\"ds:ms-[var(--spacing-xs)] ds:inline-flex ds:shrink-0 ds:items-center\"\n >\n {trendInfo}\n </span>\n </span>\n ))}\n </div>\n );\n },\n);\n\nStat.displayName = 'Stat';\n"],"names":["statVariants","cva","valueVariants","trendVariants","ARROW","TREND_KEY","StatTrend","trend","delta","deltaFormat","locale","polarity","t","i18n","useTranslation","formattedDelta","tone","jsxs","jsx","parseStatValue","raw","trimmed","sign","body","suffix","suffixMatch","group","decimal","probe","part","usStyleMatch","direct","normalised","numeric","Stat","forwardRef","label","value","format","currency","trendPolarity","icon","info","trendInfo","labelPosition","loading","animate","animateOnEveryView","animateDurationMs","animateLocale","animateSeparators","variant","size","align","intent","className","props","ref","labelId","useId","lang","staticValue","useCallback","animationLocale","useRef","parsed","useMemo","shouldAnimate","target","formatter","n","magnitudeNF","magnitudeStr","abs","intPart","fracPart","groupGlyph","intStr","fracStr","decimalGlyph","resolvedSign","countUp","useCountUp","valueClass"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { forwardRef as C } from "react";
|
|
|
3
3
|
import { c as w } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as T } from "react-i18next";
|
|
5
5
|
import { V as p } from "./visually-hidden-BHxEUGyT.js";
|
|
6
|
-
import { p as z } from "./privacy-mask-
|
|
6
|
+
import { p as z } from "./privacy-mask-Dc3kdkCR.js";
|
|
7
7
|
import { c as S } from "./createLucideIcon-DhHxpK9K.js";
|
|
8
8
|
import { B as V } from "./building-2-D33bLCWL.js";
|
|
9
9
|
import { U as g } from "./user-B12p7bVF.js";
|
|
@@ -187,4 +187,4 @@ export {
|
|
|
187
187
|
O as T,
|
|
188
188
|
q as i
|
|
189
189
|
};
|
|
190
|
-
//# sourceMappingURL=task-card-
|
|
190
|
+
//# sourceMappingURL=task-card-DqVoitRk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-card-TSJjuuDe.js","sources":["../../node_modules/lucide-react/dist/esm/icons/briefcase.mjs","../../src/components/task-card/task-card.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\", key: \"jecpp\" }],\n [\"rect\", { width: \"20\", height: \"14\", x: \"2\", y: \"6\", rx: \"2\", key: \"i6l2r4\" }]\n];\nconst Briefcase = createLucideIcon(\"briefcase\", __iconNode);\n\nexport { __iconNode, Briefcase as default };\n//# sourceMappingURL=briefcase.mjs.map\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n CircleAlert,\n Briefcase,\n Building2,\n SquareCheckBig,\n ChevronRight,\n EyeOff,\n Square,\n User,\n} from 'lucide-react';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { privacyMask } from '../_shared/privacy-mask';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport type TaskStatus = 'open' | 'in-progress' | 'done';\nexport type TaskPriority = 'low' | 'normal' | 'high';\n\n/** Which entity the task links to. The platform `DoctorReminder` links to exactly one of these (or none). */\nexport type TaskLinkType = 'patient' | 'company' | 'operator';\n\n/** Linked-entity glyph — patient (person), company (building), operator (briefcase). */\nconst LINK_ICON: Record<TaskLinkType, typeof User> = {\n patient: User,\n company: Building2,\n operator: Briefcase,\n};\n\nexport interface TaskItem {\n /** Unique identifier for the task. */\n id: string;\n /** Title — single line, primary content. */\n title: string;\n /** Optional secondary line (e.g. \"Patient A · Due today\"). */\n description?: string;\n /**\n * Localised due-date hint (e.g. \"Due today\" / \"Tomorrow\"). Rendered as a\n * trailing eyebrow chip when set; consumers compute the bucket and pass\n * the localised string.\n */\n dueLabel?: string;\n /**\n * Linked-entity NAME (the patient / company / operator the task points at) —\n * e.g. \"Mario Rossi\". When `linkType` is set the card renders it as a typed\n * chip (a per-type glyph + an accessible \"Patient/Company/Operator:\" prefix);\n * otherwise it renders as a plain eyebrow line. The consumer composes the\n * name only — no prefix.\n */\n linkedLabel?: string;\n /** Type of the linked entity — drives the leading glyph + the accessible prefix on the linked chip. */\n linkType?: TaskLinkType;\n /**\n * The linked name is a privacy mask. The chip shows an EyeOff glyph, then a\n * visually hidden \"Patient name hidden\", then the mask marked aria-hidden:\n * `linkedLabel`, or the kit's bullets when the host sends none. It replaces\n * the \"Patient:\" prefix.\n */\n linkedLabelMasked?: boolean;\n /** Localised assignee display name (host-composed, e.g. \"Dr. Alfa\"). Renders an assignee chip on the meta line. */\n assigneeLabel?: string;\n /** Free-text note attached to the task — muted body line, clamped. */\n note?: string;\n /** Lifecycle state — drives the leading icon. */\n status?: TaskStatus;\n /** Priority — `high` colours the leading icon as `--destructive`. */\n priority?: TaskPriority;\n /** Optional deep link — when present the row is an anchor. */\n url?: string;\n}\n\nexport interface TaskCardProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'role' | 'title'>,\n VariantProps<typeof taskCardVariants> {\n /** The task to render. */\n item: TaskItem;\n /** Visual density. `xs` is the compact rail row (Control Room); `sm`/`md` for in-page lists. */\n size?: 'xs' | 'sm' | 'md';\n /** Fires when the row is activated (click / Enter / Space). */\n onActivate?: (item: TaskItem) => void;\n /**\n * Trailing per-row action toolbar (icon buttons: schedule, edit, …).\n * Rendered above the stretched-link overlay so the controls stay\n * clickable inside an interactive row.\n */\n actions?: ReactNode;\n /**\n * Replaces the leading status glyph. Pass a control (the done checkbox)\n * when the row can be completed in place: the glyph alone only reports\n * status, and rendering both a glyph and a matching toggle elsewhere in\n * the row shows the same mark twice, of which only one does anything.\n * Rendered above the stretched-link overlay so it stays clickable.\n */\n leading?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst taskCardVariants = cva(\n [\n 'ds:relative ds:flex ds:items-start ds:gap-[var(--spacing-sm)]',\n // Same corner as the elevated Card the note and appointment rows use.\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:transition-colors',\n 'ds:motion-reduce:transition-none',\n 'ds:text-start ds:group',\n 'ds:[:where(&)]:border-[length:var(--surface-border-width,var(--border-width-sm))] ds:border-[color:var(--card-border)]',\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n xs: 'ds:p-[var(--spacing-xs)]',\n sm: 'ds:p-[var(--spacing-sm)]',\n md: 'ds:p-[var(--spacing-md)]',\n },\n interactive: {\n true: 'ds:hover:bg-[color:var(--muted)]/40 ds:cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n interactive: false,\n },\n },\n);\n\n/* The activator keeps a box of its own (display: contents cannot take\n focus in Chromium); its ::after still stretches over the card. */\nconst stretchedLinkClass = [\n 'ds:focus-visible:outline-none',\n \"ds:after:content-[''] ds:after:absolute ds:after:inset-0 ds:after:rounded-[var(--radius-lg)]\",\n 'ds:after:pointer-events-auto',\n 'ds:focus-visible:after:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:after:outline-solid',\n 'ds:focus-visible:after:outline-[color:var(--ring)]',\n 'ds:focus-visible:after:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:after:outline-[CanvasText]',\n].join(' ');\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nexport function isSafeTaskUrl(url: string): boolean {\n return /^(https?:\\/\\/(?!\\/)|\\/(?!\\/)|#)/.test(url);\n}\n\nfunction StatusIcon({\n status,\n priority,\n}: {\n status?: TaskStatus;\n priority?: TaskPriority;\n}): ReactNode {\n const tone =\n priority === 'high'\n ? 'ds:text-[color:var(--destructive)]'\n : 'ds:text-[color:var(--muted-foreground)]';\n if (status === 'done') {\n return (\n <SquareCheckBig aria-hidden=\"true\" className={`ds:size-4 ${tone}`} />\n );\n }\n if (priority === 'high') {\n return <CircleAlert aria-hidden=\"true\" className={`ds:size-4 ${tone}`} />;\n }\n return <Square aria-hidden=\"true\" className={`ds:size-4 ${tone}`} />;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const TaskCard = forwardRef<HTMLDivElement, TaskCardProps>(\n (\n { item, size = 'sm', onActivate, actions, leading, className, ...rest },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const interactive = !!onActivate;\n const hasSafeUrl = !!item.url && isSafeTaskUrl(item.url);\n const ariaLabel = t('taskCard.itemLabel', {\n title: item.title,\n due: item.dueLabel ?? '',\n defaultValue: '{{title}}{{due, prepend, \" · \"}}',\n });\n\n // Static key lookups so the i18n coverage gate sees each literal key.\n const linkTypeLabels: Record<TaskLinkType, string> = {\n patient: t('taskCard.link.patient'),\n company: t('taskCard.link.company'),\n operator: t('taskCard.link.operator'),\n };\n const LinkIcon = item.linkType ? LINK_ICON[item.linkType] : null;\n // A masked name always gets the chip, so it can say what is hidden,\n // even when the host sends no mask of its own.\n const masked = !!item.linkedLabelMasked;\n // The meta row carries icon-led chips: a typed linked entity + an assignee.\n const showLinkChip = masked || (!!item.linkType && !!item.linkedLabel);\n const hasMetaRow = showLinkChip || !!item.assigneeLabel;\n\n const titleNode = (\n <span className=\"ds:flex-1 ds:min-w-0 ds:truncate type-body-sm ds:text-[color:var(--foreground)]\">\n {item.title}\n </span>\n );\n\n let activator: ReactNode;\n if (interactive && hasSafeUrl) {\n activator = (\n <a\n href={item.url}\n aria-label={ariaLabel}\n data-action=\"open-task\"\n className={stretchedLinkClass + ' ds:flex ds:min-w-0'}\n onClick={(e) => {\n if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey)\n return;\n onActivate?.(item);\n }}\n >\n {titleNode}\n </a>\n );\n } else if (interactive) {\n activator = (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n data-action=\"open-task\"\n className={\n stretchedLinkClass +\n ' ds:flex ds:min-w-0 ds:bg-transparent ds:border-0 ds:p-0 ds:text-start'\n }\n onClick={() => onActivate?.(item)}\n >\n {titleNode}\n </button>\n );\n } else {\n activator = titleNode;\n }\n\n return (\n <div\n ref={ref}\n role=\"listitem\"\n data-component=\"task-card\"\n data-component-id={item.id}\n data-status={item.status ?? 'open'}\n data-priority={item.priority ?? 'normal'}\n className={taskCardVariants({ size, interactive, className })}\n {...rest}\n >\n <span className=\"ds:relative ds:z-[1] ds:mt-[var(--spacing-2xs)] ds:shrink-0\">\n {leading ?? (\n <StatusIcon status={item.status} priority={item.priority} />\n )}\n </span>\n\n <div className=\"ds:flex-1 ds:min-w-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {activator}\n {item.description ? (\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {item.description}\n </span>\n ) : null}\n {item.note ? (\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)] ds:line-clamp-2\">\n {item.note}\n </span>\n ) : null}\n {hasMetaRow ? (\n // `type-meta` (not `type-eyebrow`): these chips carry proper-noun\n // values (patient / company / operator name, assignee) that must\n // not be uppercased. Icons are decorative; the type word is exposed\n // to AT via a VisuallyHidden prefix so each chip reads e.g.\n // \"Patient: Mario Rossi\" / \"Assignee: Dr. Alfa\".\n <div className=\"type-meta ds:flex ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-2xs)] ds:text-[color:var(--muted-foreground)]\">\n {masked ? (\n // The mask is visual noise to a screen reader, so it hears\n // what the mask stands for instead.\n <span className=\"ds:inline-flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <EyeOff\n aria-hidden=\"true\"\n className=\"ds:size-3 ds:shrink-0\"\n />\n <VisuallyHidden>\n {t('appointmentPeek.hiddenName')}\n </VisuallyHidden>\n <span aria-hidden=\"true\" className=\"ds:truncate\">\n {privacyMask(item.linkedLabel)}\n </span>\n </span>\n ) : item.linkType && item.linkedLabel && LinkIcon ? (\n <span className=\"ds:inline-flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <LinkIcon\n aria-hidden=\"true\"\n className=\"ds:size-3 ds:shrink-0\"\n />\n <VisuallyHidden>{`${linkTypeLabels[item.linkType]}: `}</VisuallyHidden>\n <span className=\"ds:truncate\">{item.linkedLabel}</span>\n </span>\n ) : null}\n {item.assigneeLabel ? (\n <span className=\"ds:inline-flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <User aria-hidden=\"true\" className=\"ds:size-3 ds:shrink-0\" />\n <VisuallyHidden>{`${t('taskCard.assignee')}: `}</VisuallyHidden>\n <span className=\"ds:truncate\">{item.assigneeLabel}</span>\n </span>\n ) : null}\n </div>\n ) : null}\n {item.linkedLabel && !item.linkType && !masked ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {item.linkedLabel}\n </span>\n ) : null}\n {item.dueLabel ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)]\">\n {item.dueLabel}\n </span>\n ) : null}\n </div>\n\n {actions ? (\n // Above the stretched-link overlay so the buttons stay clickable.\n <span className=\"ds:relative ds:z-[1] ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:shrink-0\">\n {actions}\n </span>\n ) : null}\n\n {interactive ? (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:mt-[var(--spacing-2xs)] ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:opacity-0 ds:transition-opacity ds:motion-reduce:transition-none ds:group-hover:opacity-100 ds:group-focus-within:opacity-100 ds:rtl:rotate-180\"\n />\n ) : null}\n </div>\n );\n },\n);\n\nTaskCard.displayName = 'TaskCard';\n"],"names":["__iconNode","Briefcase","createLucideIcon","LINK_ICON","User","Building2","taskCardVariants","cva","stretchedLinkClass","isSafeTaskUrl","url","StatusIcon","status","priority","tone","SquareCheckBig","CircleAlert","Square","TaskCard","forwardRef","item","size","onActivate","actions","leading","className","rest","ref","t","useTranslation","interactive","hasSafeUrl","ariaLabel","linkTypeLabels","LinkIcon","masked","hasMetaRow","titleNode","jsx","activator","e","jsxs","EyeOff","VisuallyHidden","privacyMask","ChevronRight"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"task-card-DqVoitRk.js","sources":["../../node_modules/lucide-react/dist/esm/icons/briefcase.mjs","../../src/components/task-card/task-card.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\", key: \"jecpp\" }],\n [\"rect\", { width: \"20\", height: \"14\", x: \"2\", y: \"6\", rx: \"2\", key: \"i6l2r4\" }]\n];\nconst Briefcase = createLucideIcon(\"briefcase\", __iconNode);\n\nexport { __iconNode, Briefcase as default };\n//# sourceMappingURL=briefcase.mjs.map\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport {\n CircleAlert,\n Briefcase,\n Building2,\n SquareCheckBig,\n ChevronRight,\n EyeOff,\n Square,\n User,\n} from 'lucide-react';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { privacyMask } from '../_shared/privacy-mask';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport type TaskStatus = 'open' | 'in-progress' | 'done';\nexport type TaskPriority = 'low' | 'normal' | 'high';\n\n/** Which entity the task links to. The platform `DoctorReminder` links to exactly one of these (or none). */\nexport type TaskLinkType = 'patient' | 'company' | 'operator';\n\n/** Linked-entity glyph — patient (person), company (building), operator (briefcase). */\nconst LINK_ICON: Record<TaskLinkType, typeof User> = {\n patient: User,\n company: Building2,\n operator: Briefcase,\n};\n\nexport interface TaskItem {\n /** Unique identifier for the task. */\n id: string;\n /** Title — single line, primary content. */\n title: string;\n /** Optional secondary line (e.g. \"Patient A · Due today\"). */\n description?: string;\n /**\n * Localised due-date hint (e.g. \"Due today\" / \"Tomorrow\"). Rendered as a\n * trailing eyebrow chip when set; consumers compute the bucket and pass\n * the localised string.\n */\n dueLabel?: string;\n /**\n * Linked-entity NAME (the patient / company / operator the task points at) —\n * e.g. \"Mario Rossi\". When `linkType` is set the card renders it as a typed\n * chip (a per-type glyph + an accessible \"Patient/Company/Operator:\" prefix);\n * otherwise it renders as a plain eyebrow line. The consumer composes the\n * name only — no prefix.\n */\n linkedLabel?: string;\n /** Type of the linked entity — drives the leading glyph + the accessible prefix on the linked chip. */\n linkType?: TaskLinkType;\n /**\n * The linked name is a privacy mask. The chip shows an EyeOff glyph, then a\n * visually hidden \"Patient name hidden\", then the mask marked aria-hidden:\n * `linkedLabel`, or the kit's bullets when the host sends none. It replaces\n * the \"Patient:\" prefix.\n */\n linkedLabelMasked?: boolean;\n /** Localised assignee display name (host-composed, e.g. \"Dr. Alfa\"). Renders an assignee chip on the meta line. */\n assigneeLabel?: string;\n /** Free-text note attached to the task — muted body line, clamped. */\n note?: string;\n /** Lifecycle state — drives the leading icon. */\n status?: TaskStatus;\n /** Priority — `high` colours the leading icon as `--destructive`. */\n priority?: TaskPriority;\n /** Optional deep link — when present the row is an anchor. */\n url?: string;\n}\n\nexport interface TaskCardProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'role' | 'title'>,\n VariantProps<typeof taskCardVariants> {\n /** The task to render. */\n item: TaskItem;\n /** Visual density. `xs` is the compact rail row (Control Room); `sm`/`md` for in-page lists. */\n size?: 'xs' | 'sm' | 'md';\n /** Fires when the row is activated (click / Enter / Space). */\n onActivate?: (item: TaskItem) => void;\n /**\n * Trailing per-row action toolbar (icon buttons: schedule, edit, …).\n * Rendered above the stretched-link overlay so the controls stay\n * clickable inside an interactive row.\n */\n actions?: ReactNode;\n /**\n * Replaces the leading status glyph. Pass a control (the done checkbox)\n * when the row can be completed in place: the glyph alone only reports\n * status, and rendering both a glyph and a matching toggle elsewhere in\n * the row shows the same mark twice, of which only one does anything.\n * Rendered above the stretched-link overlay so it stays clickable.\n */\n leading?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst taskCardVariants = cva(\n [\n 'ds:relative ds:flex ds:items-start ds:gap-[var(--spacing-sm)]',\n // Same corner as the elevated Card the note and appointment rows use.\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:transition-colors',\n 'ds:motion-reduce:transition-none',\n 'ds:text-start ds:group',\n 'ds:[:where(&)]:border-[length:var(--surface-border-width,var(--border-width-sm))] ds:border-[color:var(--card-border)]',\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n xs: 'ds:p-[var(--spacing-xs)]',\n sm: 'ds:p-[var(--spacing-sm)]',\n md: 'ds:p-[var(--spacing-md)]',\n },\n interactive: {\n true: 'ds:hover:bg-[color:var(--muted)]/40 ds:cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n interactive: false,\n },\n },\n);\n\n/* The activator keeps a box of its own (display: contents cannot take\n focus in Chromium); its ::after still stretches over the card. */\nconst stretchedLinkClass = [\n 'ds:focus-visible:outline-none',\n \"ds:after:content-[''] ds:after:absolute ds:after:inset-0 ds:after:rounded-[var(--radius-lg)]\",\n 'ds:after:pointer-events-auto',\n 'ds:focus-visible:after:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:after:outline-solid',\n 'ds:focus-visible:after:outline-[color:var(--ring)]',\n 'ds:focus-visible:after:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:after:outline-[CanvasText]',\n].join(' ');\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nexport function isSafeTaskUrl(url: string): boolean {\n return /^(https?:\\/\\/(?!\\/)|\\/(?!\\/)|#)/.test(url);\n}\n\nfunction StatusIcon({\n status,\n priority,\n}: {\n status?: TaskStatus;\n priority?: TaskPriority;\n}): ReactNode {\n const tone =\n priority === 'high'\n ? 'ds:text-[color:var(--destructive)]'\n : 'ds:text-[color:var(--muted-foreground)]';\n if (status === 'done') {\n return (\n <SquareCheckBig aria-hidden=\"true\" className={`ds:size-4 ${tone}`} />\n );\n }\n if (priority === 'high') {\n return <CircleAlert aria-hidden=\"true\" className={`ds:size-4 ${tone}`} />;\n }\n return <Square aria-hidden=\"true\" className={`ds:size-4 ${tone}`} />;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const TaskCard = forwardRef<HTMLDivElement, TaskCardProps>(\n (\n { item, size = 'sm', onActivate, actions, leading, className, ...rest },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const interactive = !!onActivate;\n const hasSafeUrl = !!item.url && isSafeTaskUrl(item.url);\n const ariaLabel = t('taskCard.itemLabel', {\n title: item.title,\n due: item.dueLabel ?? '',\n defaultValue: '{{title}}{{due, prepend, \" · \"}}',\n });\n\n // Static key lookups so the i18n coverage gate sees each literal key.\n const linkTypeLabels: Record<TaskLinkType, string> = {\n patient: t('taskCard.link.patient'),\n company: t('taskCard.link.company'),\n operator: t('taskCard.link.operator'),\n };\n const LinkIcon = item.linkType ? LINK_ICON[item.linkType] : null;\n // A masked name always gets the chip, so it can say what is hidden,\n // even when the host sends no mask of its own.\n const masked = !!item.linkedLabelMasked;\n // The meta row carries icon-led chips: a typed linked entity + an assignee.\n const showLinkChip = masked || (!!item.linkType && !!item.linkedLabel);\n const hasMetaRow = showLinkChip || !!item.assigneeLabel;\n\n const titleNode = (\n <span className=\"ds:flex-1 ds:min-w-0 ds:truncate type-body-sm ds:text-[color:var(--foreground)]\">\n {item.title}\n </span>\n );\n\n let activator: ReactNode;\n if (interactive && hasSafeUrl) {\n activator = (\n <a\n href={item.url}\n aria-label={ariaLabel}\n data-action=\"open-task\"\n className={stretchedLinkClass + ' ds:flex ds:min-w-0'}\n onClick={(e) => {\n if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey)\n return;\n onActivate?.(item);\n }}\n >\n {titleNode}\n </a>\n );\n } else if (interactive) {\n activator = (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n data-action=\"open-task\"\n className={\n stretchedLinkClass +\n ' ds:flex ds:min-w-0 ds:bg-transparent ds:border-0 ds:p-0 ds:text-start'\n }\n onClick={() => onActivate?.(item)}\n >\n {titleNode}\n </button>\n );\n } else {\n activator = titleNode;\n }\n\n return (\n <div\n ref={ref}\n role=\"listitem\"\n data-component=\"task-card\"\n data-component-id={item.id}\n data-status={item.status ?? 'open'}\n data-priority={item.priority ?? 'normal'}\n className={taskCardVariants({ size, interactive, className })}\n {...rest}\n >\n <span className=\"ds:relative ds:z-[1] ds:mt-[var(--spacing-2xs)] ds:shrink-0\">\n {leading ?? (\n <StatusIcon status={item.status} priority={item.priority} />\n )}\n </span>\n\n <div className=\"ds:flex-1 ds:min-w-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {activator}\n {item.description ? (\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {item.description}\n </span>\n ) : null}\n {item.note ? (\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)] ds:line-clamp-2\">\n {item.note}\n </span>\n ) : null}\n {hasMetaRow ? (\n // `type-meta` (not `type-eyebrow`): these chips carry proper-noun\n // values (patient / company / operator name, assignee) that must\n // not be uppercased. Icons are decorative; the type word is exposed\n // to AT via a VisuallyHidden prefix so each chip reads e.g.\n // \"Patient: Mario Rossi\" / \"Assignee: Dr. Alfa\".\n <div className=\"type-meta ds:flex ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-sm)] ds:gap-y-[var(--spacing-2xs)] ds:text-[color:var(--muted-foreground)]\">\n {masked ? (\n // The mask is visual noise to a screen reader, so it hears\n // what the mask stands for instead.\n <span className=\"ds:inline-flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <EyeOff\n aria-hidden=\"true\"\n className=\"ds:size-3 ds:shrink-0\"\n />\n <VisuallyHidden>\n {t('appointmentPeek.hiddenName')}\n </VisuallyHidden>\n <span aria-hidden=\"true\" className=\"ds:truncate\">\n {privacyMask(item.linkedLabel)}\n </span>\n </span>\n ) : item.linkType && item.linkedLabel && LinkIcon ? (\n <span className=\"ds:inline-flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <LinkIcon\n aria-hidden=\"true\"\n className=\"ds:size-3 ds:shrink-0\"\n />\n <VisuallyHidden>{`${linkTypeLabels[item.linkType]}: `}</VisuallyHidden>\n <span className=\"ds:truncate\">{item.linkedLabel}</span>\n </span>\n ) : null}\n {item.assigneeLabel ? (\n <span className=\"ds:inline-flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-2xs)]\">\n <User aria-hidden=\"true\" className=\"ds:size-3 ds:shrink-0\" />\n <VisuallyHidden>{`${t('taskCard.assignee')}: `}</VisuallyHidden>\n <span className=\"ds:truncate\">{item.assigneeLabel}</span>\n </span>\n ) : null}\n </div>\n ) : null}\n {item.linkedLabel && !item.linkType && !masked ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {item.linkedLabel}\n </span>\n ) : null}\n {item.dueLabel ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)]\">\n {item.dueLabel}\n </span>\n ) : null}\n </div>\n\n {actions ? (\n // Above the stretched-link overlay so the buttons stay clickable.\n <span className=\"ds:relative ds:z-[1] ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:shrink-0\">\n {actions}\n </span>\n ) : null}\n\n {interactive ? (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:mt-[var(--spacing-2xs)] ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:opacity-0 ds:transition-opacity ds:motion-reduce:transition-none ds:group-hover:opacity-100 ds:group-focus-within:opacity-100 ds:rtl:rotate-180\"\n />\n ) : null}\n </div>\n );\n },\n);\n\nTaskCard.displayName = 'TaskCard';\n"],"names":["__iconNode","Briefcase","createLucideIcon","LINK_ICON","User","Building2","taskCardVariants","cva","stretchedLinkClass","isSafeTaskUrl","url","StatusIcon","status","priority","tone","SquareCheckBig","CircleAlert","Square","TaskCard","forwardRef","item","size","onActivate","actions","leading","className","rest","ref","t","useTranslation","interactive","hasSafeUrl","ariaLabel","linkTypeLabels","LinkIcon","masked","hasMetaRow","titleNode","jsx","activator","e","jsxs","EyeOff","VisuallyHidden","privacyMask","ChevronRight"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -25,7 +25,7 @@ import { u as Vt } from "./registry-DvAUVLHh.js";
|
|
|
25
25
|
import { u as Lt } from "./use-isomorphic-layout-effect-BGfaCOP1.js";
|
|
26
26
|
import { c as Ut } from "./compose-refs-C0k0tdqF.js";
|
|
27
27
|
import { n as Wt } from "./normalize-diacritics-BNGbFNlJ.js";
|
|
28
|
-
import { p as Kt, P as Ht } from "./privacy-mask-
|
|
28
|
+
import { p as Kt, P as Ht } from "./privacy-mask-Dc3kdkCR.js";
|
|
29
29
|
import { g as je, h as Gt } from "./handled-rejection-6gqCf5vt.js";
|
|
30
30
|
import { L as Qt } from "./lock-ClAFG1gy.js";
|
|
31
31
|
import { X as Yt } from "./x-B5YnXwCz.js";
|
|
@@ -1239,4 +1239,4 @@ export {
|
|
|
1239
1239
|
vn as T,
|
|
1240
1240
|
ln as t
|
|
1241
1241
|
};
|
|
1242
|
-
//# sourceMappingURL=task-editor-
|
|
1242
|
+
//# sourceMappingURL=task-editor-D--LwVrg.js.map
|