@alfadocs/ui-kit-debug 1.6.0 → 1.7.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/{actions-cell-renderer-BD-jruqA.js → actions-cell-renderer-ALEAGO3j.js} +6 -6
- package/dist/_chunks/{actions-cell-renderer-BD-jruqA.js.map → actions-cell-renderer-ALEAGO3j.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-CYR-znfE.js → agenda-tray-BweO8pDo.js} +3 -3
- package/dist/_chunks/{agenda-tray-CYR-znfE.js.map → agenda-tray-BweO8pDo.js.map} +1 -1
- package/dist/_chunks/{ai-consent-banner-DLF6FNXv.js → ai-consent-banner-OggpS5hW.js} +2 -2
- package/dist/_chunks/{ai-consent-banner-DLF6FNXv.js.map → ai-consent-banner-OggpS5hW.js.map} +1 -1
- package/dist/_chunks/{ai-prompt-input-BgAubYKd.js → ai-prompt-input-DnbfEJnr.js} +2 -2
- package/dist/_chunks/{ai-prompt-input-BgAubYKd.js.map → ai-prompt-input-DnbfEJnr.js.map} +1 -1
- package/dist/_chunks/{alia-sidebar-Bg53-ZOT.js → alia-sidebar-BWcWZivN.js} +7 -7
- package/dist/_chunks/{alia-sidebar-Bg53-ZOT.js.map → alia-sidebar-BWcWZivN.js.map} +1 -1
- package/dist/_chunks/{anamnesis-card-BylMLHYj.js → anamnesis-card-NTi4LLzI.js} +2 -2
- package/dist/_chunks/{anamnesis-card-BylMLHYj.js.map → anamnesis-card-NTi4LLzI.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-BpYztFUv.js → anamnesis-summary-rows-F-cCmFAn.js} +7 -7
- package/dist/_chunks/{anamnesis-summary-rows-BpYztFUv.js.map → anamnesis-summary-rows-F-cCmFAn.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-DT1uFp8z.js → appointment-timeline-CMPvzlGZ.js} +4 -4
- package/dist/_chunks/{appointment-timeline-DT1uFp8z.js.map → appointment-timeline-CMPvzlGZ.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-DvyVK7um.js → appointment-tray-3c_FLxXJ.js} +3 -3
- package/dist/_chunks/{appointment-tray-DvyVK7um.js.map → appointment-tray-3c_FLxXJ.js.map} +1 -1
- package/dist/_chunks/{audio-recorder-nVRN4PSK.js → audio-recorder-EWBCNIsd.js} +3 -3
- package/dist/_chunks/{audio-recorder-nVRN4PSK.js.map → audio-recorder-EWBCNIsd.js.map} +1 -1
- package/dist/_chunks/{bishop-score-BV1JAEMV.js → bishop-score-Cnu0xs-z.js} +2 -2
- package/dist/_chunks/{bishop-score-BV1JAEMV.js.map → bishop-score-Cnu0xs-z.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-CdR-RLFj.js → bmi-calculator-CcH6upht.js} +2 -2
- package/dist/_chunks/{bmi-calculator-CdR-RLFj.js.map → bmi-calculator-CcH6upht.js.map} +1 -1
- package/dist/_chunks/{booking-D84O6H2X.js → booking-CQMJUFG-.js} +5 -5
- package/dist/_chunks/{booking-D84O6H2X.js.map → booking-CQMJUFG-.js.map} +1 -1
- package/dist/_chunks/{button-group-Be_In68J.js → button-group-CaxRJsNG.js} +2 -2
- package/dist/_chunks/{button-group-Be_In68J.js.map → button-group-CaxRJsNG.js.map} +1 -1
- package/dist/_chunks/{button-BvNtqHAS.js → button-nJaPh_HC.js} +68 -38
- package/dist/_chunks/button-nJaPh_HC.js.map +1 -0
- package/dist/_chunks/{care-plan-card-CehAU7F_.js → care-plan-card-DQjVRDxO.js} +2 -2
- package/dist/_chunks/{care-plan-card-CehAU7F_.js.map → care-plan-card-DQjVRDxO.js.map} +1 -1
- package/dist/_chunks/{care-plan-entry-card-ChWRMfMw.js → care-plan-entry-card-CMpoeNkb.js} +2 -2
- package/dist/_chunks/{care-plan-entry-card-ChWRMfMw.js.map → care-plan-entry-card-CMpoeNkb.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-_B0TTWT1.js → care-plan-header-CxYoq23f.js} +2 -2
- package/dist/_chunks/{care-plan-header-_B0TTWT1.js.map → care-plan-header-CxYoq23f.js.map} +1 -1
- package/dist/_chunks/{carousel.agent-pjORsMS8.js → carousel.agent-CLxdHEBP.js} +2 -2
- package/dist/_chunks/{carousel.agent-pjORsMS8.js.map → carousel.agent-CLxdHEBP.js.map} +1 -1
- package/dist/_chunks/{chart-Y-gso_Uz.js → chart-Bkr1Sh4o.js} +3 -3
- package/dist/_chunks/{chart-Y-gso_Uz.js.map → chart-Bkr1Sh4o.js.map} +1 -1
- package/dist/_chunks/{chat-input-BqI9GXQh.js → chat-input-BsB5Umpj.js} +2 -2
- package/dist/_chunks/{chat-input-BqI9GXQh.js.map → chat-input-BsB5Umpj.js.map} +1 -1
- package/dist/_chunks/{chat-message-DHNUbjXA.js → chat-message-DBQu10rs.js} +3 -3
- package/dist/_chunks/{chat-message-DHNUbjXA.js.map → chat-message-DBQu10rs.js.map} +1 -1
- package/dist/_chunks/{code-block-BONe9fJi.js → code-block-BIkpRLkl.js} +2 -2
- package/dist/_chunks/{code-block-BONe9fJi.js.map → code-block-BIkpRLkl.js.map} +1 -1
- package/dist/_chunks/{connection-status-NT8hUtYl.js → connection-status-DRZIcMqM.js} +3 -3
- package/dist/_chunks/{connection-status-NT8hUtYl.js.map → connection-status-DRZIcMqM.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-BxHiG8e6.js → contact-profile-card-CE9OJKcl.js} +2 -2
- package/dist/_chunks/{contact-profile-card-BxHiG8e6.js.map → contact-profile-card-CE9OJKcl.js.map} +1 -1
- package/dist/_chunks/{control-room-rail-DDyPDBji.js → control-room-rail-IH1eBjrK.js} +3 -3
- package/dist/_chunks/{control-room-rail-DDyPDBji.js.map → control-room-rail-IH1eBjrK.js.map} +1 -1
- package/dist/_chunks/{copy-field-B-DoMBH_.js → copy-field-fYKpl6aN.js} +2 -2
- package/dist/_chunks/{copy-field-B-DoMBH_.js.map → copy-field-fYKpl6aN.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-DJZYvNhw.js → cycle-calculator-DzgO1vzP.js} +2 -2
- package/dist/_chunks/{cycle-calculator-DJZYvNhw.js.map → cycle-calculator-DzgO1vzP.js.map} +1 -1
- package/dist/_chunks/{dashboard-grid-bd0QW2a8.js → dashboard-grid-BFtdHqfn.js} +2 -2
- package/dist/_chunks/{dashboard-grid-bd0QW2a8.js.map → dashboard-grid-BFtdHqfn.js.map} +1 -1
- package/dist/_chunks/{data-table-tabs-C8uDThT3.js → data-table-tabs-C1kRUzat.js} +3 -3
- package/dist/_chunks/{data-table-tabs-C8uDThT3.js.map → data-table-tabs-C1kRUzat.js.map} +1 -1
- package/dist/_chunks/{description-list-Ck7fKdt5.js → description-list-CjJqR8WK.js} +2 -2
- package/dist/_chunks/{description-list-Ck7fKdt5.js.map → description-list-CjJqR8WK.js.map} +1 -1
- package/dist/_chunks/{document-preview-Aae2yKvY.js → document-preview-oyx9RhCo.js} +2 -2
- package/dist/_chunks/{document-preview-Aae2yKvY.js.map → document-preview-oyx9RhCo.js.map} +1 -1
- package/dist/_chunks/{document-scanner-qNZLhH_r.js → document-scanner-C5Vrbu21.js} +2 -2
- package/dist/_chunks/{document-scanner-qNZLhH_r.js.map → document-scanner-C5Vrbu21.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-ajaQ4ya5.js → due-date-calculator-wK8Tajzz.js} +2 -2
- package/dist/_chunks/{due-date-calculator-ajaQ4ya5.js.map → due-date-calculator-wK8Tajzz.js.map} +1 -1
- package/dist/_chunks/{editable-currency-cell-renderer-DyMbSyDK.js → editable-currency-cell-renderer-DYdzKpjL.js} +3 -3
- package/dist/_chunks/{editable-currency-cell-renderer-DyMbSyDK.js.map → editable-currency-cell-renderer-DYdzKpjL.js.map} +1 -1
- package/dist/_chunks/{editor-overlay-DE-gxj9L.js → editor-overlay-DEc5yYwo.js} +2 -2
- package/dist/_chunks/{editor-overlay-DE-gxj9L.js.map → editor-overlay-DEc5yYwo.js.map} +1 -1
- package/dist/_chunks/{empty-state-Df0tM6Kn.js → empty-state-X0sVPfVo.js} +2 -2
- package/dist/_chunks/{empty-state-Df0tM6Kn.js.map → empty-state-X0sVPfVo.js.map} +1 -1
- package/dist/_chunks/{entity-summary-DBOI5di6.js → entity-summary-B_vO5Ur4.js} +3 -3
- package/dist/_chunks/{entity-summary-DBOI5di6.js.map → entity-summary-B_vO5Ur4.js.map} +1 -1
- package/dist/_chunks/{face-scheme-D7Pub04e.js → face-scheme-BfDi4YkW.js} +5 -5
- package/dist/_chunks/{face-scheme-D7Pub04e.js.map → face-scheme-BfDi4YkW.js.map} +1 -1
- package/dist/_chunks/{fetal-weight-jon6GIfQ.js → fetal-weight-Dqy0T1fP.js} +2 -2
- package/dist/_chunks/{fetal-weight-jon6GIfQ.js.map → fetal-weight-Dqy0T1fP.js.map} +1 -1
- package/dist/_chunks/{field-array-BQFX5OYi.js → field-array-BjkXZzSr.js} +3 -3
- package/dist/_chunks/{field-array-BQFX5OYi.js.map → field-array-BjkXZzSr.js.map} +1 -1
- package/dist/_chunks/{field-value-BbiDRyNh.js → field-value-DG8zaZvo.js} +4 -4
- package/dist/_chunks/{field-value-BbiDRyNh.js.map → field-value-DG8zaZvo.js.map} +1 -1
- package/dist/_chunks/{file-manager-CML_C6_h.js → file-manager-Cc_upjZX.js} +6 -6
- package/dist/_chunks/{file-manager-CML_C6_h.js.map → file-manager-Cc_upjZX.js.map} +1 -1
- package/dist/_chunks/{finished-terminal-BWNVh7Y8.js → finished-terminal-Br61Ip4e.js} +2 -2
- package/dist/_chunks/{finished-terminal-BWNVh7Y8.js.map → finished-terminal-Br61Ip4e.js.map} +1 -1
- package/dist/_chunks/{fiscal-code-input-Nx1N9r72.js → fiscal-code-input-B_nYMSEM.js} +2 -2
- package/dist/_chunks/{fiscal-code-input-Nx1N9r72.js.map → fiscal-code-input-B_nYMSEM.js.map} +1 -1
- package/dist/_chunks/{freemium-paywall-HG3pFvMp.js → freemium-paywall-DrXzYfv-.js} +2 -2
- package/dist/_chunks/{freemium-paywall-HG3pFvMp.js.map → freemium-paywall-DrXzYfv-.js.map} +1 -1
- package/dist/_chunks/{gestational-age-calculator-dEpQDWcb.js → gestational-age-calculator-C_uDAeP_.js} +2 -2
- package/dist/_chunks/{gestational-age-calculator-dEpQDWcb.js.map → gestational-age-calculator-C_uDAeP_.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-CC6TLtHd.js → hcg-doubling-BaXkJhT-.js} +2 -2
- package/dist/_chunks/{hcg-doubling-CC6TLtHd.js.map → hcg-doubling-BaXkJhT-.js.map} +1 -1
- package/dist/_chunks/{header-CimZS-J9.js → header-DUXRIPyM.js} +2 -2
- package/dist/_chunks/{header-CimZS-J9.js.map → header-DUXRIPyM.js.map} +1 -1
- package/dist/_chunks/{header-settings-C0zHLXJE.js → header-settings-CVC_davE.js} +4 -4
- package/dist/_chunks/{header-settings-C0zHLXJE.js.map → header-settings-CVC_davE.js.map} +1 -1
- package/dist/_chunks/{icon-button-9c9Gp41m.js → icon-button-DA2CAGHZ.js} +2 -2
- package/dist/_chunks/{icon-button-9c9Gp41m.js.map → icon-button-DA2CAGHZ.js.map} +1 -1
- package/dist/_chunks/{icon-button-group-DrvuWPGJ.js → icon-button-group-D6SVMteH.js} +2 -2
- package/dist/_chunks/{icon-button-group-DrvuWPGJ.js.map → icon-button-group-D6SVMteH.js.map} +1 -1
- package/dist/_chunks/{icon-picker-DXV3sDp1.js → icon-picker-ChzpCnZ-.js} +3 -3
- package/dist/_chunks/{icon-picker-DXV3sDp1.js.map → icon-picker-ChzpCnZ-.js.map} +1 -1
- package/dist/_chunks/{image-cropper-DWSnyLwW.js → image-cropper-C84NDTB7.js} +2 -2
- package/dist/_chunks/{image-cropper-DWSnyLwW.js.map → image-cropper-C84NDTB7.js.map} +1 -1
- package/dist/_chunks/{info-tip-C4mPSJbS.js → info-tip-C119cwQl.js} +2 -2
- package/dist/_chunks/{info-tip-C4mPSJbS.js.map → info-tip-C119cwQl.js.map} +1 -1
- package/dist/_chunks/{insert-result-98J1QEp7.js → insert-result-LCNTskNJ.js} +2 -2
- package/dist/_chunks/{insert-result-98J1QEp7.js.map → insert-result-LCNTskNJ.js.map} +1 -1
- package/dist/_chunks/{key-value-pair-DGkGlgCF.js → key-value-pair-BubG4fUa.js} +2 -2
- package/dist/_chunks/{key-value-pair-DGkGlgCF.js.map → key-value-pair-BubG4fUa.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-D3IsW_2R.js → link-cell-renderer-DH4JYpKU.js} +2 -2
- package/dist/_chunks/{link-cell-renderer-D3IsW_2R.js.map → link-cell-renderer-DH4JYpKU.js.map} +1 -1
- package/dist/_chunks/{locale-picker-sI0HWgZy.js → locale-picker-BvbVjDQ-.js} +3 -3
- package/dist/_chunks/{locale-picker-sI0HWgZy.js.map → locale-picker-BvbVjDQ-.js.map} +1 -1
- package/dist/_chunks/{map-view-iwSDRW3t.js → map-view-CCAlC9IL.js} +2 -2
- package/dist/_chunks/{map-view-iwSDRW3t.js.map → map-view-CCAlC9IL.js.map} +1 -1
- package/dist/_chunks/{marketplace-app-shell-b5hN-Q0m.js → marketplace-app-shell-Chfdia7m.js} +4 -4
- package/dist/_chunks/{marketplace-app-shell-b5hN-Q0m.js.map → marketplace-app-shell-Chfdia7m.js.map} +1 -1
- package/dist/_chunks/{message-card-BCJ-Jgs6.js → message-card-D8GB4FdF.js} +3 -3
- package/dist/_chunks/{message-card-BCJ-Jgs6.js.map → message-card-D8GB4FdF.js.map} +1 -1
- package/dist/_chunks/{message-tray-DHtm_WaF.js → message-tray-CGIRQjx5.js} +4 -4
- package/dist/_chunks/{message-tray-DHtm_WaF.js.map → message-tray-CGIRQjx5.js.map} +1 -1
- package/dist/_chunks/{notes-panel-D6HKLLS-.js → notes-panel-DlnENphf.js} +3 -3
- package/dist/_chunks/{notes-panel-D6HKLLS-.js.map → notes-panel-DlnENphf.js.map} +1 -1
- package/dist/_chunks/{notification-card-CcMQn2RX.js → notification-card-CtrzoTUO.js} +3 -3
- package/dist/_chunks/{notification-card-CcMQn2RX.js.map → notification-card-CtrzoTUO.js.map} +1 -1
- package/dist/_chunks/{notification-tray-nr7dv-Q8.js → notification-tray-BiRzXHDf.js} +4 -4
- package/dist/_chunks/{notification-tray-nr7dv-Q8.js.map → notification-tray-BiRzXHDf.js.map} +1 -1
- package/dist/_chunks/{optical-prescription-DtzEqFQm.js → optical-prescription-Dj3Eh5Ok.js} +2 -2
- package/dist/_chunks/{optical-prescription-DtzEqFQm.js.map → optical-prescription-Dj3Eh5Ok.js.map} +1 -1
- package/dist/_chunks/{patient-details-rENrE_qY.js → patient-details-qnsqYBGQ.js} +5 -5
- package/dist/_chunks/{patient-details-rENrE_qY.js.map → patient-details-qnsqYBGQ.js.map} +1 -1
- package/dist/_chunks/{patient-search-NQemeJlL.js → patient-search-D5ufYoRc.js} +2 -2
- package/dist/_chunks/{patient-search-NQemeJlL.js.map → patient-search-D5ufYoRc.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-DQJgOOrA.js → patient-summary-card-CBfuDvJ5.js} +3 -3
- package/dist/_chunks/{patient-summary-card-DQJgOOrA.js.map → patient-summary-card-CBfuDvJ5.js.map} +1 -1
- package/dist/_chunks/{patient-table-BubxfOWL.js → patient-table-DwshfVsQ.js} +3 -3
- package/dist/_chunks/{patient-table-BubxfOWL.js.map → patient-table-DwshfVsQ.js.map} +1 -1
- package/dist/_chunks/{payment-automation-upsell-CnaBPt5e.js → payment-automation-upsell-BBIG7NFL.js} +2 -2
- package/dist/_chunks/{payment-automation-upsell-CnaBPt5e.js.map → payment-automation-upsell-BBIG7NFL.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-CvhDzDNk.js → payment-request-card-BjjBMdsp.js} +3 -3
- package/dist/_chunks/{payment-request-card-CvhDzDNk.js.map → payment-request-card-BjjBMdsp.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-C0nNQKKK.js → periodontal-chart-BatZEFar.js} +2 -2
- package/dist/_chunks/{periodontal-chart-C0nNQKKK.js.map → periodontal-chart-BatZEFar.js.map} +1 -1
- package/dist/_chunks/{periodontal-chart-card-Bz-ebteE.js → periodontal-chart-card-BBpY_rBc.js} +2 -2
- package/dist/_chunks/{periodontal-chart-card-Bz-ebteE.js.map → periodontal-chart-card-BBpY_rBc.js.map} +1 -1
- package/dist/_chunks/{popover-Btj6N25H.js → popover-Cqcjx-Ny.js} +2 -2
- package/dist/_chunks/{popover-Btj6N25H.js.map → popover-Cqcjx-Ny.js.map} +1 -1
- package/dist/_chunks/{practice-results-CKoLD_x5.js → practice-results-BEsAdW-B.js} +719 -633
- package/dist/_chunks/practice-results-BEsAdW-B.js.map +1 -0
- package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js → pregnancy-dating-BVS_9YU2.js} +2 -2
- package/dist/_chunks/{pregnancy-dating-DQVpFs_f.js.map → pregnancy-dating-BVS_9YU2.js.map} +1 -1
- package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js → pregnancy-weight-gain-CJwbs9W-.js} +2 -2
- package/dist/_chunks/{pregnancy-weight-gain-hm3QJALe.js.map → pregnancy-weight-gain-CJwbs9W-.js.map} +1 -1
- package/dist/_chunks/{privacy-lock-SQYFRSuH.js → privacy-lock-CkAUo6Dz.js} +3 -3
- package/dist/_chunks/{privacy-lock-SQYFRSuH.js.map → privacy-lock-CkAUo6Dz.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-BjnD9pdl.js → product-hub-panel-BScCotGD.js} +3 -3
- package/dist/_chunks/{product-hub-panel-BjnD9pdl.js.map → product-hub-panel-BScCotGD.js.map} +1 -1
- package/dist/_chunks/{public-header.agent-DseNK2NQ.js → public-header.agent-kth2SdXn.js} +3 -3
- package/dist/_chunks/{public-header.agent-DseNK2NQ.js.map → public-header.agent-kth2SdXn.js.map} +1 -1
- package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js → radiograph-panel.agent-CiHwgISa.js} +4 -4
- package/dist/_chunks/{radiograph-panel.agent-CAXFgCyn.js.map → radiograph-panel.agent-CiHwgISa.js.map} +1 -1
- package/dist/_chunks/{reviews-panel-Cd3SxJdW.js → reviews-panel-BKHEfqVQ.js} +4 -4
- package/dist/_chunks/{reviews-panel-Cd3SxJdW.js.map → reviews-panel-BKHEfqVQ.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-DGtn_4sb.js → rich-text-editor-DARnq_6N.js} +5 -5
- package/dist/_chunks/{rich-text-editor-DGtn_4sb.js.map → rich-text-editor-DARnq_6N.js.map} +1 -1
- package/dist/_chunks/{session-countdown-q4r5TlCo.js → session-countdown-QMsnRa1x.js} +2 -2
- package/dist/_chunks/{session-countdown-q4r5TlCo.js.map → session-countdown-QMsnRa1x.js.map} +1 -1
- package/dist/_chunks/{sheet-CD99CdXr.js → sheet-BSznOyJs.js} +2 -2
- package/dist/_chunks/{sheet-CD99CdXr.js.map → sheet-BSznOyJs.js.map} +1 -1
- package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js → sign-in-with-alfadocs-button-BLe_quy5.js} +2 -2
- package/dist/_chunks/{sign-in-with-alfadocs-button-_JxVRO5d.js.map → sign-in-with-alfadocs-button-BLe_quy5.js.map} +1 -1
- package/dist/_chunks/{signature-request-C4UBfVRZ.js → signature-request-DXhpphlp.js} +4 -4
- package/dist/_chunks/{signature-request-C4UBfVRZ.js.map → signature-request-DXhpphlp.js.map} +1 -1
- package/dist/_chunks/{slot-grid-P_e9p5t5.js → slot-grid-BuZOKfcd.js} +4 -4
- package/dist/_chunks/{slot-grid-P_e9p5t5.js.map → slot-grid-BuZOKfcd.js.map} +1 -1
- package/dist/_chunks/{streaming-text-BuW7I0Zu.js → streaming-text-CvsjIQ7S.js} +2 -2
- package/dist/_chunks/{streaming-text-BuW7I0Zu.js.map → streaming-text-CvsjIQ7S.js.map} +1 -1
- package/dist/_chunks/{task-tray-BT288xoM.js → task-tray-CYG6rj2s.js} +3 -3
- package/dist/_chunks/{task-tray-BT288xoM.js.map → task-tray-CYG6rj2s.js.map} +1 -1
- package/dist/_chunks/{tasks-panel-BBkZuejF.js → tasks-panel-Do5SFp-j.js} +5 -5
- package/dist/_chunks/{tasks-panel-BBkZuejF.js.map → tasks-panel-Do5SFp-j.js.map} +1 -1
- package/dist/_chunks/{theme-toggle-Bi-CmV6M.js → theme-toggle-DuMhQNFS.js} +3 -3
- package/dist/_chunks/{theme-toggle-Bi-CmV6M.js.map → theme-toggle-DuMhQNFS.js.map} +1 -1
- package/dist/_chunks/{toast.agent-C44mtGrW.js → toast.agent-D1tdg6DS.js} +2 -2
- package/dist/_chunks/{toast.agent-C44mtGrW.js.map → toast.agent-D1tdg6DS.js.map} +1 -1
- package/dist/_chunks/{token-insert-menu-D8FgXl33.js → token-insert-menu-9Um0JinI.js} +2 -2
- package/dist/_chunks/{token-insert-menu-D8FgXl33.js.map → token-insert-menu-9Um0JinI.js.map} +1 -1
- package/dist/_chunks/{tool-rail-BF3F2Ihq.js → tool-rail-CHyUmulN.js} +2 -2
- package/dist/_chunks/{tool-rail-BF3F2Ihq.js.map → tool-rail-CHyUmulN.js.map} +1 -1
- package/dist/_chunks/{tooth-scheme-BPXE1_3N.js → tooth-scheme-WdyVymQ1.js} +3 -3
- package/dist/_chunks/{tooth-scheme-BPXE1_3N.js.map → tooth-scheme-WdyVymQ1.js.map} +1 -1
- package/dist/_chunks/{unit-converter-iDxlxKmm.js → unit-converter-BPumXMA6.js} +2 -2
- package/dist/_chunks/{unit-converter-iDxlxKmm.js.map → unit-converter-BPumXMA6.js.map} +1 -1
- package/dist/_chunks/{warning-stack-nczJf52p.js → warning-stack-DQz0Jyir.js} +3 -3
- package/dist/_chunks/{warning-stack-nczJf52p.js.map → warning-stack-DQz0Jyir.js.map} +1 -1
- package/dist/_chunks/{workflow-map-BVofnDYh.js → workflow-map-DE_ribRM.js} +5 -5
- package/dist/_chunks/{workflow-map-BVofnDYh.js.map → workflow-map-DE_ribRM.js.map} +1 -1
- package/dist/agent-catalog.json +2 -2
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/ai-consent-banner/index.js +1 -1
- package/dist/components/ai-prompt-input/index.js +1 -1
- package/dist/components/anamnesis-card/index.js +1 -1
- package/dist/components/appointment-card/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/audio-recorder/index.js +1 -1
- package/dist/components/bishop-score/index.js +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/button/button.d.ts +10 -0
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/index.js +2 -2
- package/dist/components/button-group/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-entry-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/carousel/index.js +1 -1
- package/dist/components/chart/index.js +1 -1
- package/dist/components/chat-input/index.js +1 -1
- package/dist/components/chat-message/index.js +1 -1
- package/dist/components/connection-status/index.js +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/control-room-rail/index.js +1 -1
- package/dist/components/copy-field/index.js +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/dashboard-grid/index.js +1 -1
- package/dist/components/data-table/index.js +3 -3
- package/dist/components/data-table-tabs/index.js +1 -1
- package/dist/components/description-list/index.js +1 -1
- package/dist/components/document-preview/index.js +1 -1
- package/dist/components/document-scanner/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/editor-overlay/index.js +1 -1
- package/dist/components/empty-state/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/face-scheme/index.js +1 -1
- package/dist/components/fetal-weight/index.js +1 -1
- package/dist/components/field-array/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/finished-terminal/index.js +1 -1
- package/dist/components/fiscal-code-input/index.js +1 -1
- package/dist/components/freemium-paywall/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/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/icon-button/index.js +1 -1
- package/dist/components/icon-button-group/index.js +1 -1
- package/dist/components/icon-picker/index.js +1 -1
- package/dist/components/image-cropper/index.js +1 -1
- package/dist/components/info-tip/index.js +1 -1
- package/dist/components/key-value-pair/index.js +1 -1
- package/dist/components/locale-picker/index.js +1 -1
- package/dist/components/map-view/index.js +1 -1
- package/dist/components/matrix-rain/matrix-rain.d.ts +1 -1
- package/dist/components/message-card/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notification-card/index.js +1 -1
- package/dist/components/notification-tray/index.js +1 -1
- package/dist/components/optical-prescription/index.js +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-search/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/periodontal-chart/index.js +1 -1
- package/dist/components/periodontal-chart-card/index.js +1 -1
- package/dist/components/popover/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/practice-results/practice-results.d.ts +47 -7
- package/dist/components/practice-results/practice-results.d.ts.map +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/privacy-lock/index.js +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/public-header/public-header.d.ts +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/reviews-panel/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/session-countdown/index.js +1 -1
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/components/streaming-text/index.js +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/toast/index.js +1 -1
- package/dist/components/token-insert-menu/index.js +1 -1
- package/dist/components/tool-rail/index.js +1 -1
- package/dist/components/tooth-scheme/index.js +1 -1
- package/dist/components/unit-converter/index.js +1 -1
- package/dist/components/warning-stack/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +1 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +2 -1
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +1 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +2 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +1 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +2 -1
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +1 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +2 -1
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +1 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +2 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +1 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +2 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +1 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +2 -1
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +1 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +2 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +1 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +2 -1
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +1 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +2 -1
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +1 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +2 -1
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +1 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +2 -1
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +1 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +2 -1
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +1 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +2 -1
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +1 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +2 -1
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +1 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +2 -1
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +1 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +2 -1
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +1 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +2 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +96 -96
- package/dist/locales/ar.json +2 -1
- package/dist/locales/de.json +2 -1
- package/dist/locales/el.json +2 -1
- package/dist/locales/en.json +2 -1
- package/dist/locales/es.json +2 -1
- package/dist/locales/fr.json +2 -1
- package/dist/locales/hi.json +2 -1
- package/dist/locales/it.json +2 -1
- package/dist/locales/ja.json +2 -1
- package/dist/locales/nl.json +2 -1
- package/dist/locales/pl.json +2 -1
- package/dist/locales/pt.json +2 -1
- package/dist/locales/ro.json +2 -1
- package/dist/locales/ru.json +2 -1
- package/dist/locales/sq.json +2 -1
- package/dist/locales/sv.json +2 -1
- package/dist/locales/tr.json +2 -1
- package/dist/locales/zh.json +2 -1
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/payment-automation-upsell/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/button-BvNtqHAS.js.map +0 -1
- package/dist/_chunks/practice-results-CKoLD_x5.js.map +0 -1
package/dist/_chunks/{product-hub-panel-BjnD9pdl.js.map → product-hub-panel-BScCotGD.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-hub-panel-BjnD9pdl.js","sources":["../../node_modules/lucide-react/dist/esm/icons/gift.mjs","../../src/components/product-hub-tray/product-hub-tray.agent.ts","../../src/components/product-hub-tray/product-hub-tray.tsx","../../src/components/product-hub-tray/product-hub-panel.agent.ts","../../src/components/product-hub-tray/product-hub-panel.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 7v14\", key: \"1akyts\" }],\n [\"path\", { d: \"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\", key: \"1sqzm4\" }],\n [\n \"path\",\n { d: \"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\", key: \"kc0143\" }\n ],\n [\"rect\", { x: \"3\", y: \"7\", width: \"18\", height: \"4\", rx: \"1\", key: \"1hberx\" }]\n];\nconst Gift = createLucideIcon(\"gift\", __iconNode);\n\nexport { __iconNode, Gift as default };\n//# sourceMappingURL=gift.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — ProductHubTray. */\n/* */\n/* Tray-level surface: an agent can open / close the dropdown panel and */\n/* read the unseen-release count. Release content (titles, summaries, */\n/* URLs) is never exposed — counts and booleans only. All actions are */\n/* routed through the curated imperative handle; the adapter never */\n/* touches the DOM directly. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ProductHubTrayHandle } from './product-hub-tray';\n\nexport const productHubTrayAgent: AgentAdapter<ProductHubTrayHandle> = {\n id: 'product-hub-tray',\n capabilities: ['open', 'close'],\n state: {\n unseenCount: {\n type: 'number',\n descriptionKey: 'ui.agent.productHubTray.state.unseenCount',\n description:\n 'Number of unseen product releases — the trigger badge count.',\n read: (handle) => handle.getUnseenCount(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.productHubTray.actions.open',\n description: 'Open the product-updates panel.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.productHubTray.actions.close',\n description: 'Close the product-updates panel.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'product-hub-tray',\n description: 'Marks the ProductHubTray 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-update-id',\n description:\n 'Stable release id emitted on each rendered release row inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\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 { Gift, X } from 'lucide-react';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { IconButton } from '../button/icon-button';\nimport { Link } from '../link';\nimport { ScrollArea } from '../scroll-area/scroll-area';\nimport { Separator } from '../separator/separator';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { Timestamp } from '../timestamp';\nimport { isSafeEntityUrl } from '../_shared/is-safe-url';\nimport { safeImageSrc } from '../_shared/safe-image-src';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { productHubTrayAgent } from './product-hub-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * One product-hub release entry. The kit is purely presentational —\n * the consumer fetches releases (Supabase, REST, …) and maps them into\n * this shape.\n */\nexport interface ProductHubItem {\n /** Unique identifier for the release. */\n id: string;\n /** Release title — rendered bold on the first line. */\n title: string;\n /** Short release summary — rendered as plain text, clamped to 2 lines. */\n summary?: string;\n /** ISO-8601 publish date — rendered as a localised, italic absolute date. */\n dateIso?: string;\n /**\n * Thumbnail URL. Guarded through the shared `safeImageSrc` allow-list\n * and rendered with `referrerPolicy=\"no-referrer\"`. Unsafe or missing\n * sources fall back to a Gift glyph tile.\n */\n imageUrl?: string;\n /**\n * Release deep link. Guarded through `isSafeEntityUrl`; safe URLs make\n * the row title an anchor that opens in a new tab. Unsafe URLs render\n * the title as plain text.\n */\n url?: string;\n /** Marks the release as not yet seen — highlights the row and counts toward the trigger badge. */\n unseen?: boolean;\n}\n\n/**\n * Curated imperative handle for ProductHubTray. Exposed to the agent\n * registry so a future MCP UI bridge can drive the tray without touching\n * the DOM. See `product-hub-tray.agent.ts`.\n */\nexport interface ProductHubTrayHandle {\n open: () => void;\n close: () => void;\n getUnseenCount: () => number;\n}\n\nexport interface ProductHubTrayProps\n extends\n Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onClick' | 'children' | 'role' | 'id'\n >,\n VariantProps<typeof productHubTrayVariants> {\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 /** Releases rendered in the dropdown panel, newest first. */\n items: ProductHubItem[];\n /**\n * Product-hub landing URL. When set (and safe) the panel renders a\n * pinned \"Open in Product Hub\" footer link that opens in a new tab.\n */\n hubUrl?: string;\n /** When true the panel shows skeleton placeholders. */\n loading?: boolean;\n /** Error-state slot — rendered inside the panel instead of the list. */\n error?: ReactNode;\n /**\n * Unseen-release count override. Defaults to the number of `items`\n * with `unseen: true`. Drives the trigger badge.\n */\n unseenCount?: number;\n /** Fires when the open state changes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Analytics hook — fires when a row is activated. Navigation itself is\n * owned by the row anchor (new tab); this callback must not be relied\n * on for routing.\n */\n onItemActivate?: (item: ProductHubItem) => void;\n /** Override for the trigger's accessible label. */\n triggerLabel?: string;\n /** Number of releases rendered before the rest are cut off. Default 10. */\n maxVisible?: number;\n /** Empty-state slot — replaces the built-in \"No product updates yet\" panel. */\n emptyState?: ReactNode;\n /** Open the panel on first mount (uncontrolled). */\n defaultOpen?: boolean;\n /** BCP-47 locale override for the per-row dates. Falls back to `i18n.language`. */\n locale?: string;\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 productHubTrayVariants = cva(\n 'ds:relative ds:inline-flex ds:items-center',\n {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'md',\n },\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 // Fluid below the design cap so narrow viewports keep a gutter on\n // both sides of the panel (shadow included).\n 'ds:w-[min(24rem,calc(100vw-2*var(--spacing-md)))]',\n // Near-full-screen sheet below `sm`; auto above, where the list's\n // own `--product-hub-tray-max-block-size` 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 // Anchored to the top-end corner of the trigger, nudged outward so\n // the gift glyph isn't covered.\n 'ds:absolute ds:-top-[var(--spacing-xs)] ds:-end-[var(--spacing-xs)]',\n 'ds:inline-flex ds:items-center ds:justify-center',\n // Circle at 1-2 digits; widens into a pill only for \"99+\".\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 // One red unseen-count chip across every header tray — matches the\n // platform header and the NotificationTray badge convention.\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/* Shared release row — used by both ProductHubTray (compact) and */\n/* ProductHubPanel (roomier). Internal seam, not part of the barrel. */\n/* ------------------------------------------------------------------ */\n\nconst rowVariants = cva(\n [\n // `group` so the hover/focus-revealed close button can react to the whole\n // row, not just itself.\n 'ds:group ds:relative ds:flex ds:items-start',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-start',\n 'ds:transition-colors ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n density: {\n tray: 'ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]',\n panel: 'ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]',\n },\n // Unseen no longer tints the background — the read/new state is carried\n // by the leading-corner Gift indicator instead, matching the\n // notification / message cards.\n unseen: {\n true: 'ds:hover:bg-[color:var(--muted)]/40',\n false: 'ds:hover:bg-[color:var(--muted)]/40',\n },\n // Row chrome: flat (inside a bordered tray/panel) vs elevated (own card\n // on a rail). Mirrors AppointmentCard / NotificationCard so the Inbox\n // feed reads consistently with the other rail panels.\n surface: {\n flat: '',\n elevated:\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2 ds:shadow-[var(--shadow-sm)]',\n },\n },\n defaultVariants: {\n density: 'tray',\n unseen: false,\n surface: 'flat',\n },\n },\n);\n\nconst thumbVariants = cva(\n [\n 'ds:shrink-0 ds:rounded-[var(--radius-sm)] ds:object-cover',\n // Tile backdrop so transparent / still-loading thumbnails keep a\n // visible square instead of collapsing into whitespace.\n 'ds:bg-[color:var(--muted)]',\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n density: {\n tray: 'ds:size-10',\n panel: 'ds:size-12',\n },\n },\n defaultVariants: {\n density: 'tray',\n },\n },\n);\n\nconst stretchedLinkClass = [\n 'ds:focus-visible:outline-none',\n \"ds:after:content-[''] ds:after:absolute ds:after:inset-0 ds:after:rounded-[var(--radius-sm)]\",\n 'ds:after:pointer-events-auto',\n 'ds:focus-visible:after:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:after:outline-solid',\n 'ds:focus-visible:after:outline-[color:var(--ring)]',\n 'ds:focus-visible:after:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:after:outline-[CanvasText]',\n].join(' ');\n\nexport interface ProductHubUpdateRowProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onClick' | 'role' | 'title'\n> {\n /** The release to render. */\n item: ProductHubItem;\n /** `tray` — compact dropdown row. `panel` — roomier dashboard row. */\n density?: 'tray' | 'panel';\n /**\n * Row chrome. `'flat'` (default) — chrome-less row inside a bordered\n * tray/panel. `'elevated'` — own card chrome (border + `--shadow-sm`) for\n * rail feeds (e.g. the Inbox), matching the sibling notification/message\n * cards.\n */\n surface?: 'flat' | 'elevated';\n /** BCP-47 locale override for the date. */\n locale?: string;\n /** Analytics hook — navigation is owned by the row anchor. */\n onActivate?: (item: ProductHubItem) => void;\n /**\n * When supplied, renders a close affordance (revealed on row hover / focus)\n * that fires with this item — e.g. dismissing the update from an Inbox feed.\n */\n onDismiss?: (item: ProductHubItem) => void;\n}\n\n/**\n * @internal Shared row between ProductHubTray and ProductHubPanel.\n * Exported for the sibling panel only — import the trays, not this.\n */\nexport function ProductHubUpdateRow({\n item,\n density = 'tray',\n surface = 'flat',\n locale,\n onActivate,\n onDismiss,\n className,\n ...rest\n}: ProductHubUpdateRowProps) {\n const { t } = useTranslation();\n const safeSrc = safeImageSrc(item.imageUrl);\n const hasSafeUrl = !!item.url && isSafeEntityUrl(item.url);\n const unseen = !!item.unseen;\n\n // Close insets track the row padding so it aligns with the title's first\n // line at either density.\n const closeInset =\n density === 'panel'\n ? 'ds:top-[var(--spacing-md)] ds:end-[var(--spacing-md)]'\n : 'ds:top-[var(--spacing-sm)] ds:end-[var(--spacing-sm)]';\n\n // Read after the title when the row gets focus / is traversed:\n // \"<title>, new, (opens in a new tab)\". The unseen dot itself is\n // decorative — state never relies on colour alone.\n const unseenHint = unseen ? (\n <span className=\"ds:sr-only\">\n {t('productHubTray.unseenLabel', ', new')}\n </span>\n ) : null;\n\n return (\n <div\n role=\"listitem\"\n data-component=\"product-hub-update\"\n data-update-id={item.id}\n data-unseen={unseen ? 'true' : 'false'}\n className={rowVariants({ density, unseen, surface, className })}\n {...rest}\n >\n <span className=\"ds:relative ds:shrink-0\">\n {safeSrc ? (\n <img\n src={safeSrc}\n alt=\"\"\n aria-hidden=\"true\"\n referrerPolicy=\"no-referrer\"\n loading=\"lazy\"\n className={thumbVariants({ density })}\n />\n ) : (\n <span\n aria-hidden=\"true\"\n className={`${thumbVariants({ density })} ds:inline-flex ds:items-center ds:justify-center ds:text-[color:var(--muted-foreground)] ds:[&>svg]:size-5`}\n >\n <Gift />\n </span>\n )}\n {/* Unseen \"new\" marker — a dot on the thumbnail corner (the read /\n unread indicator moved inline-start). Decorative; the title link\n carries the sr-only \"new\" hint for assistive tech. */}\n {unseen ? (\n <span\n aria-hidden=\"true\"\n data-testid=\"product-hub-unseen-dot\"\n className=\"ds:absolute ds:top-[calc(var(--spacing-xs)*-1)] ds:end-[calc(var(--spacing-xs)*-1)] ds:z-[1] ds:block ds:size-[calc(var(--spacing-sm)+var(--spacing-xs))] ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)] ds:ring-2 ds:ring-[color:var(--card)] ds:forced-colors:bg-[Highlight]\"\n />\n ) : null}\n </span>\n\n <div className=\"ds:min-w-0 ds:flex-1 ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] type-title-item ds:text-[color:var(--foreground)]\">\n {hasSafeUrl ? (\n // A real (non-display:contents) anchor so the row is reliably\n // keyboard-focusable; the ::after stretch keeps the whole row\n // clickable and carries the focus ring.\n <a\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`${stretchedLinkClass} ds:min-w-0 ds:flex-1 ds:no-underline ds:text-[color:var(--foreground)]`}\n onClick={() => onActivate?.(item)}\n >\n <span className=\"ds:block ds:truncate ds:font-semibold\">\n {item.title}\n </span>\n {unseenHint}\n <span className=\"ds:sr-only\">\n {t('productHubTray.opensInNewTab', '(opens in a new tab)')}\n </span>\n </a>\n ) : (\n <>\n <span className=\"ds:min-w-0 ds:flex-1 ds:truncate ds:font-semibold\">\n {item.title}\n </span>\n {unseenHint}\n </>\n )}\n </span>\n\n {item.summary ? (\n <p className=\"ds:m-0 type-body-sm ds:text-[color:var(--muted-foreground)] ds:[overflow:hidden] ds:[display:-webkit-box] ds:[-webkit-box-orient:vertical] ds:[-webkit-line-clamp:2] ds:break-words\">\n {item.summary}\n </p>\n ) : null}\n\n {item.dateIso ? (\n <Timestamp\n value={item.dateIso}\n format=\"absolute\"\n locale={locale}\n className=\"ds:italic ds:text-[color:var(--muted-foreground)]\"\n />\n ) : null}\n </div>\n\n {/* Close — inline-end, hover/focus-revealed. Absolutely positioned so it\n claims no width at rest: the title fills the row and there's no empty\n gap when the row isn't hovered. */}\n {onDismiss ? (\n <span\n className={\n 'ds:absolute ds:z-[2] ds:opacity-0 ds:pointer-events-none ds:transition-opacity ds:motion-reduce:transition-none ds:group-hover:opacity-100 ds:group-hover:pointer-events-auto ds:group-focus-within:opacity-100 ds:group-focus-within:pointer-events-auto ' +\n closeInset\n }\n >\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('productHubTray.dismiss', 'Dismiss update')}\n onClick={() => onDismiss(item)}\n />\n </span>\n ) : null}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Shared loading / status helpers (also consumed by ProductHubPanel) */\n/* ------------------------------------------------------------------ */\n\n/** @internal Skeleton placeholder mirroring the row layout. */\nexport function UpdateSkeletonRow({\n density = 'tray',\n}: {\n density?: 'tray' | 'panel';\n}) {\n return (\n <div\n aria-hidden=\"true\"\n className={\n density === 'panel'\n ? 'ds:flex ds:items-start ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]'\n : 'ds:flex ds:items-start ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]'\n }\n >\n <Skeleton\n variant=\"rounded\"\n width={density === 'panel' ? '3rem' : '2.5rem'}\n height={density === 'panel' ? '3rem' : '2.5rem'}\n />\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=\"90%\" />\n <Skeleton variant=\"text\" size=\"sm\" width=\"30%\" />\n </div>\n </div>\n );\n}\n\n/** @internal Centered status container for error / consumer-slot states. */\nexport function UpdateStatusPanel({ children }: { children: ReactNode }) {\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 type-body-sm ds:text-[color:var(--muted-foreground)]\"\n >\n {children}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction formatBadgeCount(count: number, overflowLabel: string): string {\n return count > 99 ? overflowLabel : String(count);\n}\n\nfunction EmptyPanel() {\n const { t } = useTranslation();\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 <Gift />\n </span>\n <p className=\"type-title-item ds:text-[color:var(--foreground)]\">\n {t('productHubTray.emptyTitle', 'No product updates yet')}\n </p>\n <p className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {t(\n 'productHubTray.emptyDescription',\n 'New releases and improvements will appear here.',\n )}\n </p>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport const ProductHubTray = forwardRef<HTMLDivElement, ProductHubTrayProps>(\n (\n {\n id,\n items,\n hubUrl,\n loading = false,\n error,\n unseenCount,\n onOpenChange,\n onItemActivate,\n triggerLabel,\n maxVisible = 10,\n emptyState,\n defaultOpen = false,\n locale,\n align = 'end',\n side = 'bottom',\n size = 'md',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const [isOpenRaw, handleOpenChange] = useControllableState<boolean>({\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n const isOpen = isOpenRaw ?? false;\n\n const displayCount = unseenCount ?? items.filter((i) => i.unseen).length;\n const resolvedTriggerLabel =\n triggerLabel ??\n (displayCount > 0\n ? t('productHubTray.triggerLabel', {\n count: displayCount,\n defaultValue: \"What's new, {{count}} unseen updates\",\n })\n : t('productHubTray.triggerLabelNone', \"What's new\"));\n\n const badgeLabel = formatBadgeCount(\n displayCount,\n t('productHubTray.badgeCountOverflow', '99+'),\n );\n\n const visible = items.slice(0, Math.max(0, maxVisible));\n const showList = !error && !loading && visible.length > 0;\n const safeHubUrl = hubUrl && isSafeEntityUrl(hubUrl) ? hubUrl : undefined;\n\n /* Curated handle — refs keep the look-ups current without\n * re-memoising on every items update. */\n const itemsRef = useRef<ProductHubItem[]>(items);\n itemsRef.current = items;\n const unseenRef = useRef<number | undefined>(unseenCount);\n unseenRef.current = unseenCount;\n\n const handle = useMemo<ProductHubTrayHandle>(\n () => ({\n open: () => handleOpenChange(true),\n close: () => handleOpenChange(false),\n getUnseenCount: () =>\n unseenRef.current ?? itemsRef.current.filter((i) => i.unseen).length,\n }),\n [handleOpenChange],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLDivElement, []);\n useAgentRegistration(productHubTrayAgent, handle, id);\n\n let body: ReactNode;\n if (error) {\n body = <UpdateStatusPanel>{error}</UpdateStatusPanel>;\n } else if (loading) {\n body = (\n <>\n <UpdateSkeletonRow />\n <UpdateSkeletonRow />\n <UpdateSkeletonRow />\n </>\n );\n } else if (visible.length === 0) {\n body = emptyState ?? <EmptyPanel />;\n } else {\n body = visible.map((item) => (\n <ProductHubUpdateRow\n key={item.id}\n item={item}\n density=\"tray\"\n locale={locale}\n onActivate={onItemActivate}\n />\n ));\n }\n\n return (\n <div\n ref={rootRef}\n data-component=\"product-hub-tray\"\n data-component-id={id}\n className={[productHubTrayVariants({ 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={<Gift />}\n intent=\"outline\"\n size={size === 'sm' ? 'sm' : 'md'}\n aria-label={resolvedTriggerLabel}\n aria-haspopup=\"dialog\"\n />\n </RadixPopover.Trigger>\n {displayCount > 0 ? (\n <span\n aria-hidden=\"true\"\n data-testid=\"product-hub-tray-badge\"\n className={badgeVariants()}\n >\n {badgeLabel}\n </span>\n ) : null}\n <RadixPopover.Portal>\n <RadixPopover.Content\n role=\"dialog\"\n aria-label={t('productHubTray.panelTitle', \"What's new\")}\n side={side}\n align={align}\n sideOffset={8}\n // Keeps Radix's collision-avoidance from flush-mounting the\n // panel against the viewport edge on narrow screens.\n collisionPadding={16}\n className={panelVariants({ size })}\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('productHubTray.panelTitle', \"What's new\")}\n </h3>\n </div>\n <Separator />\n {/* The release list is the ONLY scroll region. `role=\"list\"`\n requires `listitem` children, so it is applied only when\n rows render (axe aria-required-children). Consumers\n override the height cap via the\n `--product-hub-tray-max-block-size` custom property. */}\n <ScrollArea\n orientation=\"vertical\"\n className=\"ds:flex-1 ds:sm:flex-none ds:sm:[max-block-size:var(--product-hub-tray-max-block-size,24rem)]\"\n >\n <div\n role={showList ? '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 {body}\n </div>\n </ScrollArea>\n {safeHubUrl ? (\n <>\n <Separator />\n <div className=\"ds:flex ds:justify-center ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-xs)]\">\n <Link href={safeHubUrl} external>\n {t('productHubTray.openHub', 'Open in Product Hub')}\n </Link>\n </div>\n </>\n ) : null}\n </RadixPopover.Content>\n </RadixPopover.Portal>\n </RadixPopover.Root>\n </div>\n );\n },\n);\n\nProductHubTray.displayName = 'ProductHubTray';\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — ProductHubPanel. */\n/* */\n/* Read-mostly dashboard surface: an agent can read the displayed */\n/* release ids + unseen flags (never titles / summaries / URLs) and */\n/* route a per-item activation through the curated handle. The adapter */\n/* never touches the DOM directly. */\n/* */\n/* NOTE: catalog discovery only picks up `<dirName>.agent.ts`, so this */\n/* sibling adapter is registered at runtime but not yet listed in */\n/* dist/agent-catalog.json (same situation as appointment-tray inside */\n/* the appointment-card directory). */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ProductHubPanelHandle } from './product-hub-panel';\n\nexport const productHubPanelAgent: AgentAdapter<ProductHubPanelHandle> = {\n id: 'product-hub-panel',\n // selectItem activates one release row (fires the host hook) without\n // persisting a stored selection → `pick`, not `select_single`.\n capabilities: ['pick'],\n state: {\n items: {\n type: 'Array<{ id: string; unseen: boolean }>',\n descriptionKey: 'ui.agent.productHubPanel.state.items',\n description:\n 'Currently-displayed releases. Ids + unseen flag only — no content.',\n read: (handle) => handle.getItems(),\n },\n unseenCount: {\n type: 'number',\n descriptionKey: 'ui.agent.productHubPanel.state.unseenCount',\n description: 'Number of displayed releases still marked unseen.',\n read: (handle) => handle.getUnseenCount(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Stable release id (the data-update-id of the row).',\n },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.productHubPanel.actions.selectItem',\n description:\n 'Activate the release with the given id (fires the host analytics hook).',\n examples: [\n { args: { id: 'rel-0680' }, note: 'Activate a specific release row.' },\n ],\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'product-hub-panel',\n description: 'Marks the ProductHubPanel section.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific panel from the agent.',\n },\n item: {\n attr: 'data-update-id',\n description:\n 'Stable release id emitted on each rendered release row inside the panel.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Gift } from 'lucide-react';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Link } from '../link';\nimport { Separator } from '../separator/separator';\nimport { isSafeEntityUrl } from '../_shared/is-safe-url';\nimport { useAgentRegistration } from '../../agent/registry';\nimport {\n ProductHubUpdateRow,\n UpdateSkeletonRow,\n UpdateStatusPanel,\n type ProductHubItem,\n} from './product-hub-tray';\nimport { productHubPanelAgent } from './product-hub-panel.agent';\n\n/* -------------------------------------------------------------------- */\n/* ProductHubPanel */\n/* */\n/* Dashboard-panel sibling of ProductHubTray: a titled, bordered card */\n/* (model: AgendaTray + the dashboard \"Recent notifications\" panel) */\n/* listing the same release rows at a roomier density — no popover. */\n/* The consumer fetches the data; loading / empty / error are props. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst productHubPanelVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:overflow-hidden',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n surface: {\n flat: '',\n elevated: 'ds:shadow-[var(--shadow-card)]',\n },\n },\n defaultVariants: {\n surface: 'elevated',\n },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/**\n * Curated imperative handle for ProductHubPanel — read-only ids / counts\n * plus a select delegation. See `product-hub-panel.agent.ts`.\n */\nexport interface ProductHubPanelHandle {\n getItems: () => Array<{ id: string; unseen: boolean }>;\n getUnseenCount: () => number;\n selectItem: (id: string) => void;\n}\n\nexport interface ProductHubPanelProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'onClick' | 'children' | 'id'>,\n VariantProps<typeof productHubPanelVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific panel.\n */\n id?: string;\n /** Releases rendered in the panel, newest first. */\n items: ProductHubItem[];\n /**\n * Product-hub landing URL. When set (and safe) the panel renders an\n * \"Open in Product Hub\" footer link that opens in a new tab.\n */\n hubUrl?: string;\n /** When true the panel shows skeleton placeholders. */\n loading?: boolean;\n /** Error-state slot — rendered instead of the list. */\n error?: ReactNode;\n /** Panel heading. Defaults to the localised \"What's new\". */\n title?: string;\n /** Optional sub-heading rendered under the title. */\n description?: string;\n /** Number of releases rendered before the rest are cut off. Default 5. */\n maxVisible?: number;\n /** Empty-state slot — replaces the built-in EmptyState. */\n emptyState?: ReactNode;\n /**\n * Analytics hook — fires when a row is activated. Navigation itself is\n * owned by the row anchor (new tab).\n */\n onItemActivate?: (item: ProductHubItem) => void;\n /** BCP-47 locale override for the per-row dates. */\n locale?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const ProductHubPanel = forwardRef<HTMLElement, ProductHubPanelProps>(\n (\n {\n id,\n items,\n hubUrl,\n loading = false,\n error,\n title,\n description,\n maxVisible = 5,\n emptyState,\n onItemActivate,\n locale,\n surface = 'elevated',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const heading = title ?? t('productHubPanel.title', \"What's new\");\n\n const visible = items.slice(0, Math.max(0, maxVisible));\n const safeHubUrl = hubUrl && isSafeEntityUrl(hubUrl) ? hubUrl : undefined;\n\n let body: ReactNode;\n if (error) {\n body = <UpdateStatusPanel>{error}</UpdateStatusPanel>;\n } else if (loading) {\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:p-[var(--spacing-sm)] ds:pt-0\">\n {[0, 1, 2].map((i) => (\n <UpdateSkeletonRow key={i} density=\"panel\" />\n ))}\n </div>\n );\n } else if (visible.length === 0) {\n body = emptyState ?? (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t('productHubPanel.emptyTitle', 'No product updates yet')}\n description={t(\n 'productHubPanel.emptyDescription',\n 'New releases and improvements will appear here.',\n )}\n />\n </div>\n );\n } else {\n body = (\n <div\n role=\"list\"\n data-max-visible={maxVisible}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:p-[var(--spacing-sm)] ds:pt-0\"\n >\n {visible.map((item) => (\n <ProductHubUpdateRow\n key={item.id}\n item={item}\n density=\"panel\"\n locale={locale}\n onActivate={onItemActivate}\n />\n ))}\n </div>\n );\n }\n\n /* Curated imperative handle for agent integration. */\n const itemsRef = useRef<ProductHubItem[]>(items);\n itemsRef.current = items;\n\n const handle = useMemo<ProductHubPanelHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({ id: i.id, unseen: !!i.unseen })),\n getUnseenCount: () => itemsRef.current.filter((i) => i.unseen).length,\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onItemActivate?.(found);\n },\n }),\n [onItemActivate],\n );\n\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n useAgentRegistration(productHubPanelAgent, handle, id);\n\n return (\n <section\n ref={innerRef}\n aria-label={heading}\n data-component=\"product-hub-panel\"\n data-component-id={id}\n className={productHubPanelVariants({ surface, className })}\n {...rest}\n >\n <header className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-[var(--spacing-md)] ds:pb-[var(--spacing-sm)]\">\n {/* h2 — visual peer of the dashboard's other titled regions.\n Heading ladder: h1 (page) → h2 (this panel) → row titles. */}\n <h2 className=\"ds:m-0 ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-start type-title-section ds:text-[color:var(--foreground)]\">\n <Gift aria-hidden=\"true\" className=\"ds:size-5 ds:shrink-0\" />\n {heading}\n </h2>\n {description ? (\n <p className=\"ds:m-0 ds:text-start type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {description}\n </p>\n ) : null}\n </header>\n {body}\n {safeHubUrl ? (\n <>\n <Separator />\n <div className=\"ds:flex ds:justify-center ds:p-[var(--spacing-sm)]\">\n <Link href={safeHubUrl} external>\n {t('productHubPanel.openHub', 'Open in Product Hub')}\n </Link>\n </div>\n </>\n ) : null}\n </section>\n );\n },\n);\n\nProductHubPanel.displayName = 'ProductHubPanel';\n"],"names":["__iconNode","Gift","createLucideIcon","productHubTrayAgent","handle","productHubTrayVariants","cva","panelVariants","badgeVariants","rowVariants","thumbVariants","stretchedLinkClass","ProductHubUpdateRow","item","density","surface","locale","onActivate","onDismiss","className","rest","t","useTranslation","safeSrc","safeImageSrc","hasSafeUrl","isSafeEntityUrl","unseen","closeInset","unseenHint","jsx","jsxs","Fragment","Timestamp","IconButton","X","UpdateSkeletonRow","Skeleton","UpdateStatusPanel","children","formatBadgeCount","count","overflowLabel","EmptyPanel","ProductHubTray","forwardRef","id","items","hubUrl","loading","error","unseenCount","onOpenChange","onItemActivate","triggerLabel","maxVisible","emptyState","defaultOpen","align","side","size","ref","isOpenRaw","handleOpenChange","useControllableState","isOpen","displayCount","i","resolvedTriggerLabel","badgeLabel","visible","showList","safeHubUrl","itemsRef","useRef","unseenRef","useMemo","rootRef","useImperativeHandle","useAgentRegistration","body","RadixPopover","Separator","ScrollArea","Link","productHubPanelAgent","args","productHubPanelVariants","ProductHubPanel","title","description","heading","EmptyState","targetId","found","innerRef"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"product-hub-panel-BScCotGD.js","sources":["../../node_modules/lucide-react/dist/esm/icons/gift.mjs","../../src/components/product-hub-tray/product-hub-tray.agent.ts","../../src/components/product-hub-tray/product-hub-tray.tsx","../../src/components/product-hub-tray/product-hub-panel.agent.ts","../../src/components/product-hub-tray/product-hub-panel.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 7v14\", key: \"1akyts\" }],\n [\"path\", { d: \"M20 11v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8\", key: \"1sqzm4\" }],\n [\n \"path\",\n { d: \"M7.5 7a1 1 0 0 1 0-5A4.8 8 0 0 1 12 7a4.8 8 0 0 1 4.5-5 1 1 0 0 1 0 5\", key: \"kc0143\" }\n ],\n [\"rect\", { x: \"3\", y: \"7\", width: \"18\", height: \"4\", rx: \"1\", key: \"1hberx\" }]\n];\nconst Gift = createLucideIcon(\"gift\", __iconNode);\n\nexport { __iconNode, Gift as default };\n//# sourceMappingURL=gift.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — ProductHubTray. */\n/* */\n/* Tray-level surface: an agent can open / close the dropdown panel and */\n/* read the unseen-release count. Release content (titles, summaries, */\n/* URLs) is never exposed — counts and booleans only. All actions are */\n/* routed through the curated imperative handle; the adapter never */\n/* touches the DOM directly. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ProductHubTrayHandle } from './product-hub-tray';\n\nexport const productHubTrayAgent: AgentAdapter<ProductHubTrayHandle> = {\n id: 'product-hub-tray',\n capabilities: ['open', 'close'],\n state: {\n unseenCount: {\n type: 'number',\n descriptionKey: 'ui.agent.productHubTray.state.unseenCount',\n description:\n 'Number of unseen product releases — the trigger badge count.',\n read: (handle) => handle.getUnseenCount(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.productHubTray.actions.open',\n description: 'Open the product-updates panel.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.productHubTray.actions.close',\n description: 'Close the product-updates panel.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'product-hub-tray',\n description: 'Marks the ProductHubTray 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-update-id',\n description:\n 'Stable release id emitted on each rendered release row inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\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 { Gift, X } from 'lucide-react';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { IconButton } from '../button/icon-button';\nimport { Link } from '../link';\nimport { ScrollArea } from '../scroll-area/scroll-area';\nimport { Separator } from '../separator/separator';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { Timestamp } from '../timestamp';\nimport { isSafeEntityUrl } from '../_shared/is-safe-url';\nimport { safeImageSrc } from '../_shared/safe-image-src';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { productHubTrayAgent } from './product-hub-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * One product-hub release entry. The kit is purely presentational —\n * the consumer fetches releases (Supabase, REST, …) and maps them into\n * this shape.\n */\nexport interface ProductHubItem {\n /** Unique identifier for the release. */\n id: string;\n /** Release title — rendered bold on the first line. */\n title: string;\n /** Short release summary — rendered as plain text, clamped to 2 lines. */\n summary?: string;\n /** ISO-8601 publish date — rendered as a localised, italic absolute date. */\n dateIso?: string;\n /**\n * Thumbnail URL. Guarded through the shared `safeImageSrc` allow-list\n * and rendered with `referrerPolicy=\"no-referrer\"`. Unsafe or missing\n * sources fall back to a Gift glyph tile.\n */\n imageUrl?: string;\n /**\n * Release deep link. Guarded through `isSafeEntityUrl`; safe URLs make\n * the row title an anchor that opens in a new tab. Unsafe URLs render\n * the title as plain text.\n */\n url?: string;\n /** Marks the release as not yet seen — highlights the row and counts toward the trigger badge. */\n unseen?: boolean;\n}\n\n/**\n * Curated imperative handle for ProductHubTray. Exposed to the agent\n * registry so a future MCP UI bridge can drive the tray without touching\n * the DOM. See `product-hub-tray.agent.ts`.\n */\nexport interface ProductHubTrayHandle {\n open: () => void;\n close: () => void;\n getUnseenCount: () => number;\n}\n\nexport interface ProductHubTrayProps\n extends\n Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onClick' | 'children' | 'role' | 'id'\n >,\n VariantProps<typeof productHubTrayVariants> {\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 /** Releases rendered in the dropdown panel, newest first. */\n items: ProductHubItem[];\n /**\n * Product-hub landing URL. When set (and safe) the panel renders a\n * pinned \"Open in Product Hub\" footer link that opens in a new tab.\n */\n hubUrl?: string;\n /** When true the panel shows skeleton placeholders. */\n loading?: boolean;\n /** Error-state slot — rendered inside the panel instead of the list. */\n error?: ReactNode;\n /**\n * Unseen-release count override. Defaults to the number of `items`\n * with `unseen: true`. Drives the trigger badge.\n */\n unseenCount?: number;\n /** Fires when the open state changes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * Analytics hook — fires when a row is activated. Navigation itself is\n * owned by the row anchor (new tab); this callback must not be relied\n * on for routing.\n */\n onItemActivate?: (item: ProductHubItem) => void;\n /** Override for the trigger's accessible label. */\n triggerLabel?: string;\n /** Number of releases rendered before the rest are cut off. Default 10. */\n maxVisible?: number;\n /** Empty-state slot — replaces the built-in \"No product updates yet\" panel. */\n emptyState?: ReactNode;\n /** Open the panel on first mount (uncontrolled). */\n defaultOpen?: boolean;\n /** BCP-47 locale override for the per-row dates. Falls back to `i18n.language`. */\n locale?: string;\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 productHubTrayVariants = cva(\n 'ds:relative ds:inline-flex ds:items-center',\n {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'md',\n },\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 // Fluid below the design cap so narrow viewports keep a gutter on\n // both sides of the panel (shadow included).\n 'ds:w-[min(24rem,calc(100vw-2*var(--spacing-md)))]',\n // Near-full-screen sheet below `sm`; auto above, where the list's\n // own `--product-hub-tray-max-block-size` 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 // Anchored to the top-end corner of the trigger, nudged outward so\n // the gift glyph isn't covered.\n 'ds:absolute ds:-top-[var(--spacing-xs)] ds:-end-[var(--spacing-xs)]',\n 'ds:inline-flex ds:items-center ds:justify-center',\n // Circle at 1-2 digits; widens into a pill only for \"99+\".\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 // One red unseen-count chip across every header tray — matches the\n // platform header and the NotificationTray badge convention.\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/* Shared release row — used by both ProductHubTray (compact) and */\n/* ProductHubPanel (roomier). Internal seam, not part of the barrel. */\n/* ------------------------------------------------------------------ */\n\nconst rowVariants = cva(\n [\n // `group` so the hover/focus-revealed close button can react to the whole\n // row, not just itself.\n 'ds:group ds:relative ds:flex ds:items-start',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-start',\n 'ds:transition-colors ds:motion-reduce:transition-none',\n ].join(' '),\n {\n variants: {\n density: {\n tray: 'ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]',\n panel: 'ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]',\n },\n // Unseen no longer tints the background — the read/new state is carried\n // by the leading-corner Gift indicator instead, matching the\n // notification / message cards.\n unseen: {\n true: 'ds:hover:bg-[color:var(--muted)]/40',\n false: 'ds:hover:bg-[color:var(--muted)]/40',\n },\n // Row chrome: flat (inside a bordered tray/panel) vs elevated (own card\n // on a rail). Mirrors AppointmentCard / NotificationCard so the Inbox\n // feed reads consistently with the other rail panels.\n surface: {\n flat: '',\n elevated:\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2 ds:shadow-[var(--shadow-sm)]',\n },\n },\n defaultVariants: {\n density: 'tray',\n unseen: false,\n surface: 'flat',\n },\n },\n);\n\nconst thumbVariants = cva(\n [\n 'ds:shrink-0 ds:rounded-[var(--radius-sm)] ds:object-cover',\n // Tile backdrop so transparent / still-loading thumbnails keep a\n // visible square instead of collapsing into whitespace.\n 'ds:bg-[color:var(--muted)]',\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n density: {\n tray: 'ds:size-10',\n panel: 'ds:size-12',\n },\n },\n defaultVariants: {\n density: 'tray',\n },\n },\n);\n\nconst stretchedLinkClass = [\n 'ds:focus-visible:outline-none',\n \"ds:after:content-[''] ds:after:absolute ds:after:inset-0 ds:after:rounded-[var(--radius-sm)]\",\n 'ds:after:pointer-events-auto',\n 'ds:focus-visible:after:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:after:outline-solid',\n 'ds:focus-visible:after:outline-[color:var(--ring)]',\n 'ds:focus-visible:after:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:after:outline-[CanvasText]',\n].join(' ');\n\nexport interface ProductHubUpdateRowProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'onClick' | 'role' | 'title'\n> {\n /** The release to render. */\n item: ProductHubItem;\n /** `tray` — compact dropdown row. `panel` — roomier dashboard row. */\n density?: 'tray' | 'panel';\n /**\n * Row chrome. `'flat'` (default) — chrome-less row inside a bordered\n * tray/panel. `'elevated'` — own card chrome (border + `--shadow-sm`) for\n * rail feeds (e.g. the Inbox), matching the sibling notification/message\n * cards.\n */\n surface?: 'flat' | 'elevated';\n /** BCP-47 locale override for the date. */\n locale?: string;\n /** Analytics hook — navigation is owned by the row anchor. */\n onActivate?: (item: ProductHubItem) => void;\n /**\n * When supplied, renders a close affordance (revealed on row hover / focus)\n * that fires with this item — e.g. dismissing the update from an Inbox feed.\n */\n onDismiss?: (item: ProductHubItem) => void;\n}\n\n/**\n * @internal Shared row between ProductHubTray and ProductHubPanel.\n * Exported for the sibling panel only — import the trays, not this.\n */\nexport function ProductHubUpdateRow({\n item,\n density = 'tray',\n surface = 'flat',\n locale,\n onActivate,\n onDismiss,\n className,\n ...rest\n}: ProductHubUpdateRowProps) {\n const { t } = useTranslation();\n const safeSrc = safeImageSrc(item.imageUrl);\n const hasSafeUrl = !!item.url && isSafeEntityUrl(item.url);\n const unseen = !!item.unseen;\n\n // Close insets track the row padding so it aligns with the title's first\n // line at either density.\n const closeInset =\n density === 'panel'\n ? 'ds:top-[var(--spacing-md)] ds:end-[var(--spacing-md)]'\n : 'ds:top-[var(--spacing-sm)] ds:end-[var(--spacing-sm)]';\n\n // Read after the title when the row gets focus / is traversed:\n // \"<title>, new, (opens in a new tab)\". The unseen dot itself is\n // decorative — state never relies on colour alone.\n const unseenHint = unseen ? (\n <span className=\"ds:sr-only\">\n {t('productHubTray.unseenLabel', ', new')}\n </span>\n ) : null;\n\n return (\n <div\n role=\"listitem\"\n data-component=\"product-hub-update\"\n data-update-id={item.id}\n data-unseen={unseen ? 'true' : 'false'}\n className={rowVariants({ density, unseen, surface, className })}\n {...rest}\n >\n <span className=\"ds:relative ds:shrink-0\">\n {safeSrc ? (\n <img\n src={safeSrc}\n alt=\"\"\n aria-hidden=\"true\"\n referrerPolicy=\"no-referrer\"\n loading=\"lazy\"\n className={thumbVariants({ density })}\n />\n ) : (\n <span\n aria-hidden=\"true\"\n className={`${thumbVariants({ density })} ds:inline-flex ds:items-center ds:justify-center ds:text-[color:var(--muted-foreground)] ds:[&>svg]:size-5`}\n >\n <Gift />\n </span>\n )}\n {/* Unseen \"new\" marker — a dot on the thumbnail corner (the read /\n unread indicator moved inline-start). Decorative; the title link\n carries the sr-only \"new\" hint for assistive tech. */}\n {unseen ? (\n <span\n aria-hidden=\"true\"\n data-testid=\"product-hub-unseen-dot\"\n className=\"ds:absolute ds:top-[calc(var(--spacing-xs)*-1)] ds:end-[calc(var(--spacing-xs)*-1)] ds:z-[1] ds:block ds:size-[calc(var(--spacing-sm)+var(--spacing-xs))] ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)] ds:ring-2 ds:ring-[color:var(--card)] ds:forced-colors:bg-[Highlight]\"\n />\n ) : null}\n </span>\n\n <div className=\"ds:min-w-0 ds:flex-1 ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] type-title-item ds:text-[color:var(--foreground)]\">\n {hasSafeUrl ? (\n // A real (non-display:contents) anchor so the row is reliably\n // keyboard-focusable; the ::after stretch keeps the whole row\n // clickable and carries the focus ring.\n <a\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`${stretchedLinkClass} ds:min-w-0 ds:flex-1 ds:no-underline ds:text-[color:var(--foreground)]`}\n onClick={() => onActivate?.(item)}\n >\n <span className=\"ds:block ds:truncate ds:font-semibold\">\n {item.title}\n </span>\n {unseenHint}\n <span className=\"ds:sr-only\">\n {t('productHubTray.opensInNewTab', '(opens in a new tab)')}\n </span>\n </a>\n ) : (\n <>\n <span className=\"ds:min-w-0 ds:flex-1 ds:truncate ds:font-semibold\">\n {item.title}\n </span>\n {unseenHint}\n </>\n )}\n </span>\n\n {item.summary ? (\n <p className=\"ds:m-0 type-body-sm ds:text-[color:var(--muted-foreground)] ds:[overflow:hidden] ds:[display:-webkit-box] ds:[-webkit-box-orient:vertical] ds:[-webkit-line-clamp:2] ds:break-words\">\n {item.summary}\n </p>\n ) : null}\n\n {item.dateIso ? (\n <Timestamp\n value={item.dateIso}\n format=\"absolute\"\n locale={locale}\n className=\"ds:italic ds:text-[color:var(--muted-foreground)]\"\n />\n ) : null}\n </div>\n\n {/* Close — inline-end, hover/focus-revealed. Absolutely positioned so it\n claims no width at rest: the title fills the row and there's no empty\n gap when the row isn't hovered. */}\n {onDismiss ? (\n <span\n className={\n 'ds:absolute ds:z-[2] ds:opacity-0 ds:pointer-events-none ds:transition-opacity ds:motion-reduce:transition-none ds:group-hover:opacity-100 ds:group-hover:pointer-events-auto ds:group-focus-within:opacity-100 ds:group-focus-within:pointer-events-auto ' +\n closeInset\n }\n >\n <IconButton\n icon={<X />}\n intent=\"ghost\"\n size=\"sm\"\n aria-label={t('productHubTray.dismiss', 'Dismiss update')}\n onClick={() => onDismiss(item)}\n />\n </span>\n ) : null}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Shared loading / status helpers (also consumed by ProductHubPanel) */\n/* ------------------------------------------------------------------ */\n\n/** @internal Skeleton placeholder mirroring the row layout. */\nexport function UpdateSkeletonRow({\n density = 'tray',\n}: {\n density?: 'tray' | 'panel';\n}) {\n return (\n <div\n aria-hidden=\"true\"\n className={\n density === 'panel'\n ? 'ds:flex ds:items-start ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]'\n : 'ds:flex ds:items-start ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]'\n }\n >\n <Skeleton\n variant=\"rounded\"\n width={density === 'panel' ? '3rem' : '2.5rem'}\n height={density === 'panel' ? '3rem' : '2.5rem'}\n />\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=\"90%\" />\n <Skeleton variant=\"text\" size=\"sm\" width=\"30%\" />\n </div>\n </div>\n );\n}\n\n/** @internal Centered status container for error / consumer-slot states. */\nexport function UpdateStatusPanel({ children }: { children: ReactNode }) {\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 type-body-sm ds:text-[color:var(--muted-foreground)]\"\n >\n {children}\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction formatBadgeCount(count: number, overflowLabel: string): string {\n return count > 99 ? overflowLabel : String(count);\n}\n\nfunction EmptyPanel() {\n const { t } = useTranslation();\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 <Gift />\n </span>\n <p className=\"type-title-item ds:text-[color:var(--foreground)]\">\n {t('productHubTray.emptyTitle', 'No product updates yet')}\n </p>\n <p className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {t(\n 'productHubTray.emptyDescription',\n 'New releases and improvements will appear here.',\n )}\n </p>\n </div>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport const ProductHubTray = forwardRef<HTMLDivElement, ProductHubTrayProps>(\n (\n {\n id,\n items,\n hubUrl,\n loading = false,\n error,\n unseenCount,\n onOpenChange,\n onItemActivate,\n triggerLabel,\n maxVisible = 10,\n emptyState,\n defaultOpen = false,\n locale,\n align = 'end',\n side = 'bottom',\n size = 'md',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const [isOpenRaw, handleOpenChange] = useControllableState<boolean>({\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n const isOpen = isOpenRaw ?? false;\n\n const displayCount = unseenCount ?? items.filter((i) => i.unseen).length;\n const resolvedTriggerLabel =\n triggerLabel ??\n (displayCount > 0\n ? t('productHubTray.triggerLabel', {\n count: displayCount,\n defaultValue: \"What's new, {{count}} unseen updates\",\n })\n : t('productHubTray.triggerLabelNone', \"What's new\"));\n\n const badgeLabel = formatBadgeCount(\n displayCount,\n t('productHubTray.badgeCountOverflow', '99+'),\n );\n\n const visible = items.slice(0, Math.max(0, maxVisible));\n const showList = !error && !loading && visible.length > 0;\n const safeHubUrl = hubUrl && isSafeEntityUrl(hubUrl) ? hubUrl : undefined;\n\n /* Curated handle — refs keep the look-ups current without\n * re-memoising on every items update. */\n const itemsRef = useRef<ProductHubItem[]>(items);\n itemsRef.current = items;\n const unseenRef = useRef<number | undefined>(unseenCount);\n unseenRef.current = unseenCount;\n\n const handle = useMemo<ProductHubTrayHandle>(\n () => ({\n open: () => handleOpenChange(true),\n close: () => handleOpenChange(false),\n getUnseenCount: () =>\n unseenRef.current ?? itemsRef.current.filter((i) => i.unseen).length,\n }),\n [handleOpenChange],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLDivElement, []);\n useAgentRegistration(productHubTrayAgent, handle, id);\n\n let body: ReactNode;\n if (error) {\n body = <UpdateStatusPanel>{error}</UpdateStatusPanel>;\n } else if (loading) {\n body = (\n <>\n <UpdateSkeletonRow />\n <UpdateSkeletonRow />\n <UpdateSkeletonRow />\n </>\n );\n } else if (visible.length === 0) {\n body = emptyState ?? <EmptyPanel />;\n } else {\n body = visible.map((item) => (\n <ProductHubUpdateRow\n key={item.id}\n item={item}\n density=\"tray\"\n locale={locale}\n onActivate={onItemActivate}\n />\n ));\n }\n\n return (\n <div\n ref={rootRef}\n data-component=\"product-hub-tray\"\n data-component-id={id}\n className={[productHubTrayVariants({ 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={<Gift />}\n intent=\"outline\"\n size={size === 'sm' ? 'sm' : 'md'}\n aria-label={resolvedTriggerLabel}\n aria-haspopup=\"dialog\"\n />\n </RadixPopover.Trigger>\n {displayCount > 0 ? (\n <span\n aria-hidden=\"true\"\n data-testid=\"product-hub-tray-badge\"\n className={badgeVariants()}\n >\n {badgeLabel}\n </span>\n ) : null}\n <RadixPopover.Portal>\n <RadixPopover.Content\n role=\"dialog\"\n aria-label={t('productHubTray.panelTitle', \"What's new\")}\n side={side}\n align={align}\n sideOffset={8}\n // Keeps Radix's collision-avoidance from flush-mounting the\n // panel against the viewport edge on narrow screens.\n collisionPadding={16}\n className={panelVariants({ size })}\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('productHubTray.panelTitle', \"What's new\")}\n </h3>\n </div>\n <Separator />\n {/* The release list is the ONLY scroll region. `role=\"list\"`\n requires `listitem` children, so it is applied only when\n rows render (axe aria-required-children). Consumers\n override the height cap via the\n `--product-hub-tray-max-block-size` custom property. */}\n <ScrollArea\n orientation=\"vertical\"\n className=\"ds:flex-1 ds:sm:flex-none ds:sm:[max-block-size:var(--product-hub-tray-max-block-size,24rem)]\"\n >\n <div\n role={showList ? '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 {body}\n </div>\n </ScrollArea>\n {safeHubUrl ? (\n <>\n <Separator />\n <div className=\"ds:flex ds:justify-center ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-xs)]\">\n <Link href={safeHubUrl} external>\n {t('productHubTray.openHub', 'Open in Product Hub')}\n </Link>\n </div>\n </>\n ) : null}\n </RadixPopover.Content>\n </RadixPopover.Portal>\n </RadixPopover.Root>\n </div>\n );\n },\n);\n\nProductHubTray.displayName = 'ProductHubTray';\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — ProductHubPanel. */\n/* */\n/* Read-mostly dashboard surface: an agent can read the displayed */\n/* release ids + unseen flags (never titles / summaries / URLs) and */\n/* route a per-item activation through the curated handle. The adapter */\n/* never touches the DOM directly. */\n/* */\n/* NOTE: catalog discovery only picks up `<dirName>.agent.ts`, so this */\n/* sibling adapter is registered at runtime but not yet listed in */\n/* dist/agent-catalog.json (same situation as appointment-tray inside */\n/* the appointment-card directory). */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ProductHubPanelHandle } from './product-hub-panel';\n\nexport const productHubPanelAgent: AgentAdapter<ProductHubPanelHandle> = {\n id: 'product-hub-panel',\n // selectItem activates one release row (fires the host hook) without\n // persisting a stored selection → `pick`, not `select_single`.\n capabilities: ['pick'],\n state: {\n items: {\n type: 'Array<{ id: string; unseen: boolean }>',\n descriptionKey: 'ui.agent.productHubPanel.state.items',\n description:\n 'Currently-displayed releases. Ids + unseen flag only — no content.',\n read: (handle) => handle.getItems(),\n },\n unseenCount: {\n type: 'number',\n descriptionKey: 'ui.agent.productHubPanel.state.unseenCount',\n description: 'Number of displayed releases still marked unseen.',\n read: (handle) => handle.getUnseenCount(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Stable release id (the data-update-id of the row).',\n },\n },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.productHubPanel.actions.selectItem',\n description:\n 'Activate the release with the given id (fires the host analytics hook).',\n examples: [\n { args: { id: 'rel-0680' }, note: 'Activate a specific release row.' },\n ],\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'product-hub-panel',\n description: 'Marks the ProductHubPanel section.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific panel from the agent.',\n },\n item: {\n attr: 'data-update-id',\n description:\n 'Stable release id emitted on each rendered release row inside the panel.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Gift } from 'lucide-react';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Link } from '../link';\nimport { Separator } from '../separator/separator';\nimport { isSafeEntityUrl } from '../_shared/is-safe-url';\nimport { useAgentRegistration } from '../../agent/registry';\nimport {\n ProductHubUpdateRow,\n UpdateSkeletonRow,\n UpdateStatusPanel,\n type ProductHubItem,\n} from './product-hub-tray';\nimport { productHubPanelAgent } from './product-hub-panel.agent';\n\n/* -------------------------------------------------------------------- */\n/* ProductHubPanel */\n/* */\n/* Dashboard-panel sibling of ProductHubTray: a titled, bordered card */\n/* (model: AgendaTray + the dashboard \"Recent notifications\" panel) */\n/* listing the same release rows at a roomier density — no popover. */\n/* The consumer fetches the data; loading / empty / error are props. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst productHubPanelVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:overflow-hidden',\n 'ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n surface: {\n flat: '',\n elevated: 'ds:shadow-[var(--shadow-card)]',\n },\n },\n defaultVariants: {\n surface: 'elevated',\n },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/**\n * Curated imperative handle for ProductHubPanel — read-only ids / counts\n * plus a select delegation. See `product-hub-panel.agent.ts`.\n */\nexport interface ProductHubPanelHandle {\n getItems: () => Array<{ id: string; unseen: boolean }>;\n getUnseenCount: () => number;\n selectItem: (id: string) => void;\n}\n\nexport interface ProductHubPanelProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'onClick' | 'children' | 'id'>,\n VariantProps<typeof productHubPanelVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific panel.\n */\n id?: string;\n /** Releases rendered in the panel, newest first. */\n items: ProductHubItem[];\n /**\n * Product-hub landing URL. When set (and safe) the panel renders an\n * \"Open in Product Hub\" footer link that opens in a new tab.\n */\n hubUrl?: string;\n /** When true the panel shows skeleton placeholders. */\n loading?: boolean;\n /** Error-state slot — rendered instead of the list. */\n error?: ReactNode;\n /** Panel heading. Defaults to the localised \"What's new\". */\n title?: string;\n /** Optional sub-heading rendered under the title. */\n description?: string;\n /** Number of releases rendered before the rest are cut off. Default 5. */\n maxVisible?: number;\n /** Empty-state slot — replaces the built-in EmptyState. */\n emptyState?: ReactNode;\n /**\n * Analytics hook — fires when a row is activated. Navigation itself is\n * owned by the row anchor (new tab).\n */\n onItemActivate?: (item: ProductHubItem) => void;\n /** BCP-47 locale override for the per-row dates. */\n locale?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const ProductHubPanel = forwardRef<HTMLElement, ProductHubPanelProps>(\n (\n {\n id,\n items,\n hubUrl,\n loading = false,\n error,\n title,\n description,\n maxVisible = 5,\n emptyState,\n onItemActivate,\n locale,\n surface = 'elevated',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const heading = title ?? t('productHubPanel.title', \"What's new\");\n\n const visible = items.slice(0, Math.max(0, maxVisible));\n const safeHubUrl = hubUrl && isSafeEntityUrl(hubUrl) ? hubUrl : undefined;\n\n let body: ReactNode;\n if (error) {\n body = <UpdateStatusPanel>{error}</UpdateStatusPanel>;\n } else if (loading) {\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:p-[var(--spacing-sm)] ds:pt-0\">\n {[0, 1, 2].map((i) => (\n <UpdateSkeletonRow key={i} density=\"panel\" />\n ))}\n </div>\n );\n } else if (visible.length === 0) {\n body = emptyState ?? (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t('productHubPanel.emptyTitle', 'No product updates yet')}\n description={t(\n 'productHubPanel.emptyDescription',\n 'New releases and improvements will appear here.',\n )}\n />\n </div>\n );\n } else {\n body = (\n <div\n role=\"list\"\n data-max-visible={maxVisible}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:p-[var(--spacing-sm)] ds:pt-0\"\n >\n {visible.map((item) => (\n <ProductHubUpdateRow\n key={item.id}\n item={item}\n density=\"panel\"\n locale={locale}\n onActivate={onItemActivate}\n />\n ))}\n </div>\n );\n }\n\n /* Curated imperative handle for agent integration. */\n const itemsRef = useRef<ProductHubItem[]>(items);\n itemsRef.current = items;\n\n const handle = useMemo<ProductHubPanelHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({ id: i.id, unseen: !!i.unseen })),\n getUnseenCount: () => itemsRef.current.filter((i) => i.unseen).length,\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onItemActivate?.(found);\n },\n }),\n [onItemActivate],\n );\n\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n useAgentRegistration(productHubPanelAgent, handle, id);\n\n return (\n <section\n ref={innerRef}\n aria-label={heading}\n data-component=\"product-hub-panel\"\n data-component-id={id}\n className={productHubPanelVariants({ surface, className })}\n {...rest}\n >\n <header className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-[var(--spacing-md)] ds:pb-[var(--spacing-sm)]\">\n {/* h2 — visual peer of the dashboard's other titled regions.\n Heading ladder: h1 (page) → h2 (this panel) → row titles. */}\n <h2 className=\"ds:m-0 ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-start type-title-section ds:text-[color:var(--foreground)]\">\n <Gift aria-hidden=\"true\" className=\"ds:size-5 ds:shrink-0\" />\n {heading}\n </h2>\n {description ? (\n <p className=\"ds:m-0 ds:text-start type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {description}\n </p>\n ) : null}\n </header>\n {body}\n {safeHubUrl ? (\n <>\n <Separator />\n <div className=\"ds:flex ds:justify-center ds:p-[var(--spacing-sm)]\">\n <Link href={safeHubUrl} external>\n {t('productHubPanel.openHub', 'Open in Product Hub')}\n </Link>\n </div>\n </>\n ) : null}\n </section>\n );\n },\n);\n\nProductHubPanel.displayName = 'ProductHubPanel';\n"],"names":["__iconNode","Gift","createLucideIcon","productHubTrayAgent","handle","productHubTrayVariants","cva","panelVariants","badgeVariants","rowVariants","thumbVariants","stretchedLinkClass","ProductHubUpdateRow","item","density","surface","locale","onActivate","onDismiss","className","rest","t","useTranslation","safeSrc","safeImageSrc","hasSafeUrl","isSafeEntityUrl","unseen","closeInset","unseenHint","jsx","jsxs","Fragment","Timestamp","IconButton","X","UpdateSkeletonRow","Skeleton","UpdateStatusPanel","children","formatBadgeCount","count","overflowLabel","EmptyPanel","ProductHubTray","forwardRef","id","items","hubUrl","loading","error","unseenCount","onOpenChange","onItemActivate","triggerLabel","maxVisible","emptyState","defaultOpen","align","side","size","ref","isOpenRaw","handleOpenChange","useControllableState","isOpen","displayCount","i","resolvedTriggerLabel","badgeLabel","visible","showList","safeHubUrl","itemsRef","useRef","unseenRef","useMemo","rootRef","useImperativeHandle","useAgentRegistration","body","RadixPopover","Separator","ScrollArea","Link","productHubPanelAgent","args","productHubPanelVariants","ProductHubPanel","title","description","heading","EmptyState","targetId","found","innerRef"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -3,8 +3,8 @@ import { forwardRef as h, useId as Z, useState as y, useCallback as D, useImpera
|
|
|
3
3
|
import { c as C } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as de } from "react-i18next";
|
|
5
5
|
import * as m from "@radix-ui/react-navigation-menu";
|
|
6
|
-
import { I as ae } from "./icon-button-
|
|
7
|
-
import { S as f } from "./sheet-
|
|
6
|
+
import { I as ae } from "./icon-button-DA2CAGHZ.js";
|
|
7
|
+
import { S as f } from "./sheet-BSznOyJs.js";
|
|
8
8
|
import { u as ne } from "./use-visual-viewport-pin-ChurOsHM.js";
|
|
9
9
|
import { C as R } from "./chevron-down-DWE7GSq9.js";
|
|
10
10
|
import { X as re } from "./x-B5YnXwCz.js";
|
|
@@ -600,4 +600,4 @@ export {
|
|
|
600
600
|
Le as P,
|
|
601
601
|
Pe as p
|
|
602
602
|
};
|
|
603
|
-
//# sourceMappingURL=public-header.agent-
|
|
603
|
+
//# sourceMappingURL=public-header.agent-kth2SdXn.js.map
|