@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text-editor-DGtn_4sb.js","sources":["../../node_modules/lucide-react/dist/esm/icons/baseline.mjs","../../node_modules/lucide-react/dist/esm/icons/between-horizontal-end.mjs","../../node_modules/lucide-react/dist/esm/icons/between-horizontal-start.mjs","../../node_modules/lucide-react/dist/esm/icons/between-vertical-end.mjs","../../node_modules/lucide-react/dist/esm/icons/between-vertical-start.mjs","../../node_modules/lucide-react/dist/esm/icons/bold.mjs","../../node_modules/lucide-react/dist/esm/icons/columns-2.mjs","../../node_modules/lucide-react/dist/esm/icons/heading-2.mjs","../../node_modules/lucide-react/dist/esm/icons/heading-3.mjs","../../node_modules/lucide-react/dist/esm/icons/italic.mjs","../../node_modules/lucide-react/dist/esm/icons/link.mjs","../../node_modules/lucide-react/dist/esm/icons/list-ordered.mjs","../../node_modules/lucide-react/dist/esm/icons/list.mjs","../../node_modules/lucide-react/dist/esm/icons/paint-bucket.mjs","../../node_modules/lucide-react/dist/esm/icons/paint-roller.mjs","../../node_modules/lucide-react/dist/esm/icons/palette.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-left.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-right.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-top-dashed.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-top.mjs","../../node_modules/lucide-react/dist/esm/icons/pilcrow.mjs","../../node_modules/lucide-react/dist/esm/icons/quote.mjs","../../node_modules/lucide-react/dist/esm/icons/rows-2.mjs","../../node_modules/lucide-react/dist/esm/icons/spell-check.mjs","../../node_modules/lucide-react/dist/esm/icons/strikethrough.mjs","../../node_modules/lucide-react/dist/esm/icons/table.mjs","../../node_modules/lucide-react/dist/esm/icons/text-align-center.mjs","../../node_modules/lucide-react/dist/esm/icons/text-align-end.mjs","../../node_modules/lucide-react/dist/esm/icons/text-align-start.mjs","../../node_modules/lucide-react/dist/esm/icons/underline.mjs","../../node_modules/lucide-react/dist/esm/icons/wand-sparkles.mjs","../../node_modules/lucide-react/dist/esm/icons/wrench.mjs","../../src/components/rich-text-editor/rich-text-editor.agent.ts","../../src/components/rich-text-editor/help-me-write-overlay.tsx","../../src/components/rich-text-editor/editor-toolbar.tsx","../../src/components/rich-text-editor/rich-text-editor.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: \"M4 20h16\", key: \"14thso\" }],\n [\"path\", { d: \"m6 16 6-12 6 12\", key: \"1b4byz\" }],\n [\"path\", { d: \"M8 12h8\", key: \"1wcyev\" }]\n];\nconst Baseline = createLucideIcon(\"baseline\", __iconNode);\n\nexport { __iconNode, Baseline as default };\n//# sourceMappingURL=baseline.mjs.map\n","/**\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 [\"rect\", { width: \"13\", height: \"7\", x: \"3\", y: \"3\", rx: \"1\", key: \"11xb64\" }],\n [\"path\", { d: \"m22 15-3-3 3-3\", key: \"26chmm\" }],\n [\"rect\", { width: \"13\", height: \"7\", x: \"3\", y: \"14\", rx: \"1\", key: \"k6ky7n\" }]\n];\nconst BetweenHorizontalEnd = createLucideIcon(\"between-horizontal-end\", __iconNode);\n\nexport { __iconNode, BetweenHorizontalEnd as default };\n//# sourceMappingURL=between-horizontal-end.mjs.map\n","/**\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 [\"rect\", { width: \"13\", height: \"7\", x: \"8\", y: \"3\", rx: \"1\", key: \"pkso9a\" }],\n [\"path\", { d: \"m2 9 3 3-3 3\", key: \"1agib5\" }],\n [\"rect\", { width: \"13\", height: \"7\", x: \"8\", y: \"14\", rx: \"1\", key: \"1q5fc1\" }]\n];\nconst BetweenHorizontalStart = createLucideIcon(\"between-horizontal-start\", __iconNode);\n\nexport { __iconNode, BetweenHorizontalStart as default };\n//# sourceMappingURL=between-horizontal-start.mjs.map\n","/**\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 [\"rect\", { width: \"7\", height: \"13\", x: \"3\", y: \"3\", rx: \"1\", key: \"1fdu0f\" }],\n [\"path\", { d: \"m9 22 3-3 3 3\", key: \"17z65a\" }],\n [\"rect\", { width: \"7\", height: \"13\", x: \"14\", y: \"3\", rx: \"1\", key: \"1squn4\" }]\n];\nconst BetweenVerticalEnd = createLucideIcon(\"between-vertical-end\", __iconNode);\n\nexport { __iconNode, BetweenVerticalEnd as default };\n//# sourceMappingURL=between-vertical-end.mjs.map\n","/**\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 [\"rect\", { width: \"7\", height: \"13\", x: \"3\", y: \"8\", rx: \"1\", key: \"1fjrkv\" }],\n [\"path\", { d: \"m15 2-3 3-3-3\", key: \"1uh6eb\" }],\n [\"rect\", { width: \"7\", height: \"13\", x: \"14\", y: \"8\", rx: \"1\", key: \"w3fjg8\" }]\n];\nconst BetweenVerticalStart = createLucideIcon(\"between-vertical-start\", __iconNode);\n\nexport { __iconNode, BetweenVerticalStart as default };\n//# sourceMappingURL=between-vertical-start.mjs.map\n","/**\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 [\n \"path\",\n { d: \"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\", key: \"mg9rjx\" }\n ]\n];\nconst Bold = createLucideIcon(\"bold\", __iconNode);\n\nexport { __iconNode, Bold as default };\n//# sourceMappingURL=bold.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }]\n];\nconst Columns2 = createLucideIcon(\"columns-2\", __iconNode);\n\nexport { __iconNode, Columns2 as default };\n//# sourceMappingURL=columns-2.mjs.map\n","/**\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: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1\", key: \"9jr5yi\" }]\n];\nconst Heading2 = createLucideIcon(\"heading-2\", __iconNode);\n\nexport { __iconNode, Heading2 as default };\n//# sourceMappingURL=heading-2.mjs.map\n","/**\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: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2\", key: \"68ncm8\" }],\n [\"path\", { d: \"M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2\", key: \"1ejuhz\" }]\n];\nconst Heading3 = createLucideIcon(\"heading-3\", __iconNode);\n\nexport { __iconNode, Heading3 as default };\n//# sourceMappingURL=heading-3.mjs.map\n","/**\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 [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n];\nconst Italic = createLucideIcon(\"italic\", __iconNode);\n\nexport { __iconNode, Italic as default };\n//# sourceMappingURL=italic.mjs.map\n","/**\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: \"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\", key: \"1cjeqo\" }],\n [\"path\", { d: \"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\", key: \"19qd67\" }]\n];\nconst Link = createLucideIcon(\"link\", __iconNode);\n\nexport { __iconNode, Link as default };\n//# sourceMappingURL=link.mjs.map\n","/**\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: \"M11 5h10\", key: \"1cz7ny\" }],\n [\"path\", { d: \"M11 12h10\", key: \"1438ji\" }],\n [\"path\", { d: \"M11 19h10\", key: \"11t30w\" }],\n [\"path\", { d: \"M4 4h1v5\", key: \"10yrso\" }],\n [\"path\", { d: \"M4 9h2\", key: \"r1h2o0\" }],\n [\"path\", { d: \"M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02\", key: \"xtkcd5\" }]\n];\nconst ListOrdered = createLucideIcon(\"list-ordered\", __iconNode);\n\nexport { __iconNode, ListOrdered as default };\n//# sourceMappingURL=list-ordered.mjs.map\n","/**\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: \"M3 5h.01\", key: \"18ugdj\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M3 19h.01\", key: \"noohij\" }],\n [\"path\", { d: \"M8 5h13\", key: \"1pao27\" }],\n [\"path\", { d: \"M8 12h13\", key: \"1za7za\" }],\n [\"path\", { d: \"M8 19h13\", key: \"m83p4d\" }]\n];\nconst List = createLucideIcon(\"list\", __iconNode);\n\nexport { __iconNode, List as default };\n//# sourceMappingURL=list.mjs.map\n","/**\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: \"M11 7 6 2\", key: \"1jwth8\" }],\n [\"path\", { d: \"M18.992 12H2.041\", key: \"xw1gg\" }],\n [\n \"path\",\n {\n d: \"M21.145 18.38A3.34 3.34 0 0 1 20 16.5a3.3 3.3 0 0 1-1.145 1.88c-.575.46-.855 1.02-.855 1.595A2 2 0 0 0 20 22a2 2 0 0 0 2-2.025c0-.58-.285-1.13-.855-1.595\",\n key: \"1nkol4\"\n }\n ],\n [\n \"path\",\n {\n d: \"m8.5 4.5 2.148-2.148a1.205 1.205 0 0 1 1.704 0l7.296 7.296a1.205 1.205 0 0 1 0 1.704l-7.592 7.592a3.615 3.615 0 0 1-5.112 0l-3.888-3.888a3.615 3.615 0 0 1 0-5.112L5.67 7.33\",\n key: \"1nk1rd\"\n }\n ]\n];\nconst PaintBucket = createLucideIcon(\"paint-bucket\", __iconNode);\n\nexport { __iconNode, PaintBucket as default };\n//# sourceMappingURL=paint-bucket.mjs.map\n","/**\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 [\"rect\", { width: \"16\", height: \"6\", x: \"2\", y: \"2\", rx: \"2\", key: \"jcyz7m\" }],\n [\"path\", { d: \"M10 16v-2a2 2 0 0 1 2-2h8a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2\", key: \"1b9h7c\" }],\n [\"rect\", { width: \"4\", height: \"6\", x: \"8\", y: \"16\", rx: \"1\", key: \"d6e7yl\" }]\n];\nconst PaintRoller = createLucideIcon(\"paint-roller\", __iconNode);\n\nexport { __iconNode, PaintRoller as default };\n//# sourceMappingURL=paint-roller.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z\",\n key: \"e79jfc\"\n }\n ],\n [\"circle\", { cx: \"13.5\", cy: \"6.5\", r: \".5\", fill: \"currentColor\", key: \"1okk4w\" }],\n [\"circle\", { cx: \"17.5\", cy: \"10.5\", r: \".5\", fill: \"currentColor\", key: \"f64h9f\" }],\n [\"circle\", { cx: \"6.5\", cy: \"12.5\", r: \".5\", fill: \"currentColor\", key: \"qy21gx\" }],\n [\"circle\", { cx: \"8.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"fotxhn\" }]\n];\nconst Palette = createLucideIcon(\"palette\", __iconNode);\n\nexport { __iconNode, Palette as default };\n//# sourceMappingURL=palette.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }]\n];\nconst PanelLeft = createLucideIcon(\"panel-left\", __iconNode);\n\nexport { __iconNode, PanelLeft as default };\n//# sourceMappingURL=panel-left.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M15 3v18\", key: \"14nvp0\" }]\n];\nconst PanelRight = createLucideIcon(\"panel-right\", __iconNode);\n\nexport { __iconNode, PanelRight as default };\n//# sourceMappingURL=panel-right.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M14 9h1\", key: \"l0svgy\" }],\n [\"path\", { d: \"M19 9h2\", key: \"te2zfg\" }],\n [\"path\", { d: \"M3 9h2\", key: \"1h4ldw\" }],\n [\"path\", { d: \"M9 9h1\", key: \"15jzuz\" }]\n];\nconst PanelTopDashed = createLucideIcon(\"panel-top-dashed\", __iconNode);\n\nexport { __iconNode, PanelTopDashed as default };\n//# sourceMappingURL=panel-top-dashed.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }]\n];\nconst PanelTop = createLucideIcon(\"panel-top\", __iconNode);\n\nexport { __iconNode, PanelTop as default };\n//# sourceMappingURL=panel-top.mjs.map\n","/**\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: \"M13 4v16\", key: \"8vvj80\" }],\n [\"path\", { d: \"M17 4v16\", key: \"7dpous\" }],\n [\"path\", { d: \"M19 4H9.5a4.5 4.5 0 0 0 0 9H13\", key: \"sh4n9v\" }]\n];\nconst Pilcrow = createLucideIcon(\"pilcrow\", __iconNode);\n\nexport { __iconNode, Pilcrow as default };\n//# sourceMappingURL=pilcrow.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\",\n key: \"rib7q0\"\n }\n ],\n [\n \"path\",\n {\n d: \"M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\",\n key: \"1ymkrd\"\n }\n ]\n];\nconst Quote = createLucideIcon(\"quote\", __iconNode);\n\nexport { __iconNode, Quote as default };\n//# sourceMappingURL=quote.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }]\n];\nconst Rows2 = createLucideIcon(\"rows-2\", __iconNode);\n\nexport { __iconNode, Rows2 as default };\n//# sourceMappingURL=rows-2.mjs.map\n","/**\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: \"m6 16 6-12 6 12\", key: \"1b4byz\" }],\n [\"path\", { d: \"M8 12h8\", key: \"1wcyev\" }],\n [\"path\", { d: \"m16 20 2 2 4-4\", key: \"13tcca\" }]\n];\nconst SpellCheck = createLucideIcon(\"spell-check\", __iconNode);\n\nexport { __iconNode, SpellCheck as default };\n//# sourceMappingURL=spell-check.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 4H9a3 3 0 0 0-2.83 4\", key: \"43sutm\" }],\n [\"path\", { d: \"M14 12a4 4 0 0 1 0 8H6\", key: \"nlfj13\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"12\", y2: \"12\", key: \"1e0a9i\" }]\n];\nconst Strikethrough = createLucideIcon(\"strikethrough\", __iconNode);\n\nexport { __iconNode, Strikethrough as default };\n//# sourceMappingURL=strikethrough.mjs.map\n","/**\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 3v18\", key: \"108xh3\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }]\n];\nconst Table = createLucideIcon(\"table\", __iconNode);\n\nexport { __iconNode, Table as default };\n//# sourceMappingURL=table.mjs.map\n","/**\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: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }],\n [\"path\", { d: \"M19 19H5\", key: \"vjpgq2\" }]\n];\nconst TextAlignCenter = createLucideIcon(\"text-align-center\", __iconNode);\n\nexport { __iconNode, TextAlignCenter as default };\n//# sourceMappingURL=text-align-center.mjs.map\n","/**\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: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M21 19H7\", key: \"4cu937\" }]\n];\nconst TextAlignEnd = createLucideIcon(\"text-align-end\", __iconNode);\n\nexport { __iconNode, TextAlignEnd as default };\n//# sourceMappingURL=text-align-end.mjs.map\n","/**\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: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M17 19H3\", key: \"z6ezky\" }]\n];\nconst TextAlignStart = createLucideIcon(\"text-align-start\", __iconNode);\n\nexport { __iconNode, TextAlignStart as default };\n//# sourceMappingURL=text-align-start.mjs.map\n","/**\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: \"M6 4v6a6 6 0 0 0 12 0V4\", key: \"9kb039\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"20\", y2: \"20\", key: \"nun2al\" }]\n];\nconst Underline = createLucideIcon(\"underline\", __iconNode);\n\nexport { __iconNode, Underline as default };\n//# sourceMappingURL=underline.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n];\nconst WandSparkles = createLucideIcon(\"wand-sparkles\", __iconNode);\n\nexport { __iconNode, WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\",\n key: \"1ngwbx\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.mjs.map\n","import type { AgentAdapter } from '../../agent/types';\nimport type { EditorFormat, RichTextEditorHandle } from './rich-text-editor';\n\nexport const richTextEditorAgent: AgentAdapter<RichTextEditorHandle> = {\n id: 'rich-text-editor',\n capabilities: ['edit_inline'],\n state: {\n html: {\n type: 'string',\n descriptionKey: 'ui.agent.richTextEditor.state.html',\n description: 'Sanitised HTML representation of the editor content.',\n read: (handle) => handle.getHTML(),\n },\n text: {\n type: 'string',\n descriptionKey: 'ui.agent.richTextEditor.state.text',\n description: 'Plain-text content of the editor (tags stripped).',\n read: (handle) => handle.getText(),\n },\n markdown: {\n type: 'string',\n descriptionKey: 'ui.agent.richTextEditor.state.markdown',\n description:\n 'Markdown representation of the editor content. The Redactor engine has no native Markdown serialiser, so this is always empty — read `html` instead.',\n read: (handle) => handle.getMarkdown(),\n },\n },\n // Image wrap/align/resize are intentionally NOT agent actions — they target\n // the ephemeral click-selected image the handle can't address. Agents emit\n // `<img class=\"wysiwyg-img-*\" style=\"width:N%\">` via set_content instead.\n actions: {\n set_content: {\n // Replaces the whole document — discards whatever the user had typed.\n safety: 'destructive',\n argsType: '{ html: string }',\n argsSchema: {\n type: 'object',\n properties: {\n html: {\n type: 'string',\n description: 'Replacement HTML (sanitised via DOMPurify).',\n },\n },\n required: ['html'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.richTextEditor.actions.setContent',\n description: 'Replace the editor content. Loses unsaved input.',\n invoke: (handle, args: { html: string }) => {\n handle.setContent(args.html);\n },\n },\n insert_at_cursor: {\n // Reversible via the editor's own undo stack — write, not destructive.\n safety: 'write',\n argsType: '{ content: string; asHtml?: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'Content to insert at the caret.',\n },\n asHtml: {\n type: 'boolean',\n description:\n 'Treat content as HTML (sanitised). Pass false for plain text. Defaults to true.',\n },\n },\n required: ['content'],\n },\n descriptionKey: 'ui.agent.richTextEditor.actions.insertAtCursor',\n description:\n 'Insert content at the caret (replacing any selection). HTML is sanitised; pass asHtml:false for plain text. Seam for merge/template variables and AI-generated drafts.',\n examples: [\n {\n args: { content: '{{patient.firstName}}', asHtml: false },\n note: 'Insert a merge variable as plain text.',\n },\n ],\n invoke: (handle, args: { content: string; asHtml?: boolean }) => {\n handle.insertAtCursor(args.content, { asHtml: args.asHtml });\n },\n },\n apply_format: {\n // Reversible via undo — write, not destructive.\n safety: 'write',\n argsType:\n \"{ format: 'bold' | 'italic' | 'strikethrough' | 'bulletedList' | 'numberedList' | 'heading' | 'quote' | 'paragraph' }\",\n argsSchema: {\n type: 'object',\n properties: {\n format: {\n type: 'string',\n enum: [\n 'bold',\n 'italic',\n 'strikethrough',\n 'bulletedList',\n 'numberedList',\n 'heading',\n 'quote',\n 'paragraph',\n ],\n description: 'Block or inline format to toggle/apply.',\n },\n },\n required: ['format'],\n },\n descriptionKey: 'ui.agent.richTextEditor.actions.applyFormat',\n description:\n 'Toggle/apply a block or inline format on the current selection (bold, italic, strikethrough, bulleted/numbered list, heading, quote, paragraph).',\n examples: [{ args: { format: 'bold' }, note: 'Bold the selection.' }],\n invoke: (handle, args: { format: EditorFormat }) => {\n handle.applyFormat(args.format);\n },\n },\n clear: {\n // Empties the document — loses unsaved input.\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.richTextEditor.actions.clear',\n description: 'Empty the editor. Loses unsaved input.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n focus: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.richTextEditor.actions.focus',\n description: 'Move keyboard focus to the editor surface.',\n invoke: (handle) => {\n handle.focus();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'rich-text-editor' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* HelpMeWriteOverlay — the \"Help me write\" flow on the non-modal */\n/* EditorOverlay (Gemini / Mac Mail style): a slim docked bar with a */\n/* one-row composer (mic · prompt · Write) → a preview of the draft with */\n/* Discard / Try again / Insert. */\n/* */\n/* The kit owns the UI; the backend call is the consumer's */\n/* `onRequestAiDraft({ prompt, signal })`. When `onDictate` is supplied */\n/* the composer grows a mic that streams transcripts INTO the prompt */\n/* (the same consumer dictation seam the editor FAB uses). The returned */\n/* draft is previewed (sanitised via SafeHtml) and only inserted on */\n/* confirm — sanitisation of the inserted value happens again at the */\n/* editor seam. */\n/* ------------------------------------------------------------------ */\n\nimport {\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Check, Mic, RotateCcw, Send, Square, X } from 'lucide-react';\n\nimport { IconButton } from '../button';\nimport { Spinner } from '../spinner';\nimport { TextArea } from '../text-area';\nimport { SafeHtml } from '../_shared/safe-html';\nimport { EditorOverlay } from '../editor-overlay';\n\nexport interface HelpMeWriteOverlayProps {\n open: boolean;\n onClose: () => void;\n onRequestAiDraft: (ctx: {\n prompt: string;\n signal: AbortSignal;\n }) => Promise<string>;\n onInsert: (draft: string) => void;\n /** Preview + insert the draft as HTML (default) or plain text. */\n previewAsHtml?: boolean;\n privacyNotice?: ReactNode;\n /**\n * Voice dictation into the prompt. Same seam as the editor's `onDictate`:\n * the consumer runs mic + transcription and pushes text back; the kit appends\n * finals to the prompt. When omitted, the composer shows no mic.\n */\n onDictate?: (ctx: {\n signal: AbortSignal;\n onPartialTranscript: (text: string) => void;\n onFinalTranscript: (text: string) => void;\n }) => Promise<void>;\n}\n\n// Force the recording mic solid-destructive (red). IconButton's base\n// `aria-pressed:bg-muted` (for IconButtonGroup toggles) would otherwise\n// out-specify the intent fill, so the override is marked important.\nconst RECORDING_MIC =\n 'ds:aria-pressed:!bg-[var(--destructive)] ds:aria-pressed:!text-[var(--destructive-foreground)]';\n\n// Pin the action buttons to the input's height (--min-target-size, 44/48px) so\n// the composer's input + mic + send line up exactly. IconButton md is h-10\n// (40px), below the TextArea md min-height, so force the match (important wins\n// over the size variant). Scales with the accessible theme for free.\nconst ACTION_SIZE = 'ds:!size-[var(--min-target-size)]';\n\nconst noticeClass =\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--muted-foreground)]';\nconst errorClass =\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--destructive)]';\nconst previewClass = [\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[color-mix(in_srgb,var(--background)_70%,transparent)]',\n 'ds:p-[var(--spacing-sm)] ds:[max-block-size:10rem] ds:overflow-y-auto',\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)]',\n // The preview renders arbitrary model-generated rich text, and the\n // `rich-text` SafeHtml profile allows ul/ol/li. Inside a\n // [data-component] preflight's list reset still applies and the host\n // undo deliberately does not reach, so markers and indent have to be\n // asked for explicitly — otherwise a generated bullet list previews as\n // flush, marker-less lines.\n 'ds:[&_ul]:list-disc ds:[&_ol]:list-decimal',\n 'ds:[&_ul]:ps-[var(--spacing-md)] ds:[&_ol]:ps-[var(--spacing-md)]',\n].join(' ');\n\n// Join a base string with appended dictation text, inserting a single space\n// only when the base doesn't already end in whitespace.\nfunction joinWith(base: string, extra: string): string {\n if (!extra) return base;\n if (!base) return extra;\n return /\\s$/.test(base) ? `${base}${extra}` : `${base} ${extra}`;\n}\n\nexport function HelpMeWriteOverlay({\n open,\n onClose,\n onRequestAiDraft,\n onInsert,\n previewAsHtml = true,\n privacyNotice,\n onDictate,\n}: HelpMeWriteOverlayProps): React.JSX.Element {\n const { t } = useTranslation();\n const promptId = useId();\n const errorId = useId();\n const [prompt, setPrompt] = useState('');\n const [loading, setLoading] = useState(false);\n const [errored, setErrored] = useState(false);\n const [draft, setDraft] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n /* ---- In-prompt voice dictation (consumer runs mic + STT) ---- */\n const [isDictating, setIsDictating] = useState(false);\n const [interim, setInterim] = useState('');\n // Drives the visually-hidden live region: announces the listening status on\n // start and each committed phrase as it lands. The interim text shows in the\n // read-only field, but SR users can't perceive a read-only value change, so\n // the polite region gives them the same feedback.\n const [dictationAnnouncement, setDictationAnnouncement] = useState('');\n const dictateAbortRef = useRef<AbortController | null>(null);\n\n const stopDictation = useCallback(() => {\n dictateAbortRef.current?.abort();\n }, []);\n\n const startDictation = useCallback(() => {\n if (!onDictate) return;\n const controller = new AbortController();\n dictateAbortRef.current = controller;\n setIsDictating(true);\n setInterim('');\n setDictationAnnouncement(t('editor.ai.listening'));\n onDictate({\n signal: controller.signal,\n onPartialTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n setInterim(text);\n },\n onFinalTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n const trimmed = text.trim();\n setInterim('');\n if (trimmed) {\n setPrompt((p) => joinWith(p, trimmed));\n setDictationAnnouncement(trimmed);\n }\n },\n })\n .catch(() => {\n /* dictation errors are non-fatal here — the user can type instead */\n })\n .finally(() => {\n setInterim('');\n if (dictateAbortRef.current === controller) {\n dictateAbortRef.current = null;\n setIsDictating(false);\n setDictationAnnouncement('');\n }\n });\n }, [onDictate, t]);\n\n const toggleDictation = useCallback(() => {\n if (isDictating) stopDictation();\n else startDictation();\n }, [isDictating, startDictation, stopDictation]);\n\n // Fresh state each time it opens; abort any in-flight request/dictation on close.\n useEffect(() => {\n if (open) {\n setPrompt('');\n setLoading(false);\n setErrored(false);\n setDraft(null);\n setInterim('');\n setDictationAnnouncement('');\n } else {\n abortRef.current?.abort();\n abortRef.current = null;\n dictateAbortRef.current?.abort();\n }\n }, [open]);\n useEffect(\n () => () => {\n abortRef.current?.abort();\n dictateAbortRef.current?.abort();\n },\n [],\n );\n\n const generate = useCallback(() => {\n const trimmed = prompt.trim();\n if (!trimmed || loading) return;\n stopDictation();\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n setErrored(false);\n setLoading(true);\n onRequestAiDraft({ prompt: trimmed, signal: controller.signal })\n .then((result) => {\n if (controller.signal.aborted) return;\n setDraft(result);\n setLoading(false);\n })\n .catch((err: unknown) => {\n if (\n controller.signal.aborted ||\n (err &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name?: string }).name === 'AbortError')\n ) {\n return;\n }\n setErrored(true);\n setLoading(false);\n });\n }, [prompt, loading, onRequestAiDraft, stopDictation]);\n\n const insert = useCallback(() => {\n if (draft == null) return;\n onInsert(draft);\n onClose();\n }, [draft, onInsert, onClose]);\n\n const hasDraft = draft != null;\n // While dictating, show committed prompt + live interim; the field is\n // read-only so the streamed text isn't fought over by onChange.\n const fieldValue = isDictating ? joinWith(prompt, interim) : prompt;\n\n return (\n <EditorOverlay\n open={open}\n onClose={onClose}\n ariaLabel={t('editor.ai.dialogTitle')}\n >\n {hasDraft ? (\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-sm)]\">\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={ACTION_SIZE}\n icon={<X />}\n aria-label={t('common.close')}\n onClick={onClose}\n />\n <div className=\"ds:min-w-0 ds:flex-1\">\n {previewAsHtml ? (\n <SafeHtml\n html={draft as string}\n profile=\"rich-text\"\n className={previewClass}\n tabIndex={0}\n aria-label={t('editor.ai.dialogTitle')}\n />\n ) : (\n // Focusable so a keyboard user can scroll a long draft preview\n // (mirrors the SafeHtml preview branch above). The lint rule's\n // tabIndex allowlist doesn't cover a scrollable, non-interactive\n // text region.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n <p className={previewClass} tabIndex={0}>\n {draft}\n </p>\n )}\n </div>\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={`${ACTION_SIZE} ds:rounded-full`}\n icon={<RotateCcw />}\n aria-label={t('editor.ai.retry')}\n onClick={() => setDraft(null)}\n />\n <IconButton\n size=\"md\"\n intent=\"primary\"\n className={`${ACTION_SIZE} ds:bg-[image:var(--gradient-brand)] ds:rounded-full`}\n icon={<Check />}\n aria-label={t('common.confirm')}\n onClick={insert}\n />\n </div>\n ) : (\n <>\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-sm)]\">\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={ACTION_SIZE}\n icon={<X />}\n aria-label={t('common.close')}\n onClick={onClose}\n />\n <div className=\"ds:min-w-0 ds:flex-1\">\n <TextArea\n id={promptId}\n size=\"md\"\n // Centre a single line within the min-height; when it grows to\n // multiple rows autoResize removes the slack so text fills from\n // the top as usual.\n className=\"ds:content-center\"\n value={fieldValue}\n onChange={(event) => setPrompt(event.target.value)}\n placeholder={t('editor.ai.promptPlaceholder')}\n aria-label={t('editor.ai.promptLabel')}\n autoResize\n minRows={1}\n maxRows={3}\n readOnly={isDictating}\n tone={errored ? 'error' : 'default'}\n aria-describedby={errored ? errorId : undefined}\n />\n </div>\n {onDictate ? (\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={\n isDictating ? `${ACTION_SIZE} ${RECORDING_MIC}` : ACTION_SIZE\n }\n icon={\n isDictating ? <Square className=\"ds:fill-current\" /> : <Mic />\n }\n aria-pressed={isDictating}\n aria-label={\n isDictating\n ? t('editor.ai.dictateStop')\n : t('editor.ai.dictateStart')\n }\n onClick={toggleDictation}\n />\n ) : null}\n <IconButton\n size=\"md\"\n intent=\"primary\"\n icon={loading ? <Spinner size=\"sm\" variant=\"pulse\" /> : <Send />}\n className={`${ACTION_SIZE} ds:bg-[image:var(--gradient-brand)] ds:rounded-full`}\n disabled={loading || !prompt.trim()}\n aria-busy={loading || undefined}\n aria-label={t('editor.ai.generate')}\n onClick={generate}\n />\n </div>\n {onDictate ? (\n <p className=\"ds:sr-only\" role=\"status\" aria-live=\"polite\">\n {dictationAnnouncement}\n </p>\n ) : null}\n {errored ? (\n <p id={errorId} role=\"alert\" className={errorClass}>\n {t('editor.ai.error')}\n </p>\n ) : privacyNotice ? (\n <p className={noticeClass}>{privacyNotice}</p>\n ) : null}\n </>\n )}\n </EditorOverlay>\n );\n}\n","/* ------------------------------------------------------------------ */\n/* EditorToolbar — the kit's OWN toolbar for RichTextEditor. */\n/* */\n/* Redactor renders with `toolbar: false` (no native toolbar); this DS */\n/* toolbar drives the editor through Redactor's command API via `run` */\n/* and, for surfaces that would otherwise use Redactor's own modals */\n/* (link, image), through DS Dialogs + the `insertHtml` seam so EVERY */\n/* interactive surface is a kit component. Colour uses the DS */\n/* ColorPicker; the style menu is a labelled menu button; table offers */\n/* a size-grid insert + contextual row/column/header ops. */\n/* ------------------------------------------------------------------ */\n\nimport {\n Fragment,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Baseline,\n BetweenHorizontalEnd,\n BetweenHorizontalStart,\n BetweenVerticalEnd,\n BetweenVerticalStart,\n Bold,\n ChevronDown,\n Columns2,\n Heading2,\n Heading3,\n Highlighter,\n Image as ImageIcon,\n Italic,\n Link as LinkIcon,\n List,\n ListOrdered,\n Ellipsis,\n PaintBucket,\n PaintRoller,\n PanelLeft,\n PanelRight,\n PanelTop,\n PanelTopDashed,\n Palette,\n Pilcrow,\n Quote,\n Rows2,\n Strikethrough,\n Table as TableIcon,\n TextAlignCenter,\n TextAlignEnd,\n TextAlignStart,\n Trash2,\n Underline,\n Wrench,\n} from 'lucide-react';\nimport { cva } from 'class-variance-authority';\n\nimport { Button, IconButton } from '../button';\nimport { TooltipProvider } from '../tooltip';\nimport { Popover } from '../popover';\nimport { DropdownMenu } from '../dropdown-menu';\nimport { Dialog } from '../dialog';\nimport { ColorPicker } from '../color-picker';\nimport { TextInput } from '../text-input';\nimport { Checkbox } from '../checkbox';\nimport { FileUpload } from '../file-upload';\n\nexport type EditorToolbarPreset = 'minimal' | 'standard' | 'full';\n\nexport interface EditorToolbarProps {\n /** Dispatch a Redactor command (and refresh active state). */\n run: (command: string, ...args: unknown[]) => void;\n /** Active formats at the caret — toggle buttons render pressed. */\n active: ReadonlySet<string>;\n preset: EditorToolbarPreset;\n /** Insert sanitised HTML at the caret (link / image / table). */\n insertHtml: (html: string) => void;\n /** Insert a table — list-aware (drops it after a list, never inside an <li>). */\n insertTable: (html: string) => void;\n /** Save the editor selection before a DS popover/dialog takes focus. */\n saveSelection: () => void;\n /** Restore the saved selection before applying. */\n restoreSelection: () => void;\n /** Current selected text — prefills the link dialog's text field. */\n getSelectedText: () => string;\n /** Upload an image file and resolve its URL (image dialog's upload area). */\n uploadImage?: (file: File, signal?: AbortSignal) => Promise<string>;\n /** Show the text-colour control. */\n enableColor?: boolean;\n /** Show the image control (consumer set an image-upload URL). */\n enableImage?: boolean;\n /** Show the table control (consumer loaded the table plugin). */\n enableTable?: boolean;\n /**\n * Show an \"Editor extensions\" tools affordance (marketplace tools), placed\n * inline at the end of the toolbar. Currently a visual placeholder — not\n * wired to a menu.\n */\n showExtensions?: boolean;\n}\n\n/** i18n key + English fallback (for keys not yet in every locale). */\ntype L = [string, string];\n\ninterface ToolbarItem {\n id: string;\n icon: ReactNode;\n label: L;\n command: [string, ...unknown[]];\n /** When set, the button is a toggle and presses when `active` has this key. */\n toggle?: string;\n}\n\nconst ITEMS: Record<string, ToolbarItem> = {\n bold: {\n id: 'bold',\n icon: <Bold />,\n label: ['editor.bold', 'Bold'],\n command: ['module.inline.format', { tag: 'b' }],\n toggle: 'bold',\n },\n italic: {\n id: 'italic',\n icon: <Italic />,\n label: ['editor.italic', 'Italic'],\n command: ['module.inline.format', { tag: 'i' }],\n toggle: 'italic',\n },\n underline: {\n id: 'underline',\n icon: <Underline />,\n label: ['editor.underline', 'Underline'],\n command: ['module.inline.format', { tag: 'u' }],\n toggle: 'underline',\n },\n strike: {\n id: 'strike',\n icon: <Strikethrough />,\n label: ['editor.strike', 'Strikethrough'],\n command: ['module.inline.format', { tag: 'del' }],\n toggle: 'strike',\n },\n ul: {\n id: 'ul',\n icon: <List />,\n label: ['editor.list.bullet', 'Bulleted list'],\n command: ['module.list.toggle', 'ul'],\n toggle: 'ul',\n },\n ol: {\n id: 'ol',\n icon: <ListOrdered />,\n label: ['editor.list.ordered', 'Numbered list'],\n command: ['module.list.toggle', 'ol'],\n toggle: 'ol',\n },\n};\n\n// Block-format options. `id` matches the active token emitted by the editor\n// (paragraph / h2 / h3 / quote) so the labelled button shows the active style.\nconst FORMAT_OPTIONS: { id: string; tag: string; icon: ReactNode; label: L }[] =\n [\n {\n id: 'paragraph',\n tag: 'p',\n icon: <Pilcrow />,\n label: ['editor.paragraph', 'Paragraph'],\n },\n {\n id: 'h2',\n tag: 'h2',\n icon: <Heading2 />,\n label: ['editor.heading2', 'Heading 2'],\n },\n {\n id: 'h3',\n tag: 'h3',\n icon: <Heading3 />,\n label: ['editor.heading3', 'Heading 3'],\n },\n {\n id: 'quote',\n tag: 'blockquote',\n icon: <Quote />,\n label: ['editor.quote', 'Quote'],\n },\n ];\n\nconst PRESETS: Record<EditorToolbarPreset, string[]> = {\n minimal: ['bold', 'italic', 'underline', 'link'],\n standard: [\n 'format',\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'ul',\n 'ol',\n 'link',\n ],\n full: ['format', 'bold', 'italic', 'underline', 'strike', 'ul', 'ol', 'link'],\n};\n\n// Table ops mirror EXACTLY the commands platform's Redactor table plugin\n// exposes (verified against platform/web/static/redactor/_plugins/table) — it\n// has no merge/split/align commands, so neither do we.\nconst TABLE_OPS: { id: string; command: string; icon: ReactNode; label: L }[] =\n [\n {\n id: 'rowAbove',\n command: 'plugin.table.addRowAbove',\n icon: <BetweenHorizontalStart />,\n label: ['editor.table.rowAbove', 'Add row above'],\n },\n {\n id: 'rowBelow',\n command: 'plugin.table.addRowBelow',\n icon: <BetweenHorizontalEnd />,\n label: ['editor.table.rowBelow', 'Add row below'],\n },\n {\n id: 'colLeft',\n command: 'plugin.table.addColumnLeft',\n icon: <BetweenVerticalStart />,\n label: ['editor.table.columnLeft', 'Add column left'],\n },\n {\n id: 'colRight',\n command: 'plugin.table.addColumnRight',\n icon: <BetweenVerticalEnd />,\n label: ['editor.table.columnRight', 'Add column right'],\n },\n {\n id: 'addHead',\n command: 'plugin.table.addHead',\n icon: <PanelTop />,\n label: ['editor.table.addHeader', 'Add header row'],\n },\n {\n id: 'deleteHead',\n command: 'plugin.table.deleteHead',\n icon: <PanelTopDashed />,\n label: ['editor.table.deleteHeader', 'Remove header row'],\n },\n {\n id: 'deleteRow',\n command: 'plugin.table.deleteRow',\n icon: <Rows2 />,\n label: ['editor.table.deleteRow', 'Delete row'],\n },\n {\n id: 'deleteColumn',\n command: 'plugin.table.deleteColumn',\n icon: <Columns2 />,\n label: ['editor.table.deleteColumn', 'Delete column'],\n },\n {\n id: 'deleteTable',\n command: 'plugin.table.deleteTable',\n icon: <Trash2 />,\n label: ['editor.table.deleteTable', 'Delete table'],\n },\n ];\n\nconst TABLE_GRID = 6; // max rows/cols offered by the size picker\n\n// Outer element: query container ('toolbar') + visual chrome. The flex row\n// lives in `toolbarRowClass` on an inner child so `container-type` is never set\n// on the flex parent (that would blockify the inline-flowing controls).\nconst toolbarClass = cva(\n [\n 'ds:@container/toolbar',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:p-[var(--spacing-xs)]',\n 'ds:shadow-[var(--shadow-md)]',\n ].join(' '),\n);\n\nconst toolbarRowClass =\n 'ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]';\n\nconst dividerClass =\n 'ds:self-stretch ds:[inline-size:var(--border-width-sm)] ds:bg-[var(--border)] ds:[margin-inline:var(--spacing-2xs)]';\n\nconst fieldLabelClass =\n 'ds:text-[length:var(--font-size-sm)] ds:font-medium ds:text-[color:var(--foreground)]';\n\n// Escape a string for safe interpolation; insertHtml re-sanitises via DOMPurify,\n// but encoding here keeps the constructed markup well-formed first.\nfunction esc(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\n/* ------------------------------------------------------------------ */\n/* Style — labelled menu button */\n/* ------------------------------------------------------------------ */\n\nfunction StyleMenu({\n run,\n active,\n onTriggerDown,\n}: {\n run: EditorToolbarProps['run'];\n active: ReadonlySet<string>;\n onTriggerDown: (event: { preventDefault: () => void }) => void;\n}): React.JSX.Element {\n const { t } = useTranslation();\n const current =\n FORMAT_OPTIONS.find((o) => active.has(o.id)) ?? FORMAT_OPTIONS[0];\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <Button\n size=\"sm\"\n intent=\"ghost\"\n startIcon={current.icon}\n endIcon={<ChevronDown />}\n // Accessible name includes the current format so it (a) survives the\n // icon-only state below @md and (b) contains the visible label when\n // shown, satisfying WCAG 2.5.3 Label in Name.\n aria-label={`${t('editor.format', 'Paragraph style')}: ${t(\n current.label[0],\n current.label[1],\n )}`}\n onMouseDown={onTriggerDown}\n >\n {/* Drop the text label on a narrow toolbar — the start icon + chevron\n still convey \"current style + menu\", and the aria-label carries the\n accessible name. Shown again from 448px. The threshold is px, not\n the `@md` rem alias — container-query `rem` follows the host root\n font-size and misfires off a non-16px root. */}\n <span className=\"ds:hidden ds:@[448px]/toolbar:inline\">\n {t(current.label[0], current.label[1])}\n </span>\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"start\">\n {FORMAT_OPTIONS.map((opt) => (\n <DropdownMenu.Item\n key={opt.id}\n startIcon={opt.icon}\n onSelect={() => run('module.block.format', { tag: opt.tag })}\n >\n {t(opt.label[0], opt.label[1])}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Link — DS Dialog */\n/* ------------------------------------------------------------------ */\n\nfunction LinkDialog({\n insertHtml,\n saveSelection,\n restoreSelection,\n getSelectedText,\n}: Pick<\n EditorToolbarProps,\n 'insertHtml' | 'saveSelection' | 'restoreSelection' | 'getSelectedText'\n>): React.JSX.Element {\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const [url, setUrl] = useState('');\n const [text, setText] = useState('');\n const [newTab, setNewTab] = useState(false);\n const urlId = useId();\n const textId = useId();\n\n const reset = (): void => {\n setUrl('');\n setText('');\n setNewTab(false);\n };\n\n const handleInsert = (): void => {\n const href = url.trim();\n if (!href) return;\n const label = text.trim() || href;\n const tab = newTab ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : '';\n const html = `<a href=\"${esc(href)}\"${tab}>${esc(label)}</a>`;\n setOpen(false);\n reset();\n window.requestAnimationFrame(() => {\n restoreSelection();\n insertHtml(html);\n });\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={setOpen}>\n <Dialog.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<LinkIcon />}\n aria-label={t('editor.link.insert', 'Insert link')}\n // Save the selection synchronously (before focus leaves the editor);\n // no preventDefault — the modal Dialog needs normal focus handling.\n onMouseDown={() => {\n saveSelection();\n setText(getSelectedText());\n }}\n />\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>{t('editor.link.insert', 'Insert link')}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={urlId} className={fieldLabelClass}>\n {t('editor.link.url', 'URL')}\n </label>\n <TextInput\n id={urlId}\n type=\"url\"\n value={url}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://…\"\n />\n </div>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={textId} className={fieldLabelClass}>\n {t('editor.link.text', 'Text to display')}\n </label>\n <TextInput\n id={textId}\n value={text}\n onChange={(event) => setText(event.target.value)}\n placeholder={t('editor.link.textPlaceholder', 'Link text')}\n />\n </div>\n <Checkbox\n checked={newTab}\n onCheckedChange={(checked) => setNewTab(checked === true)}\n label={t('editor.link.newTab', 'Open in new tab')}\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button intent=\"secondary\">{t('common.cancel')}</Button>\n </Dialog.Close>\n <Button onClick={handleInsert} disabled={!url.trim()}>\n {t('editor.link.insertAction', 'Insert')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Image — DS Dialog */\n/* ------------------------------------------------------------------ */\n\nfunction ImageDialog({\n insertHtml,\n saveSelection,\n restoreSelection,\n uploadImage,\n}: Pick<\n EditorToolbarProps,\n 'insertHtml' | 'saveSelection' | 'restoreSelection' | 'uploadImage'\n>): React.JSX.Element {\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const [src, setSrc] = useState('');\n const [alt, setAlt] = useState('');\n const srcId = useId();\n const altId = useId();\n\n const insertImage = (url: string, altText: string): void => {\n const html = `<img src=\"${esc(url)}\" alt=\"${esc(altText)}\" loading=\"lazy\">`;\n setOpen(false);\n setSrc('');\n setAlt('');\n window.requestAnimationFrame(() => {\n restoreSelection();\n insertHtml(html);\n });\n };\n\n const handleInsert = (): void => {\n const url = src.trim();\n if (url) insertImage(url, alt.trim());\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={setOpen}>\n <Dialog.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<ImageIcon />}\n aria-label={t('editor.image.insert', 'Insert image')}\n // No preventDefault — the modal Dialog needs normal focus handling.\n onMouseDown={() => saveSelection()}\n />\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>\n {t('editor.image.insert', 'Insert image')}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {uploadImage ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <span className={fieldLabelClass}>\n {t('editor.image.upload', 'Upload')}\n </span>\n <FileUpload\n variant=\"dropzone\"\n accept={{\n 'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'],\n }}\n maxFiles={1}\n onUpload={async (file, { signal }) => {\n const url = await uploadImage(file, signal);\n insertImage(url, file.name);\n }}\n />\n <span className=\"ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--muted-foreground)]\">\n {t('editor.image.orUrl', 'Or paste an image URL')}\n </span>\n </div>\n ) : null}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={srcId} className={fieldLabelClass}>\n {t('editor.image.url', 'Image URL')}\n </label>\n <TextInput\n id={srcId}\n type=\"url\"\n value={src}\n onChange={(event) => setSrc(event.target.value)}\n placeholder=\"https://…\"\n />\n </div>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={altId} className={fieldLabelClass}>\n {t('editor.image.alt', 'Alt text')}\n </label>\n <TextInput\n id={altId}\n value={alt}\n onChange={(event) => setAlt(event.target.value)}\n placeholder={t(\n 'editor.image.altPlaceholder',\n 'Describe the image',\n )}\n />\n </div>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button intent=\"secondary\">{t('common.cancel')}</Button>\n </Dialog.Close>\n <Button onClick={handleInsert} disabled={!src.trim()}>\n {t('editor.image.insertAction', 'Insert')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Colour — DS ColorPicker */\n/* ------------------------------------------------------------------ */\n\nfunction ColourControl({\n run,\n saveSelection,\n restoreSelection,\n}: Pick<\n EditorToolbarProps,\n 'run' | 'saveSelection' | 'restoreSelection'\n>): React.JSX.Element {\n const { t } = useTranslation();\n // Colour-picker seed value: a text-colour picker emits arbitrary, user-chosen\n // colours, so a literal hex default (rather than a brand token) is correct.\n // eslint-disable-next-line no-restricted-syntax\n const [colour, setColour] = useState('#1f2a5c');\n\n // Apply on pick — a colour control shouldn't need a separate \"Apply\" step.\n // The picker is compact (swatch-only), so onChange fires once per swatch\n // click; mirror Redactor's fontcolor plugin (toggle <span> with a colour\n // style — `type: 'toggle'` is required for the format to apply).\n const applyColour = (hex: string): void => {\n setColour(hex);\n restoreSelection();\n run('module.inline.format', {\n tag: 'span',\n style: { color: hex },\n type: 'toggle',\n });\n };\n const removeColour = (): void => {\n restoreSelection();\n run('module.inline.remove', { style: 'color' });\n };\n\n return (\n <Popover onOpenChange={(o) => o && saveSelection()}>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<Palette />}\n aria-label={t('editor.textColor', 'Text colour')}\n onMouseDown={(event) => {\n event.preventDefault();\n saveSelection();\n }}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"start\">\n <Popover.Heading>\n {t('editor.textColor', 'Text colour')}\n </Popover.Heading>\n <div className=\"ds:pt-[var(--spacing-sm)]\">\n <ColorPicker\n variant=\"inline\"\n size=\"sm\"\n value={colour}\n onChange={applyColour}\n />\n </div>\n <div className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:items-center ds:justify-end\">\n <Button size=\"sm\" intent=\"secondary\" onClick={removeColour}>\n {t('editor.color.remove', 'Remove colour')}\n </Button>\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Highlight — DS ColorPicker applied as a text background */\n/* ------------------------------------------------------------------ */\n\nfunction HighlightControl({\n run,\n saveSelection,\n restoreSelection,\n}: Pick<\n EditorToolbarProps,\n 'run' | 'saveSelection' | 'restoreSelection'\n>): React.JSX.Element {\n const { t } = useTranslation();\n // Highlight seed value: a highlight picker emits arbitrary, user-chosen\n // colours, so a literal hex default (rather than a brand token) is correct.\n // eslint-disable-next-line no-restricted-syntax\n const [colour, setColour] = useState('#fff3a3');\n\n // Apply on pick. Highlight is the same inline <span> as text colour, but the\n // style key is `background-color` (mirrors Redactor's fontcolor \"Highlight\").\n const applyHighlight = (hex: string): void => {\n setColour(hex);\n restoreSelection();\n run('module.inline.format', {\n tag: 'span',\n style: { 'background-color': hex },\n type: 'toggle',\n });\n };\n const removeHighlight = (): void => {\n restoreSelection();\n run('module.inline.remove', { style: 'background-color' });\n };\n\n return (\n <Popover onOpenChange={(o) => o && saveSelection()}>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<Highlighter />}\n aria-label={t('editor.highlightColor', 'Highlight')}\n onMouseDown={(event) => {\n event.preventDefault();\n saveSelection();\n }}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"start\">\n <Popover.Heading>\n {t('editor.highlightColor', 'Highlight')}\n </Popover.Heading>\n <div className=\"ds:pt-[var(--spacing-sm)]\">\n <ColorPicker\n variant=\"inline\"\n size=\"sm\"\n value={colour}\n onChange={applyHighlight}\n />\n </div>\n <div className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:items-center ds:justify-end\">\n <Button size=\"sm\" intent=\"secondary\" onClick={removeHighlight}>\n {t('editor.highlight.remove', 'Remove highlight')}\n </Button>\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Table — size-grid insert + contextual ops */\n/* ------------------------------------------------------------------ */\n\nfunction buildTable(rows: number, cols: number): string {\n const cells = Array.from({ length: cols }, () => '<td><br></td>').join('');\n const body = Array.from({ length: rows }, () => `<tr>${cells}</tr>`).join('');\n return `<table><tbody>${body}</tbody></table>`;\n}\n\nfunction TableControl({\n run,\n insertTable,\n active,\n}: Pick<\n EditorToolbarProps,\n 'run' | 'insertTable' | 'active'\n>): React.JSX.Element {\n const { t } = useTranslation();\n const [hover, setHover] = useState<{ r: number; c: number }>({ r: 0, c: 0 });\n const inTable = active.has('table');\n\n return (\n <Popover onOpenChange={(o) => !o && setHover({ r: 0, c: 0 })}>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<TableIcon />}\n aria-label={t('editor.table.insert', 'Insert table')}\n onMouseDown={(event) => event.preventDefault()}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"start\">\n {inTable ? (\n // Caret is already inside a table — offer the manage ops only, never\n // a nested-table insert (mirrors Redactor's native dropdown, which\n // disables \"insert table\" while the caret is in a table).\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {TABLE_OPS.map((op) => (\n <button\n key={op.id}\n type=\"button\"\n onClick={() => run(op.command)}\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-2xs)] ds:text-start ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)] ds:hover:bg-[var(--muted)]\"\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center ds:text-[color:var(--muted-foreground)]\"\n >\n {op.icon}\n </span>\n {t(op.label[0], op.label[1])}\n </button>\n ))}\n </div>\n ) : (\n <>\n <Popover.Heading>\n {t('editor.table.insert', 'Insert table')}\n </Popover.Heading>\n <div\n role=\"group\"\n aria-label={t('editor.table.sizePicker', 'Table size')}\n className=\"ds:mt-[var(--spacing-sm)] ds:grid ds:w-fit ds:grid-cols-6 ds:gap-[var(--spacing-2xs)]\"\n onMouseLeave={() => setHover({ r: 0, c: 0 })}\n >\n {Array.from({ length: TABLE_GRID * TABLE_GRID }, (_, i) => {\n const r = Math.floor(i / TABLE_GRID) + 1;\n const c = (i % TABLE_GRID) + 1;\n const on = r <= hover.r && c <= hover.c;\n return (\n <button\n key={i}\n type=\"button\"\n aria-label={t('editor.table.sizeCell', '{{r}}×{{c}}', {\n r,\n c,\n })}\n onMouseEnter={() => setHover({ r, c })}\n onClick={() => insertTable(buildTable(r, c))}\n className={`ds:size-5 ds:rounded-[var(--radius-sm)] ds:border ds:border-[color:var(--border)] ${\n on ? 'ds:bg-[var(--primary)]' : 'ds:bg-[var(--muted)]'\n }`}\n />\n );\n })}\n </div>\n <p className=\"ds:mt-[var(--spacing-xs)] ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--muted-foreground)]\">\n {hover.r > 0\n ? t('editor.table.sizeCell', '{{r}}×{{c}}', {\n r: hover.r,\n c: hover.c,\n })\n : t('editor.table.sizeHint', 'Pick a size')}\n </p>\n </>\n )}\n </Popover.Content>\n </Popover>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Floating in-cell table toolbar */\n/* */\n/* Appears anchored above the table whenever the caret is inside one, */\n/* so the common row/column ops are one click away without opening the */\n/* toolbar menu. Dispatches the same `plugin.table.*` commands via the */\n/* shared `run` seam; the toolbar TableControl menu stays as the place */\n/* for inserting tables and header ops. */\n/* ------------------------------------------------------------------ */\n\nconst TABLE_OP_BY_ID: Record<string, (typeof TABLE_OPS)[number]> =\n Object.fromEntries(TABLE_OPS.map((op) => [op.id, op]));\n\nconst tableFloatClass = [\n 'ds:absolute ds:z-20 ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n 'ds:[inset-block-start:var(--rte-tt-top)] ds:[inset-inline-start:var(--rte-tt-start)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--popover)] ds:p-[var(--spacing-2xs)] ds:shadow-[var(--shadow-lg)]',\n].join(' ');\n\nexport interface TableFloatingToolbarProps {\n active: ReadonlySet<string>;\n run: EditorToolbarProps['run'];\n /** Positioned container the bar is absolutely placed within. */\n areaRef: RefObject<HTMLDivElement | null>;\n /** The <table> the caret is currently inside (relative to this editor). */\n getActiveTableEl: () => HTMLElement | null;\n /** Show the cell/row background-colour controls (fontcolor plugin loaded). */\n enableColor?: boolean;\n /** Snapshot the current cell before a colour popover takes focus. */\n saveTableCell: () => void;\n /** Set/clear a background colour on the current cell or its row. */\n applyTableBackground: (scope: 'cell' | 'row', colour: string | null) => void;\n}\n\n// Colour-control seed: an arbitrary user-chosen background, so a literal hex\n// default is correct (mirrors ColourControl / HighlightControl).\n// eslint-disable-next-line no-restricted-syntax\nconst TABLE_BG_SEED = '#fde68a';\n\n// One cell/row background-colour control: an icon trigger → compact ColorPicker\n// (applies on pick) + a clear action. The cell is captured on open (saveTableCell)\n// because the popover takes focus; `onOpenChange` lets the bar stay mounted.\nfunction TableBgColourControl({\n scope,\n icon,\n label,\n onOpenChange,\n saveTableCell,\n applyTableBackground,\n}: {\n scope: 'cell' | 'row';\n icon: ReactNode;\n label: string;\n onOpenChange: (open: boolean) => void;\n saveTableCell: () => void;\n applyTableBackground: (scope: 'cell' | 'row', colour: string | null) => void;\n}): React.JSX.Element {\n const { t } = useTranslation();\n const [colour, setColour] = useState(TABLE_BG_SEED);\n return (\n <Popover\n onOpenChange={(open) => {\n onOpenChange(open);\n if (open) saveTableCell();\n }}\n >\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={icon}\n tooltip={label}\n onMouseDown={(event) => event.preventDefault()}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"center\">\n <ColorPicker\n variant=\"inline\"\n size=\"sm\"\n value={colour}\n onChange={(hex) => {\n setColour(hex);\n applyTableBackground(scope, hex);\n }}\n />\n <Button\n size=\"sm\"\n intent=\"ghost\"\n className=\"ds:mt-[var(--spacing-xs)] ds:w-full\"\n onClick={() => applyTableBackground(scope, null)}\n >\n {t('editor.table.clearColor', 'Clear colour')}\n </Button>\n </Popover.Content>\n </Popover>\n );\n}\n\nexport function TableFloatingToolbar({\n active,\n run,\n areaRef,\n getActiveTableEl,\n enableColor = false,\n saveTableCell,\n applyTableBackground,\n}: TableFloatingToolbarProps): React.JSX.Element | null {\n const { t } = useTranslation();\n const inTable = active.has('table');\n const [pos, setPos] = useState<{\n top: number;\n start: number;\n rtl: boolean;\n } | null>(null);\n\n // Keep the bar mounted while a colour popover is open: opening it can move\n // focus out of the editor, dropping `table` from `active`, which would\n // otherwise unmount the bar (and close the popover) mid-interaction.\n const colourOpenCount = useRef(0);\n const [colourOpen, setColourOpen] = useState(false);\n const handleColourOpenChange = useCallback((open: boolean): void => {\n colourOpenCount.current = Math.max(\n 0,\n colourOpenCount.current + (open ? 1 : -1),\n );\n setColourOpen(colourOpenCount.current > 0);\n }, []);\n\n useEffect(() => {\n // Freeze tracking while a colour popover is open (the caret may have left\n // the editor); resume when it closes.\n if (colourOpen) return;\n if (!inTable || typeof window === 'undefined') {\n setPos(null);\n return;\n }\n const recompute = (): void => {\n const area = areaRef.current;\n const table = getActiveTableEl();\n if (!area || !table) {\n setPos(null);\n return;\n }\n const a = area.getBoundingClientRect();\n const r = table.getBoundingClientRect();\n const rtl = getComputedStyle(area).direction === 'rtl';\n // Float just above the table's block-start edge, clamped to the container\n // top so it never renders above the editing surface. 44 ≈ the bar's own\n // height (one --min-target-size row) plus a small gap.\n const top = Math.max(0, r.top - a.top - 44);\n // Anchor `start` to the table's inline CENTRE; the render translates the\n // bar back by half its own width so it sits centred over the table.\n const center = rtl\n ? a.right - r.right + r.width / 2\n : r.left - a.left + r.width / 2;\n setPos({ top, start: Math.max(0, center), rtl });\n };\n recompute();\n // While the caret stays in the table the bar must track it: cell edits and\n // add-row/column grow the table (ResizeObserver), and the surface or the\n // viewport can scroll/resize.\n const ro = new ResizeObserver(recompute);\n const area = areaRef.current;\n const table = getActiveTableEl();\n if (area) ro.observe(area);\n if (table) ro.observe(table);\n window.addEventListener('scroll', recompute, true);\n window.addEventListener('resize', recompute);\n return () => {\n ro.disconnect();\n window.removeEventListener('scroll', recompute, true);\n window.removeEventListener('resize', recompute);\n };\n }, [inTable, colourOpen, areaRef, getActiveTableEl]);\n\n if ((!inTable && !colourOpen) || !pos) return null;\n\n // Ordered render groups; 'colour' is the cell/row background controls.\n const groups: (string[] | 'colour')[] = [\n ['rowAbove', 'rowBelow'],\n ['colLeft', 'colRight'],\n ['addHead'],\n ...(enableColor ? (['colour'] as const) : []),\n ['deleteRow', 'deleteColumn'],\n ['deleteTable'],\n ];\n\n return (\n // Tooltips disambiguate the icon-only ops on hover (and provide each\n // button's accessible name via IconButton's `tooltip` prop). Radix Tooltip\n // needs a provider ancestor, so scope one to the bar.\n <TooltipProvider>\n <div\n // role=\"group\", not \"toolbar\": these controls are independent tab\n // stops with no roving-focus / arrow-key navigation, so advertising the\n // WAI-ARIA toolbar contract would be a false promise. role=\"group\" keeps\n // the labelled grouping without committing to single-tab-stop semantics.\n role=\"group\"\n aria-label={t('editor.table.toolbar', 'Table tools')}\n // Centre on the table: --rte-tt-start is the table's inline centre, so\n // pull back by half the bar's width (mirrored for RTL).\n className={`${tableFloatClass} ${pos.rtl ? 'ds:translate-x-1/2' : 'ds:-translate-x-1/2'}`}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-computed position injected via CSS custom properties (23-constraints §Runtime-computed dimensions); the inset rules live in the class\n style={{\n ['--rte-tt-top' as string]: `${pos.top}px`,\n ['--rte-tt-start' as string]: `${pos.start}px`,\n }}\n >\n {groups.map((group, gi) => (\n <Fragment key={group === 'colour' ? 'colour' : group[0]}>\n {gi > 0 ? (\n <span aria-hidden=\"true\" className={dividerClass} />\n ) : null}\n {group === 'colour' ? (\n <>\n <TableBgColourControl\n scope=\"cell\"\n icon={<PaintBucket />}\n label={t('editor.table.cellColor', 'Cell colour')}\n onOpenChange={handleColourOpenChange}\n saveTableCell={saveTableCell}\n applyTableBackground={applyTableBackground}\n />\n <TableBgColourControl\n scope=\"row\"\n icon={<PaintRoller />}\n label={t('editor.table.rowColor', 'Row colour')}\n onOpenChange={handleColourOpenChange}\n saveTableCell={saveTableCell}\n applyTableBackground={applyTableBackground}\n />\n </>\n ) : (\n group.map((opId) => {\n const op = TABLE_OP_BY_ID[opId];\n return (\n <IconButton\n key={opId}\n size=\"sm\"\n intent=\"ghost\"\n icon={op.icon}\n tooltip={t(op.label[0], op.label[1])}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => run(op.command)}\n />\n );\n })\n )}\n </Fragment>\n ))}\n </div>\n </TooltipProvider>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* ImageFloatingToolbar — contextual image controls + resize handles */\n/* */\n/* Framed over the selected image, so text-wrap (inline / wrap-left / */\n/* wrap-right) and block alignment (left / centre / right) are one */\n/* click away and the four corner handles resize it by pointer drag or */\n/* keyboard. DS-native parity with platform's Redactor imageAlignment + */\n/* imageResize plugins (HTP-4954): the SAME `wysiwyg-img-*` classes are */\n/* applied so saved HTML round-trips byte-for-byte across surfaces, and */\n/* the width is an inline % so it never overflows the editable. */\n/* Redactor's own resizer is off (imageResizable:false) — this is the */\n/* single, keyboard-accessible resize UI. */\n/* ------------------------------------------------------------------ */\n\n/* Layout classes — byte-identical to platform's imageAlignment plugin. */\nexport const IMAGE_FLOW_CLASSES = [\n 'wysiwyg-img-inline',\n 'wysiwyg-img-wrap-left',\n 'wysiwyg-img-wrap-right',\n] as const;\n\nexport const IMAGE_ALIGN_CLASSES = [\n 'wysiwyg-img-align-left',\n 'wysiwyg-img-align-center',\n 'wysiwyg-img-align-right',\n] as const;\n\n/** The layout class currently set within a group on `el` (or '' for none). */\nexport function selectedImageClass(\n el: HTMLElement,\n group: readonly string[],\n): string {\n return group.find((c) => el.classList.contains(c)) ?? '';\n}\n\n/** The image's rendered width as a whole-percent of its editable box. */\nexport function imageWidthPercent(img: HTMLElement): number {\n const box = img.closest('.redactor-in');\n const boxWidth = box instanceof HTMLElement ? box.clientWidth : 0;\n const imgWidth = img.getBoundingClientRect().width;\n if (boxWidth <= 0 || imgWidth <= 0) return IMG_MAX_PCT;\n return Math.round(Math.min(IMG_MAX_PCT, (imgWidth / boxWidth) * 100));\n}\n\nconst IMG_MIN_PCT = 10;\nconst IMG_MAX_PCT = 100;\nconst IMG_STEP = 5;\nconst IMG_STEP_COARSE = 10;\n\nconst clampPct = (pct: number): number =>\n Math.min(IMG_MAX_PCT, Math.max(IMG_MIN_PCT, Math.round(pct)));\n\n// Text-flow group: how surrounding text relates to the image. `inline` keeps\n// it in the line; the wrap options float it and flow text down the other side.\nconst IMAGE_FLOW_OPS: { id: string; icon: ReactNode; label: L }[] = [\n {\n id: 'wysiwyg-img-inline',\n icon: <Baseline />,\n label: ['editor.image.inline', 'Inline with text'],\n },\n {\n id: 'wysiwyg-img-wrap-left',\n icon: <PanelLeft />,\n label: ['editor.image.wrapLeft', 'Wrap left'],\n },\n {\n id: 'wysiwyg-img-wrap-right',\n icon: <PanelRight />,\n label: ['editor.image.wrapRight', 'Wrap right'],\n },\n];\n\n// Block-alignment group: where a non-wrapped image sits across the column.\nconst IMAGE_ALIGN_OPS: { id: string; icon: ReactNode; label: L }[] = [\n {\n id: 'wysiwyg-img-align-left',\n icon: <TextAlignStart />,\n label: ['editor.image.alignLeft', 'Align left'],\n },\n {\n id: 'wysiwyg-img-align-center',\n icon: <TextAlignCenter />,\n label: ['editor.image.alignCenter', 'Align centre'],\n },\n {\n id: 'wysiwyg-img-align-right',\n icon: <TextAlignEnd />,\n label: ['editor.image.alignRight', 'Align right'],\n },\n];\n\n// Four corner handles. `sign` is the horizontal grow direction for a pointer\n// drag (the inline-end corners grow rightward, the inline-start ones leftward);\n// it is flipped again for RTL at interaction time. The cursor is physical.\nconst IMAGE_CORNERS: {\n id: 'tl' | 'tr' | 'bl' | 'br';\n pos: string;\n cursor: string;\n sign: 1 | -1;\n labelKey: string;\n labelFallback: string;\n}[] = [\n {\n id: 'tl',\n pos: 'ds:[inset-block-start:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-start:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nwse-resize',\n sign: -1,\n labelKey: 'editor.image.resizeTopStart',\n labelFallback: 'Resize image, top-start corner',\n },\n {\n id: 'tr',\n pos: 'ds:[inset-block-start:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-end:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nesw-resize',\n sign: 1,\n labelKey: 'editor.image.resizeTopEnd',\n labelFallback: 'Resize image, top-end corner',\n },\n {\n id: 'bl',\n pos: 'ds:[inset-block-end:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-start:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nesw-resize',\n sign: -1,\n labelKey: 'editor.image.resizeBottomStart',\n labelFallback: 'Resize image, bottom-start corner',\n },\n {\n id: 'br',\n pos: 'ds:[inset-block-end:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-end:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nwse-resize',\n sign: 1,\n labelKey: 'editor.image.resizeBottomEnd',\n labelFallback: 'Resize image, bottom-end corner',\n },\n];\n\n// Selection frame outlined over the image; pointer-events off so clicks still\n// reach the image, re-enabled per handle. Rect injected via custom properties.\nconst imageFrameClass = [\n 'ds:absolute ds:z-20 ds:pointer-events-none',\n 'ds:[inset-block-start:var(--rte-img-top)] ds:[inset-inline-start:var(--rte-img-start)]',\n 'ds:[inline-size:var(--rte-img-width)] ds:[block-size:var(--rte-img-height)]',\n 'ds:rounded-[var(--radius-2xs)]',\n 'ds:[outline-style:solid] ds:[outline-width:var(--border-width-md)]',\n 'ds:[outline-color:var(--accent)] ds:[outline-offset:var(--focus-ring-offset)]',\n].join(' ');\n\n// One corner handle: a small accent square whose CENTRE sits on the corner.\n// Centred via per-corner negative-half-size insets (see IMAGE_CORNERS.pos) —\n// logical insets so it stays correct under RTL, with no physical transform.\nconst imageHandleClass = [\n 'ds:absolute ds:pointer-events-auto ds:touch-none',\n 'ds:[inline-size:var(--spacing-md)] ds:[block-size:var(--spacing-md)]',\n 'ds:rounded-[var(--radius-2xs)] ds:shadow-[var(--shadow-sm)]',\n 'ds:bg-[var(--accent)] ds:border ds:border-[color:var(--background)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:[outline-offset:var(--focus-ring-offset)]',\n 'ds:forced-colors:bg-[CanvasText]',\n].join(' ');\n\n// Controls bar, centred above the frame (mirrors tableFloatClass).\nconst imageBarClass = [\n 'ds:absolute ds:z-20 ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n 'ds:[inset-block-start:var(--rte-img-bar-top)] ds:[inset-inline-start:var(--rte-img-center)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--popover)] ds:p-[var(--spacing-2xs)] ds:shadow-[var(--shadow-lg)]',\n].join(' ');\n\nexport interface ImageFloatingToolbarProps {\n /** Positioned container the frame + bar are absolutely placed within. */\n areaRef: RefObject<HTMLDivElement | null>;\n /** The <img> currently selected in THIS editor, or null. */\n activeImageEl: HTMLElement | null;\n /** Apply/replace a `wysiwyg-img-*` class within its group on the image. */\n applyImageClass: (className: string) => void;\n /** Set the image width as a % of its editable box (clamped 10–100). */\n setImageWidth: (pct: number) => void;\n}\n\nexport function ImageFloatingToolbar({\n areaRef,\n activeImageEl: img,\n applyImageClass,\n setImageWidth,\n}: ImageFloatingToolbarProps): React.JSX.Element | null {\n const { t } = useTranslation();\n const [pos, setPos] = useState<{\n top: number;\n start: number;\n width: number;\n height: number;\n center: number;\n barTop: number;\n pct: number;\n rtl: boolean;\n } | null>(null);\n\n // Pointer-drag state (one active pointer at a time).\n const dragRef = useRef<{\n pointerId: number;\n startX: number;\n startPct: number;\n sign: number;\n } | null>(null);\n\n useEffect(() => {\n if (!img || typeof window === 'undefined') {\n setPos(null);\n return;\n }\n const recompute = (): void => {\n const area = areaRef.current;\n if (!area) {\n setPos(null);\n return;\n }\n const a = area.getBoundingClientRect();\n const r = img.getBoundingClientRect();\n const rtl = getComputedStyle(area).direction === 'rtl';\n const top = r.top - a.top;\n // Anchor inline-start from the writing-direction start edge.\n const start = rtl ? a.right - r.right : r.left - a.left;\n const center = start + r.width / 2;\n // 44 ≈ the bar's own height (one --min-target-size row) plus a small gap.\n const barTop = Math.max(0, top - 44);\n setPos({\n top,\n start: Math.max(0, start),\n width: r.width,\n height: r.height,\n center: Math.max(0, center),\n barTop,\n pct: imageWidthPercent(img),\n rtl,\n });\n };\n recompute();\n // The image rect moves when it resizes, when align / wrap / width change,\n // when the document reflows, or when the surface / viewport scrolls.\n // ResizeObserver catches size changes; a MutationObserver on the EDITABLE\n // catches the class / attribute / childList changes that REPOSITION the\n // image without resizing it (it observes the editable, not the frame — a\n // sibling — so it never reacts to its own output); scroll/resize cover the\n // viewport.\n const ro = new ResizeObserver(recompute);\n ro.observe(img);\n const area = areaRef.current;\n if (area) ro.observe(area);\n const editable = img.closest('.redactor-in');\n let mo: MutationObserver | null = null;\n if (editable) {\n mo = new MutationObserver(recompute);\n mo.observe(editable, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['class', 'style', 'width', 'height', 'src'],\n });\n }\n window.addEventListener('scroll', recompute, true);\n window.addEventListener('resize', recompute);\n return () => {\n ro.disconnect();\n mo?.disconnect();\n window.removeEventListener('scroll', recompute, true);\n window.removeEventListener('resize', recompute);\n };\n }, [img, areaRef]);\n\n const onHandlePointerDown = useCallback(\n (corner: (typeof IMAGE_CORNERS)[number]) =>\n (event: React.PointerEvent<HTMLDivElement>): void => {\n if (!event.isPrimary || !pos) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n dragRef.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startPct: pos.pct,\n sign: corner.sign * (pos.rtl ? -1 : 1),\n };\n },\n [pos],\n );\n\n const onHandlePointerMove = useCallback(\n (event: React.PointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (!drag || event.pointerId !== drag.pointerId || !img) return;\n const box = img.closest('.redactor-in');\n const boxWidth = box instanceof HTMLElement ? box.clientWidth : 0;\n if (boxWidth <= 0) return;\n const deltaPct =\n ((drag.sign * (event.clientX - drag.startX)) / boxWidth) * 100;\n setImageWidth(clampPct(drag.startPct + deltaPct));\n },\n [img, setImageWidth],\n );\n\n const onHandlePointerEnd = useCallback(\n (event: React.PointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (!drag || event.pointerId !== drag.pointerId) return;\n event.currentTarget.releasePointerCapture(event.pointerId);\n dragRef.current = null;\n },\n [],\n );\n\n const onHandleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (!pos) return;\n let next: number | null = null;\n const step = event.shiftKey ? IMG_STEP_COARSE : IMG_STEP;\n switch (event.key) {\n // Up / right always grow; down / left always shrink — independent of\n // which corner has focus, so the gesture reads the same everywhere.\n case 'ArrowRight':\n case 'ArrowUp':\n next = pos.pct + step;\n break;\n case 'ArrowLeft':\n case 'ArrowDown':\n next = pos.pct - step;\n break;\n case 'Home':\n next = IMG_MIN_PCT;\n break;\n case 'End':\n next = IMG_MAX_PCT;\n break;\n default:\n return;\n }\n event.preventDefault();\n setImageWidth(clampPct(next));\n },\n [pos, setImageWidth],\n );\n\n if (!img || !pos) return null;\n\n const flowActive = selectedImageClass(img, IMAGE_FLOW_CLASSES);\n const alignActive = selectedImageClass(img, IMAGE_ALIGN_CLASSES);\n const widthText = t('editor.image.widthAnnounce', {\n width: pos.pct,\n defaultValue: '{{width}} percent',\n });\n\n return (\n <>\n {/* Selection frame + corner resize handles. */}\n <div\n className={imageFrameClass}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-measured image rect injected via CSS custom properties (23-constraints §Runtime-computed dimensions); the inset/size rules live in the class\n style={{\n ['--rte-img-top' as string]: `${pos.top}px`,\n ['--rte-img-start' as string]: `${pos.start}px`,\n ['--rte-img-width' as string]: `${pos.width}px`,\n ['--rte-img-height' as string]: `${pos.height}px`,\n }}\n >\n {IMAGE_CORNERS.map((corner) => (\n <div\n key={corner.id}\n role=\"slider\"\n tabIndex={0}\n aria-label={t(corner.labelKey, corner.labelFallback)}\n aria-orientation=\"horizontal\"\n aria-valuemin={IMG_MIN_PCT}\n aria-valuemax={IMG_MAX_PCT}\n aria-valuenow={pos.pct}\n aria-valuetext={widthText}\n className={`${imageHandleClass} ${corner.pos} ${corner.cursor}`}\n onPointerDown={onHandlePointerDown(corner)}\n onPointerMove={onHandlePointerMove}\n onPointerUp={onHandlePointerEnd}\n onPointerCancel={onHandlePointerEnd}\n onKeyDown={onHandleKeyDown}\n />\n ))}\n </div>\n\n {/* Wrap + alignment controls, centred above the frame. */}\n <TooltipProvider>\n <div\n role=\"group\"\n aria-label={t('editor.image.toolbar', 'Image tools')}\n className={`${imageBarClass} ${pos.rtl ? 'ds:translate-x-1/2' : 'ds:-translate-x-1/2'}`}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-computed anchor injected via CSS custom properties; the inset rules live in the class\n style={{\n ['--rte-img-bar-top' as string]: `${pos.barTop}px`,\n ['--rte-img-center' as string]: `${pos.center}px`,\n }}\n >\n {[IMAGE_FLOW_OPS, IMAGE_ALIGN_OPS].map((group, gi) => (\n <Fragment key={gi === 0 ? 'flow' : 'align'}>\n {gi > 0 ? (\n <span aria-hidden=\"true\" className={dividerClass} />\n ) : null}\n {group.map((op) => {\n const isActive =\n gi === 0 ? flowActive === op.id : alignActive === op.id;\n return (\n <IconButton\n key={op.id}\n size=\"sm\"\n intent=\"ghost\"\n icon={op.icon}\n aria-pressed={isActive}\n tooltip={t(op.label[0], op.label[1])}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => applyImageClass(op.id)}\n />\n );\n })}\n </Fragment>\n ))}\n </div>\n </TooltipProvider>\n </>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Toolbar */\n/* ------------------------------------------------------------------ */\n\nexport function EditorToolbar({\n run,\n active,\n preset,\n insertHtml,\n insertTable,\n saveSelection,\n restoreSelection,\n getSelectedText,\n uploadImage,\n enableColor = false,\n enableImage = false,\n enableTable = false,\n showExtensions = false,\n}: EditorToolbarProps): React.JSX.Element {\n const { t } = useTranslation();\n // Keep toolbar clicks from stealing the editor's selection.\n const keepSelection = (event: { preventDefault: () => void }): void =>\n event.preventDefault();\n\n // Render a simple command button by id, gated by the active preset.\n const has = (id: string): boolean => PRESETS[preset].includes(id);\n const btn = (id: string): React.JSX.Element | null => {\n if (!has(id)) return null;\n const item = ITEMS[id];\n return (\n <IconButton\n key={item.id}\n size=\"sm\"\n intent=\"ghost\"\n icon={item.icon}\n aria-label={t(item.label[0], item.label[1])}\n aria-pressed={item.toggle ? active.has(item.toggle) : undefined}\n onMouseDown={keepSelection}\n onClick={() => run(...item.command)}\n />\n );\n };\n const Divider = (): React.JSX.Element => (\n <span aria-hidden=\"true\" className={dividerClass} />\n );\n\n // Standard toolbar grouping (matches Google Docs / Word / TinyMCE order):\n // style ▸ inline (B/I/U/S + colour/highlight) ▸ lists ▸ insert ▸ extensions.\n const styleGroup = has('format');\n\n // Primary controls — always inline (style + B/I/U/S + colour/highlight).\n const inlineNodes = [\n btn('bold'),\n btn('italic'),\n btn('underline'),\n btn('strike'),\n enableColor ? (\n <ColourControl\n key=\"colour\"\n run={run}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n />\n ) : null,\n enableColor ? (\n <HighlightControl\n key=\"highlight\"\n run={run}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n />\n ) : null,\n ].filter(Boolean);\n const hasPrimary = styleGroup || inlineNodes.length > 0;\n\n // Secondary controls — lists ▸ insert ▸ extensions. These collapse into the\n // right-hand \"More\" popover on a narrow toolbar (below the @sm breakpoint)\n // instead of wrapping the bar onto a second line.\n const listsNodes = [btn('ul'), btn('ol')].filter(Boolean);\n const insertNodes = [\n has('link') ? (\n <LinkDialog\n key=\"link\"\n insertHtml={insertHtml}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n getSelectedText={getSelectedText}\n />\n ) : null,\n enableImage ? (\n <ImageDialog\n key=\"image\"\n insertHtml={insertHtml}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n uploadImage={uploadImage}\n />\n ) : null,\n enableTable ? (\n <TableControl\n key=\"table\"\n run={run}\n insertTable={insertTable}\n active={active}\n />\n ) : null,\n ].filter(Boolean);\n const extensionNodes = showExtensions\n ? [\n <IconButton\n key=\"extensions\"\n size=\"sm\"\n intent=\"ghost\"\n icon={<Wrench />}\n aria-label={t('editor.extensions', 'Editor extensions')}\n // Placeholder affordance: no handler is wired yet, so the control\n // must not be operable — an enabled button with no onClick fails\n // SC 4.1.2. Disable it until a marketplace handler is connected.\n disabled\n onMouseDown={keepSelection}\n />,\n ]\n : [];\n\n const secondarySubgroups = [listsNodes, insertNodes, extensionNodes].filter(\n (group) => group.length > 0,\n );\n const hasSecondary = secondarySubgroups.length > 0;\n\n // Render the secondary subgroups separated by dividers. `leadingDivider`\n // controls whether a divider precedes the first subgroup (true inline, where\n // the primary controls sit before it; false inside the More popover).\n const renderSecondary = (leadingDivider: boolean): ReactNode =>\n secondarySubgroups.map((group, index) => (\n <Fragment key={index}>\n {index > 0 || leadingDivider ? <Divider /> : null}\n {group}\n </Fragment>\n ));\n\n return (\n // Outer element is the query container + visual chrome; the flex row is an\n // inner child so `container-type` never lands on the flex parent (which\n // would blockify the inline controls).\n <div className={toolbarClass()} data-component=\"editor-toolbar\">\n <div\n // role=\"group\", not \"toolbar\": every control is its own tab stop with\n // no roving focus / arrow-key handling, so the toolbar contract would\n // be false. role=\"group\" keeps the labelled grouping without the\n // single-tab-stop + arrow-navigation promise.\n role=\"group\"\n aria-label={t('editor.toolbarLabel')}\n className={toolbarRowClass}\n >\n {/* Block style */}\n {styleGroup ? (\n <StyleMenu run={run} active={active} onTriggerDown={keepSelection} />\n ) : null}\n\n {/* Inline formatting */}\n {styleGroup && inlineNodes.length > 0 ? <Divider /> : null}\n {inlineNodes}\n\n {hasSecondary ? (\n <>\n {/* Secondary controls inline — shown from 384px. px, not the `@sm`\n rem alias: container-query `rem` follows the host root\n font-size and misfires off a non-16px root. */}\n <div className=\"ds:hidden ds:@[384px]/toolbar:contents\">\n {renderSecondary(hasPrimary)}\n </div>\n\n {/* Overflow \"More\" menu — replaces the inline secondary controls\n below @sm so the bar never wraps onto a second line. */}\n <div className=\"ds:contents ds:@[384px]/toolbar:hidden\">\n {hasPrimary ? <Divider /> : null}\n <Popover>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<Ellipsis />}\n aria-label={t('editor.more', 'More options')}\n onMouseDown={keepSelection}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"end\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n {renderSecondary(false)}\n </div>\n </Popover.Content>\n </Popover>\n </div>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n","/* ------------------------------------------------------------------ */\n/* RichTextEditor — thin, secure wrapper over Redactor (Imperavi). */\n/* */\n/* LICENCE-SAFETY MODEL (read first): */\n/* Redactor is a COMMERCIAL editor and `@alfadocs/ui-kit` publishes */\n/* to PUBLIC npm — so redactor.js bytes MUST NOT enter `dist/`. This */\n/* wrapper never imports Redactor; it resolves a Redactor factory at */\n/* runtime from a `redactor` prop or the UMD globals `window.$R` / */\n/* `window.Redactor` that the CONSUMER's licensed build sets */\n/* (platform ships `web/static/redactor/redactor.js`). With no */\n/* factory found, the editor renders a graceful plain <textarea>. */\n/* Storybook loads a vendored dev-only build via preview-head.html. */\n/* */\n/* - Toolbar/buttons/dropdowns/shortcuts are owned entirely by Redactor */\n/* itself. The kit only skins them via `redactor-theme.css` and feeds */\n/* button presets + lang strings. */\n/* - Security: all inbound HTML (value/defaultValue/setContent) and the */\n/* editor's outbound `changed` HTML run through DOMPurify with an */\n/* explicit FORBID list. Outbound HTML also gets `loading=\"lazy\"` on */\n/* images and platform's empty-placeholder normalisation. */\n/* - Backend-coupled features (image upload, help-me-write, */\n/* voice-recording) are CONSUMER-PROVIDED via `imageUploadUrl` / */\n/* `plugins` / `options`; the kit never bakes a backend route in. */\n/* - i18n: placeholder/aria via `t('editor.placeholder')`; Redactor's */\n/* own `lang` is derived from the active locale (not hardcoded). */\n/* ------------------------------------------------------------------ */\n\nimport {\n Fragment,\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Mic, SpellCheck, Astroid, Square, WandSparkles } from 'lucide-react';\n\nimport '../../tokens/themes/bridges/redactor-theme.css';\n\nimport { sanitiseHtml as sanitiseShared } from '../_shared/safe-html';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { Spinner } from '../spinner';\nimport { richTextEditorAgent } from './rich-text-editor.agent';\nimport { HelpMeWriteOverlay } from './help-me-write-overlay';\nimport {\n EditorToolbar,\n ImageFloatingToolbar,\n TableFloatingToolbar,\n IMAGE_FLOW_CLASSES,\n IMAGE_ALIGN_CLASSES,\n} from './editor-toolbar';\n\n/* ------------------------------------------------------------------ */\n/* Sanitisation */\n/* ------------------------------------------------------------------ */\n\n// Single sanitiser surface (constraints §8): the editor routes every inbound\n// and outbound HTML string through the shared `rich-text` DOMPurify profile in\n// `_shared/safe-html.tsx`, so one audit covers the whole kit. The wrapper adds\n// only editor-specific shaping (normalizeEditorValue + withLazyImages) around it.\nfunction sanitiseHtml(input: string): string {\n return sanitiseShared(input, 'rich-text');\n}\n\n// Mirror platform's RedactorWysiwyg `normalizeEditorValue` (RedactorWysiwyg.js\n// :26-44): map Redactor's empty placeholders to '' for the emptiness test, but\n// preserve image-only HTML so embedded-image notes aren't dropped on save.\nfunction normalizeEditorValue(html = ''): string {\n const normalized = String(html).trim();\n if (\n normalized === '' ||\n normalized === '<p><br></p>' ||\n normalized === '<p> </p>'\n ) {\n return '';\n }\n const contentWithoutTags = normalized\n .replace(/<br\\s*\\/?>/gi, '')\n .replace(/ /gi, '')\n .replace(/<[^>]+>/g, '')\n .trim();\n if (contentWithoutTags === '' && /<img\\b[^>]*>/i.test(normalized)) {\n return normalized;\n }\n return contentWithoutTags === '' ? '' : normalized;\n}\n\n// Inject `loading=\"lazy\"` on any <img> lacking it (platform parity).\nfunction withLazyImages(html: string): string {\n return html.replace(\n /<img(?![^>]*\\sloading=)([^>]*)>/gi,\n '<img loading=\"lazy\"$1>',\n );\n}\n\n// Pull the uploaded image URL out of a Redactor-style imageUpload response.\n// Handles the common shapes: `{ file: { url } }`, `{ url }`, `{ data: { url } }`,\n// and the multi-file map `{ \"1\": { url }, … }`.\nfunction extractUploadedUrl(data: unknown): string | undefined {\n if (!data || typeof data !== 'object') return undefined;\n const rec = data as Record<string, unknown>;\n const fromNode = (node: unknown): string | undefined => {\n if (node && typeof node === 'object' && 'url' in node) {\n const url = (node as { url?: unknown }).url;\n return typeof url === 'string' ? url : undefined;\n }\n return undefined;\n };\n if (typeof rec.url === 'string') return rec.url;\n return (\n fromNode(rec.file) ??\n fromNode(rec.data) ??\n Object.values(rec).map(fromNode).find(Boolean)\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Redactor factory resolution (external — never bundled) */\n/* ------------------------------------------------------------------ */\n\nexport type RedactorFactory = (\n selector: string | HTMLElement,\n command?: unknown,\n ...args: unknown[]\n) => unknown;\n\nfunction resolveRedactor(injected?: RedactorFactory): RedactorFactory | null {\n if (injected) return injected;\n if (typeof window === 'undefined') return null;\n const w = window as unknown as {\n $R?: RedactorFactory;\n Redactor?: RedactorFactory;\n };\n return w.$R ?? w.Redactor ?? null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type RichTextEditorToolbar = 'minimal' | 'standard' | 'full';\n\nexport interface RichTextEditorProps {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** HTML initial value (uncontrolled). Runs through DOMPurify. */\n defaultValue?: string;\n /** Controlled value (HTML). Sanitised; synced with a skip-once caret guard. */\n value?: string;\n /** Emits on every change — debounced 100ms. `markdown` is '' (Redactor has no serializer). */\n onChange?: (payload: { html: string; markdown: string }) => void;\n /** Toolbar preset → Redactor `buttons`. */\n toolbar?: RichTextEditorToolbar;\n /** Placeholder text — translates via useTranslation if omitted. */\n placeholder?: string;\n /** Read-only mode. */\n readOnly?: boolean;\n /** Accessible name for the editing region. */\n ariaLabel?: string;\n /** Size variant for the minimum block-size of the editing region. */\n minHeight?: 'sm' | 'md' | 'lg';\n /** Show a right-aligned editor-extensions affordance (visual placeholder). */\n showExtensions?: boolean;\n /** Extra class names on the wrapper. */\n className?: string;\n\n /* --- Redactor-specific seams (all CONSUMER-PROVIDED) --- */\n /** Inject the Redactor factory explicitly; else `window.$R` / `window.Redactor`. */\n redactor?: RedactorFactory;\n /** Raw Redactor options, deep-merged LAST over the kit defaults (callbacks reserved). */\n options?: Record<string, unknown>;\n /** Redactor plugin names to enable (the consumer must register/load them). */\n plugins?: string[];\n /** Redactor lang code; default derived from the active i18n locale. */\n lang?: string;\n /** Consumer image-upload endpoint → Redactor `imageUpload`. Omitted if absent. */\n imageUploadUrl?: string;\n /** App keyboard-shortcut seam (e.g. Ctrl/Cmd+Enter to save). */\n onKeyDown?: (event: KeyboardEvent) => void;\n\n /* --- AI assistance (DS-native UI; backend stays consumer-provided) --- */\n /**\n * Help-me-write. When provided, a DS \"Help me write\" action appears; the kit\n * opens a dialog, calls this with the prompt + an AbortSignal, sanitises the\n * returned draft and inserts it at the caret. The backend call / auth /\n * practiceId all live in the consumer's implementation — never in the kit.\n */\n onRequestAiDraft?: (ctx: {\n prompt: string;\n signal: AbortSignal;\n }) => Promise<string>;\n /** Whether `onRequestAiDraft` returns HTML (default) or plain text. */\n aiDraftFormat?: 'html' | 'text';\n /** Override the compliance notice shown in the Help-me-write dialog. */\n aiPrivacyNotice?: ReactNode;\n /**\n * Voice dictation. When provided, a DS mic toggle + live-transcript region\n * appear. The kit owns the UI; the consumer runs mic capture + transcription\n * inside the callback and pushes text back via `onPartialTranscript` (drives\n * the live region) and `onFinalTranscript` (sanitised + inserted at the\n * caret). Resolve when the session ends; honour `signal` to stop. All\n * mic / transcription / backend logic stays consumer-side.\n */\n onDictate?: (ctx: {\n signal: AbortSignal;\n onPartialTranscript: (text: string) => void;\n onFinalTranscript: (text: string) => void;\n }) => Promise<void>;\n /**\n * One-shot AI document actions (CONSUMER-PROVIDED backend). Each gets the\n * current HTML + an AbortSignal and resolves with rewritten HTML; while one\n * runs the editor is disabled with a spinner and the result replaces the whole\n * document. `onProofread` corrects spelling/grammar; `onAutoFormat` tidies the\n * document's structure/formatting. Each adds a FAB segment when provided.\n */\n onProofread?: (ctx: { html: string; signal: AbortSignal }) => Promise<string>;\n onAutoFormat?: (ctx: {\n html: string;\n signal: AbortSignal;\n }) => Promise<string>;\n}\n\n/** Block/inline formats the editor can toggle via `applyFormat`. */\nexport type EditorFormat =\n | 'bold'\n | 'italic'\n | 'strikethrough'\n | 'bulletedList'\n | 'numberedList'\n | 'heading'\n | 'quote'\n | 'paragraph';\n\n// Maps each format to its Redactor command (shared with the toolbar).\nconst FORMAT_COMMANDS: Record<EditorFormat, [string, ...unknown[]]> = {\n bold: ['module.inline.format', { tag: 'b' }],\n italic: ['module.inline.format', { tag: 'i' }],\n strikethrough: ['module.inline.format', { tag: 'del' }],\n bulletedList: ['module.list.toggle', 'ul'],\n numberedList: ['module.list.toggle', 'ol'],\n heading: ['module.block.format', { tag: 'h2' }],\n quote: ['module.block.format', { tag: 'blockquote' }],\n paragraph: ['module.block.format', { tag: 'p' }],\n};\n\nexport interface RichTextEditorHandle {\n getHTML: () => string;\n /** Plain-text content of the editor (tags stripped). */\n getText: () => string;\n /** Always '' — Redactor has no native Markdown serializer (see MDX). */\n getMarkdown: () => string;\n /** HTML goes through DOMPurify before reaching Redactor. */\n setContent: (html: string) => void;\n /**\n * Insert content at the caret (replacing any selection). HTML is\n * DOMPurify-sanitised; pass `{ asHtml: false }` for a plain-text insert.\n * Works with the degraded <textarea> too. This is the seam for inserting\n * merge/template variables and AI-generated drafts.\n */\n insertAtCursor: (content: string, opts?: { asHtml?: boolean }) => void;\n /** Toggle/apply a block or inline format on the current selection. */\n applyFormat: (format: EditorFormat) => void;\n focus: () => void;\n clear: () => void;\n}\n\n// Map the kit's locale codes to Redactor's lang-file codes where they differ\n// (Redactor ships zh_cn / zh_tw / pt_br; the kit uses zh / pt). RTL (ar/fa/he)\n// pass through — direction is handled by the document dir, not the lang code.\nconst REDACTOR_LANG: Record<string, string> = {\n zh: 'zh_cn',\n pt: 'pt_br',\n};\n\nfunction toRedactorLang(locale: string): string {\n const base = locale.split('-')[0];\n return REDACTOR_LANG[base] ?? base ?? 'en';\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst wrapperVariants = cva(\n 'redactor-theme-alfadocs ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n);\n\n// Degraded-mode plain textarea (Redactor not found) — looks like a kit field.\nconst degradedTextareaVariants = cva(\n [\n 'ds:block ds:[inline-size:100%]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:shadow-[var(--shadow-md)]',\n 'ds:font-[family-name:var(--font-sans)] ds:text-[length:var(--font-size-base)]',\n 'ds:p-[var(--spacing-md)] ds:[min-block-size:var(--rich-text-editor-min-block-size)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\n// Split-FAB segment: an icon button inside the primary pill (record |\n// help-me-write). Transparent on the pill with an INSET focus ring (the pill\n// clips overflow, so the ring must be inset).\nconst fabSegmentBase = [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]',\n 'ds:text-[color:var(--primary-foreground)]',\n 'ds:transition-colors',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--primary-foreground)]',\n 'ds:focus-visible:[outline-offset:calc(var(--focus-ring-width)*-1)]',\n].join(' ');\n\n// Idle segment: a translucent-white hover overlay over the pill.\nconst fabSegmentIdle = `${fabSegmentBase} ds:hover:bg-[color-mix(in_srgb,var(--primary-foreground)_15%,transparent)]`;\n\n// Recording mic: a solid destructive (red) fill that stays red on hover so the\n// \"stop\" state reads as live recording. Deliberately no aria-pressed translucent\n// overlay — its attribute selector out-specifies the red and would wash it out.\nconst fabSegmentRecording = `${fabSegmentBase} ds:bg-[var(--destructive)] ds:hover:bg-[color-mix(in_srgb,var(--destructive)_88%,var(--primary-foreground))]`;\n\n/* ------------------------------------------------------------------ */\n/* RichTextEditor */\n/* ------------------------------------------------------------------ */\n\nexport const RichTextEditor = forwardRef<\n RichTextEditorHandle,\n RichTextEditorProps\n>(\n (\n {\n id,\n defaultValue,\n value,\n onChange,\n toolbar = 'standard',\n placeholder,\n readOnly = false,\n ariaLabel,\n minHeight,\n showExtensions,\n className,\n redactor,\n options,\n plugins,\n lang,\n imageUploadUrl,\n onKeyDown,\n onRequestAiDraft,\n aiDraftFormat = 'html',\n aiPrivacyNotice,\n onDictate,\n onProofread,\n onAutoFormat,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const rawId = useId();\n const editorId = useMemo(\n () => `rte-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}`,\n [rawId],\n );\n const selector = `#${editorId}`;\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const redactorRef = useRef<RedactorFactory | null>(null);\n // Skip-once guard: Redactor's `changed` already pushed this value out via\n // onChange, so the controlled-value effect must not echo it back with\n // setCode (which resets the caret to position 0). Mirrors platform.\n const skipNextPropSyncRef = useRef(false);\n // Mirrors the live readOnly state for imperative ops: Redactor blocks every\n // command except `disableReadOnly` while read-only, so writes (setContent /\n // clear / insertAtCursor / controlled-value sync) must lift it first.\n const readOnlyRef = useRef(readOnly);\n const wrapperRef = useRef<HTMLDivElement>(null);\n // The positioned editing-surface container — the floating table toolbar is\n // absolutely placed within it.\n const editorAreaRef = useRef<HTMLDivElement>(null);\n const [degraded, setDegraded] = useState(false);\n const [aiOpen, setAiOpen] = useState(false);\n // Active formats at the caret (bold/italic/strike/ul/ol/heading) — drives\n // the custom toolbar's pressed state; refreshed on Redactor's `observe`.\n const [activeFormats, setActiveFormats] = useState<ReadonlySet<string>>(\n () => new Set(),\n );\n // The <img> the user has selected (clicked) in this editor's editable, or\n // null — drives the ImageFloatingToolbar (wrap / align / resize). The ref\n // mirrors the state so the apply seams read the live element synchronously.\n const activeImageElRef = useRef<HTMLElement | null>(null);\n const [activeImageEl, setActiveImageEl] = useState<HTMLElement | null>(\n null,\n );\n const selectImage = useCallback((el: HTMLElement | null): void => {\n activeImageElRef.current = el;\n setActiveImageEl(el);\n }, []);\n\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const onChangeRef = useRef<RichTextEditorProps['onChange']>(onChange);\n const onKeyDownRef = useRef<RichTextEditorProps['onKeyDown']>(onKeyDown);\n useEffect(() => {\n onChangeRef.current = onChange;\n onKeyDownRef.current = onKeyDown;\n }, [onChange, onKeyDown]);\n\n // Initial content is computed once (controlled `value` is then synced by\n // the effect below). Sanitised before it ever reaches Redactor.\n const initialContentRef = useRef<string>(\n (() => {\n const raw = value ?? defaultValue ?? '';\n return raw ? sanitiseHtml(raw) : '';\n })(),\n );\n\n // Read the current editor HTML. Redactor's `source.getCode` is blocked while\n // read-only (returns undefined), so fall back to the synced source textarea\n // — never toggle read-only just to read.\n const readCode = useCallback((): string => {\n const R = redactorRef.current;\n if (R) {\n try {\n const code = R(selector, 'source.getCode');\n if (typeof code === 'string') return code;\n } catch {\n /* fall through to the source textarea */\n }\n }\n return textareaRef.current?.value ?? '';\n }, [selector]);\n\n // Dispatch a mutating Redactor command, transparently lifting read-only\n // (which blocks every command but `disableReadOnly`) and restoring it after.\n // Returns false when Redactor is absent or the call failed so the caller can\n // fall back to the degraded <textarea>.\n const dispatchWrite = useCallback(\n (command: string, ...args: unknown[]): boolean => {\n const R = redactorRef.current;\n if (!R) return false;\n const wasReadOnly = readOnlyRef.current;\n if (wasReadOnly) {\n try {\n R(selector, 'disableReadOnly');\n } catch {\n /* ignore */\n }\n }\n try {\n R(selector, command, ...args);\n return true;\n } catch {\n return false;\n } finally {\n if (wasReadOnly) {\n try {\n R(selector, 'enableReadOnly');\n } catch {\n // Restore failed — the editor may be left editable. Surface it in\n // DEV; the next readOnly-sync tick re-asserts it on a prop change.\n if (import.meta.env.DEV) {\n console.warn(\n '[RichTextEditor] failed to restore read-only after a write; the editor may be left editable.',\n );\n }\n }\n }\n }\n },\n [selector],\n );\n\n // Insert content at the caret, sanitised, with a degraded <textarea> splice\n // fallback. Shared by the imperative handle (merge variables) and the\n // Help-me-write dialog (AI drafts).\n const insertAtCursor = useCallback(\n (content: string, opts?: { asHtml?: boolean }): void => {\n const asHtml = opts?.asHtml ?? true;\n const payload = asHtml ? sanitiseHtml(content) : content;\n const command = asHtml\n ? 'insertion.insertHtml'\n : 'insertion.insertText';\n if (dispatchWrite(command, payload)) return;\n const ta = textareaRef.current;\n if (!ta) return;\n const start = ta.selectionStart ?? ta.value.length;\n const end = ta.selectionEnd ?? ta.value.length;\n ta.value = ta.value.slice(0, start) + payload + ta.value.slice(end);\n const caret = start + payload.length;\n try {\n ta.setSelectionRange(caret, caret);\n } catch {\n /* selection API unavailable */\n }\n onChangeRef.current?.({ html: sanitiseHtml(ta.value), markdown: '' });\n },\n [dispatchWrite],\n );\n\n // Last in-editor selection range — see updateActiveFormats / restoreSelection.\n const lastRangeRef = useRef<Range | null>(null);\n\n // Recompute the active inline/block formats at the caret (scoped to THIS\n // editor's `.redactor-in`) for the custom toolbar's pressed state.\n const updateActiveFormats = useCallback((): void => {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection =\n typeof window !== 'undefined' ? window.getSelection() : null;\n const next = new Set<string>();\n if (\n root &&\n selection &&\n selection.anchorNode &&\n root.contains(selection.anchorNode) &&\n typeof document.queryCommandState === 'function'\n ) {\n // Track the live in-editor range so a focus-stealing DS popover/dialog\n // can restore EXACTLY here — needed because Redactor's insertHtml wraps\n // the insert in a fresh <p> when no selection is active at insert time.\n if (selection.rangeCount > 0) {\n lastRangeRef.current = selection.getRangeAt(0).cloneRange();\n }\n // queryCommandState reads the selection's EFFECTIVE format (it handles\n // range boundaries + nesting), unlike walking the anchor's ancestors —\n // which misses a format when the anchor sits just outside the wrapper.\n try {\n if (document.queryCommandState('bold')) next.add('bold');\n if (document.queryCommandState('italic')) next.add('italic');\n if (document.queryCommandState('underline')) next.add('underline');\n if (document.queryCommandState('strikeThrough')) next.add('strike');\n if (document.queryCommandState('insertUnorderedList')) next.add('ul');\n if (document.queryCommandState('insertOrderedList')) next.add('ol');\n const block = String(\n document.queryCommandValue('formatBlock') || '',\n ).toLowerCase();\n // Add both the generic 'heading' token and the specific block tag\n // (h2/h3/quote/paragraph) so the toolbar's labelled style button can\n // show the active style by name.\n if (/^h[1-6]$/.test(block)) {\n next.add('heading');\n next.add(block);\n } else if (block === 'blockquote') {\n next.add('quote');\n } else {\n next.add('paragraph');\n }\n // Table context — drives the contextual table ops in the toolbar.\n const anchorEl =\n selection.anchorNode.nodeType === Node.TEXT_NODE\n ? selection.anchorNode.parentElement\n : (selection.anchorNode as Element | null);\n if (\n anchorEl &&\n root.contains(anchorEl) &&\n anchorEl.closest('table')\n ) {\n next.add('table');\n }\n } catch {\n /* queryCommand unsupported in this environment */\n }\n }\n setActiveFormats((prev) =>\n prev.size === next.size && [...next].every((f) => prev.has(f))\n ? prev\n : next,\n );\n }, []);\n\n // Run a Redactor command from the custom toolbar, then refresh active state.\n const runCommand = useCallback(\n (command: string, ...args: unknown[]): void => {\n dispatchWrite(command, ...args);\n // Defer the active-state read: let Redactor finish applying the command\n // and the selection settle first, otherwise un-toggling a format reads\n // the stale pre-change DOM and the button stays pressed.\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n } else {\n updateActiveFormats();\n }\n },\n [dispatchWrite, updateActiveFormats],\n );\n\n // Inline-format keyboard shortcuts (Cmd/Ctrl + B/I/U). Redactor ships these\n // natively, but with `toolbar: false` its shortcut fires yet silently no-ops\n // (it preventDefaults the key, then its inline.format applies nothing). So\n // the kit owns them: intercept on the editor in the capture phase — before\n // Redactor's own keydown listener — and route through the SAME runCommand\n // path the toolbar uses (which works). stopImmediatePropagation suppresses\n // Redactor's dead handler; preventDefault suppresses the browser's native\n // execCommand so the format applies exactly once.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return undefined;\n // Local key→command map (the same inline commands the toolbar buttons\n // fire) so this owns nothing on the public format API.\n const SHORTCUT_COMMANDS: Record<string, [string, ...unknown[]]> = {\n b: ['module.inline.format', { tag: 'b' }],\n i: ['module.inline.format', { tag: 'i' }],\n u: ['module.inline.format', { tag: 'u' }],\n };\n const onKeyDownCapture = (event: KeyboardEvent): void => {\n if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey)\n return;\n if (event.isComposing) return;\n const command = SHORTCUT_COMMANDS[event.key.toLowerCase()];\n if (!command) return;\n // Only when the caret is in this editor's editable, and it's writable.\n const editable = wrapper.querySelector('.redactor-in');\n if (\n !editable ||\n !(event.target instanceof Node) ||\n !editable.contains(event.target) ||\n readOnlyRef.current\n )\n return;\n event.preventDefault();\n event.stopImmediatePropagation();\n runCommand(...command);\n };\n wrapper.addEventListener('keydown', onKeyDownCapture, true);\n return () =>\n wrapper.removeEventListener('keydown', onKeyDownCapture, true);\n }, [runCommand]);\n\n // Insert sanitised HTML at the caret — the toolbar's link/image dialogs use\n // this (DOMPurify runs inside insertAtCursor) instead of Redactor's native\n // modals.\n const insertHtml = useCallback(\n (html: string): void => {\n insertAtCursor(html, { asHtml: true });\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [insertAtCursor, updateActiveFormats],\n );\n\n // Save / restore the editor selection around a DS popover/dialog (which\n // takes focus and would otherwise collapse the caret). Backed by Redactor's\n // selection module; no-ops in the degraded textarea.\n const saveSelection = useCallback((): void => {\n // Snapshot the current in-editor range synchronously (before a trigger's\n // focus move can collapse it), in addition to the observe-driven tracking.\n if (typeof window !== 'undefined') {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const sel = window.getSelection();\n if (\n root &&\n sel &&\n sel.rangeCount > 0 &&\n sel.anchorNode &&\n root.contains(sel.anchorNode)\n ) {\n lastRangeRef.current = sel.getRangeAt(0).cloneRange();\n }\n }\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'selection.save');\n } catch {\n /* selection module unavailable */\n }\n }\n }, [selector]);\n\n const restoreSelection = useCallback((): void => {\n const R = redactorRef.current;\n if (!R) return;\n // Re-focus the editor, then re-apply the tracked DOM range. This is more\n // reliable than Redactor's marker-based restore when a modal's focus trap\n // moved focus before the markers were set — without an active selection\n // Redactor's insertHtml wraps the insert in a new <p> (the link/image\n // \"block\" bug). Fall back to the marker restore if no range was tracked.\n // Capture the tracked range BEFORE editor.focus: focusing fires Redactor's\n // `observe`, which runs updateActiveFormats and overwrites lastRangeRef with\n // the post-focus caret (editor start). Reading it first preserves the\n // user's real selection (otherwise colour/link land at the top of the doc).\n const range = lastRangeRef.current;\n try {\n R(selector, 'editor.focus');\n } catch {\n /* ignore */\n }\n if (range && typeof window !== 'undefined') {\n const sel = window.getSelection();\n if (sel) {\n try {\n sel.removeAllRanges();\n sel.addRange(range);\n return;\n } catch {\n /* range no longer valid — fall through to marker restore */\n }\n }\n }\n try {\n R(selector, 'selection.restore');\n } catch {\n /* selection module unavailable */\n }\n }, [selector]);\n\n // Current selected text (for prefilling the link dialog's text field).\n const getSelectedText = useCallback((): string => {\n if (typeof window === 'undefined') return '';\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n if (\n !root ||\n !selection ||\n !selection.anchorNode ||\n !root.contains(selection.anchorNode)\n ) {\n return '';\n }\n return selection.toString();\n }, []);\n\n // The <table> the caret is currently inside (scoped to THIS editor's\n // `.redactor-in`), or null — drives the floating in-cell table toolbar's\n // visibility + anchor. Mirrors the table detection in updateActiveFormats.\n const getActiveTableEl = useCallback((): HTMLElement | null => {\n if (typeof window === 'undefined') return null;\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n if (!root || !selection || selection.rangeCount === 0) return null;\n const node = selection.anchorNode;\n const el =\n node && node.nodeType === Node.TEXT_NODE\n ? node.parentElement\n : (node as Element | null);\n if (!el || !root.contains(el)) return null;\n return el.closest('table');\n }, []);\n\n // The <td>/<th> the caret is in (scoped to this editor) — backs the table\n // background-colour controls.\n const lastCellRef = useRef<HTMLElement | null>(null);\n const getActiveCellEl = useCallback((): HTMLElement | null => {\n if (typeof window === 'undefined') return null;\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n if (!root || !selection || selection.rangeCount === 0) return null;\n const node = selection.anchorNode;\n const el =\n node && node.nodeType === Node.TEXT_NODE\n ? node.parentElement\n : (node as Element | null);\n if (!el || !root.contains(el)) return null;\n return el.closest('td,th') as HTMLElement | null;\n }, []);\n\n // Snapshot the current cell before a colour popover steals focus.\n const saveTableCell = useCallback((): void => {\n lastCellRef.current = getActiveCellEl();\n }, [getActiveCellEl]);\n\n // Apply (colour) or clear (colour === null) a background on the saved cell,\n // or every cell in its row. Redactor has no cell-styling command, so this\n // mutates the editable DOM directly, takes a best-effort undo snapshot, then\n // hard-syncs so the change lands in the source + fires `changed` → onChange.\n const applyTableBackground = useCallback(\n (scope: 'cell' | 'row', colour: string | null): void => {\n const cell = lastCellRef.current ?? getActiveCellEl();\n if (!cell) return;\n const targets: HTMLElement[] =\n scope === 'row'\n ? Array.from(cell.closest('tr')?.children ?? [cell]).filter(\n (n): n is HTMLElement =>\n n instanceof HTMLElement &&\n (n.tagName === 'TD' || n.tagName === 'TH'),\n )\n : [cell];\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'module.buffer.trigger');\n } catch {\n /* undo buffer unavailable — colour still applies */\n }\n }\n for (const el of targets) {\n if (colour) el.style.setProperty('background-color', colour);\n else el.style.removeProperty('background-color');\n }\n if (R) {\n try {\n R(selector, 'broadcast', 'hardsync');\n } catch {\n /* sync unavailable */\n }\n }\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [getActiveCellEl, selector, updateActiveFormats],\n );\n\n // Track which image is selected: a click inside the editable selects the\n // clicked <img> (or clears when it lands on non-image content); Escape\n // deselects; focus leaving the whole editor clears. Clicks on the floating\n // controls (outside `.redactor-in`) keep the current selection so its bar\n // stays reachable. Scoped to THIS editor's wrapper.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (typeof window === 'undefined' || !wrapper) return undefined;\n const onClick = (event: MouseEvent): void => {\n const editable = wrapper.querySelector('.redactor-in');\n const target = event.target;\n if (\n !editable ||\n !(target instanceof Node) ||\n !editable.contains(target)\n )\n return;\n const img = target instanceof Element ? target.closest('img') : null;\n selectImage(img && editable.contains(img) ? img : null);\n };\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape' && activeImageElRef.current) {\n selectImage(null);\n }\n };\n const onFocusOut = (event: FocusEvent): void => {\n const next = event.relatedTarget;\n if (!(next instanceof Node) || !wrapper.contains(next)) {\n selectImage(null);\n }\n };\n wrapper.addEventListener('click', onClick);\n wrapper.addEventListener('keydown', onKeyDown);\n wrapper.addEventListener('focusout', onFocusOut);\n return () => {\n wrapper.removeEventListener('click', onClick);\n wrapper.removeEventListener('keydown', onKeyDown);\n wrapper.removeEventListener('focusout', onFocusOut);\n };\n }, [selectImage]);\n\n // Apply (or replace) a `wysiwyg-img-*` layout class within its group on the\n // selected image. Mirrors applyTableBackground: snapshot undo, mutate the\n // editable DOM directly (Redactor has no image-class command), then hard-\n // sync so the change lands in the source + fires `changed` → onChange.\n const applyImageClass = useCallback(\n (className: string): void => {\n const img = activeImageElRef.current;\n if (!img) return;\n const group = (IMAGE_FLOW_CLASSES as readonly string[]).includes(\n className,\n )\n ? IMAGE_FLOW_CLASSES\n : IMAGE_ALIGN_CLASSES;\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'module.buffer.trigger');\n } catch {\n /* undo buffer unavailable — class still applies */\n }\n }\n for (const c of group) img.classList.remove(c);\n img.classList.add(className);\n if (R) {\n try {\n R(selector, 'broadcast', 'hardsync');\n } catch {\n /* sync unavailable */\n }\n }\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [selector, updateActiveFormats],\n );\n\n // Set the selected image's width as a % of its editable box. The width is\n // an inline style (the only continuous-value carrier; survives the rich-\n // text DOMPurify profile) — same runtime-DOM-mutation seam as the table\n // colour control, not a JSX inline style.\n const setImageWidth = useCallback(\n (pct: number): void => {\n const img = activeImageElRef.current;\n if (!img) return;\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'module.buffer.trigger');\n } catch {\n /* undo buffer unavailable — width still applies */\n }\n }\n img.style.setProperty('width', `${pct}%`);\n if (R) {\n try {\n R(selector, 'broadcast', 'hardsync');\n } catch {\n /* sync unavailable */\n }\n }\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [selector, updateActiveFormats],\n );\n\n // Insert a table, but never inside a list item — tables can't live in an\n // <li> and the nested markup hides the table UI. When the caret is in a\n // list, drop it after the whole list so the table lands as its own block.\n const insertTable = useCallback(\n (html: string): void => {\n const R = redactorRef.current;\n if (R && typeof window !== 'undefined') {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n const node = selection?.anchorNode;\n const el =\n node && node.nodeType === Node.TEXT_NODE\n ? node.parentElement\n : (node as Element | null);\n const list = el && root?.contains(el) ? el.closest('ul,ol') : null;\n if (list) {\n try {\n R(selector, 'caret.setAfter', list);\n } catch {\n /* caret module unavailable — falls back to cursor insert */\n }\n }\n }\n insertHtml(html);\n // Redactor's insertion leaves a stray trailing whitespace text node in\n // the final cell (<td><br> </td>); that space renders as a second line\n // and makes the last row taller WHILE EDITING. The saved source is\n // already clean (cleaner.output strips it), so just tidy the live\n // editable so every row renders at one line.\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n root?.querySelectorAll('table td, table th').forEach((cell) => {\n let last = cell.lastChild;\n while (\n last &&\n last.nodeType === Node.TEXT_NODE &&\n !(last.textContent ?? '').trim()\n ) {\n const prev = last.previousSibling;\n cell.removeChild(last);\n last = prev;\n }\n });\n });\n }\n },\n [insertHtml, selector],\n );\n\n // Upload an image file to the consumer's endpoint (mirrors Redactor's\n // imageUpload config) and resolve the stored URL — the image dialog's\n // upload tab uses this so users can upload, not just paste a URL.\n const uploadImage = useCallback(\n async (file: File, signal?: AbortSignal): Promise<string> => {\n if (!imageUploadUrl) throw new Error('No image upload URL configured.');\n const form = new FormData();\n form.append('file', file);\n const res = await fetch(imageUploadUrl, {\n method: 'POST',\n body: form,\n credentials: 'same-origin',\n signal,\n });\n if (!res.ok) throw new Error(`Image upload failed (${res.status}).`);\n const url = extractUploadedUrl(await res.json());\n if (!url) throw new Error('Image upload response contained no URL.');\n return url;\n },\n [imageUploadUrl],\n );\n\n /* ---- Voice dictation (DS UI; consumer runs mic + transcription) - */\n const dictateAbortRef = useRef<AbortController | null>(null);\n const interimRef = useRef<HTMLElement | null>(null);\n const [isDictating, setIsDictating] = useState(false);\n const [dictationErrored, setDictationErrored] = useState(false);\n // Drives the visually-hidden live region: announces the listening status on\n // start and each committed phrase as it lands, so screen-reader users get\n // the same feedback sighted users get from the grey interim span + caret.\n const [dictationAnnouncement, setDictationAnnouncement] = useState('');\n\n // Live (interim) speech shown in the editor as a grey, non-editable span\n // with a blinking caret; replaced by committed text on each final phrase.\n const clearInterim = useCallback((): void => {\n const el = interimRef.current;\n if (el?.parentNode) el.parentNode.removeChild(el);\n interimRef.current = null;\n }, []);\n\n const showInterim = useCallback((text: string): void => {\n const root = wrapperRef.current?.querySelector(\n '.redactor-in',\n ) as HTMLElement | null;\n if (!root) return;\n let el = interimRef.current;\n if (!el || !root.contains(el)) {\n el = document.createElement('span');\n el.setAttribute('data-rte-interim', '');\n el.setAttribute('contenteditable', 'false');\n const selection = window.getSelection();\n if (\n selection &&\n selection.rangeCount > 0 &&\n root.contains(selection.anchorNode)\n ) {\n const range = selection.getRangeAt(0);\n range.collapse(false);\n range.insertNode(el);\n } else {\n root.appendChild(el);\n }\n interimRef.current = el;\n }\n el.textContent = text;\n }, []);\n\n const stopDictation = useCallback(() => {\n // Abort but keep the ref: the in-flight session's `.finally` clears it\n // (and resets state) only when it's still the current session, so a normal\n // stop resets while a stale settle after a newer start does not.\n dictateAbortRef.current?.abort();\n }, []);\n\n const startDictation = useCallback(() => {\n if (!onDictate) return;\n const controller = new AbortController();\n dictateAbortRef.current = controller;\n setDictationErrored(false);\n setIsDictating(true);\n setDictationAnnouncement(t('editor.ai.listening'));\n clearInterim();\n onDictate({\n signal: controller.signal,\n // Interim text shows live in the editor (grey + caret); each final\n // replaces it with committed text at the caret.\n onPartialTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n showInterim(text);\n },\n onFinalTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n clearInterim();\n const trimmed = text.trim();\n if (trimmed) {\n insertAtCursor(`${trimmed} `, { asHtml: false });\n // Announce the committed phrase; it replaces the interim text the\n // SR could not perceive (the grey span is aria-hidden DOM injected\n // outside React's tree).\n setDictationAnnouncement(trimmed);\n }\n },\n })\n .catch((err: unknown) => {\n if (\n controller.signal.aborted ||\n (err &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name?: string }).name === 'AbortError')\n ) {\n return;\n }\n setDictationErrored(true);\n })\n .finally(() => {\n clearInterim();\n // Only the session that still owns the ref resets state — a stale\n // settle (a newer session already started) must not clobber it.\n if (dictateAbortRef.current === controller) {\n dictateAbortRef.current = null;\n setIsDictating(false);\n setDictationAnnouncement('');\n }\n });\n }, [onDictate, insertAtCursor, clearInterim, showInterim, t]);\n\n const toggleDictation = useCallback(() => {\n if (isDictating) stopDictation();\n else startDictation();\n }, [isDictating, startDictation, stopDictation]);\n\n // Abort dictation on unmount.\n useEffect(() => () => dictateAbortRef.current?.abort(), []);\n\n /* ---- One-shot AI document actions (proofread / auto-format) ---- */\n // Which one-shot action is running (drives the FAB spinner + the editor's\n // disabled scrim); only one runs at a time.\n const [oneShot, setOneShot] = useState<'proofread' | 'format' | null>(null);\n const oneShotAbortRef = useRef<AbortController | null>(null);\n const runOneShot = useCallback(\n (\n kind: 'proofread' | 'format',\n fn: (ctx: { html: string; signal: AbortSignal }) => Promise<string>,\n ): void => {\n if (oneShotAbortRef.current) return; // one at a time\n const controller = new AbortController();\n oneShotAbortRef.current = controller;\n setOneShot(kind);\n const html = readCode();\n Promise.resolve(fn({ html, signal: controller.signal }))\n .then((result) => {\n if (controller.signal.aborted) return;\n // Replace the whole document with the rewritten HTML (re-sanitised\n // at the editor seam) and notify the consumer.\n const safe = sanitiseHtml(String(result ?? ''));\n dispatchWrite('source.setCode', safe);\n onChangeRef.current?.({ html: safe, markdown: '' });\n })\n .catch(() => {\n /* abort / backend error — leave the document unchanged */\n })\n .finally(() => {\n if (oneShotAbortRef.current === controller) {\n oneShotAbortRef.current = null;\n setOneShot(null);\n }\n });\n },\n [readCode, dispatchWrite],\n );\n\n // Cancel a running one-shot. Clears the UI immediately (and aborts the\n // signal) rather than waiting on the promise, so the user always recovers\n // even if the consumer's call ignores the signal / hangs — the settle\n // guards (aborted + ref identity) then make the late result a no-op.\n const cancelOneShot = useCallback((): void => {\n oneShotAbortRef.current?.abort();\n oneShotAbortRef.current = null;\n setOneShot(null);\n }, []);\n\n // Abort an in-flight one-shot on unmount.\n useEffect(() => () => oneShotAbortRef.current?.abort(), []);\n\n /* ---- Init Redactor once (or degrade gracefully) -------------- */\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return undefined;\n // Seed the host textarea imperatively: Redactor reads it on init, and in\n // degraded mode it stays as the textarea's shown value. (Done here, not\n // via `defaultValue`, because `degraded` flips after mount so a\n // `defaultValue` prop would never apply.)\n ta.value = initialContentRef.current;\n const R = resolveRedactor(redactor);\n if (!R) {\n setDegraded(true);\n if (import.meta.env.DEV) {\n console.warn(\n '[RichTextEditor] Redactor not found on window.$R / window.Redactor and no `redactor` prop supplied; rendering a plain textarea.',\n );\n }\n return undefined;\n }\n redactorRef.current = R;\n\n const kitDefaults: Record<string, unknown> = {\n lang: lang ?? toRedactorLang(i18n.language || 'en'),\n // The kit renders its OWN toolbar (EditorToolbar) and drives Redactor\n // via the command API, so Redactor's native toolbar is suppressed.\n toolbar: false,\n plugins: plugins ?? [],\n placeholder: placeholder ?? t('editor.placeholder'),\n toolbarFixed: false,\n // Platform parity (RedactorWysiwyg.js:84): no inline shortcode expansion.\n shortcodes: false,\n // The kit owns image editing: ImageFloatingToolbar provides DS-native,\n // keyboard-accessible resize + wrap/align, so Redactor's own image\n // popup AND its single-handle drag-resizer are both disabled to avoid a\n // second, untokenised, mouse-only UI competing with ours.\n imageEditable: false,\n imageResizable: false,\n };\n const imageUploadOption = imageUploadUrl\n ? { imageUpload: imageUploadUrl }\n : {};\n\n const consumerCallbacks =\n (options?.callbacks as Record<string, unknown> | undefined) ?? {};\n\n const finalOptions: Record<string, unknown> = {\n ...kitDefaults,\n ...imageUploadOption,\n ...(options ?? {}),\n // Re-pin safety-critical keys LAST so consumer `options` can't override\n // the sanitising change handler or re-enable Redactor's native image UI\n // (the kit's ImageFloatingToolbar replaces both — see kitDefaults above).\n imageEditable: false,\n imageResizable: false,\n callbacks: {\n ...consumerCallbacks,\n changed(html: string): void {\n const normalized = normalizeEditorValue(withLazyImages(html));\n const safe = sanitiseHtml(normalized);\n skipNextPropSyncRef.current = true;\n if (!onChangeRef.current) return;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n onChangeRef.current?.({ html: safe, markdown: '' });\n }, 100);\n },\n keydown(event: KeyboardEvent): void {\n onKeyDownRef.current?.(event);\n },\n observe(): void {\n updateActiveFormats();\n },\n },\n };\n\n try {\n R(selector, finalOptions);\n // Redactor's read-only commands are camel-cased `enableReadOnly` /\n // `disableReadOnly` in this build (lower-case `enableReadonly` is a\n // silent no-op). Guarded so an unknown command stays inert.\n if (readOnly) {\n try {\n R(selector, 'enableReadOnly');\n } catch {\n /* readonly command unsupported in this Redactor build */\n }\n }\n } catch {\n setDegraded(true);\n }\n\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n try {\n // Platform forgets to destroy and leaks; we clean up on unmount.\n R(selector, 'destroy');\n } catch {\n /* already torn down */\n }\n redactorRef.current = null;\n };\n // Init once — option changes after mount are not re-applied (matches the\n // editor's uncontrolled-internals model); value/readOnly sync below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /* ---- Keep controlled `value` in sync (skip-once caret guard) - */\n useEffect(() => {\n if (!redactorRef.current || value === undefined) return;\n if (skipNextPropSyncRef.current) {\n skipNextPropSyncRef.current = false;\n return;\n }\n const safe = sanitiseHtml(normalizeEditorValue(value));\n const current = normalizeEditorValue(readCode());\n if (current !== safe) dispatchWrite('source.setCode', safe);\n }, [value, readCode, dispatchWrite]);\n\n /* ---- Keep readOnly in sync ----------------------------------- */\n useEffect(() => {\n readOnlyRef.current = readOnly;\n const R = redactorRef.current;\n if (!R) return;\n try {\n R(selector, readOnly ? 'enableReadOnly' : 'disableReadOnly');\n } catch {\n /* readonly command unsupported in this Redactor build */\n }\n }, [readOnly, selector]);\n\n /* ---- Degraded fallback: reflect controlled `value` ----------- */\n // Without Redactor the host textarea is uncontrolled (seeded once on init),\n // so it would otherwise ignore external `value` updates. Sync imperatively\n // (a controlled `value=` would warn when `degraded` flips after mount), and\n // skip while focused so we never reset the user's caret mid-type.\n useEffect(() => {\n if (!degraded || value === undefined) return;\n const ta = textareaRef.current;\n if (!ta) return;\n const safe = sanitiseHtml(value);\n if (ta.value !== safe && document.activeElement !== ta) {\n ta.value = safe;\n }\n }, [degraded, value]);\n\n /* ---- Imperative handle --------------------------------------- */\n const handle = useMemo<RichTextEditorHandle>(\n () => ({\n getHTML(): string {\n return readCode();\n },\n getText(): string {\n return readCode()\n .replace(/<[^>]*>/g, ' ')\n .replace(/ /gi, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n },\n getMarkdown(): string {\n return '';\n },\n setContent(html: string): void {\n const safe = sanitiseHtml(html);\n if (dispatchWrite('source.setCode', safe)) return;\n if (textareaRef.current) textareaRef.current.value = safe;\n },\n insertAtCursor,\n applyFormat(format): void {\n const command = FORMAT_COMMANDS[format];\n if (command) runCommand(...command);\n },\n focus(): void {\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'editor.focus');\n return;\n } catch {\n /* fall through */\n }\n }\n textareaRef.current?.focus();\n },\n clear(): void {\n if (dispatchWrite('source.setCode', '')) return;\n if (textareaRef.current) textareaRef.current.value = '';\n },\n }),\n [selector, readCode, dispatchWrite, insertAtCursor, runCommand],\n );\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(richTextEditorAgent, handle, id);\n\n /* ---- Degraded-mode change handler ---------------------------- */\n const handleDegradedChange = useCallback(\n (event: ChangeEvent<HTMLTextAreaElement>): void => {\n onChangeRef.current?.({\n html: sanitiseHtml(event.target.value),\n markdown: '',\n });\n },\n [],\n );\n\n // Accessible name for the editing region — a dedicated label, not the\n // placeholder, so the region's name and its placeholder hint don't collide.\n const resolvedLabel = ariaLabel ?? t('editor.regionLabel');\n const resolvedPlaceholder = placeholder ?? t('editor.placeholder');\n\n /* ---- Normalise Redactor's editing-surface ARIA --------------- */\n // Redactor renders the surface as a role=\"presentation\" contenteditable and,\n // while empty, points aria-labelledby at its hidden voice region — invalid\n // ARIA (axe: aria-prohibited-attr, since aria-labelledby can't sit on a\n // presentational node). Promote it to a properly-named textbox and keep it\n // that way as Redactor toggles the placeholder state. Redactor's own kit\n // usages never hit this because they all seed content (no empty placeholder).\n useEffect(() => {\n if (degraded) return undefined;\n const editable = wrapperRef.current?.querySelector('.redactor-in');\n if (!editable) return undefined;\n const normalise = () => {\n if (editable.getAttribute('role') !== 'textbox')\n editable.setAttribute('role', 'textbox');\n if (editable.getAttribute('aria-multiline') !== 'true')\n editable.setAttribute('aria-multiline', 'true');\n if (editable.getAttribute('aria-label') !== resolvedLabel)\n editable.setAttribute('aria-label', resolvedLabel);\n if (editable.hasAttribute('aria-labelledby'))\n editable.removeAttribute('aria-labelledby');\n };\n normalise();\n const observer = new MutationObserver(normalise);\n observer.observe(editable, {\n attributes: true,\n attributeFilter: ['role', 'aria-labelledby'],\n });\n return () => observer.disconnect();\n }, [degraded, resolvedLabel]);\n\n // AI FAB segments — rendered as one pill in this order: dictation · spelling\n // & grammar · auto-format · Alia. The two one-shot actions show a spinner\n // while running; everything else is disabled meanwhile.\n const busy = oneShot !== null;\n const fabSegments: {\n key: string;\n icon: ReactNode;\n label: string;\n onClick: () => void;\n recording?: boolean;\n running?: boolean;\n }[] = [];\n if (onDictate) {\n fabSegments.push({\n key: 'dictate',\n icon: isDictating ? (\n <Square aria-hidden=\"true\" className=\"ds:size-5 ds:fill-current\" />\n ) : (\n <Mic aria-hidden=\"true\" className=\"ds:size-5\" />\n ),\n label: isDictating\n ? t('editor.ai.dictateStop')\n : t('editor.ai.dictateStart'),\n onClick: toggleDictation,\n recording: isDictating,\n });\n }\n if (onProofread) {\n fabSegments.push({\n key: 'proofread',\n // While running, the segment becomes a STOP/cancel button (progress is\n // shown by the scrim spinner).\n icon:\n oneShot === 'proofread' ? (\n <Square aria-hidden=\"true\" className=\"ds:size-5 ds:fill-current\" />\n ) : (\n <SpellCheck aria-hidden=\"true\" className=\"ds:size-5\" />\n ),\n label:\n oneShot === 'proofread'\n ? t('common.cancel')\n : t('editor.ai.proofread', 'Check spelling & grammar'),\n onClick:\n oneShot === 'proofread'\n ? cancelOneShot\n : () => runOneShot('proofread', onProofread),\n running: oneShot === 'proofread',\n });\n }\n if (onAutoFormat) {\n fabSegments.push({\n key: 'format',\n icon:\n oneShot === 'format' ? (\n <Square aria-hidden=\"true\" className=\"ds:size-5 ds:fill-current\" />\n ) : (\n <WandSparkles aria-hidden=\"true\" className=\"ds:size-5\" />\n ),\n label:\n oneShot === 'format'\n ? t('common.cancel')\n : t('editor.ai.autoFormat', 'Auto-format document'),\n onClick:\n oneShot === 'format'\n ? cancelOneShot\n : () => runOneShot('format', onAutoFormat),\n running: oneShot === 'format',\n });\n }\n if (onRequestAiDraft) {\n fabSegments.push({\n key: 'write',\n icon: <Astroid aria-hidden=\"true\" className=\"ds:size-5\" />,\n label: t('editor.ai.helpMeWrite'),\n onClick: () => {\n saveSelection();\n setAiOpen(true);\n },\n });\n }\n\n return (\n <div\n ref={wrapperRef}\n className={[wrapperVariants(), className].filter(Boolean).join(' ')}\n data-component=\"rich-text-editor\"\n data-component-id={id}\n data-min-height={minHeight}\n >\n {!degraded && !readOnly ? (\n <EditorToolbar\n run={runCommand}\n active={activeFormats}\n preset={toolbar}\n insertHtml={insertHtml}\n insertTable={insertTable}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n getSelectedText={getSelectedText}\n uploadImage={imageUploadUrl ? uploadImage : undefined}\n enableColor={plugins?.includes('fontcolor') ?? false}\n enableImage={Boolean(imageUploadUrl)}\n enableTable={plugins?.includes('table') ?? false}\n showExtensions={showExtensions}\n />\n ) : null}\n <div className=\"ds:relative\" ref={editorAreaRef}>\n <textarea\n ref={textareaRef}\n id={editorId}\n aria-label={resolvedLabel}\n aria-multiline=\"true\"\n aria-busy={busy || undefined}\n placeholder={resolvedPlaceholder}\n onChange={degraded ? handleDegradedChange : undefined}\n readOnly={degraded ? readOnly : undefined}\n className={degraded ? degradedTextareaVariants() : undefined}\n />\n {/* While a one-shot AI action runs, dim + block the editor (it's being\n rewritten) with a centred spinner; the running FAB segment turns\n into a Stop/Cancel button. */}\n {busy ? (\n <div\n aria-hidden=\"true\"\n className=\"ds:absolute ds:inset-0 ds:z-[5] ds:flex ds:items-center ds:justify-center ds:cursor-wait ds:rounded-[var(--radius-md)] ds:bg-[color-mix(in_srgb,var(--background)_40%,transparent)]\"\n >\n <Spinner size=\"lg\" variant=\"prism\" />\n </div>\n ) : null}\n {/* AI affordances — the FAB + Alia popout. Wrapped in a zero-height\n STICKY dock (its only children are absolute) so in a long document\n they ride the viewport's block-end instead of scrolling off at the\n editor's bottom; the FAB/overlay keep their absolute positioning,\n now anchored to this dock. */}\n <div className=\"ds:sticky ds:bottom-0 ds:z-10\">\n {fabSegments.length > 0 ? (\n <div className=\"ds:absolute ds:[inset-block-end:var(--spacing-md)] ds:[inset-inline-end:var(--spacing-md)] ds:z-10 ds:flex ds:items-center ds:overflow-hidden ds:rounded-full ds:bg-[var(--primary)] ds:bg-[image:var(--gradient-brand)] ds:shadow-[0_8px_24px_color-mix(in_srgb,var(--primary)_35%,transparent)]\">\n {fabSegments.map((seg, i) => (\n <Fragment key={seg.key}>\n {i > 0 ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:self-stretch ds:[inline-size:var(--border-width-sm)] ds:bg-[color-mix(in_srgb,var(--primary-foreground)_35%,transparent)]\"\n />\n ) : null}\n <button\n type=\"button\"\n onClick={seg.onClick}\n aria-pressed={seg.recording || undefined}\n aria-busy={seg.running || undefined}\n disabled={(busy && !seg.running) || undefined}\n aria-label={seg.label}\n title={seg.label}\n className={\n seg.recording ? fabSegmentRecording : fabSegmentIdle\n }\n >\n {seg.icon}\n </button>\n </Fragment>\n ))}\n </div>\n ) : null}\n {onRequestAiDraft ? (\n <HelpMeWriteOverlay\n open={aiOpen}\n onClose={() => setAiOpen(false)}\n onRequestAiDraft={onRequestAiDraft}\n onInsert={(draft) => {\n // Restore the caret saved when the FAB opened the overlay, so\n // the draft lands where the user was, not at the doc start.\n restoreSelection();\n insertAtCursor(draft, { asHtml: aiDraftFormat !== 'text' });\n }}\n previewAsHtml={aiDraftFormat !== 'text'}\n privacyNotice={aiPrivacyNotice}\n onDictate={onDictate}\n />\n ) : null}\n </div>\n {/* Rendered LAST inside the positioned container (after the Redactor-\n managed textarea/box) so its conditional mount never asks React to\n insertBefore the textarea, which Redactor moves into its own box\n (that would throw \"node ... is not a child of this node\"). */}\n {!degraded && !readOnly && (plugins?.includes('table') ?? false) ? (\n <TableFloatingToolbar\n active={activeFormats}\n run={runCommand}\n areaRef={editorAreaRef}\n getActiveTableEl={getActiveTableEl}\n enableColor={plugins?.includes('fontcolor') ?? false}\n saveTableCell={saveTableCell}\n applyTableBackground={applyTableBackground}\n />\n ) : null}\n {/* Image wrap / align / resize — appears when an image is selected.\n Works on any embedded image, so it's gated only on edit mode (not\n on a plugin). Rendered after the table bar for the same reason it\n is: never inserted before the Redactor-managed textarea. */}\n {!degraded && !readOnly ? (\n <ImageFloatingToolbar\n areaRef={editorAreaRef}\n activeImageEl={activeImageEl}\n applyImageClass={applyImageClass}\n setImageWidth={setImageWidth}\n />\n ) : null}\n </div>\n {onDictate ? (\n <p className=\"ds:sr-only\" role=\"status\" aria-live=\"polite\">\n {dictationAnnouncement}\n </p>\n ) : null}\n {onDictate && dictationErrored ? (\n <p\n role=\"alert\"\n className=\"ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--destructive)]\"\n >\n {t('editor.ai.dictationError')}\n </p>\n ) : null}\n </div>\n );\n },\n);\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport { wrapperVariants };\n"],"names":["__iconNode","Baseline","createLucideIcon","BetweenHorizontalEnd","BetweenHorizontalStart","BetweenVerticalEnd","BetweenVerticalStart","Bold","Columns2","Heading2","Heading3","Italic","Link","ListOrdered","List","PaintBucket","PaintRoller","Palette","PanelLeft","PanelRight","PanelTopDashed","PanelTop","Pilcrow","Quote","Rows2","SpellCheck","Strikethrough","Table","TextAlignCenter","TextAlignEnd","TextAlignStart","Underline","WandSparkles","Wrench","richTextEditorAgent","handle","args","RECORDING_MIC","ACTION_SIZE","noticeClass","errorClass","previewClass","joinWith","base","extra","HelpMeWriteOverlay","open","onClose","onRequestAiDraft","onInsert","previewAsHtml","privacyNotice","onDictate","t","useTranslation","promptId","useId","errorId","prompt","setPrompt","useState","loading","setLoading","errored","setErrored","draft","setDraft","abortRef","useRef","isDictating","setIsDictating","interim","setInterim","dictationAnnouncement","setDictationAnnouncement","dictateAbortRef","stopDictation","useCallback","_a","startDictation","controller","text","trimmed","p","toggleDictation","useEffect","_b","generate","result","err","insert","hasDraft","fieldValue","jsx","EditorOverlay","jsxs","IconButton","X","SafeHtml","RotateCcw","Check","Fragment","TextArea","event","Square","Mic","Spinner","Send","ITEMS","FORMAT_OPTIONS","PRESETS","TABLE_OPS","Trash2","TABLE_GRID","toolbarClass","cva","toolbarRowClass","dividerClass","fieldLabelClass","esc","value","StyleMenu","run","active","onTriggerDown","current","o","DropdownMenu","Button","ChevronDown","opt","LinkDialog","insertHtml","saveSelection","restoreSelection","getSelectedText","setOpen","url","setUrl","setText","newTab","setNewTab","urlId","textId","reset","handleInsert","href","label","tab","html","Dialog","LinkIcon","TextInput","Checkbox","checked","ImageDialog","uploadImage","src","setSrc","alt","setAlt","srcId","altId","insertImage","altText","ImageIcon","FileUpload","file","signal","ColourControl","colour","setColour","applyColour","hex","removeColour","Popover","ColorPicker","HighlightControl","applyHighlight","removeHighlight","Highlighter","buildTable","rows","cols","cells","TableControl","insertTable","hover","setHover","inTable","TableIcon","op","_","i","r","c","on","TABLE_OP_BY_ID","tableFloatClass","TABLE_BG_SEED","TableBgColourControl","scope","icon","onOpenChange","saveTableCell","applyTableBackground","TableFloatingToolbar","areaRef","getActiveTableEl","enableColor","pos","setPos","colourOpenCount","colourOpen","setColourOpen","handleColourOpenChange","recompute","area","table","a","rtl","top","center","ro","groups","TooltipProvider","group","gi","opId","IMAGE_FLOW_CLASSES","IMAGE_ALIGN_CLASSES","selectedImageClass","el","imageWidthPercent","img","box","boxWidth","imgWidth","IMG_MAX_PCT","IMG_MIN_PCT","IMG_STEP","IMG_STEP_COARSE","clampPct","pct","IMAGE_FLOW_OPS","IMAGE_ALIGN_OPS","IMAGE_CORNERS","imageFrameClass","imageHandleClass","imageBarClass","ImageFloatingToolbar","applyImageClass","setImageWidth","dragRef","start","barTop","editable","mo","onHandlePointerDown","corner","onHandlePointerMove","drag","deltaPct","onHandlePointerEnd","onHandleKeyDown","next","step","flowActive","alignActive","widthText","isActive","EditorToolbar","preset","enableImage","enableTable","showExtensions","keepSelection","has","id","btn","item","Divider","styleGroup","inlineNodes","hasPrimary","listsNodes","insertNodes","extensionNodes","secondarySubgroups","hasSecondary","renderSecondary","leadingDivider","index","Ellipsis","sanitiseHtml","input","sanitiseShared","normalizeEditorValue","normalized","contentWithoutTags","withLazyImages","extractUploadedUrl","data","rec","fromNode","node","resolveRedactor","injected","w","FORMAT_COMMANDS","REDACTOR_LANG","toRedactorLang","locale","wrapperVariants","degradedTextareaVariants","fabSegmentBase","fabSegmentIdle","fabSegmentRecording","RichTextEditor","forwardRef","defaultValue","onChange","toolbar","placeholder","readOnly","ariaLabel","minHeight","className","redactor","options","plugins","lang","imageUploadUrl","onKeyDown","aiDraftFormat","aiPrivacyNotice","onProofread","onAutoFormat","ref","i18n","rawId","editorId","useMemo","selector","textareaRef","redactorRef","skipNextPropSyncRef","readOnlyRef","wrapperRef","editorAreaRef","degraded","setDegraded","aiOpen","setAiOpen","activeFormats","setActiveFormats","activeImageElRef","activeImageEl","setActiveImageEl","selectImage","debounceRef","onChangeRef","onKeyDownRef","initialContentRef","raw","readCode","R","code","dispatchWrite","command","wasReadOnly","insertAtCursor","content","opts","asHtml","payload","ta","end","caret","lastRangeRef","updateActiveFormats","root","selection","block","anchorEl","prev","f","runCommand","wrapper","SHORTCUT_COMMANDS","onKeyDownCapture","sel","range","lastCellRef","getActiveCellEl","cell","targets","n","onClick","target","onFocusOut","list","last","form","res","interimRef","dictationErrored","setDictationErrored","clearInterim","showInterim","oneShot","setOneShot","oneShotAbortRef","runOneShot","kind","fn","safe","cancelOneShot","kitDefaults","imageUploadOption","consumerCallbacks","finalOptions","format","useImperativeHandle","useAgentRegistration","handleDegradedChange","resolvedLabel","resolvedPlaceholder","normalise","observer","busy","fabSegments","Astroid","seg"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]}
|
|
1
|
+
{"version":3,"file":"rich-text-editor-DARnq_6N.js","sources":["../../node_modules/lucide-react/dist/esm/icons/baseline.mjs","../../node_modules/lucide-react/dist/esm/icons/between-horizontal-end.mjs","../../node_modules/lucide-react/dist/esm/icons/between-horizontal-start.mjs","../../node_modules/lucide-react/dist/esm/icons/between-vertical-end.mjs","../../node_modules/lucide-react/dist/esm/icons/between-vertical-start.mjs","../../node_modules/lucide-react/dist/esm/icons/bold.mjs","../../node_modules/lucide-react/dist/esm/icons/columns-2.mjs","../../node_modules/lucide-react/dist/esm/icons/heading-2.mjs","../../node_modules/lucide-react/dist/esm/icons/heading-3.mjs","../../node_modules/lucide-react/dist/esm/icons/italic.mjs","../../node_modules/lucide-react/dist/esm/icons/link.mjs","../../node_modules/lucide-react/dist/esm/icons/list-ordered.mjs","../../node_modules/lucide-react/dist/esm/icons/list.mjs","../../node_modules/lucide-react/dist/esm/icons/paint-bucket.mjs","../../node_modules/lucide-react/dist/esm/icons/paint-roller.mjs","../../node_modules/lucide-react/dist/esm/icons/palette.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-left.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-right.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-top-dashed.mjs","../../node_modules/lucide-react/dist/esm/icons/panel-top.mjs","../../node_modules/lucide-react/dist/esm/icons/pilcrow.mjs","../../node_modules/lucide-react/dist/esm/icons/quote.mjs","../../node_modules/lucide-react/dist/esm/icons/rows-2.mjs","../../node_modules/lucide-react/dist/esm/icons/spell-check.mjs","../../node_modules/lucide-react/dist/esm/icons/strikethrough.mjs","../../node_modules/lucide-react/dist/esm/icons/table.mjs","../../node_modules/lucide-react/dist/esm/icons/text-align-center.mjs","../../node_modules/lucide-react/dist/esm/icons/text-align-end.mjs","../../node_modules/lucide-react/dist/esm/icons/text-align-start.mjs","../../node_modules/lucide-react/dist/esm/icons/underline.mjs","../../node_modules/lucide-react/dist/esm/icons/wand-sparkles.mjs","../../node_modules/lucide-react/dist/esm/icons/wrench.mjs","../../src/components/rich-text-editor/rich-text-editor.agent.ts","../../src/components/rich-text-editor/help-me-write-overlay.tsx","../../src/components/rich-text-editor/editor-toolbar.tsx","../../src/components/rich-text-editor/rich-text-editor.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: \"M4 20h16\", key: \"14thso\" }],\n [\"path\", { d: \"m6 16 6-12 6 12\", key: \"1b4byz\" }],\n [\"path\", { d: \"M8 12h8\", key: \"1wcyev\" }]\n];\nconst Baseline = createLucideIcon(\"baseline\", __iconNode);\n\nexport { __iconNode, Baseline as default };\n//# sourceMappingURL=baseline.mjs.map\n","/**\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 [\"rect\", { width: \"13\", height: \"7\", x: \"3\", y: \"3\", rx: \"1\", key: \"11xb64\" }],\n [\"path\", { d: \"m22 15-3-3 3-3\", key: \"26chmm\" }],\n [\"rect\", { width: \"13\", height: \"7\", x: \"3\", y: \"14\", rx: \"1\", key: \"k6ky7n\" }]\n];\nconst BetweenHorizontalEnd = createLucideIcon(\"between-horizontal-end\", __iconNode);\n\nexport { __iconNode, BetweenHorizontalEnd as default };\n//# sourceMappingURL=between-horizontal-end.mjs.map\n","/**\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 [\"rect\", { width: \"13\", height: \"7\", x: \"8\", y: \"3\", rx: \"1\", key: \"pkso9a\" }],\n [\"path\", { d: \"m2 9 3 3-3 3\", key: \"1agib5\" }],\n [\"rect\", { width: \"13\", height: \"7\", x: \"8\", y: \"14\", rx: \"1\", key: \"1q5fc1\" }]\n];\nconst BetweenHorizontalStart = createLucideIcon(\"between-horizontal-start\", __iconNode);\n\nexport { __iconNode, BetweenHorizontalStart as default };\n//# sourceMappingURL=between-horizontal-start.mjs.map\n","/**\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 [\"rect\", { width: \"7\", height: \"13\", x: \"3\", y: \"3\", rx: \"1\", key: \"1fdu0f\" }],\n [\"path\", { d: \"m9 22 3-3 3 3\", key: \"17z65a\" }],\n [\"rect\", { width: \"7\", height: \"13\", x: \"14\", y: \"3\", rx: \"1\", key: \"1squn4\" }]\n];\nconst BetweenVerticalEnd = createLucideIcon(\"between-vertical-end\", __iconNode);\n\nexport { __iconNode, BetweenVerticalEnd as default };\n//# sourceMappingURL=between-vertical-end.mjs.map\n","/**\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 [\"rect\", { width: \"7\", height: \"13\", x: \"3\", y: \"8\", rx: \"1\", key: \"1fjrkv\" }],\n [\"path\", { d: \"m15 2-3 3-3-3\", key: \"1uh6eb\" }],\n [\"rect\", { width: \"7\", height: \"13\", x: \"14\", y: \"8\", rx: \"1\", key: \"w3fjg8\" }]\n];\nconst BetweenVerticalStart = createLucideIcon(\"between-vertical-start\", __iconNode);\n\nexport { __iconNode, BetweenVerticalStart as default };\n//# sourceMappingURL=between-vertical-start.mjs.map\n","/**\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 [\n \"path\",\n { d: \"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\", key: \"mg9rjx\" }\n ]\n];\nconst Bold = createLucideIcon(\"bold\", __iconNode);\n\nexport { __iconNode, Bold as default };\n//# sourceMappingURL=bold.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }]\n];\nconst Columns2 = createLucideIcon(\"columns-2\", __iconNode);\n\nexport { __iconNode, Columns2 as default };\n//# sourceMappingURL=columns-2.mjs.map\n","/**\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: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1\", key: \"9jr5yi\" }]\n];\nconst Heading2 = createLucideIcon(\"heading-2\", __iconNode);\n\nexport { __iconNode, Heading2 as default };\n//# sourceMappingURL=heading-2.mjs.map\n","/**\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: \"M4 12h8\", key: \"17cfdx\" }],\n [\"path\", { d: \"M4 18V6\", key: \"1rz3zl\" }],\n [\"path\", { d: \"M12 18V6\", key: \"zqpxq5\" }],\n [\"path\", { d: \"M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2\", key: \"68ncm8\" }],\n [\"path\", { d: \"M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2\", key: \"1ejuhz\" }]\n];\nconst Heading3 = createLucideIcon(\"heading-3\", __iconNode);\n\nexport { __iconNode, Heading3 as default };\n//# sourceMappingURL=heading-3.mjs.map\n","/**\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 [\"line\", { x1: \"19\", x2: \"10\", y1: \"4\", y2: \"4\", key: \"15jd3p\" }],\n [\"line\", { x1: \"14\", x2: \"5\", y1: \"20\", y2: \"20\", key: \"bu0au3\" }],\n [\"line\", { x1: \"15\", x2: \"9\", y1: \"4\", y2: \"20\", key: \"uljnxc\" }]\n];\nconst Italic = createLucideIcon(\"italic\", __iconNode);\n\nexport { __iconNode, Italic as default };\n//# sourceMappingURL=italic.mjs.map\n","/**\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: \"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\", key: \"1cjeqo\" }],\n [\"path\", { d: \"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\", key: \"19qd67\" }]\n];\nconst Link = createLucideIcon(\"link\", __iconNode);\n\nexport { __iconNode, Link as default };\n//# sourceMappingURL=link.mjs.map\n","/**\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: \"M11 5h10\", key: \"1cz7ny\" }],\n [\"path\", { d: \"M11 12h10\", key: \"1438ji\" }],\n [\"path\", { d: \"M11 19h10\", key: \"11t30w\" }],\n [\"path\", { d: \"M4 4h1v5\", key: \"10yrso\" }],\n [\"path\", { d: \"M4 9h2\", key: \"r1h2o0\" }],\n [\"path\", { d: \"M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02\", key: \"xtkcd5\" }]\n];\nconst ListOrdered = createLucideIcon(\"list-ordered\", __iconNode);\n\nexport { __iconNode, ListOrdered as default };\n//# sourceMappingURL=list-ordered.mjs.map\n","/**\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: \"M3 5h.01\", key: \"18ugdj\" }],\n [\"path\", { d: \"M3 12h.01\", key: \"nlz23k\" }],\n [\"path\", { d: \"M3 19h.01\", key: \"noohij\" }],\n [\"path\", { d: \"M8 5h13\", key: \"1pao27\" }],\n [\"path\", { d: \"M8 12h13\", key: \"1za7za\" }],\n [\"path\", { d: \"M8 19h13\", key: \"m83p4d\" }]\n];\nconst List = createLucideIcon(\"list\", __iconNode);\n\nexport { __iconNode, List as default };\n//# sourceMappingURL=list.mjs.map\n","/**\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: \"M11 7 6 2\", key: \"1jwth8\" }],\n [\"path\", { d: \"M18.992 12H2.041\", key: \"xw1gg\" }],\n [\n \"path\",\n {\n d: \"M21.145 18.38A3.34 3.34 0 0 1 20 16.5a3.3 3.3 0 0 1-1.145 1.88c-.575.46-.855 1.02-.855 1.595A2 2 0 0 0 20 22a2 2 0 0 0 2-2.025c0-.58-.285-1.13-.855-1.595\",\n key: \"1nkol4\"\n }\n ],\n [\n \"path\",\n {\n d: \"m8.5 4.5 2.148-2.148a1.205 1.205 0 0 1 1.704 0l7.296 7.296a1.205 1.205 0 0 1 0 1.704l-7.592 7.592a3.615 3.615 0 0 1-5.112 0l-3.888-3.888a3.615 3.615 0 0 1 0-5.112L5.67 7.33\",\n key: \"1nk1rd\"\n }\n ]\n];\nconst PaintBucket = createLucideIcon(\"paint-bucket\", __iconNode);\n\nexport { __iconNode, PaintBucket as default };\n//# sourceMappingURL=paint-bucket.mjs.map\n","/**\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 [\"rect\", { width: \"16\", height: \"6\", x: \"2\", y: \"2\", rx: \"2\", key: \"jcyz7m\" }],\n [\"path\", { d: \"M10 16v-2a2 2 0 0 1 2-2h8a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2\", key: \"1b9h7c\" }],\n [\"rect\", { width: \"4\", height: \"6\", x: \"8\", y: \"16\", rx: \"1\", key: \"d6e7yl\" }]\n];\nconst PaintRoller = createLucideIcon(\"paint-roller\", __iconNode);\n\nexport { __iconNode, PaintRoller as default };\n//# sourceMappingURL=paint-roller.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z\",\n key: \"e79jfc\"\n }\n ],\n [\"circle\", { cx: \"13.5\", cy: \"6.5\", r: \".5\", fill: \"currentColor\", key: \"1okk4w\" }],\n [\"circle\", { cx: \"17.5\", cy: \"10.5\", r: \".5\", fill: \"currentColor\", key: \"f64h9f\" }],\n [\"circle\", { cx: \"6.5\", cy: \"12.5\", r: \".5\", fill: \"currentColor\", key: \"qy21gx\" }],\n [\"circle\", { cx: \"8.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"fotxhn\" }]\n];\nconst Palette = createLucideIcon(\"palette\", __iconNode);\n\nexport { __iconNode, Palette as default };\n//# sourceMappingURL=palette.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }]\n];\nconst PanelLeft = createLucideIcon(\"panel-left\", __iconNode);\n\nexport { __iconNode, PanelLeft as default };\n//# sourceMappingURL=panel-left.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M15 3v18\", key: \"14nvp0\" }]\n];\nconst PanelRight = createLucideIcon(\"panel-right\", __iconNode);\n\nexport { __iconNode, PanelRight as default };\n//# sourceMappingURL=panel-right.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M14 9h1\", key: \"l0svgy\" }],\n [\"path\", { d: \"M19 9h2\", key: \"te2zfg\" }],\n [\"path\", { d: \"M3 9h2\", key: \"1h4ldw\" }],\n [\"path\", { d: \"M9 9h1\", key: \"15jzuz\" }]\n];\nconst PanelTopDashed = createLucideIcon(\"panel-top-dashed\", __iconNode);\n\nexport { __iconNode, PanelTopDashed as default };\n//# sourceMappingURL=panel-top-dashed.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }]\n];\nconst PanelTop = createLucideIcon(\"panel-top\", __iconNode);\n\nexport { __iconNode, PanelTop as default };\n//# sourceMappingURL=panel-top.mjs.map\n","/**\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: \"M13 4v16\", key: \"8vvj80\" }],\n [\"path\", { d: \"M17 4v16\", key: \"7dpous\" }],\n [\"path\", { d: \"M19 4H9.5a4.5 4.5 0 0 0 0 9H13\", key: \"sh4n9v\" }]\n];\nconst Pilcrow = createLucideIcon(\"pilcrow\", __iconNode);\n\nexport { __iconNode, Pilcrow as default };\n//# sourceMappingURL=pilcrow.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"M16 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\",\n key: \"rib7q0\"\n }\n ],\n [\n \"path\",\n {\n d: \"M5 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2 1 1 0 0 1 1 1v1a2 2 0 0 1-2 2 1 1 0 0 0-1 1v2a1 1 0 0 0 1 1 6 6 0 0 0 6-6V5a2 2 0 0 0-2-2z\",\n key: \"1ymkrd\"\n }\n ]\n];\nconst Quote = createLucideIcon(\"quote\", __iconNode);\n\nexport { __iconNode, Quote as default };\n//# sourceMappingURL=quote.mjs.map\n","/**\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 [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }]\n];\nconst Rows2 = createLucideIcon(\"rows-2\", __iconNode);\n\nexport { __iconNode, Rows2 as default };\n//# sourceMappingURL=rows-2.mjs.map\n","/**\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: \"m6 16 6-12 6 12\", key: \"1b4byz\" }],\n [\"path\", { d: \"M8 12h8\", key: \"1wcyev\" }],\n [\"path\", { d: \"m16 20 2 2 4-4\", key: \"13tcca\" }]\n];\nconst SpellCheck = createLucideIcon(\"spell-check\", __iconNode);\n\nexport { __iconNode, SpellCheck as default };\n//# sourceMappingURL=spell-check.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 4H9a3 3 0 0 0-2.83 4\", key: \"43sutm\" }],\n [\"path\", { d: \"M14 12a4 4 0 0 1 0 8H6\", key: \"nlfj13\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"12\", y2: \"12\", key: \"1e0a9i\" }]\n];\nconst Strikethrough = createLucideIcon(\"strikethrough\", __iconNode);\n\nexport { __iconNode, Strikethrough as default };\n//# sourceMappingURL=strikethrough.mjs.map\n","/**\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 3v18\", key: \"108xh3\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }]\n];\nconst Table = createLucideIcon(\"table\", __iconNode);\n\nexport { __iconNode, Table as default };\n//# sourceMappingURL=table.mjs.map\n","/**\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: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M17 12H7\", key: \"16if0g\" }],\n [\"path\", { d: \"M19 19H5\", key: \"vjpgq2\" }]\n];\nconst TextAlignCenter = createLucideIcon(\"text-align-center\", __iconNode);\n\nexport { __iconNode, TextAlignCenter as default };\n//# sourceMappingURL=text-align-center.mjs.map\n","/**\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: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M21 12H9\", key: \"dn1m92\" }],\n [\"path\", { d: \"M21 19H7\", key: \"4cu937\" }]\n];\nconst TextAlignEnd = createLucideIcon(\"text-align-end\", __iconNode);\n\nexport { __iconNode, TextAlignEnd as default };\n//# sourceMappingURL=text-align-end.mjs.map\n","/**\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: \"M21 5H3\", key: \"1fi0y6\" }],\n [\"path\", { d: \"M15 12H3\", key: \"6jk70r\" }],\n [\"path\", { d: \"M17 19H3\", key: \"z6ezky\" }]\n];\nconst TextAlignStart = createLucideIcon(\"text-align-start\", __iconNode);\n\nexport { __iconNode, TextAlignStart as default };\n//# sourceMappingURL=text-align-start.mjs.map\n","/**\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: \"M6 4v6a6 6 0 0 0 12 0V4\", key: \"9kb039\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"20\", y2: \"20\", key: \"nun2al\" }]\n];\nconst Underline = createLucideIcon(\"underline\", __iconNode);\n\nexport { __iconNode, Underline as default };\n//# sourceMappingURL=underline.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n];\nconst WandSparkles = createLucideIcon(\"wand-sparkles\", __iconNode);\n\nexport { __iconNode, WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.mjs.map\n","/**\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 [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\",\n key: \"1ngwbx\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.mjs.map\n","import type { AgentAdapter } from '../../agent/types';\nimport type { EditorFormat, RichTextEditorHandle } from './rich-text-editor';\n\nexport const richTextEditorAgent: AgentAdapter<RichTextEditorHandle> = {\n id: 'rich-text-editor',\n capabilities: ['edit_inline'],\n state: {\n html: {\n type: 'string',\n descriptionKey: 'ui.agent.richTextEditor.state.html',\n description: 'Sanitised HTML representation of the editor content.',\n read: (handle) => handle.getHTML(),\n },\n text: {\n type: 'string',\n descriptionKey: 'ui.agent.richTextEditor.state.text',\n description: 'Plain-text content of the editor (tags stripped).',\n read: (handle) => handle.getText(),\n },\n markdown: {\n type: 'string',\n descriptionKey: 'ui.agent.richTextEditor.state.markdown',\n description:\n 'Markdown representation of the editor content. The Redactor engine has no native Markdown serialiser, so this is always empty — read `html` instead.',\n read: (handle) => handle.getMarkdown(),\n },\n },\n // Image wrap/align/resize are intentionally NOT agent actions — they target\n // the ephemeral click-selected image the handle can't address. Agents emit\n // `<img class=\"wysiwyg-img-*\" style=\"width:N%\">` via set_content instead.\n actions: {\n set_content: {\n // Replaces the whole document — discards whatever the user had typed.\n safety: 'destructive',\n argsType: '{ html: string }',\n argsSchema: {\n type: 'object',\n properties: {\n html: {\n type: 'string',\n description: 'Replacement HTML (sanitised via DOMPurify).',\n },\n },\n required: ['html'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.richTextEditor.actions.setContent',\n description: 'Replace the editor content. Loses unsaved input.',\n invoke: (handle, args: { html: string }) => {\n handle.setContent(args.html);\n },\n },\n insert_at_cursor: {\n // Reversible via the editor's own undo stack — write, not destructive.\n safety: 'write',\n argsType: '{ content: string; asHtml?: boolean }',\n argsSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'Content to insert at the caret.',\n },\n asHtml: {\n type: 'boolean',\n description:\n 'Treat content as HTML (sanitised). Pass false for plain text. Defaults to true.',\n },\n },\n required: ['content'],\n },\n descriptionKey: 'ui.agent.richTextEditor.actions.insertAtCursor',\n description:\n 'Insert content at the caret (replacing any selection). HTML is sanitised; pass asHtml:false for plain text. Seam for merge/template variables and AI-generated drafts.',\n examples: [\n {\n args: { content: '{{patient.firstName}}', asHtml: false },\n note: 'Insert a merge variable as plain text.',\n },\n ],\n invoke: (handle, args: { content: string; asHtml?: boolean }) => {\n handle.insertAtCursor(args.content, { asHtml: args.asHtml });\n },\n },\n apply_format: {\n // Reversible via undo — write, not destructive.\n safety: 'write',\n argsType:\n \"{ format: 'bold' | 'italic' | 'strikethrough' | 'bulletedList' | 'numberedList' | 'heading' | 'quote' | 'paragraph' }\",\n argsSchema: {\n type: 'object',\n properties: {\n format: {\n type: 'string',\n enum: [\n 'bold',\n 'italic',\n 'strikethrough',\n 'bulletedList',\n 'numberedList',\n 'heading',\n 'quote',\n 'paragraph',\n ],\n description: 'Block or inline format to toggle/apply.',\n },\n },\n required: ['format'],\n },\n descriptionKey: 'ui.agent.richTextEditor.actions.applyFormat',\n description:\n 'Toggle/apply a block or inline format on the current selection (bold, italic, strikethrough, bulleted/numbered list, heading, quote, paragraph).',\n examples: [{ args: { format: 'bold' }, note: 'Bold the selection.' }],\n invoke: (handle, args: { format: EditorFormat }) => {\n handle.applyFormat(args.format);\n },\n },\n clear: {\n // Empties the document — loses unsaved input.\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.richTextEditor.actions.clear',\n description: 'Empty the editor. Loses unsaved input.',\n invoke: (handle) => {\n handle.clear();\n },\n },\n focus: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.richTextEditor.actions.focus',\n description: 'Move keyboard focus to the editor surface.',\n invoke: (handle) => {\n handle.focus();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'rich-text-editor' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","/* ------------------------------------------------------------------ */\n/* HelpMeWriteOverlay — the \"Help me write\" flow on the non-modal */\n/* EditorOverlay (Gemini / Mac Mail style): a slim docked bar with a */\n/* one-row composer (mic · prompt · Write) → a preview of the draft with */\n/* Discard / Try again / Insert. */\n/* */\n/* The kit owns the UI; the backend call is the consumer's */\n/* `onRequestAiDraft({ prompt, signal })`. When `onDictate` is supplied */\n/* the composer grows a mic that streams transcripts INTO the prompt */\n/* (the same consumer dictation seam the editor FAB uses). The returned */\n/* draft is previewed (sanitised via SafeHtml) and only inserted on */\n/* confirm — sanitisation of the inserted value happens again at the */\n/* editor seam. */\n/* ------------------------------------------------------------------ */\n\nimport {\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Check, Mic, RotateCcw, Send, Square, X } from 'lucide-react';\n\nimport { IconButton } from '../button';\nimport { Spinner } from '../spinner';\nimport { TextArea } from '../text-area';\nimport { SafeHtml } from '../_shared/safe-html';\nimport { EditorOverlay } from '../editor-overlay';\n\nexport interface HelpMeWriteOverlayProps {\n open: boolean;\n onClose: () => void;\n onRequestAiDraft: (ctx: {\n prompt: string;\n signal: AbortSignal;\n }) => Promise<string>;\n onInsert: (draft: string) => void;\n /** Preview + insert the draft as HTML (default) or plain text. */\n previewAsHtml?: boolean;\n privacyNotice?: ReactNode;\n /**\n * Voice dictation into the prompt. Same seam as the editor's `onDictate`:\n * the consumer runs mic + transcription and pushes text back; the kit appends\n * finals to the prompt. When omitted, the composer shows no mic.\n */\n onDictate?: (ctx: {\n signal: AbortSignal;\n onPartialTranscript: (text: string) => void;\n onFinalTranscript: (text: string) => void;\n }) => Promise<void>;\n}\n\n// Force the recording mic solid-destructive (red). IconButton's base\n// `aria-pressed:bg-muted` (for IconButtonGroup toggles) would otherwise\n// out-specify the intent fill, so the override is marked important.\nconst RECORDING_MIC =\n 'ds:aria-pressed:!bg-[var(--destructive)] ds:aria-pressed:!text-[var(--destructive-foreground)]';\n\n// Pin the action buttons to the input's height (--min-target-size, 44/48px) so\n// the composer's input + mic + send line up exactly. IconButton md is h-10\n// (40px), below the TextArea md min-height, so force the match (important wins\n// over the size variant). Scales with the accessible theme for free.\nconst ACTION_SIZE = 'ds:!size-[var(--min-target-size)]';\n\nconst noticeClass =\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--muted-foreground)]';\nconst errorClass =\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--destructive)]';\nconst previewClass = [\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[color-mix(in_srgb,var(--background)_70%,transparent)]',\n 'ds:p-[var(--spacing-sm)] ds:[max-block-size:10rem] ds:overflow-y-auto',\n 'ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)]',\n // The preview renders arbitrary model-generated rich text, and the\n // `rich-text` SafeHtml profile allows ul/ol/li. Inside a\n // [data-component] preflight's list reset still applies and the host\n // undo deliberately does not reach, so markers and indent have to be\n // asked for explicitly — otherwise a generated bullet list previews as\n // flush, marker-less lines.\n 'ds:[&_ul]:list-disc ds:[&_ol]:list-decimal',\n 'ds:[&_ul]:ps-[var(--spacing-md)] ds:[&_ol]:ps-[var(--spacing-md)]',\n].join(' ');\n\n// Join a base string with appended dictation text, inserting a single space\n// only when the base doesn't already end in whitespace.\nfunction joinWith(base: string, extra: string): string {\n if (!extra) return base;\n if (!base) return extra;\n return /\\s$/.test(base) ? `${base}${extra}` : `${base} ${extra}`;\n}\n\nexport function HelpMeWriteOverlay({\n open,\n onClose,\n onRequestAiDraft,\n onInsert,\n previewAsHtml = true,\n privacyNotice,\n onDictate,\n}: HelpMeWriteOverlayProps): React.JSX.Element {\n const { t } = useTranslation();\n const promptId = useId();\n const errorId = useId();\n const [prompt, setPrompt] = useState('');\n const [loading, setLoading] = useState(false);\n const [errored, setErrored] = useState(false);\n const [draft, setDraft] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n\n /* ---- In-prompt voice dictation (consumer runs mic + STT) ---- */\n const [isDictating, setIsDictating] = useState(false);\n const [interim, setInterim] = useState('');\n // Drives the visually-hidden live region: announces the listening status on\n // start and each committed phrase as it lands. The interim text shows in the\n // read-only field, but SR users can't perceive a read-only value change, so\n // the polite region gives them the same feedback.\n const [dictationAnnouncement, setDictationAnnouncement] = useState('');\n const dictateAbortRef = useRef<AbortController | null>(null);\n\n const stopDictation = useCallback(() => {\n dictateAbortRef.current?.abort();\n }, []);\n\n const startDictation = useCallback(() => {\n if (!onDictate) return;\n const controller = new AbortController();\n dictateAbortRef.current = controller;\n setIsDictating(true);\n setInterim('');\n setDictationAnnouncement(t('editor.ai.listening'));\n onDictate({\n signal: controller.signal,\n onPartialTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n setInterim(text);\n },\n onFinalTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n const trimmed = text.trim();\n setInterim('');\n if (trimmed) {\n setPrompt((p) => joinWith(p, trimmed));\n setDictationAnnouncement(trimmed);\n }\n },\n })\n .catch(() => {\n /* dictation errors are non-fatal here — the user can type instead */\n })\n .finally(() => {\n setInterim('');\n if (dictateAbortRef.current === controller) {\n dictateAbortRef.current = null;\n setIsDictating(false);\n setDictationAnnouncement('');\n }\n });\n }, [onDictate, t]);\n\n const toggleDictation = useCallback(() => {\n if (isDictating) stopDictation();\n else startDictation();\n }, [isDictating, startDictation, stopDictation]);\n\n // Fresh state each time it opens; abort any in-flight request/dictation on close.\n useEffect(() => {\n if (open) {\n setPrompt('');\n setLoading(false);\n setErrored(false);\n setDraft(null);\n setInterim('');\n setDictationAnnouncement('');\n } else {\n abortRef.current?.abort();\n abortRef.current = null;\n dictateAbortRef.current?.abort();\n }\n }, [open]);\n useEffect(\n () => () => {\n abortRef.current?.abort();\n dictateAbortRef.current?.abort();\n },\n [],\n );\n\n const generate = useCallback(() => {\n const trimmed = prompt.trim();\n if (!trimmed || loading) return;\n stopDictation();\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n setErrored(false);\n setLoading(true);\n onRequestAiDraft({ prompt: trimmed, signal: controller.signal })\n .then((result) => {\n if (controller.signal.aborted) return;\n setDraft(result);\n setLoading(false);\n })\n .catch((err: unknown) => {\n if (\n controller.signal.aborted ||\n (err &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name?: string }).name === 'AbortError')\n ) {\n return;\n }\n setErrored(true);\n setLoading(false);\n });\n }, [prompt, loading, onRequestAiDraft, stopDictation]);\n\n const insert = useCallback(() => {\n if (draft == null) return;\n onInsert(draft);\n onClose();\n }, [draft, onInsert, onClose]);\n\n const hasDraft = draft != null;\n // While dictating, show committed prompt + live interim; the field is\n // read-only so the streamed text isn't fought over by onChange.\n const fieldValue = isDictating ? joinWith(prompt, interim) : prompt;\n\n return (\n <EditorOverlay\n open={open}\n onClose={onClose}\n ariaLabel={t('editor.ai.dialogTitle')}\n >\n {hasDraft ? (\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-sm)]\">\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={ACTION_SIZE}\n icon={<X />}\n aria-label={t('common.close')}\n onClick={onClose}\n />\n <div className=\"ds:min-w-0 ds:flex-1\">\n {previewAsHtml ? (\n <SafeHtml\n html={draft as string}\n profile=\"rich-text\"\n className={previewClass}\n tabIndex={0}\n aria-label={t('editor.ai.dialogTitle')}\n />\n ) : (\n // Focusable so a keyboard user can scroll a long draft preview\n // (mirrors the SafeHtml preview branch above). The lint rule's\n // tabIndex allowlist doesn't cover a scrollable, non-interactive\n // text region.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n <p className={previewClass} tabIndex={0}>\n {draft}\n </p>\n )}\n </div>\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={`${ACTION_SIZE} ds:rounded-full`}\n icon={<RotateCcw />}\n aria-label={t('editor.ai.retry')}\n onClick={() => setDraft(null)}\n />\n <IconButton\n size=\"md\"\n intent=\"primary\"\n className={`${ACTION_SIZE} ds:bg-[image:var(--gradient-brand)] ds:rounded-full`}\n icon={<Check />}\n aria-label={t('common.confirm')}\n onClick={insert}\n />\n </div>\n ) : (\n <>\n <div className=\"ds:flex ds:items-end ds:gap-[var(--spacing-sm)]\">\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={ACTION_SIZE}\n icon={<X />}\n aria-label={t('common.close')}\n onClick={onClose}\n />\n <div className=\"ds:min-w-0 ds:flex-1\">\n <TextArea\n id={promptId}\n size=\"md\"\n // Centre a single line within the min-height; when it grows to\n // multiple rows autoResize removes the slack so text fills from\n // the top as usual.\n className=\"ds:content-center\"\n value={fieldValue}\n onChange={(event) => setPrompt(event.target.value)}\n placeholder={t('editor.ai.promptPlaceholder')}\n aria-label={t('editor.ai.promptLabel')}\n autoResize\n minRows={1}\n maxRows={3}\n readOnly={isDictating}\n tone={errored ? 'error' : 'default'}\n aria-describedby={errored ? errorId : undefined}\n />\n </div>\n {onDictate ? (\n <IconButton\n size=\"md\"\n intent=\"outline\"\n className={\n isDictating ? `${ACTION_SIZE} ${RECORDING_MIC}` : ACTION_SIZE\n }\n icon={\n isDictating ? <Square className=\"ds:fill-current\" /> : <Mic />\n }\n aria-pressed={isDictating}\n aria-label={\n isDictating\n ? t('editor.ai.dictateStop')\n : t('editor.ai.dictateStart')\n }\n onClick={toggleDictation}\n />\n ) : null}\n <IconButton\n size=\"md\"\n intent=\"primary\"\n icon={loading ? <Spinner size=\"sm\" variant=\"pulse\" /> : <Send />}\n className={`${ACTION_SIZE} ds:bg-[image:var(--gradient-brand)] ds:rounded-full`}\n disabled={loading || !prompt.trim()}\n aria-busy={loading || undefined}\n aria-label={t('editor.ai.generate')}\n onClick={generate}\n />\n </div>\n {onDictate ? (\n <p className=\"ds:sr-only\" role=\"status\" aria-live=\"polite\">\n {dictationAnnouncement}\n </p>\n ) : null}\n {errored ? (\n <p id={errorId} role=\"alert\" className={errorClass}>\n {t('editor.ai.error')}\n </p>\n ) : privacyNotice ? (\n <p className={noticeClass}>{privacyNotice}</p>\n ) : null}\n </>\n )}\n </EditorOverlay>\n );\n}\n","/* ------------------------------------------------------------------ */\n/* EditorToolbar — the kit's OWN toolbar for RichTextEditor. */\n/* */\n/* Redactor renders with `toolbar: false` (no native toolbar); this DS */\n/* toolbar drives the editor through Redactor's command API via `run` */\n/* and, for surfaces that would otherwise use Redactor's own modals */\n/* (link, image), through DS Dialogs + the `insertHtml` seam so EVERY */\n/* interactive surface is a kit component. Colour uses the DS */\n/* ColorPicker; the style menu is a labelled menu button; table offers */\n/* a size-grid insert + contextual row/column/header ops. */\n/* ------------------------------------------------------------------ */\n\nimport {\n Fragment,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ReactNode,\n type RefObject,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Baseline,\n BetweenHorizontalEnd,\n BetweenHorizontalStart,\n BetweenVerticalEnd,\n BetweenVerticalStart,\n Bold,\n ChevronDown,\n Columns2,\n Heading2,\n Heading3,\n Highlighter,\n Image as ImageIcon,\n Italic,\n Link as LinkIcon,\n List,\n ListOrdered,\n Ellipsis,\n PaintBucket,\n PaintRoller,\n PanelLeft,\n PanelRight,\n PanelTop,\n PanelTopDashed,\n Palette,\n Pilcrow,\n Quote,\n Rows2,\n Strikethrough,\n Table as TableIcon,\n TextAlignCenter,\n TextAlignEnd,\n TextAlignStart,\n Trash2,\n Underline,\n Wrench,\n} from 'lucide-react';\nimport { cva } from 'class-variance-authority';\n\nimport { Button, IconButton } from '../button';\nimport { TooltipProvider } from '../tooltip';\nimport { Popover } from '../popover';\nimport { DropdownMenu } from '../dropdown-menu';\nimport { Dialog } from '../dialog';\nimport { ColorPicker } from '../color-picker';\nimport { TextInput } from '../text-input';\nimport { Checkbox } from '../checkbox';\nimport { FileUpload } from '../file-upload';\n\nexport type EditorToolbarPreset = 'minimal' | 'standard' | 'full';\n\nexport interface EditorToolbarProps {\n /** Dispatch a Redactor command (and refresh active state). */\n run: (command: string, ...args: unknown[]) => void;\n /** Active formats at the caret — toggle buttons render pressed. */\n active: ReadonlySet<string>;\n preset: EditorToolbarPreset;\n /** Insert sanitised HTML at the caret (link / image / table). */\n insertHtml: (html: string) => void;\n /** Insert a table — list-aware (drops it after a list, never inside an <li>). */\n insertTable: (html: string) => void;\n /** Save the editor selection before a DS popover/dialog takes focus. */\n saveSelection: () => void;\n /** Restore the saved selection before applying. */\n restoreSelection: () => void;\n /** Current selected text — prefills the link dialog's text field. */\n getSelectedText: () => string;\n /** Upload an image file and resolve its URL (image dialog's upload area). */\n uploadImage?: (file: File, signal?: AbortSignal) => Promise<string>;\n /** Show the text-colour control. */\n enableColor?: boolean;\n /** Show the image control (consumer set an image-upload URL). */\n enableImage?: boolean;\n /** Show the table control (consumer loaded the table plugin). */\n enableTable?: boolean;\n /**\n * Show an \"Editor extensions\" tools affordance (marketplace tools), placed\n * inline at the end of the toolbar. Currently a visual placeholder — not\n * wired to a menu.\n */\n showExtensions?: boolean;\n}\n\n/** i18n key + English fallback (for keys not yet in every locale). */\ntype L = [string, string];\n\ninterface ToolbarItem {\n id: string;\n icon: ReactNode;\n label: L;\n command: [string, ...unknown[]];\n /** When set, the button is a toggle and presses when `active` has this key. */\n toggle?: string;\n}\n\nconst ITEMS: Record<string, ToolbarItem> = {\n bold: {\n id: 'bold',\n icon: <Bold />,\n label: ['editor.bold', 'Bold'],\n command: ['module.inline.format', { tag: 'b' }],\n toggle: 'bold',\n },\n italic: {\n id: 'italic',\n icon: <Italic />,\n label: ['editor.italic', 'Italic'],\n command: ['module.inline.format', { tag: 'i' }],\n toggle: 'italic',\n },\n underline: {\n id: 'underline',\n icon: <Underline />,\n label: ['editor.underline', 'Underline'],\n command: ['module.inline.format', { tag: 'u' }],\n toggle: 'underline',\n },\n strike: {\n id: 'strike',\n icon: <Strikethrough />,\n label: ['editor.strike', 'Strikethrough'],\n command: ['module.inline.format', { tag: 'del' }],\n toggle: 'strike',\n },\n ul: {\n id: 'ul',\n icon: <List />,\n label: ['editor.list.bullet', 'Bulleted list'],\n command: ['module.list.toggle', 'ul'],\n toggle: 'ul',\n },\n ol: {\n id: 'ol',\n icon: <ListOrdered />,\n label: ['editor.list.ordered', 'Numbered list'],\n command: ['module.list.toggle', 'ol'],\n toggle: 'ol',\n },\n};\n\n// Block-format options. `id` matches the active token emitted by the editor\n// (paragraph / h2 / h3 / quote) so the labelled button shows the active style.\nconst FORMAT_OPTIONS: { id: string; tag: string; icon: ReactNode; label: L }[] =\n [\n {\n id: 'paragraph',\n tag: 'p',\n icon: <Pilcrow />,\n label: ['editor.paragraph', 'Paragraph'],\n },\n {\n id: 'h2',\n tag: 'h2',\n icon: <Heading2 />,\n label: ['editor.heading2', 'Heading 2'],\n },\n {\n id: 'h3',\n tag: 'h3',\n icon: <Heading3 />,\n label: ['editor.heading3', 'Heading 3'],\n },\n {\n id: 'quote',\n tag: 'blockquote',\n icon: <Quote />,\n label: ['editor.quote', 'Quote'],\n },\n ];\n\nconst PRESETS: Record<EditorToolbarPreset, string[]> = {\n minimal: ['bold', 'italic', 'underline', 'link'],\n standard: [\n 'format',\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'ul',\n 'ol',\n 'link',\n ],\n full: ['format', 'bold', 'italic', 'underline', 'strike', 'ul', 'ol', 'link'],\n};\n\n// Table ops mirror EXACTLY the commands platform's Redactor table plugin\n// exposes (verified against platform/web/static/redactor/_plugins/table) — it\n// has no merge/split/align commands, so neither do we.\nconst TABLE_OPS: { id: string; command: string; icon: ReactNode; label: L }[] =\n [\n {\n id: 'rowAbove',\n command: 'plugin.table.addRowAbove',\n icon: <BetweenHorizontalStart />,\n label: ['editor.table.rowAbove', 'Add row above'],\n },\n {\n id: 'rowBelow',\n command: 'plugin.table.addRowBelow',\n icon: <BetweenHorizontalEnd />,\n label: ['editor.table.rowBelow', 'Add row below'],\n },\n {\n id: 'colLeft',\n command: 'plugin.table.addColumnLeft',\n icon: <BetweenVerticalStart />,\n label: ['editor.table.columnLeft', 'Add column left'],\n },\n {\n id: 'colRight',\n command: 'plugin.table.addColumnRight',\n icon: <BetweenVerticalEnd />,\n label: ['editor.table.columnRight', 'Add column right'],\n },\n {\n id: 'addHead',\n command: 'plugin.table.addHead',\n icon: <PanelTop />,\n label: ['editor.table.addHeader', 'Add header row'],\n },\n {\n id: 'deleteHead',\n command: 'plugin.table.deleteHead',\n icon: <PanelTopDashed />,\n label: ['editor.table.deleteHeader', 'Remove header row'],\n },\n {\n id: 'deleteRow',\n command: 'plugin.table.deleteRow',\n icon: <Rows2 />,\n label: ['editor.table.deleteRow', 'Delete row'],\n },\n {\n id: 'deleteColumn',\n command: 'plugin.table.deleteColumn',\n icon: <Columns2 />,\n label: ['editor.table.deleteColumn', 'Delete column'],\n },\n {\n id: 'deleteTable',\n command: 'plugin.table.deleteTable',\n icon: <Trash2 />,\n label: ['editor.table.deleteTable', 'Delete table'],\n },\n ];\n\nconst TABLE_GRID = 6; // max rows/cols offered by the size picker\n\n// Outer element: query container ('toolbar') + visual chrome. The flex row\n// lives in `toolbarRowClass` on an inner child so `container-type` is never set\n// on the flex parent (that would blockify the inline-flowing controls).\nconst toolbarClass = cva(\n [\n 'ds:@container/toolbar',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:p-[var(--spacing-xs)]',\n 'ds:shadow-[var(--shadow-md)]',\n ].join(' '),\n);\n\nconst toolbarRowClass =\n 'ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]';\n\nconst dividerClass =\n 'ds:self-stretch ds:[inline-size:var(--border-width-sm)] ds:bg-[var(--border)] ds:[margin-inline:var(--spacing-2xs)]';\n\nconst fieldLabelClass =\n 'ds:text-[length:var(--font-size-sm)] ds:font-medium ds:text-[color:var(--foreground)]';\n\n// Escape a string for safe interpolation; insertHtml re-sanitises via DOMPurify,\n// but encoding here keeps the constructed markup well-formed first.\nfunction esc(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\n/* ------------------------------------------------------------------ */\n/* Style — labelled menu button */\n/* ------------------------------------------------------------------ */\n\nfunction StyleMenu({\n run,\n active,\n onTriggerDown,\n}: {\n run: EditorToolbarProps['run'];\n active: ReadonlySet<string>;\n onTriggerDown: (event: { preventDefault: () => void }) => void;\n}): React.JSX.Element {\n const { t } = useTranslation();\n const current =\n FORMAT_OPTIONS.find((o) => active.has(o.id)) ?? FORMAT_OPTIONS[0];\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <Button\n size=\"sm\"\n intent=\"ghost\"\n startIcon={current.icon}\n endIcon={<ChevronDown />}\n // Accessible name includes the current format so it (a) survives the\n // icon-only state below @md and (b) contains the visible label when\n // shown, satisfying WCAG 2.5.3 Label in Name.\n aria-label={`${t('editor.format', 'Paragraph style')}: ${t(\n current.label[0],\n current.label[1],\n )}`}\n onMouseDown={onTriggerDown}\n >\n {/* Drop the text label on a narrow toolbar — the start icon + chevron\n still convey \"current style + menu\", and the aria-label carries the\n accessible name. Shown again from 448px. The threshold is px, not\n the `@md` rem alias — container-query `rem` follows the host root\n font-size and misfires off a non-16px root. */}\n <span className=\"ds:hidden ds:@[448px]/toolbar:inline\">\n {t(current.label[0], current.label[1])}\n </span>\n </Button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content align=\"start\">\n {FORMAT_OPTIONS.map((opt) => (\n <DropdownMenu.Item\n key={opt.id}\n startIcon={opt.icon}\n onSelect={() => run('module.block.format', { tag: opt.tag })}\n >\n {t(opt.label[0], opt.label[1])}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Link — DS Dialog */\n/* ------------------------------------------------------------------ */\n\nfunction LinkDialog({\n insertHtml,\n saveSelection,\n restoreSelection,\n getSelectedText,\n}: Pick<\n EditorToolbarProps,\n 'insertHtml' | 'saveSelection' | 'restoreSelection' | 'getSelectedText'\n>): React.JSX.Element {\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const [url, setUrl] = useState('');\n const [text, setText] = useState('');\n const [newTab, setNewTab] = useState(false);\n const urlId = useId();\n const textId = useId();\n\n const reset = (): void => {\n setUrl('');\n setText('');\n setNewTab(false);\n };\n\n const handleInsert = (): void => {\n const href = url.trim();\n if (!href) return;\n const label = text.trim() || href;\n const tab = newTab ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : '';\n const html = `<a href=\"${esc(href)}\"${tab}>${esc(label)}</a>`;\n setOpen(false);\n reset();\n window.requestAnimationFrame(() => {\n restoreSelection();\n insertHtml(html);\n });\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={setOpen}>\n <Dialog.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<LinkIcon />}\n aria-label={t('editor.link.insert', 'Insert link')}\n // Save the selection synchronously (before focus leaves the editor);\n // no preventDefault — the modal Dialog needs normal focus handling.\n onMouseDown={() => {\n saveSelection();\n setText(getSelectedText());\n }}\n />\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>{t('editor.link.insert', 'Insert link')}</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={urlId} className={fieldLabelClass}>\n {t('editor.link.url', 'URL')}\n </label>\n <TextInput\n id={urlId}\n type=\"url\"\n value={url}\n onChange={(event) => setUrl(event.target.value)}\n placeholder=\"https://…\"\n />\n </div>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={textId} className={fieldLabelClass}>\n {t('editor.link.text', 'Text to display')}\n </label>\n <TextInput\n id={textId}\n value={text}\n onChange={(event) => setText(event.target.value)}\n placeholder={t('editor.link.textPlaceholder', 'Link text')}\n />\n </div>\n <Checkbox\n checked={newTab}\n onCheckedChange={(checked) => setNewTab(checked === true)}\n label={t('editor.link.newTab', 'Open in new tab')}\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button intent=\"secondary\">{t('common.cancel')}</Button>\n </Dialog.Close>\n <Button onClick={handleInsert} disabled={!url.trim()}>\n {t('editor.link.insertAction', 'Insert')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Image — DS Dialog */\n/* ------------------------------------------------------------------ */\n\nfunction ImageDialog({\n insertHtml,\n saveSelection,\n restoreSelection,\n uploadImage,\n}: Pick<\n EditorToolbarProps,\n 'insertHtml' | 'saveSelection' | 'restoreSelection' | 'uploadImage'\n>): React.JSX.Element {\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n const [src, setSrc] = useState('');\n const [alt, setAlt] = useState('');\n const srcId = useId();\n const altId = useId();\n\n const insertImage = (url: string, altText: string): void => {\n const html = `<img src=\"${esc(url)}\" alt=\"${esc(altText)}\" loading=\"lazy\">`;\n setOpen(false);\n setSrc('');\n setAlt('');\n window.requestAnimationFrame(() => {\n restoreSelection();\n insertHtml(html);\n });\n };\n\n const handleInsert = (): void => {\n const url = src.trim();\n if (url) insertImage(url, alt.trim());\n };\n\n return (\n <Dialog.Root open={open} onOpenChange={setOpen}>\n <Dialog.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<ImageIcon />}\n aria-label={t('editor.image.insert', 'Insert image')}\n // No preventDefault — the modal Dialog needs normal focus handling.\n onMouseDown={() => saveSelection()}\n />\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>\n {t('editor.image.insert', 'Insert image')}\n </Dialog.Title>\n </Dialog.Header>\n <Dialog.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {uploadImage ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <span className={fieldLabelClass}>\n {t('editor.image.upload', 'Upload')}\n </span>\n <FileUpload\n variant=\"dropzone\"\n accept={{\n 'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'],\n }}\n maxFiles={1}\n onUpload={async (file, { signal }) => {\n const url = await uploadImage(file, signal);\n insertImage(url, file.name);\n }}\n />\n <span className=\"ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--muted-foreground)]\">\n {t('editor.image.orUrl', 'Or paste an image URL')}\n </span>\n </div>\n ) : null}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={srcId} className={fieldLabelClass}>\n {t('editor.image.url', 'Image URL')}\n </label>\n <TextInput\n id={srcId}\n type=\"url\"\n value={src}\n onChange={(event) => setSrc(event.target.value)}\n placeholder=\"https://…\"\n />\n </div>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <label htmlFor={altId} className={fieldLabelClass}>\n {t('editor.image.alt', 'Alt text')}\n </label>\n <TextInput\n id={altId}\n value={alt}\n onChange={(event) => setAlt(event.target.value)}\n placeholder={t(\n 'editor.image.altPlaceholder',\n 'Describe the image',\n )}\n />\n </div>\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Close asChild>\n <Button intent=\"secondary\">{t('common.cancel')}</Button>\n </Dialog.Close>\n <Button onClick={handleInsert} disabled={!src.trim()}>\n {t('editor.image.insertAction', 'Insert')}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Colour — DS ColorPicker */\n/* ------------------------------------------------------------------ */\n\nfunction ColourControl({\n run,\n saveSelection,\n restoreSelection,\n}: Pick<\n EditorToolbarProps,\n 'run' | 'saveSelection' | 'restoreSelection'\n>): React.JSX.Element {\n const { t } = useTranslation();\n // Colour-picker seed value: a text-colour picker emits arbitrary, user-chosen\n // colours, so a literal hex default (rather than a brand token) is correct.\n // eslint-disable-next-line no-restricted-syntax\n const [colour, setColour] = useState('#1f2a5c');\n\n // Apply on pick — a colour control shouldn't need a separate \"Apply\" step.\n // The picker is compact (swatch-only), so onChange fires once per swatch\n // click; mirror Redactor's fontcolor plugin (toggle <span> with a colour\n // style — `type: 'toggle'` is required for the format to apply).\n const applyColour = (hex: string): void => {\n setColour(hex);\n restoreSelection();\n run('module.inline.format', {\n tag: 'span',\n style: { color: hex },\n type: 'toggle',\n });\n };\n const removeColour = (): void => {\n restoreSelection();\n run('module.inline.remove', { style: 'color' });\n };\n\n return (\n <Popover onOpenChange={(o) => o && saveSelection()}>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<Palette />}\n aria-label={t('editor.textColor', 'Text colour')}\n onMouseDown={(event) => {\n event.preventDefault();\n saveSelection();\n }}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"start\">\n <Popover.Heading>\n {t('editor.textColor', 'Text colour')}\n </Popover.Heading>\n <div className=\"ds:pt-[var(--spacing-sm)]\">\n <ColorPicker\n variant=\"inline\"\n size=\"sm\"\n value={colour}\n onChange={applyColour}\n />\n </div>\n <div className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:items-center ds:justify-end\">\n <Button size=\"sm\" intent=\"secondary\" onClick={removeColour}>\n {t('editor.color.remove', 'Remove colour')}\n </Button>\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Highlight — DS ColorPicker applied as a text background */\n/* ------------------------------------------------------------------ */\n\nfunction HighlightControl({\n run,\n saveSelection,\n restoreSelection,\n}: Pick<\n EditorToolbarProps,\n 'run' | 'saveSelection' | 'restoreSelection'\n>): React.JSX.Element {\n const { t } = useTranslation();\n // Highlight seed value: a highlight picker emits arbitrary, user-chosen\n // colours, so a literal hex default (rather than a brand token) is correct.\n // eslint-disable-next-line no-restricted-syntax\n const [colour, setColour] = useState('#fff3a3');\n\n // Apply on pick. Highlight is the same inline <span> as text colour, but the\n // style key is `background-color` (mirrors Redactor's fontcolor \"Highlight\").\n const applyHighlight = (hex: string): void => {\n setColour(hex);\n restoreSelection();\n run('module.inline.format', {\n tag: 'span',\n style: { 'background-color': hex },\n type: 'toggle',\n });\n };\n const removeHighlight = (): void => {\n restoreSelection();\n run('module.inline.remove', { style: 'background-color' });\n };\n\n return (\n <Popover onOpenChange={(o) => o && saveSelection()}>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<Highlighter />}\n aria-label={t('editor.highlightColor', 'Highlight')}\n onMouseDown={(event) => {\n event.preventDefault();\n saveSelection();\n }}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"start\">\n <Popover.Heading>\n {t('editor.highlightColor', 'Highlight')}\n </Popover.Heading>\n <div className=\"ds:pt-[var(--spacing-sm)]\">\n <ColorPicker\n variant=\"inline\"\n size=\"sm\"\n value={colour}\n onChange={applyHighlight}\n />\n </div>\n <div className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:items-center ds:justify-end\">\n <Button size=\"sm\" intent=\"secondary\" onClick={removeHighlight}>\n {t('editor.highlight.remove', 'Remove highlight')}\n </Button>\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Table — size-grid insert + contextual ops */\n/* ------------------------------------------------------------------ */\n\nfunction buildTable(rows: number, cols: number): string {\n const cells = Array.from({ length: cols }, () => '<td><br></td>').join('');\n const body = Array.from({ length: rows }, () => `<tr>${cells}</tr>`).join('');\n return `<table><tbody>${body}</tbody></table>`;\n}\n\nfunction TableControl({\n run,\n insertTable,\n active,\n}: Pick<\n EditorToolbarProps,\n 'run' | 'insertTable' | 'active'\n>): React.JSX.Element {\n const { t } = useTranslation();\n const [hover, setHover] = useState<{ r: number; c: number }>({ r: 0, c: 0 });\n const inTable = active.has('table');\n\n return (\n <Popover onOpenChange={(o) => !o && setHover({ r: 0, c: 0 })}>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<TableIcon />}\n aria-label={t('editor.table.insert', 'Insert table')}\n onMouseDown={(event) => event.preventDefault()}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"start\">\n {inTable ? (\n // Caret is already inside a table — offer the manage ops only, never\n // a nested-table insert (mirrors Redactor's native dropdown, which\n // disables \"insert table\" while the caret is in a table).\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {TABLE_OPS.map((op) => (\n <button\n key={op.id}\n type=\"button\"\n onClick={() => run(op.command)}\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-2xs)] ds:text-start ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--foreground)] ds:hover:bg-[var(--muted)]\"\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center ds:text-[color:var(--muted-foreground)]\"\n >\n {op.icon}\n </span>\n {t(op.label[0], op.label[1])}\n </button>\n ))}\n </div>\n ) : (\n <>\n <Popover.Heading>\n {t('editor.table.insert', 'Insert table')}\n </Popover.Heading>\n <div\n role=\"group\"\n aria-label={t('editor.table.sizePicker', 'Table size')}\n className=\"ds:mt-[var(--spacing-sm)] ds:grid ds:w-fit ds:grid-cols-6 ds:gap-[var(--spacing-2xs)]\"\n onMouseLeave={() => setHover({ r: 0, c: 0 })}\n >\n {Array.from({ length: TABLE_GRID * TABLE_GRID }, (_, i) => {\n const r = Math.floor(i / TABLE_GRID) + 1;\n const c = (i % TABLE_GRID) + 1;\n const on = r <= hover.r && c <= hover.c;\n return (\n <button\n key={i}\n type=\"button\"\n aria-label={t('editor.table.sizeCell', '{{r}}×{{c}}', {\n r,\n c,\n })}\n onMouseEnter={() => setHover({ r, c })}\n onClick={() => insertTable(buildTable(r, c))}\n className={`ds:size-5 ds:rounded-[var(--radius-sm)] ds:border ds:border-[color:var(--border)] ${\n on ? 'ds:bg-[var(--primary)]' : 'ds:bg-[var(--muted)]'\n }`}\n />\n );\n })}\n </div>\n <p className=\"ds:mt-[var(--spacing-xs)] ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--muted-foreground)]\">\n {hover.r > 0\n ? t('editor.table.sizeCell', '{{r}}×{{c}}', {\n r: hover.r,\n c: hover.c,\n })\n : t('editor.table.sizeHint', 'Pick a size')}\n </p>\n </>\n )}\n </Popover.Content>\n </Popover>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Floating in-cell table toolbar */\n/* */\n/* Appears anchored above the table whenever the caret is inside one, */\n/* so the common row/column ops are one click away without opening the */\n/* toolbar menu. Dispatches the same `plugin.table.*` commands via the */\n/* shared `run` seam; the toolbar TableControl menu stays as the place */\n/* for inserting tables and header ops. */\n/* ------------------------------------------------------------------ */\n\nconst TABLE_OP_BY_ID: Record<string, (typeof TABLE_OPS)[number]> =\n Object.fromEntries(TABLE_OPS.map((op) => [op.id, op]));\n\nconst tableFloatClass = [\n 'ds:absolute ds:z-20 ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n 'ds:[inset-block-start:var(--rte-tt-top)] ds:[inset-inline-start:var(--rte-tt-start)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--popover)] ds:p-[var(--spacing-2xs)] ds:shadow-[var(--shadow-lg)]',\n].join(' ');\n\nexport interface TableFloatingToolbarProps {\n active: ReadonlySet<string>;\n run: EditorToolbarProps['run'];\n /** Positioned container the bar is absolutely placed within. */\n areaRef: RefObject<HTMLDivElement | null>;\n /** The <table> the caret is currently inside (relative to this editor). */\n getActiveTableEl: () => HTMLElement | null;\n /** Show the cell/row background-colour controls (fontcolor plugin loaded). */\n enableColor?: boolean;\n /** Snapshot the current cell before a colour popover takes focus. */\n saveTableCell: () => void;\n /** Set/clear a background colour on the current cell or its row. */\n applyTableBackground: (scope: 'cell' | 'row', colour: string | null) => void;\n}\n\n// Colour-control seed: an arbitrary user-chosen background, so a literal hex\n// default is correct (mirrors ColourControl / HighlightControl).\n// eslint-disable-next-line no-restricted-syntax\nconst TABLE_BG_SEED = '#fde68a';\n\n// One cell/row background-colour control: an icon trigger → compact ColorPicker\n// (applies on pick) + a clear action. The cell is captured on open (saveTableCell)\n// because the popover takes focus; `onOpenChange` lets the bar stay mounted.\nfunction TableBgColourControl({\n scope,\n icon,\n label,\n onOpenChange,\n saveTableCell,\n applyTableBackground,\n}: {\n scope: 'cell' | 'row';\n icon: ReactNode;\n label: string;\n onOpenChange: (open: boolean) => void;\n saveTableCell: () => void;\n applyTableBackground: (scope: 'cell' | 'row', colour: string | null) => void;\n}): React.JSX.Element {\n const { t } = useTranslation();\n const [colour, setColour] = useState(TABLE_BG_SEED);\n return (\n <Popover\n onOpenChange={(open) => {\n onOpenChange(open);\n if (open) saveTableCell();\n }}\n >\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={icon}\n tooltip={label}\n onMouseDown={(event) => event.preventDefault()}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"center\">\n <ColorPicker\n variant=\"inline\"\n size=\"sm\"\n value={colour}\n onChange={(hex) => {\n setColour(hex);\n applyTableBackground(scope, hex);\n }}\n />\n <Button\n size=\"sm\"\n intent=\"ghost\"\n className=\"ds:mt-[var(--spacing-xs)] ds:w-full\"\n onClick={() => applyTableBackground(scope, null)}\n >\n {t('editor.table.clearColor', 'Clear colour')}\n </Button>\n </Popover.Content>\n </Popover>\n );\n}\n\nexport function TableFloatingToolbar({\n active,\n run,\n areaRef,\n getActiveTableEl,\n enableColor = false,\n saveTableCell,\n applyTableBackground,\n}: TableFloatingToolbarProps): React.JSX.Element | null {\n const { t } = useTranslation();\n const inTable = active.has('table');\n const [pos, setPos] = useState<{\n top: number;\n start: number;\n rtl: boolean;\n } | null>(null);\n\n // Keep the bar mounted while a colour popover is open: opening it can move\n // focus out of the editor, dropping `table` from `active`, which would\n // otherwise unmount the bar (and close the popover) mid-interaction.\n const colourOpenCount = useRef(0);\n const [colourOpen, setColourOpen] = useState(false);\n const handleColourOpenChange = useCallback((open: boolean): void => {\n colourOpenCount.current = Math.max(\n 0,\n colourOpenCount.current + (open ? 1 : -1),\n );\n setColourOpen(colourOpenCount.current > 0);\n }, []);\n\n useEffect(() => {\n // Freeze tracking while a colour popover is open (the caret may have left\n // the editor); resume when it closes.\n if (colourOpen) return;\n if (!inTable || typeof window === 'undefined') {\n setPos(null);\n return;\n }\n const recompute = (): void => {\n const area = areaRef.current;\n const table = getActiveTableEl();\n if (!area || !table) {\n setPos(null);\n return;\n }\n const a = area.getBoundingClientRect();\n const r = table.getBoundingClientRect();\n const rtl = getComputedStyle(area).direction === 'rtl';\n // Float just above the table's block-start edge, clamped to the container\n // top so it never renders above the editing surface. 44 ≈ the bar's own\n // height (one --min-target-size row) plus a small gap.\n const top = Math.max(0, r.top - a.top - 44);\n // Anchor `start` to the table's inline CENTRE; the render translates the\n // bar back by half its own width so it sits centred over the table.\n const center = rtl\n ? a.right - r.right + r.width / 2\n : r.left - a.left + r.width / 2;\n setPos({ top, start: Math.max(0, center), rtl });\n };\n recompute();\n // While the caret stays in the table the bar must track it: cell edits and\n // add-row/column grow the table (ResizeObserver), and the surface or the\n // viewport can scroll/resize.\n const ro = new ResizeObserver(recompute);\n const area = areaRef.current;\n const table = getActiveTableEl();\n if (area) ro.observe(area);\n if (table) ro.observe(table);\n window.addEventListener('scroll', recompute, true);\n window.addEventListener('resize', recompute);\n return () => {\n ro.disconnect();\n window.removeEventListener('scroll', recompute, true);\n window.removeEventListener('resize', recompute);\n };\n }, [inTable, colourOpen, areaRef, getActiveTableEl]);\n\n if ((!inTable && !colourOpen) || !pos) return null;\n\n // Ordered render groups; 'colour' is the cell/row background controls.\n const groups: (string[] | 'colour')[] = [\n ['rowAbove', 'rowBelow'],\n ['colLeft', 'colRight'],\n ['addHead'],\n ...(enableColor ? (['colour'] as const) : []),\n ['deleteRow', 'deleteColumn'],\n ['deleteTable'],\n ];\n\n return (\n // Tooltips disambiguate the icon-only ops on hover (and provide each\n // button's accessible name via IconButton's `tooltip` prop). Radix Tooltip\n // needs a provider ancestor, so scope one to the bar.\n <TooltipProvider>\n <div\n // role=\"group\", not \"toolbar\": these controls are independent tab\n // stops with no roving-focus / arrow-key navigation, so advertising the\n // WAI-ARIA toolbar contract would be a false promise. role=\"group\" keeps\n // the labelled grouping without committing to single-tab-stop semantics.\n role=\"group\"\n aria-label={t('editor.table.toolbar', 'Table tools')}\n // Centre on the table: --rte-tt-start is the table's inline centre, so\n // pull back by half the bar's width (mirrored for RTL).\n className={`${tableFloatClass} ${pos.rtl ? 'ds:translate-x-1/2' : 'ds:-translate-x-1/2'}`}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-computed position injected via CSS custom properties (23-constraints §Runtime-computed dimensions); the inset rules live in the class\n style={{\n ['--rte-tt-top' as string]: `${pos.top}px`,\n ['--rte-tt-start' as string]: `${pos.start}px`,\n }}\n >\n {groups.map((group, gi) => (\n <Fragment key={group === 'colour' ? 'colour' : group[0]}>\n {gi > 0 ? (\n <span aria-hidden=\"true\" className={dividerClass} />\n ) : null}\n {group === 'colour' ? (\n <>\n <TableBgColourControl\n scope=\"cell\"\n icon={<PaintBucket />}\n label={t('editor.table.cellColor', 'Cell colour')}\n onOpenChange={handleColourOpenChange}\n saveTableCell={saveTableCell}\n applyTableBackground={applyTableBackground}\n />\n <TableBgColourControl\n scope=\"row\"\n icon={<PaintRoller />}\n label={t('editor.table.rowColor', 'Row colour')}\n onOpenChange={handleColourOpenChange}\n saveTableCell={saveTableCell}\n applyTableBackground={applyTableBackground}\n />\n </>\n ) : (\n group.map((opId) => {\n const op = TABLE_OP_BY_ID[opId];\n return (\n <IconButton\n key={opId}\n size=\"sm\"\n intent=\"ghost\"\n icon={op.icon}\n tooltip={t(op.label[0], op.label[1])}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => run(op.command)}\n />\n );\n })\n )}\n </Fragment>\n ))}\n </div>\n </TooltipProvider>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* ImageFloatingToolbar — contextual image controls + resize handles */\n/* */\n/* Framed over the selected image, so text-wrap (inline / wrap-left / */\n/* wrap-right) and block alignment (left / centre / right) are one */\n/* click away and the four corner handles resize it by pointer drag or */\n/* keyboard. DS-native parity with platform's Redactor imageAlignment + */\n/* imageResize plugins (HTP-4954): the SAME `wysiwyg-img-*` classes are */\n/* applied so saved HTML round-trips byte-for-byte across surfaces, and */\n/* the width is an inline % so it never overflows the editable. */\n/* Redactor's own resizer is off (imageResizable:false) — this is the */\n/* single, keyboard-accessible resize UI. */\n/* ------------------------------------------------------------------ */\n\n/* Layout classes — byte-identical to platform's imageAlignment plugin. */\nexport const IMAGE_FLOW_CLASSES = [\n 'wysiwyg-img-inline',\n 'wysiwyg-img-wrap-left',\n 'wysiwyg-img-wrap-right',\n] as const;\n\nexport const IMAGE_ALIGN_CLASSES = [\n 'wysiwyg-img-align-left',\n 'wysiwyg-img-align-center',\n 'wysiwyg-img-align-right',\n] as const;\n\n/** The layout class currently set within a group on `el` (or '' for none). */\nexport function selectedImageClass(\n el: HTMLElement,\n group: readonly string[],\n): string {\n return group.find((c) => el.classList.contains(c)) ?? '';\n}\n\n/** The image's rendered width as a whole-percent of its editable box. */\nexport function imageWidthPercent(img: HTMLElement): number {\n const box = img.closest('.redactor-in');\n const boxWidth = box instanceof HTMLElement ? box.clientWidth : 0;\n const imgWidth = img.getBoundingClientRect().width;\n if (boxWidth <= 0 || imgWidth <= 0) return IMG_MAX_PCT;\n return Math.round(Math.min(IMG_MAX_PCT, (imgWidth / boxWidth) * 100));\n}\n\nconst IMG_MIN_PCT = 10;\nconst IMG_MAX_PCT = 100;\nconst IMG_STEP = 5;\nconst IMG_STEP_COARSE = 10;\n\nconst clampPct = (pct: number): number =>\n Math.min(IMG_MAX_PCT, Math.max(IMG_MIN_PCT, Math.round(pct)));\n\n// Text-flow group: how surrounding text relates to the image. `inline` keeps\n// it in the line; the wrap options float it and flow text down the other side.\nconst IMAGE_FLOW_OPS: { id: string; icon: ReactNode; label: L }[] = [\n {\n id: 'wysiwyg-img-inline',\n icon: <Baseline />,\n label: ['editor.image.inline', 'Inline with text'],\n },\n {\n id: 'wysiwyg-img-wrap-left',\n icon: <PanelLeft />,\n label: ['editor.image.wrapLeft', 'Wrap left'],\n },\n {\n id: 'wysiwyg-img-wrap-right',\n icon: <PanelRight />,\n label: ['editor.image.wrapRight', 'Wrap right'],\n },\n];\n\n// Block-alignment group: where a non-wrapped image sits across the column.\nconst IMAGE_ALIGN_OPS: { id: string; icon: ReactNode; label: L }[] = [\n {\n id: 'wysiwyg-img-align-left',\n icon: <TextAlignStart />,\n label: ['editor.image.alignLeft', 'Align left'],\n },\n {\n id: 'wysiwyg-img-align-center',\n icon: <TextAlignCenter />,\n label: ['editor.image.alignCenter', 'Align centre'],\n },\n {\n id: 'wysiwyg-img-align-right',\n icon: <TextAlignEnd />,\n label: ['editor.image.alignRight', 'Align right'],\n },\n];\n\n// Four corner handles. `sign` is the horizontal grow direction for a pointer\n// drag (the inline-end corners grow rightward, the inline-start ones leftward);\n// it is flipped again for RTL at interaction time. The cursor is physical.\nconst IMAGE_CORNERS: {\n id: 'tl' | 'tr' | 'bl' | 'br';\n pos: string;\n cursor: string;\n sign: 1 | -1;\n labelKey: string;\n labelFallback: string;\n}[] = [\n {\n id: 'tl',\n pos: 'ds:[inset-block-start:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-start:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nwse-resize',\n sign: -1,\n labelKey: 'editor.image.resizeTopStart',\n labelFallback: 'Resize image, top-start corner',\n },\n {\n id: 'tr',\n pos: 'ds:[inset-block-start:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-end:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nesw-resize',\n sign: 1,\n labelKey: 'editor.image.resizeTopEnd',\n labelFallback: 'Resize image, top-end corner',\n },\n {\n id: 'bl',\n pos: 'ds:[inset-block-end:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-start:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nesw-resize',\n sign: -1,\n labelKey: 'editor.image.resizeBottomStart',\n labelFallback: 'Resize image, bottom-start corner',\n },\n {\n id: 'br',\n pos: 'ds:[inset-block-end:calc(var(--spacing-md)*-0.5)] ds:[inset-inline-end:calc(var(--spacing-md)*-0.5)]',\n cursor: 'ds:cursor-nwse-resize',\n sign: 1,\n labelKey: 'editor.image.resizeBottomEnd',\n labelFallback: 'Resize image, bottom-end corner',\n },\n];\n\n// Selection frame outlined over the image; pointer-events off so clicks still\n// reach the image, re-enabled per handle. Rect injected via custom properties.\nconst imageFrameClass = [\n 'ds:absolute ds:z-20 ds:pointer-events-none',\n 'ds:[inset-block-start:var(--rte-img-top)] ds:[inset-inline-start:var(--rte-img-start)]',\n 'ds:[inline-size:var(--rte-img-width)] ds:[block-size:var(--rte-img-height)]',\n 'ds:rounded-[var(--radius-2xs)]',\n 'ds:[outline-style:solid] ds:[outline-width:var(--border-width-md)]',\n 'ds:[outline-color:var(--accent)] ds:[outline-offset:var(--focus-ring-offset)]',\n].join(' ');\n\n// One corner handle: a small accent square whose CENTRE sits on the corner.\n// Centred via per-corner negative-half-size insets (see IMAGE_CORNERS.pos) —\n// logical insets so it stays correct under RTL, with no physical transform.\nconst imageHandleClass = [\n 'ds:absolute ds:pointer-events-auto ds:touch-none',\n 'ds:[inline-size:var(--spacing-md)] ds:[block-size:var(--spacing-md)]',\n 'ds:rounded-[var(--radius-2xs)] ds:shadow-[var(--shadow-sm)]',\n 'ds:bg-[var(--accent)] ds:border ds:border-[color:var(--background)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:[outline-offset:var(--focus-ring-offset)]',\n 'ds:forced-colors:bg-[CanvasText]',\n].join(' ');\n\n// Controls bar, centred above the frame (mirrors tableFloatClass).\nconst imageBarClass = [\n 'ds:absolute ds:z-20 ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]',\n 'ds:[inset-block-start:var(--rte-img-bar-top)] ds:[inset-inline-start:var(--rte-img-center)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--popover)] ds:p-[var(--spacing-2xs)] ds:shadow-[var(--shadow-lg)]',\n].join(' ');\n\nexport interface ImageFloatingToolbarProps {\n /** Positioned container the frame + bar are absolutely placed within. */\n areaRef: RefObject<HTMLDivElement | null>;\n /** The <img> currently selected in THIS editor, or null. */\n activeImageEl: HTMLElement | null;\n /** Apply/replace a `wysiwyg-img-*` class within its group on the image. */\n applyImageClass: (className: string) => void;\n /** Set the image width as a % of its editable box (clamped 10–100). */\n setImageWidth: (pct: number) => void;\n}\n\nexport function ImageFloatingToolbar({\n areaRef,\n activeImageEl: img,\n applyImageClass,\n setImageWidth,\n}: ImageFloatingToolbarProps): React.JSX.Element | null {\n const { t } = useTranslation();\n const [pos, setPos] = useState<{\n top: number;\n start: number;\n width: number;\n height: number;\n center: number;\n barTop: number;\n pct: number;\n rtl: boolean;\n } | null>(null);\n\n // Pointer-drag state (one active pointer at a time).\n const dragRef = useRef<{\n pointerId: number;\n startX: number;\n startPct: number;\n sign: number;\n } | null>(null);\n\n useEffect(() => {\n if (!img || typeof window === 'undefined') {\n setPos(null);\n return;\n }\n const recompute = (): void => {\n const area = areaRef.current;\n if (!area) {\n setPos(null);\n return;\n }\n const a = area.getBoundingClientRect();\n const r = img.getBoundingClientRect();\n const rtl = getComputedStyle(area).direction === 'rtl';\n const top = r.top - a.top;\n // Anchor inline-start from the writing-direction start edge.\n const start = rtl ? a.right - r.right : r.left - a.left;\n const center = start + r.width / 2;\n // 44 ≈ the bar's own height (one --min-target-size row) plus a small gap.\n const barTop = Math.max(0, top - 44);\n setPos({\n top,\n start: Math.max(0, start),\n width: r.width,\n height: r.height,\n center: Math.max(0, center),\n barTop,\n pct: imageWidthPercent(img),\n rtl,\n });\n };\n recompute();\n // The image rect moves when it resizes, when align / wrap / width change,\n // when the document reflows, or when the surface / viewport scrolls.\n // ResizeObserver catches size changes; a MutationObserver on the EDITABLE\n // catches the class / attribute / childList changes that REPOSITION the\n // image without resizing it (it observes the editable, not the frame — a\n // sibling — so it never reacts to its own output); scroll/resize cover the\n // viewport.\n const ro = new ResizeObserver(recompute);\n ro.observe(img);\n const area = areaRef.current;\n if (area) ro.observe(area);\n const editable = img.closest('.redactor-in');\n let mo: MutationObserver | null = null;\n if (editable) {\n mo = new MutationObserver(recompute);\n mo.observe(editable, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['class', 'style', 'width', 'height', 'src'],\n });\n }\n window.addEventListener('scroll', recompute, true);\n window.addEventListener('resize', recompute);\n return () => {\n ro.disconnect();\n mo?.disconnect();\n window.removeEventListener('scroll', recompute, true);\n window.removeEventListener('resize', recompute);\n };\n }, [img, areaRef]);\n\n const onHandlePointerDown = useCallback(\n (corner: (typeof IMAGE_CORNERS)[number]) =>\n (event: React.PointerEvent<HTMLDivElement>): void => {\n if (!event.isPrimary || !pos) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n dragRef.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startPct: pos.pct,\n sign: corner.sign * (pos.rtl ? -1 : 1),\n };\n },\n [pos],\n );\n\n const onHandlePointerMove = useCallback(\n (event: React.PointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (!drag || event.pointerId !== drag.pointerId || !img) return;\n const box = img.closest('.redactor-in');\n const boxWidth = box instanceof HTMLElement ? box.clientWidth : 0;\n if (boxWidth <= 0) return;\n const deltaPct =\n ((drag.sign * (event.clientX - drag.startX)) / boxWidth) * 100;\n setImageWidth(clampPct(drag.startPct + deltaPct));\n },\n [img, setImageWidth],\n );\n\n const onHandlePointerEnd = useCallback(\n (event: React.PointerEvent<HTMLDivElement>): void => {\n const drag = dragRef.current;\n if (!drag || event.pointerId !== drag.pointerId) return;\n event.currentTarget.releasePointerCapture(event.pointerId);\n dragRef.current = null;\n },\n [],\n );\n\n const onHandleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>): void => {\n if (!pos) return;\n let next: number | null = null;\n const step = event.shiftKey ? IMG_STEP_COARSE : IMG_STEP;\n switch (event.key) {\n // Up / right always grow; down / left always shrink — independent of\n // which corner has focus, so the gesture reads the same everywhere.\n case 'ArrowRight':\n case 'ArrowUp':\n next = pos.pct + step;\n break;\n case 'ArrowLeft':\n case 'ArrowDown':\n next = pos.pct - step;\n break;\n case 'Home':\n next = IMG_MIN_PCT;\n break;\n case 'End':\n next = IMG_MAX_PCT;\n break;\n default:\n return;\n }\n event.preventDefault();\n setImageWidth(clampPct(next));\n },\n [pos, setImageWidth],\n );\n\n if (!img || !pos) return null;\n\n const flowActive = selectedImageClass(img, IMAGE_FLOW_CLASSES);\n const alignActive = selectedImageClass(img, IMAGE_ALIGN_CLASSES);\n const widthText = t('editor.image.widthAnnounce', {\n width: pos.pct,\n defaultValue: '{{width}} percent',\n });\n\n return (\n <>\n {/* Selection frame + corner resize handles. */}\n <div\n className={imageFrameClass}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-measured image rect injected via CSS custom properties (23-constraints §Runtime-computed dimensions); the inset/size rules live in the class\n style={{\n ['--rte-img-top' as string]: `${pos.top}px`,\n ['--rte-img-start' as string]: `${pos.start}px`,\n ['--rte-img-width' as string]: `${pos.width}px`,\n ['--rte-img-height' as string]: `${pos.height}px`,\n }}\n >\n {IMAGE_CORNERS.map((corner) => (\n <div\n key={corner.id}\n role=\"slider\"\n tabIndex={0}\n aria-label={t(corner.labelKey, corner.labelFallback)}\n aria-orientation=\"horizontal\"\n aria-valuemin={IMG_MIN_PCT}\n aria-valuemax={IMG_MAX_PCT}\n aria-valuenow={pos.pct}\n aria-valuetext={widthText}\n className={`${imageHandleClass} ${corner.pos} ${corner.cursor}`}\n onPointerDown={onHandlePointerDown(corner)}\n onPointerMove={onHandlePointerMove}\n onPointerUp={onHandlePointerEnd}\n onPointerCancel={onHandlePointerEnd}\n onKeyDown={onHandleKeyDown}\n />\n ))}\n </div>\n\n {/* Wrap + alignment controls, centred above the frame. */}\n <TooltipProvider>\n <div\n role=\"group\"\n aria-label={t('editor.image.toolbar', 'Image tools')}\n className={`${imageBarClass} ${pos.rtl ? 'ds:translate-x-1/2' : 'ds:-translate-x-1/2'}`}\n // eslint-disable-next-line react/forbid-dom-props -- runtime-computed anchor injected via CSS custom properties; the inset rules live in the class\n style={{\n ['--rte-img-bar-top' as string]: `${pos.barTop}px`,\n ['--rte-img-center' as string]: `${pos.center}px`,\n }}\n >\n {[IMAGE_FLOW_OPS, IMAGE_ALIGN_OPS].map((group, gi) => (\n <Fragment key={gi === 0 ? 'flow' : 'align'}>\n {gi > 0 ? (\n <span aria-hidden=\"true\" className={dividerClass} />\n ) : null}\n {group.map((op) => {\n const isActive =\n gi === 0 ? flowActive === op.id : alignActive === op.id;\n return (\n <IconButton\n key={op.id}\n size=\"sm\"\n intent=\"ghost\"\n icon={op.icon}\n aria-pressed={isActive}\n tooltip={t(op.label[0], op.label[1])}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => applyImageClass(op.id)}\n />\n );\n })}\n </Fragment>\n ))}\n </div>\n </TooltipProvider>\n </>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Toolbar */\n/* ------------------------------------------------------------------ */\n\nexport function EditorToolbar({\n run,\n active,\n preset,\n insertHtml,\n insertTable,\n saveSelection,\n restoreSelection,\n getSelectedText,\n uploadImage,\n enableColor = false,\n enableImage = false,\n enableTable = false,\n showExtensions = false,\n}: EditorToolbarProps): React.JSX.Element {\n const { t } = useTranslation();\n // Keep toolbar clicks from stealing the editor's selection.\n const keepSelection = (event: { preventDefault: () => void }): void =>\n event.preventDefault();\n\n // Render a simple command button by id, gated by the active preset.\n const has = (id: string): boolean => PRESETS[preset].includes(id);\n const btn = (id: string): React.JSX.Element | null => {\n if (!has(id)) return null;\n const item = ITEMS[id];\n return (\n <IconButton\n key={item.id}\n size=\"sm\"\n intent=\"ghost\"\n icon={item.icon}\n aria-label={t(item.label[0], item.label[1])}\n aria-pressed={item.toggle ? active.has(item.toggle) : undefined}\n onMouseDown={keepSelection}\n onClick={() => run(...item.command)}\n />\n );\n };\n const Divider = (): React.JSX.Element => (\n <span aria-hidden=\"true\" className={dividerClass} />\n );\n\n // Standard toolbar grouping (matches Google Docs / Word / TinyMCE order):\n // style ▸ inline (B/I/U/S + colour/highlight) ▸ lists ▸ insert ▸ extensions.\n const styleGroup = has('format');\n\n // Primary controls — always inline (style + B/I/U/S + colour/highlight).\n const inlineNodes = [\n btn('bold'),\n btn('italic'),\n btn('underline'),\n btn('strike'),\n enableColor ? (\n <ColourControl\n key=\"colour\"\n run={run}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n />\n ) : null,\n enableColor ? (\n <HighlightControl\n key=\"highlight\"\n run={run}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n />\n ) : null,\n ].filter(Boolean);\n const hasPrimary = styleGroup || inlineNodes.length > 0;\n\n // Secondary controls — lists ▸ insert ▸ extensions. These collapse into the\n // right-hand \"More\" popover on a narrow toolbar (below the @sm breakpoint)\n // instead of wrapping the bar onto a second line.\n const listsNodes = [btn('ul'), btn('ol')].filter(Boolean);\n const insertNodes = [\n has('link') ? (\n <LinkDialog\n key=\"link\"\n insertHtml={insertHtml}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n getSelectedText={getSelectedText}\n />\n ) : null,\n enableImage ? (\n <ImageDialog\n key=\"image\"\n insertHtml={insertHtml}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n uploadImage={uploadImage}\n />\n ) : null,\n enableTable ? (\n <TableControl\n key=\"table\"\n run={run}\n insertTable={insertTable}\n active={active}\n />\n ) : null,\n ].filter(Boolean);\n const extensionNodes = showExtensions\n ? [\n <IconButton\n key=\"extensions\"\n size=\"sm\"\n intent=\"ghost\"\n icon={<Wrench />}\n aria-label={t('editor.extensions', 'Editor extensions')}\n // Placeholder affordance: no handler is wired yet, so the control\n // must not be operable — an enabled button with no onClick fails\n // SC 4.1.2. Disable it until a marketplace handler is connected.\n disabled\n onMouseDown={keepSelection}\n />,\n ]\n : [];\n\n const secondarySubgroups = [listsNodes, insertNodes, extensionNodes].filter(\n (group) => group.length > 0,\n );\n const hasSecondary = secondarySubgroups.length > 0;\n\n // Render the secondary subgroups separated by dividers. `leadingDivider`\n // controls whether a divider precedes the first subgroup (true inline, where\n // the primary controls sit before it; false inside the More popover).\n const renderSecondary = (leadingDivider: boolean): ReactNode =>\n secondarySubgroups.map((group, index) => (\n <Fragment key={index}>\n {index > 0 || leadingDivider ? <Divider /> : null}\n {group}\n </Fragment>\n ));\n\n return (\n // Outer element is the query container + visual chrome; the flex row is an\n // inner child so `container-type` never lands on the flex parent (which\n // would blockify the inline controls).\n <div className={toolbarClass()} data-component=\"editor-toolbar\">\n <div\n // role=\"group\", not \"toolbar\": every control is its own tab stop with\n // no roving focus / arrow-key handling, so the toolbar contract would\n // be false. role=\"group\" keeps the labelled grouping without the\n // single-tab-stop + arrow-navigation promise.\n role=\"group\"\n aria-label={t('editor.toolbarLabel')}\n className={toolbarRowClass}\n >\n {/* Block style */}\n {styleGroup ? (\n <StyleMenu run={run} active={active} onTriggerDown={keepSelection} />\n ) : null}\n\n {/* Inline formatting */}\n {styleGroup && inlineNodes.length > 0 ? <Divider /> : null}\n {inlineNodes}\n\n {hasSecondary ? (\n <>\n {/* Secondary controls inline — shown from 384px. px, not the `@sm`\n rem alias: container-query `rem` follows the host root\n font-size and misfires off a non-16px root. */}\n <div className=\"ds:hidden ds:@[384px]/toolbar:contents\">\n {renderSecondary(hasPrimary)}\n </div>\n\n {/* Overflow \"More\" menu — replaces the inline secondary controls\n below @sm so the bar never wraps onto a second line. */}\n <div className=\"ds:contents ds:@[384px]/toolbar:hidden\">\n {hasPrimary ? <Divider /> : null}\n <Popover>\n <Popover.Trigger asChild>\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<Ellipsis />}\n aria-label={t('editor.more', 'More options')}\n onMouseDown={keepSelection}\n />\n </Popover.Trigger>\n <Popover.Content side=\"bottom\" align=\"end\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n {renderSecondary(false)}\n </div>\n </Popover.Content>\n </Popover>\n </div>\n </>\n ) : null}\n </div>\n </div>\n );\n}\n","/* ------------------------------------------------------------------ */\n/* RichTextEditor — thin, secure wrapper over Redactor (Imperavi). */\n/* */\n/* LICENCE-SAFETY MODEL (read first): */\n/* Redactor is a COMMERCIAL editor and `@alfadocs/ui-kit` publishes */\n/* to PUBLIC npm — so redactor.js bytes MUST NOT enter `dist/`. This */\n/* wrapper never imports Redactor; it resolves a Redactor factory at */\n/* runtime from a `redactor` prop or the UMD globals `window.$R` / */\n/* `window.Redactor` that the CONSUMER's licensed build sets */\n/* (platform ships `web/static/redactor/redactor.js`). With no */\n/* factory found, the editor renders a graceful plain <textarea>. */\n/* Storybook loads a vendored dev-only build via preview-head.html. */\n/* */\n/* - Toolbar/buttons/dropdowns/shortcuts are owned entirely by Redactor */\n/* itself. The kit only skins them via `redactor-theme.css` and feeds */\n/* button presets + lang strings. */\n/* - Security: all inbound HTML (value/defaultValue/setContent) and the */\n/* editor's outbound `changed` HTML run through DOMPurify with an */\n/* explicit FORBID list. Outbound HTML also gets `loading=\"lazy\"` on */\n/* images and platform's empty-placeholder normalisation. */\n/* - Backend-coupled features (image upload, help-me-write, */\n/* voice-recording) are CONSUMER-PROVIDED via `imageUploadUrl` / */\n/* `plugins` / `options`; the kit never bakes a backend route in. */\n/* - i18n: placeholder/aria via `t('editor.placeholder')`; Redactor's */\n/* own `lang` is derived from the active locale (not hardcoded). */\n/* ------------------------------------------------------------------ */\n\nimport {\n Fragment,\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ChangeEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Mic, SpellCheck, Astroid, Square, WandSparkles } from 'lucide-react';\n\nimport '../../tokens/themes/bridges/redactor-theme.css';\n\nimport { sanitiseHtml as sanitiseShared } from '../_shared/safe-html';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { Spinner } from '../spinner';\nimport { richTextEditorAgent } from './rich-text-editor.agent';\nimport { HelpMeWriteOverlay } from './help-me-write-overlay';\nimport {\n EditorToolbar,\n ImageFloatingToolbar,\n TableFloatingToolbar,\n IMAGE_FLOW_CLASSES,\n IMAGE_ALIGN_CLASSES,\n} from './editor-toolbar';\n\n/* ------------------------------------------------------------------ */\n/* Sanitisation */\n/* ------------------------------------------------------------------ */\n\n// Single sanitiser surface (constraints §8): the editor routes every inbound\n// and outbound HTML string through the shared `rich-text` DOMPurify profile in\n// `_shared/safe-html.tsx`, so one audit covers the whole kit. The wrapper adds\n// only editor-specific shaping (normalizeEditorValue + withLazyImages) around it.\nfunction sanitiseHtml(input: string): string {\n return sanitiseShared(input, 'rich-text');\n}\n\n// Mirror platform's RedactorWysiwyg `normalizeEditorValue` (RedactorWysiwyg.js\n// :26-44): map Redactor's empty placeholders to '' for the emptiness test, but\n// preserve image-only HTML so embedded-image notes aren't dropped on save.\nfunction normalizeEditorValue(html = ''): string {\n const normalized = String(html).trim();\n if (\n normalized === '' ||\n normalized === '<p><br></p>' ||\n normalized === '<p> </p>'\n ) {\n return '';\n }\n const contentWithoutTags = normalized\n .replace(/<br\\s*\\/?>/gi, '')\n .replace(/ /gi, '')\n .replace(/<[^>]+>/g, '')\n .trim();\n if (contentWithoutTags === '' && /<img\\b[^>]*>/i.test(normalized)) {\n return normalized;\n }\n return contentWithoutTags === '' ? '' : normalized;\n}\n\n// Inject `loading=\"lazy\"` on any <img> lacking it (platform parity).\nfunction withLazyImages(html: string): string {\n return html.replace(\n /<img(?![^>]*\\sloading=)([^>]*)>/gi,\n '<img loading=\"lazy\"$1>',\n );\n}\n\n// Pull the uploaded image URL out of a Redactor-style imageUpload response.\n// Handles the common shapes: `{ file: { url } }`, `{ url }`, `{ data: { url } }`,\n// and the multi-file map `{ \"1\": { url }, … }`.\nfunction extractUploadedUrl(data: unknown): string | undefined {\n if (!data || typeof data !== 'object') return undefined;\n const rec = data as Record<string, unknown>;\n const fromNode = (node: unknown): string | undefined => {\n if (node && typeof node === 'object' && 'url' in node) {\n const url = (node as { url?: unknown }).url;\n return typeof url === 'string' ? url : undefined;\n }\n return undefined;\n };\n if (typeof rec.url === 'string') return rec.url;\n return (\n fromNode(rec.file) ??\n fromNode(rec.data) ??\n Object.values(rec).map(fromNode).find(Boolean)\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Redactor factory resolution (external — never bundled) */\n/* ------------------------------------------------------------------ */\n\nexport type RedactorFactory = (\n selector: string | HTMLElement,\n command?: unknown,\n ...args: unknown[]\n) => unknown;\n\nfunction resolveRedactor(injected?: RedactorFactory): RedactorFactory | null {\n if (injected) return injected;\n if (typeof window === 'undefined') return null;\n const w = window as unknown as {\n $R?: RedactorFactory;\n Redactor?: RedactorFactory;\n };\n return w.$R ?? w.Redactor ?? null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type RichTextEditorToolbar = 'minimal' | 'standard' | 'full';\n\nexport interface RichTextEditorProps {\n /** Opaque instance id — emitted as `data-component-id` for the agent registry. */\n id?: string;\n /** HTML initial value (uncontrolled). Runs through DOMPurify. */\n defaultValue?: string;\n /** Controlled value (HTML). Sanitised; synced with a skip-once caret guard. */\n value?: string;\n /** Emits on every change — debounced 100ms. `markdown` is '' (Redactor has no serializer). */\n onChange?: (payload: { html: string; markdown: string }) => void;\n /** Toolbar preset → Redactor `buttons`. */\n toolbar?: RichTextEditorToolbar;\n /** Placeholder text — translates via useTranslation if omitted. */\n placeholder?: string;\n /** Read-only mode. */\n readOnly?: boolean;\n /** Accessible name for the editing region. */\n ariaLabel?: string;\n /** Size variant for the minimum block-size of the editing region. */\n minHeight?: 'sm' | 'md' | 'lg';\n /** Show a right-aligned editor-extensions affordance (visual placeholder). */\n showExtensions?: boolean;\n /** Extra class names on the wrapper. */\n className?: string;\n\n /* --- Redactor-specific seams (all CONSUMER-PROVIDED) --- */\n /** Inject the Redactor factory explicitly; else `window.$R` / `window.Redactor`. */\n redactor?: RedactorFactory;\n /** Raw Redactor options, deep-merged LAST over the kit defaults (callbacks reserved). */\n options?: Record<string, unknown>;\n /** Redactor plugin names to enable (the consumer must register/load them). */\n plugins?: string[];\n /** Redactor lang code; default derived from the active i18n locale. */\n lang?: string;\n /** Consumer image-upload endpoint → Redactor `imageUpload`. Omitted if absent. */\n imageUploadUrl?: string;\n /** App keyboard-shortcut seam (e.g. Ctrl/Cmd+Enter to save). */\n onKeyDown?: (event: KeyboardEvent) => void;\n\n /* --- AI assistance (DS-native UI; backend stays consumer-provided) --- */\n /**\n * Help-me-write. When provided, a DS \"Help me write\" action appears; the kit\n * opens a dialog, calls this with the prompt + an AbortSignal, sanitises the\n * returned draft and inserts it at the caret. The backend call / auth /\n * practiceId all live in the consumer's implementation — never in the kit.\n */\n onRequestAiDraft?: (ctx: {\n prompt: string;\n signal: AbortSignal;\n }) => Promise<string>;\n /** Whether `onRequestAiDraft` returns HTML (default) or plain text. */\n aiDraftFormat?: 'html' | 'text';\n /** Override the compliance notice shown in the Help-me-write dialog. */\n aiPrivacyNotice?: ReactNode;\n /**\n * Voice dictation. When provided, a DS mic toggle + live-transcript region\n * appear. The kit owns the UI; the consumer runs mic capture + transcription\n * inside the callback and pushes text back via `onPartialTranscript` (drives\n * the live region) and `onFinalTranscript` (sanitised + inserted at the\n * caret). Resolve when the session ends; honour `signal` to stop. All\n * mic / transcription / backend logic stays consumer-side.\n */\n onDictate?: (ctx: {\n signal: AbortSignal;\n onPartialTranscript: (text: string) => void;\n onFinalTranscript: (text: string) => void;\n }) => Promise<void>;\n /**\n * One-shot AI document actions (CONSUMER-PROVIDED backend). Each gets the\n * current HTML + an AbortSignal and resolves with rewritten HTML; while one\n * runs the editor is disabled with a spinner and the result replaces the whole\n * document. `onProofread` corrects spelling/grammar; `onAutoFormat` tidies the\n * document's structure/formatting. Each adds a FAB segment when provided.\n */\n onProofread?: (ctx: { html: string; signal: AbortSignal }) => Promise<string>;\n onAutoFormat?: (ctx: {\n html: string;\n signal: AbortSignal;\n }) => Promise<string>;\n}\n\n/** Block/inline formats the editor can toggle via `applyFormat`. */\nexport type EditorFormat =\n | 'bold'\n | 'italic'\n | 'strikethrough'\n | 'bulletedList'\n | 'numberedList'\n | 'heading'\n | 'quote'\n | 'paragraph';\n\n// Maps each format to its Redactor command (shared with the toolbar).\nconst FORMAT_COMMANDS: Record<EditorFormat, [string, ...unknown[]]> = {\n bold: ['module.inline.format', { tag: 'b' }],\n italic: ['module.inline.format', { tag: 'i' }],\n strikethrough: ['module.inline.format', { tag: 'del' }],\n bulletedList: ['module.list.toggle', 'ul'],\n numberedList: ['module.list.toggle', 'ol'],\n heading: ['module.block.format', { tag: 'h2' }],\n quote: ['module.block.format', { tag: 'blockquote' }],\n paragraph: ['module.block.format', { tag: 'p' }],\n};\n\nexport interface RichTextEditorHandle {\n getHTML: () => string;\n /** Plain-text content of the editor (tags stripped). */\n getText: () => string;\n /** Always '' — Redactor has no native Markdown serializer (see MDX). */\n getMarkdown: () => string;\n /** HTML goes through DOMPurify before reaching Redactor. */\n setContent: (html: string) => void;\n /**\n * Insert content at the caret (replacing any selection). HTML is\n * DOMPurify-sanitised; pass `{ asHtml: false }` for a plain-text insert.\n * Works with the degraded <textarea> too. This is the seam for inserting\n * merge/template variables and AI-generated drafts.\n */\n insertAtCursor: (content: string, opts?: { asHtml?: boolean }) => void;\n /** Toggle/apply a block or inline format on the current selection. */\n applyFormat: (format: EditorFormat) => void;\n focus: () => void;\n clear: () => void;\n}\n\n// Map the kit's locale codes to Redactor's lang-file codes where they differ\n// (Redactor ships zh_cn / zh_tw / pt_br; the kit uses zh / pt). RTL (ar/fa/he)\n// pass through — direction is handled by the document dir, not the lang code.\nconst REDACTOR_LANG: Record<string, string> = {\n zh: 'zh_cn',\n pt: 'pt_br',\n};\n\nfunction toRedactorLang(locale: string): string {\n const base = locale.split('-')[0];\n return REDACTOR_LANG[base] ?? base ?? 'en';\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst wrapperVariants = cva(\n 'redactor-theme-alfadocs ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n);\n\n// Degraded-mode plain textarea (Redactor not found) — looks like a kit field.\nconst degradedTextareaVariants = cva(\n [\n 'ds:block ds:[inline-size:100%]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[color:var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:shadow-[var(--shadow-md)]',\n 'ds:font-[family-name:var(--font-sans)] ds:text-[length:var(--font-size-base)]',\n 'ds:p-[var(--spacing-md)] ds:[min-block-size:var(--rich-text-editor-min-block-size)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n);\n\n// Split-FAB segment: an icon button inside the primary pill (record |\n// help-me-write). Transparent on the pill with an INSET focus ring (the pill\n// clips overflow, so the ring must be inset).\nconst fabSegmentBase = [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]',\n 'ds:text-[color:var(--primary-foreground)]',\n 'ds:transition-colors',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--primary-foreground)]',\n 'ds:focus-visible:[outline-offset:calc(var(--focus-ring-width)*-1)]',\n].join(' ');\n\n// Idle segment: a translucent-white hover overlay over the pill.\nconst fabSegmentIdle = `${fabSegmentBase} ds:hover:bg-[color-mix(in_srgb,var(--primary-foreground)_15%,transparent)]`;\n\n// Recording mic: a solid destructive (red) fill that stays red on hover so the\n// \"stop\" state reads as live recording. Deliberately no aria-pressed translucent\n// overlay — its attribute selector out-specifies the red and would wash it out.\nconst fabSegmentRecording = `${fabSegmentBase} ds:bg-[var(--destructive)] ds:hover:bg-[color-mix(in_srgb,var(--destructive)_88%,var(--primary-foreground))]`;\n\n/* ------------------------------------------------------------------ */\n/* RichTextEditor */\n/* ------------------------------------------------------------------ */\n\nexport const RichTextEditor = forwardRef<\n RichTextEditorHandle,\n RichTextEditorProps\n>(\n (\n {\n id,\n defaultValue,\n value,\n onChange,\n toolbar = 'standard',\n placeholder,\n readOnly = false,\n ariaLabel,\n minHeight,\n showExtensions,\n className,\n redactor,\n options,\n plugins,\n lang,\n imageUploadUrl,\n onKeyDown,\n onRequestAiDraft,\n aiDraftFormat = 'html',\n aiPrivacyNotice,\n onDictate,\n onProofread,\n onAutoFormat,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const rawId = useId();\n const editorId = useMemo(\n () => `rte-${rawId.replace(/[^a-zA-Z0-9-_]/g, '')}`,\n [rawId],\n );\n const selector = `#${editorId}`;\n\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const redactorRef = useRef<RedactorFactory | null>(null);\n // Skip-once guard: Redactor's `changed` already pushed this value out via\n // onChange, so the controlled-value effect must not echo it back with\n // setCode (which resets the caret to position 0). Mirrors platform.\n const skipNextPropSyncRef = useRef(false);\n // Mirrors the live readOnly state for imperative ops: Redactor blocks every\n // command except `disableReadOnly` while read-only, so writes (setContent /\n // clear / insertAtCursor / controlled-value sync) must lift it first.\n const readOnlyRef = useRef(readOnly);\n const wrapperRef = useRef<HTMLDivElement>(null);\n // The positioned editing-surface container — the floating table toolbar is\n // absolutely placed within it.\n const editorAreaRef = useRef<HTMLDivElement>(null);\n const [degraded, setDegraded] = useState(false);\n const [aiOpen, setAiOpen] = useState(false);\n // Active formats at the caret (bold/italic/strike/ul/ol/heading) — drives\n // the custom toolbar's pressed state; refreshed on Redactor's `observe`.\n const [activeFormats, setActiveFormats] = useState<ReadonlySet<string>>(\n () => new Set(),\n );\n // The <img> the user has selected (clicked) in this editor's editable, or\n // null — drives the ImageFloatingToolbar (wrap / align / resize). The ref\n // mirrors the state so the apply seams read the live element synchronously.\n const activeImageElRef = useRef<HTMLElement | null>(null);\n const [activeImageEl, setActiveImageEl] = useState<HTMLElement | null>(\n null,\n );\n const selectImage = useCallback((el: HTMLElement | null): void => {\n activeImageElRef.current = el;\n setActiveImageEl(el);\n }, []);\n\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const onChangeRef = useRef<RichTextEditorProps['onChange']>(onChange);\n const onKeyDownRef = useRef<RichTextEditorProps['onKeyDown']>(onKeyDown);\n useEffect(() => {\n onChangeRef.current = onChange;\n onKeyDownRef.current = onKeyDown;\n }, [onChange, onKeyDown]);\n\n // Initial content is computed once (controlled `value` is then synced by\n // the effect below). Sanitised before it ever reaches Redactor.\n const initialContentRef = useRef<string>(\n (() => {\n const raw = value ?? defaultValue ?? '';\n return raw ? sanitiseHtml(raw) : '';\n })(),\n );\n\n // Read the current editor HTML. Redactor's `source.getCode` is blocked while\n // read-only (returns undefined), so fall back to the synced source textarea\n // — never toggle read-only just to read.\n const readCode = useCallback((): string => {\n const R = redactorRef.current;\n if (R) {\n try {\n const code = R(selector, 'source.getCode');\n if (typeof code === 'string') return code;\n } catch {\n /* fall through to the source textarea */\n }\n }\n return textareaRef.current?.value ?? '';\n }, [selector]);\n\n // Dispatch a mutating Redactor command, transparently lifting read-only\n // (which blocks every command but `disableReadOnly`) and restoring it after.\n // Returns false when Redactor is absent or the call failed so the caller can\n // fall back to the degraded <textarea>.\n const dispatchWrite = useCallback(\n (command: string, ...args: unknown[]): boolean => {\n const R = redactorRef.current;\n if (!R) return false;\n const wasReadOnly = readOnlyRef.current;\n if (wasReadOnly) {\n try {\n R(selector, 'disableReadOnly');\n } catch {\n /* ignore */\n }\n }\n try {\n R(selector, command, ...args);\n return true;\n } catch {\n return false;\n } finally {\n if (wasReadOnly) {\n try {\n R(selector, 'enableReadOnly');\n } catch {\n // Restore failed — the editor may be left editable. Surface it in\n // DEV; the next readOnly-sync tick re-asserts it on a prop change.\n if (import.meta.env.DEV) {\n console.warn(\n '[RichTextEditor] failed to restore read-only after a write; the editor may be left editable.',\n );\n }\n }\n }\n }\n },\n [selector],\n );\n\n // Insert content at the caret, sanitised, with a degraded <textarea> splice\n // fallback. Shared by the imperative handle (merge variables) and the\n // Help-me-write dialog (AI drafts).\n const insertAtCursor = useCallback(\n (content: string, opts?: { asHtml?: boolean }): void => {\n const asHtml = opts?.asHtml ?? true;\n const payload = asHtml ? sanitiseHtml(content) : content;\n const command = asHtml\n ? 'insertion.insertHtml'\n : 'insertion.insertText';\n if (dispatchWrite(command, payload)) return;\n const ta = textareaRef.current;\n if (!ta) return;\n const start = ta.selectionStart ?? ta.value.length;\n const end = ta.selectionEnd ?? ta.value.length;\n ta.value = ta.value.slice(0, start) + payload + ta.value.slice(end);\n const caret = start + payload.length;\n try {\n ta.setSelectionRange(caret, caret);\n } catch {\n /* selection API unavailable */\n }\n onChangeRef.current?.({ html: sanitiseHtml(ta.value), markdown: '' });\n },\n [dispatchWrite],\n );\n\n // Last in-editor selection range — see updateActiveFormats / restoreSelection.\n const lastRangeRef = useRef<Range | null>(null);\n\n // Recompute the active inline/block formats at the caret (scoped to THIS\n // editor's `.redactor-in`) for the custom toolbar's pressed state.\n const updateActiveFormats = useCallback((): void => {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection =\n typeof window !== 'undefined' ? window.getSelection() : null;\n const next = new Set<string>();\n if (\n root &&\n selection &&\n selection.anchorNode &&\n root.contains(selection.anchorNode) &&\n typeof document.queryCommandState === 'function'\n ) {\n // Track the live in-editor range so a focus-stealing DS popover/dialog\n // can restore EXACTLY here — needed because Redactor's insertHtml wraps\n // the insert in a fresh <p> when no selection is active at insert time.\n if (selection.rangeCount > 0) {\n lastRangeRef.current = selection.getRangeAt(0).cloneRange();\n }\n // queryCommandState reads the selection's EFFECTIVE format (it handles\n // range boundaries + nesting), unlike walking the anchor's ancestors —\n // which misses a format when the anchor sits just outside the wrapper.\n try {\n if (document.queryCommandState('bold')) next.add('bold');\n if (document.queryCommandState('italic')) next.add('italic');\n if (document.queryCommandState('underline')) next.add('underline');\n if (document.queryCommandState('strikeThrough')) next.add('strike');\n if (document.queryCommandState('insertUnorderedList')) next.add('ul');\n if (document.queryCommandState('insertOrderedList')) next.add('ol');\n const block = String(\n document.queryCommandValue('formatBlock') || '',\n ).toLowerCase();\n // Add both the generic 'heading' token and the specific block tag\n // (h2/h3/quote/paragraph) so the toolbar's labelled style button can\n // show the active style by name.\n if (/^h[1-6]$/.test(block)) {\n next.add('heading');\n next.add(block);\n } else if (block === 'blockquote') {\n next.add('quote');\n } else {\n next.add('paragraph');\n }\n // Table context — drives the contextual table ops in the toolbar.\n const anchorEl =\n selection.anchorNode.nodeType === Node.TEXT_NODE\n ? selection.anchorNode.parentElement\n : (selection.anchorNode as Element | null);\n if (\n anchorEl &&\n root.contains(anchorEl) &&\n anchorEl.closest('table')\n ) {\n next.add('table');\n }\n } catch {\n /* queryCommand unsupported in this environment */\n }\n }\n setActiveFormats((prev) =>\n prev.size === next.size && [...next].every((f) => prev.has(f))\n ? prev\n : next,\n );\n }, []);\n\n // Run a Redactor command from the custom toolbar, then refresh active state.\n const runCommand = useCallback(\n (command: string, ...args: unknown[]): void => {\n dispatchWrite(command, ...args);\n // Defer the active-state read: let Redactor finish applying the command\n // and the selection settle first, otherwise un-toggling a format reads\n // the stale pre-change DOM and the button stays pressed.\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n } else {\n updateActiveFormats();\n }\n },\n [dispatchWrite, updateActiveFormats],\n );\n\n // Inline-format keyboard shortcuts (Cmd/Ctrl + B/I/U). Redactor ships these\n // natively, but with `toolbar: false` its shortcut fires yet silently no-ops\n // (it preventDefaults the key, then its inline.format applies nothing). So\n // the kit owns them: intercept on the editor in the capture phase — before\n // Redactor's own keydown listener — and route through the SAME runCommand\n // path the toolbar uses (which works). stopImmediatePropagation suppresses\n // Redactor's dead handler; preventDefault suppresses the browser's native\n // execCommand so the format applies exactly once.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (!wrapper) return undefined;\n // Local key→command map (the same inline commands the toolbar buttons\n // fire) so this owns nothing on the public format API.\n const SHORTCUT_COMMANDS: Record<string, [string, ...unknown[]]> = {\n b: ['module.inline.format', { tag: 'b' }],\n i: ['module.inline.format', { tag: 'i' }],\n u: ['module.inline.format', { tag: 'u' }],\n };\n const onKeyDownCapture = (event: KeyboardEvent): void => {\n if (!(event.metaKey || event.ctrlKey) || event.altKey || event.shiftKey)\n return;\n if (event.isComposing) return;\n const command = SHORTCUT_COMMANDS[event.key.toLowerCase()];\n if (!command) return;\n // Only when the caret is in this editor's editable, and it's writable.\n const editable = wrapper.querySelector('.redactor-in');\n if (\n !editable ||\n !(event.target instanceof Node) ||\n !editable.contains(event.target) ||\n readOnlyRef.current\n )\n return;\n event.preventDefault();\n event.stopImmediatePropagation();\n runCommand(...command);\n };\n wrapper.addEventListener('keydown', onKeyDownCapture, true);\n return () =>\n wrapper.removeEventListener('keydown', onKeyDownCapture, true);\n }, [runCommand]);\n\n // Insert sanitised HTML at the caret — the toolbar's link/image dialogs use\n // this (DOMPurify runs inside insertAtCursor) instead of Redactor's native\n // modals.\n const insertHtml = useCallback(\n (html: string): void => {\n insertAtCursor(html, { asHtml: true });\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [insertAtCursor, updateActiveFormats],\n );\n\n // Save / restore the editor selection around a DS popover/dialog (which\n // takes focus and would otherwise collapse the caret). Backed by Redactor's\n // selection module; no-ops in the degraded textarea.\n const saveSelection = useCallback((): void => {\n // Snapshot the current in-editor range synchronously (before a trigger's\n // focus move can collapse it), in addition to the observe-driven tracking.\n if (typeof window !== 'undefined') {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const sel = window.getSelection();\n if (\n root &&\n sel &&\n sel.rangeCount > 0 &&\n sel.anchorNode &&\n root.contains(sel.anchorNode)\n ) {\n lastRangeRef.current = sel.getRangeAt(0).cloneRange();\n }\n }\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'selection.save');\n } catch {\n /* selection module unavailable */\n }\n }\n }, [selector]);\n\n const restoreSelection = useCallback((): void => {\n const R = redactorRef.current;\n if (!R) return;\n // Re-focus the editor, then re-apply the tracked DOM range. This is more\n // reliable than Redactor's marker-based restore when a modal's focus trap\n // moved focus before the markers were set — without an active selection\n // Redactor's insertHtml wraps the insert in a new <p> (the link/image\n // \"block\" bug). Fall back to the marker restore if no range was tracked.\n // Capture the tracked range BEFORE editor.focus: focusing fires Redactor's\n // `observe`, which runs updateActiveFormats and overwrites lastRangeRef with\n // the post-focus caret (editor start). Reading it first preserves the\n // user's real selection (otherwise colour/link land at the top of the doc).\n const range = lastRangeRef.current;\n try {\n R(selector, 'editor.focus');\n } catch {\n /* ignore */\n }\n if (range && typeof window !== 'undefined') {\n const sel = window.getSelection();\n if (sel) {\n try {\n sel.removeAllRanges();\n sel.addRange(range);\n return;\n } catch {\n /* range no longer valid — fall through to marker restore */\n }\n }\n }\n try {\n R(selector, 'selection.restore');\n } catch {\n /* selection module unavailable */\n }\n }, [selector]);\n\n // Current selected text (for prefilling the link dialog's text field).\n const getSelectedText = useCallback((): string => {\n if (typeof window === 'undefined') return '';\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n if (\n !root ||\n !selection ||\n !selection.anchorNode ||\n !root.contains(selection.anchorNode)\n ) {\n return '';\n }\n return selection.toString();\n }, []);\n\n // The <table> the caret is currently inside (scoped to THIS editor's\n // `.redactor-in`), or null — drives the floating in-cell table toolbar's\n // visibility + anchor. Mirrors the table detection in updateActiveFormats.\n const getActiveTableEl = useCallback((): HTMLElement | null => {\n if (typeof window === 'undefined') return null;\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n if (!root || !selection || selection.rangeCount === 0) return null;\n const node = selection.anchorNode;\n const el =\n node && node.nodeType === Node.TEXT_NODE\n ? node.parentElement\n : (node as Element | null);\n if (!el || !root.contains(el)) return null;\n return el.closest('table');\n }, []);\n\n // The <td>/<th> the caret is in (scoped to this editor) — backs the table\n // background-colour controls.\n const lastCellRef = useRef<HTMLElement | null>(null);\n const getActiveCellEl = useCallback((): HTMLElement | null => {\n if (typeof window === 'undefined') return null;\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n if (!root || !selection || selection.rangeCount === 0) return null;\n const node = selection.anchorNode;\n const el =\n node && node.nodeType === Node.TEXT_NODE\n ? node.parentElement\n : (node as Element | null);\n if (!el || !root.contains(el)) return null;\n return el.closest('td,th') as HTMLElement | null;\n }, []);\n\n // Snapshot the current cell before a colour popover steals focus.\n const saveTableCell = useCallback((): void => {\n lastCellRef.current = getActiveCellEl();\n }, [getActiveCellEl]);\n\n // Apply (colour) or clear (colour === null) a background on the saved cell,\n // or every cell in its row. Redactor has no cell-styling command, so this\n // mutates the editable DOM directly, takes a best-effort undo snapshot, then\n // hard-syncs so the change lands in the source + fires `changed` → onChange.\n const applyTableBackground = useCallback(\n (scope: 'cell' | 'row', colour: string | null): void => {\n const cell = lastCellRef.current ?? getActiveCellEl();\n if (!cell) return;\n const targets: HTMLElement[] =\n scope === 'row'\n ? Array.from(cell.closest('tr')?.children ?? [cell]).filter(\n (n): n is HTMLElement =>\n n instanceof HTMLElement &&\n (n.tagName === 'TD' || n.tagName === 'TH'),\n )\n : [cell];\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'module.buffer.trigger');\n } catch {\n /* undo buffer unavailable — colour still applies */\n }\n }\n for (const el of targets) {\n if (colour) el.style.setProperty('background-color', colour);\n else el.style.removeProperty('background-color');\n }\n if (R) {\n try {\n R(selector, 'broadcast', 'hardsync');\n } catch {\n /* sync unavailable */\n }\n }\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [getActiveCellEl, selector, updateActiveFormats],\n );\n\n // Track which image is selected: a click inside the editable selects the\n // clicked <img> (or clears when it lands on non-image content); Escape\n // deselects; focus leaving the whole editor clears. Clicks on the floating\n // controls (outside `.redactor-in`) keep the current selection so its bar\n // stays reachable. Scoped to THIS editor's wrapper.\n useEffect(() => {\n const wrapper = wrapperRef.current;\n if (typeof window === 'undefined' || !wrapper) return undefined;\n const onClick = (event: MouseEvent): void => {\n const editable = wrapper.querySelector('.redactor-in');\n const target = event.target;\n if (\n !editable ||\n !(target instanceof Node) ||\n !editable.contains(target)\n )\n return;\n const img = target instanceof Element ? target.closest('img') : null;\n selectImage(img && editable.contains(img) ? img : null);\n };\n const onKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Escape' && activeImageElRef.current) {\n selectImage(null);\n }\n };\n const onFocusOut = (event: FocusEvent): void => {\n const next = event.relatedTarget;\n if (!(next instanceof Node) || !wrapper.contains(next)) {\n selectImage(null);\n }\n };\n wrapper.addEventListener('click', onClick);\n wrapper.addEventListener('keydown', onKeyDown);\n wrapper.addEventListener('focusout', onFocusOut);\n return () => {\n wrapper.removeEventListener('click', onClick);\n wrapper.removeEventListener('keydown', onKeyDown);\n wrapper.removeEventListener('focusout', onFocusOut);\n };\n }, [selectImage]);\n\n // Apply (or replace) a `wysiwyg-img-*` layout class within its group on the\n // selected image. Mirrors applyTableBackground: snapshot undo, mutate the\n // editable DOM directly (Redactor has no image-class command), then hard-\n // sync so the change lands in the source + fires `changed` → onChange.\n const applyImageClass = useCallback(\n (className: string): void => {\n const img = activeImageElRef.current;\n if (!img) return;\n const group = (IMAGE_FLOW_CLASSES as readonly string[]).includes(\n className,\n )\n ? IMAGE_FLOW_CLASSES\n : IMAGE_ALIGN_CLASSES;\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'module.buffer.trigger');\n } catch {\n /* undo buffer unavailable — class still applies */\n }\n }\n for (const c of group) img.classList.remove(c);\n img.classList.add(className);\n if (R) {\n try {\n R(selector, 'broadcast', 'hardsync');\n } catch {\n /* sync unavailable */\n }\n }\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [selector, updateActiveFormats],\n );\n\n // Set the selected image's width as a % of its editable box. The width is\n // an inline style (the only continuous-value carrier; survives the rich-\n // text DOMPurify profile) — same runtime-DOM-mutation seam as the table\n // colour control, not a JSX inline style.\n const setImageWidth = useCallback(\n (pct: number): void => {\n const img = activeImageElRef.current;\n if (!img) return;\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'module.buffer.trigger');\n } catch {\n /* undo buffer unavailable — width still applies */\n }\n }\n img.style.setProperty('width', `${pct}%`);\n if (R) {\n try {\n R(selector, 'broadcast', 'hardsync');\n } catch {\n /* sync unavailable */\n }\n }\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => updateActiveFormats());\n }\n },\n [selector, updateActiveFormats],\n );\n\n // Insert a table, but never inside a list item — tables can't live in an\n // <li> and the nested markup hides the table UI. When the caret is in a\n // list, drop it after the whole list so the table lands as its own block.\n const insertTable = useCallback(\n (html: string): void => {\n const R = redactorRef.current;\n if (R && typeof window !== 'undefined') {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n const selection = window.getSelection();\n const node = selection?.anchorNode;\n const el =\n node && node.nodeType === Node.TEXT_NODE\n ? node.parentElement\n : (node as Element | null);\n const list = el && root?.contains(el) ? el.closest('ul,ol') : null;\n if (list) {\n try {\n R(selector, 'caret.setAfter', list);\n } catch {\n /* caret module unavailable — falls back to cursor insert */\n }\n }\n }\n insertHtml(html);\n // Redactor's insertion leaves a stray trailing whitespace text node in\n // the final cell (<td><br> </td>); that space renders as a second line\n // and makes the last row taller WHILE EDITING. The saved source is\n // already clean (cleaner.output strips it), so just tidy the live\n // editable so every row renders at one line.\n if (typeof window !== 'undefined') {\n window.requestAnimationFrame(() => {\n const root = wrapperRef.current?.querySelector('.redactor-in');\n root?.querySelectorAll('table td, table th').forEach((cell) => {\n let last = cell.lastChild;\n while (\n last &&\n last.nodeType === Node.TEXT_NODE &&\n !(last.textContent ?? '').trim()\n ) {\n const prev = last.previousSibling;\n cell.removeChild(last);\n last = prev;\n }\n });\n });\n }\n },\n [insertHtml, selector],\n );\n\n // Upload an image file to the consumer's endpoint (mirrors Redactor's\n // imageUpload config) and resolve the stored URL — the image dialog's\n // upload tab uses this so users can upload, not just paste a URL.\n const uploadImage = useCallback(\n async (file: File, signal?: AbortSignal): Promise<string> => {\n if (!imageUploadUrl) throw new Error('No image upload URL configured.');\n const form = new FormData();\n form.append('file', file);\n const res = await fetch(imageUploadUrl, {\n method: 'POST',\n body: form,\n credentials: 'same-origin',\n signal,\n });\n if (!res.ok) throw new Error(`Image upload failed (${res.status}).`);\n const url = extractUploadedUrl(await res.json());\n if (!url) throw new Error('Image upload response contained no URL.');\n return url;\n },\n [imageUploadUrl],\n );\n\n /* ---- Voice dictation (DS UI; consumer runs mic + transcription) - */\n const dictateAbortRef = useRef<AbortController | null>(null);\n const interimRef = useRef<HTMLElement | null>(null);\n const [isDictating, setIsDictating] = useState(false);\n const [dictationErrored, setDictationErrored] = useState(false);\n // Drives the visually-hidden live region: announces the listening status on\n // start and each committed phrase as it lands, so screen-reader users get\n // the same feedback sighted users get from the grey interim span + caret.\n const [dictationAnnouncement, setDictationAnnouncement] = useState('');\n\n // Live (interim) speech shown in the editor as a grey, non-editable span\n // with a blinking caret; replaced by committed text on each final phrase.\n const clearInterim = useCallback((): void => {\n const el = interimRef.current;\n if (el?.parentNode) el.parentNode.removeChild(el);\n interimRef.current = null;\n }, []);\n\n const showInterim = useCallback((text: string): void => {\n const root = wrapperRef.current?.querySelector(\n '.redactor-in',\n ) as HTMLElement | null;\n if (!root) return;\n let el = interimRef.current;\n if (!el || !root.contains(el)) {\n el = document.createElement('span');\n el.setAttribute('data-rte-interim', '');\n el.setAttribute('contenteditable', 'false');\n const selection = window.getSelection();\n if (\n selection &&\n selection.rangeCount > 0 &&\n root.contains(selection.anchorNode)\n ) {\n const range = selection.getRangeAt(0);\n range.collapse(false);\n range.insertNode(el);\n } else {\n root.appendChild(el);\n }\n interimRef.current = el;\n }\n el.textContent = text;\n }, []);\n\n const stopDictation = useCallback(() => {\n // Abort but keep the ref: the in-flight session's `.finally` clears it\n // (and resets state) only when it's still the current session, so a normal\n // stop resets while a stale settle after a newer start does not.\n dictateAbortRef.current?.abort();\n }, []);\n\n const startDictation = useCallback(() => {\n if (!onDictate) return;\n const controller = new AbortController();\n dictateAbortRef.current = controller;\n setDictationErrored(false);\n setIsDictating(true);\n setDictationAnnouncement(t('editor.ai.listening'));\n clearInterim();\n onDictate({\n signal: controller.signal,\n // Interim text shows live in the editor (grey + caret); each final\n // replaces it with committed text at the caret.\n onPartialTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n showInterim(text);\n },\n onFinalTranscript: (text: string): void => {\n if (controller.signal.aborted) return;\n clearInterim();\n const trimmed = text.trim();\n if (trimmed) {\n insertAtCursor(`${trimmed} `, { asHtml: false });\n // Announce the committed phrase; it replaces the interim text the\n // SR could not perceive (the grey span is aria-hidden DOM injected\n // outside React's tree).\n setDictationAnnouncement(trimmed);\n }\n },\n })\n .catch((err: unknown) => {\n if (\n controller.signal.aborted ||\n (err &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name?: string }).name === 'AbortError')\n ) {\n return;\n }\n setDictationErrored(true);\n })\n .finally(() => {\n clearInterim();\n // Only the session that still owns the ref resets state — a stale\n // settle (a newer session already started) must not clobber it.\n if (dictateAbortRef.current === controller) {\n dictateAbortRef.current = null;\n setIsDictating(false);\n setDictationAnnouncement('');\n }\n });\n }, [onDictate, insertAtCursor, clearInterim, showInterim, t]);\n\n const toggleDictation = useCallback(() => {\n if (isDictating) stopDictation();\n else startDictation();\n }, [isDictating, startDictation, stopDictation]);\n\n // Abort dictation on unmount.\n useEffect(() => () => dictateAbortRef.current?.abort(), []);\n\n /* ---- One-shot AI document actions (proofread / auto-format) ---- */\n // Which one-shot action is running (drives the FAB spinner + the editor's\n // disabled scrim); only one runs at a time.\n const [oneShot, setOneShot] = useState<'proofread' | 'format' | null>(null);\n const oneShotAbortRef = useRef<AbortController | null>(null);\n const runOneShot = useCallback(\n (\n kind: 'proofread' | 'format',\n fn: (ctx: { html: string; signal: AbortSignal }) => Promise<string>,\n ): void => {\n if (oneShotAbortRef.current) return; // one at a time\n const controller = new AbortController();\n oneShotAbortRef.current = controller;\n setOneShot(kind);\n const html = readCode();\n Promise.resolve(fn({ html, signal: controller.signal }))\n .then((result) => {\n if (controller.signal.aborted) return;\n // Replace the whole document with the rewritten HTML (re-sanitised\n // at the editor seam) and notify the consumer.\n const safe = sanitiseHtml(String(result ?? ''));\n dispatchWrite('source.setCode', safe);\n onChangeRef.current?.({ html: safe, markdown: '' });\n })\n .catch(() => {\n /* abort / backend error — leave the document unchanged */\n })\n .finally(() => {\n if (oneShotAbortRef.current === controller) {\n oneShotAbortRef.current = null;\n setOneShot(null);\n }\n });\n },\n [readCode, dispatchWrite],\n );\n\n // Cancel a running one-shot. Clears the UI immediately (and aborts the\n // signal) rather than waiting on the promise, so the user always recovers\n // even if the consumer's call ignores the signal / hangs — the settle\n // guards (aborted + ref identity) then make the late result a no-op.\n const cancelOneShot = useCallback((): void => {\n oneShotAbortRef.current?.abort();\n oneShotAbortRef.current = null;\n setOneShot(null);\n }, []);\n\n // Abort an in-flight one-shot on unmount.\n useEffect(() => () => oneShotAbortRef.current?.abort(), []);\n\n /* ---- Init Redactor once (or degrade gracefully) -------------- */\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return undefined;\n // Seed the host textarea imperatively: Redactor reads it on init, and in\n // degraded mode it stays as the textarea's shown value. (Done here, not\n // via `defaultValue`, because `degraded` flips after mount so a\n // `defaultValue` prop would never apply.)\n ta.value = initialContentRef.current;\n const R = resolveRedactor(redactor);\n if (!R) {\n setDegraded(true);\n if (import.meta.env.DEV) {\n console.warn(\n '[RichTextEditor] Redactor not found on window.$R / window.Redactor and no `redactor` prop supplied; rendering a plain textarea.',\n );\n }\n return undefined;\n }\n redactorRef.current = R;\n\n const kitDefaults: Record<string, unknown> = {\n lang: lang ?? toRedactorLang(i18n.language || 'en'),\n // The kit renders its OWN toolbar (EditorToolbar) and drives Redactor\n // via the command API, so Redactor's native toolbar is suppressed.\n toolbar: false,\n plugins: plugins ?? [],\n placeholder: placeholder ?? t('editor.placeholder'),\n toolbarFixed: false,\n // Platform parity (RedactorWysiwyg.js:84): no inline shortcode expansion.\n shortcodes: false,\n // The kit owns image editing: ImageFloatingToolbar provides DS-native,\n // keyboard-accessible resize + wrap/align, so Redactor's own image\n // popup AND its single-handle drag-resizer are both disabled to avoid a\n // second, untokenised, mouse-only UI competing with ours.\n imageEditable: false,\n imageResizable: false,\n };\n const imageUploadOption = imageUploadUrl\n ? { imageUpload: imageUploadUrl }\n : {};\n\n const consumerCallbacks =\n (options?.callbacks as Record<string, unknown> | undefined) ?? {};\n\n const finalOptions: Record<string, unknown> = {\n ...kitDefaults,\n ...imageUploadOption,\n ...(options ?? {}),\n // Re-pin safety-critical keys LAST so consumer `options` can't override\n // the sanitising change handler or re-enable Redactor's native image UI\n // (the kit's ImageFloatingToolbar replaces both — see kitDefaults above).\n imageEditable: false,\n imageResizable: false,\n callbacks: {\n ...consumerCallbacks,\n changed(html: string): void {\n const normalized = normalizeEditorValue(withLazyImages(html));\n const safe = sanitiseHtml(normalized);\n skipNextPropSyncRef.current = true;\n if (!onChangeRef.current) return;\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(() => {\n onChangeRef.current?.({ html: safe, markdown: '' });\n }, 100);\n },\n keydown(event: KeyboardEvent): void {\n onKeyDownRef.current?.(event);\n },\n observe(): void {\n updateActiveFormats();\n },\n },\n };\n\n try {\n R(selector, finalOptions);\n // Redactor's read-only commands are camel-cased `enableReadOnly` /\n // `disableReadOnly` in this build (lower-case `enableReadonly` is a\n // silent no-op). Guarded so an unknown command stays inert.\n if (readOnly) {\n try {\n R(selector, 'enableReadOnly');\n } catch {\n /* readonly command unsupported in this Redactor build */\n }\n }\n } catch {\n setDegraded(true);\n }\n\n return () => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n try {\n // Platform forgets to destroy and leaks; we clean up on unmount.\n R(selector, 'destroy');\n } catch {\n /* already torn down */\n }\n redactorRef.current = null;\n };\n // Init once — option changes after mount are not re-applied (matches the\n // editor's uncontrolled-internals model); value/readOnly sync below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /* ---- Keep controlled `value` in sync (skip-once caret guard) - */\n useEffect(() => {\n if (!redactorRef.current || value === undefined) return;\n if (skipNextPropSyncRef.current) {\n skipNextPropSyncRef.current = false;\n return;\n }\n const safe = sanitiseHtml(normalizeEditorValue(value));\n const current = normalizeEditorValue(readCode());\n if (current !== safe) dispatchWrite('source.setCode', safe);\n }, [value, readCode, dispatchWrite]);\n\n /* ---- Keep readOnly in sync ----------------------------------- */\n useEffect(() => {\n readOnlyRef.current = readOnly;\n const R = redactorRef.current;\n if (!R) return;\n try {\n R(selector, readOnly ? 'enableReadOnly' : 'disableReadOnly');\n } catch {\n /* readonly command unsupported in this Redactor build */\n }\n }, [readOnly, selector]);\n\n /* ---- Degraded fallback: reflect controlled `value` ----------- */\n // Without Redactor the host textarea is uncontrolled (seeded once on init),\n // so it would otherwise ignore external `value` updates. Sync imperatively\n // (a controlled `value=` would warn when `degraded` flips after mount), and\n // skip while focused so we never reset the user's caret mid-type.\n useEffect(() => {\n if (!degraded || value === undefined) return;\n const ta = textareaRef.current;\n if (!ta) return;\n const safe = sanitiseHtml(value);\n if (ta.value !== safe && document.activeElement !== ta) {\n ta.value = safe;\n }\n }, [degraded, value]);\n\n /* ---- Imperative handle --------------------------------------- */\n const handle = useMemo<RichTextEditorHandle>(\n () => ({\n getHTML(): string {\n return readCode();\n },\n getText(): string {\n return readCode()\n .replace(/<[^>]*>/g, ' ')\n .replace(/ /gi, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n },\n getMarkdown(): string {\n return '';\n },\n setContent(html: string): void {\n const safe = sanitiseHtml(html);\n if (dispatchWrite('source.setCode', safe)) return;\n if (textareaRef.current) textareaRef.current.value = safe;\n },\n insertAtCursor,\n applyFormat(format): void {\n const command = FORMAT_COMMANDS[format];\n if (command) runCommand(...command);\n },\n focus(): void {\n const R = redactorRef.current;\n if (R) {\n try {\n R(selector, 'editor.focus');\n return;\n } catch {\n /* fall through */\n }\n }\n textareaRef.current?.focus();\n },\n clear(): void {\n if (dispatchWrite('source.setCode', '')) return;\n if (textareaRef.current) textareaRef.current.value = '';\n },\n }),\n [selector, readCode, dispatchWrite, insertAtCursor, runCommand],\n );\n useImperativeHandle(ref, () => handle, [handle]);\n useAgentRegistration(richTextEditorAgent, handle, id);\n\n /* ---- Degraded-mode change handler ---------------------------- */\n const handleDegradedChange = useCallback(\n (event: ChangeEvent<HTMLTextAreaElement>): void => {\n onChangeRef.current?.({\n html: sanitiseHtml(event.target.value),\n markdown: '',\n });\n },\n [],\n );\n\n // Accessible name for the editing region — a dedicated label, not the\n // placeholder, so the region's name and its placeholder hint don't collide.\n const resolvedLabel = ariaLabel ?? t('editor.regionLabel');\n const resolvedPlaceholder = placeholder ?? t('editor.placeholder');\n\n /* ---- Normalise Redactor's editing-surface ARIA --------------- */\n // Redactor renders the surface as a role=\"presentation\" contenteditable and,\n // while empty, points aria-labelledby at its hidden voice region — invalid\n // ARIA (axe: aria-prohibited-attr, since aria-labelledby can't sit on a\n // presentational node). Promote it to a properly-named textbox and keep it\n // that way as Redactor toggles the placeholder state. Redactor's own kit\n // usages never hit this because they all seed content (no empty placeholder).\n useEffect(() => {\n if (degraded) return undefined;\n const editable = wrapperRef.current?.querySelector('.redactor-in');\n if (!editable) return undefined;\n const normalise = () => {\n if (editable.getAttribute('role') !== 'textbox')\n editable.setAttribute('role', 'textbox');\n if (editable.getAttribute('aria-multiline') !== 'true')\n editable.setAttribute('aria-multiline', 'true');\n if (editable.getAttribute('aria-label') !== resolvedLabel)\n editable.setAttribute('aria-label', resolvedLabel);\n if (editable.hasAttribute('aria-labelledby'))\n editable.removeAttribute('aria-labelledby');\n };\n normalise();\n const observer = new MutationObserver(normalise);\n observer.observe(editable, {\n attributes: true,\n attributeFilter: ['role', 'aria-labelledby'],\n });\n return () => observer.disconnect();\n }, [degraded, resolvedLabel]);\n\n // AI FAB segments — rendered as one pill in this order: dictation · spelling\n // & grammar · auto-format · Alia. The two one-shot actions show a spinner\n // while running; everything else is disabled meanwhile.\n const busy = oneShot !== null;\n const fabSegments: {\n key: string;\n icon: ReactNode;\n label: string;\n onClick: () => void;\n recording?: boolean;\n running?: boolean;\n }[] = [];\n if (onDictate) {\n fabSegments.push({\n key: 'dictate',\n icon: isDictating ? (\n <Square aria-hidden=\"true\" className=\"ds:size-5 ds:fill-current\" />\n ) : (\n <Mic aria-hidden=\"true\" className=\"ds:size-5\" />\n ),\n label: isDictating\n ? t('editor.ai.dictateStop')\n : t('editor.ai.dictateStart'),\n onClick: toggleDictation,\n recording: isDictating,\n });\n }\n if (onProofread) {\n fabSegments.push({\n key: 'proofread',\n // While running, the segment becomes a STOP/cancel button (progress is\n // shown by the scrim spinner).\n icon:\n oneShot === 'proofread' ? (\n <Square aria-hidden=\"true\" className=\"ds:size-5 ds:fill-current\" />\n ) : (\n <SpellCheck aria-hidden=\"true\" className=\"ds:size-5\" />\n ),\n label:\n oneShot === 'proofread'\n ? t('common.cancel')\n : t('editor.ai.proofread', 'Check spelling & grammar'),\n onClick:\n oneShot === 'proofread'\n ? cancelOneShot\n : () => runOneShot('proofread', onProofread),\n running: oneShot === 'proofread',\n });\n }\n if (onAutoFormat) {\n fabSegments.push({\n key: 'format',\n icon:\n oneShot === 'format' ? (\n <Square aria-hidden=\"true\" className=\"ds:size-5 ds:fill-current\" />\n ) : (\n <WandSparkles aria-hidden=\"true\" className=\"ds:size-5\" />\n ),\n label:\n oneShot === 'format'\n ? t('common.cancel')\n : t('editor.ai.autoFormat', 'Auto-format document'),\n onClick:\n oneShot === 'format'\n ? cancelOneShot\n : () => runOneShot('format', onAutoFormat),\n running: oneShot === 'format',\n });\n }\n if (onRequestAiDraft) {\n fabSegments.push({\n key: 'write',\n icon: <Astroid aria-hidden=\"true\" className=\"ds:size-5\" />,\n label: t('editor.ai.helpMeWrite'),\n onClick: () => {\n saveSelection();\n setAiOpen(true);\n },\n });\n }\n\n return (\n <div\n ref={wrapperRef}\n className={[wrapperVariants(), className].filter(Boolean).join(' ')}\n data-component=\"rich-text-editor\"\n data-component-id={id}\n data-min-height={minHeight}\n >\n {!degraded && !readOnly ? (\n <EditorToolbar\n run={runCommand}\n active={activeFormats}\n preset={toolbar}\n insertHtml={insertHtml}\n insertTable={insertTable}\n saveSelection={saveSelection}\n restoreSelection={restoreSelection}\n getSelectedText={getSelectedText}\n uploadImage={imageUploadUrl ? uploadImage : undefined}\n enableColor={plugins?.includes('fontcolor') ?? false}\n enableImage={Boolean(imageUploadUrl)}\n enableTable={plugins?.includes('table') ?? false}\n showExtensions={showExtensions}\n />\n ) : null}\n <div className=\"ds:relative\" ref={editorAreaRef}>\n <textarea\n ref={textareaRef}\n id={editorId}\n aria-label={resolvedLabel}\n aria-multiline=\"true\"\n aria-busy={busy || undefined}\n placeholder={resolvedPlaceholder}\n onChange={degraded ? handleDegradedChange : undefined}\n readOnly={degraded ? readOnly : undefined}\n className={degraded ? degradedTextareaVariants() : undefined}\n />\n {/* While a one-shot AI action runs, dim + block the editor (it's being\n rewritten) with a centred spinner; the running FAB segment turns\n into a Stop/Cancel button. */}\n {busy ? (\n <div\n aria-hidden=\"true\"\n className=\"ds:absolute ds:inset-0 ds:z-[5] ds:flex ds:items-center ds:justify-center ds:cursor-wait ds:rounded-[var(--radius-md)] ds:bg-[color-mix(in_srgb,var(--background)_40%,transparent)]\"\n >\n <Spinner size=\"lg\" variant=\"prism\" />\n </div>\n ) : null}\n {/* AI affordances — the FAB + Alia popout. Wrapped in a zero-height\n STICKY dock (its only children are absolute) so in a long document\n they ride the viewport's block-end instead of scrolling off at the\n editor's bottom; the FAB/overlay keep their absolute positioning,\n now anchored to this dock. */}\n <div className=\"ds:sticky ds:bottom-0 ds:z-10\">\n {fabSegments.length > 0 ? (\n <div className=\"ds:absolute ds:[inset-block-end:var(--spacing-md)] ds:[inset-inline-end:var(--spacing-md)] ds:z-10 ds:flex ds:items-center ds:overflow-hidden ds:rounded-full ds:bg-[var(--primary)] ds:bg-[image:var(--gradient-brand)] ds:shadow-[0_8px_24px_color-mix(in_srgb,var(--primary)_35%,transparent)]\">\n {fabSegments.map((seg, i) => (\n <Fragment key={seg.key}>\n {i > 0 ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:self-stretch ds:[inline-size:var(--border-width-sm)] ds:bg-[color-mix(in_srgb,var(--primary-foreground)_35%,transparent)]\"\n />\n ) : null}\n <button\n type=\"button\"\n onClick={seg.onClick}\n aria-pressed={seg.recording || undefined}\n aria-busy={seg.running || undefined}\n disabled={(busy && !seg.running) || undefined}\n aria-label={seg.label}\n title={seg.label}\n className={\n seg.recording ? fabSegmentRecording : fabSegmentIdle\n }\n >\n {seg.icon}\n </button>\n </Fragment>\n ))}\n </div>\n ) : null}\n {onRequestAiDraft ? (\n <HelpMeWriteOverlay\n open={aiOpen}\n onClose={() => setAiOpen(false)}\n onRequestAiDraft={onRequestAiDraft}\n onInsert={(draft) => {\n // Restore the caret saved when the FAB opened the overlay, so\n // the draft lands where the user was, not at the doc start.\n restoreSelection();\n insertAtCursor(draft, { asHtml: aiDraftFormat !== 'text' });\n }}\n previewAsHtml={aiDraftFormat !== 'text'}\n privacyNotice={aiPrivacyNotice}\n onDictate={onDictate}\n />\n ) : null}\n </div>\n {/* Rendered LAST inside the positioned container (after the Redactor-\n managed textarea/box) so its conditional mount never asks React to\n insertBefore the textarea, which Redactor moves into its own box\n (that would throw \"node ... is not a child of this node\"). */}\n {!degraded && !readOnly && (plugins?.includes('table') ?? false) ? (\n <TableFloatingToolbar\n active={activeFormats}\n run={runCommand}\n areaRef={editorAreaRef}\n getActiveTableEl={getActiveTableEl}\n enableColor={plugins?.includes('fontcolor') ?? false}\n saveTableCell={saveTableCell}\n applyTableBackground={applyTableBackground}\n />\n ) : null}\n {/* Image wrap / align / resize — appears when an image is selected.\n Works on any embedded image, so it's gated only on edit mode (not\n on a plugin). Rendered after the table bar for the same reason it\n is: never inserted before the Redactor-managed textarea. */}\n {!degraded && !readOnly ? (\n <ImageFloatingToolbar\n areaRef={editorAreaRef}\n activeImageEl={activeImageEl}\n applyImageClass={applyImageClass}\n setImageWidth={setImageWidth}\n />\n ) : null}\n </div>\n {onDictate ? (\n <p className=\"ds:sr-only\" role=\"status\" aria-live=\"polite\">\n {dictationAnnouncement}\n </p>\n ) : null}\n {onDictate && dictationErrored ? (\n <p\n role=\"alert\"\n className=\"ds:text-[length:var(--font-size-sm)] ds:text-[color:var(--destructive)]\"\n >\n {t('editor.ai.dictationError')}\n </p>\n ) : null}\n </div>\n );\n },\n);\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport { wrapperVariants };\n"],"names":["__iconNode","Baseline","createLucideIcon","BetweenHorizontalEnd","BetweenHorizontalStart","BetweenVerticalEnd","BetweenVerticalStart","Bold","Columns2","Heading2","Heading3","Italic","Link","ListOrdered","List","PaintBucket","PaintRoller","Palette","PanelLeft","PanelRight","PanelTopDashed","PanelTop","Pilcrow","Quote","Rows2","SpellCheck","Strikethrough","Table","TextAlignCenter","TextAlignEnd","TextAlignStart","Underline","WandSparkles","Wrench","richTextEditorAgent","handle","args","RECORDING_MIC","ACTION_SIZE","noticeClass","errorClass","previewClass","joinWith","base","extra","HelpMeWriteOverlay","open","onClose","onRequestAiDraft","onInsert","previewAsHtml","privacyNotice","onDictate","t","useTranslation","promptId","useId","errorId","prompt","setPrompt","useState","loading","setLoading","errored","setErrored","draft","setDraft","abortRef","useRef","isDictating","setIsDictating","interim","setInterim","dictationAnnouncement","setDictationAnnouncement","dictateAbortRef","stopDictation","useCallback","_a","startDictation","controller","text","trimmed","p","toggleDictation","useEffect","_b","generate","result","err","insert","hasDraft","fieldValue","jsx","EditorOverlay","jsxs","IconButton","X","SafeHtml","RotateCcw","Check","Fragment","TextArea","event","Square","Mic","Spinner","Send","ITEMS","FORMAT_OPTIONS","PRESETS","TABLE_OPS","Trash2","TABLE_GRID","toolbarClass","cva","toolbarRowClass","dividerClass","fieldLabelClass","esc","value","StyleMenu","run","active","onTriggerDown","current","o","DropdownMenu","Button","ChevronDown","opt","LinkDialog","insertHtml","saveSelection","restoreSelection","getSelectedText","setOpen","url","setUrl","setText","newTab","setNewTab","urlId","textId","reset","handleInsert","href","label","tab","html","Dialog","LinkIcon","TextInput","Checkbox","checked","ImageDialog","uploadImage","src","setSrc","alt","setAlt","srcId","altId","insertImage","altText","ImageIcon","FileUpload","file","signal","ColourControl","colour","setColour","applyColour","hex","removeColour","Popover","ColorPicker","HighlightControl","applyHighlight","removeHighlight","Highlighter","buildTable","rows","cols","cells","TableControl","insertTable","hover","setHover","inTable","TableIcon","op","_","i","r","c","on","TABLE_OP_BY_ID","tableFloatClass","TABLE_BG_SEED","TableBgColourControl","scope","icon","onOpenChange","saveTableCell","applyTableBackground","TableFloatingToolbar","areaRef","getActiveTableEl","enableColor","pos","setPos","colourOpenCount","colourOpen","setColourOpen","handleColourOpenChange","recompute","area","table","a","rtl","top","center","ro","groups","TooltipProvider","group","gi","opId","IMAGE_FLOW_CLASSES","IMAGE_ALIGN_CLASSES","selectedImageClass","el","imageWidthPercent","img","box","boxWidth","imgWidth","IMG_MAX_PCT","IMG_MIN_PCT","IMG_STEP","IMG_STEP_COARSE","clampPct","pct","IMAGE_FLOW_OPS","IMAGE_ALIGN_OPS","IMAGE_CORNERS","imageFrameClass","imageHandleClass","imageBarClass","ImageFloatingToolbar","applyImageClass","setImageWidth","dragRef","start","barTop","editable","mo","onHandlePointerDown","corner","onHandlePointerMove","drag","deltaPct","onHandlePointerEnd","onHandleKeyDown","next","step","flowActive","alignActive","widthText","isActive","EditorToolbar","preset","enableImage","enableTable","showExtensions","keepSelection","has","id","btn","item","Divider","styleGroup","inlineNodes","hasPrimary","listsNodes","insertNodes","extensionNodes","secondarySubgroups","hasSecondary","renderSecondary","leadingDivider","index","Ellipsis","sanitiseHtml","input","sanitiseShared","normalizeEditorValue","normalized","contentWithoutTags","withLazyImages","extractUploadedUrl","data","rec","fromNode","node","resolveRedactor","injected","w","FORMAT_COMMANDS","REDACTOR_LANG","toRedactorLang","locale","wrapperVariants","degradedTextareaVariants","fabSegmentBase","fabSegmentIdle","fabSegmentRecording","RichTextEditor","forwardRef","defaultValue","onChange","toolbar","placeholder","readOnly","ariaLabel","minHeight","className","redactor","options","plugins","lang","imageUploadUrl","onKeyDown","aiDraftFormat","aiPrivacyNotice","onProofread","onAutoFormat","ref","i18n","rawId","editorId","useMemo","selector","textareaRef","redactorRef","skipNextPropSyncRef","readOnlyRef","wrapperRef","editorAreaRef","degraded","setDegraded","aiOpen","setAiOpen","activeFormats","setActiveFormats","activeImageElRef","activeImageEl","setActiveImageEl","selectImage","debounceRef","onChangeRef","onKeyDownRef","initialContentRef","raw","readCode","R","code","dispatchWrite","command","wasReadOnly","insertAtCursor","content","opts","asHtml","payload","ta","end","caret","lastRangeRef","updateActiveFormats","root","selection","block","anchorEl","prev","f","runCommand","wrapper","SHORTCUT_COMMANDS","onKeyDownCapture","sel","range","lastCellRef","getActiveCellEl","cell","targets","n","onClick","target","onFocusOut","list","last","form","res","interimRef","dictationErrored","setDictationErrored","clearInterim","showInterim","oneShot","setOneShot","oneShotAbortRef","runOneShot","kind","fn","safe","cancelOneShot","kitDefaults","imageUploadOption","consumerCallbacks","finalOptions","format","useImperativeHandle","useAgentRegistration","handleDegradedChange","resolvedLabel","resolvedPlaceholder","normalise","observer","busy","fabSegments","Astroid","seg"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]}
|