@alfadocs/ui-kit-debug 1.56.0 → 1.57.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/{ai-credits-notice-BoNJtOuE.js → ai-credits-notice-ktklr8fy.js} +2 -2
- package/dist/_chunks/{ai-credits-notice-BoNJtOuE.js.map → ai-credits-notice-ktklr8fy.js.map} +1 -1
- package/dist/_chunks/ai-permission-notice-DyuEGwAt.js +206 -0
- package/dist/_chunks/ai-permission-notice-DyuEGwAt.js.map +1 -0
- package/dist/_chunks/alia-sidebar-BBKBJCv6.js +1284 -0
- package/dist/_chunks/alia-sidebar-BBKBJCv6.js.map +1 -0
- package/dist/_chunks/{anamnesis-summary-rows-CQ-XGr0T.js → anamnesis-summary-rows-CCQ62mMN.js} +4 -4
- package/dist/_chunks/{anamnesis-summary-rows-CQ-XGr0T.js.map → anamnesis-summary-rows-CCQ62mMN.js.map} +1 -1
- package/dist/_chunks/{appointment-peek-BIZaDeCi.js → appointment-peek-WvNbE4JG.js} +2 -2
- package/dist/_chunks/{appointment-peek-BIZaDeCi.js.map → appointment-peek-WvNbE4JG.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-DmqYEIT9.js → appointment-timeline-Z0494xO-.js} +2 -2
- package/dist/_chunks/{appointment-timeline-DmqYEIT9.js.map → appointment-timeline-Z0494xO-.js.map} +1 -1
- package/dist/_chunks/{balance-badge-cell-DmDcXw0c.js → balance-badge-cell-CII3SDmR.js} +3 -3
- package/dist/_chunks/{balance-badge-cell-DmDcXw0c.js.map → balance-badge-cell-CII3SDmR.js.map} +1 -1
- package/dist/_chunks/{booking-WyNGKPE2.js → booking-81WnKDsH.js} +3 -3
- package/dist/_chunks/{booking-WyNGKPE2.js.map → booking-81WnKDsH.js.map} +1 -1
- package/dist/_chunks/{calculator-dialog-pCPWta7h.js → calculator-dialog-CzQv03p0.js} +2 -2
- package/dist/_chunks/{calculator-dialog-pCPWta7h.js.map → calculator-dialog-CzQv03p0.js.map} +1 -1
- package/dist/_chunks/{calendar-workspace-Du2ryaI-.js → calendar-workspace-D5-k_9zE.js} +13 -13
- package/dist/_chunks/{calendar-workspace-Du2ryaI-.js.map → calendar-workspace-D5-k_9zE.js.map} +1 -1
- package/dist/_chunks/{care-plan-card-Ddjh5Doc.js → care-plan-card-DxrRLRdW.js} +2 -2
- package/dist/_chunks/{care-plan-card-Ddjh5Doc.js.map → care-plan-card-DxrRLRdW.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-DUX_SVvF.js → care-plan-header-BMwZIgHJ.js} +2 -2
- package/dist/_chunks/{care-plan-header-DUX_SVvF.js.map → care-plan-header-BMwZIgHJ.js.map} +1 -1
- package/dist/_chunks/{chart-HsF1KHbx.js → chart-DQ5GxqgT.js} +347 -350
- package/dist/_chunks/chart-DQ5GxqgT.js.map +1 -0
- package/dist/_chunks/{clinical-note-card-14JIoUR0.js → clinical-note-card-hx939bvw.js} +2 -2
- package/dist/_chunks/{clinical-note-card-14JIoUR0.js.map → clinical-note-card-hx939bvw.js.map} +1 -1
- package/dist/_chunks/{color-picker-BRQ4Y9SO.js → color-picker-BsggJovx.js} +128 -123
- package/dist/_chunks/color-picker-BsggJovx.js.map +1 -0
- package/dist/_chunks/{contact-card-CmK05vNb.js → contact-card-fHBMwEsx.js} +2 -2
- package/dist/_chunks/{contact-card-CmK05vNb.js.map → contact-card-fHBMwEsx.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-Ci8lBQ6a.js → contact-profile-card-CMyBYgRR.js} +2 -2
- package/dist/_chunks/{contact-profile-card-Ci8lBQ6a.js.map → contact-profile-card-CMyBYgRR.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-Dgfqr4Q4.js → cycle-calculator-Cww9DzIa.js} +2 -2
- package/dist/_chunks/{cycle-calculator-Dgfqr4Q4.js.map → cycle-calculator-Cww9DzIa.js.map} +1 -1
- package/dist/_chunks/{data-table-D8fuhqO1.js → data-table-fAMTeAjM.js} +2 -2
- package/dist/_chunks/{data-table-D8fuhqO1.js.map → data-table-fAMTeAjM.js.map} +1 -1
- package/dist/_chunks/{data-table-tabs-Xhg5G0gU.js → data-table-tabs-CHYAAeHy.js} +2 -2
- package/dist/_chunks/{data-table-tabs-Xhg5G0gU.js.map → data-table-tabs-CHYAAeHy.js.map} +1 -1
- package/dist/_chunks/{date-picker-wRAcq2lt.js → date-picker-BSZuKo13.js} +69 -62
- package/dist/_chunks/date-picker-BSZuKo13.js.map +1 -0
- package/dist/_chunks/{date-range-picker-CtUOI38x.js → date-range-picker-CFk-5O3R.js} +176 -171
- package/dist/_chunks/date-range-picker-CFk-5O3R.js.map +1 -0
- package/dist/_chunks/{date-time-picker-CLeLKuv9.js → date-time-picker-CjxTkblD.js} +92 -85
- package/dist/_chunks/date-time-picker-CjxTkblD.js.map +1 -0
- package/dist/_chunks/{dialog-CUzbnKLw.js → dialog-Dn-iQ0Jp.js} +2 -2
- package/dist/_chunks/{dialog-CUzbnKLw.js.map → dialog-Dn-iQ0Jp.js.map} +1 -1
- package/dist/_chunks/{document-preview-uoTekVR7.js → document-preview-CHGGG0l_.js} +2 -2
- package/dist/_chunks/{document-preview-uoTekVR7.js.map → document-preview-CHGGG0l_.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-CSjklbyw.js → due-date-calculator-D_qFUiHp.js} +2 -2
- package/dist/_chunks/{due-date-calculator-CSjklbyw.js.map → due-date-calculator-D_qFUiHp.js.map} +1 -1
- package/dist/_chunks/{entity-summary-DcB0fIiv.js → entity-summary-CWcCSThK.js} +2 -2
- package/dist/_chunks/{entity-summary-DcB0fIiv.js.map → entity-summary-CWcCSThK.js.map} +1 -1
- package/dist/_chunks/{file-manager-Cc_uO8r2.js → file-manager-CFsL1KVt.js} +3 -3
- package/dist/_chunks/{file-manager-Cc_uO8r2.js.map → file-manager-CFsL1KVt.js.map} +1 -1
- package/dist/_chunks/{gestational-age-calculator-DqVeJke2.js → gestational-age-calculator-CZi43xKG.js} +2 -2
- package/dist/_chunks/{gestational-age-calculator-DqVeJke2.js.map → gestational-age-calculator-CZi43xKG.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-BIYyI2Yo.js → hcg-doubling-Ccvh7OaU.js} +2 -2
- package/dist/_chunks/{hcg-doubling-BIYyI2Yo.js.map → hcg-doubling-Ccvh7OaU.js.map} +1 -1
- package/dist/_chunks/{header-settings-ge_3gYEq.js → header-settings-BMcCx2LC.js} +2 -2
- package/dist/_chunks/{header-settings-ge_3gYEq.js.map → header-settings-BMcCx2LC.js.map} +1 -1
- package/dist/_chunks/{heatmap-Gf9r7Tn1.js → heatmap-BEeOThkW.js} +2 -2
- package/dist/_chunks/{heatmap-Gf9r7Tn1.js.map → heatmap-BEeOThkW.js.map} +1 -1
- package/dist/_chunks/{help-me-write-templates-fV-Apf72.js → help-me-write-templates-BUoYGo6f.js} +2 -2
- package/dist/_chunks/{help-me-write-templates-fV-Apf72.js.map → help-me-write-templates-BUoYGo6f.js.map} +1 -1
- package/dist/_chunks/{hover-card-BnTueNS2.js → hover-card-U_ZYoh1n.js} +201 -187
- package/dist/_chunks/hover-card-U_ZYoh1n.js.map +1 -0
- package/dist/_chunks/{icon-picker-DWrqmI1c.js → icon-picker-C86lQTIA.js} +2 -2
- package/dist/_chunks/{icon-picker-DWrqmI1c.js.map → icon-picker-C86lQTIA.js.map} +1 -1
- package/dist/_chunks/{info-tip-B0jmIt6M.js → info-tip-CJpNpzZe.js} +2 -2
- package/dist/_chunks/{info-tip-B0jmIt6M.js.map → info-tip-CJpNpzZe.js.map} +1 -1
- package/dist/_chunks/{kit-extensions-Byfxy6sy.js → kit-extensions-DYVxWcqv.js} +4 -4
- package/dist/_chunks/{kit-extensions-Byfxy6sy.js.map → kit-extensions-DYVxWcqv.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-TeJNvymP.js → link-cell-renderer-CxW_oLa5.js} +2 -2
- package/dist/_chunks/{link-cell-renderer-TeJNvymP.js.map → link-cell-renderer-CxW_oLa5.js.map} +1 -1
- package/dist/_chunks/link-gRw3NtOt.js +137 -0
- package/dist/_chunks/link-gRw3NtOt.js.map +1 -0
- package/dist/_chunks/{locale-picker-DfNSdOpy.js → locale-picker-BGfrZyTw.js} +2 -2
- package/dist/_chunks/{locale-picker-DfNSdOpy.js.map → locale-picker-BGfrZyTw.js.map} +1 -1
- package/dist/_chunks/{marketplace-app-shell-Dcx-JEjg.js → marketplace-app-shell-BZcA9Z06.js} +143 -129
- package/dist/_chunks/marketplace-app-shell-BZcA9Z06.js.map +1 -0
- package/dist/_chunks/{message-tray-BB95DA82.js → message-tray-QKQutwxj.js} +76 -69
- package/dist/_chunks/message-tray-QKQutwxj.js.map +1 -0
- package/dist/_chunks/{nav-grid-BqCPH8sm.js → nav-grid-Byx8PxuB.js} +2 -2
- package/dist/_chunks/{nav-grid-BqCPH8sm.js.map → nav-grid-Byx8PxuB.js.map} +1 -1
- package/dist/_chunks/non-modal-tab-exit-j3CPOuE3.js +89 -0
- package/dist/_chunks/non-modal-tab-exit-j3CPOuE3.js.map +1 -0
- package/dist/_chunks/{note-attachment-I1NLoeRZ.js → note-attachment-Bt2cddsZ.js} +2 -2
- package/dist/_chunks/{note-attachment-I1NLoeRZ.js.map → note-attachment-Bt2cddsZ.js.map} +1 -1
- package/dist/_chunks/{note-timeline-CsY8YOE7.js → note-timeline-CX9nAgAR.js} +2 -2
- package/dist/_chunks/{note-timeline-CsY8YOE7.js.map → note-timeline-CX9nAgAR.js.map} +1 -1
- package/dist/_chunks/{notes-panel-DceRhthG.js → notes-panel-Cm4pttpl.js} +4 -4
- package/dist/_chunks/{notes-panel-DceRhthG.js.map → notes-panel-Cm4pttpl.js.map} +1 -1
- package/dist/_chunks/{notification-tray-__sJXnsz.js → notification-tray-C5VtbGjd.js} +83 -76
- package/dist/_chunks/notification-tray-C5VtbGjd.js.map +1 -0
- package/dist/_chunks/{patient-details-DsTtjpuX.js → patient-details-99kEdtc5.js} +2 -2
- package/dist/_chunks/{patient-details-DsTtjpuX.js.map → patient-details-99kEdtc5.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-BvZ9luz-.js → patient-field-row-DkxY13T6.js} +5 -5
- package/dist/_chunks/{patient-field-row-BvZ9luz-.js.map → patient-field-row-DkxY13T6.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-9nQWTQf6.js → patient-summary-card-opdyfeW2.js} +4 -4
- package/dist/_chunks/{patient-summary-card-9nQWTQf6.js.map → patient-summary-card-opdyfeW2.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-CwDpwXUC.js → payment-request-card-DAniJNLX.js} +2 -2
- package/dist/_chunks/{payment-request-card-CwDpwXUC.js.map → payment-request-card-DAniJNLX.js.map} +1 -1
- package/dist/_chunks/{pdf-viewer-C3minW5b.js → pdf-viewer-CNQxa4tv.js} +396 -391
- package/dist/_chunks/pdf-viewer-CNQxa4tv.js.map +1 -0
- package/dist/_chunks/{phone-input-DxkHMYmu.js → phone-input-O9camxkq.js} +156 -151
- package/dist/_chunks/phone-input-O9camxkq.js.map +1 -0
- package/dist/_chunks/popover-BG75rYjN.js +367 -0
- package/dist/_chunks/popover-BG75rYjN.js.map +1 -0
- package/dist/_chunks/{practice-results-Dhbo-fc_.js → practice-results-CfRkjzsI.js} +2 -2
- package/dist/_chunks/{practice-results-Dhbo-fc_.js.map → practice-results-CfRkjzsI.js.map} +1 -1
- package/dist/_chunks/{pregnancy-dating-Bfu0Cq4H.js → pregnancy-dating-BFzv9g1N.js} +2 -2
- package/dist/_chunks/{pregnancy-dating-Bfu0Cq4H.js.map → pregnancy-dating-BFzv9g1N.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-BSSiGGG4.js → product-hub-panel-DlVRK7Ue.js} +103 -96
- package/dist/_chunks/product-hub-panel-DlVRK7Ue.js.map +1 -0
- package/dist/_chunks/{public-footer-CxpG6J1M.js → public-footer-ZWTEG1Rq.js} +2 -2
- package/dist/_chunks/{public-footer-CxpG6J1M.js.map → public-footer-ZWTEG1Rq.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-pr2hyiND.js → public-header.agent-BctevbuY.js} +2 -2
- package/dist/_chunks/{public-header.agent-pr2hyiND.js.map → public-header.agent-BctevbuY.js.map} +1 -1
- package/dist/_chunks/{radiograph-panel.agent-DkUokbEa.js → radiograph-panel.agent-DyqbTECc.js} +4 -4
- package/dist/_chunks/{radiograph-panel.agent-DkUokbEa.js.map → radiograph-panel.agent-DyqbTECc.js.map} +1 -1
- package/dist/_chunks/{registration-form-D7iNqMBF.js → registration-form-BlTzYywa.js} +2 -2
- package/dist/_chunks/{registration-form-D7iNqMBF.js.map → registration-form-BlTzYywa.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-CkFfmA3v.js → rich-text-editor-DTnNZ4Ff.js} +489 -484
- package/dist/_chunks/rich-text-editor-DTnNZ4Ff.js.map +1 -0
- package/dist/_chunks/{sheet-C7SwIxwB.js → sheet-8qsiMoUI.js} +2 -2
- package/dist/_chunks/{sheet-C7SwIxwB.js.map → sheet-8qsiMoUI.js.map} +1 -1
- package/dist/_chunks/{sign-document-B6HlyCGV.js → sign-document-D4iHS_Ug.js} +2 -2
- package/dist/_chunks/{sign-document-B6HlyCGV.js.map → sign-document-D4iHS_Ug.js.map} +1 -1
- package/dist/_chunks/{signature-request-DhbpB9N9.js → signature-request-DRuYAG5I.js} +2 -2
- package/dist/_chunks/{signature-request-DhbpB9N9.js.map → signature-request-DRuYAG5I.js.map} +1 -1
- package/dist/_chunks/{signed-out-frame-B2GTIeqA.js → signed-out-frame-AhMsNW1r.js} +2 -2
- package/dist/_chunks/{signed-out-frame-B2GTIeqA.js.map → signed-out-frame-AhMsNW1r.js.map} +1 -1
- package/dist/_chunks/{task-editor-ByyRu29Y.js → task-editor-NkcopDna.js} +3 -3
- package/dist/_chunks/{task-editor-ByyRu29Y.js.map → task-editor-NkcopDna.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-JsDM48tf.js → use-appointment-details-read-CfFQNOF_.js} +5 -5
- package/dist/_chunks/{use-appointment-details-read-JsDM48tf.js.map → use-appointment-details-read-CfFQNOF_.js.map} +1 -1
- package/dist/_chunks/{voice-control-panel-Bg1eklL0.js → voice-control-panel-BKbgb7FM.js} +2 -2
- package/dist/_chunks/{voice-control-panel-Bg1eklL0.js.map → voice-control-panel-BKbgb7FM.js.map} +1 -1
- package/dist/_chunks/{widget-picker-DXYBMTfe.js → widget-picker-rBA7MR5P.js} +2 -2
- package/dist/_chunks/{widget-picker-DXYBMTfe.js.map → widget-picker-rBA7MR5P.js.map} +1 -1
- package/dist/agent-catalog.json +2 -2
- package/dist/components/_shared/non-modal-tab-exit.d.ts +15 -4
- package/dist/components/_shared/non-modal-tab-exit.d.ts.map +1 -1
- package/dist/components/ai-credits-notice/index.js +1 -1
- package/dist/components/ai-permission-notice/ai-permission-notice.d.ts +32 -0
- package/dist/components/ai-permission-notice/ai-permission-notice.d.ts.map +1 -1
- package/dist/components/ai-permission-notice/index.d.ts +1 -1
- package/dist/components/ai-permission-notice/index.d.ts.map +1 -1
- package/dist/components/ai-permission-notice/index.js +1 -1
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/appointment-peek/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/calculator-dialog/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/chart/chart.d.ts +5 -5
- package/dist/components/chart/chart.d.ts.map +1 -1
- package/dist/components/chart/index.js +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/color-picker/color-picker.d.ts.map +1 -1
- package/dist/components/color-picker/index.js +1 -1
- package/dist/components/contact-card/index.js +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/data-table-tabs/index.js +1 -1
- package/dist/components/date-picker/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/date-range-picker/date-range-picker.d.ts.map +1 -1
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/date-time-picker/date-time-picker.d.ts.map +1 -1
- package/dist/components/date-time-picker/index.js +1 -1
- package/dist/components/dialog/index.js +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/hcg-doubling/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/heatmap/index.js +1 -1
- package/dist/components/hover-card/hover-card.d.ts.map +1 -1
- package/dist/components/hover-card/index.js +1 -1
- package/dist/components/icon-picker/index.js +1 -1
- package/dist/components/info-tip/index.js +1 -1
- package/dist/components/link/index.js +1 -1
- package/dist/components/link/link.d.ts +5 -3
- package/dist/components/link/link.d.ts.map +1 -1
- package/dist/components/locale-picker/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/message-tray/message-tray.d.ts.map +1 -1
- package/dist/components/nav-grid/index.js +1 -1
- package/dist/components/note-timeline/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/notification-tray/notification-tray.d.ts.map +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/pdf-viewer/index.js +1 -1
- package/dist/components/pdf-viewer/pdf-viewer.d.ts.map +1 -1
- package/dist/components/phone-input/index.js +1 -1
- package/dist/components/phone-input/phone-input.d.ts.map +1 -1
- package/dist/components/popover/index.js +1 -1
- package/dist/components/popover/popover.d.ts +1 -1
- package/dist/components/popover/popover.d.ts.map +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/product-hub-tray/product-hub-tray.d.ts.map +1 -1
- package/dist/components/public-footer/index.js +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/rich-text-editor/editor-toolbar.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +2 -2
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sign-document/index.js +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/voice-control-panel/index.js +1 -1
- package/dist/components/widget-picker/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +14 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +15 -1
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +14 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +15 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +14 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +15 -1
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +14 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +15 -1
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +14 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +15 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +14 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +15 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +14 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +15 -1
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +14 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +15 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +14 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +15 -1
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +14 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +15 -1
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +14 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +15 -1
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +14 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +15 -1
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +14 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +15 -1
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +14 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +15 -1
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +14 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +15 -1
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +14 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +15 -1
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +14 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +15 -1
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +14 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +15 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +194 -193
- package/dist/locales/ar.json +15 -1
- package/dist/locales/de.json +15 -1
- package/dist/locales/el.json +15 -1
- package/dist/locales/en.json +15 -1
- package/dist/locales/es.json +15 -1
- package/dist/locales/fr.json +15 -1
- package/dist/locales/hi.json +15 -1
- package/dist/locales/it.json +15 -1
- package/dist/locales/ja.json +15 -1
- package/dist/locales/nl.json +15 -1
- package/dist/locales/pl.json +15 -1
- package/dist/locales/pt.json +15 -1
- package/dist/locales/ro.json +15 -1
- package/dist/locales/ru.json +15 -1
- package/dist/locales/sq.json +15 -1
- package/dist/locales/sv.json +15 -1
- package/dist/locales/tr.json +15 -1
- package/dist/locales/zh.json +15 -1
- package/dist/patterns/alia-assistant/alia-asteroid-icon.d.ts +10 -13
- package/dist/patterns/alia-assistant/alia-asteroid-icon.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/alia-chat-surface.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/alia-popout.d.ts +5 -3
- package/dist/patterns/alia-assistant/alia-popout.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/index.d.ts +2 -0
- package/dist/patterns/alia-assistant/index.d.ts.map +1 -1
- package/dist/patterns/alia-assistant/index.js +6 -5
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/help-me-write-templates/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/marketplace-app-shell.d.ts +7 -2
- package/dist/patterns/marketplace-app-shell/marketplace-app-shell.d.ts.map +1 -1
- package/dist/patterns/registration-form/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/patterns/signed-out-frame/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/ai-permission-notice-5vpblPCx.js +0 -171
- package/dist/_chunks/ai-permission-notice-5vpblPCx.js.map +0 -1
- package/dist/_chunks/alia-sidebar-DOei4Iyu.js +0 -1183
- package/dist/_chunks/alia-sidebar-DOei4Iyu.js.map +0 -1
- package/dist/_chunks/chart-HsF1KHbx.js.map +0 -1
- package/dist/_chunks/color-picker-BRQ4Y9SO.js.map +0 -1
- package/dist/_chunks/date-picker-wRAcq2lt.js.map +0 -1
- package/dist/_chunks/date-range-picker-CtUOI38x.js.map +0 -1
- package/dist/_chunks/date-time-picker-CLeLKuv9.js.map +0 -1
- package/dist/_chunks/hover-card-BnTueNS2.js.map +0 -1
- package/dist/_chunks/link-2HokYuIi.js +0 -130
- package/dist/_chunks/link-2HokYuIi.js.map +0 -1
- package/dist/_chunks/marketplace-app-shell-Dcx-JEjg.js.map +0 -1
- package/dist/_chunks/message-tray-BB95DA82.js.map +0 -1
- package/dist/_chunks/non-modal-tab-exit-D2Bd93Bq.js +0 -65
- package/dist/_chunks/non-modal-tab-exit-D2Bd93Bq.js.map +0 -1
- package/dist/_chunks/notification-tray-__sJXnsz.js.map +0 -1
- package/dist/_chunks/pdf-viewer-C3minW5b.js.map +0 -1
- package/dist/_chunks/phone-input-DxkHMYmu.js.map +0 -1
- package/dist/_chunks/popover-BI3oV3eY.js +0 -305
- package/dist/_chunks/popover-BI3oV3eY.js.map +0 -1
- package/dist/_chunks/product-hub-panel-BSSiGGG4.js.map +0 -1
- package/dist/_chunks/rich-text-editor-CkFfmA3v.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hover-card-BnTueNS2.js","sources":["../../src/components/hover-card/hover-card.agent.ts","../../src/components/hover-card/hover-card.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — HoverCard. */\n/* */\n/* Unlike Tooltip, a hover card holds interactive content, so an agent */\n/* has a legitimate reason to open one and read its state. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { HoverCardHandle } from './hover-card';\n\nexport const hoverCardAgent: AgentAdapter<HoverCardHandle> = {\n id: 'hover-card',\n capabilities: ['open', 'close'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.hoverCard.state.isOpen',\n description: 'True when the hover card is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.hoverCard.actions.open',\n description: 'Open the hover card without moving focus into it.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.hoverCard.actions.close',\n description: 'Close the hover card.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'hover-card' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on HoverCard.Root.',\n },\n },\n};\n","import {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport * as RadixPopover from '@radix-ui/react-popover';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { X } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { useAgentRegistration } from '../../agent';\nimport { hoverCardAgent } from './hover-card.agent';\n\n/* -------------------------------------------------------------------- */\n/* Logical → physical side */\n/* -------------------------------------------------------------------- */\n\nexport type HoverCardSide = 'top' | 'end' | 'bottom' | 'start';\n\nfunction resolvePhysicalSide(\n logicalSide: HoverCardSide,\n isRtl: boolean,\n): 'left' | 'top' | 'right' | 'bottom' {\n if (logicalSide === 'top' || logicalSide === 'bottom') return logicalSide;\n if (logicalSide === 'start') return isRtl ? 'right' : 'left';\n /* logicalSide === 'end' */\n return isRtl ? 'left' : 'right';\n}\n\n/* -------------------------------------------------------------------- */\n/* Contexts */\n/* -------------------------------------------------------------------- */\n\ninterface HoverCardA11yContext {\n headingId: string | undefined;\n setHeadingId: (id: string | undefined) => void;\n}\n\nconst A11yContext = createContext<HoverCardA11yContext>({\n headingId: undefined,\n setHeadingId: () => {},\n});\n\ninterface HoverCardRootContext {\n /** Keeps the card open while the pointer or focus is inside the content. */\n cancelClose: () => void;\n closeWithDelay: () => void;\n /** True when this open should move focus into the card. */\n shouldFocusOnOpen: () => boolean;\n /** True when focus was actually moved in, so closing may return it. */\n didMoveFocus: () => boolean;\n noteMovedFocus: () => void;\n /** Called when closing hands focus back, so the trigger's focus handler\n * does not read that return as a fresh Tab and reopen the card. */\n noteFocusReturn: () => void;\n clearMovedFocus: () => void;\n registerContent: (node: HTMLDivElement | null) => void;\n /** The trigger node, used to resolve the reading direction. Content is\n * portalled to body, so only the trigger can see a scoped [dir]. */\n triggerRef: React.MutableRefObject<HTMLElement | null>;\n instanceId: string | undefined;\n}\n\nconst RootContext = createContext<HoverCardRootContext>({\n cancelClose: () => {},\n closeWithDelay: () => {},\n shouldFocusOnOpen: () => false,\n didMoveFocus: () => false,\n noteMovedFocus: () => {},\n noteFocusReturn: () => {},\n clearMovedFocus: () => {},\n registerContent: () => {},\n triggerRef: { current: null },\n instanceId: undefined,\n});\n\n/** `flush` moves padding from the Content onto the inner slots, so Media can\n * bleed to the card's edge. */\nconst PaddingContext = createContext<'default' | 'flush'>('default');\n\n/* -------------------------------------------------------------------- */\n/* CVA — content surface */\n/* -------------------------------------------------------------------- */\n\nconst contentVariants = cva(\n [\n // Same elevated surface as Popover: `--card-border` at 32% alpha reads as\n // a subtle edge in both themes, where the shadow alone lets the card\n // float as an unbounded blob on dark. Forced colours upgrade it to a\n // fully visible `CanvasText` edge.\n 'ds:relative ds:bg-[var(--popover)] ds:border ds:border-[color:var(--card-border)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:max-w-[calc(100vw-var(--spacing-lg))]',\n 'ds:z-[var(--z-popover)]',\n 'ds:text-[var(--popover-foreground)] ds:text-[length:var(--font-size-sm)]',\n 'ds:break-words',\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=closed]:fade-out-0 ds:data-[state=open]:fade-in-0',\n 'ds:data-[state=closed]:zoom-out-95 ds:data-[state=open]:zoom-in-95',\n 'ds:data-[side=bottom]:slide-in-from-top-2 ds:data-[side=left]:slide-in-from-right-2',\n 'ds:data-[side=right]:slide-in-from-left-2 ds:data-[side=top]:slide-in-from-bottom-2',\n 'ds:motion-reduce:transition-none ds:motion-reduce:animate-none',\n 'ds:forced-colors:border-[CanvasText]',\n 'ds:focus-visible:outline-none',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:w-[var(--popover-size-sm)]',\n md: 'ds:w-[var(--popover-size-md)]',\n lg: 'ds:w-[var(--popover-size-lg)]',\n },\n padding: {\n default: 'ds:p-[var(--spacing-md)]',\n // Media bleeds to the edge, so the slots pad themselves instead.\n flush: 'ds:p-[var(--spacing-none)] ds:overflow-hidden',\n },\n },\n defaultVariants: {\n size: 'md',\n padding: 'default',\n },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* Root */\n/* -------------------------------------------------------------------- */\n\n// Curated agent-readiness handle — see hover-card.agent.ts.\nexport interface HoverCardHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface HoverCardProps {\n children: ReactNode;\n /**\n * How the card opens. `hover-or-click` (the default) opens on pointer hover\n * without taking focus, and on click, tap or Enter with focus moved into the\n * card so the footer actions are reachable. `click` disables hover entirely.\n */\n openOn?: 'hover-or-click' | 'click';\n /** Controlled open state. */\n open?: boolean;\n /** Uncontrolled initial open state. */\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Delay before a hover opens the card, in ms. Default 300. */\n openDelay?: number;\n /** Grace period before a pointer leaving closes the card, in ms. Default 300. */\n closeDelay?: number;\n /** Opaque instance id — emitted on Content as `data-component-id`. */\n id?: string;\n}\n\nfunction HoverCardRoot({\n children,\n openOn = 'hover-or-click',\n open: controlledOpen,\n defaultOpen,\n onOpenChange,\n openDelay = 300,\n closeDelay = 300,\n id,\n}: HoverCardProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange],\n );\n\n const isOpenRef = useRef(isOpen);\n useEffect(() => {\n isOpenRef.current = isOpen;\n }, [isOpen]);\n\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const clearTimer = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n useEffect(() => clearTimer, [clearTimer]);\n\n /* Focus bookkeeping. A hover must never pull focus off whatever the user is\n doing; a click or Enter must move focus in, or the footer buttons are\n unreachable. `focusOnOpen` decides which, and `movedFocus` records whether\n closing is allowed to hand focus back to the trigger. */\n const focusOnOpenRef = useRef(false);\n const movedFocusRef = useRef(false);\n const contentRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n\n const openWithDelay = useCallback(() => {\n clearTimer();\n timerRef.current = setTimeout(() => {\n focusOnOpenRef.current = false;\n setOpen(true);\n }, openDelay);\n }, [clearTimer, openDelay, setOpen]);\n\n const closeWithDelay = useCallback(() => {\n clearTimer();\n timerRef.current = setTimeout(() => setOpen(false), closeDelay);\n }, [clearTimer, closeDelay, setOpen]);\n\n /* Closing hands focus back to the trigger, which fires the trigger's focus\n handler and would reopen the card it just closed — an Escape that does\n nothing. The return is swallowed once, with a timeout as a safety net so\n a suppression can never outlive the interaction that armed it. */\n const suppressFocusOpenRef = useRef(false);\n const suppressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const noteFocusReturn = useCallback(() => {\n suppressFocusOpenRef.current = true;\n if (suppressTimerRef.current) clearTimeout(suppressTimerRef.current);\n suppressTimerRef.current = setTimeout(() => {\n suppressFocusOpenRef.current = false;\n }, 100);\n }, []);\n useEffect(\n () => () => {\n if (suppressTimerRef.current) clearTimeout(suppressTimerRef.current);\n },\n [],\n );\n\n /** Tabbing onto the trigger reveals the card at once, but leaves focus on\n * the trigger so a keyboard user can pass by without being pulled in. */\n const openOnFocus = useCallback(() => {\n if (suppressFocusOpenRef.current) {\n suppressFocusOpenRef.current = false;\n return;\n }\n clearTimer();\n focusOnOpenRef.current = false;\n setOpen(true);\n }, [clearTimer, setOpen]);\n\n const focusContent = useCallback(() => {\n movedFocusRef.current = true;\n contentRef.current?.focus();\n }, []);\n\n /* Press bookkeeping. \"Was the card open?\" is the wrong question: hover and\n Tab both reveal it, so by the time Enter or a click arrives it is already\n open and a naive toggle would close what the user is trying to enter.\n The right question is whether focus was already INSIDE the card, which\n separates \"take me in\" from \"I am in, let me out\".\n\n It must be snapshotted at press start, not read at click time, because\n pointerdown moves focus to the trigger and would erase the answer.\n `null` means an orphan press (a programmatic `.click()`, or assistive\n tech dispatching click alone) and is treated as \"take me in\". */\n const focusWasInsideRef = useRef<boolean | null>(null);\n const notePressStart = useCallback(() => {\n const content = contentRef.current;\n focusWasInsideRef.current = Boolean(\n content && content.contains(document.activeElement),\n );\n }, []);\n\n const handleTriggerClick = useCallback(() => {\n const focusWasInside = focusWasInsideRef.current;\n focusWasInsideRef.current = null;\n if (focusWasInside === true) {\n setOpen(false);\n return;\n }\n focusOnOpenRef.current = true;\n if (isOpenRef.current) {\n // Hover or Tab already opened it, so no state change will fire\n // onOpenAutoFocus. Move focus in directly.\n focusContent();\n } else {\n setOpen(true);\n }\n }, [focusContent, setOpen]);\n\n const agentHandle = useMemo<HoverCardHandle>(\n () => ({\n getIsOpen: () => isOpenRef.current,\n open: () => {\n focusOnOpenRef.current = false;\n setOpen(true);\n },\n close: () => setOpen(false),\n }),\n [setOpen],\n );\n useAgentRegistration(hoverCardAgent, agentHandle, id);\n\n const [headingId, setHeadingId] = useState<string | undefined>(undefined);\n\n const isHoverMode = openOn === 'hover-or-click';\n\n const rootValue = useMemo<HoverCardRootContext>(\n () => ({\n cancelClose: clearTimer,\n closeWithDelay: isHoverMode ? closeWithDelay : () => {},\n shouldFocusOnOpen: () => focusOnOpenRef.current,\n didMoveFocus: () => movedFocusRef.current,\n noteMovedFocus: () => {\n movedFocusRef.current = true;\n },\n noteFocusReturn,\n clearMovedFocus: () => {\n movedFocusRef.current = false;\n },\n registerContent: (node) => {\n contentRef.current = node;\n },\n triggerRef,\n instanceId: id,\n }),\n [clearTimer, closeWithDelay, id, isHoverMode, noteFocusReturn],\n );\n\n const triggerValue = useMemo<HoverCardTriggerContext>(\n () => ({\n isHoverMode,\n openOnFocus,\n openWithDelay,\n closeWithDelay,\n cancelClose: clearTimer,\n notePressStart,\n onClick: handleTriggerClick,\n }),\n [\n clearTimer,\n closeWithDelay,\n handleTriggerClick,\n isHoverMode,\n notePressStart,\n openOnFocus,\n openWithDelay,\n ],\n );\n\n return (\n <A11yContext.Provider value={{ headingId, setHeadingId }}>\n <RootContext.Provider value={rootValue}>\n <TriggerContext.Provider value={triggerValue}>\n <RadixPopover.Root open={isOpen} onOpenChange={setOpen}>\n {children}\n </RadixPopover.Root>\n </TriggerContext.Provider>\n </RootContext.Provider>\n </A11yContext.Provider>\n );\n}\nHoverCardRoot.displayName = 'HoverCard.Root';\n\n/* -------------------------------------------------------------------- */\n/* Trigger */\n/* -------------------------------------------------------------------- */\n\ninterface HoverCardTriggerContext {\n isHoverMode: boolean;\n openOnFocus: () => void;\n openWithDelay: () => void;\n closeWithDelay: () => void;\n cancelClose: () => void;\n notePressStart: () => void;\n onClick: () => void;\n}\n\nconst TriggerContext = createContext<HoverCardTriggerContext>({\n isHoverMode: true,\n openOnFocus: () => {},\n openWithDelay: () => {},\n closeWithDelay: () => {},\n cancelClose: () => {},\n notePressStart: () => {},\n onClick: () => {},\n});\n\nexport type HoverCardTriggerProps = ComponentPropsWithoutRef<\n typeof RadixPopover.Trigger\n>;\n\nconst HoverCardTrigger = forwardRef<HTMLButtonElement, HoverCardTriggerProps>(\n (\n {\n children,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n onPointerDown,\n onKeyDown,\n onClick,\n ...props\n },\n ref,\n ) => {\n const ctx = useContext(TriggerContext);\n const { triggerRef } = useContext(RootContext);\n\n const setRefs = useCallback(\n (node: HTMLButtonElement | null) => {\n triggerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref, triggerRef],\n );\n\n return (\n <RadixPopover.Trigger\n ref={setRefs}\n onMouseEnter={(event) => {\n if (ctx.isHoverMode) ctx.openWithDelay();\n onMouseEnter?.(event);\n }}\n onMouseLeave={(event) => {\n if (ctx.isHoverMode) ctx.closeWithDelay();\n onMouseLeave?.(event);\n }}\n onFocus={(event) => {\n if (ctx.isHoverMode) ctx.openOnFocus();\n onFocus?.(event);\n }}\n onBlur={(event) => {\n if (ctx.isHoverMode) ctx.closeWithDelay();\n onBlur?.(event);\n }}\n onPointerDown={(event) => {\n ctx.notePressStart();\n onPointerDown?.(event);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') ctx.notePressStart();\n onKeyDown?.(event);\n }}\n onClick={(event) => {\n // Own the toggle outright: Radix's own click toggle would close a\n // card that this very press had just opened via focus.\n event.preventDefault();\n ctx.onClick();\n onClick?.(event);\n }}\n {...props}\n >\n {children}\n </RadixPopover.Trigger>\n );\n },\n);\nHoverCardTrigger.displayName = 'HoverCard.Trigger';\n\nexport type HoverCardAnchorProps = ComponentPropsWithoutRef<\n typeof RadixPopover.Anchor\n>;\n\nconst HoverCardAnchor = forwardRef<\n ElementRef<typeof RadixPopover.Anchor>,\n HoverCardAnchorProps\n>((props, ref) => {\n const { triggerRef } = useContext(RootContext);\n const setRefs = useCallback(\n (node: ElementRef<typeof RadixPopover.Anchor> | null) => {\n triggerRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref, triggerRef],\n );\n\n return <RadixPopover.Anchor ref={setRefs} {...props} />;\n});\nHoverCardAnchor.displayName = 'HoverCard.Anchor';\n\n/* -------------------------------------------------------------------- */\n/* Content */\n/* -------------------------------------------------------------------- */\n\nexport interface HoverCardContentProps\n extends\n Omit<\n ComponentPropsWithoutRef<typeof RadixPopover.Content>,\n 'side' | 'align'\n >,\n VariantProps<typeof contentVariants> {\n /** Logical side, resolved against the reading direction. Default `'top'`. */\n side?: HoverCardSide;\n align?: 'start' | 'center' | 'end';\n size?: 'sm' | 'md' | 'lg';\n padding?: 'default' | 'flush';\n /** Render the arrow. Default `true`. */\n showArrow?: boolean;\n /** Render a close button, for touch users on a card with actions. */\n showClose?: boolean;\n /**\n * An action pinned to the top-end corner — the same slot `showClose` uses.\n * For a card whose ANCHOR has a real open action, so the card mirrors it\n * instead of describing it in prose (\"Click to open …\"). Only give a card\n * one when the trigger genuinely opens something; a card that merely points\n * somewhere else should say so in a hint line, because an icon button there\n * promises a click the anchor does not have.\n *\n * A card carrying one must be interactive — the pointer has to be able to\n * travel into it — so do not combine it with a pointer-events-none peek.\n */\n headerAction?: ReactNode;\n className?: string;\n children: ReactNode;\n}\n\nconst HoverCardContent = forwardRef<HTMLDivElement, HoverCardContentProps>(\n (\n {\n side = 'top',\n align = 'center',\n size = 'md',\n padding = 'default',\n showArrow = true,\n showClose = false,\n headerAction,\n dir: providedDirection,\n className,\n children,\n onOpenAutoFocus,\n onCloseAutoFocus,\n onMouseEnter,\n onMouseLeave,\n onFocusCapture,\n ...props\n },\n ref,\n ) => {\n const { headingId } = useContext(A11yContext);\n const root = useContext(RootContext);\n const { t } = useTranslation('ui');\n const [isRtl, setIsRtl] = useState(false);\n const localRef = useRef<HTMLDivElement | null>(null);\n\n const setRefs = useCallback(\n (node: HTMLDivElement | null) => {\n localRef.current = node;\n root.registerContent(node);\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref, root],\n );\n\n // Read direction from the TRIGGER, not from this content: the content is\n // portalled to body, where `closest('[dir]')` can only ever find <html>.\n // Reading the trigger lets one RTL region inside an LTR page resolve\n // start/end correctly.\n useEffect(() => {\n const anchor = root.triggerRef.current;\n const scoped = anchor?.closest('[dir]');\n const resolved =\n scoped?.getAttribute('dir') ?? document.documentElement.dir ?? 'ltr';\n setIsRtl(resolved === 'rtl');\n }, [root.triggerRef]);\n\n const contentDirection = providedDirection ?? (isRtl ? 'rtl' : 'ltr');\n const directionIsRtl = contentDirection === 'rtl';\n const physicalSide = resolvePhysicalSide(side, directionIsRtl);\n // Radix resolves `align` physically unless a DirectionProvider is present,\n // which the kit does not mount. On the block axis (a card on the inline\n // start or end) align is unaffected by direction; on the inline axis it\n // must be mirrored by hand so `align=\"start\"` means the reading start.\n const isInlineAxis = physicalSide === 'top' || physicalSide === 'bottom';\n const physicalAlign =\n directionIsRtl && isInlineAxis && align !== 'center'\n ? align === 'start'\n ? 'end'\n : 'start'\n : align;\n\n return (\n <RadixPopover.Portal>\n <RadixPopover.Content\n ref={setRefs}\n dir={contentDirection}\n side={physicalSide}\n align={physicalAlign}\n sideOffset={8}\n collisionPadding={8}\n aria-labelledby={headingId}\n className={contentVariants({ size, padding, className })}\n data-component=\"hover-card\"\n data-component-id={root.instanceId}\n onOpenAutoFocus={(event) => {\n // A hover-opened card must not take focus; a click- or\n // Enter-opened one must, or the footer actions are unreachable.\n if (root.shouldFocusOnOpen()) root.noteMovedFocus();\n else event.preventDefault();\n onOpenAutoFocus?.(event);\n }}\n onCloseAutoFocus={(event) => {\n // Only hand focus back if we took it in the first place, and warn\n // the trigger that the focus it is about to receive is a return.\n if (root.didMoveFocus()) root.noteFocusReturn();\n else event.preventDefault();\n root.clearMovedFocus();\n onCloseAutoFocus?.(event);\n }}\n onMouseEnter={(event) => {\n root.cancelClose();\n onMouseEnter?.(event);\n }}\n onMouseLeave={(event) => {\n root.closeWithDelay();\n onMouseLeave?.(event);\n }}\n onFocusCapture={(event) => {\n root.cancelClose();\n onFocusCapture?.(event);\n }}\n {...props}\n >\n <PaddingContext.Provider value={padding}>\n {children}\n </PaddingContext.Provider>\n {showClose || headerAction ? (\n <div\n className={[\n 'ds:absolute ds:top-[var(--spacing-sm)] ds:end-[var(--spacing-sm)]',\n 'ds:z-[1] ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n ].join(' ')}\n >\n {headerAction}\n {showClose ? (\n <RadixPopover.Close asChild>\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('common.close', 'Close')}\n />\n </RadixPopover.Close>\n ) : null}\n </div>\n ) : null}\n {showArrow ? (\n // Radix places the arrow on the resolved side and keeps it over\n // the trigger through collision flip and shift.\n //\n // A custom path, not the default polygon, so the card's OUTLINE\n // carries on around the point instead of stopping dead at it. The\n // path is left open (no `Z`), so the fill closes the triangle\n // while the stroke draws only the two slanted sides — a closed\n // path would rule a line straight across the arrow's base.\n // `-translate-y-px` then tucks that base a hairline under the\n // card, so the card's own border does not show through it. The\n // translate is applied inside Radix's rotation wrapper, so \"up\"\n // means \"towards the card\" on every side.\n <RadixPopover.Arrow asChild width={12} height={6}>\n <svg\n viewBox=\"0 0 12 6\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n className=\"ds:-translate-y-px ds:fill-[var(--popover)] ds:stroke-[color:var(--card-border)]\"\n >\n <path d=\"M0 0 L6 6 L12 0\" strokeLinejoin=\"round\" />\n </svg>\n </RadixPopover.Arrow>\n ) : null}\n </RadixPopover.Content>\n </RadixPopover.Portal>\n );\n },\n);\nHoverCardContent.displayName = 'HoverCard.Content';\n\n/* -------------------------------------------------------------------- */\n/* Slots */\n/* -------------------------------------------------------------------- */\n\n/** The media slot: an avatar row, a thumbnail, or a banner. Under\n * `padding=\"flush\"` it bleeds to the card's edge. */\nconst HoverCardMedia = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"media\"\n className={['ds:flex ds:items-center ds:gap-[var(--spacing-sm)]', className]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nHoverCardMedia.displayName = 'HoverCard.Media';\n\n/**\n * The card's category line, above the heading: \"Signing\", \"Billing\",\n * \"Anamnesis\". It says WHICH KIND of thing the reader is looking at, so a\n * card that appears under the pointer is self-describing without repeating\n * the chip's own words in the heading.\n *\n * Decorative by role: the heading carries the meaning and the accessible\n * name, so the eyebrow is quiet type and adds no landmark of its own.\n */\nconst HoverCardEyebrow = forwardRef<\n HTMLParagraphElement,\n HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n data-slot=\"eyebrow\"\n className={[\n 'ds:m-0 type-eyebrow ds:text-[color:var(--muted-foreground)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n));\nHoverCardEyebrow.displayName = 'HoverCard.Eyebrow';\n\nexport interface HoverCardHeadingProps extends HTMLAttributes<HTMLHeadingElement> {\n as?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n}\n\nconst HoverCardHeading = forwardRef<HTMLHeadingElement, HoverCardHeadingProps>(\n ({ as: Tag = 'h3', id: providedId, className, ...props }, ref) => {\n const generatedId = useId();\n const headingId = providedId ?? generatedId;\n const { setHeadingId } = useContext(A11yContext);\n const padding = useContext(PaddingContext);\n\n useEffect(() => {\n setHeadingId(headingId);\n return () => setHeadingId(undefined);\n }, [headingId, setHeadingId]);\n\n return (\n <Tag\n ref={ref}\n id={headingId}\n data-slot=\"heading\"\n className={[\n 'type-title-item ds:leading-snug ds:break-words',\n padding === 'flush'\n ? 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pt-[var(--spacing-md)]'\n : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n );\n },\n);\nHoverCardHeading.displayName = 'HoverCard.Heading';\n\n/** The body slot. A `div`, not a `p`: a hover card body routinely holds\n * KeyValuePairs and chips, and a `p` may only contain phrasing content. */\nconst HoverCardBody = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n const padding = useContext(PaddingContext);\n\n return (\n <div\n ref={ref}\n data-slot=\"body\"\n className={[\n 'type-body-sm ds:text-[var(--muted-foreground)]',\n 'ds:mt-[var(--spacing-xs)]',\n padding === 'flush'\n ? 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pb-[var(--spacing-md)]'\n : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n );\n});\nHoverCardBody.displayName = 'HoverCard.Body';\n\n/** The action row. Actions sit at the inline end; anything that should stay at\n * the inline start (a status badge) gets `ds:me-auto`. */\nconst HoverCardFooter = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => {\n const padding = useContext(PaddingContext);\n\n return (\n <div\n ref={ref}\n data-slot=\"footer\"\n className={[\n 'ds:flex ds:flex-wrap ds:items-center ds:justify-end',\n 'ds:gap-[var(--spacing-sm)]',\n 'ds:border-t ds:border-[color:var(--card-border)]',\n padding === 'flush'\n ? 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]'\n : 'ds:mt-[var(--spacing-md)] ds:pt-[var(--spacing-md)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...props}\n />\n );\n});\nHoverCardFooter.displayName = 'HoverCard.Footer';\n\n/* -------------------------------------------------------------------- */\n/* useHoverCardTiming */\n/* */\n/* Lets a CUSTOM anchored trigger — one that can't use `Trigger asChild` */\n/* because it already spends its one asChild slot elsewhere (a */\n/* DropdownMenu's own trigger, say) — share the SAME close timer */\n/* `Content` itself cancels/re-arms on hover and focus. Without this, */\n/* an anchored trigger that keeps its own separate close timer goes */\n/* stale the moment the pointer or focus moves onto the (portalled) */\n/* content: `Content`'s built-in handlers cancel ROOT's timer, which */\n/* was never the one counting down, so the card closes under the user's */\n/* cursor. Call this from a descendant of `HoverCard` (anywhere inside */\n/* the tree the Root provides context to), drive your own open timing, */\n/* but always close through `closeWithDelay` / `cancelClose` here — */\n/* never a private `setTimeout`. */\n/* -------------------------------------------------------------------- */\nexport function useHoverCardTiming(): {\n cancelClose: () => void;\n closeWithDelay: () => void;\n} {\n const { cancelClose, closeWithDelay } = useContext(RootContext);\n return { cancelClose, closeWithDelay };\n}\n\n/* -------------------------------------------------------------------- */\n\nexport const HoverCard = Object.assign(HoverCardRoot, {\n Root: HoverCardRoot,\n Trigger: HoverCardTrigger,\n // Anchor the card to an arbitrary element when a trigger button is\n // unsuitable, such as a calendar grid cell.\n Anchor: HoverCardAnchor,\n Content: HoverCardContent,\n Media: HoverCardMedia,\n Eyebrow: HoverCardEyebrow,\n Heading: HoverCardHeading,\n Body: HoverCardBody,\n Footer: HoverCardFooter,\n});\n"],"names":["hoverCardAgent","handle","resolvePhysicalSide","logicalSide","isRtl","A11yContext","createContext","RootContext","PaddingContext","contentVariants","cva","HoverCardRoot","children","openOn","controlledOpen","defaultOpen","onOpenChange","openDelay","closeDelay","id","internalOpen","setInternalOpen","useState","isControlled","isOpen","setOpen","useCallback","next","isOpenRef","useRef","useEffect","timerRef","clearTimer","focusOnOpenRef","movedFocusRef","contentRef","triggerRef","openWithDelay","closeWithDelay","suppressFocusOpenRef","suppressTimerRef","noteFocusReturn","openOnFocus","focusContent","_a","focusWasInsideRef","notePressStart","content","handleTriggerClick","focusWasInside","agentHandle","useMemo","useAgentRegistration","headingId","setHeadingId","isHoverMode","rootValue","node","triggerValue","jsx","TriggerContext","RadixPopover","HoverCardTrigger","forwardRef","onMouseEnter","onMouseLeave","onFocus","onBlur","onPointerDown","onKeyDown","onClick","props","ref","ctx","useContext","setRefs","event","HoverCardAnchor","HoverCardContent","side","align","size","padding","showArrow","showClose","headerAction","providedDirection","className","onOpenAutoFocus","onCloseAutoFocus","onFocusCapture","root","t","useTranslation","setIsRtl","localRef","anchor","scoped","resolved","contentDirection","directionIsRtl","physicalSide","physicalAlign","jsxs","IconButton","X","HoverCardMedia","HoverCardEyebrow","HoverCardHeading","Tag","providedId","generatedId","useId","HoverCardBody","HoverCardFooter","useHoverCardTiming","cancelClose","HoverCard"],"mappings":"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"}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { jsxs as k, jsx as e } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as L } from "react";
|
|
3
|
-
import { c as j } from "./index-D2ZczOXr.js";
|
|
4
|
-
import { useTranslation as T } from "react-i18next";
|
|
5
|
-
import { E as z } from "./external-link-CY6zAXXU.js";
|
|
6
|
-
const E = j(
|
|
7
|
-
[
|
|
8
|
-
"ds:underline-offset-4",
|
|
9
|
-
"ds:rounded-[var(--radius-xs)]",
|
|
10
|
-
"ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none",
|
|
11
|
-
"ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid",
|
|
12
|
-
"ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]",
|
|
13
|
-
"ds:forced-colors:focus-visible:outline-[CanvasText]",
|
|
14
|
-
"ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50 ds:aria-disabled:no-underline"
|
|
15
|
-
].join(" "),
|
|
16
|
-
{
|
|
17
|
-
variants: {
|
|
18
|
-
intent: {
|
|
19
|
-
// `--primary` is 4.23:1 as text on the dark page, so the link
|
|
20
|
-
// re-points it (and its hover step) at `--primary-readable`, which
|
|
21
|
-
// differs only in the dark theme. The colour classes stay as they
|
|
22
|
-
// were: a host still on an older token sheet keeps today's look,
|
|
23
|
-
// and a consumer `className` wins or loses exactly as before.
|
|
24
|
-
default: "ds:[--primary:var(--primary-readable)] ds:[--primary-hover:var(--primary-readable-hover)] ds:text-primary ds:underline ds:hover:text-primary-hover ds:active:opacity-80",
|
|
25
|
-
subtle: "ds:text-muted-foreground ds:no-underline ds:hover:text-foreground ds:hover:underline ds:active:opacity-80",
|
|
26
|
-
inverted: "ds:text-primary-foreground ds:underline ds:hover:opacity-90 ds:active:opacity-80"
|
|
27
|
-
},
|
|
28
|
-
weight: {
|
|
29
|
-
normal: "ds:font-normal",
|
|
30
|
-
strong: "ds:font-semibold"
|
|
31
|
-
},
|
|
32
|
-
// When the link carries an icon, the anchor itself becomes a flex
|
|
33
|
-
// container so glyphs centre on the text optical centre — the
|
|
34
|
-
// previous `vertical-align: -0.125em` heuristic over-corrected when
|
|
35
|
-
// the link was the only thing on its line (e.g. each <li> of a
|
|
36
|
-
// vertical sidebar nav). Text-only links remain plain `inline` so
|
|
37
|
-
// they wrap naturally inside a paragraph.
|
|
38
|
-
hasIcon: {
|
|
39
|
-
no: "ds:inline",
|
|
40
|
-
yes: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
defaultVariants: {
|
|
44
|
-
intent: "default",
|
|
45
|
-
weight: "normal",
|
|
46
|
-
hasIcon: "no"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
), I = L(
|
|
50
|
-
({
|
|
51
|
-
href: f,
|
|
52
|
-
external: s = !1,
|
|
53
|
-
externalIcon: u = !0,
|
|
54
|
-
disabled: n = !1,
|
|
55
|
-
startIcon: i,
|
|
56
|
-
endIcon: a,
|
|
57
|
-
intent: o,
|
|
58
|
-
weight: m,
|
|
59
|
-
className: v,
|
|
60
|
-
children: p,
|
|
61
|
-
target: h,
|
|
62
|
-
rel: t,
|
|
63
|
-
onClick: r,
|
|
64
|
-
...g
|
|
65
|
-
}, y) => {
|
|
66
|
-
const { t: b } = T("ui"), x = s ? "_blank" : h, w = s ? [t, "noopener", "noreferrer"].filter(Boolean).join(" ") : t, d = b("link.opensInNewTab", "Opens in a new tab"), N = (c) => {
|
|
67
|
-
if (n) {
|
|
68
|
-
c.preventDefault();
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
r == null || r(c);
|
|
72
|
-
}, l = s && u;
|
|
73
|
-
return /* @__PURE__ */ k(
|
|
74
|
-
"a",
|
|
75
|
-
{
|
|
76
|
-
ref: y,
|
|
77
|
-
href: n ? void 0 : f,
|
|
78
|
-
role: n ? "link" : void 0,
|
|
79
|
-
"aria-disabled": n || void 0,
|
|
80
|
-
target: x,
|
|
81
|
-
rel: w || void 0,
|
|
82
|
-
onClick: N,
|
|
83
|
-
"data-component": "link",
|
|
84
|
-
"data-intent": o ?? "default",
|
|
85
|
-
className: E({
|
|
86
|
-
intent: o,
|
|
87
|
-
weight: m,
|
|
88
|
-
hasIcon: !!(i || a || l) ? "yes" : "no",
|
|
89
|
-
className: v
|
|
90
|
-
}),
|
|
91
|
-
...g,
|
|
92
|
-
children: [
|
|
93
|
-
i ? /* @__PURE__ */ e(
|
|
94
|
-
"span",
|
|
95
|
-
{
|
|
96
|
-
"aria-hidden": "true",
|
|
97
|
-
className: "ds:inline-flex ds:items-center ds:[&_svg]:size-[1em]",
|
|
98
|
-
children: i
|
|
99
|
-
}
|
|
100
|
-
) : null,
|
|
101
|
-
p,
|
|
102
|
-
l ? /* @__PURE__ */ e(
|
|
103
|
-
"span",
|
|
104
|
-
{
|
|
105
|
-
className: "ds:inline-flex ds:items-center",
|
|
106
|
-
"aria-label": d,
|
|
107
|
-
children: /* @__PURE__ */ e(z, { "aria-hidden": "true", className: "ds:size-[1em]" })
|
|
108
|
-
}
|
|
109
|
-
) : s ? (
|
|
110
|
-
// External wiring without the glyph — keep the SR-only
|
|
111
|
-
// "opens in new tab" announcement so the affordance reads.
|
|
112
|
-
/* @__PURE__ */ e("span", { className: "ds:sr-only", children: d })
|
|
113
|
-
) : a ? /* @__PURE__ */ e(
|
|
114
|
-
"span",
|
|
115
|
-
{
|
|
116
|
-
"aria-hidden": "true",
|
|
117
|
-
className: "ds:inline-flex ds:items-center ds:[&_svg]:size-[1em]",
|
|
118
|
-
children: a
|
|
119
|
-
}
|
|
120
|
-
) : null
|
|
121
|
-
]
|
|
122
|
-
}
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
);
|
|
126
|
-
I.displayName = "Link";
|
|
127
|
-
export {
|
|
128
|
-
I as L
|
|
129
|
-
};
|
|
130
|
-
//# sourceMappingURL=link-2HokYuIi.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"link-2HokYuIi.js","sources":["../../src/components/link/link.tsx"],"sourcesContent":["import { forwardRef, type AnchorHTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ExternalLink } from 'lucide-react';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n/**\n * Link is the semantic anchor primitive for inline navigation —\n * privacy / terms in form copy, external \"remote support\" links in\n * sidebars, in-paragraph references inside info-tip body copy.\n *\n * For action affordances that *look* like a link but trigger UI rather\n * than navigation, use `<Button intent=\"link\">` instead — the semantic\n * boundary matters for screen readers and keyboard users.\n */\nconst linkVariants = cva(\n [\n 'ds:underline-offset-4',\n 'ds:rounded-[var(--radius-xs)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50 ds:aria-disabled:no-underline',\n ].join(' '),\n {\n variants: {\n intent: {\n // `--primary` is 4.23:1 as text on the dark page, so the link\n // re-points it (and its hover step) at `--primary-readable`, which\n // differs only in the dark theme. The colour classes stay as they\n // were: a host still on an older token sheet keeps today's look,\n // and a consumer `className` wins or loses exactly as before.\n default:\n 'ds:[--primary:var(--primary-readable)] ds:[--primary-hover:var(--primary-readable-hover)] ds:text-primary ds:underline ds:hover:text-primary-hover ds:active:opacity-80',\n subtle:\n 'ds:text-muted-foreground ds:no-underline ds:hover:text-foreground ds:hover:underline ds:active:opacity-80',\n inverted:\n 'ds:text-primary-foreground ds:underline ds:hover:opacity-90 ds:active:opacity-80',\n },\n weight: {\n normal: 'ds:font-normal',\n strong: 'ds:font-semibold',\n },\n // When the link carries an icon, the anchor itself becomes a flex\n // container so glyphs centre on the text optical centre — the\n // previous `vertical-align: -0.125em` heuristic over-corrected when\n // the link was the only thing on its line (e.g. each <li> of a\n // vertical sidebar nav). Text-only links remain plain `inline` so\n // they wrap naturally inside a paragraph.\n hasIcon: {\n no: 'ds:inline',\n yes: 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]',\n },\n },\n defaultVariants: {\n intent: 'default',\n weight: 'normal',\n hasIcon: 'no',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface LinkProps\n extends\n Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>,\n VariantProps<typeof linkVariants> {\n /** Anchor target. Required — the whole point of the component. */\n href: string;\n /**\n * Flag the link as opening in a new browsing context. Automatically\n * adds `target=\"_blank\"` + `rel=\"noopener noreferrer\"` and renders a\n * trailing `ExternalLink` icon with an i18n'd aria-label.\n */\n external?: boolean;\n /**\n * Render the trailing external-link glyph. Default `true` — set to\n * `false` for surfaces (footer, social rows, dense nav) where the\n * indicator adds visual noise. The `target` / `rel` / \"opens in new\n * tab\" aria-label are still applied.\n */\n externalIcon?: boolean;\n /**\n * Render the link in a non-interactive disabled state. Strips `href`,\n * adds `aria-disabled` + `role=\"link\"`, suppresses the underline.\n * Prefer hiding the link entirely when possible — disabled links are\n * a usability anti-pattern outside of state-machine flows.\n */\n disabled?: boolean;\n /** Optional leading icon (inline-start). */\n startIcon?: ReactNode;\n /** Optional trailing icon (inline-end). Ignored when `external`. */\n endIcon?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(\n (\n {\n href,\n external = false,\n externalIcon = true,\n disabled = false,\n startIcon,\n endIcon,\n intent,\n weight,\n className,\n children,\n target,\n rel,\n onClick,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n const effectiveTarget = external ? '_blank' : target;\n const effectiveRel = external\n ? [rel, 'noopener', 'noreferrer'].filter(Boolean).join(' ')\n : rel;\n\n const externalLabel = t('link.opensInNewTab', 'Opens in a new tab');\n\n const handleClick: AnchorHTMLAttributes<HTMLAnchorElement>['onClick'] = (\n event,\n ) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n onClick?.(event);\n };\n\n const showExternalIcon = external && externalIcon;\n const hasIcon = Boolean(startIcon || endIcon || showExternalIcon);\n\n return (\n <a\n ref={ref}\n // When disabled, drop href so the link is not actionable; pair\n // with aria-disabled + role=\"link\" so AT still announces the\n // role (the implicit role disappears once href is removed).\n href={disabled ? undefined : href}\n role={disabled ? 'link' : undefined}\n aria-disabled={disabled || undefined}\n target={effectiveTarget}\n rel={effectiveRel || undefined}\n onClick={handleClick}\n data-component=\"link\"\n data-intent={intent ?? 'default'}\n className={linkVariants({\n intent,\n weight,\n hasIcon: hasIcon ? 'yes' : 'no',\n className,\n })}\n {...rest}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:[&_svg]:size-[1em]\"\n >\n {startIcon}\n </span>\n ) : null}\n {children}\n {showExternalIcon ? (\n <span\n className=\"ds:inline-flex ds:items-center\"\n aria-label={externalLabel}\n >\n <ExternalLink aria-hidden=\"true\" className=\"ds:size-[1em]\" />\n </span>\n ) : external ? (\n // External wiring without the glyph — keep the SR-only\n // \"opens in new tab\" announcement so the affordance reads.\n <span className=\"ds:sr-only\">{externalLabel}</span>\n ) : endIcon ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:[&_svg]:size-[1em]\"\n >\n {endIcon}\n </span>\n ) : null}\n </a>\n );\n },\n);\n\nLink.displayName = 'Link';\n"],"names":["linkVariants","cva","Link","forwardRef","href","external","externalIcon","disabled","startIcon","endIcon","intent","weight","className","children","target","rel","onClick","rest","ref","t","useTranslation","effectiveTarget","effectiveRel","externalLabel","handleClick","event","showExternalIcon","jsxs","jsx","ExternalLink"],"mappings":";;;;;AAkBA,MAAMA,IAAeC;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMN,SACE;AAAA,QACF,QACE;AAAA,QACF,UACE;AAAA,MAAA;AAAA,MAEJ,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR,QAAQ;AAAA,MAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQV,SAAS;AAAA,QACP,IAAI;AAAA,QACJ,KAAK;AAAA,MAAA;AAAA,IACP;AAAA,IAEF,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GA0CaC,IAAOC;AAAA,EAClB,CACE;AAAA,IACE,MAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,cAAAC,IAAe;AAAA,IACf,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,SAAAC;AAAA,IACA,QAAAC;AAAA,IACA,QAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,QAAAC;AAAA,IACA,KAAAC;AAAA,IACA,SAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAM,EAAE,GAAAC,EAAA,IAAMC,EAAe,IAAI,GAE3BC,IAAkBhB,IAAW,WAAWS,GACxCQ,IAAejB,IACjB,CAACU,GAAK,YAAY,YAAY,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,IACxDA,GAEEQ,IAAgBJ,EAAE,sBAAsB,oBAAoB,GAE5DK,IAAkE,CACtEC,MACG;AACH,UAAIlB,GAAU;AACZ,QAAAkB,EAAM,eAAA;AACN;AAAA,MACF;AACA,MAAAT,KAAA,QAAAA,EAAUS;AAAA,IACZ,GAEMC,IAAmBrB,KAAYC;AAGrC,WACE,gBAAAqB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAT;AAAA,QAIA,MAAMX,IAAW,SAAYH;AAAA,QAC7B,MAAMG,IAAW,SAAS;AAAA,QAC1B,iBAAeA,KAAY;AAAA,QAC3B,QAAQc;AAAA,QACR,KAAKC,KAAgB;AAAA,QACrB,SAASE;AAAA,QACT,kBAAe;AAAA,QACf,eAAad,KAAU;AAAA,QACvB,WAAWV,EAAa;AAAA,UACtB,QAAAU;AAAA,UACA,QAAAC;AAAA,UACA,SAnBU,GAAQH,KAAaC,KAAWiB,KAmBvB,QAAQ;AAAA,UAC3B,WAAAd;AAAA,QAAA,CACD;AAAA,QACA,GAAGK;AAAA,QAEH,UAAA;AAAA,UAAAT,IACC,gBAAAoB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,eAAY;AAAA,cACZ,WAAU;AAAA,cAET,UAAApB;AAAA,YAAA;AAAA,UAAA,IAED;AAAA,UACHK;AAAA,UACAa,IACC,gBAAAE;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,cAAYL;AAAA,cAEZ,UAAA,gBAAAK,EAACC,GAAA,EAAa,eAAY,QAAO,WAAU,gBAAA,CAAgB;AAAA,YAAA;AAAA,UAAA,IAE3DxB;AAAA;AAAA;AAAA,YAGF,gBAAAuB,EAAC,QAAA,EAAK,WAAU,cAAc,UAAAL,EAAA,CAAc;AAAA,cAC1Cd,IACF,gBAAAmB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,eAAY;AAAA,cACZ,WAAU;AAAA,cAET,UAAAnB;AAAA,YAAA;AAAA,UAAA,IAED;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AAEAP,EAAK,cAAc;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"marketplace-app-shell-Dcx-JEjg.js","sources":["../../src/brand/product-lockup/product-lockup.tsx","../../src/patterns/marketplace-app-shell/marketplace-app-shell.tsx"],"sourcesContent":["import { forwardRef, type ComponentPropsWithoutRef } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Trans, useTranslation } from 'react-i18next';\nimport { Logo } from '../../components/logo/logo';\nimport { AlfadocsLogoMark, AlfadocsLogoNeg } from '../logo-asset';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n// Outer lockup row. ~4px logical gap between the wordmark and the product\n// name (`--spacing-xs`), centre-aligned so the name's cap height sits\n// against the wordmark's letterforms.\nconst lockup = cva('ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]');\n\n// The product name. Marketing serif (Fraunces, `--font-serif`) — permitted\n// here because this file lives under `src/brand/`, never in `src/components/`\n// or `src/patterns/` (constraint 10). Sized to ~95% of the wordmark height so\n// its cap height matches the logo letterforms across every size and theme\n// (the `--logo-size-*` tokens shift up in the accessible themes; the calc\n// keeps the name proportional for free).\nconst productName = cva(\n [\n 'ds:[font-family:var(--font-serif)]',\n 'ds:font-semibold',\n 'ds:leading-none',\n 'ds:tracking-[0.01em]',\n 'ds:whitespace-nowrap',\n // Forced-colors: drop the transparent text-fill and paint the label\n // as solid CanvasText so it never disappears under Windows HCM —\n // a gradient/transparent fill has no meaning there.\n 'ds:forced-colors:text-[CanvasText]',\n 'ds:forced-colors:[-webkit-text-fill-color:CanvasText]',\n ],\n {\n variants: {\n size: {\n sm: 'ds:text-[calc(var(--logo-size-sm)*0.95)]',\n md: 'ds:text-[calc(var(--logo-size-md)*0.95)]',\n lg: 'ds:text-[calc(var(--logo-size-lg)*0.95)]',\n xl: 'ds:text-[calc(var(--logo-size-xl)*0.95)]',\n },\n tone: {\n // Brand gradient filled into the glyphs via background-clip:text.\n // `--gradient-wordmark` rides the theme aliases, so it stays\n // AA-safe and adapts per theme on its own (and flattens to a solid\n // ink in the accessible / forced-colors blocks — see tokens).\n gradient: [\n 'ds:italic',\n 'ds:bg-[image:var(--gradient-wordmark)]',\n 'ds:bg-clip-text',\n 'ds:text-transparent',\n 'ds:[-webkit-text-fill-color:transparent]',\n ],\n // Monochrome: solid currentColor ink, upright, no gradient — for\n // print, single-colour work, and coloured chrome (e.g. app-shell\n // headers) where the lockup must ride the surrounding ink.\n solid: 'ds:text-current',\n },\n },\n defaultVariants: { size: 'md', tone: 'gradient' },\n },\n);\n\n// Maker lockup root. Sets a single `--lockup-unit` custom property to the\n// matching `--logo-size-*` token; every maker sub-element (mark, name, the\n// \"by Alfadocs\" tag) sizes off `var(--lockup-unit)`, so there's one per-size\n// source of truth that shifts up with the accessible themes for free.\n// `whitespace-nowrap` keeps \"[mark] Name by Alfadocs\" on one line.\nconst makerRoot = cva('ds:whitespace-nowrap', {\n variants: {\n size: {\n sm: 'ds:[--lockup-unit:var(--logo-size-sm)]',\n md: 'ds:[--lockup-unit:var(--logo-size-md)]',\n lg: 'ds:[--lockup-unit:var(--logo-size-lg)]',\n xl: 'ds:[--lockup-unit:var(--logo-size-xl)]',\n },\n },\n defaultVariants: { size: 'md' },\n});\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\ntype LockupSize = NonNullable<VariantProps<typeof productName>['size']>;\n\nexport type ProductLockupProps = {\n /**\n * The product name. Passed verbatim (product names are not translated).\n *\n * - `variant=\"standard\"` (default): renders as \"Alfadocs <name>\" with the\n * wordmark; accessible name is `Alfadocs <name>`.\n * - `variant=\"maker\"`: renders as \"[mark] <name> by Alfadocs\"; accessible\n * name is `<name> by Alfadocs`.\n */\n name: string;\n /**\n * Which lockup composition to use.\n *\n * - `'standard'` (default) — Alfadocs wordmark + product name (\"Alfadocs\n * Builders\"). Use for **internal** Alfadocs products (Alfadocs Builders,\n * Alfadocs API) where the product is part of the Alfadocs family.\n * - `'maker'` — \"<name> by Alfadocs\" with the four-pillar mark and the name\n * as the prominent element. Use for **external** marketplace extensions\n * (\"Scribe by Alfadocs\") where the extension's own name leads and\n * \"by Alfadocs\" is the maker attribution.\n */\n variant?: 'standard' | 'maker';\n /**\n * Render the name as a solid `--foreground` ink, upright (no gradient, no\n * italic), and pair it with the monochrome wordmark. Use for print,\n * single-colour reproductions, or any constrained context where the\n * gradient/serif treatment is inappropriate.\n */\n monochrome?: boolean;\n /**\n * Ink resolution. `'auto'` (default) uses the lockup's intended ink\n * (`--foreground` for monochrome). `'inherit'` makes the whole lockup ride\n * `currentColor` — use it with `monochrome` on a coloured brand surface (a\n * tinted header or split-login panel) so the wordmark + name both take the\n * surface's text colour rather than clashing with a fixed `--foreground`.\n */\n tone?: 'auto' | 'inherit';\n /** Lockup size. Drives both the wordmark and the name's cap height. */\n size?: LockupSize;\n className?: string;\n} & Omit<\n ComponentPropsWithoutRef<'span'>,\n 'role' | 'aria-label' | 'aria-hidden' | 'children' | 'className'\n>;\n\n/* ------------------------------------------------------------------ */\n/* ProductLockup */\n/* ------------------------------------------------------------------ */\n\n/**\n * Pairs a product name with the Alfadocs brand. Two compositions:\n *\n * - `variant=\"standard\"` (default) — the Alfadocs wordmark + product name\n * (\"Alfadocs Builders\"). For internal Alfadocs products. Exposed to\n * assistive tech as a single `img` named `Alfadocs <name>`.\n * - `variant=\"maker\"` — \"[mark] <name> by Alfadocs\". For external marketplace\n * extensions where the extension's name leads. Exposed as a single `img`\n * named `<name> by Alfadocs`.\n *\n * In both cases the inner wordmark/mark and the visible name are decorative so\n * the brand isn't announced twice. Every marketplace app should use this\n * rather than hand-rolling a wordmark + typed span.\n */\nexport const ProductLockup = forwardRef<HTMLSpanElement, ProductLockupProps>(\n (\n {\n name,\n variant = 'standard',\n monochrome = false,\n tone = 'auto',\n size = 'md',\n className,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n if (import.meta.env.DEV && !name.trim()) {\n console.warn(\n '[ProductLockup] `name` is empty — the lockup will render the bare wordmark with no product name. Pass the product name (e.g. \"Builders\").',\n );\n }\n\n if (variant === 'maker') {\n // Ink matrix mirrors the standard variant's tone/monochrome model:\n // - tone=\"inherit\": every element rides currentColor (no explicit ink),\n // for coloured surfaces.\n // - monochrome (tone auto): foreground ink, with the attribution muted.\n // - default (colour, tone auto): the name + mark take --primary; the\n // wordmark lettering stays --foreground; the attribution is muted.\n const inherit = tone === 'inherit';\n const markInk = inherit\n ? ''\n : monochrome\n ? 'ds:text-[color:var(--foreground)]'\n : 'ds:text-[color:var(--primary)]';\n const nameInk = inherit\n ? ''\n : monochrome\n ? 'ds:text-[color:var(--foreground)]'\n : 'ds:text-[color:var(--primary)]';\n const byInk = inherit ? '' : 'ds:text-[color:var(--muted-foreground)]';\n const letteringInk = inherit ? '' : 'ds:text-[color:var(--foreground)]';\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={t('productLockup.makerLabel', { name: name.trim() })}\n className={makerRoot({ size, className })}\n data-component=\"product-lockup\"\n {...props}\n >\n {/* Pillar mark sized close to the app name (≈0.88 of the serif em),\n vertically centred on it. Inline (not flex) so the maker tag can\n use vertical-align. */}\n <AlfadocsLogoMark\n aria-hidden\n className={`ds:inline-block ds:align-middle ds:me-[var(--spacing-sm)] ds:h-[calc(var(--lockup-unit)*0.88)] ds:w-auto ds:forced-colors:text-[CanvasText] ${markInk}`}\n />\n <span\n aria-hidden\n className={`ds:align-middle ds:[font-family:var(--font-serif)] ds:font-semibold ds:italic ds:leading-none ds:tracking-[0.01em] ${nameInk} ds:text-[calc(var(--lockup-unit)*0.95)]`}\n >\n {name}\n </span>\n {/* Maker tag — superscript style, its top aligned to the app name's\n cap-height via vertical-align: text-top. */}\n <span\n aria-hidden\n className={`ds:align-text-top ds:ms-[var(--spacing-sm)] ds:inline-flex ds:items-baseline ds:gap-[var(--spacing-2xs)] ${byInk}`}\n >\n <Trans\n ns=\"ui\"\n t={t}\n i18nKey=\"productLockup.attribution\"\n components={{\n text: (\n <span className=\"ds:text-[calc(var(--lockup-unit)*0.4)] ds:leading-none\" />\n ),\n brand: (\n <AlfadocsLogoNeg\n aria-hidden\n viewBox=\"168 0 637 125\"\n className={`ds:h-[calc(var(--lockup-unit)*0.45)] ds:w-auto ds:forced-colors:text-[CanvasText] ${letteringInk}`}\n />\n ),\n }}\n />\n </span>\n </span>\n );\n }\n\n return (\n <span\n ref={ref}\n role=\"img\"\n aria-label={`Alfadocs ${name}`.trim()}\n className={lockup({ className })}\n data-component=\"product-lockup\"\n {...props}\n >\n <Logo\n variant={monochrome ? 'monochrome' : 'wordmark'}\n tone={tone}\n size={size}\n decorative\n />\n <span\n aria-hidden\n className={productName({\n size,\n tone: monochrome ? 'solid' : 'gradient',\n })}\n >\n {name}\n </span>\n </span>\n );\n },\n);\nProductLockup.displayName = 'ProductLockup';\n","/**\n * Marketplace App Shell — the standard chrome for an app built on top of\n * AlfaDocs (the kind a partner scaffolds with Claude Code, Lovable, etc.).\n *\n * It is a thin, opinionated composition of kit primitives: an `AppFrame` with\n * a branded `Header` (the maker `ProductLockup` — \"<Product> by Alfadocs\" —\n * rendered `monochrome` so it rides the header's ink; maker is the lockup\n * style for external marketplace extensions), a `Sidebar` for app\n * navigation, `HeaderSettings` (theme/locale/accessibility), and a bare-avatar\n * account menu (fullscreen + sign-out) matching the main app shell.\n * `ConnectWithAlfadocs` is the matching pre-auth screen, with the full-colour\n * maker lockup and `SignInWithAlfadocsButton`.\n *\n * Like `AliaSidebar`, this pattern ships a RUNTIME component (surfaced via\n * `src/patterns/index.ts` and the library bundle) because consuming apps mount\n * it in production rather than copying the source.\n *\n * Auth is intentionally decoupled: the shell takes the signed-in `user` and an\n * `onSignOut` callback as props, and `ConnectWithAlfadocs` takes a `status` +\n * `onConnect`. Wire them to `@alfadocs/auth/react`'s `useAlfadocsAuth()` in the\n * consuming app — the kit never touches OAuth or secrets (those live in the\n * server-side `@alfadocs/auth` BFF).\n *\n * All user-visible copy is consumer-provided (props) so each app localises in\n * its own i18n; the only kit-owned strings reuse existing translated `ui.*`\n * keys (sidebar label, skip link, menu button).\n */\nimport { forwardRef, useState, type MouseEvent, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport { LogOut, Maximize2 } from 'lucide-react';\n\nimport { AppFrame } from '../../components/app-frame';\nimport { Avatar } from '../../components/avatar';\nimport { Alert } from '../../components/alert';\nimport { Card } from '../../components/card';\nimport { DropdownMenu } from '../../components/dropdown-menu';\nimport { TabBar } from '../../components/tab-bar';\nimport {\n Header,\n HeaderBrand,\n HeaderCenter,\n HeaderEnd,\n HeaderMenuButton,\n HeaderSkipLink,\n HeaderStart,\n} from '../../components/header';\nimport { HeaderSettings } from '../../components/header-settings';\nimport { ProductLockup } from '../../brand/product-lockup';\nimport { SignInWithAlfadocsButton } from '../../components/sign-in-with-alfadocs-button';\nimport {\n Sidebar,\n SidebarBody,\n SidebarCollapseTrigger,\n SidebarHeader,\n SidebarItem,\n SidebarItemBadge,\n SidebarItemIcon,\n SidebarItemLabel,\n type SidebarMode,\n} from '../../components/sidebar';\nimport { ThemeRoot } from '../../components/theme-root';\nimport { TooltipProvider } from '../../components/tooltip';\nimport { useTheme } from '../../hooks/use-theme';\n\n/* ------------------------------------------------------------------ */\n/* Public API */\n/* ------------------------------------------------------------------ */\n\nexport interface MarketplaceNavItem {\n id: string;\n /** Pre-translated label — apps localise their own nav copy. */\n label: string;\n href: string;\n /** Optional leading icon (a lucide-react element or equivalent). */\n icon?: ReactNode;\n /** Optional unseen-item count rendered as a pill badge. */\n badgeCount?: number;\n /** Mark the item as the current page (`aria-current='page'`). */\n isActive?: boolean;\n /**\n * Optional click handler threaded onto the nav link's `<a>`. The lightweight\n * alternative to `renderLink`: intercept a same-origin click (call\n * `event.preventDefault()`) and route client-side without a full page load —\n * no router `<Link>` needed. Applies to both the standalone sidebar item and\n * the embedded tab. When `renderLink` is supplied it's handed through to the\n * consumer's link element instead.\n */\n onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;\n}\n\n/**\n * Props the shell hands to `renderLink` for each nav item. The consumer returns\n * their router's `<Link to={href}>` carrying the same `className` (the kit's\n * active styling) and `aria-current` (`'page'` on the active item) so a tab /\n * sidebar-item click is a client-side route change, not a full page reload.\n */\nexport interface MarketplaceRenderLinkProps {\n /** The item's destination — feed it to your router's `to` / `href`. */\n href: string;\n /** The kit's classes — apply verbatim to the link element. */\n className?: string;\n /** Icon + label + badge — render as the link's children. */\n children: ReactNode;\n /** `'page'` on the active item, otherwise omitted — forward to the link. */\n 'aria-current'?: 'page';\n /**\n * The item's stable id, as the agent / automation DOM hook. Spread it onto\n * your router link so the item stays addressable by `[data-tab-id]` — see\n * PRS §26 §6. Only supplied on the bottom-tab-bar path.\n */\n 'data-tab-id'?: string;\n}\n\n/**\n * Render a nav item through the consumer's router instead of the kit's own\n * `<a>`. Returned by the consumer; the shell forwards `href`, the kit's\n * `className`, the item children, and `aria-current` so the active styling and\n * the `aria-current=\"page\"` marker survive a client-side route change.\n */\nexport type MarketplaceRenderLink = (\n props: MarketplaceRenderLinkProps,\n) => ReactNode;\n\nexport interface MarketplaceAppUser {\n /** Display name — drives the avatar initials + the account-menu header. */\n name: string;\n /** Optional email shown under the name in the account menu. */\n email?: string;\n /** Optional avatar image URL. */\n avatarSrc?: string;\n}\n\nexport interface MarketplaceAppShellLabels {\n /** Accessible name for the account-menu trigger, e.g. \"Account menu\". */\n accountMenu: string;\n /** The sign-out menu item, e.g. \"Sign out\". */\n signOut: string;\n /**\n * Optional fullscreen menu item label, e.g. \"Toggle fullscreen\". The item\n * renders whenever `onToggleFullscreen` is supplied; when this label is\n * omitted it falls back to the translated `ui.*` \"Toggle fullscreen\" string.\n */\n fullscreen?: string;\n}\n\nexport interface MarketplaceAppShellProps {\n /** Extension name — renders as the maker lockup \"<productName> by Alfadocs\". */\n productName: string;\n /** Link target for the brand lockup. Default `'/'`. */\n productHref?: string;\n /** Sidebar nav items, in order. */\n nav: MarketplaceNavItem[];\n /**\n * Render nav items (and the brand lockup) through the consumer's router so a\n * tab / item click is a client-side route change with **no full-page reload\n * or session flash**. Wire it to your router's `<Link>`:\n *\n * ```tsx\n * import { Link } from '@tanstack/react-router';\n * <MarketplaceAppShell\n * nav={nav}\n * renderLink={({ href, className, children, ...rest }) => (\n * <Link to={href} className={className} {...rest}>{children}</Link>\n * )}\n * />\n * ```\n *\n * Threaded to the standalone sidebar items, the embedded top tab strip, and\n * the brand lockup. The kit forwards the same `className` + `aria-current` so\n * the active styling and the `aria-current=\"page\"` marker survive in both\n * modes. Omit it to render the plain `<a href>` exactly as before — non-routed\n * consumers are byte-for-byte unaffected. A per-item `onClick` (a\n * click-interceptor shim) is the lighter alternative when you don't want to\n * thread a router `<Link>`.\n */\n renderLink?: MarketplaceRenderLink;\n /** The signed-in user shown in the account menu. */\n user: MarketplaceAppUser;\n /** Consumer-localised chrome labels owned by the shell. */\n labels: MarketplaceAppShellLabels;\n /** Fires when the user picks \"Sign out\". Wire to `useAlfadocsAuth().signOut`. */\n onSignOut?: () => void;\n /** Fires when the user toggles fullscreen. Omit to hide the fullscreen item. */\n onToggleFullscreen?: () => void;\n /**\n * Force the sidebar into a specific mode. Apps typically flip to `'overlay'`\n * on narrow viewports and leave this undefined elsewhere (defaults to\n * `'expanded'`).\n */\n sidebarState?: SidebarMode;\n /**\n * Render a collapse/expand toggle in the sidebar header, letting the user\n * shrink the standalone sidebar to an icon rail. The chosen mode persists\n * per-user (the underlying `Sidebar` stores it) and survives reloads. Opt-in\n * so existing consumers are unaffected; ignored when `sidebarState` forces a\n * mode or in the `'embedded'` variant (no sidebar). @default false\n */\n collapsibleSidebar?: boolean;\n /** Override the accessible name of the `<main>` landmark. */\n mainAriaLabel?: string;\n /**\n * Chrome variant. `'standalone'` (default) renders the full shell — branded\n * Header, Sidebar, and account menu. `'embedded'` is for apps running INSIDE\n * the AlfaDocs platform iframe (consumers detect this with\n * `window !== window.top`): it drops the Header, Sidebar, account menu, and\n * product lockup — the platform already brands and identifies the session\n * around the iframe — and renders the `nav` items as a single slim top tab\n * strip. `onSignOut`, `onToggleFullscreen`, `productName`, `productHref`, and\n * `sidebarState` are ignored in `'embedded'`; the `<main>` landmark,\n * `mainAriaLabel`, and the skip link are kept.\n */\n variant?: 'standalone' | 'embedded';\n /** Children render inside the main content region. */\n children: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Internals */\n/* ------------------------------------------------------------------ */\n\nfunction formatBadgeCount(count: number): string {\n return count > 99 ? '99+' : String(count);\n}\n\nfunction AccountMenu({\n user,\n labels,\n onSignOut,\n onToggleFullscreen,\n}: {\n user: MarketplaceAppUser;\n labels: MarketplaceAppShellLabels;\n onSignOut?: () => void;\n onToggleFullscreen?: () => void;\n}) {\n const { t } = useTranslation('ui');\n // Default to the translated `ui.*` label so a consumer that wires\n // `onToggleFullscreen` but omits the label still gets a localised item.\n const fullscreenLabel =\n labels.fullscreen ?? t('marketplaceAppShell.settings.fullscreen');\n return (\n // Non-modal: an account menu shouldn't inert/aria-hide the whole shell\n // behind it (which leaves the still-focusable chrome inside an\n // aria-hidden region — an `aria-hidden-focus` violation).\n <DropdownMenu.Root modal={false}>\n <DropdownMenu.Trigger asChild>\n {/* Bare avatar circle — matches the main app shell's account\n trigger. The name lives inside the menu, not beside the avatar. */}\n <button\n type=\"button\"\n aria-label={labels.accountMenu}\n data-testid=\"marketplace-account-trigger\"\n className=\"ds:inline-flex ds:items-center ds:justify-center ds:shrink-0 ds:size-10 ds:rounded-[var(--radius-full)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:forced-colors:focus-visible:outline-[CanvasText]\"\n >\n <span aria-hidden=\"true\">\n <Avatar name={user.name} src={user.avatarSrc} size=\"md\" />\n </span>\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"end\" collisionPadding={16}>\n {/* GitHub-style identity header — small avatar + name + secondary\n line, matching the main app shell's account menu. */}\n <DropdownMenu.Label>\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <span aria-hidden=\"true\">\n <Avatar name={user.name} src={user.avatarSrc} size=\"sm\" />\n </span>\n <span className=\"ds:flex ds:flex-col ds:min-w-0\">\n <span className=\"type-label ds:text-[color:var(--foreground)] ds:truncate\">\n {user.name}\n </span>\n {user.email ? (\n <span className=\"type-meta ds:truncate\">{user.email}</span>\n ) : null}\n </span>\n </span>\n </DropdownMenu.Label>\n {onToggleFullscreen ? (\n <>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n startIcon={<Maximize2 aria-hidden />}\n onSelect={onToggleFullscreen}\n data-testid=\"marketplace-fullscreen\"\n >\n {fullscreenLabel}\n </DropdownMenu.Item>\n </>\n ) : null}\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n startIcon={<LogOut aria-hidden />}\n onSelect={onSignOut}\n data-testid=\"marketplace-sign-out\"\n >\n {labels.signOut}\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\nfunction MarketplaceSidebarNav({\n nav,\n renderLink,\n}: {\n nav: MarketplaceNavItem[];\n renderLink?: MarketplaceRenderLink;\n}) {\n return (\n <SidebarBody>\n {nav.map((item) => {\n const badge =\n typeof item.badgeCount === 'number' && item.badgeCount > 0\n ? item.badgeCount\n : undefined;\n const inner = (\n <>\n {item.icon ? <SidebarItemIcon>{item.icon}</SidebarItemIcon> : null}\n <SidebarItemLabel>{item.label}</SidebarItemLabel>\n {badge !== undefined ? (\n <SidebarItemBadge>{formatBadgeCount(badge)}</SidebarItemBadge>\n ) : null}\n </>\n );\n\n // Consumer-router mode: render the item through Radix `Slot`\n // (`SidebarItem asChild`) so the consumer's `<Link>` takes over the\n // anchor while keeping the kit's item styling + `aria-current=\"page\"`.\n // Clicking routes client-side — no full-page reload.\n if (renderLink) {\n return (\n <SidebarItem key={item.id} asChild isActive={item.isActive}>\n {renderLink({\n href: item.href,\n children: inner,\n 'aria-current': item.isActive ? 'page' : undefined,\n })}\n </SidebarItem>\n );\n }\n\n // Default: plain anchor — byte-identical to before when no per-item\n // `onClick` is supplied (it's omitted entirely, not passed as\n // undefined, so the rendered `<a>` is unchanged).\n return (\n <SidebarItem\n key={item.id}\n href={item.href}\n aria-label={item.label}\n isActive={item.isActive}\n {...(item.onClick ? { onClick: item.onClick } : {})}\n >\n {inner}\n </SidebarItem>\n );\n })}\n </SidebarBody>\n );\n}\n\n/* CVA for the chrome variant — drives the `<main>` surface; the structural\n header/sidebar-vs-tab-strip difference is conditional in the render.\n\n The `standalone` `<main>` gets its content inset from AppFrame's own\n `mainVariants({ padded: true })` (`--spacing-md` on every logical side), so\n this variant only carries the canvas colour there. The `embedded` `<main>`\n is a plain element (no AppFrame), so it has to supply its own inset:\n `--spacing-md` inline + block-end to match the standalone inset, and a\n larger `--spacing-lg` block-start so content clears the floating tab strip's\n pill instead of butting up against it. All logical — RTL mirrors for free. */\nconst shellMainVariants = cva('ds:bg-[color:var(--app-shell-background)]', {\n variants: {\n variant: {\n standalone: '',\n embedded: [\n 'ds:flex-1',\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n 'ds:pt-[var(--spacing-lg)] ds:pb-[var(--spacing-md)]',\n ].join(' '),\n },\n },\n defaultVariants: { variant: 'standalone' },\n});\n\n/**\n * Embedded chrome: the slim floating tab strip (no Header / Sidebar / account\n * menu) for apps running inside the AlfaDocs platform iframe. It's the shared\n * {@link TabBar} fed the shell's nav items — the platform brands and identifies\n * the session around the iframe, so the strip is the only chrome. The\n * `MarketplaceNavItem` shape is structurally a `TabBarItem`, so the nav passes\n * straight through.\n */\nfunction EmbeddedTabStrip({\n nav,\n ariaLabel,\n renderLink,\n}: {\n nav: MarketplaceNavItem[];\n ariaLabel: string;\n renderLink?: MarketplaceRenderLink;\n}) {\n // Adapt the shell's `renderLink` to TabBar's `renderLink` signature — TabBar\n // also offers the per-item `onClick`, but in consumer-router mode the\n // `<Link>` owns navigation (matching the standalone sidebar), so we forward\n // only `href` / `className` / `children` / `aria-current`. With `renderLink`\n // omitted, TabBar renders its own plain `<a href>` exactly as before, and a\n // per-item `onClick` rides through `nav` → `TabBarItem` untouched.\n const tabRenderLink = renderLink\n ? ({\n href,\n className,\n children,\n 'aria-current': ariaCurrent,\n 'data-tab-id': tabId,\n }: {\n href: string;\n className: string;\n children: ReactNode;\n 'aria-current'?: 'page';\n 'data-tab-id'?: string;\n }) =>\n renderLink({\n href,\n className,\n children,\n 'aria-current': ariaCurrent,\n // Forward the agent DOM hook — without it a consumer-router tab is\n // invisible to `[data-tab-id]` lookups (PRS §26 §6).\n 'data-tab-id': tabId,\n })\n : undefined;\n\n return (\n <TabBar\n items={nav}\n ariaLabel={ariaLabel}\n {...(tabRenderLink ? { renderLink: tabRenderLink } : {})}\n />\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* MarketplaceAppShell */\n/* ------------------------------------------------------------------ */\n\nexport const MarketplaceAppShell = forwardRef<\n HTMLDivElement,\n MarketplaceAppShellProps\n>(\n (\n {\n productName,\n productHref = '/',\n nav,\n renderLink,\n user,\n labels,\n onSignOut,\n onToggleFullscreen,\n sidebarState,\n collapsibleSidebar = false,\n mainAriaLabel,\n variant = 'standalone',\n children,\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n // The brand lockup as a consumer-router link: when `renderLink` is\n // supplied, the brand anchor routes client-side too (no session flash when\n // jumping home). The maker lockup's \"<productName> by Alfadocs\" supplies\n // the link's accessible name, matching the default `HeaderBrand` anchor.\n const headerBrand = renderLink ? (\n <HeaderBrand asChild>\n {renderLink({\n href: productHref,\n children: (\n <ProductLockup\n name={productName}\n size=\"md\"\n monochrome\n variant=\"maker\"\n />\n ),\n })}\n </HeaderBrand>\n ) : (\n <HeaderBrand\n href={productHref}\n logo={\n <ProductLockup\n name={productName}\n size=\"md\"\n monochrome\n variant=\"maker\"\n />\n }\n />\n );\n\n // Only wrap in a nested ThemeRoot when the user has an\n // explicit theme/accessibility override, so we don't clobber the consuming\n // app's (or Storybook's) outer theme cascade.\n const { theme: themePref, accessibility, resolvedTheme } = useTheme();\n const hasExplicitOverride =\n themePref !== 'system' || accessibility !== 'system';\n const themeBase = resolvedTheme.startsWith('dark') ? 'dark' : 'light';\n const themeAccessible = resolvedTheme.endsWith('-accessible');\n\n // Narrow-viewport overlay: HeaderMenuButton only renders below `md`.\n const [sidebarOpen, setSidebarOpen] = useState(false);\n\n const shell = (\n <TooltipProvider>\n <AppFrame\n mainAriaLabel={mainAriaLabel}\n mainClassName={shellMainVariants({ variant: 'standalone' })}\n header={\n <Header>\n <HeaderStart>\n <HeaderSkipLink href=\"#main-content\" />\n <HeaderMenuButton onMenuOpen={() => setSidebarOpen(true)} />\n {headerBrand}\n </HeaderStart>\n <HeaderCenter />\n <HeaderEnd>\n <HeaderSettings size=\"sm\" />\n <AccountMenu\n user={user}\n labels={labels}\n onSignOut={onSignOut}\n onToggleFullscreen={onToggleFullscreen}\n />\n </HeaderEnd>\n </Header>\n }\n sidebar={\n <Sidebar\n {...(sidebarState !== undefined\n ? { state: sidebarState }\n : { defaultState: 'expanded' as const })}\n open={sidebarOpen}\n onOpenChange={setSidebarOpen}\n aria-label={t('navigation.sidebar.label')}\n data-testid=\"marketplace-app-shell-sidebar\"\n >\n {collapsibleSidebar && sidebarState === undefined ? (\n // No justify override: SidebarHeader centres its child in the\n // icon rail (`justify-center`) and left-aligns it when expanded,\n // matching the nav icons below. `justify-end` here would win over\n // the icon-mode centring and offset the toggle in the rail.\n <SidebarHeader>\n <SidebarCollapseTrigger />\n </SidebarHeader>\n ) : null}\n <MarketplaceSidebarNav nav={nav} renderLink={renderLink} />\n </Sidebar>\n }\n >\n {children}\n </AppFrame>\n </TooltipProvider>\n );\n\n const embedded = (\n // The shell owns the warm-grey canvas; TabBar's strip is transparent and\n // floats its pill on it, and `<main>` continues the same surface.\n <div className=\"ds:flex ds:min-h-dvh ds:flex-col ds:bg-[color:var(--app-shell-background)]\">\n <HeaderSkipLink href=\"#main-content\" />\n <EmbeddedTabStrip\n nav={nav}\n ariaLabel={t('navigation.sidebar.label')}\n renderLink={renderLink}\n />\n <main\n id=\"main-content\"\n tabIndex={-1}\n aria-label={\n mainAriaLabel ?? t('navigation.main.label', 'Main content')\n }\n className={shellMainVariants({ variant: 'embedded' })}\n >\n {children}\n </main>\n </div>\n );\n\n const content = variant === 'embedded' ? embedded : shell;\n\n if (!hasExplicitOverride) {\n return (\n <div\n ref={ref}\n className=\"ds:contents\"\n data-component=\"marketplace-app-shell\"\n >\n {content}\n </div>\n );\n }\n\n return (\n <ThemeRoot\n ref={ref}\n theme={themeBase}\n accessible={themeAccessible}\n className=\"ds:contents\"\n data-component=\"marketplace-app-shell\"\n >\n {content}\n </ThemeRoot>\n );\n },\n);\n\nMarketplaceAppShell.displayName = 'MarketplaceAppShell';\n\n/* ------------------------------------------------------------------ */\n/* ConnectWithAlfadocs */\n/* ------------------------------------------------------------------ */\n\nexport type ConnectStatus = 'idle' | 'connecting' | 'error';\n\nexport interface ConnectWithAlfadocsProps {\n /** Product name shown next to the wordmark at the top of the card. */\n productName: string;\n /** Heading, e.g. \"Connect your AlfaDocs account\". */\n title: string;\n /** Supporting copy below the heading. */\n description: ReactNode;\n /** The connect button label, e.g. \"Connect with AlfaDocs\". */\n connectLabel: string;\n /** Connection lifecycle. `connecting` shows a loading button; `error` shows the alert. */\n status?: ConnectStatus;\n /** Error message shown (as an alert) when `status === 'error'`. */\n error?: ReactNode;\n /** Fires when the connect button is pressed. Wire to `useAlfadocsAuth().connect`. */\n onConnect?: () => void;\n /** Optional footer content below the button (e.g. a \"what's this?\" link). */\n footer?: ReactNode;\n /**\n * Visual layout. `'card'` (default) is the centred card on the warm-grey\n * canvas — unchanged. `'split'` adds, at `lg:` and up, a two-panel desktop\n * layout: a brand panel on the inline-start and the connect card on the\n * inline-end. Below `lg:`, `'split'` collapses to exactly the card layout —\n * so it falls back gracefully inside iframes / embeds that never reach\n * desktop width. Use `'split'` for full-page desktop logins.\n */\n layout?: 'card' | 'split';\n /**\n * Optional content shown under the lockup in the `'split'` brand panel (a\n * tagline, value props, an illustration). Ignored in `'card'` and below `lg:`.\n */\n brandPanel?: ReactNode;\n className?: string;\n}\n\n/* Split-layout CVAs (lg+ two-panel; collapses to the centred card below lg). */\nconst connectRootVariants = cva(\n 'ds:flex ds:min-h-dvh ds:bg-[color:var(--app-shell-background)]',\n {\n variants: {\n layout: {\n card: '',\n split: 'ds:flex-col ds:lg:flex-row',\n },\n },\n defaultVariants: { layout: 'card' },\n },\n);\n\nconst connectCardWidthVariants = cva('ds:w-full', {\n variants: {\n layout: {\n card: 'ds:max-w-[400px]',\n split: 'ds:max-w-[400px] ds:lg:max-w-[480px]',\n },\n },\n defaultVariants: { layout: 'card' },\n});\n\n// The card's own lockup hides at lg+ in `split` (the brand panel shows it there).\nconst connectCardLockupVariants = cva('', {\n variants: {\n layout: { card: '', split: 'ds:lg:hidden' },\n },\n defaultVariants: { layout: 'card' },\n});\n\n/**\n * The pre-auth \"Connect with AlfaDocs\" screen. Centred white card on the\n * warm-grey canvas with the AlfaDocs wordmark + product name, copy, an error\n * slot, and the primary connect CTA. An opt-in `layout=\"split\"` adds a desktop\n * two-panel brand layout (lg+). Presentational — `onConnect` should call\n * `useAlfadocsAuth().connect()`, which redirects the browser to the server-side\n * BFF that runs the real OAuth2 + PKCE flow.\n */\nexport const ConnectWithAlfadocs = forwardRef<\n HTMLDivElement,\n ConnectWithAlfadocsProps\n>(\n (\n {\n productName,\n title,\n description,\n connectLabel,\n status = 'idle',\n error,\n onConnect,\n footer,\n layout = 'card',\n brandPanel,\n className,\n },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n data-component=\"connect-with-alfadocs\"\n className={`${connectRootVariants({ layout })} ${className ?? ''}`}\n >\n {layout === 'split' ? (\n // Desktop brand panel (lg+ only): a bold `--primary` surface with the\n // monochrome lockup riding the `--primary-foreground` ink, plus an\n // optional `brandPanel` slot. Decorative — the card carries the real\n // heading + CTA, and shows its own lockup below `lg:`.\n <div className=\"ds:hidden ds:lg:flex ds:lg:w-[55%] ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-lg)] ds:bg-[color:var(--primary)] ds:text-[color:var(--primary-foreground)] ds:ps-[var(--spacing-2xl)] ds:pe-[var(--spacing-2xl)] ds:pt-[var(--spacing-2xl)] ds:pb-[var(--spacing-2xl)] ds:text-start\">\n <ProductLockup\n name={productName}\n size=\"lg\"\n monochrome\n tone=\"inherit\"\n variant=\"maker\"\n />\n {brandPanel ? (\n <div className=\"type-body ds:max-w-[28rem] ds:text-start\">\n {brandPanel}\n </div>\n ) : null}\n </div>\n ) : null}\n <div className=\"ds:flex ds:flex-1 ds:items-center ds:justify-center ds:p-[var(--spacing-lg)]\">\n <Card className={connectCardWidthVariants({ layout })}>\n <Card.Body className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-lg)] ds:text-center\">\n <ProductLockup\n name={productName}\n size=\"lg\"\n variant=\"maker\"\n className={connectCardLockupVariants({ layout })}\n />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <h1 className=\"type-title-card\">{title}</h1>\n <p className=\"type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {description}\n </p>\n </div>\n {status === 'error' && error ? (\n <Alert variant=\"error\" className=\"ds:w-full ds:text-start\">\n {error}\n </Alert>\n ) : null}\n <SignInWithAlfadocsButton\n intent=\"primary\"\n className=\"ds:w-full\"\n loading={status === 'connecting'}\n onClick={onConnect}\n label={connectLabel}\n data-testid=\"connect-with-alfadocs-button\"\n />\n {footer ? (\n <div className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {footer}\n </div>\n ) : null}\n </Card.Body>\n </Card>\n </div>\n </div>\n );\n },\n);\n\nConnectWithAlfadocs.displayName = 'ConnectWithAlfadocs';\n"],"names":["lockup","cva","productName","makerRoot","ProductLockup","forwardRef","name","variant","monochrome","tone","size","className","props","ref","t","useTranslation","inherit","markInk","nameInk","byInk","letteringInk","jsxs","jsx","AlfadocsLogoMark","Trans","AlfadocsLogoNeg","Logo","formatBadgeCount","count","AccountMenu","user","labels","onSignOut","onToggleFullscreen","fullscreenLabel","DropdownMenu","Avatar","Fragment","Maximize2","LogOut","MarketplaceSidebarNav","nav","renderLink","SidebarBody","item","badge","inner","SidebarItemIcon","SidebarItemLabel","SidebarItemBadge","SidebarItem","shellMainVariants","EmbeddedTabStrip","ariaLabel","tabRenderLink","href","children","ariaCurrent","tabId","TabBar","MarketplaceAppShell","productHref","sidebarState","collapsibleSidebar","mainAriaLabel","headerBrand","HeaderBrand","themePref","accessibility","resolvedTheme","useTheme","hasExplicitOverride","themeBase","themeAccessible","sidebarOpen","setSidebarOpen","useState","shell","TooltipProvider","AppFrame","Header","HeaderStart","HeaderSkipLink","HeaderMenuButton","HeaderCenter","HeaderEnd","HeaderSettings","Sidebar","SidebarHeader","SidebarCollapseTrigger","embedded","content","ThemeRoot","connectRootVariants","connectCardWidthVariants","connectCardLockupVariants","ConnectWithAlfadocs","title","description","connectLabel","status","error","onConnect","footer","layout","brandPanel","Card","Alert","SignInWithAlfadocsButton"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-tray-BB95DA82.js","sources":["../../src/components/message-tray/message-tray.agent.ts","../../src/components/message-tray/message-tray.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — MessageTray. */\n/* */\n/* Tray-level surface: open/close the inbox panel, read message ids and */\n/* unread flag (never sender names / subjects / previews — those are */\n/* PHI), and route per-message operations through the curated handle. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { MessageTrayHandle } from './message-tray';\n\nexport const messageTrayAgent: AgentAdapter<MessageTrayHandle> = {\n id: 'message-tray',\n capabilities: ['open', 'close', 'select_single', 'dismiss', 'navigate'],\n state: {\n items: {\n type: 'Array<{ id: string; read: boolean }>',\n descriptionKey: 'ui.agent.messageTray.state.items',\n description:\n 'Currently-displayed messages. Ids + read flag only — no PHI / no sender names.',\n read: (handle) => handle.getItems(),\n },\n unreadCount: {\n type: 'number',\n descriptionKey: 'ui.agent.messageTray.state.unreadCount',\n description: 'Badge unread count surfaced by the host.',\n read: (handle) => handle.getUnreadCount(),\n },\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.messageTray.state.isOpen',\n description: 'Whether the dropdown panel is currently open.',\n read: (handle) => handle.isOpen(),\n },\n },\n actions: {\n open: {\n // Pure ephemeral panel-visibility change — read.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.messageTray.actions.open',\n description: 'Open the message panel.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n // Pure ephemeral panel-visibility change — read.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.messageTray.actions.close',\n description: 'Close the message panel.',\n invoke: (handle) => {\n handle.close();\n },\n },\n select_item: {\n // Activates (navigates to) a message — ephemeral view change, read.\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description:\n 'Stable message id to activate (sourced from item.id).',\n },\n },\n required: ['id'],\n },\n descriptionKey: 'ui.agent.messageTray.actions.selectItem',\n description: 'Activate the message with the given id.',\n examples: [\n { args: { id: 'msg-1' }, note: 'Open the message with id \"msg-1\".' },\n ],\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n mark_read: {\n // Persists read-intent for one message, reversible via the same UI — write.\n safety: 'write',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Stable message id to mark as read.',\n },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.messageTray.actions.markRead',\n description: 'Request the host to mark a message as read.',\n invoke: (handle, args: { id: string }) => {\n handle.markRead(args.id);\n },\n },\n dismiss: {\n // Archives / removes a message — irreversible from this UI, destructive.\n safety: 'destructive',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Stable message id to dismiss / archive.',\n },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.messageTray.actions.dismiss',\n description:\n 'Request the host to dismiss / archive the message with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.dismiss(args.id);\n },\n },\n mark_all_read: {\n // Persists read-intent across every message, reversible per-message — write.\n safety: 'write',\n idempotent: true,\n descriptionKey: 'ui.agent.messageTray.actions.markAllRead',\n description: 'Request the host to mark every message as read.',\n invoke: (handle) => {\n handle.markAllRead();\n },\n },\n view_all: {\n // Navigates to the full inbox surface — ephemeral view change, read.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.messageTray.actions.viewAll',\n description: 'Navigate to the full inbox / message list.',\n invoke: (handle) => {\n handle.viewAll();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'message-tray',\n description: 'Marks the MessageTray wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific tray from the agent.',\n },\n item: {\n attr: 'data-message-id',\n description:\n 'Stable message id emitted on each rendered MessageCard inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n} from 'react';\nimport * as RadixPopover from '@radix-ui/react-popover';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { Mail } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { Button } from '../button/button';\nimport { Separator } from '../separator/separator';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { ScrollArea } from '../scroll-area/scroll-area';\nimport { MessageCard, type MessageItem } from '../message-card/message-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { messageTrayAgent } from './message-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * Curated imperative handle for MessageTray. Exposed as the forwardRef\n * target so a future agent / MCP UI bridge can drive the tray without\n * touching the DOM. See `message-tray.agent.ts`.\n */\nexport interface MessageTrayHandle {\n open: () => void;\n close: () => void;\n isOpen: () => boolean;\n getItems: () => Array<{ id: string; read: boolean }>;\n getUnreadCount: () => number;\n selectItem: (id: string) => void;\n markRead: (id: string) => void;\n dismiss: (id: string) => void;\n /** Request the host to mark every message as read (mirrors onMarkAllRead). */\n markAllRead: () => void;\n /** Navigate to the full inbox (mirrors onViewAll). */\n viewAll: () => void;\n}\n\nexport interface MessageTrayProps\n extends\n Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onClick' | 'children' | 'role' | 'id'\n >,\n VariantProps<typeof messageTrayVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific tray.\n */\n id?: string;\n /** Fires when the host should mark a single message as read (used by agent integration). */\n onMarkRead?: (item: MessageItem) => void;\n /** Messages rendered in the dropdown panel. */\n items: MessageItem[];\n /** Number of unread messages. Drives the badge count. */\n unreadCount?: number;\n /** Controlled open state. */\n open?: boolean;\n /** Fires when the open state changes. */\n onOpenChange?: (open: boolean) => void;\n /** Fires when the user activates an item (click or Enter/Space). */\n onItemClick?: (item: MessageItem) => void;\n /** Fires when the user dismisses / archives a message. */\n onDismiss?: (item: MessageItem) => void;\n /** Fires when the user clicks the header \"Mark all as read\" action. */\n onMarkAllRead?: () => void;\n /** When true the panel shows skeleton placeholders. */\n loading?: boolean;\n /**\n * Advisory item count before the list scrolls. Consumers override the cap\n * via the `--message-tray-max-block-size` custom property.\n */\n maxVisible?: number;\n /** When set renders a footer link that invokes `onViewAll`. */\n viewAllLabel?: string;\n /** Fires when the footer \"View all\" link is clicked. */\n onViewAll?: () => void;\n /** Panel alignment relative to the trigger. Default `'end'`. */\n align?: 'start' | 'center' | 'end';\n /** Side of the trigger to open on. Default `'bottom'`. */\n side?: 'top' | 'bottom';\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst messageTrayVariants = cva('ds:relative ds:inline-flex ds:items-center', {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nconst panelVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:bg-[var(--popover)] ds:text-[var(--popover-foreground)]',\n 'ds:border ds:border-[color:var(--card-border)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:z-[var(--z-popover)]',\n // Width: fluid below the design cap so narrow viewports keep a visible\n // gutter on both sides (shadow included). Cap slightly wider than\n // NotificationTray because message rows carry subject + preview.\n 'ds:w-[min(26rem,calc(100vw-2*var(--spacing-md)))]',\n // Height: below the `sm` breakpoint the panel takes a near-full-screen\n // sheet shape so the user gets room to triage an inbox without\n // scrolling a tiny popover. `6rem` reserves space for the Header\n // (≈4rem) plus the sideOffset + collisionPadding (≈2rem). Above `sm`\n // it returns to `h-auto` so the list's own cap governs the height.\n 'ds:h-[calc(100dvh-6rem)] ds:sm:h-auto',\n 'ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out',\n 'ds:data-[state=closed]:fade-out-0 ds:data-[state=open]:fade-in-0',\n 'ds:data-[state=closed]:zoom-out-95 ds:data-[state=open]:zoom-in-95',\n 'ds:motion-reduce:transition-none ds:motion-reduce:animate-none',\n 'ds:focus-visible:outline-none',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:p-[var(--spacing-xs)]',\n md: 'ds:p-[var(--spacing-sm)]',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\nconst badgeVariants = cva(\n [\n 'ds:absolute ds:-top-[var(--spacing-xs)] ds:-end-[var(--spacing-xs)]',\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-w-[calc(var(--spacing-md)+var(--spacing-xs))] ds:h-[calc(var(--spacing-md)+var(--spacing-xs))] ds:ps-[calc(var(--spacing-xs)/1.5)] ds:pe-[calc(var(--spacing-xs)/1.5)]',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[color:var(--destructive)] ds:text-[color:var(--destructive-foreground)]',\n 'ds:text-[length:var(--font-size-xs)] ds:font-semibold ds:leading-none',\n 'ds:pointer-events-none ds:select-none',\n 'ds:forced-colors:outline ds:forced-colors:outline-1 ds:forced-colors:outline-[CanvasText]',\n ].join(' '),\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction formatBadgeCount(count: number, overflowLabel: string): string {\n return count > 99 ? overflowLabel : String(count);\n}\n\nfunction SkeletonRow() {\n return (\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:items-start ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\"\n >\n <Skeleton variant=\"circular\" size=\"sm\" />\n <div className=\"ds:flex-1 ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <Skeleton variant=\"text\" size=\"md\" width=\"60%\" />\n <Skeleton variant=\"text\" size=\"sm\" width=\"80%\" />\n <Skeleton variant=\"text\" size=\"sm\" width=\"95%\" />\n <Skeleton variant=\"text\" size=\"sm\" width=\"30%\" />\n </div>\n </div>\n );\n}\n\nfunction EmptyPanel() {\n const { t } = useTranslation('ui');\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className=\"ds:flex ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-xs)] ds:p-[var(--spacing-lg)] ds:text-center\"\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:justify-center ds:size-10 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--muted)] ds:text-[color:var(--muted-foreground)] ds:[&>svg]:size-5\"\n >\n <Mail />\n </span>\n <p className=\"type-title-item ds:text-[color:var(--foreground)]\">\n {t('messageTray.noMessages', 'No messages')}\n </p>\n <p className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {t('messageTray.noMessagesDescription', 'Your inbox is clear.')}\n </p>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport const MessageTray = forwardRef<HTMLDivElement, MessageTrayProps>(\n (\n {\n id,\n items,\n unreadCount,\n open,\n onOpenChange,\n onItemClick,\n onDismiss,\n onMarkRead,\n onMarkAllRead,\n loading = false,\n maxVisible,\n viewAllLabel,\n onViewAll,\n align = 'end',\n side = 'bottom',\n size = 'md',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n const [isOpenRaw, handleOpenChange] = useControllableState<boolean>({\n value: open,\n defaultValue: false,\n onChange: onOpenChange,\n });\n const isOpen = isOpenRaw ?? false;\n\n /* Exit-animation list — same AnimatePresence-style bookkeeping as\n * NotificationTray. See that component for rationale. */\n type Displayed = { item: MessageItem; leaving: boolean };\n const [displayed, setDisplayed] = useState<Displayed[]>(() =>\n items.map((item) => ({ item, leaving: false })),\n );\n\n const animationDurationMs = useCallback((): number => {\n if (typeof window === 'undefined') return 200;\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue('--animation-duration');\n if (!raw) return 200;\n const trimmed = raw.trim();\n const n = parseFloat(trimmed);\n if (!Number.isFinite(n)) return 200;\n return trimmed.endsWith('ms') ? n : n * 1000;\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n setDisplayed((prev) => {\n const nextIds = new Set(items.map((i) => i.id));\n const prevIds = new Set(prev.map((d) => d.item.id));\n\n const merged: Displayed[] = prev.map((d) => {\n if (nextIds.has(d.item.id)) {\n const fresh = items.find((i) => i.id === d.item.id);\n return fresh\n ? { item: fresh, leaving: false }\n : { ...d, leaving: true };\n }\n return { ...d, leaving: true };\n });\n\n for (const i of items) {\n if (!prevIds.has(i.id)) merged.push({ item: i, leaving: false });\n }\n return merged;\n });\n }, [items]);\n\n useEffect(() => {\n if (!displayed.some((d) => d.leaving)) return;\n const ms = animationDurationMs();\n const timer = setTimeout(() => {\n setDisplayed((prev) => prev.filter((d) => !d.leaving));\n }, ms);\n return () => clearTimeout(timer);\n }, [displayed, animationDurationMs]);\n\n const liveRegionRef = useRef<HTMLDivElement | null>(null);\n const lastTopIdRef = useRef<string | undefined>(items[0]?.id);\n\n useEffect(() => {\n const topId = items[0]?.id;\n const prev = lastTopIdRef.current;\n if (prev && topId && prev !== topId && liveRegionRef.current) {\n const newest = items[0];\n if (newest && !newest.read) {\n liveRegionRef.current.textContent = t('messageTray.newMessage', {\n sender: newest.sender.name,\n defaultValue: 'New message from {{sender}}',\n });\n }\n }\n lastTopIdRef.current = topId;\n }, [items, t]);\n\n const displayCount = unreadCount ?? 0;\n const triggerAriaLabel =\n displayCount > 0\n ? t('messageTray.triggerLabel', {\n count: displayCount,\n defaultValue: 'Messages, {{count}} unread',\n })\n : t('messageTray.triggerLabelNone', 'Messages, none unread');\n\n const badgeLabel = formatBadgeCount(\n displayCount,\n t('messageTray.badgeCountOverflow', '99+'),\n );\n\n const panelClass = panelVariants({ size });\n\n /* Curated imperative handle for agent integration. See\n * message-tray.agent.ts. */\n const itemsRef = useRef<MessageItem[]>(items);\n itemsRef.current = items;\n const unreadRef = useRef<number | undefined>(unreadCount);\n unreadRef.current = unreadCount;\n const isOpenRef = useRef<boolean>(isOpen);\n isOpenRef.current = isOpen;\n\n const handle = useMemo<MessageTrayHandle>(\n () => ({\n open: () => handleOpenChange(true),\n close: () => handleOpenChange(false),\n isOpen: () => isOpenRef.current,\n getItems: () =>\n itemsRef.current.map((i) => ({ id: i.id, read: !!i.read })),\n getUnreadCount: () =>\n unreadRef.current ?? itemsRef.current.filter((i) => !i.read).length,\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onItemClick?.(found);\n },\n markRead: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onMarkRead?.(found);\n },\n dismiss: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onDismiss?.(found);\n },\n markAllRead: () => onMarkAllRead?.(),\n viewAll: () => onViewAll?.(),\n }),\n [\n handleOpenChange,\n onItemClick,\n onMarkRead,\n onDismiss,\n onMarkAllRead,\n onViewAll,\n ],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLDivElement, []);\n useAgentRegistration(messageTrayAgent, handle, id);\n\n return (\n <div\n ref={rootRef}\n data-component=\"message-tray\"\n data-component-id={id}\n className={[messageTrayVariants({ size }), className]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n <RadixPopover.Root open={isOpen} onOpenChange={handleOpenChange}>\n <RadixPopover.Trigger asChild>\n <IconButton\n icon={<Mail />}\n intent=\"outline\"\n size={size === 'sm' ? 'sm' : 'md'}\n aria-label={triggerAriaLabel}\n aria-haspopup=\"dialog\"\n />\n </RadixPopover.Trigger>\n {displayCount > 0 ? (\n <span\n aria-hidden=\"true\"\n data-testid=\"message-tray-badge\"\n className={badgeVariants()}\n >\n {badgeLabel}\n </span>\n ) : null}\n <div\n ref={liveRegionRef}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"ds:sr-only\"\n />\n <RadixPopover.Portal>\n <RadixPopover.Content\n role=\"dialog\"\n aria-label={t('messageTray.panelTitle', 'Messages')}\n side={side}\n align={align}\n sideOffset={8}\n // `spacing-md` (16px) keeps Radix's collision-avoidance from\n // flush-mounting the panel against the viewport edge when the\n // trigger is near the inline-end of a narrow screen.\n collisionPadding={16}\n className={panelClass}\n >\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pb-[var(--spacing-xs)]\">\n <h3 className=\"ds:m-0 type-title-card ds:text-[color:var(--foreground)]\">\n {t('messageTray.panelTitle', 'Messages')}\n </h3>\n {onMarkAllRead && items.some((item) => !item.read) ? (\n <Button\n intent=\"link\"\n size=\"sm\"\n onClick={onMarkAllRead}\n className=\"ds:text-[length:var(--font-size-xs)]\"\n >\n {t('messageTray.markAllRead', 'Mark all as read')}\n </Button>\n ) : null}\n </div>\n <Separator />\n {/* Below `sm` the panel is a near-full-screen sheet (see\n `panelVariants`) and the scroll area expands to fill the\n remaining space with `flex-1`. Above `sm` it caps at the\n `--message-tray-max-block-size` custom property so the\n popover stays compact. The ScrollArea viewport owns the\n overflow + is keyboard-focusable, so the list keeps only its\n role/content classes. */}\n <ScrollArea\n orientation=\"vertical\"\n className=\"ds:flex-1 ds:min-h-0 ds:sm:flex-none ds:sm:[max-block-size:var(--message-tray-max-block-size,26rem)]\"\n >\n <div\n // Only carry `role=\"list\"` when there are list children —\n // axe's `aria-required-children` rule fires on an empty\n // list. The loading skeleton + populated rendering both\n // produce role=\"listitem\" descendants below.\n role={displayed.length > 0 ? 'list' : undefined}\n data-max-visible={maxVisible}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:pt-[var(--spacing-xs)]\"\n >\n {loading ? (\n <>\n <SkeletonRow />\n <SkeletonRow />\n <SkeletonRow />\n </>\n ) : displayed.length === 0 ? (\n <EmptyPanel />\n ) : (\n displayed.map(({ item, leaving }) => (\n <MessageCard\n key={item.id}\n item={item}\n variant=\"compact\"\n leaving={leaving}\n onActivate={onItemClick}\n onDismiss={onDismiss}\n data-message-id={item.id}\n />\n ))\n )}\n </div>\n </ScrollArea>\n {viewAllLabel ? (\n <>\n <Separator />\n <div className=\"ds:pt-[var(--spacing-xs)]\">\n <Button\n intent=\"link\"\n size=\"sm\"\n onClick={onViewAll}\n className=\"ds:w-full ds:justify-center\"\n >\n {viewAllLabel}\n </Button>\n </div>\n </>\n ) : null}\n </RadixPopover.Content>\n </RadixPopover.Portal>\n </RadixPopover.Root>\n </div>\n );\n },\n);\n\nMessageTray.displayName = 'MessageTray';\n"],"names":["messageTrayAgent","handle","args","messageTrayVariants","cva","panelVariants","badgeVariants","formatBadgeCount","count","overflowLabel","SkeletonRow","jsxs","jsx","Skeleton","EmptyPanel","t","useTranslation","Mail","MessageTray","forwardRef","id","items","unreadCount","open","onOpenChange","onItemClick","onDismiss","onMarkRead","onMarkAllRead","loading","maxVisible","viewAllLabel","onViewAll","align","side","size","className","rest","ref","isOpenRaw","handleOpenChange","useControllableState","isOpen","displayed","setDisplayed","useState","item","animationDurationMs","useCallback","raw","trimmed","n","useIsomorphicLayoutEffect","prev","nextIds","i","prevIds","d","merged","fresh","useEffect","ms","timer","liveRegionRef","useRef","lastTopIdRef","_a","topId","newest","displayCount","triggerAriaLabel","badgeLabel","panelClass","itemsRef","unreadRef","isOpenRef","useMemo","targetId","found","rootRef","useImperativeHandle","useAgentRegistration","RadixPopover","IconButton","Button","Separator","ScrollArea","Fragment","leaving","MessageCard"],"mappings":"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"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { useCallback as f } from "react";
|
|
2
|
-
const l = "data-radix-focus-guard";
|
|
3
|
-
function s(e) {
|
|
4
|
-
return e.hidden || e.disabled === !0 || e.tagName === "INPUT" && e.type === "hidden" ? !1 : e.tabIndex >= 0;
|
|
5
|
-
}
|
|
6
|
-
function c(e, r) {
|
|
7
|
-
if (getComputedStyle(e).visibility === "hidden") return !0;
|
|
8
|
-
let t = e;
|
|
9
|
-
for (; t; ) {
|
|
10
|
-
if (r !== void 0 && t === r) return !1;
|
|
11
|
-
if (getComputedStyle(t).display === "none") return !0;
|
|
12
|
-
t = t.parentElement;
|
|
13
|
-
}
|
|
14
|
-
return !1;
|
|
15
|
-
}
|
|
16
|
-
function E(e, r) {
|
|
17
|
-
const t = e.ownerDocument.createTreeWalker(
|
|
18
|
-
e,
|
|
19
|
-
NodeFilter.SHOW_ELEMENT,
|
|
20
|
-
{
|
|
21
|
-
acceptNode: (i) => s(i) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP
|
|
22
|
-
}
|
|
23
|
-
), n = [];
|
|
24
|
-
for (; t.nextNode(); ) n.push(t.currentNode);
|
|
25
|
-
return r === "last" && n.reverse(), n.find((i) => !c(i, e));
|
|
26
|
-
}
|
|
27
|
-
function N(e) {
|
|
28
|
-
return c(e) || (e.focus(), e.ownerDocument.activeElement !== e) ? !1 : (e.tagName === "INPUT" && e.select(), !0);
|
|
29
|
-
}
|
|
30
|
-
function T(e, r) {
|
|
31
|
-
const t = e.ownerDocument, n = t.createTreeWalker(t.body, NodeFilter.SHOW_ELEMENT, {
|
|
32
|
-
acceptNode: (u) => {
|
|
33
|
-
const o = u;
|
|
34
|
-
return o === e || o.hidden || o.hasAttribute("inert") ? NodeFilter.FILTER_REJECT : s(o) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
let i = e;
|
|
38
|
-
if (!r) for (; i.lastChild; ) i = i.lastChild;
|
|
39
|
-
n.currentNode = i;
|
|
40
|
-
let a = null;
|
|
41
|
-
const d = () => r ? n.previousNode() : n.nextNode();
|
|
42
|
-
for (let u = d(); u; u = d()) {
|
|
43
|
-
const o = u;
|
|
44
|
-
if (o.hasAttribute(l)) a = o;
|
|
45
|
-
else if (N(o)) return "moved";
|
|
46
|
-
}
|
|
47
|
-
return a ? (a.focus(), t.activeElement === a ? "native" : "none") : "none";
|
|
48
|
-
}
|
|
49
|
-
function b(e) {
|
|
50
|
-
return f(
|
|
51
|
-
(r) => {
|
|
52
|
-
if (!e || r.defaultPrevented || r.key !== "Tab" || r.altKey || r.ctrlKey || r.metaKey)
|
|
53
|
-
return;
|
|
54
|
-
const t = r.currentTarget, n = t.ownerDocument.activeElement;
|
|
55
|
-
if (!n || !t.contains(n)) return;
|
|
56
|
-
const i = r.shiftKey, a = E(t, i ? "first" : "last");
|
|
57
|
-
(n === a || n === t && (!a || i)) && T(t, i) === "moved" && r.preventDefault();
|
|
58
|
-
},
|
|
59
|
-
[e]
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
export {
|
|
63
|
-
b as u
|
|
64
|
-
};
|
|
65
|
-
//# sourceMappingURL=non-modal-tab-exit-D2Bd93Bq.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"non-modal-tab-exit-D2Bd93Bq.js","sources":["../../src/components/_shared/non-modal-tab-exit.ts"],"sourcesContent":["import { useCallback, type KeyboardEvent } from 'react';\n\n// Radix DialogContent keeps `FocusScope loop` when `modal={false}`, so Tab wraps\n// inside the panel and the page is unreachable (WCAG 2.1.2). This lets Tab leave\n// at the panel's edges in DOM order, which is also the reading order.\n\nconst FOCUS_GUARD = 'data-radix-focus-guard';\n\n// Same rules as Radix FocusScope, so our edge is the edge it would wrap at.\nfunction isTabbable(el: HTMLElement): boolean {\n if (el.hidden) return false;\n if ((el as { disabled?: unknown }).disabled === true) return false;\n if (el.tagName === 'INPUT' && (el as HTMLInputElement).type === 'hidden')\n return false;\n return el.tabIndex >= 0;\n}\n\nfunction isHidden(el: HTMLElement, upTo?: HTMLElement): boolean {\n if (getComputedStyle(el).visibility === 'hidden') return true;\n let node: HTMLElement | null = el;\n while (node) {\n if (upTo !== undefined && node === upTo) return false;\n if (getComputedStyle(node).display === 'none') return true;\n node = node.parentElement;\n }\n return false;\n}\n\nfunction getTabbableEdge(\n container: HTMLElement,\n which: 'first' | 'last',\n): HTMLElement | undefined {\n const walker = container.ownerDocument.createTreeWalker(\n container,\n NodeFilter.SHOW_ELEMENT,\n {\n acceptNode: (node) =>\n isTabbable(node as HTMLElement)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP,\n },\n );\n const candidates: HTMLElement[] = [];\n while (walker.nextNode()) candidates.push(walker.currentNode as HTMLElement);\n if (which === 'last') candidates.reverse();\n return candidates.find((el) => !isHidden(el, container));\n}\n\nfunction tryFocus(el: HTMLElement): boolean {\n if (isHidden(el)) return false;\n el.focus();\n if (el.ownerDocument.activeElement !== el) return false;\n // Native Tab into a text field selects its value.\n if (el.tagName === 'INPUT') (el as HTMLInputElement).select();\n return true;\n}\n\n/**\n * Focus the nearest tabbable before or after `content` in DOM order. Radix's\n * invisible edge guards are skipped; when only a guard is left, focus rests on it\n * and the browser's own Tab carries on to its toolbar ('native').\n */\nfunction focusBeyond(\n content: HTMLElement,\n backwards: boolean,\n): 'moved' | 'native' | 'none' {\n const doc = content.ownerDocument;\n const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT, {\n acceptNode: (node) => {\n const el = node as HTMLElement;\n if (el === content || el.hidden || el.hasAttribute('inert')) {\n return NodeFilter.FILTER_REJECT;\n }\n return isTabbable(el) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;\n },\n });\n\n // nextNode() from the content would descend into it, so start from its last leaf.\n let start: Node = content;\n if (!backwards) while (start.lastChild) start = start.lastChild;\n walker.currentNode = start;\n\n let guard: HTMLElement | null = null;\n const step = () => (backwards ? walker.previousNode() : walker.nextNode());\n for (let node = step(); node; node = step()) {\n const el = node as HTMLElement;\n if (el.hasAttribute(FOCUS_GUARD)) guard = el;\n else if (tryFocus(el)) return 'moved';\n }\n if (!guard) return 'none';\n guard.focus();\n return doc.activeElement === guard ? 'native' : 'none';\n}\n\n/**\n * Lets Tab leave non-modal Radix Dialog content instead of wrapping. Enable it\n * only with `modal={false}`; modal content keeps Radix's trap and loop.\n * Returns a handler for the content's `onKeyDown`, after the consumer's own.\n */\nexport function useNonModalTabExit(\n enabled: boolean,\n): (event: KeyboardEvent<HTMLElement>) => void {\n // Content's onKeyDown runs before FocusScope's (Radix Slot calls the child\n // handler first). Once focus has moved, FocusScope no longer sees an edge.\n return useCallback(\n (event: KeyboardEvent<HTMLElement>) => {\n if (!enabled || event.defaultPrevented) return;\n if (event.key !== 'Tab' || event.altKey || event.ctrlKey || event.metaKey)\n return;\n\n const content = event.currentTarget;\n const active = content.ownerDocument.activeElement;\n if (!active || !content.contains(active)) return;\n\n const backwards = event.shiftKey;\n const edge = getTabbableEdge(content, backwards ? 'first' : 'last');\n // Focus parked on the panel itself leaves backwards, or either way when\n // the panel has nothing tabbable inside.\n const atEdge =\n active === edge || (active === content && (!edge || backwards));\n if (!atEdge) return;\n\n // 'native' leaves the default alone: focus is on a guard, not an edge.\n if (focusBeyond(content, backwards) === 'moved') event.preventDefault();\n },\n [enabled],\n );\n}\n"],"names":["FOCUS_GUARD","isTabbable","el","isHidden","upTo","node","getTabbableEdge","container","which","walker","candidates","tryFocus","focusBeyond","content","backwards","doc","start","guard","step","useNonModalTabExit","enabled","useCallback","event","active","edge"],"mappings":";AAMA,MAAMA,IAAc;AAGpB,SAASC,EAAWC,GAA0B;AAG5C,SAFIA,EAAG,UACFA,EAA8B,aAAa,MAC5CA,EAAG,YAAY,WAAYA,EAAwB,SAAS,WACvD,KACFA,EAAG,YAAY;AACxB;AAEA,SAASC,EAASD,GAAiBE,GAA6B;AAC9D,MAAI,iBAAiBF,CAAE,EAAE,eAAe,SAAU,QAAO;AACzD,MAAIG,IAA2BH;AAC/B,SAAOG,KAAM;AACX,QAAID,MAAS,UAAaC,MAASD,EAAM,QAAO;AAChD,QAAI,iBAAiBC,CAAI,EAAE,YAAY,OAAQ,QAAO;AACtD,IAAAA,IAAOA,EAAK;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAASC,EACPC,GACAC,GACyB;AACzB,QAAMC,IAASF,EAAU,cAAc;AAAA,IACrCA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,MACE,YAAY,CAACF,MACXJ,EAAWI,CAAmB,IAC1B,WAAW,gBACX,WAAW;AAAA,IAAA;AAAA,EACnB,GAEIK,IAA4B,CAAA;AAClC,SAAOD,EAAO,SAAA,IAAY,CAAAC,EAAW,KAAKD,EAAO,WAA0B;AAC3E,SAAID,MAAU,UAAQE,EAAW,QAAA,GAC1BA,EAAW,KAAK,CAACR,MAAO,CAACC,EAASD,GAAIK,CAAS,CAAC;AACzD;AAEA,SAASI,EAAST,GAA0B;AAG1C,SAFIC,EAASD,CAAE,MACfA,EAAG,MAAA,GACCA,EAAG,cAAc,kBAAkBA,KAAW,MAE9CA,EAAG,YAAY,WAAUA,EAAwB,OAAA,GAC9C;AACT;AAOA,SAASU,EACPC,GACAC,GAC6B;AAC7B,QAAMC,IAAMF,EAAQ,eACdJ,IAASM,EAAI,iBAAiBA,EAAI,MAAM,WAAW,cAAc;AAAA,IACrE,YAAY,CAACV,MAAS;AACpB,YAAMH,IAAKG;AACX,aAAIH,MAAOW,KAAWX,EAAG,UAAUA,EAAG,aAAa,OAAO,IACjD,WAAW,gBAEbD,EAAWC,CAAE,IAAI,WAAW,gBAAgB,WAAW;AAAA,IAChE;AAAA,EAAA,CACD;AAGD,MAAIc,IAAcH;AAClB,MAAI,CAACC,EAAW,QAAOE,EAAM,iBAAmBA,EAAM;AACtD,EAAAP,EAAO,cAAcO;AAErB,MAAIC,IAA4B;AAChC,QAAMC,IAAO,MAAOJ,IAAYL,EAAO,aAAA,IAAiBA,EAAO,SAAA;AAC/D,WAASJ,IAAOa,EAAA,GAAQb,GAAMA,IAAOa,KAAQ;AAC3C,UAAMhB,IAAKG;AACX,QAAIH,EAAG,aAAaF,CAAW,EAAG,CAAAiB,IAAQf;AAAA,aACjCS,EAAST,CAAE,EAAG,QAAO;AAAA,EAChC;AACA,SAAKe,KACLA,EAAM,MAAA,GACCF,EAAI,kBAAkBE,IAAQ,WAAW,UAF7B;AAGrB;AAOO,SAASE,EACdC,GAC6C;AAG7C,SAAOC;AAAA,IACL,CAACC,MAAsC;AAErC,UADI,CAACF,KAAWE,EAAM,oBAClBA,EAAM,QAAQ,SAASA,EAAM,UAAUA,EAAM,WAAWA,EAAM;AAChE;AAEF,YAAMT,IAAUS,EAAM,eAChBC,IAASV,EAAQ,cAAc;AACrC,UAAI,CAACU,KAAU,CAACV,EAAQ,SAASU,CAAM,EAAG;AAE1C,YAAMT,IAAYQ,EAAM,UAClBE,IAAOlB,EAAgBO,GAASC,IAAY,UAAU,MAAM;AAKlE,OADES,MAAWC,KAASD,MAAWV,MAAY,CAACW,KAAQV,OAIlDF,EAAYC,GAASC,CAAS,MAAM,aAAe,eAAA;AAAA,IACzD;AAAA,IACA,CAACM,CAAO;AAAA,EAAA;AAEZ;"}
|