@alfadocs/ui-kit-debug 1.55.0 → 1.56.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/{alia-sidebar-DS0b54Mv.js → alia-sidebar-DOei4Iyu.js} +2 -2
- package/dist/_chunks/{alia-sidebar-DS0b54Mv.js.map → alia-sidebar-DOei4Iyu.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-Dtw5Hpg4.js → anamnesis-summary-rows-CQ-XGr0T.js} +3 -3
- package/dist/_chunks/{anamnesis-summary-rows-Dtw5Hpg4.js.map → anamnesis-summary-rows-CQ-XGr0T.js.map} +1 -1
- package/dist/_chunks/{balance-badge-cell-zP-iN-Pd.js → balance-badge-cell-DmDcXw0c.js} +3 -3
- package/dist/_chunks/{balance-badge-cell-zP-iN-Pd.js.map → balance-badge-cell-DmDcXw0c.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-DTZhRhXe.js → bmi-calculator-C0UTxB7R.js} +2 -2
- package/dist/_chunks/{bmi-calculator-DTZhRhXe.js.map → bmi-calculator-C0UTxB7R.js.map} +1 -1
- package/dist/_chunks/{booking-uZO10TLK.js → booking-WyNGKPE2.js} +2 -2
- package/dist/_chunks/{booking-uZO10TLK.js.map → booking-WyNGKPE2.js.map} +1 -1
- package/dist/_chunks/{breadcrumb-xgVpPH2H.js → breadcrumb-Boan-5n8.js} +39 -39
- package/dist/_chunks/breadcrumb-Boan-5n8.js.map +1 -0
- package/dist/_chunks/{calculator-dialog-BRjZMWuE.js → calculator-dialog-pCPWta7h.js} +2 -2
- package/dist/_chunks/{calculator-dialog-BRjZMWuE.js.map → calculator-dialog-pCPWta7h.js.map} +1 -1
- package/dist/_chunks/{calendar-workspace-DVajSkKA.js → calendar-workspace-Du2ryaI-.js} +8 -8
- package/dist/_chunks/{calendar-workspace-DVajSkKA.js.map → calendar-workspace-Du2ryaI-.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-BeMYMiI7.js → care-plan-header-DUX_SVvF.js} +2 -2
- package/dist/_chunks/{care-plan-header-BeMYMiI7.js.map → care-plan-header-DUX_SVvF.js.map} +1 -1
- package/dist/_chunks/chart-HsF1KHbx.js +909 -0
- package/dist/_chunks/chart-HsF1KHbx.js.map +1 -0
- package/dist/_chunks/{contact-profile-card-C5DbP_X3.js → contact-profile-card-Ci8lBQ6a.js} +2 -2
- package/dist/_chunks/{contact-profile-card-C5DbP_X3.js.map → contact-profile-card-Ci8lBQ6a.js.map} +1 -1
- package/dist/_chunks/dashboard-grid-DfEY2qci.js +844 -0
- package/dist/_chunks/dashboard-grid-DfEY2qci.js.map +1 -0
- package/dist/_chunks/{data-table-C6T31E33.js → data-table-D8fuhqO1.js} +1 -1
- package/dist/_chunks/{data-table-C6T31E33.js.map → data-table-D8fuhqO1.js.map} +1 -1
- package/dist/_chunks/{date-range-picker-BOvHwWO5.js → date-range-picker-CtUOI38x.js} +188 -182
- package/dist/_chunks/date-range-picker-CtUOI38x.js.map +1 -0
- package/dist/_chunks/{dependent-selector-Bet3XAFj.js → dependent-selector-DgaAQc-c.js} +91 -86
- package/dist/_chunks/dependent-selector-DgaAQc-c.js.map +1 -0
- package/dist/_chunks/{dialog-D52AI4nF.js → dialog-CUzbnKLw.js} +86 -69
- package/dist/_chunks/dialog-CUzbnKLw.js.map +1 -0
- package/dist/_chunks/{due-date-calculator-DXDJbUzo.js → due-date-calculator-CSjklbyw.js} +2 -2
- package/dist/_chunks/{due-date-calculator-DXDJbUzo.js.map → due-date-calculator-CSjklbyw.js.map} +1 -1
- package/dist/_chunks/{file-manager-dIJQUZvq.js → file-manager-Cc_uO8r2.js} +4 -4
- package/dist/_chunks/{file-manager-dIJQUZvq.js.map → file-manager-Cc_uO8r2.js.map} +1 -1
- package/dist/_chunks/{freemium-paywall-B6ojVXq7.js → freemium-paywall-DIKuhX8b.js} +90 -86
- package/dist/_chunks/freemium-paywall-DIKuhX8b.js.map +1 -0
- package/dist/_chunks/{gestational-age-calculator-BfGpt3du.js → gestational-age-calculator-DqVeJke2.js} +2 -2
- package/dist/_chunks/{gestational-age-calculator-BfGpt3du.js.map → gestational-age-calculator-DqVeJke2.js.map} +1 -1
- package/dist/_chunks/{heatmap-BARGZZt2.js → heatmap-Gf9r7Tn1.js} +2 -2
- package/dist/_chunks/{heatmap-BARGZZt2.js.map → heatmap-Gf9r7Tn1.js.map} +1 -1
- package/dist/_chunks/{help-me-write-templates-B7L3zGsE.js → help-me-write-templates-fV-Apf72.js} +2 -2
- package/dist/_chunks/help-me-write-templates-fV-Apf72.js.map +1 -0
- package/dist/_chunks/{key-value-pair-Ax8IJr1M.js → key-value-pair-BNNITp6S.js} +25 -19
- package/dist/_chunks/key-value-pair-BNNITp6S.js.map +1 -0
- package/dist/_chunks/{kit-extensions-C9-v8Dih.js → kit-extensions-Byfxy6sy.js} +4 -4
- package/dist/_chunks/{kit-extensions-C9-v8Dih.js.map → kit-extensions-Byfxy6sy.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-DlBVPMTi.js → link-cell-renderer-TeJNvymP.js} +2 -2
- package/dist/_chunks/{link-cell-renderer-DlBVPMTi.js.map → link-cell-renderer-TeJNvymP.js.map} +1 -1
- package/dist/_chunks/non-modal-tab-exit-D2Bd93Bq.js +65 -0
- package/dist/_chunks/non-modal-tab-exit-D2Bd93Bq.js.map +1 -0
- package/dist/_chunks/{notes-panel-I8ntrrUW.js → notes-panel-DceRhthG.js} +3 -3
- package/dist/_chunks/{notes-panel-I8ntrrUW.js.map → notes-panel-DceRhthG.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-3dspc2tR.js → patient-summary-card-9nQWTQf6.js} +7 -3
- package/dist/_chunks/{patient-summary-card-3dspc2tR.js.map → patient-summary-card-9nQWTQf6.js.map} +1 -1
- package/dist/_chunks/{payment-automation-upsell-DEUfM7EU.js → payment-automation-upsell-DiHovmUL.js} +2 -2
- package/dist/_chunks/{payment-automation-upsell-DEUfM7EU.js.map → payment-automation-upsell-DiHovmUL.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-DAGqh9Yx.js → payment-request-card-CwDpwXUC.js} +2 -2
- package/dist/_chunks/{payment-request-card-DAGqh9Yx.js.map → payment-request-card-CwDpwXUC.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-BqwLxy2m.js → periodontal-chart-DD5C0M3l.js} +2 -2
- package/dist/_chunks/{periodontal-chart-BqwLxy2m.js.map → periodontal-chart-DD5C0M3l.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-card-CWZ1YM1h.js → periodontal-chart-card-CxdXvsPU.js} +2 -2
- package/dist/_chunks/{periodontal-chart-card-CWZ1YM1h.js.map → periodontal-chart-card-CxdXvsPU.js.map} +1 -1
- package/dist/_chunks/{periodontal-diagnosis-C9IuvLId.js → periodontal-diagnosis-D-PJv7KS.js} +2 -2
- package/dist/_chunks/{periodontal-diagnosis-C9IuvLId.js.map → periodontal-diagnosis-D-PJv7KS.js.map} +1 -1
- package/dist/_chunks/{position-grid-D2D5_Tze.js → position-grid-CBB88EaH.js} +38 -36
- package/dist/_chunks/position-grid-CBB88EaH.js.map +1 -0
- package/dist/_chunks/{practice-results-DxOgbPDy.js → practice-results-Dhbo-fc_.js} +2 -2
- package/dist/_chunks/{practice-results-DxOgbPDy.js.map → practice-results-Dhbo-fc_.js.map} +1 -1
- package/dist/_chunks/{pregnancy-dating-R3q5n1Wh.js → pregnancy-dating-Bfu0Cq4H.js} +2 -2
- package/dist/_chunks/{pregnancy-dating-R3q5n1Wh.js.map → pregnancy-dating-Bfu0Cq4H.js.map} +1 -1
- package/dist/_chunks/{pregnancy-weight-gain-DwmNklDU.js → pregnancy-weight-gain-CUUrBTBo.js} +2 -2
- package/dist/_chunks/{pregnancy-weight-gain-DwmNklDU.js.map → pregnancy-weight-gain-CUUrBTBo.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-BWusjxY8.js → public-header.agent-pr2hyiND.js} +2 -2
- package/dist/_chunks/{public-header.agent-BWusjxY8.js.map → public-header.agent-pr2hyiND.js.map} +1 -1
- package/dist/_chunks/{radio-group-BT97ty7o.js → radio-group-DicxWJXP.js} +111 -106
- package/dist/_chunks/radio-group-DicxWJXP.js.map +1 -0
- package/dist/_chunks/{radiograph-panel.agent-BA90I3Mu.js → radiograph-panel.agent-DkUokbEa.js} +3 -3
- package/dist/_chunks/{radiograph-panel.agent-BA90I3Mu.js.map → radiograph-panel.agent-DkUokbEa.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-Blp4smUr.js → rich-text-editor-CkFfmA3v.js} +2 -2
- package/dist/_chunks/{rich-text-editor-Blp4smUr.js.map → rich-text-editor-CkFfmA3v.js.map} +1 -1
- package/dist/_chunks/{sheet-CNFW8mYZ.js → sheet-C7SwIxwB.js} +95 -79
- package/dist/_chunks/sheet-C7SwIxwB.js.map +1 -0
- package/dist/_chunks/{signature-request-rgMsgo-C.js → signature-request-DhbpB9N9.js} +2 -2
- package/dist/_chunks/{signature-request-rgMsgo-C.js.map → signature-request-DhbpB9N9.js.map} +1 -1
- package/dist/_chunks/{stat-51CDL4au.js → stat-DmjGfXND.js} +117 -108
- package/dist/_chunks/stat-DmjGfXND.js.map +1 -0
- package/dist/_chunks/{stepper-accordion-D7lnBGh2.js → stepper-accordion-DDTSOUHc.js} +17 -6
- package/dist/_chunks/stepper-accordion-DDTSOUHc.js.map +1 -0
- package/dist/_chunks/{task-editor-Ctxsa1BY.js → task-editor-ByyRu29Y.js} +3 -3
- package/dist/_chunks/{task-editor-Ctxsa1BY.js.map → task-editor-ByyRu29Y.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-DinTrRIW.js → use-appointment-details-read-JsDM48tf.js} +2 -2
- package/dist/_chunks/{use-appointment-details-read-DinTrRIW.js.map → use-appointment-details-read-JsDM48tf.js.map} +1 -1
- package/dist/_chunks/use-select-on-arrow-Cr4iBuW5.js +26 -0
- package/dist/_chunks/use-select-on-arrow-Cr4iBuW5.js.map +1 -0
- package/dist/_chunks/{widget-picker-D8RiWrJd.js → widget-picker-DXYBMTfe.js} +2 -2
- package/dist/_chunks/{widget-picker-D8RiWrJd.js.map → widget-picker-DXYBMTfe.js.map} +1 -1
- package/dist/_chunks/{workflow-map-D3mezmGB.js → workflow-map-Demlpy39.js} +2 -2
- package/dist/_chunks/{workflow-map-D3mezmGB.js.map → workflow-map-Demlpy39.js.map} +1 -1
- package/dist/agent-catalog.json +27 -10
- package/dist/agent-i18n/en.json +8 -7
- package/dist/components/_shared/non-modal-tab-exit.d.ts +8 -0
- package/dist/components/_shared/non-modal-tab-exit.d.ts.map +1 -0
- package/dist/components/_shared/use-apex-chart-semantics.d.ts +6 -0
- package/dist/components/_shared/use-apex-chart-semantics.d.ts.map +1 -0
- package/dist/components/_shared/use-select-on-arrow.d.ts +20 -0
- package/dist/components/_shared/use-select-on-arrow.d.ts.map +1 -0
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -1
- package/dist/components/breadcrumb/index.js +1 -1
- package/dist/components/calculator-dialog/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/chart/chart.d.ts +10 -5
- package/dist/components/chart/chart.d.ts.map +1 -1
- package/dist/components/chart/index.js +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/dashboard-grid/dashboard-grid-engine.d.ts +22 -0
- package/dist/components/dashboard-grid/dashboard-grid-engine.d.ts.map +1 -1
- package/dist/components/dashboard-grid/dashboard-grid.agent.d.ts.map +1 -1
- package/dist/components/dashboard-grid/dashboard-grid.d.ts +48 -4
- package/dist/components/dashboard-grid/dashboard-grid.d.ts.map +1 -1
- package/dist/components/dashboard-grid/index.js +1 -1
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/date-range-picker/date-range-picker.d.ts.map +1 -1
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/dependent-selector/dependent-selector.d.ts.map +1 -1
- package/dist/components/dependent-selector/index.js +1 -1
- package/dist/components/dialog/dialog.d.ts +2 -2
- package/dist/components/dialog/dialog.d.ts.map +1 -1
- package/dist/components/dialog/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/freemium-paywall/freemium-paywall.d.ts.map +1 -1
- package/dist/components/freemium-paywall/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/heatmap/index.js +1 -1
- package/dist/components/key-value-pair/index.js +1 -1
- package/dist/components/key-value-pair/key-value-pair.d.ts.map +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-summary-card/patient-summary-card.d.ts.map +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/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/position-grid/index.js +1 -1
- package/dist/components/position-grid/position-grid.d.ts.map +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/radio-group/index.js +1 -1
- package/dist/components/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +2 -2
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sheet/sheet.d.ts +2 -2
- package/dist/components/sheet/sheet.d.ts.map +1 -1
- package/dist/components/stat/index.d.ts +1 -1
- package/dist/components/stat/index.d.ts.map +1 -1
- package/dist/components/stat/index.js +1 -1
- package/dist/components/stat/stat.d.ts +9 -0
- package/dist/components/stat/stat.d.ts.map +1 -1
- package/dist/components/stepper-accordion/index.js +1 -1
- package/dist/components/stepper-accordion/stepper-accordion.d.ts.map +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/widget-picker/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/host-legacy.css +13 -2
- package/dist/i18n/locales/ar.d.ts +3 -2
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +5 -4
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +3 -2
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +5 -4
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +3 -2
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +5 -4
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +3 -2
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +5 -4
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +3 -2
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +5 -4
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +3 -2
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +5 -4
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +3 -2
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +5 -4
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +3 -2
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +5 -4
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +3 -2
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +5 -4
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +3 -2
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +5 -4
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +3 -2
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +5 -4
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +3 -2
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +5 -4
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +3 -2
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +5 -4
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +3 -2
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +5 -4
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +3 -2
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +5 -4
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +3 -2
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +5 -4
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +3 -2
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +5 -4
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +3 -2
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +5 -4
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +48 -48
- package/dist/locales/ar.json +5 -4
- package/dist/locales/de.json +5 -4
- package/dist/locales/el.json +5 -4
- package/dist/locales/en.json +5 -4
- package/dist/locales/es.json +5 -4
- package/dist/locales/fr.json +5 -4
- package/dist/locales/hi.json +5 -4
- package/dist/locales/it.json +5 -4
- package/dist/locales/ja.json +5 -4
- package/dist/locales/nl.json +5 -4
- package/dist/locales/pl.json +5 -4
- package/dist/locales/pt.json +5 -4
- package/dist/locales/ro.json +5 -4
- package/dist/locales/ru.json +5 -4
- package/dist/locales/sq.json +5 -4
- package/dist/locales/sv.json +5 -4
- package/dist/locales/tr.json +5 -4
- package/dist/locales/zh.json +5 -4
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/help-me-write-templates/help-me-write-templates.d.ts +2 -2
- package/dist/patterns/help-me-write-templates/help-me-write-templates.d.ts.map +1 -1
- package/dist/patterns/help-me-write-templates/index.js +1 -1
- package/dist/patterns/payment-automation-upsell/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/tokens.css +13 -2
- package/package.json +1 -1
- package/dist/_chunks/breadcrumb-xgVpPH2H.js.map +0 -1
- package/dist/_chunks/chart-C2RBJERE.js +0 -705
- package/dist/_chunks/chart-C2RBJERE.js.map +0 -1
- package/dist/_chunks/dashboard-grid-SAGoyCtL.js +0 -691
- package/dist/_chunks/dashboard-grid-SAGoyCtL.js.map +0 -1
- package/dist/_chunks/date-range-picker-BOvHwWO5.js.map +0 -1
- package/dist/_chunks/dependent-selector-Bet3XAFj.js.map +0 -1
- package/dist/_chunks/dialog-D52AI4nF.js.map +0 -1
- package/dist/_chunks/freemium-paywall-B6ojVXq7.js.map +0 -1
- package/dist/_chunks/help-me-write-templates-B7L3zGsE.js.map +0 -1
- package/dist/_chunks/key-value-pair-Ax8IJr1M.js.map +0 -1
- package/dist/_chunks/position-grid-D2D5_Tze.js.map +0 -1
- package/dist/_chunks/radio-group-BT97ty7o.js.map +0 -1
- package/dist/_chunks/sheet-CNFW8mYZ.js.map +0 -1
- package/dist/_chunks/stat-51CDL4au.js.map +0 -1
- package/dist/_chunks/stepper-accordion-D7lnBGh2.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-grid-SAGoyCtL.js","sources":["../../node_modules/lucide-react/dist/esm/icons/move-diagonal-2.mjs","../../src/components/dashboard-grid/dashboard-grid.agent.ts","../../src/components/dashboard-grid/dashboard-grid-engine.ts","../../src/components/dashboard-grid/dashboard-grid.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: \"M19 13v6h-6\", key: \"1hxl6d\" }],\n [\"path\", { d: \"M5 11V5h6\", key: \"12e2xe\" }],\n [\"path\", { d: \"m5 5 14 14\", key: \"11anup\" }]\n];\nconst MoveDiagonal2 = createLucideIcon(\"move-diagonal-2\", __iconNode);\n\nexport { __iconNode, MoveDiagonal2 as default };\n//# sourceMappingURL=move-diagonal-2.mjs.map\n","import type { AgentAdapter } from '../../agent/types';\nimport type { DashboardGridHandle } from './dashboard-grid';\n\nexport const dashboardGridAgent: AgentAdapter<DashboardGridHandle> = {\n id: 'dashboard-grid',\n // The board's whole purpose is in-place rearrangement of its widgets.\n capabilities: ['edit_inline'],\n state: {\n layout: {\n type: '{ id: string, x: number, y: number, w: number, h: number }[]',\n descriptionKey: 'ui.agent.dashboardGrid.state.layout',\n description:\n 'Current widget geometry in cell units — ids and rectangles only, no widget content.',\n read: (handle) => handle.getGridState().layout,\n },\n cols: {\n type: 'number',\n descriptionKey: 'ui.agent.dashboardGrid.state.cols',\n description: 'Logical column count of the board.',\n read: (handle) => handle.getGridState().cols,\n },\n editing: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dashboardGrid.state.editing',\n description:\n 'Whether edit mode is on. Move/resize actions are refused while it is off — the host app owns the toggle.',\n read: (handle) => handle.getGridState().editing,\n },\n },\n actions: {\n move_widget: {\n // Rearranging the board mutates user configuration — a write,\n // reversible by moving back.\n safety: 'write',\n argsType: 'id, x, y',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Widget id (see layout state).' },\n x: {\n type: 'integer',\n minimum: 0,\n description: '0-based logical column.',\n },\n y: { type: 'integer', minimum: 0, description: '0-based row.' },\n },\n required: ['id', 'x', 'y'],\n },\n returns: 'boolean (accepted)',\n returnsSchema: {\n type: 'boolean',\n description:\n 'True when applied; false when edit mode is off or the id is unknown.',\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dashboardGrid.actions.moveWidget',\n description:\n 'Move a widget to a cell. Out-of-bounds targets are clamped; colliding widgets are pushed down and the layout re-compacts. Refused while edit mode is off.',\n invoke: (handle, args: { id: string; x: number; y: number }) =>\n handle.moveWidgetTo(args.id, args.x, args.y),\n },\n resize_widget: {\n safety: 'write',\n argsType: 'id, w, h',\n argsSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Widget id (see layout state).' },\n w: {\n type: 'integer',\n minimum: 1,\n description: 'Column span (≥ 1).',\n },\n h: { type: 'integer', minimum: 1, description: 'Row span (≥ 1).' },\n },\n required: ['id', 'w', 'h'],\n },\n returns: 'boolean (accepted)',\n returnsSchema: {\n type: 'boolean',\n description:\n 'True when applied; false when edit mode is off or the id is unknown.',\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dashboardGrid.actions.resizeWidget',\n description:\n 'Resize a widget to a span. Clamped to the grid and the widget’s min/max; colliding widgets are pushed down. Refused while edit mode is off.',\n invoke: (handle, args: { id: string; w: number; h: number }) =>\n handle.resizeWidgetTo(args.id, args.w, args.h),\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dashboard-grid' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-widget-id',\n description: 'Each widget wrapper carries its layout id.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* DashboardGrid engine — pure layout math, no DOM. */\n/* */\n/* The grid is a column-count × unbounded-rows plane. Every widget is */\n/* an axis-aligned rectangle in cell units: `x` is the 0-based LOGICAL */\n/* column (inline-start based — CSS Grid flips it visually in RTL), */\n/* `y` the 0-based row, `w`/`h` the spans. All functions are pure and */\n/* return new arrays; the component layer owns state and DOM. */\n/* ------------------------------------------------------------------ */\n\nexport interface DashboardWidgetLayout {\n id: string;\n /** 0-based logical column of the inline-start edge. */\n x: number;\n /** 0-based row of the block-start edge. */\n y: number;\n /** Column span (≥ 1). */\n w: number;\n /** Row span (≥ 1). */\n h: number;\n minW?: number;\n minH?: number;\n maxW?: number;\n maxH?: number;\n}\n\nexport function collides(\n a: DashboardWidgetLayout,\n b: DashboardWidgetLayout,\n): boolean {\n return (\n a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h\n );\n}\n\n/** Clamp a rect to the grid bounds and its own min/max constraints. */\nexport function clampRect(\n item: DashboardWidgetLayout,\n cols: number,\n): DashboardWidgetLayout {\n const minW = Math.max(1, item.minW ?? 1);\n const minH = Math.max(1, item.minH ?? 1);\n const maxW = Math.min(cols, item.maxW ?? cols);\n const maxH = item.maxH ?? Number.POSITIVE_INFINITY;\n const w = Math.min(Math.max(item.w, minW), maxW);\n const h = Math.min(Math.max(item.h, minH), maxH);\n const x = Math.min(Math.max(0, item.x), cols - w);\n const y = Math.max(0, item.y);\n return { ...item, x, y, w, h };\n}\n\n/**\n * Resolve overlaps and apply upward gravity. The `activeId` rect (the one\n * being dragged/resized) keeps its exact position; every other widget is\n * pushed down out of collisions, then pulled up as far as gravity allows.\n * Deterministic: non-active widgets settle in reading order (y, then x).\n */\nexport function normalise(\n layout: DashboardWidgetLayout[],\n cols: number,\n activeId?: string,\n): DashboardWidgetLayout[] {\n const items = layout.map((item) => clampRect(item, cols));\n const order = [...items].sort((a, b) => {\n if (a.id === activeId) return -1;\n if (b.id === activeId) return 1;\n return a.y - b.y || a.x - b.x;\n });\n const placed: DashboardWidgetLayout[] = [];\n const active = activeId\n ? items.find((item) => item.id === activeId)\n : undefined;\n for (const item of order) {\n if (item.id !== activeId) {\n // Swap-up: when the ACTIVE rect has moved onto this item, prefer\n // lifting the displaced item ABOVE the active rect (into the space\n // the active vacated) over pushing it down. Without this, moving a\n // widget downward past a same-column neighbour is impossible — the\n // neighbour keeps fleeing ahead and the drop compaction reverts the\n // whole gesture.\n if (active && collides(active, item)) {\n const above = { ...item, y: Math.max(0, active.y - item.h) };\n if (\n !collides(active, above) &&\n !placed.some((p) => p.id !== activeId && collides(p, above))\n ) {\n item.y = above.y;\n }\n }\n while (placed.some((p) => collides(p, item))) {\n item.y += 1;\n }\n while (item.y > 0) {\n const test = { ...item, y: item.y - 1 };\n if (placed.some((p) => collides(p, test))) break;\n item.y -= 1;\n }\n }\n placed.push(item);\n }\n // Preserve the caller's array order (children order), only geometry moved.\n const byId = new Map(placed.map((p) => [p.id, p]));\n return layout.map((item) => byId.get(item.id) as DashboardWidgetLayout);\n}\n\n/** Move a widget to a target cell, resolving collisions around it. */\nexport function moveItem(\n layout: DashboardWidgetLayout[],\n id: string,\n x: number,\n y: number,\n cols: number,\n): DashboardWidgetLayout[] {\n const next = layout.map((item) =>\n item.id === id ? clampRect({ ...item, x, y }, cols) : item,\n );\n return normalise(next, cols, id);\n}\n\n/** Resize a widget to a target span, resolving collisions around it. */\nexport function resizeItem(\n layout: DashboardWidgetLayout[],\n id: string,\n w: number,\n h: number,\n cols: number,\n): DashboardWidgetLayout[] {\n const next = layout.map((item) =>\n item.id === id\n ? // Resizing never moves the widget: the width clamps to the space\n // between its position and the grid edge (clampRect would slide it).\n // minW wins over the edge clamp so clampRect cannot re-raise w and\n // slide x as a side effect.\n clampRect(\n {\n ...item,\n w: Math.max(item.minW ?? 1, Math.min(w, cols - item.x)),\n h,\n },\n cols,\n )\n : item,\n );\n return normalise(next, cols, id);\n}\n\n/** First free slot (reading order) that fits a `w`×`h` rect. */\nexport function firstFit(\n layout: DashboardWidgetLayout[],\n cols: number,\n w: number,\n h: number,\n): { x: number; y: number } {\n const width = Math.min(Math.max(1, w), cols);\n const maxY = layout.reduce((m, item) => Math.max(m, item.y + item.h), 0);\n for (let y = 0; y <= maxY; y += 1) {\n for (let x = 0; x <= cols - width; x += 1) {\n const candidate: DashboardWidgetLayout = {\n id: '__candidate__',\n x,\n y,\n w: width,\n h,\n };\n if (!layout.some((item) => collides(item, candidate))) {\n return { x, y };\n }\n }\n }\n return { x: 0, y: maxY };\n}\n\n/** Total rows the layout occupies (for sizing the add tile / container). */\nexport function rowCount(layout: DashboardWidgetLayout[]): number {\n return layout.reduce((m, item) => Math.max(m, item.y + item.h), 0);\n}\n","/* ------------------------------------------------------------------ */\n/* DashboardGrid — user-configurable widget board. */\n/* */\n/* A CSS-Grid plane (N logical columns × unbounded rows) whose child */\n/* `DashboardGrid.Widget`s can be moved, resized, removed, and added */\n/* while `editing` is on. Layout state is `{id,x,y,w,h}[]` in cell */\n/* units — controlled via `layout`/`onLayoutChange` or uncontrolled */\n/* via `defaultLayout`. The collision/gravity engine lives in */\n/* `dashboard-grid-engine.ts` (pure, unit-tested). */\n/* */\n/* - Coordinates reach CSS through custom properties set with */\n/* `style.setProperty` — the sanctioned escape hatch for runtime */\n/* values (23-constraints §4; same pattern as `progress`). */\n/* - RTL is free: CSS Grid columns are logical, so column 1 sits at */\n/* the inline-start in both directions. Arrow keys are dir-aware. */\n/* - Move/resize are keyboard-first: each handle is a button — Enter/ */\n/* Space grabs, arrows step one cell, Enter drops, Escape cancels — */\n/* with a polite live region announcing every step. */\n/* ------------------------------------------------------------------ */\n\nimport {\n Children,\n Fragment,\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent as ReactKeyboardEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { GripVertical, MoveDiagonal2, Plus, X } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { dashboardGridAgent } from './dashboard-grid.agent';\nimport {\n clampRect,\n firstFit,\n moveItem,\n normalise,\n resizeItem,\n rowCount,\n type DashboardWidgetLayout,\n} from './dashboard-grid-engine';\n\nexport type { DashboardWidgetLayout } from './dashboard-grid-engine';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst dashboardGridVariants = cva(\n [\n 'ds:grid ds:w-full',\n 'ds:gap-[var(--spacing-md)]',\n 'ds:[grid-template-columns:repeat(var(--dg-cols),minmax(0,1fr))]',\n 'ds:[grid-auto-rows:var(--dg-row)]',\n // Edit-mode surface: tint the whole plane, draw faint cell lines, and\n // reserve spare rows (--dg-min-block) so the AVAILABLE space reads at\n // a glance instead of the board ending at the last occupied row.\n 'ds:data-[editing=true]:rounded-[var(--radius-lg)] ds:data-[editing=true]:bg-muted/10',\n 'ds:data-[editing=true]:[background-image:var(--dg-grid-lines)]',\n 'ds:data-[editing=true]:min-h-[var(--dg-min-block)]',\n ].join(' '),\n { variants: {}, defaultVariants: {} },\n);\n\nconst widgetVariants = cva(\n [\n 'ds:relative ds:flex ds:min-h-0 ds:min-w-0 ds:flex-col ds:overflow-hidden',\n // Mirror of Card variant=\"elevated\" so widgets read as kit cards.\n 'ds:rounded-[var(--radius-lg)] ds:bg-[var(--card)] ds:text-[var(--card-foreground)]',\n 'ds:[:where(&)]:border-[length:var(--surface-border-width,var(--border-width-sm))] ds:border-[color:var(--card-border)] ds:shadow-[var(--shadow-card)]',\n 'ds:[grid-column-start:var(--dg-x)] ds:[grid-column-end:span_var(--dg-w)]',\n 'ds:[grid-row-start:var(--dg-y)] ds:[grid-row-end:span_var(--dg-h)]',\n // Grabbed feedback (keyboard or pointer drag in flight).\n 'ds:data-[grabbed=true]:ring-[length:var(--focus-ring-width)] ds:data-[grabbed=true]:ring-ring ds:data-[grabbed=true]:z-10',\n ].join(' '),\n { variants: {}, defaultVariants: {} },\n);\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface DashboardGridProps extends VariantProps<\n typeof dashboardGridVariants\n> {\n /** Accessible name for the board region. Required. */\n 'aria-label': string;\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** Logical column count. Defaults to 12. */\n cols?: number;\n /** Row height in px (one `h` unit). Defaults to 96. */\n rowHeight?: number;\n /** Controlled layout. Entries are matched to widgets by `id`. */\n layout?: DashboardWidgetLayout[];\n /** Uncontrolled initial layout. */\n defaultLayout?: DashboardWidgetLayout[];\n /**\n * Fired after every committed change — move, resize, remove pruning, and\n * the auto-placement of widgets that had no layout entry. Persist this.\n */\n onLayoutChange?: (next: DashboardWidgetLayout[]) => void;\n /** Edit mode: shows move/resize/remove chrome and the add tile. */\n editing?: boolean;\n /**\n * Called when the user activates a widget's remove button. The kit\n * commits the entry removal (one `onLayoutChange`) and manages focus;\n * the consumer unmounts the child. Omit to hide the remove button.\n */\n onRemoveWidget?: (id: string) => void;\n /**\n * Called when the user activates the add tile (rendered in edit mode\n * only when this is provided). The consumer appends a new\n * `DashboardGrid.Widget`; it is auto-placed first-fit and reported via\n * `onLayoutChange`.\n */\n onRequestAdd?: () => void;\n /** `DashboardGrid.Widget` children. */\n children: ReactNode;\n className?: string;\n}\n\nexport interface DashboardGridHandle {\n /** Move a widget to a cell. False when not editing or id unknown. */\n moveWidgetTo: (id: string, x: number, y: number) => boolean;\n /** Resize a widget to a span. False when not editing or id unknown. */\n resizeWidgetTo: (id: string, w: number, h: number) => boolean;\n /** Current geometry + mode. */\n getGridState: () => {\n cols: number;\n editing: boolean;\n layout: DashboardWidgetLayout[];\n };\n}\n\nexport interface DashboardGridWidgetProps {\n /** Stable widget id — matches a `layout` entry. */\n id: string;\n /** Visible widget title (consumer-translated). */\n title: string;\n /** Cell span used when the widget has no layout entry yet. */\n defaultW?: number;\n defaultH?: number;\n /** Extra header actions (view mode and edit mode). */\n actionsSlot?: ReactNode;\n children?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Context */\n/* ------------------------------------------------------------------ */\n\ninterface GrabState {\n kind: 'move' | 'resize';\n id: string;\n via: 'pointer' | 'keyboard';\n}\n\ninterface DashboardGridContextValue {\n editing: boolean;\n layoutById: Map<string, DashboardWidgetLayout>;\n grab: GrabState | null;\n canRemove: boolean;\n requestRemove: (id: string) => void;\n startKeyboardGrab: (kind: 'move' | 'resize', id: string) => void;\n keyboardStep: (\n event: ReactKeyboardEvent<HTMLButtonElement>,\n id: string,\n ) => void;\n startPointerGrab: (\n kind: 'move' | 'resize',\n id: string,\n event: ReactPointerEvent<HTMLButtonElement>,\n ) => void;\n}\n\nconst DashboardGridContext = createContext<DashboardGridContextValue | null>(\n null,\n);\n\n/** Walk widget children, descending into fragments (a common JSX shape). */\nfunction forEachWidgetChild(\n children: ReactNode,\n fn: (child: ReactElement<DashboardGridWidgetProps>) => void,\n): void {\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (child.type === Fragment) {\n forEachWidgetChild(\n (child.props as { children?: ReactNode }).children,\n fn,\n );\n return;\n }\n fn(child as ReactElement<DashboardGridWidgetProps>);\n });\n}\n\n/* ------------------------------------------------------------------ */\n/* Widget */\n/* ------------------------------------------------------------------ */\n\nfunction DashboardGridWidget({\n id,\n title,\n actionsSlot,\n children,\n}: DashboardGridWidgetProps) {\n const { t } = useTranslation('ui');\n const ctx = useContext(DashboardGridContext);\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n if (import.meta.env.DEV && !ctx) {\n console.warn(\n 'DashboardGrid.Widget: must be rendered inside a <DashboardGrid>.',\n );\n }\n\n const entry = ctx?.layoutById.get(id);\n\n // Sanctioned escape hatch for runtime-computed values (23-constraints §4):\n // cell coordinates land on CSS custom properties via style.setProperty.\n useIsomorphicLayoutEffect(() => {\n const node = wrapperRef.current;\n if (!node || !entry) return;\n node.style.setProperty('--dg-x', String(entry.x + 1));\n node.style.setProperty('--dg-y', String(entry.y + 1));\n node.style.setProperty('--dg-w', String(entry.w));\n node.style.setProperty('--dg-h', String(entry.h));\n }, [entry?.x, entry?.y, entry?.w, entry?.h, entry]);\n\n if (!ctx || !entry) return null;\n\n const grabbed = ctx.grab?.id === id;\n const editing = ctx.editing;\n\n return (\n <div\n ref={wrapperRef}\n role=\"listitem\"\n aria-label={title}\n data-component=\"dashboard-grid-widget\"\n data-widget-id={id}\n data-grabbed={grabbed || undefined}\n className={widgetVariants()}\n >\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pt-[var(--spacing-sm)]\">\n {editing ? (\n <IconButton\n size=\"sm\"\n intent=\"outline\"\n type=\"button\"\n icon={<GripVertical />}\n aria-label={t('dashboardGrid.move', { title })}\n aria-pressed={grabbed && ctx.grab?.kind === 'move'}\n className=\"ds:cursor-grab ds:touch-none ds:bg-[var(--card)]\"\n onPointerDown={(event) => ctx.startPointerGrab('move', id, event)}\n onKeyDown={(event) => ctx.keyboardStep(event, id)}\n onClick={() => ctx.startKeyboardGrab('move', id)}\n />\n ) : null}\n <span className=\"ds:min-w-0 ds:flex-1 ds:truncate ds:text-sm ds:font-medium\">\n {title}\n </span>\n {actionsSlot}\n {editing && ctx.canRemove ? (\n <IconButton\n size=\"sm\"\n intent=\"outline\"\n type=\"button\"\n icon={<X />}\n className=\"ds:bg-[var(--card)]\"\n aria-label={t('dashboardGrid.remove', { title })}\n onClick={() => ctx.requestRemove(id)}\n />\n ) : null}\n </div>\n <div className=\"ds:min-h-0 ds:flex-1 ds:overflow-hidden ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pb-[var(--spacing-md)] ds:pt-[var(--spacing-xs)]\">\n {children}\n </div>\n {editing ? (\n <span className=\"ds:absolute ds:bottom-[var(--spacing-sm)] ds:end-[var(--spacing-sm)]\">\n <IconButton\n size=\"sm\"\n intent=\"outline\"\n type=\"button\"\n icon={<MoveDiagonal2 />}\n flipIconInRtl\n aria-label={t('dashboardGrid.resize', { title })}\n aria-pressed={grabbed && ctx.grab?.kind === 'resize'}\n className=\"ds:touch-none ds:bg-[var(--card)]\"\n onPointerDown={(event) => ctx.startPointerGrab('resize', id, event)}\n onKeyDown={(event) => ctx.keyboardStep(event, id)}\n onClick={() => ctx.startKeyboardGrab('resize', id)}\n />\n </span>\n ) : null}\n </div>\n );\n}\nDashboardGridWidget.displayName = 'DashboardGrid.Widget';\n\n/* ------------------------------------------------------------------ */\n/* DashboardGrid */\n/* ------------------------------------------------------------------ */\n\ninterface PointerDragState {\n kind: 'move' | 'resize';\n id: string;\n pointerId: number;\n startClientX: number;\n startClientY: number;\n origin: DashboardWidgetLayout;\n colStride: number;\n rowStride: number;\n isRtl: boolean;\n}\n\nconst DashboardGridRoot = forwardRef<DashboardGridHandle, DashboardGridProps>(\n (\n {\n 'aria-label': ariaLabel,\n id,\n cols = 12,\n rowHeight = 96,\n layout: layoutProp,\n defaultLayout,\n onLayoutChange,\n editing = false,\n onRemoveWidget,\n onRequestAdd,\n children,\n className,\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const gridRef = useRef<HTMLDivElement>(null);\n\n if (import.meta.env.DEV && !ariaLabel) {\n console.warn(\n 'DashboardGrid: `aria-label` is required for accessibility.',\n );\n }\n\n /* ---- child ids in render order --------------------------------- */\n /* Fragments are flattened: `<>{widgets}</>` is a normal consumer */\n /* shape and must contribute its widgets, not an id-less wrapper. */\n const childIds = useMemo(() => {\n const ids: string[] = [];\n forEachWidgetChild(children, (child) => {\n if (child.props.id) ids.push(child.props.id);\n });\n return ids;\n }, [children]);\n const childMeta = useMemo(() => {\n const meta = new Map<string, { defaultW: number; defaultH: number }>();\n forEachWidgetChild(children, (child) => {\n if (child.props.id) {\n meta.set(child.props.id, {\n defaultW: child.props.defaultW ?? 4,\n defaultH: child.props.defaultH ?? 2,\n });\n }\n });\n return meta;\n }, [children]);\n\n /* ---- controlled / uncontrolled layout -------------------------- */\n const [internalLayout, setInternalLayout] = useState<\n DashboardWidgetLayout[]\n >(() => defaultLayout ?? []);\n const committed = layoutProp ?? internalLayout;\n\n const commit = useCallback(\n (next: DashboardWidgetLayout[]) => {\n if (layoutProp === undefined) setInternalLayout(next);\n onLayoutChange?.(next);\n },\n [layoutProp, onLayoutChange],\n );\n\n /* ---- resolve: bounds-clamp + auto-place missing children -------- */\n /* Entries whose widget is absent are KEPT, not pruned: widgets may */\n /* mount late (lazy chunks, permission gates) and pruning would */\n /* destroy their saved geometry — they simply don't render until the */\n /* child appears. Removal goes through the remove flow, which commits */\n /* the entry removal explicitly. */\n const { resolved, autoPlaced } = useMemo(() => {\n const clamped = committed.map((entry) => clampRect(entry, cols));\n const missing = childIds.filter(\n (cid) => !clamped.some((entry) => entry.id === cid),\n );\n if (missing.length === 0) {\n return { resolved: clamped, autoPlaced: false };\n }\n const placed = [...clamped];\n for (const cid of missing) {\n const meta = childMeta.get(cid) ?? { defaultW: 4, defaultH: 2 };\n const w = Math.min(meta.defaultW, cols);\n const spot = firstFit(placed, cols, w, meta.defaultH);\n placed.push({ id: cid, x: spot.x, y: spot.y, w, h: meta.defaultH });\n }\n return { resolved: normalise(placed, cols), autoPlaced: true };\n }, [committed, childIds, childMeta, cols]);\n\n // Report auto-placement exactly once per divergence so the consumer can\n // persist the new entries. Bounds-clamping is render-only and never\n // reported — a controlled layout is not rewritten uninvited.\n const reportedRef = useRef('');\n useEffect(() => {\n if (!autoPlaced) return;\n const signature = resolved\n .map(\n (entry) => `${entry.id}:${entry.x},${entry.y},${entry.w},${entry.h}`,\n )\n .join('|');\n if (reportedRef.current !== signature) {\n reportedRef.current = signature;\n commit(resolved);\n }\n }, [autoPlaced, resolved, commit]);\n\n /* ---- drag / grab state ----------------------------------------- */\n /* Live values mirror into refs so event handlers stay PURE: no state */\n /* updater performs side effects (StrictMode double-invokes them and */\n /* render-phase commits would set consumer state during render), and */\n /* the stable callbacks read current values without dependency churn. */\n const [draft, setDraft] = useState<DashboardWidgetLayout[] | null>(null);\n const [grab, setGrab] = useState<GrabState | null>(null);\n const [announcement, setAnnouncement] = useState('');\n const draftRef = useRef<DashboardWidgetLayout[] | null>(null);\n const grabRef = useRef<\n (GrabState & { baseLayout: DashboardWidgetLayout[] }) | null\n >(null);\n const pointerDragRef = useRef<PointerDragState | null>(null);\n // A pointer interaction always ends with a trailing `click` on the\n // handle — preventDefault on pointerdown does NOT suppress it, and\n // pointer capture retargets it to the handle. This flag turns that\n // click into a no-op instead of a phantom keyboard grab.\n const suppressClickRef = useRef(false);\n const colsRef = useRef(cols);\n colsRef.current = cols;\n const resolvedRef = useRef(resolved);\n resolvedRef.current = resolved;\n\n const applyDraft = useCallback((next: DashboardWidgetLayout[] | null) => {\n draftRef.current = next;\n setDraft(next);\n }, []);\n\n const beginGrab = useCallback(\n (\n kind: 'move' | 'resize',\n widgetId: string,\n via: 'pointer' | 'keyboard',\n ) => {\n const state: GrabState = { kind, id: widgetId, via };\n // The grab-time layout is the collision base for EVERY step of this\n // grab: resolving against the mutating draft makes displaced\n // neighbours flee ahead of repeated steps (down-reorder becomes\n // unreachable); resolving against the frozen base keeps targeting\n // stateless and lets the engine's swap-up work.\n grabRef.current = { ...state, baseLayout: resolvedRef.current };\n setGrab(state);\n applyDraft(resolvedRef.current);\n },\n [applyDraft],\n );\n\n const active = draft ?? resolved;\n const layoutById = useMemo(\n () => new Map(active.map((entry) => [entry.id, entry])),\n [active],\n );\n\n const announceEntry = useCallback(\n (kind: 'move' | 'resize', entry: DashboardWidgetLayout) => {\n setAnnouncement(\n kind === 'move'\n ? t('dashboardGrid.movedTo', { col: entry.x + 1, row: entry.y + 1 })\n : t('dashboardGrid.resizedTo', { cols: entry.w, rows: entry.h }),\n );\n },\n [t],\n );\n\n const endGrab = useCallback(\n (commitDraft: boolean) => {\n const current = draftRef.current;\n const grabbed = grabRef.current;\n grabRef.current = null;\n pointerDragRef.current = null;\n setGrab(null);\n applyDraft(null);\n if (!commitDraft || !current || !grabbed) {\n setAnnouncement(t('dashboardGrid.cancelled'));\n return;\n }\n // Committing compacts the WHOLE board — the dropped widget joins\n // the gravity pass, so a saved dashboard never keeps stray gaps.\n // A release that changed nothing commits nothing: a plain press on\n // a handle must never rewrite the persisted layout.\n const final = normalise(current, colsRef.current);\n const signatureOf = (layout: DashboardWidgetLayout[]): string =>\n layout.map((e) => `${e.id}:${e.x},${e.y},${e.w},${e.h}`).join('|');\n if (signatureOf(final) === signatureOf(resolvedRef.current)) {\n setAnnouncement(t('dashboardGrid.cancelled'));\n return;\n }\n commit(final);\n // Announce where the widget actually SETTLED — compaction can move\n // it past the last previewed cell, and a screen-reader user must\n // not be left with a stale mental model.\n const landed = final.find((entry) => entry.id === grabbed.id);\n setAnnouncement(\n landed\n ? t('dashboardGrid.droppedAt', {\n col: landed.x + 1,\n row: landed.y + 1,\n })\n : t('dashboardGrid.cancelled'),\n );\n },\n [applyDraft, commit, t],\n );\n\n /* ---- keyboard grab --------------------------------------------- */\n const startKeyboardGrab = useCallback(\n (kind: 'move' | 'resize', widgetId: string) => {\n if (!editing) return;\n // The click that terminates a pointer interaction is not a request\n // for a keyboard grab.\n if (suppressClickRef.current) {\n suppressClickRef.current = false;\n return;\n }\n const current = grabRef.current;\n if (current?.via === 'pointer') return;\n if (current && current.id === widgetId && current.kind === kind) {\n // Second Enter/Space (button click) drops.\n endGrab(true);\n return;\n }\n beginGrab(kind, widgetId, 'keyboard');\n setAnnouncement(\n kind === 'move'\n ? t('dashboardGrid.grabbed')\n : t('dashboardGrid.resizeGrabbed'),\n );\n },\n [editing, beginGrab, endGrab, t],\n );\n\n const keyboardStep = useCallback(\n (event: ReactKeyboardEvent<HTMLButtonElement>, widgetId: string) => {\n const grabbed = grabRef.current;\n if (!grabbed || grabbed.id !== widgetId || grabbed.via !== 'keyboard') {\n return;\n }\n if (event.key === 'Escape') {\n event.preventDefault();\n endGrab(false);\n return;\n }\n const arrows = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];\n if (!arrows.includes(event.key)) return;\n event.preventDefault();\n const isRtl =\n typeof window !== 'undefined' && gridRef.current\n ? window.getComputedStyle(gridRef.current).direction === 'rtl'\n : false;\n // Visual left/right → logical inline delta (flips in RTL).\n const inlineDelta =\n event.key === 'ArrowRight'\n ? isRtl\n ? -1\n : 1\n : event.key === 'ArrowLeft'\n ? isRtl\n ? 1\n : -1\n : 0;\n const blockDelta =\n event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;\n // Target accumulates through the draft; collisions resolve against\n // the frozen grab-time base (see beginGrab).\n const currentDraft = draftRef.current ?? grabbed.baseLayout;\n const entry = currentDraft.find((item) => item.id === widgetId);\n if (!entry) return;\n const next =\n grabbed.kind === 'move'\n ? moveItem(\n grabbed.baseLayout,\n widgetId,\n entry.x + inlineDelta,\n entry.y + blockDelta,\n cols,\n )\n : resizeItem(\n grabbed.baseLayout,\n widgetId,\n entry.w + inlineDelta,\n entry.h + blockDelta,\n cols,\n );\n applyDraft(next);\n const moved = next.find((item) => item.id === widgetId);\n if (moved) announceEntry(grabbed.kind, moved);\n },\n [cols, endGrab, applyDraft, announceEntry],\n );\n\n /* ---- pointer drag ---------------------------------------------- */\n const startPointerGrab = useCallback(\n (\n kind: 'move' | 'resize',\n widgetId: string,\n event: ReactPointerEvent<HTMLButtonElement>,\n ) => {\n if (!editing) return;\n // Any grab in flight wins: a keyboard grab must not be hijacked,\n // and a second concurrent pointer (multi-touch) must not reset an\n // active drag.\n if (grabRef.current) return;\n const gridNode = gridRef.current;\n const entry = resolvedRef.current.find((item) => item.id === widgetId);\n if (!gridNode || !entry) return;\n event.preventDefault();\n // preventDefault suppressed the browser's mousedown-focus — restore\n // it explicitly so the focusout/Escape cancel paths stay reachable\n // and the handle shows its focus ring during the drag.\n event.currentTarget.focus?.();\n const rect = gridNode.getBoundingClientRect();\n // A 0-width container (hidden tab, jsdom) has no usable cell metric —\n // pointer dragging is meaningless there; keyboard still works.\n if (rect.width <= 0) return;\n const styles = window.getComputedStyle(gridNode);\n const gap = Number.parseFloat(styles.columnGap) || 0;\n const rowGap = Number.parseFloat(styles.rowGap) || 0;\n const colWidth = (rect.width - gap * (cols - 1)) / cols;\n pointerDragRef.current = {\n kind,\n id: widgetId,\n pointerId: event.pointerId,\n startClientX: event.clientX,\n startClientY: event.clientY,\n origin: entry,\n colStride: colWidth + gap,\n rowStride: rowHeight + rowGap,\n isRtl: styles.direction === 'rtl',\n };\n try {\n event.currentTarget.setPointerCapture?.(event.pointerId);\n } catch {\n // Synthetic pointer events (tests) have no active pointer to\n // capture; the window-level listeners track the drag regardless.\n }\n beginGrab(kind, widgetId, 'pointer');\n },\n [editing, cols, rowHeight, beginGrab],\n );\n\n // Pointer move/up/cancel are window-level while a drag is in flight so\n // the drag survives the pointer leaving the handle's hit area.\n useEffect(() => {\n if (!grab || grab.via !== 'pointer') return undefined;\n const onMove = (event: PointerEvent) => {\n const dragState = pointerDragRef.current;\n const grabbed = grabRef.current;\n if (!dragState || !grabbed || event.pointerId !== dragState.pointerId)\n return;\n const dxPx = event.clientX - dragState.startClientX;\n const dyPx = event.clientY - dragState.startClientY;\n // Visual px → logical cells: a rightward drag decreases the logical\n // column in RTL.\n const inlineCells =\n Math.round(dxPx / dragState.colStride) * (dragState.isRtl ? -1 : 1);\n const blockCells = Math.round(dyPx / dragState.rowStride);\n // Origin-absolute targeting against the frozen grab base — every\n // event re-derives the whole draft, nothing accumulates.\n const next =\n dragState.kind === 'move'\n ? moveItem(\n grabbed.baseLayout,\n dragState.id,\n dragState.origin.x + inlineCells,\n dragState.origin.y + blockCells,\n colsRef.current,\n )\n : resizeItem(\n grabbed.baseLayout,\n dragState.id,\n dragState.origin.w + inlineCells,\n dragState.origin.h + blockCells,\n colsRef.current,\n );\n applyDraft(next);\n };\n const onUp = (event: PointerEvent) => {\n const dragState = pointerDragRef.current;\n if (!dragState || event.pointerId !== dragState.pointerId) return;\n suppressClickRef.current = true;\n endGrab(true);\n };\n const onCancel = (event: PointerEvent) => {\n const dragState = pointerDragRef.current;\n if (!dragState || event.pointerId !== dragState.pointerId) return;\n suppressClickRef.current = true;\n endGrab(false);\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n window.addEventListener('pointercancel', onCancel);\n return () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n window.removeEventListener('pointercancel', onCancel);\n };\n }, [grab, endGrab, applyDraft]);\n\n // Escape cancels ANY in-flight grab wherever focus currently is (APG:\n // the cancel key must work for the whole operation, not only while the\n // grabbed handle keeps focus).\n useEffect(() => {\n if (!grab) return undefined;\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') endGrab(false);\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [grab, endGrab]);\n\n // A keyboard grab that loses focus is cancelled (never leave the board\n // in a half-grabbed state).\n useEffect(() => {\n if (!grab || grab.via !== 'keyboard') return undefined;\n const onFocusOut = (event: FocusEvent) => {\n const next = event.relatedTarget as Node | null;\n if (!next || !gridRef.current?.contains(next)) endGrab(false);\n };\n const node = gridRef.current;\n node?.addEventListener('focusout', onFocusOut);\n return () => node?.removeEventListener('focusout', onFocusOut);\n }, [grab, endGrab]);\n\n /* ---- container CSS vars ---------------------------------------- */\n useIsomorphicLayoutEffect(() => {\n const node = gridRef.current;\n if (!node) return;\n node.style.setProperty('--dg-cols', String(cols));\n node.style.setProperty('--dg-row', `${rowHeight}px`);\n }, [cols, rowHeight]);\n\n // Edit-mode surface metrics. The cell-line gradients and the spare-row\n // min height depend on runtime values (cols, rowHeight, occupied rows),\n // so they flow through custom properties like the coordinates do.\n const visibleRows = rowCount(active);\n useIsomorphicLayoutEffect(() => {\n const node = gridRef.current;\n if (!node) return;\n node.style.setProperty(\n '--dg-grid-lines',\n `repeating-linear-gradient(to right, color-mix(in srgb, var(--border) 50%, transparent) 0 1px, transparent 1px calc((100% + var(--spacing-md)) / ${cols})), ` +\n `repeating-linear-gradient(to bottom, color-mix(in srgb, var(--border) 50%, transparent) 0 1px, transparent 1px calc(${rowHeight}px + var(--spacing-md)))`,\n );\n node.style.setProperty(\n '--dg-min-block',\n `calc(${visibleRows + 2} * (${rowHeight}px + var(--spacing-md)) - var(--spacing-md))`,\n );\n }, [cols, rowHeight, visibleRows]);\n\n /* ---- add tile placement ---------------------------------------- */\n const addTileRef = useRef<HTMLDivElement>(null);\n const showAddTile = editing && Boolean(onRequestAdd);\n const addSpot = useMemo(\n () => (showAddTile ? firstFit(active, cols, 2, 2) : null),\n [showAddTile, active, cols],\n );\n useIsomorphicLayoutEffect(() => {\n const node = addTileRef.current;\n if (!node || !addSpot) return;\n node.style.setProperty('--dg-x', String(addSpot.x + 1));\n node.style.setProperty('--dg-y', String(addSpot.y + 1));\n node.style.setProperty('--dg-w', '2');\n node.style.setProperty('--dg-h', '2');\n }, [addSpot]);\n\n /* ---- remove flow ------------------------------------------------ */\n const requestRemove = useCallback(\n (widgetId: string) => {\n // The kit owns the entry removal (single commit) and the focus\n // recovery — the consumer only unmounts the child. Without this a\n // keyboard user's focus falls to <body> when the button unmounts.\n commit(\n normalise(\n resolvedRef.current.filter((entry) => entry.id !== widgetId),\n colsRef.current,\n ),\n );\n setAnnouncement(t('dashboardGrid.removed'));\n onRemoveWidget?.(widgetId);\n requestAnimationFrame(() => {\n const root = gridRef.current;\n if (!root) return;\n const nextFocus = root.querySelector<HTMLButtonElement>('button');\n if (nextFocus) nextFocus.focus();\n else root.focus();\n });\n },\n [commit, onRemoveWidget, t],\n );\n\n /* ---- imperative handle / agent --------------------------------- */\n const agentHandle = useMemo<DashboardGridHandle>(\n () => ({\n moveWidgetTo(widgetId, x, y) {\n if (!editing) return false;\n if (!Number.isFinite(x) || !Number.isFinite(y)) return false;\n if (!resolved.some((item) => item.id === widgetId)) return false;\n // Round: fractional cells produce invalid grid-column values.\n commit(\n normalise(\n moveItem(resolved, widgetId, Math.round(x), Math.round(y), cols),\n cols,\n ),\n );\n return true;\n },\n resizeWidgetTo(widgetId, w, h) {\n if (!editing) return false;\n if (!Number.isFinite(w) || !Number.isFinite(h)) return false;\n if (!resolved.some((item) => item.id === widgetId)) return false;\n commit(\n normalise(\n resizeItem(\n resolved,\n widgetId,\n Math.round(w),\n Math.round(h),\n cols,\n ),\n cols,\n ),\n );\n return true;\n },\n getGridState() {\n return {\n cols,\n editing,\n layout: resolved.map((item) => ({ ...item })),\n };\n },\n }),\n [editing, resolved, cols, commit],\n );\n useImperativeHandle(ref, () => agentHandle, [agentHandle]);\n useAgentRegistration(dashboardGridAgent, agentHandle, id);\n\n const contextValue = useMemo<DashboardGridContextValue>(\n () => ({\n editing,\n layoutById,\n grab,\n canRemove: Boolean(onRemoveWidget),\n requestRemove,\n startKeyboardGrab,\n keyboardStep,\n startPointerGrab,\n }),\n [\n editing,\n layoutById,\n grab,\n onRemoveWidget,\n requestRemove,\n startKeyboardGrab,\n keyboardStep,\n startPointerGrab,\n ],\n );\n\n return (\n <div\n data-component=\"dashboard-grid\"\n data-component-id={id}\n data-editing={editing || undefined}\n className={`ds:block ds:w-full ${className ?? ''}`.trim()}\n >\n <div role=\"status\" aria-live=\"polite\" className=\"ds:sr-only\">\n {announcement}\n </div>\n <div\n ref={gridRef}\n role=\"list\"\n aria-label={ariaLabel}\n tabIndex={-1}\n data-editing={editing || undefined}\n className={dashboardGridVariants()}\n >\n <DashboardGridContext.Provider value={contextValue}>\n {children}\n </DashboardGridContext.Provider>\n {showAddTile ? (\n // role=\"list\" allows only listitem children — the tile wrapper\n // carries the grid placement, the button fills it.\n <div\n ref={addTileRef}\n role=\"listitem\"\n className={[\n 'ds:flex',\n 'ds:[grid-column-start:var(--dg-x)] ds:[grid-column-end:span_var(--dg-w)]',\n 'ds:[grid-row-start:var(--dg-y)] ds:[grid-row-end:span_var(--dg-h)]',\n ].join(' ')}\n >\n <button\n type=\"button\"\n onClick={onRequestAdd}\n className={[\n 'ds:flex ds:flex-1 ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)]',\n 'ds:rounded-[var(--radius-lg)] ds:border ds:border-dashed ds:border-border',\n 'ds:text-sm ds:text-muted-foreground ds:transition-colors',\n 'ds:hover:bg-muted/10 ds:hover:text-foreground',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring',\n ].join(' ')}\n >\n <Plus aria-hidden=\"true\" className=\"ds:size-4\" />\n {t('dashboardGrid.add')}\n </button>\n </div>\n ) : null}\n </div>\n </div>\n );\n },\n);\nDashboardGridRoot.displayName = 'DashboardGrid';\n\nexport const DashboardGrid = Object.assign(DashboardGridRoot, {\n Widget: DashboardGridWidget,\n});\n"],"names":["__iconNode","MoveDiagonal2","createLucideIcon","dashboardGridAgent","handle","args","collides","a","b","clampRect","item","cols","minW","minH","maxW","maxH","w","h","x","y","normalise","layout","activeId","items","order","placed","active","above","p","test","byId","moveItem","id","next","resizeItem","firstFit","width","maxY","m","candidate","rowCount","dashboardGridVariants","cva","widgetVariants","DashboardGridContext","createContext","forEachWidgetChild","children","fn","Children","child","isValidElement","Fragment","DashboardGridWidget","title","actionsSlot","t","useTranslation","ctx","useContext","wrapperRef","useRef","entry","useIsomorphicLayoutEffect","node","grabbed","_a","editing","jsxs","jsx","IconButton","GripVertical","_b","event","X","_c","DashboardGridRoot","forwardRef","ariaLabel","rowHeight","layoutProp","defaultLayout","onLayoutChange","onRemoveWidget","onRequestAdd","className","ref","gridRef","childIds","useMemo","ids","childMeta","meta","internalLayout","setInternalLayout","useState","committed","commit","useCallback","resolved","autoPlaced","clamped","missing","cid","spot","reportedRef","useEffect","signature","draft","setDraft","grab","setGrab","announcement","setAnnouncement","draftRef","grabRef","pointerDragRef","suppressClickRef","colsRef","resolvedRef","applyDraft","beginGrab","kind","widgetId","via","state","layoutById","announceEntry","endGrab","commitDraft","current","final","signatureOf","e","landed","startKeyboardGrab","keyboardStep","isRtl","inlineDelta","blockDelta","moved","startPointerGrab","gridNode","rect","styles","gap","rowGap","colWidth","_d","onMove","dragState","dxPx","dyPx","inlineCells","blockCells","onUp","onCancel","onKeyDown","onFocusOut","visibleRows","addTileRef","showAddTile","addSpot","requestRemove","root","nextFocus","agentHandle","useImperativeHandle","useAgentRegistration","contextValue","Plus","DashboardGrid"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"date-range-picker-BOvHwWO5.js","sources":["../../node_modules/date-fns/subWeeks.js","../../node_modules/date-fns/subYears.js","../../src/components/date-range-picker/date-range-picker.agent.ts","../../src/components/date-range-picker/date-range-picker.tsx"],"sourcesContent":["import { addWeeks } from \"./addWeeks.js\";\n\n/**\n * The {@link subWeeks} function options.\n */\n\n/**\n * @name subWeeks\n * @category Week Helpers\n * @summary Subtract the specified number of weeks from the given date.\n *\n * @description\n * Subtract the specified number of weeks from the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The date to be changed\n * @param amount - The amount of weeks to be subtracted.\n * @param options - An object with options\n *\n * @returns The new date with the weeks subtracted\n *\n * @example\n * // Subtract 4 weeks from 1 September 2014:\n * const result = subWeeks(new Date(2014, 8, 1), 4)\n * //=> Mon Aug 04 2014 00:00:00\n */\nexport function subWeeks(date, amount, options) {\n return addWeeks(date, -amount, options);\n}\n\n// Fallback for modularized imports:\nexport default subWeeks;\n","import { addYears } from \"./addYears.js\";\n\n/**\n * The {@link subYears} function options.\n */\n\n/**\n * @name subYears\n * @category Year Helpers\n * @summary Subtract the specified number of years from the given date.\n *\n * @description\n * Subtract the specified number of years from the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The date to be changed\n * @param amount - The amount of years to be subtracted.\n * @param options - An object with options\n *\n * @returns The new date with the years subtracted\n *\n * @example\n * // Subtract 5 years from 1 September 2014:\n * const result = subYears(new Date(2014, 8, 1), 5)\n * //=> Tue Sep 01 2009 00:00:00\n */\nexport function subYears(date, amount, options) {\n return addYears(date, -amount, options);\n}\n\n// Fallback for modularized imports:\nexport default subYears;\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — DateRangePicker. */\n/* */\n/* DateRangePicker wraps react-day-picker (range mode) inside a Radix */\n/* Popover. The agent surface curates the trigger + popover into range */\n/* operations — set / clear / open / close, commit (apply / cancel), and */\n/* the Range Cockpit config (set_granularity / toggle_compare + read-only */\n/* granularity + compareRange state). */\n/* */\n/* See `src/docs/26-agent-readiness.mdx` §15. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DateRangePickerHandle } from './date-range-picker';\n\nexport const dateRangePickerAgent: AgentAdapter<DateRangePickerHandle> = {\n id: 'date-range-picker',\n capabilities: [\n 'range_pick',\n 'open',\n 'close',\n 'confirm', // apply — commit the draft range\n 'dismiss', // cancel — discard the draft\n 'set_value', // set_granularity + compare_toggle\n ],\n state: {\n range: {\n type: '{ from: iso-date | null, to: iso-date | null }',\n descriptionKey: 'ui.agent.dateRangePicker.state.range',\n description:\n 'Currently-selected ISO date range endpoints, each possibly null.',\n read: (handle) => {\n const range = handle.getRange();\n return {\n from: range.from?.toISOString() ?? null,\n to: range.to?.toISOString() ?? null,\n };\n },\n },\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dateRangePicker.state.isOpen',\n description: 'Whether the range calendar popover is open.',\n read: (handle) => handle.isOpen(),\n },\n granularity: {\n type: \"'day' | 'week' | 'month' | 'quarter' | null\",\n descriptionKey: 'ui.agent.dateRangePicker.state.granularity',\n description:\n 'Selected time granularity (Range Cockpit), or null when the control is disabled.',\n read: (handle) => handle.getGranularity() ?? null,\n },\n compareRange: {\n type: '{ from: iso-date | null, to: iso-date | null } | null',\n descriptionKey: 'ui.agent.dateRangePicker.state.compareRange',\n description:\n 'Resolved comparison period when compare-to-previous-period is on, else null.',\n read: (handle) => {\n const compare = handle.getCompareRange();\n if (!compare) return null;\n return {\n from: compare.from?.toISOString() ?? null,\n to: compare.to?.toISOString() ?? null,\n };\n },\n },\n },\n actions: {\n set_range: {\n safety: 'write',\n argsType: '{ from: string, to: string }',\n argsSchema: {\n type: 'object',\n properties: {\n from: {\n type: 'string',\n format: 'date',\n description: 'ISO start date (inclusive).',\n },\n to: {\n type: 'string',\n format: 'date',\n description: 'ISO end date (inclusive).',\n },\n },\n required: ['from', 'to'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.setRange',\n description: 'Replace the selected range with the given ISO endpoints.',\n examples: [\n {\n args: { from: '2026-06-01', to: '2026-06-30' },\n note: 'Select all of June 2026.',\n },\n ],\n invoke: (handle, args: { from: string; to: string }) => {\n handle.setRange({ from: new Date(args.from), to: new Date(args.to) });\n },\n },\n clear: {\n // Discards the selected range — loses the user's input.\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.clear',\n description: 'Clear the selected range.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.open',\n description: 'Open the range calendar popover.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.close',\n description: 'Close the range calendar popover.',\n invoke: (handle) => {\n handle.close();\n },\n },\n apply: {\n // Commits the current draft — in `commitMode=\"apply\"` this is what runs\n // the downstream query, so it is a write, not read.\n safety: 'write',\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.apply',\n description:\n 'Commit the current draft range (as the Apply / Done button).',\n invoke: (handle) => {\n handle.apply();\n },\n },\n cancel: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.cancel',\n description: 'Discard the draft and close without committing.',\n invoke: (handle) => {\n handle.cancel();\n },\n },\n set_granularity: {\n safety: 'write',\n argsType: \"{ granularity: 'day' | 'week' | 'month' | 'quarter' }\",\n argsSchema: {\n type: 'object',\n properties: {\n granularity: {\n type: 'string',\n enum: ['day', 'week', 'month', 'quarter'],\n description: 'Time grain to query the range at.',\n },\n },\n required: ['granularity'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.setGranularity',\n description: 'Set the time granularity (Range Cockpit).',\n examples: [{ args: { granularity: 'month' }, note: 'Query by month.' }],\n invoke: (\n handle,\n args: { granularity: 'day' | 'week' | 'month' | 'quarter' },\n ) => {\n handle.setGranularity(args.granularity);\n },\n },\n toggle_compare: {\n safety: 'write',\n argsType: '{ enabled: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n enabled: {\n type: 'boolean',\n description: 'Whether to compare against the previous period.',\n },\n },\n required: ['enabled'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dateRangePicker.actions.toggleCompare',\n description: 'Turn compare-to-previous-period on or off (Range Cockpit).',\n examples: [\n { args: { enabled: true }, note: 'Enable period comparison.' },\n ],\n invoke: (handle, args: { enabled: boolean }) => {\n handle.setCompare(args.enabled);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'date-range-picker',\n description: 'Marks the DateRangePicker wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","import {\n forwardRef,\n Fragment,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type KeyboardEvent,\n} from 'react';\nimport { type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport * as Popover from '@radix-ui/react-popover';\nimport * as RadioGroup from '@radix-ui/react-radio-group';\nimport { Spinner } from '../spinner';\nimport { useDayPickerLabels } from '../_shared/day-picker-labels';\nimport { DayPicker, type DateRange } from 'react-day-picker';\nimport {\n format as fnsFormat,\n parse as fnsParse,\n isValid,\n isAfter,\n isBefore,\n differenceInCalendarDays,\n isSameDay,\n addDays,\n subDays,\n subWeeks,\n subYears,\n startOfWeek,\n endOfWeek,\n startOfMonth,\n endOfMonth,\n} from 'date-fns';\nimport { CalendarDays, Check } from 'lucide-react';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport {\n useFormField,\n useFormFieldControlId,\n} from '../form-field/form-field-context';\nimport {\n useDateFnsLocale,\n getShortDateFormat,\n buildDisabledMatcher,\n CalendarChevron,\n calendarClassNames,\n calendarCompareModifierClassNames,\n triggerVariants,\n calendarIconVariants,\n popoverContentVariants,\n presetButtonVariants,\n rangeFieldVariants,\n rangeActionVariants,\n granularityGroupVariants,\n granularityItemVariants,\n presetGroupHeadingVariants,\n} from '../_shared';\nimport { Switch } from '../switch';\nimport { useAgentRegistration } from '../../agent';\nimport { dateRangePickerAgent } from './date-range-picker.agent';\n\n/* -------------------------------------------------------------------------- */\n/* Props */\n/* -------------------------------------------------------------------------- */\n\nexport interface DateRangePreset {\n label: string;\n range: () => { from: Date; to: Date };\n /** Optional group name — presets sharing a group render under one sub-heading. */\n group?: string;\n}\n\nexport interface DateRangeValue {\n from?: Date;\n to?: Date;\n}\n\n/** Time grain the range is queried at (Range Cockpit). */\nexport type DateRangeGranularity = 'day' | 'week' | 'month' | 'quarter';\n\n/** How the comparison period is derived from the selected range. */\nexport type DateRangeCompareMode = 'previous' | 'lastYear';\n\n/** Extra data emitted alongside a committed range (Range Cockpit). */\nexport interface DateRangeApplyMeta {\n granularity?: DateRangeGranularity;\n compareRange?: DateRangeValue;\n}\n\n/** Curated imperative handle exposed via `ref` — also consumed by the agent adapter. */\nexport interface DateRangePickerHandle {\n /** Get the current selected range. */\n getRange: () => DateRangeValue;\n /** Replace the selected range. */\n setRange: (range: DateRangeValue) => void;\n /** Clear the selected range. */\n clear: () => void;\n /** Whether the popover is open. */\n isOpen: () => boolean;\n /** Open the range calendar popover. */\n open: () => void;\n /** Close the range calendar popover. */\n close: () => void;\n /** Current granularity, or undefined when the control is disabled. */\n getGranularity: () => DateRangeGranularity | undefined;\n /** Set the time granularity. */\n setGranularity: (granularity: DateRangeGranularity) => void;\n /** Current comparison period, or undefined when compare is off/incomplete. */\n getCompareRange: () => DateRangeValue | undefined;\n /** Turn compare-to-previous-period on or off. */\n setCompare: (enabled: boolean) => void;\n /** Label of the preset matching the committed range, or undefined for a custom range. */\n getActivePreset: () => string | undefined;\n /** Which endpoint the next calendar click will set, or null when the draft is complete. */\n getActiveEnd: () => 'start' | 'end' | null;\n /** Commit the current draft (as the Apply / Done button does). */\n apply: () => void;\n /** Discard the draft and close (as Cancel / Escape does). */\n cancel: () => void;\n}\n\nexport interface DateRangePickerProps extends Pick<\n VariantProps<typeof triggerVariants>,\n 'size'\n> {\n /** Current range — controlled. */\n value?: DateRangeValue;\n /** Default range — uncontrolled. */\n defaultValue?: DateRangeValue;\n /**\n * Called when the range is committed. In `commitMode=\"auto\"` (default) this\n * fires the instant the range becomes COMPLETE (both ends) — never on a\n * start-only partial. In `commitMode=\"apply\"` it fires once, on Apply.\n */\n onChange?: (range: DateRangeValue) => void;\n /**\n * Commit model.\n * - `'auto'` (default): manual selection updates a popover-local draft and\n * commits (`onChange`) the moment both ends exist; the popover stays open so\n * the user can refine, and the footer's Done button dismisses it. A preset\n * commits and closes. Right for cheap client-side filters.\n * - `'apply'`: every edit (presets, calendar, typed fields) mutates the draft\n * only; nothing commits until the Apply button. Escape / outside-click /\n * Cancel revert to the last committed value. Right for expensive queries\n * that must not fire on a half-picked range.\n */\n commitMode?: 'auto' | 'apply';\n /**\n * Called when the range is committed by a decisive action that CLOSES the\n * popover — a preset click, or the Apply button. Completing a range on the\n * calendar in `'auto'` mode fires `onChange` but keeps the popover open, so it\n * does not fire `onApply`. The optional second argument carries the Range\n * Cockpit metadata (granularity + resolved comparison range) when enabled.\n */\n onApply?: (range: DateRangeValue, meta?: DateRangeApplyMeta) => void;\n /** Called when an `'apply'`-mode edit is cancelled (Cancel / Escape / dismiss). */\n onCancel?: () => void;\n /** Show the footer Clear action. Defaults to `true`. */\n showClear?: boolean;\n /** Number of month grids to render. Defaults to `2`. */\n numberOfMonths?: number;\n /**\n * Shrink the popover for a tight host — a grid column filter, a toolbar. One\n * month instead of two, no title, no preset rail. The trigger is unaffected;\n * use `size` for that.\n */\n compact?: boolean;\n /**\n * Range Cockpit — granularity. Passing `granularity` (controlled) or\n * `defaultGranularity` (uncontrolled) shows a Day / Week / Month / Quarter\n * segmented control in the header and names the queried grain.\n */\n granularity?: DateRangeGranularity;\n defaultGranularity?: DateRangeGranularity;\n onGranularityChange?: (granularity: DateRangeGranularity) => void;\n /**\n * Restrict the granularity segmented control to a subset of\n * `'day' | 'week' | 'month' | 'quarter'` — e.g. `['month', 'quarter']` for\n * data with a coarser grain. Options always render in canonical\n * Day → Quarter order regardless of the array order passed. Defaults to all\n * four (an empty array is treated as all four). Only meaningful when the\n * Cockpit granularity control is enabled (via `granularity` /\n * `defaultGranularity`) — it does not enable the control on its own. A\n * `defaultGranularity` or controlled `granularity` outside the allowed set is\n * clamped to the first allowed option.\n */\n allowedGranularities?: DateRangeGranularity[];\n /**\n * Range Cockpit — compare. When `true`, a compare-to-previous-period toggle\n * appears; enabling it overlays a neutral secondary band on the calendar and\n * (on Apply) reports the resolved comparison range via `onApply` meta and\n * `onCompareChange`.\n */\n compare?: boolean;\n /**\n * Controlled checked state of the compare toggle — the APPLIED compare\n * on/off value. Pair with `onCompareChange` and drive it from the consumer\n * so a reopened picker reflects the applied state. When omitted the toggle\n * is uncontrolled and seeded from `defaultCompare`. This is distinct from\n * `compare`, which only decides whether the control renders. Only\n * meaningful when `compare` is set.\n */\n compareEnabled?: boolean;\n /** Start with compare enabled — uncontrolled initial checked state (only meaningful when `compare` is set). */\n defaultCompare?: boolean;\n defaultCompareMode?: DateRangeCompareMode;\n onCompareChange?: (enabled: boolean, compareRange?: DateRangeValue) => void;\n /** Week start (0 = Sunday). Defaults to the locale's first day. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /** Minimum selectable date. */\n minDate?: Date;\n /** Maximum selectable date. */\n maxDate?: Date;\n /** Custom presets. Replaces defaults unless mergePresets is true. */\n presets?: DateRangePreset[];\n /** Merge custom presets with defaults instead of replacing. */\n mergePresets?: boolean;\n /** Component size. */\n size?: 'sm' | 'md' | 'lg';\n /**\n * Trigger chrome. `'input'` (default) is the soft input look — fill + the\n * `--shadow-input` halo — that matches other form fields. `'button'` renders\n * the trigger as an outline Button (flat, `--radius-md`, no halo, `md` = 40px)\n * so the picker sits flush among Buttons in a toolbar. Use `'button'` only in\n * toolbars, not in forms: the input chrome's `--control-border` edge marks\n * the field at 3:1 (WCAG 1.4.11), whereas a button-chrome trigger relies on\n * its value/label like a Button does.\n */\n chrome?: 'input' | 'button';\n /** Disabled state. */\n disabled?: boolean;\n /** Placeholder text. */\n placeholder?: string;\n /** Additional class names. */\n className?: string;\n /** id override. */\n id?: string;\n}\n\nconst GRANULARITY_OPTIONS: {\n value: DateRangeGranularity;\n fallback: string;\n}[] = [\n { value: 'day', fallback: 'Day' },\n { value: 'week', fallback: 'Week' },\n { value: 'month', fallback: 'Month' },\n { value: 'quarter', fallback: 'Quarter' },\n];\n\nconst COMPARE_MODE_OPTIONS: {\n value: DateRangeCompareMode;\n fallback: string;\n}[] = [\n { value: 'previous', fallback: 'Previous period' },\n { value: 'lastYear', fallback: 'Same period last year' },\n];\n\n/* -------------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------------- */\n\nexport const DateRangePicker = forwardRef<\n DateRangePickerHandle,\n DateRangePickerProps\n>(\n (\n {\n value,\n defaultValue,\n onChange,\n commitMode = 'auto',\n onApply,\n onCancel,\n showClear = true,\n numberOfMonths,\n compact = false,\n granularity: granularityProp,\n defaultGranularity,\n onGranularityChange,\n allowedGranularities,\n compare = false,\n compareEnabled,\n defaultCompare = false,\n defaultCompareMode = 'previous',\n onCompareChange,\n weekStartsOn,\n minDate,\n maxDate,\n presets: presetsProp,\n mergePresets = false,\n size = 'md',\n chrome = 'input',\n disabled,\n placeholder,\n className,\n id,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const ctx = useFormField();\n const effectiveId = useFormFieldControlId(ctx, id);\n const effectiveDisabled = ctx.disabled || disabled;\n const effectiveTone = ctx.invalid ? 'error' : 'default';\n\n const locale = useDateFnsLocale(i18n.language);\n const calendarLabels = useDayPickerLabels();\n const dateFormat = getShortDateFormat(i18n.language);\n const placeholderText =\n placeholder ??\n t('inputs.dateRangePicker.placeholder', 'Select date range');\n\n const [currentValueRaw, setDateRangeValue] =\n useControllableState<DateRangeValue>({\n value,\n defaultValue: defaultValue ?? {},\n onChange,\n });\n const currentValue: DateRangeValue = currentValueRaw ?? {};\n\n const [open, setOpen] = useState(false);\n // Popover-local draft — the working range while the popover is open. In\n // `auto` it commits to `currentValue` the moment it is complete; in `apply`\n // it stays local until Apply. Seeded from the committed value on open.\n const [draft, setDraft] = useState<DateRangeValue>(currentValue);\n const [month, setMonth] = useState<Date>(currentValue.from ?? new Date());\n\n // Editable endpoint field text + parse-error flags.\n const [startText, setStartText] = useState('');\n const [endText, setEndText] = useState('');\n const [startInvalid, setStartInvalid] = useState(false);\n const [endInvalid, setEndInvalid] = useState(false);\n\n // Range Cockpit state (all opt-in; the default picker never renders these).\n const granularityEnabled =\n granularityProp !== undefined || defaultGranularity !== undefined;\n // Restrict the granularity control to an allowed subset (default = all four;\n // an empty array is treated as \"all\"). Filtering GRANULARITY_OPTIONS keeps\n // the canonical Day → Quarter order no matter what order the consumer passes.\n const allowedGranularitySet =\n allowedGranularities && allowedGranularities.length > 0\n ? allowedGranularities\n : undefined;\n const visibleGranularityOptions = allowedGranularitySet\n ? GRANULARITY_OPTIONS.filter((o) =>\n allowedGranularitySet.includes(o.value),\n )\n : GRANULARITY_OPTIONS;\n const clampGranularity = (g: DateRangeGranularity): DateRangeGranularity =>\n !allowedGranularitySet || allowedGranularitySet.includes(g)\n ? g\n : (visibleGranularityOptions[0]?.value ?? g);\n const [granularity, setGranularity] =\n useControllableState<DateRangeGranularity>({\n value: granularityProp,\n defaultValue: clampGranularity(defaultGranularity ?? 'day'),\n onChange: onGranularityChange,\n });\n // The clamped granularity actually shown / reported — guards a controlled\n // `granularity` prop that sits outside the allowed set. Equal to\n // `granularity` when unrestricted, so default output is unchanged.\n const resolvedGranularity = clampGranularity(granularity ?? 'day');\n // Committed compare state — controllable, mirrors `value`/`granularity`.\n // This is the APPLIED compare on/off; the consumer drives it via the\n // `compareEnabled` prop so a reopened picker reflects the applied state.\n const [committedCompare, setCommittedCompare] =\n useControllableState<boolean>({\n value: compareEnabled,\n defaultValue: defaultCompare,\n // onCompareChange needs the resolved range as its 2nd arg, so it is\n // called manually at the commit points rather than wired here.\n });\n // Draft compare toggle — the working state while the popover is open,\n // seeded from `committedCompare` on open. Binds to the Switch so an\n // apply-mode flip shows immediately without committing.\n const [draftCompare, setDraftCompare] = useState<boolean>(\n committedCompare ?? false,\n );\n const [compareMode, setCompareMode] =\n useState<DateRangeCompareMode>(defaultCompareMode);\n\n const triggerRef = useRef<HTMLButtonElement>(null);\n // Set true immediately before a commit-and-close so the close handler does\n // not also fire the `apply`-mode cancel path.\n const committingRef = useRef(false);\n\n const monthsShown = numberOfMonths ?? (compact ? 1 : 2);\n const titleId = useId();\n const startFieldId = useId();\n const endFieldId = useId();\n const gridLabelId = useId();\n const errorId = useId();\n // The compare Switch gets its OWN id so — inside a FormField — it does not\n // inherit the field's id (which would clash with / steal the trigger label).\n const compareId = useId();\n\n const emit = useCallback(\n (range: DateRangeValue) => {\n setDateRangeValue(range);\n },\n [setDateRangeValue],\n );\n\n const disabledMatcher = buildDisabledMatcher(minDate, maxDate);\n\n // `buildDisabledMatcher` returns an rdp Matcher (for the grid), not a\n // predicate — so validate a TYPED endpoint against min/max directly.\n const isDateBlocked = (d: Date): boolean =>\n (minDate ? isBefore(d, minDate) : false) ||\n (maxDate ? isAfter(d, maxDate) : false);\n\n // Seed the draft from the committed value whenever the popover opens —\n // works for both the Radix trigger and the imperative handle / agent\n // `open()`, and resets any stale parse-error state.\n useEffect(() => {\n if (open) {\n setDraft(currentValue);\n // Re-seed the draft compare toggle from the committed (applied) value so\n // a reopened picker reflects the applied compare state — the fix for the\n // toggle silently resetting to OFF on reopen / remount.\n setDraftCompare(committedCompare ?? false);\n setStartInvalid(false);\n setEndInvalid(false);\n // Clear the commit guard on EVERY open transition (trigger, imperative\n // handle, agent) so a later Escape / outside-dismiss still runs the\n // apply-mode cancel path even if the last close was a commit.\n committingRef.current = false;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- seed only on the open transition; must not re-seed as currentValue changes mid-edit\n }, [open]);\n\n // Keep the visible field text in sync with the draft (e.g. after a calendar\n // click or a preset), unless the user is mid-typing an invalid value.\n useEffect(() => {\n if (!startInvalid) {\n setStartText(\n draft.from ? fnsFormat(draft.from, dateFormat, { locale }) : '',\n );\n }\n if (!endInvalid) {\n setEndText(draft.to ? fnsFormat(draft.to, dateFormat, { locale }) : '');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- text follows the draft; invalid flags gate the overwrite intentionally\n }, [draft.from, draft.to, dateFormat, locale]);\n\n // Default presets\n const defaultPresets: DateRangePreset[] = [\n {\n label: t('inputs.dateRangePicker.presets.today', 'Today'),\n range: () => {\n const today = new Date();\n return { from: today, to: today };\n },\n },\n {\n label: t('inputs.dateRangePicker.presets.yesterday', 'Yesterday'),\n range: () => {\n const yesterday = subDays(new Date(), 1);\n return { from: yesterday, to: yesterday };\n },\n },\n {\n label: t('inputs.dateRangePicker.presets.last7', 'Last 7 days'),\n range: () => ({\n from: subDays(new Date(), 6),\n to: new Date(),\n }),\n },\n {\n label: t('inputs.dateRangePicker.presets.thisWeek', 'This week'),\n range: () => ({\n // `weekStartsOn` (when set) overrides the locale's first day; when\n // undefined date-fns falls back to the locale.\n from: startOfWeek(new Date(), { locale, weekStartsOn }),\n to: endOfWeek(new Date(), { locale, weekStartsOn }),\n }),\n },\n {\n label: t('inputs.dateRangePicker.presets.lastWeek', 'Last week'),\n range: () => {\n const lastWeekDay = subWeeks(new Date(), 1);\n return {\n from: startOfWeek(lastWeekDay, { locale, weekStartsOn }),\n to: endOfWeek(lastWeekDay, { locale, weekStartsOn }),\n };\n },\n },\n {\n label: t('inputs.dateRangePicker.presets.thisMonth', 'This month'),\n range: () => ({\n from: startOfMonth(new Date()),\n to: endOfMonth(new Date()),\n }),\n },\n {\n label: t('inputs.dateRangePicker.presets.last30', 'Last 30 days'),\n range: () => ({\n from: subDays(new Date(), 29),\n to: new Date(),\n }),\n },\n ];\n\n const effectivePresets = presetsProp\n ? mergePresets\n ? [...defaultPresets, ...presetsProp]\n : presetsProp\n : defaultPresets;\n\n // Preset groups (Range Cockpit grouped rail). If no preset declares a\n // `group`, this collapses to a single unnamed group == the flat list.\n const presetGroups = (() => {\n const order: string[] = [];\n const byGroup = new Map<string, DateRangePreset[]>();\n for (const preset of effectivePresets) {\n const key = preset.group ?? '';\n if (!byGroup.has(key)) {\n byGroup.set(key, []);\n order.push(key);\n }\n byGroup.get(key)!.push(preset);\n }\n return order.map((key) => ({ group: key, presets: byGroup.get(key)! }));\n })();\n const hasPresetGroups = presetGroups.some((g) => g.group !== '');\n\n // Derive the comparison period from a base range. `mode` defaults to the\n // current state, but callers that are ALSO changing the mode pass the new\n // value explicitly (React state updates are async, so the closure would\n // otherwise still see the old mode).\n const computeCompareRange = (\n base: DateRangeValue,\n mode: DateRangeCompareMode = compareMode,\n ): DateRangeValue | undefined => {\n if (!base.from || !base.to) return undefined;\n if (mode === 'lastYear') {\n // Shift back one year. (For a selected range longer than a year the\n // comparison would overlap the primary band; that is an unusual\n // period-over-period selection and is left as-is.)\n return { from: subYears(base.from, 1), to: subYears(base.to, 1) };\n }\n // 'previous': same length, immediately before the start.\n const length = differenceInCalendarDays(base.to, base.from);\n const to = subDays(base.from, 1);\n return { from: subDays(to, length), to };\n };\n\n // Draft-scoped: working compare state while the popover is open — drives\n // the calendar band, preview chip, mode radios, and the Apply meta.\n const draftCompareActive = compare && draftCompare;\n // Committed-scoped: applied compare state — drives the imperative handle's\n // getCompareRange (read from the committed `currentValue`).\n const committedCompareActive = compare && (committedCompare ?? false);\n const draftCompareRange = draftCompareActive\n ? computeCompareRange(draft)\n : undefined;\n const compareModifiers:\n | Record<string, Date | { from: Date; to: Date }>\n | undefined = (() => {\n if (!draftCompareRange?.from || !draftCompareRange.to) return undefined;\n const from = draftCompareRange.from;\n const to = draftCompareRange.to;\n const mods: Record<string, Date | { from: Date; to: Date }> = {\n compareStart: from,\n compareEnd: to,\n };\n // Only add the middle band for spans of 3+ days. For a 1-2 day span the\n // start/end caps fully describe it, and an inverted middle range\n // ({from: from+1, to: to-1}) would be SWAPPED by rdp and paint cells\n // outside the comparison period (including the selected day).\n if (differenceInCalendarDays(to, from) >= 2) {\n mods.compareMiddle = { from: addDays(from, 1), to: subDays(to, 1) };\n }\n return mods;\n })();\n\n const applyMeta = (\n base: DateRangeValue,\n ): DateRangeApplyMeta | undefined => {\n const meta: DateRangeApplyMeta = {};\n if (granularityEnabled) meta.granularity = resolvedGranularity;\n if (draftCompareActive) meta.compareRange = computeCompareRange(base);\n return meta.granularity || meta.compareRange ? meta : undefined;\n };\n\n const handleCompareModeChange = (v: string) => {\n const mode = v as DateRangeCompareMode;\n setCompareMode(mode);\n // Report the recomputed comparison range for the newly-selected mode.\n // In apply mode the mode change rides Apply (applyMeta re-reads the\n // updated `compareMode`), so only auto mode reports it immediately.\n if (draftCompareActive && commitMode === 'auto') {\n onCompareChange?.(true, computeCompareRange(draft, mode));\n }\n };\n\n const handleCompareToggle = (next: boolean) => {\n // Always update the working draft so the Switch reflects the flip.\n setDraftCompare(next);\n // `auto` commits immediately (like a completed range); `apply` keeps it\n // a draft until Apply, so nothing commits early.\n if (commitMode === 'auto') {\n setCommittedCompare(next);\n onCompareChange?.(next, next ? computeCompareRange(draft) : undefined);\n }\n };\n\n /**\n * Update the draft. In `auto` mode, commit the instant the range is\n * complete (both ends) — and NEVER on a start-only partial, which removes\n * the old half-open `{from, to:undefined}` emit.\n */\n const updateDraft = useCallback(\n (next: DateRangeValue) => {\n setDraft(next);\n if (commitMode === 'auto' && next.from && next.to) {\n emit(next);\n }\n },\n [commitMode, emit],\n );\n\n const handleRangeSelect = (range: DateRange | undefined) => {\n // Picking on the calendar clears any stale typed-field parse error.\n setStartInvalid(false);\n setEndInvalid(false);\n updateDraft({ from: range?.from, to: range?.to });\n };\n\n const handlePresetClick = (preset: DateRangePreset) => {\n const range = preset.range();\n setStartInvalid(false);\n setEndInvalid(false);\n setDraft(range);\n setMonth(range.from);\n if (commitMode === 'auto') {\n emit(range);\n onApply?.(range, applyMeta(range));\n committingRef.current = true;\n setOpen(false);\n }\n };\n\n /** Parse + apply one typed endpoint, keeping `from <= to`. */\n const commitField = (which: 'from' | 'to', text: string) => {\n const setInvalid = which === 'from' ? setStartInvalid : setEndInvalid;\n if (text.trim() === '') {\n setInvalid(false);\n updateDraft(\n which === 'from'\n ? { from: undefined, to: draft.to }\n : { from: draft.from, to: undefined },\n );\n return;\n }\n const parsed = fnsParse(text, dateFormat, new Date(), { locale });\n if (!isValid(parsed) || isDateBlocked(parsed)) {\n setInvalid(true);\n return;\n }\n setInvalid(false);\n let next: DateRangeValue;\n if (which === 'from') {\n next =\n draft.to && isAfter(parsed, draft.to)\n ? { from: parsed, to: undefined }\n : { from: parsed, to: draft.to };\n } else {\n next =\n draft.from && isAfter(draft.from, parsed)\n ? { from: parsed, to: undefined }\n : { from: draft.from, to: parsed };\n }\n setMonth(parsed);\n updateDraft(next);\n };\n\n const handleFieldKeyDown =\n (which: 'from' | 'to') => (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commitField(which, which === 'from' ? startText : endText);\n }\n };\n\n const handleClear = () => {\n setDraft({});\n setStartInvalid(false);\n setEndInvalid(false);\n if (commitMode === 'auto') {\n emit({});\n }\n };\n\n // The draft can be applied when it is a COMPLETE range or fully EMPTY\n // (so Clear -> Apply can commit a cleared range) — but not a half-picked\n // `{ from, to:undefined }` partial.\n const draftComplete = Boolean(draft.from && draft.to);\n const draftEmpty = !draft.from && !draft.to;\n // Block the commit while a typed field is showing a parse error, so Apply\n // can't silently save the last-valid range while the user sees an error.\n const canApply =\n (draftComplete || draftEmpty) && !startInvalid && !endInvalid;\n\n const handleApply = () => {\n if (canApply) {\n emit(draft);\n // Commit the draft compare toggle (apply-mode defers it here) and\n // report it once, with its resolved range, alongside the range Apply.\n if (compare && draftCompare !== (committedCompare ?? false)) {\n setCommittedCompare(draftCompare);\n onCompareChange?.(\n draftCompare,\n draftCompare ? computeCompareRange(draft) : undefined,\n );\n }\n onApply?.(draft, applyMeta(draft));\n }\n committingRef.current = true;\n setOpen(false);\n };\n\n const handleDone = () => {\n committingRef.current = true;\n setOpen(false);\n };\n\n // Programmatic `setOpen(false)` does NOT call Radix's `onOpenChange`, so the\n // Cancel button reverts explicitly (only Escape / outside-dismiss flows\n // through `handleOpenChange`).\n const handleCancel = () => {\n if (commitMode === 'apply') {\n onCancel?.();\n }\n setDraft(currentValue);\n setDraftCompare(committedCompare ?? false);\n setOpen(false);\n };\n\n const handleOpenChange = (next: boolean) => {\n if (next) {\n // Opening — the draft is seeded by the `open` effect below (which also\n // covers opening via the imperative handle / agent, not just Radix).\n committingRef.current = false;\n setOpen(true);\n return;\n }\n // Closing. A dismiss (Escape / outside-click) that is NOT one of our\n // commit buttons reverts the draft in `apply` mode.\n if (commitMode === 'apply' && !committingRef.current) {\n onCancel?.();\n }\n setDraft(currentValue);\n setDraftCompare(committedCompare ?? false);\n committingRef.current = false;\n setOpen(false);\n };\n\n // A preset is \"active\" when the committed range matches the range it would\n // produce (same calendar day at both ends) — so the highlighted band and\n // its shortcut visibly agree, and a custom range simply matches nothing.\n const isPresetActive = (preset: DateRangePreset): boolean => {\n if (!currentValue.from || !currentValue.to) return false;\n const range = preset.range();\n return (\n isSameDay(range.from, currentValue.from) &&\n isSameDay(range.to, currentValue.to)\n );\n };\n\n // Dedup coincident presets: when several presets resolve to the SAME\n // committed range (e.g. \"This month\" and \"This quarter\" both start on the\n // 1st in a quarter's first month), only the FIRST in consumer order is\n // marked active — one predictable highlight. This is the same first-match\n // rule `getActivePreset()` already reports, so the visual state and the\n // imperative handle never diverge. `effectivePresets` is the flat consumer\n // array; `presetGroups` regroups the SAME object references for display, so\n // an object-identity compare in the render loop is sound within a render.\n const activePreset = effectivePresets.find(isPresetActive);\n\n // Trigger label reflects the COMMITTED value (locale-aware short format).\n const displayText = (() => {\n if (currentValue.from && currentValue.to) {\n const fromStr = fnsFormat(currentValue.from, dateFormat, { locale });\n const toStr = fnsFormat(currentValue.to, dateFormat, { locale });\n return `${fromStr} – ${toStr}`;\n }\n if (currentValue.from) {\n return fnsFormat(currentValue.from, dateFormat, { locale });\n }\n return '';\n })();\n\n // Which endpoint the next calendar click will set — drives the field ring\n // and the guidance line.\n const activeEnd: 'start' | 'end' | null = !draft.from\n ? 'start'\n : !draft.to\n ? 'end'\n : null;\n\n // Footer live-region text: selection guidance until complete, then the full\n // localised summary (dates + day count), never a bare number.\n const summaryText = (() => {\n if (!draft.from) {\n return t('inputs.dateRangePicker.selectStart', 'Select start date');\n }\n if (!draft.to) {\n return t('inputs.dateRangePicker.selectEnd', 'Select end date');\n }\n // Compose the summary with a PLURALISED day count (via the `days_*`\n // plural keys) so the live region reads \"… · 1 day\" / \"… · 15 days\"\n // grammatically, rather than the \"{{count}} day(s)\" literal.\n const days = differenceInCalendarDays(draft.to, draft.from) + 1;\n const fromStr = fnsFormat(draft.from, dateFormat, { locale });\n const toStr = fnsFormat(draft.to, dateFormat, { locale });\n const daysLabel = t('inputs.dateRangePicker.days', { count: days });\n return `${fromStr} – ${toStr} · ${daysLabel}`;\n })();\n\n // A live pointer to the render-scoped values the imperative handle reads,\n // so the handle object stays STABLE (agent registers once) while always\n // reflecting current state.\n const liveRef = useRef({\n currentValue,\n open,\n getGranularity: (): DateRangeGranularity | undefined =>\n granularityEnabled ? resolvedGranularity : undefined,\n setGranularity: (g: DateRangeGranularity): void =>\n setGranularity(clampGranularity(g)),\n getCompareRange: (): DateRangeValue | undefined =>\n committedCompareActive ? computeCompareRange(currentValue) : undefined,\n // Imperative/agent path commits directly (like setRange/clear), so\n // toggle_compare reflects in getCompareRange immediately — not a draft.\n setCompare: (enabled: boolean): void => {\n setDraftCompare(enabled);\n setCommittedCompare(enabled);\n onCompareChange?.(\n enabled,\n enabled ? computeCompareRange(currentValue) : undefined,\n );\n },\n getActivePreset: (): string | undefined => activePreset?.label,\n getActiveEnd: (): 'start' | 'end' | null => activeEnd,\n apply: () => handleApply(),\n cancel: () => handleCancel(),\n });\n liveRef.current = {\n currentValue,\n open,\n getGranularity: () =>\n granularityEnabled ? resolvedGranularity : undefined,\n setGranularity: (g: DateRangeGranularity) =>\n setGranularity(clampGranularity(g)),\n getCompareRange: () =>\n committedCompareActive ? computeCompareRange(currentValue) : undefined,\n setCompare: (enabled: boolean) => {\n setDraftCompare(enabled);\n setCommittedCompare(enabled);\n onCompareChange?.(\n enabled,\n enabled ? computeCompareRange(currentValue) : undefined,\n );\n },\n getActivePreset: () => activePreset?.label,\n getActiveEnd: () => activeEnd,\n apply: () => handleApply(),\n cancel: () => handleCancel(),\n };\n\n const handle = useMemo<DateRangePickerHandle>(\n () => ({\n getRange: () => liveRef.current.currentValue,\n setRange: (range) => emit(range),\n clear: () => emit({}),\n isOpen: () => liveRef.current.open,\n open: () => setOpen(true),\n close: () => setOpen(false),\n getGranularity: () => liveRef.current.getGranularity(),\n setGranularity: (g) => liveRef.current.setGranularity(g),\n getCompareRange: () => liveRef.current.getCompareRange(),\n setCompare: (enabled) => liveRef.current.setCompare(enabled),\n getActivePreset: () => liveRef.current.getActivePreset(),\n getActiveEnd: () => liveRef.current.getActiveEnd(),\n apply: () => liveRef.current.apply(),\n cancel: () => liveRef.current.cancel(),\n }),\n [emit],\n );\n\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(dateRangePickerAgent, handle, effectiveId);\n\n const fieldState = (which: 'from' | 'to') => {\n if (which === 'from') {\n return startInvalid\n ? 'error'\n : activeEnd === 'start'\n ? 'active'\n : 'default';\n }\n return endInvalid ? 'error' : activeEnd === 'end' ? 'active' : 'default';\n };\n\n return (\n <Popover.Root open={open} onOpenChange={handleOpenChange}>\n <div\n className={className}\n data-component=\"date-range-picker\"\n data-component-id={effectiveId}\n >\n <Popover.Trigger asChild disabled={effectiveDisabled}>\n {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props -- FormField propagates invalid state to its trigger; users rely on this for validation announcements */}\n <button\n ref={triggerRef}\n id={effectiveId}\n type=\"button\"\n disabled={effectiveDisabled}\n aria-describedby={ctx.describedBy || undefined}\n aria-invalid={ctx.invalid || undefined}\n // `aria-required` is not valid on `<button>` per ARIA 1.2 — the\n // FormField label's visible asterisk + `aria-describedby` link\n // communicate the required state instead.\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n className={triggerVariants({ size, tone: effectiveTone, chrome })}\n >\n <span\n className={[\n // Truncate so a long value/placeholder ellipsises instead of\n // running under the absolutely-positioned calendar icon (the\n // trigger reserves the icon's space via `pe-10`). `min-w-0`\n // lets the flex child shrink below its content width so\n // `truncate` engages.\n 'ds:min-w-0 ds:flex-1 ds:truncate ds:text-start',\n displayText\n ? 'ds:text-foreground'\n : 'ds:text-muted-foreground',\n ].join(' ')}\n >\n {displayText || placeholderText}\n </span>\n <span\n aria-hidden=\"true\"\n className={calendarIconVariants({ size })}\n >\n <CalendarDays />\n </span>\n </button>\n </Popover.Trigger>\n\n <Popover.Portal>\n <Popover.Content\n sideOffset={4}\n align=\"start\"\n role=\"dialog\"\n // Name the dialog with a direct `aria-label` rather than\n // `aria-labelledby` to the header title — the cross-reference did\n // not resolve reliably on the Radix-portaled content in a real\n // browser (axe `aria-dialog-name`), whereas a literal label is\n // read directly. The visible `<h2>` title still repeats it.\n aria-label={t(\n 'inputs.dateRangePicker.title',\n 'Select date range',\n )}\n /* Portaled outside [data-component] scope — needs its own\n marker for the kit's font/scrollbar/cascade baselines\n (same idiom as `select-content` / `date-picker-content`). */\n data-component=\"date-range-picker-content\"\n className={popoverContentVariants()}\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Header — title + editable Start / End endpoints */}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n {/* Kept in the a11y tree either way — the dialog's own\n aria-label repeats it, so hiding it visually costs no\n naming. */}\n <h2\n id={titleId}\n className={\n compact\n ? 'ds:sr-only'\n : 'type-body-sm ds:font-semibold ds:text-foreground'\n }\n >\n {t('inputs.dateRangePicker.title', 'Select date range')}\n </h2>\n {granularityEnabled ? (\n <RadioGroup.Root\n value={resolvedGranularity}\n onValueChange={(v) =>\n setGranularity(\n clampGranularity(v as DateRangeGranularity),\n )\n }\n aria-label={t(\n 'inputs.dateRangePicker.granularityLabel',\n 'Granularity',\n )}\n className={granularityGroupVariants()}\n >\n {visibleGranularityOptions.map((o) => (\n <RadioGroup.Item\n key={o.value}\n value={o.value}\n className={granularityItemVariants()}\n >\n {t(\n `inputs.dateRangePicker.granularity.${o.value}`,\n o.fallback,\n )}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n ) : null}\n </div>\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-xs)]\">\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label\n htmlFor={startFieldId}\n className=\"ds:text-[length:var(--font-size-xs)] ds:text-muted-foreground\"\n >\n {t('inputs.dateRangePicker.startLabel', 'Start date')}\n </label>\n <input\n id={startFieldId}\n type=\"text\"\n inputMode=\"numeric\"\n value={startText}\n placeholder={dateFormat.toUpperCase()}\n aria-invalid={startInvalid || undefined}\n aria-describedby={startInvalid ? errorId : undefined}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n setStartText(e.target.value)\n }\n onBlur={(e) => commitField('from', e.target.value)}\n onKeyDown={handleFieldKeyDown('from')}\n className={rangeFieldVariants({\n state: fieldState('from'),\n })}\n />\n </div>\n <span\n aria-hidden=\"true\"\n className=\"ds:pb-[var(--spacing-xs)] ds:text-muted-foreground\"\n >\n {'–'}\n </span>\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label\n htmlFor={endFieldId}\n className=\"ds:text-[length:var(--font-size-xs)] ds:text-muted-foreground\"\n >\n {t('inputs.dateRangePicker.endLabel', 'End date')}\n </label>\n <input\n id={endFieldId}\n type=\"text\"\n inputMode=\"numeric\"\n value={endText}\n placeholder={dateFormat.toUpperCase()}\n aria-invalid={endInvalid || undefined}\n aria-describedby={endInvalid ? errorId : undefined}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n setEndText(e.target.value)\n }\n onBlur={(e) => commitField('to', e.target.value)}\n onKeyDown={handleFieldKeyDown('to')}\n className={rangeFieldVariants({\n state: fieldState('to'),\n })}\n />\n </div>\n </div>\n {startInvalid || endInvalid ? (\n <p\n id={errorId}\n role=\"alert\"\n className=\"ds:text-[length:var(--font-size-xs)] ds:text-destructive\"\n >\n {t(\n 'inputs.dateRangePicker.invalidDate',\n 'Enter a date as {{format}}',\n {\n format: dateFormat.toUpperCase(),\n },\n )}\n </p>\n ) : null}\n </div>\n\n {/* Body — presets + dual calendar */}\n <div className=\"ds:flex ds:gap-[var(--spacing-md)]\">\n {!compact && effectivePresets.length > 0 ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:min-w-[8rem] ds:border-e ds:border-border ds:pe-[var(--spacing-md)]\">\n {presetGroups.map((grp, gi) => {\n const headingId = `${titleId}-pg${gi}`;\n const buttons = grp.presets.map((preset) => {\n // Identity compare against the single deduped active\n // preset — coincident presets collapse to one highlight.\n const active = preset === activePreset;\n return (\n <button\n key={preset.label}\n type=\"button\"\n aria-pressed={active}\n onClick={() => handlePresetClick(preset)}\n className={presetButtonVariants({ active })}\n >\n <span className=\"ds:min-w-0 ds:truncate\">\n {preset.label}\n </span>\n {active ? (\n <Check\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-primary\"\n />\n ) : null}\n </button>\n );\n });\n // A named group is a labelled `role=\"group\"` so the\n // visual grouping is conveyed to assistive tech.\n if (hasPresetGroups && grp.group) {\n return (\n <div\n key={grp.group}\n role=\"group\"\n aria-labelledby={headingId}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <div\n id={headingId}\n className={presetGroupHeadingVariants()}\n >\n {grp.group}\n </div>\n {buttons}\n </div>\n );\n }\n return (\n <Fragment key={grp.group || '_ungrouped'}>\n {buttons}\n </Fragment>\n );\n })}\n </div>\n ) : null}\n\n <div role=\"region\" aria-labelledby={gridLabelId}>\n <span id={gridLabelId} className=\"ds:sr-only\">\n {t('inputs.dateRangePicker.gridLabel', 'Calendar')}\n </span>\n {locale ? (\n <DayPicker\n mode=\"range\"\n selected={\n draft.from\n ? { from: draft.from, to: draft.to }\n : undefined\n }\n onSelect={handleRangeSelect}\n month={month}\n onMonthChange={setMonth}\n numberOfMonths={monthsShown}\n weekStartsOn={weekStartsOn}\n disabled={disabledMatcher}\n locale={locale}\n labels={calendarLabels}\n dir={i18n.dir()}\n showOutsideDays\n fixedWeeks\n pagedNavigation\n classNames={calendarClassNames}\n modifiers={compareModifiers}\n modifiersClassNames={calendarCompareModifierClassNames}\n components={{ Chevron: CalendarChevron }}\n />\n ) : (\n <Spinner />\n )}\n </div>\n </div>\n\n {/* Compare-to-previous-period row (Range Cockpit) */}\n {compare ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)] ds:border-t ds:border-border ds:pt-[var(--spacing-sm)]\">\n <Switch\n id={compareId}\n label={t(\n 'inputs.dateRangePicker.compareLabel',\n 'Compare to previous period',\n )}\n size=\"sm\"\n checked={draftCompare}\n onCheckedChange={handleCompareToggle}\n />\n {draftCompareActive && draftCompareRange ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-[length:var(--font-size-xs)] ds:text-muted-foreground\">\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-block ds:size-3 ds:rounded-[calc(var(--radius-sm)-2px)] ds:bg-[var(--calendar-compare-fill)] ds:border-b-2 ds:border-dashed ds:border-b-[var(--calendar-compare-edge)]\"\n />\n {`${fnsFormat(draftCompareRange.from as Date, dateFormat, { locale })} – ${fnsFormat(draftCompareRange.to as Date, dateFormat, { locale })}`}\n </span>\n ) : null}\n {draftCompare ? (\n <RadioGroup.Root\n value={compareMode}\n onValueChange={handleCompareModeChange}\n aria-label={t(\n 'inputs.dateRangePicker.compareModeLabel',\n 'Comparison period',\n )}\n className={`${granularityGroupVariants()} ds:ms-auto`}\n >\n {COMPARE_MODE_OPTIONS.map((o) => (\n <RadioGroup.Item\n key={o.value}\n value={o.value}\n className={granularityItemVariants()}\n >\n {t(\n `inputs.dateRangePicker.compareMode.${o.value}`,\n o.fallback,\n )}\n </RadioGroup.Item>\n ))}\n </RadioGroup.Root>\n ) : null}\n </div>\n ) : null}\n\n {/* Footer — persistent live summary + actions */}\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-md)] ds:border-t ds:border-border ds:pt-[var(--spacing-sm)]\">\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"type-body-sm ds:min-w-0 ds:truncate ds:text-muted-foreground\"\n >\n {summaryText}\n </div>\n <div className=\"ds:flex ds:shrink-0 ds:gap-[var(--spacing-xs)]\">\n {showClear ? (\n <button\n type=\"button\"\n onClick={handleClear}\n className={rangeActionVariants({ intent: 'ghost' })}\n >\n {t('inputs.dateRangePicker.clear', 'Clear')}\n </button>\n ) : null}\n {commitMode === 'apply' ? (\n <>\n <button\n type=\"button\"\n onClick={handleCancel}\n className={rangeActionVariants({ intent: 'ghost' })}\n >\n {t('inputs.dateRangePicker.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n disabled={!canApply}\n onClick={handleApply}\n className={rangeActionVariants({ intent: 'primary' })}\n >\n {t('inputs.dateRangePicker.apply', 'Apply')}\n </button>\n </>\n ) : (\n <button\n type=\"button\"\n onClick={handleDone}\n className={rangeActionVariants({ intent: 'primary' })}\n >\n {t('inputs.dateRangePicker.done', 'Done')}\n </button>\n )}\n </div>\n </div>\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Root>\n );\n },\n);\n\nDateRangePicker.displayName = 'DateRangePicker';\n"],"names":["subWeeks","date","amount","options","addWeeks","subYears","addYears","dateRangePickerAgent","handle","range","_a","_b","compare","args","GRANULARITY_OPTIONS","COMPARE_MODE_OPTIONS","DateRangePicker","forwardRef","value","defaultValue","onChange","commitMode","onApply","onCancel","showClear","numberOfMonths","compact","granularityProp","defaultGranularity","onGranularityChange","allowedGranularities","compareEnabled","defaultCompare","defaultCompareMode","onCompareChange","weekStartsOn","minDate","maxDate","presetsProp","mergePresets","size","chrome","disabled","placeholder","className","id","ref","t","i18n","useTranslation","ctx","useFormField","effectiveId","useFormFieldControlId","effectiveDisabled","effectiveTone","locale","useDateFnsLocale","calendarLabels","useDayPickerLabels","dateFormat","getShortDateFormat","placeholderText","currentValueRaw","setDateRangeValue","useControllableState","currentValue","open","setOpen","useState","draft","setDraft","month","setMonth","startText","setStartText","endText","setEndText","startInvalid","setStartInvalid","endInvalid","setEndInvalid","granularityEnabled","allowedGranularitySet","visibleGranularityOptions","o","clampGranularity","g","granularity","setGranularity","resolvedGranularity","committedCompare","setCommittedCompare","draftCompare","setDraftCompare","compareMode","setCompareMode","triggerRef","useRef","committingRef","monthsShown","titleId","useId","startFieldId","endFieldId","gridLabelId","errorId","compareId","emit","useCallback","disabledMatcher","buildDisabledMatcher","isDateBlocked","d","isBefore","isAfter","useEffect","fnsFormat","defaultPresets","today","yesterday","subDays","startOfWeek","endOfWeek","lastWeekDay","startOfMonth","endOfMonth","effectivePresets","presetGroups","order","byGroup","preset","key","hasPresetGroups","computeCompareRange","base","mode","length","differenceInCalendarDays","to","draftCompareActive","committedCompareActive","draftCompareRange","compareModifiers","from","mods","addDays","applyMeta","meta","handleCompareModeChange","v","handleCompareToggle","next","updateDraft","handleRangeSelect","handlePresetClick","commitField","which","text","setInvalid","parsed","fnsParse","isValid","handleFieldKeyDown","e","handleClear","draftComplete","draftEmpty","canApply","handleApply","handleDone","handleCancel","handleOpenChange","isPresetActive","isSameDay","activePreset","displayText","fromStr","toStr","activeEnd","summaryText","days","daysLabel","liveRef","enabled","useMemo","useImperativeHandle","useAgentRegistration","fieldState","Popover","jsxs","jsx","triggerVariants","calendarIconVariants","CalendarDays","popoverContentVariants","RadioGroup","granularityGroupVariants","granularityItemVariants","rangeFieldVariants","grp","gi","headingId","buttons","active","presetButtonVariants","Check","presetGroupHeadingVariants","Fragment","DayPicker","calendarClassNames","calendarCompareModifierClassNames","CalendarChevron","Spinner","Switch","rangeActionVariants"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dependent-selector-Bet3XAFj.js","sources":["../../src/components/dependent-selector/dependent-selector.agent.ts","../../src/components/dependent-selector/dependent-selector.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — DependentSelector. */\n/* */\n/* Mirrors radio-group.agent.ts: a single-select domain control. The */\n/* selected person id is the externally-observable state; `select_single` */\n/* is the capability. Per-row `data-option-id` lets an agent address each */\n/* person by their stable opaque id. */\n/* */\n/* See `src/docs/26-agent-readiness.mdx` for the contract. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { DependentSelectorHandle } from './dependent-selector';\n\nexport const dependentSelectorAgent: AgentAdapter<DependentSelectorHandle> = {\n id: 'dependent-selector',\n capabilities: ['select_single'],\n state: {\n value: {\n type: 'string',\n descriptionKey: 'ui.agent.dependentSelector.state.value',\n description:\n 'Id of the currently selected person, or empty string when none.',\n read: (handle) => handle.getValue(),\n },\n },\n actions: {\n set_value: {\n safety: 'write',\n argsType: '{ value: string }',\n argsSchema: {\n type: 'object',\n properties: {\n value: {\n type: 'string',\n description: 'Stable opaque id of the person row to select.',\n },\n },\n required: ['value'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.dependentSelector.actions.setValue',\n description: 'Select the person row with the given id.',\n examples: [\n { args: { value: 'person-2' }, note: 'Select the second dependent.' },\n ],\n invoke: (handle, args: { value: string }) => {\n handle.setValue(args.value);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'dependent-selector',\n description: 'Marks the DependentSelector root (role=radiogroup).',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-option-id',\n description: 'Stable person id emitted on each rendered person row.',\n },\n },\n};\n","import {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\nimport * as RadixRadioGroup from '@radix-ui/react-radio-group';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { CircleAlert } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Avatar } from '../avatar';\nimport { Badge } from '../badge';\nimport { Tooltip } from '../tooltip';\nimport { useDirection } from '../_shared/use-direction';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useAgentRegistration } from '../../agent';\nimport { dependentSelectorAgent } from './dependent-selector.agent';\n\n/* -------------------------------------------------------------------- */\n/* DependentSelector */\n/* */\n/* Single-select roster of people — the verified guardian (\"You\") plus */\n/* their registered dependents/minors — that a check-in kiosk uses to */\n/* answer \"Who are you checking in?\". Built on Radix RadioGroup semantics */\n/* (role=radiogroup, single tab stop, roving arrow-key focus, one */\n/* selected value), mirroring the proven src/components/radio-group/ */\n/* pattern. Each option is a person row (Avatar + name + relationship + */\n/* optional age/Minor badge) wrapped in a <label> so the whole card is */\n/* the click target. */\n/* */\n/* The kit owns the localised relationship + age strings via the closed */\n/* `relationshipKey` enum — consumers pass data, never free-text labels, */\n/* or i18n/RTL breaks. `age` is display-only (pre-computed whole years); */\n/* `isMinor` is an explicit per-person flag, NOT age<18 inference. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\n/**\n * Closed relationship vocabulary. The kit owns the localised label for\n * each key (`dependentSelector.relationship.<key>`). `'other'` is the\n * escape hatch for relationships the enum doesn't model.\n */\nexport type DependentRelationship =\n | 'self'\n | 'son'\n | 'daughter'\n | 'child'\n | 'spouse'\n | 'parent'\n | 'sibling'\n | 'ward'\n | 'other';\n\nexport interface DependentSelectorPerson {\n /** Stable id — becomes the radio value + `data-option-id`. */\n id: string;\n /** Display-formatted name (already formatted by the consumer). */\n name: string;\n /** Closed relationship key — the kit owns the localised label. */\n relationshipKey: DependentRelationship;\n /**\n * Explicit \"minor\" flag — drives the localised \"Minor\" badge.\n * Consumer-supplied, NOT derived from `age < 18` (legal age of\n * majority varies by market).\n */\n isMinor?: boolean;\n /** Avatar image source — falls back to initials, then icon. */\n avatarSrc?: string;\n /** Whole years, pre-computed by the consumer. Display-only. */\n age?: number;\n /**\n * ISO 8601 date of birth. Used ONLY for the row title/tooltip — never\n * parsed for display math (timezone/locale birthday math is the\n * consumer's job).\n */\n dob?: string;\n /** Disables this row; skipped by arrow navigation. */\n disabled?: boolean;\n /** Shown in a Tooltip on the disabled row (like Radio.disabledReason). */\n disabledReason?: string;\n}\n\n/** Agent-readiness curated handle for DependentSelector. */\nexport interface DependentSelectorHandle {\n getValue: () => string;\n setValue: (value: string) => void;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:min-w-0',\n {\n variants: {\n size: { sm: '', md: '', lg: '' },\n tone: { default: '', checkin: '' },\n },\n defaultVariants: { size: 'md', tone: 'checkin' },\n },\n);\n\nconst rowVariants = cva(\n [\n // The row IS the Radix Item (`<button role=\"radio\">`). Reset the\n // button chrome, lay out avatar + text on the inline axis. Logical\n // properties only.\n 'ds:group ds:flex ds:items-center ds:gap-[var(--spacing-md)] ds:w-full ds:text-start ds:appearance-none',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-border ds:bg-card',\n // Touch-target floor: even sm clears AA/AAA (44 → 48px in accessible).\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n // Selected state: low-alpha accent tint BEHIND tokenised text +\n // a ring-coloured border (never accent as a foreground meeting text).\n 'ds:data-[state=checked]:border-ring',\n // Roving focus ring on the item itself — single tab stop, arrow keys\n // move focus+selection.\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n // Forced-colours: repaint a ButtonBorder edge + a Highlight checked\n // edge + a CanvasText focus ring so the row + its checked state\n // survive Windows High Contrast Mode.\n 'ds:forced-colors:border-[ButtonBorder]',\n 'ds:forced-colors:data-[state=checked]:border-[Highlight]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-md)] ds:py-[var(--spacing-xs)]',\n md: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:py-[var(--spacing-sm)]',\n lg: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-lg)] ds:py-[var(--spacing-md)]',\n },\n tone: {\n // Neutral RadioGroup-card tint for plain forms.\n default:\n 'ds:data-[state=checked]:bg-[color-mix(in_srgb,var(--accent)_5%,transparent)]',\n // Accent-tinted selected surface tuned for the check-in kiosk —\n // slightly stronger low-alpha mix BEHIND the tokenised foreground.\n checkin:\n 'ds:data-[state=checked]:bg-[color-mix(in_srgb,var(--accent)_8%,transparent)]',\n },\n disabled: {\n true: 'ds:cursor-not-allowed ds:opacity-50',\n false:\n 'ds:cursor-pointer ds:hover:bg-[color-mix(in_srgb,var(--accent)_4%,transparent)]',\n },\n },\n defaultVariants: { size: 'md', tone: 'checkin', disabled: false },\n },\n);\n\nconst avatarSizeBySize = { sm: 'sm', md: 'md', lg: 'lg' } as const;\n\n// Keep the loading skeleton's avatar footprint in lock-step with the real\n// Avatar scale (sm=size-8 / md=size-10 / lg=size-12) so the roster\n// resolving in doesn't shift the row height.\nconst skeletonAvatarSizeBySize = {\n sm: 'ds:size-8',\n md: 'ds:size-10',\n lg: 'ds:size-12',\n} as const;\n\nconst nameTypeBySize = {\n sm: 'type-body-sm',\n md: 'type-label',\n lg: 'type-body',\n} as const;\n\n/* -------------------------------------------------------------------- */\n/* Props */\n/* -------------------------------------------------------------------- */\n\ntype RadixRootProps = ComponentPropsWithoutRef<typeof RadixRadioGroup.Root>;\n\nexport interface DependentSelectorProps\n extends\n Omit<\n RadixRootProps,\n 'children' | 'orientation' | 'value' | 'defaultValue' | 'onValueChange'\n >,\n VariantProps<typeof rootVariants> {\n /** Ordered roster to render as options. */\n people: DependentSelectorPerson[];\n /** Controlled selected person id. */\n value?: string;\n /** Uncontrolled initial selection. Ignored when `value` is set. */\n defaultValue?: string;\n /** Fires with the newly selected person id on user selection. */\n onValueChange?: (personId: string) => void;\n /** Accessible group name, rendered as the `<legend>`. */\n label?: string;\n /** Optional helper paragraph under the legend (wired via aria-describedby). */\n description?: string;\n /** Shows N skeleton rows while the roster resolves; sets aria-busy. */\n loading?: boolean;\n /** Validation/empty-confirmation message — role=alert + aria-invalid. */\n error?: string;\n /** Slot shown when no selectable dependents exist (only self / empty). */\n emptyState?: ReactNode;\n /** Forwarded to the radiogroup root as id + data-component-id. */\n id?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const DependentSelector = forwardRef<\n HTMLDivElement,\n DependentSelectorProps\n>(\n (\n {\n people,\n value,\n defaultValue,\n onValueChange,\n label,\n description,\n size: sizeProp = 'md',\n tone: toneProp = 'checkin',\n loading = false,\n error,\n emptyState,\n id,\n className,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...props\n },\n ref,\n ) => {\n // CVA's VariantProps types each axis as `T | null | undefined`; the\n // destructure default only covers `undefined`, so coalesce `null`\n // too before the values index the size→class lookup maps.\n const size = sizeProp ?? 'md';\n const tone = toneProp ?? 'checkin';\n const { t } = useTranslation('ui');\n const baseId = useId();\n const legendId = `${baseId}-legend`;\n const descriptionId = `${baseId}-description`;\n const errorId = `${baseId}-error`;\n\n /* ---- Dev-mode accessible-name enforcement ---- */\n const warnedRef = useRef(false);\n useEffect(() => {\n if (\n import.meta.env.DEV &&\n !warnedRef.current &&\n !label &&\n !ariaLabel &&\n !ariaLabelledBy\n ) {\n warnedRef.current = true;\n console.warn(\n '<DependentSelector> rendered without an accessible name. Pass `label`, or `aria-label` / `aria-labelledby`, so the radiogroup is never unnamed.',\n );\n }\n }, [label, ariaLabel, ariaLabelledBy]);\n\n /* ---- Selectable roster + single-selectable auto-select ---- */\n const selectablePeople = useMemo(\n () => people.filter((person) => !person.disabled),\n [people],\n );\n // The dependents region (everything that isn't the verified self row)\n // drives the empty-state slot.\n const hasDependents = people.some(\n (person) => person.relationshipKey !== 'self',\n );\n const autoSelectId =\n selectablePeople.length === 1 ? selectablePeople[0].id : undefined;\n\n /* ---- Controlled / uncontrolled value handling (mirrors RadioGroup) ---- */\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string>(\n defaultValue ?? autoSelectId ?? '',\n );\n const currentValue = isControlled ? (value ?? '') : internalValue;\n const currentValueRef = useRef<string>(currentValue);\n currentValueRef.current = currentValue;\n\n const handleValueChange = (next: string) => {\n if (loading) return;\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n };\n\n /* ---- Auto-select change notification ---- */\n /* When exactly one selectable person exists we seed the uncontrolled */\n /* selection (Radix `defaultValue` + internal state) so the row */\n /* paints checked — but Radix never fires onValueChange for a */\n /* defaultValue. In the kiosk consent flow the consumer wires the */\n /* consent audit trail off onValueChange, so we fire it once on mount */\n /* for that auto-selection. Only when uncontrolled, not loading, and */\n /* the consumer didn't pass an explicit defaultValue. */\n const onValueChangeRef = useRef(onValueChange);\n onValueChangeRef.current = onValueChange;\n const autoSelectNotifiedRef = useRef(false);\n useEffect(() => {\n if (\n !autoSelectNotifiedRef.current &&\n !isControlled &&\n !loading &&\n defaultValue === undefined &&\n autoSelectId !== undefined\n ) {\n autoSelectNotifiedRef.current = true;\n onValueChangeRef.current?.(autoSelectId);\n }\n }, [isControlled, loading, defaultValue, autoSelectId]);\n\n /* ---- Agent registration ---- */\n const agentHandle = useMemo<DependentSelectorHandle>(\n () => ({\n getValue: () => currentValueRef.current,\n setValue: (next) => handleValueChange(next),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [isControlled, loading, onValueChange],\n );\n useAgentRegistration(dependentSelectorAgent, agentHandle, id);\n\n /* ---- Direction (Radix auto-flips Left/Right for rtl) ---- */\n const rootRef = useRef<HTMLDivElement>(null);\n const composedRef = composeRefs(ref, rootRef);\n const dir = useDirection(rootRef);\n\n /* ---- Resolved a11y wiring ---- */\n /* ONE grouping mechanism: when `label` is set we render a plain */\n /* heading <div id={legendId}> (NOT a native <fieldset>/<legend>) and */\n /* name the single role=radiogroup via aria-labelledby. A fieldset */\n /* would add a second, redundant named group nested around the */\n /* radiogroup — so we deliberately avoid it. */\n const resolvedAriaLabelledBy =\n ariaLabelledBy ?? (label ? legendId : undefined);\n const describedBy =\n [description ? descriptionId : null, error ? errorId : null]\n .filter(Boolean)\n .join(' ') || undefined;\n\n /* ---- Helpers ---- */\n const relationshipLabel = (key: DependentRelationship): string =>\n t(`dependentSelector.relationship.${key}`);\n\n const ageLabel = (age: number): string =>\n t('dependentSelector.age', { count: age });\n\n /** Compose the full accessible name a screen reader announces. */\n const personAccessibleName = (person: DependentSelectorPerson): string => {\n const base = t('dependentSelector.optionLabel', {\n name: person.name,\n relationship: relationshipLabel(person.relationshipKey),\n });\n const parts = [base];\n if (typeof person.age === 'number') parts.push(ageLabel(person.age));\n if (person.isMinor) parts.push(t('dependentSelector.minorBadge'));\n return parts.join(', ');\n };\n\n /* ---- Description + error nodes ---- */\n const descriptionNode = description ? (\n <p id={descriptionId} className=\"type-body-sm ds:text-muted-foreground\">\n {description}\n </p>\n ) : null;\n\n const errorNode = error ? (\n <p\n id={errorId}\n role=\"alert\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-destructive\"\n >\n <CircleAlert aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0\" />\n <span>{error}</span>\n </p>\n ) : null;\n\n /* ---- Skeleton rows (loading) ---- */\n const skeletonRows = (\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n {Array.from({ length: 3 }).map((_, index) => (\n <div\n key={index}\n className={rowVariants({ size, tone, disabled: false })}\n >\n <span\n className={`ds:inline-flex ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-muted ds:animate-pulse ${skeletonAvatarSizeBySize[size]}`}\n />\n <span className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:min-w-0 ds:flex-1\">\n <span className=\"ds:h-4 ds:w-1/2 ds:rounded-[var(--radius-sm)] ds:bg-muted ds:animate-pulse\" />\n <span className=\"ds:h-3 ds:w-1/3 ds:rounded-[var(--radius-sm)] ds:bg-muted ds:animate-pulse\" />\n </span>\n </div>\n ))}\n </div>\n );\n\n /* ---- Person row ---- */\n /* The Radix Item IS the card: it renders the `<button role=\"radio\">` */\n /* that owns the roving tabindex + arrow navigation, so the whole row */\n /* is the focus + click target. The composed name lives on */\n /* `aria-label`; the visible content is aria-hidden so a screen reader */\n /* hears the clean composed name once (no duplication). */\n const renderPerson = (person: DependentSelectorPerson) => {\n const rowId = `${baseId}-row-${person.id}`;\n const accessibleName = personAccessibleName(person);\n\n const row = (\n <RadixRadioGroup.Item\n key={person.id}\n id={rowId}\n value={person.id}\n // Native `disabled` is the single disabled model: Radix renders\n // a <button disabled> that is skipped by roving arrow nav and is\n // non-selectable. `aria-disabled` is intentionally NOT also set —\n // on a natively-disabled button it is redundant (it is meant for\n // elements that REMAIN focusable). The disabledReason tooltip is\n // reached via a focusable wrapper span below, not this button.\n disabled={person.disabled}\n aria-label={accessibleName}\n title={person.dob ?? undefined}\n data-option-id={person.id}\n className={rowVariants({\n size,\n tone,\n disabled: Boolean(person.disabled),\n })}\n >\n {/* The Avatar is intentionally aria-hidden: its name only feeds\n initials/colour, and the radio's own aria-label is the sole\n accessible name. Keep aria-hidden so a future refactor doesn't\n reintroduce a duplicate \"image, <name>\" announcement (the kit\n Avatar always renders role=\"img\" + aria-label={name}). */}\n <Avatar\n src={person.avatarSrc}\n name={person.name}\n size={avatarSizeBySize[size]}\n aria-hidden=\"true\"\n />\n <span\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:min-w-0 ds:flex-1\"\n >\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:min-w-0\">\n <span\n className={`${nameTypeBySize[size]} ds:text-foreground ds:truncate ds:min-w-0`}\n >\n {person.name}\n </span>\n {person.isMinor ? (\n // Neutral chip (validated AA ~6:1) — the \"Minor\" flag is\n // informational, not a warning STATE. The tonal `warning`\n // variant fails AA at the small chip font size.\n <Badge variant=\"neutral\" size=\"sm\">\n {t('dependentSelector.minorBadge')}\n </Badge>\n ) : null}\n </span>\n <span className=\"type-body-sm ds:text-muted-foreground ds:truncate ds:min-w-0\">\n {relationshipLabel(person.relationshipKey)}\n {typeof person.age === 'number'\n ? ` · ${ageLabel(person.age)}`\n : null}\n </span>\n </span>\n </RadixRadioGroup.Item>\n );\n\n if (person.disabled && person.disabledReason) {\n // The Radix Item renders a <button disabled>, which is removed\n // from the tab order and does not fire hover/pointer events — so a\n // Tooltip wrapped directly around it would never open. Wrap the row\n // in a focusable, hoverable <span tabIndex={0}> and make THAT the\n // tooltip trigger, so the disabledReason is reachable by both mouse\n // hover and keyboard focus (mirrors radio.tsx putting the Tooltip\n // on the non-disabled wrapper, not the disabled control).\n return (\n <Tooltip key={person.id} label={person.disabledReason}>\n <span\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- intentional focusable tooltip trigger so keyboard users can reach the disabled reason\n tabIndex={0}\n data-disabled-row={person.id}\n aria-label={accessibleName}\n className=\"ds:flex ds:min-w-0 ds:rounded-[var(--radius-md)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]\"\n >\n {row}\n </span>\n </Tooltip>\n );\n }\n return row;\n };\n\n /* ---- Empty-state slot ---- */\n const resolvedEmptyState = emptyState ?? (\n <p className=\"type-body-sm ds:text-muted-foreground\">\n {t('dependentSelector.empty')}\n </p>\n );\n\n /* ---- Radiogroup body ---- */\n /* While loading we still render a role=radiogroup container (carrying */\n /* the data-component marker + aria-busy) holding aria-hidden skeleton */\n /* rows — selection is inert. Otherwise the Radix root renders the */\n /* real person rows. */\n const body = loading ? (\n <div\n ref={composedRef}\n id={id}\n role=\"radiogroup\"\n aria-label={!resolvedAriaLabelledBy ? ariaLabel : undefined}\n aria-labelledby={resolvedAriaLabelledBy}\n aria-describedby={describedBy}\n aria-invalid={Boolean(error) || undefined}\n aria-busy=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:min-w-0\"\n data-component=\"dependent-selector\"\n data-component-id={id}\n >\n <span className=\"ds:sr-only\">\n {t('dependentSelector.loadingLabel')}\n </span>\n {skeletonRows}\n </div>\n ) : (\n <RadixRadioGroup.Root\n ref={composedRef}\n id={id}\n dir={dir}\n value={isControlled ? (value ?? '') : undefined}\n defaultValue={\n !isControlled ? (defaultValue ?? autoSelectId) : undefined\n }\n onValueChange={handleValueChange}\n aria-label={!resolvedAriaLabelledBy ? ariaLabel : undefined}\n aria-labelledby={resolvedAriaLabelledBy}\n aria-describedby={describedBy}\n aria-invalid={Boolean(error) || undefined}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:min-w-0\"\n data-component=\"dependent-selector\"\n data-component-id={id}\n {...props}\n >\n {people.map(renderPerson)}\n </RadixRadioGroup.Root>\n );\n\n /* ---- Outer wrapper ---- */\n /* When `label` is set we render a plain heading <div id={legendId}> */\n /* styled like a legend, and the single role=radiogroup is named via */\n /* aria-labelledby={legendId}. We do NOT wrap in <fieldset>/<legend>: */\n /* that would create a second named grouping container nested around */\n /* the radiogroup (the legend announced twice). One grouping */\n /* mechanism only. */\n const outerClasses = rootVariants({ size, tone, className });\n\n return (\n <div className={outerClasses}>\n {label ? (\n <div id={legendId} className=\"type-label ds:text-foreground\">\n {label}\n </div>\n ) : null}\n {descriptionNode}\n {body}\n {!loading && !hasDependents ? resolvedEmptyState : null}\n {errorNode}\n </div>\n );\n },\n);\n\nDependentSelector.displayName = 'DependentSelector';\n"],"names":["dependentSelectorAgent","handle","args","rootVariants","cva","rowVariants","avatarSizeBySize","skeletonAvatarSizeBySize","nameTypeBySize","DependentSelector","forwardRef","people","value","defaultValue","onValueChange","label","description","sizeProp","toneProp","loading","error","emptyState","id","className","ariaLabel","ariaLabelledBy","props","ref","size","tone","t","useTranslation","baseId","useId","legendId","descriptionId","errorId","useRef","useEffect","selectablePeople","useMemo","person","hasDependents","autoSelectId","isControlled","internalValue","setInternalValue","useState","currentValue","currentValueRef","handleValueChange","next","onValueChangeRef","autoSelectNotifiedRef","_a","agentHandle","useAgentRegistration","rootRef","composedRef","composeRefs","dir","useDirection","resolvedAriaLabelledBy","describedBy","relationshipLabel","key","ageLabel","age","personAccessibleName","parts","descriptionNode","jsx","errorNode","jsxs","CircleAlert","skeletonRows","_","index","renderPerson","rowId","accessibleName","row","RadixRadioGroup","Avatar","Badge","Tooltip","resolvedEmptyState","body","outerClasses"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dialog-D52AI4nF.js","sources":["../../src/components/dialog/dialog.agent.ts","../../src/components/dialog/dialog.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { DialogHandle } from './dialog';\n\n/**\n * Dialog wraps Radix Dialog. The curated handle (`DialogHandle`) bridges the\n * Radix controlled-or-uncontrolled `open` state so an agent can observe and\n * drive the dialog without owning the React state itself.\n */\nexport const dialogAgent: AgentAdapter<DialogHandle> = {\n id: 'dialog',\n capabilities: ['open', 'close', 'dismiss'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.dialog.state.isOpen',\n description: 'True when the dialog is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dialog.actions.open',\n description: 'Open the dialog.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.dialog.actions.close',\n description: 'Close the dialog. Reversible by reopening.',\n invoke: (handle) => {\n handle.close();\n },\n },\n dismiss: {\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.dialog.actions.dismiss',\n description:\n 'Dismiss the dialog. Loses any in-progress input that has not been committed.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'dialog' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on Dialog.Root.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport * as RadixDialog from '@radix-ui/react-dialog';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { X } from 'lucide-react';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useAgentRegistration } from '../../agent';\nimport { dialogAgent } from './dialog.agent';\n\n// The `ds-dialog__*` class names below are the framework-agnostic contract\n// defined in src/styles.css (@layer ui-kit-components). The React component\n// renders the SAME classes a vanilla (non-React) host hand-authors — the\n// surface (`ds-dialog__surface` + its size modifiers), the close button\n// (`ds-dialog__close`), and the body slot (`ds-dialog__body`) — so there is\n// ONE visual skin (scrim, radius, elevation, bg, padding, centering, sizing,\n// close-button glyph + hover/focus) and the two surfaces can't drift. The few\n// Tailwind utilities that remain are NOT skin: they are the Radix animation\n// hooks (`data-[state=…]:animate-*`) and the surface focus-suppression chrome\n// — neither lives in the vanilla CSS contract. Layer order\n// (`…, utilities, ui-kit-tokens, ui-kit-components`) puts the `ds-dialog__*`\n// rules after Tailwind's utilities, so the contract owns every visual\n// property and the animation utilities only touch `animation` / `outline`.\nconst OVERLAY_CLASSES = [\n 'ds-dialog__backdrop',\n 'ds:backdrop-blur-sm',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:fade-in-0',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out-0',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\n// Animation + focus chrome only — every visual property (position, centering,\n// bg, radius, elevation, padding, sizing) comes from `.ds-dialog__surface`.\nconst SURFACE_CHROME = [\n 'ds:focus-visible:outline-none',\n 'ds:data-[state=open]:animate-in ds:data-[state=open]:fade-in-0 ds:data-[state=open]:zoom-in-95',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out-0 ds:data-[state=closed]:zoom-out-95',\n 'ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\n// CVA drives only the contract class names per size. `ds-dialog` is the host\n// marker (cascade-reset boundary); `ds-dialog__surface` carries the panel skin;\n// the `--sm` / `--lg` / `--fullscreen` modifiers shift only `max-inline-size`\n// (or the fullscreen geometry) and are defined alongside the base rule in\n// src/styles.css — so size, like the skin, lives in one place.\nconst contentVariants = cva(`ds-dialog ds-dialog__surface ${SURFACE_CHROME}`, {\n variants: {\n size: {\n sm: 'ds-dialog__surface--sm',\n md: '',\n lg: 'ds-dialog__surface--lg',\n fullscreen: 'ds-dialog__surface--fullscreen',\n },\n // `body` pins the header and footer and scrolls only `Dialog.Body` once\n // the content passes the height cap. `surface` (default) scrolls the\n // whole panel as one block.\n scroll: {\n surface: '',\n body: 'ds-dialog__surface--scroll-body',\n },\n },\n defaultVariants: { size: 'md', scroll: 'surface' },\n});\n\n// Curated agent-readiness handle — see dialog.agent.ts.\nexport interface DialogHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface DialogRootProps extends ComponentPropsWithoutRef<\n typeof RadixDialog.Root\n> {\n /** Opaque instance id — forwarded to Dialog.Content as `data-component-id`. */\n id?: string;\n}\n\nconst DialogIdContext = createContext<string | undefined>(undefined);\n\nconst DialogRoot = ({\n children,\n id,\n open: openProp,\n defaultOpen,\n onOpenChange,\n ...props\n}: DialogRootProps) => {\n const [openRaw, setOpen] = useControllableState<boolean>({\n value: openProp,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n const open = openRaw ?? false;\n\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const handle = useMemo<DialogHandle>(\n () => ({\n getIsOpen: () => openRef.current,\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [setOpen],\n );\n useAgentRegistration(dialogAgent, handle, id);\n\n return (\n <DialogIdContext.Provider value={id}>\n <RadixDialog.Root open={open} onOpenChange={setOpen} {...props}>\n {children}\n </RadixDialog.Root>\n </DialogIdContext.Provider>\n );\n};\nDialogRoot.displayName = 'Dialog.Root';\n\nconst DialogTrigger = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Trigger>\n>(({ children, ...props }, ref) => (\n <RadixDialog.Trigger ref={ref} {...props}>\n {children}\n </RadixDialog.Trigger>\n));\nDialogTrigger.displayName = 'Dialog.Trigger';\n\nconst DialogClose = forwardRef<\n HTMLButtonElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Close>\n>(({ children, ...props }, ref) => (\n <RadixDialog.Close ref={ref} {...props}>\n {children}\n </RadixDialog.Close>\n));\nDialogClose.displayName = 'Dialog.Close';\n\nexport interface DialogContentProps\n extends\n Omit<ComponentPropsWithoutRef<typeof RadixDialog.Content>, 'role'>,\n VariantProps<typeof contentVariants> {\n size?: 'sm' | 'md' | 'lg' | 'fullscreen';\n variant?: 'default' | 'alert' | 'confirmation';\n /**\n * Hide the top-right dismiss \"X\". The default is **variant-aware**: the X is\n * shown for `variant=\"default\"` and hidden for `variant=\"alert\"` /\n * `\"confirmation\"` (forced-choice surfaces, where the decision is made via\n * the explicit footer actions). An explicit value always wins — pass `false`\n * to force the X onto an alert, or `true` to suppress it on a default dialog.\n */\n hideCloseButton?: boolean;\n /**\n * What scrolls once the content passes the height cap (85dvh). `surface`\n * (default) scrolls the whole panel, title and footer included. `body`\n * keeps `Dialog.Header` and `Dialog.Footer` in view and scrolls only\n * `Dialog.Body`, so the content must sit in a `Dialog.Body`. Below 480px\n * of viewport height it falls back to scrolling the whole panel.\n */\n scroll?: 'surface' | 'body';\n className?: string;\n children: ReactNode;\n}\n\nconst DialogContent = forwardRef<HTMLDivElement, DialogContentProps>(\n (\n {\n size = 'md',\n variant = 'default',\n scroll = 'surface',\n hideCloseButton,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const instanceId = useContext(DialogIdContext);\n // Only forward `role` when we actually need to override Radix's default\n // (`role=\"dialog\"`). Passing `role={undefined}` explicitly wins over\n // Radix's internal assignment and strips the attribute entirely.\n const roleOverride =\n variant === 'alert' ? { role: 'alertdialog' as const } : {};\n\n // Variant-aware close default: plain dialogs expose the dismiss X; alert\n // and confirmation dialogs are forced-choice (no X) so the decision is\n // made via the explicit footer actions. An explicit `hideCloseButton`\n // always wins.\n const closeHidden = hideCloseButton ?? variant !== 'default';\n\n return (\n <RadixDialog.Portal>\n <RadixDialog.Overlay\n data-component=\"dialog-overlay\"\n className={OVERLAY_CLASSES}\n />\n <RadixDialog.Content\n ref={ref}\n {...roleOverride}\n data-component=\"dialog\"\n data-component-id={instanceId}\n className={contentVariants({ size, scroll, className })}\n {...props}\n >\n {children}\n\n {!closeHidden && (\n // The close is a plain button carrying the `ds-dialog__close`\n // contract class — the SAME class a vanilla host renders. The CSS\n // (src/styles.css) owns its position, sizing, glyph size, hover\n // wash, and focus ring from tokens, so the React and non-React\n // close buttons are identical and can't drift.\n <RadixDialog.Close\n type=\"button\"\n className=\"ds-dialog__close\"\n aria-label={t('common.close', 'Close')}\n >\n <X aria-hidden=\"true\" />\n </RadixDialog.Close>\n )}\n </RadixDialog.Content>\n </RadixDialog.Portal>\n );\n },\n);\nDialogContent.displayName = 'Dialog.Content';\n\nconst DialogHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={['ds-dialog__header', className].filter(Boolean).join(' ')}\n {...props}\n />\n ),\n);\nDialogHeader.displayName = 'Dialog.Header';\n\n// Optional body slot. Carries the `ds-dialog__body` contract class — the SAME\n// class a vanilla host renders — so content / iframe slots match between the\n// React and non-React surfaces and can't drift. Additive: content placed\n// directly in Dialog.Content (without this wrapper) still works as before.\nconst DialogBody = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={['ds-dialog__body', className].filter(Boolean).join(' ')}\n {...props}\n />\n ),\n);\nDialogBody.displayName = 'Dialog.Body';\n\nconst DialogTitle = forwardRef<\n HTMLHeadingElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Title>\n>(({ className, ...props }, ref) => (\n <RadixDialog.Title\n ref={ref}\n className={['ds-dialog__title type-title-card ds:break-words', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nDialogTitle.displayName = 'Dialog.Title';\n\nconst DialogDescription = forwardRef<\n HTMLParagraphElement,\n ComponentPropsWithoutRef<typeof RadixDialog.Description>\n>(({ className, ...props }, ref) => (\n <RadixDialog.Description\n ref={ref}\n className={['type-body-sm ds:text-[var(--muted-foreground)]', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nDialogDescription.displayName = 'Dialog.Description';\n\ninterface DialogFooterProps extends HTMLAttributes<HTMLDivElement> {\n divider?: boolean;\n}\n\nconst DialogFooter = forwardRef<HTMLDivElement, DialogFooterProps>(\n ({ className, divider = false, ...props }, ref) => (\n <div\n ref={ref}\n className={[\n 'ds:flex ds:items-center ds:justify-end ds:gap-[var(--spacing-sm)]',\n 'ds:mt-[var(--spacing-md)]',\n divider &&\n 'ds:border-t ds:border-[color:var(--border)] ds:pt-[var(--spacing-md)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n ),\n);\nDialogFooter.displayName = 'Dialog.Footer';\n\nexport const Dialog = Object.assign(DialogRoot, {\n Root: DialogRoot,\n Trigger: DialogTrigger,\n Content: DialogContent,\n Header: DialogHeader,\n Title: DialogTitle,\n Description: DialogDescription,\n Body: DialogBody,\n Footer: DialogFooter,\n Close: DialogClose,\n});\n\nexport type { DialogFooterProps };\n"],"names":["dialogAgent","handle","OVERLAY_CLASSES","SURFACE_CHROME","contentVariants","cva","DialogIdContext","createContext","DialogRoot","children","id","openProp","defaultOpen","onOpenChange","props","openRaw","setOpen","useControllableState","open","openRef","useRef","useEffect","useMemo","useAgentRegistration","jsx","RadixDialog","DialogTrigger","forwardRef","ref","DialogClose","DialogContent","size","variant","scroll","hideCloseButton","className","t","useTranslation","instanceId","useContext","roleOverride","closeHidden","jsxs","X","DialogHeader","DialogBody","DialogTitle","DialogDescription","DialogFooter","divider","Dialog"],"mappings":"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"}
|