themelia-react-ui 2.0.1 → 2.0.3
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/CHANGELOG.md +317 -131
- package/README.md +25 -9
- package/THIRD_PARTY_NOTICES.md +7 -0
- package/dist/{accordion-B6a3vVgA.js → accordion-Cjb6sx0G.js} +14 -13
- package/dist/accordion-Cjb6sx0G.js.map +1 -0
- package/dist/action-menu-CllU52Mm.js +280 -0
- package/dist/action-menu-CllU52Mm.js.map +1 -0
- package/dist/affordance-geometry.generated-tF36bREk.js +140 -0
- package/dist/affordance-geometry.generated-tF36bREk.js.map +1 -0
- package/dist/ai-artifact-DvTwDVyL.js +1148 -0
- package/dist/ai-artifact-DvTwDVyL.js.map +1 -0
- package/dist/{app-shell-ZK5RWdo6.js → app-shell-C4FhvCqF.js} +5 -5
- package/dist/{app-shell-ZK5RWdo6.js.map → app-shell-C4FhvCqF.js.map} +1 -1
- package/dist/attachment-BxDfL2mw.js +246 -0
- package/dist/attachment-BxDfL2mw.js.map +1 -0
- package/dist/{auth-CYxKfo69.js → auth-BGua8ouh.js} +58 -54
- package/dist/auth-BGua8ouh.js.map +1 -0
- package/dist/{avatar-BBnEJIx8.js → avatar-DAPlDvhJ.js} +7 -7
- package/dist/avatar-DAPlDvhJ.js.map +1 -0
- package/dist/{badge-MrKVNzW9.js → badge-HpFqoqSY.js} +40 -40
- package/dist/badge-HpFqoqSY.js.map +1 -0
- package/dist/base/accordion.js +1 -1
- package/dist/base/action-menu.js +1 -1
- package/dist/base/attachment.js +1 -1
- package/dist/base/avatar.js +1 -1
- package/dist/base/badge.js +1 -1
- package/dist/base/batch-action-bar.js +1 -1
- package/dist/base/buttons.js +1 -1
- package/dist/base/cards.js +2 -2
- package/dist/base/carousel.js +40 -36
- package/dist/base/carousel.js.map +1 -1
- package/dist/base/cascader.js +92 -92
- package/dist/base/cascader.js.map +1 -1
- package/dist/base/chart.js +1 -1
- package/dist/base/choice-inputs.js +2 -2
- package/dist/base/code-block.js +1 -1
- package/dist/base/combobox.js +2 -2
- package/dist/base/command.js +1 -1
- package/dist/base/copyable.js +1 -1
- package/dist/base/date-pickers.js +2 -2
- package/dist/base/display.js +6 -6
- package/dist/base/feedback.js +3 -3
- package/dist/base/forms-numeric.js +1 -1
- package/dist/base/forms.js +2 -2
- package/dist/base/inline-edit.js +14 -14
- package/dist/base/inline-edit.js.map +1 -1
- package/dist/base/item.js +1 -1
- package/dist/base/media-gallery.js +1 -1
- package/dist/base/metadata-list.js +1 -1
- package/dist/base/navigation.js +6 -6
- package/dist/base/popover-menu.js +1 -1
- package/dist/base/popover.js +1 -1
- package/dist/base/qr-code.js +1 -1
- package/dist/base/repeaters.js +171 -176
- package/dist/base/repeaters.js.map +1 -1
- package/dist/base/sheet.js +1 -1
- package/dist/base/sidebar.js +1 -1
- package/dist/base/signature-pad.js +6 -6
- package/dist/base/skeleton.js +1 -1
- package/dist/base/spinner.js +79 -2
- package/dist/base/spinner.js.map +1 -0
- package/dist/base/structure.js +1 -1
- package/dist/base/table.js +1 -1
- package/dist/base/text-inputs.js +2 -2
- package/dist/base/toaster.js +46 -45
- package/dist/base/toaster.js.map +1 -1
- package/dist/base/tree.js +1 -1
- package/dist/base/upload-queue.js +1 -1
- package/dist/base/upload.js +3 -3
- package/dist/base/value-inputs.js +1 -1
- package/dist/{batch-action-bar-BZGDG-Si.js → batch-action-bar-DnUJ21NQ.js} +6 -5
- package/dist/batch-action-bar-DnUJ21NQ.js.map +1 -0
- package/dist/blocks/admin.js +42 -42
- package/dist/blocks/admin.js.map +1 -1
- package/dist/blocks/ai.js +260 -240
- package/dist/blocks/ai.js.map +1 -1
- package/dist/blocks/analytics/usage-card.js +1 -1
- package/dist/blocks/analytics.js +620 -585
- package/dist/blocks/analytics.js.map +1 -1
- package/dist/blocks/collaboration.js +1 -1
- package/dist/blocks/commerce/receipt.js +1 -1
- package/dist/blocks/commerce.js +1152 -1109
- package/dist/blocks/commerce.js.map +1 -1
- package/dist/blocks/data-display.js +2 -2
- package/dist/blocks/onboarding.js +48 -39
- package/dist/blocks/onboarding.js.map +1 -1
- package/dist/blocks/planning.js +13 -12
- package/dist/blocks/planning.js.map +1 -1
- package/dist/blocks/timelines.js +1 -1
- package/dist/{breadcrumbs-D5t7I023.js → breadcrumbs-C-oqs1sQ.js} +5 -5
- package/dist/breadcrumbs-C-oqs1sQ.js.map +1 -0
- package/dist/{button-QYwiyhD2.js → button-DVzspB_G.js} +2 -2
- package/dist/{button-QYwiyhD2.js.map → button-DVzspB_G.js.map} +1 -1
- package/dist/{buttons-SbIcm1HJ.js → buttons-DPZekJFu.js} +20 -15
- package/dist/buttons-DPZekJFu.js.map +1 -0
- package/dist/cards-BaBZR-AU.js +68 -0
- package/dist/cards-BaBZR-AU.js.map +1 -0
- package/dist/{chart-QfrARkXl.js → chart-ZOYyK2xG.js} +58 -55
- package/dist/chart-ZOYyK2xG.js.map +1 -0
- package/dist/{checkbox-DhB6K0bK.js → checkbox-AWIhNhmo.js} +2 -2
- package/dist/{checkbox-DhB6K0bK.js.map → checkbox-AWIhNhmo.js.map} +1 -1
- package/dist/{choice-inputs-t6w3ATNz.js → choice-inputs-CNHvARCJ.js} +49 -45
- package/dist/choice-inputs-CNHvARCJ.js.map +1 -0
- package/dist/{code-block-Dgbu-CU3.js → code-block-DeneBJR_.js} +8 -8
- package/dist/code-block-DeneBJR_.js.map +1 -0
- package/dist/{collapsible-D8AEGU1-.js → collapsible-C-_l4hpy.js} +3 -3
- package/dist/{collapsible-D8AEGU1-.js.map → collapsible-C-_l4hpy.js.map} +1 -1
- package/dist/{collection-content-uK16Grv0.js → collection-content-By56pLog.js} +3 -3
- package/dist/{collection-content-uK16Grv0.js.map → collection-content-By56pLog.js.map} +1 -1
- package/dist/combobox-DaHESuiL.js +355 -0
- package/dist/combobox-DaHESuiL.js.map +1 -0
- package/dist/{combobox-DLl0bfiq.js → combobox-Dxo2fAYQ.js} +289 -279
- package/dist/combobox-Dxo2fAYQ.js.map +1 -0
- package/dist/{command-kNR20o7x.js → command-C25VMRII.js} +7 -7
- package/dist/{command-kNR20o7x.js.map → command-C25VMRII.js.map} +1 -1
- package/dist/{comments-BpDuCUUu.js → comments-DD0DUPwJ.js} +114 -105
- package/dist/comments-DD0DUPwJ.js.map +1 -0
- package/dist/components/base/badge/badge.recipes.d.ts +1 -1
- package/dist/components/base/buttons/loader-button.d.ts +2 -1
- package/dist/components/base/cards/card.recipes.d.ts +2 -3
- package/dist/components/base/cards/partials/smart-card-skeleton.d.ts +3 -13
- package/dist/components/base/cards/smart-card.types.d.ts +11 -4
- package/dist/components/base/chart/chart.d.ts +2 -5
- package/dist/components/base/combobox/combobox-field.d.ts +16 -0
- package/dist/components/base/combobox/combobox.strings.d.ts +7 -0
- package/dist/components/base/combobox/index.d.ts +30 -4
- package/dist/components/base/forms/form-sizing.d.ts +11 -3
- package/dist/components/base/navigation/pagination.d.ts +5 -2
- package/dist/components/base/popover/popover.recipes.d.ts +15 -1
- package/dist/components/base/table/index.d.ts +9 -2
- package/dist/components/base/text-inputs/input-group.d.ts +2 -2
- package/dist/components/blocks/ai/ai-shimmer/ai-shimmer.d.ts +1 -1
- package/dist/components/blocks/ai/ai-shimmer/types.d.ts +3 -0
- package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +3 -1
- package/dist/components/blocks/data-display/inline-stat/inline-stat.d.ts +16 -8
- package/dist/components/features/activities/partials/activity-marker.d.ts +6 -3
- package/dist/components/features/appointment-calendar/appointment-calendar.d.ts +5 -0
- package/dist/components/features/appointment-calendar/appointment-calendar.types.d.ts +220 -0
- package/dist/components/features/appointment-calendar/appointment-calendar.utils.d.ts +41 -0
- package/dist/components/features/appointment-calendar/index.d.ts +3 -0
- package/dist/components/features/appointment-calendar/partials/appointment-agenda.d.ts +32 -0
- package/dist/components/features/appointment-calendar/partials/appointment-month.d.ts +13 -0
- package/dist/components/features/combobox/combobox.strings.d.ts +15 -1
- package/dist/components/features/combobox/types.d.ts +4 -0
- package/dist/components/features/media-library/media-library.strings.d.ts +2 -0
- package/dist/components/features/rich-text-editor/index.d.ts +1 -1
- package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +6 -0
- package/dist/components/features/rich-text-editor/rich-text-editor.types.d.ts +9 -1
- package/dist/components/features/table/table-header.d.ts +1 -1
- package/dist/components/features/table/table.strings.d.ts +55 -1
- package/dist/components/features/table/table.types.d.ts +17 -4
- package/dist/components/features/theme-tweaker/theme-tweaker.types.d.ts +5 -0
- package/dist/components/primitives/number.d.ts +4 -2
- package/dist/components/primitives/value.d.ts +3 -1
- package/dist/components/typography/text-link.d.ts +4 -0
- package/dist/components/ui/combobox-dismiss.d.ts +16 -0
- package/dist/components/ui/combobox.d.ts +16 -7
- package/dist/components/ui/dialog.d.ts +1 -1
- package/dist/components/ui/item.d.ts +8 -8
- package/dist/components/ui/popover.d.ts +1 -1
- package/dist/components/ui/sheet.d.ts +1 -1
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/{containers-DmWiJa2I.js → containers-Mu1LMGV1.js} +2 -2
- package/dist/{containers-DmWiJa2I.js.map → containers-Mu1LMGV1.js.map} +1 -1
- package/dist/{copyable-B3Gwgdqc.js → copyable-ClBuk_UK.js} +4 -4
- package/dist/{copyable-B3Gwgdqc.js.map → copyable-ClBuk_UK.js.map} +1 -1
- package/dist/{data-display-DafIvCl5.js → data-display-DT_khPl_.js} +98 -87
- package/dist/data-display-DT_khPl_.js.map +1 -0
- package/dist/{date-BgK3bTdo.js → date-DCrsDTZc.js} +5 -5
- package/dist/{date-BgK3bTdo.js.map → date-DCrsDTZc.js.map} +1 -1
- package/dist/{date-picker-CF-DtUpF.js → date-picker-B2K3ucWn.js} +594 -593
- package/dist/date-picker-B2K3ucWn.js.map +1 -0
- package/dist/date-pickers-Ds8gLaoP.js +175 -0
- package/dist/date-pickers-Ds8gLaoP.js.map +1 -0
- package/dist/{display-DsQTVzMz.js → display-hAc1HjpI.js} +49 -49
- package/dist/display-hAc1HjpI.js.map +1 -0
- package/dist/dropdown-menu-Cl4X7L5S.js +193 -0
- package/dist/dropdown-menu-Cl4X7L5S.js.map +1 -0
- package/dist/editable-text-recipe-Cn61kEcv.js +10 -0
- package/dist/editable-text-recipe-Cn61kEcv.js.map +1 -0
- package/dist/features/activities.js +398 -375
- package/dist/features/activities.js.map +1 -1
- package/dist/features/ai-chat.js +188 -179
- package/dist/features/ai-chat.js.map +1 -1
- package/dist/features/appointment-calendar.js +683 -0
- package/dist/features/appointment-calendar.js.map +1 -0
- package/dist/features/async-preview.js +109 -107
- package/dist/features/async-preview.js.map +1 -1
- package/dist/features/combobox.js +1 -1
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +137 -137
- package/dist/features/data-view.js.map +1 -1
- package/dist/features/email-composer.js +255 -255
- package/dist/features/email-composer.js.map +1 -1
- package/dist/features/event-calendar.js +254 -248
- package/dist/features/event-calendar.js.map +1 -1
- package/dist/features/filters.js +1 -1
- package/dist/features/global-search.js +35 -32
- package/dist/features/global-search.js.map +1 -1
- package/dist/features/kanban.js +118 -117
- package/dist/features/kanban.js.map +1 -1
- package/dist/features/map.js +233 -231
- package/dist/features/map.js.map +1 -1
- package/dist/features/media-library.js +789 -775
- package/dist/features/media-library.js.map +1 -1
- package/dist/features/mentions.js +1 -1
- package/dist/features/overlays.js +1 -1
- package/dist/features/products.js +922 -902
- package/dist/features/products.js.map +1 -1
- package/dist/features/questionnaire.js +28 -24
- package/dist/features/questionnaire.js.map +1 -1
- package/dist/features/resource-assignment.js +18 -15
- package/dist/features/resource-assignment.js.map +1 -1
- package/dist/features/resource.js +12 -12
- package/dist/features/resource.js.map +1 -1
- package/dist/features/rich-text-editor.js +2 -2
- package/dist/features/schema-form.js +15 -13
- package/dist/features/schema-form.js.map +1 -1
- package/dist/features/suggestions.js +3 -3
- package/dist/features/sync.js +11 -5
- package/dist/features/sync.js.map +1 -1
- package/dist/features/table.js +1 -1
- package/dist/features/theme-tweaker.js +493 -489
- package/dist/features/theme-tweaker.js.map +1 -1
- package/dist/feedback-BYIhtitP.js +239 -0
- package/dist/feedback-BYIhtitP.js.map +1 -0
- package/dist/{field-affordance-recipes-qQeIf4lG.js → field-affordance-recipes-DZhnIL_Y.js} +11 -18
- package/dist/field-affordance-recipes-DZhnIL_Y.js.map +1 -0
- package/dist/{filters-BkHH53uv.js → filters-DJVAveHA.js} +589 -580
- package/dist/filters-DJVAveHA.js.map +1 -0
- package/dist/{form-field-DUt4UxSV.js → form-field-CwH9y77i.js} +6 -5
- package/dist/form-field-CwH9y77i.js.map +1 -0
- package/dist/{form-sizing-By94KzXE.js → form-sizing-BdP_Mf5p.js} +39 -44
- package/dist/form-sizing-BdP_Mf5p.js.map +1 -0
- package/dist/{forms-Bzha-Y3B.js → forms-B9G_xwzi.js} +8 -8
- package/dist/{forms-Bzha-Y3B.js.map → forms-B9G_xwzi.js.map} +1 -1
- package/dist/{forms-numeric-C0bvjRPZ.js → forms-numeric-B_jraJaQ.js} +309 -309
- package/dist/forms-numeric-B_jraJaQ.js.map +1 -0
- package/dist/{header-BOefOKd1.js → header-BSfIEWbI.js} +160 -153
- package/dist/header-BSfIEWbI.js.map +1 -0
- package/dist/{hooks-9k_TtmKh.js → hooks-ClH9thn4.js} +2 -2
- package/dist/{hooks-9k_TtmKh.js.map → hooks-ClH9thn4.js.map} +1 -1
- package/dist/{icon-badge-CAuKupo9.js → icon-badge-DYKIwvOV.js} +4 -4
- package/dist/{icon-badge-CAuKupo9.js.map → icon-badge-DYKIwvOV.js.map} +1 -1
- package/dist/index.js +3 -3
- package/dist/input-CZw8iU99.js +21 -0
- package/dist/input-CZw8iU99.js.map +1 -0
- package/dist/input-DQdEd0YD.js +263 -0
- package/dist/input-DQdEd0YD.js.map +1 -0
- package/dist/{interaction-recipes-CHr0dJUs.js → interaction-recipes-XR9ZpVYL.js} +2 -1
- package/dist/interaction-recipes-XR9ZpVYL.js.map +1 -0
- package/dist/item-K5_ghvze.js +275 -0
- package/dist/item-K5_ghvze.js.map +1 -0
- package/dist/layout/app-shell.js +1 -1
- package/dist/layout/auth.js +1 -1
- package/dist/layout/containers.js +1 -1
- package/dist/layout/header.js +1 -1
- package/dist/layout/hooks.js +1 -1
- package/dist/layout/navigation.js +1 -1
- package/dist/layout/page.js +1 -1
- package/dist/layout/settings.js +1 -1
- package/dist/layout/sidebar.js +2 -2
- package/dist/layout/workspace.js +1 -1
- package/dist/layout.js +10 -10
- package/dist/lib/affordance-geometry.generated.d.ts +71 -0
- package/dist/lib/editable-text-recipe.d.ts +4 -4
- package/dist/lib/field-affordance-recipes.d.ts +2 -2
- package/dist/lib/interaction-recipes.d.ts +5 -0
- package/dist/lib/theme-mode-css.d.ts +7 -0
- package/dist/lib/tone-recipes.d.ts +8 -0
- package/dist/lib/ui-provider/types.d.ts +2 -2
- package/dist/lib/use-popup-focus-recovery.d.ts +8 -0
- package/dist/lib/utils.js +1 -1
- package/dist/{media-gallery-DcTtAaeC.js → media-gallery-3zIVLMWH.js} +8 -8
- package/dist/media-gallery-3zIVLMWH.js.map +1 -0
- package/dist/{mentions-D-uyCh01.js → mentions-CGlEJ15c.js} +144 -142
- package/dist/mentions-CGlEJ15c.js.map +1 -0
- package/dist/{message-CdHgIWKf.js → message-DZ_ruyUV.js} +6 -5
- package/dist/message-DZ_ruyUV.js.map +1 -0
- package/dist/{metadata-list-X5rYAKSB.js → metadata-list-8N16ZMW_.js} +130 -119
- package/dist/metadata-list-8N16ZMW_.js.map +1 -0
- package/dist/{navigation-D3KwXmaq.js → navigation-Bnotn4AQ.js} +19 -19
- package/dist/navigation-Bnotn4AQ.js.map +1 -0
- package/dist/{navigation-HJf5zxlH.js → navigation-BzhHI3lo.js} +36 -35
- package/dist/navigation-BzhHI3lo.js.map +1 -0
- package/dist/{navigation-row-recipes-BVowojQw.js → navigation-row-recipes-BFLCk_Aq.js} +2 -2
- package/dist/{navigation-row-recipes-BVowojQw.js.map → navigation-row-recipes-BFLCk_Aq.js.map} +1 -1
- package/dist/{number-DMhe-Vsk.js → number-DbV1Dija.js} +36 -34
- package/dist/{number-DMhe-Vsk.js.map → number-DbV1Dija.js.map} +1 -1
- package/dist/{overflow-tab-bar-sQHXLlwQ.js → overflow-tab-bar-CWY7Nogn.js} +105 -103
- package/dist/overflow-tab-bar-CWY7Nogn.js.map +1 -0
- package/dist/{overlays-I0axtYA6.js → overlays-tMkF-VAN.js} +282 -278
- package/dist/overlays-tMkF-VAN.js.map +1 -0
- package/dist/{page-B5dTH9gE.js → page-CL9YeH_V.js} +8 -8
- package/dist/{page-B5dTH9gE.js.map → page-CL9YeH_V.js.map} +1 -1
- package/dist/{page-header-commands-DjzFEq3E.js → page-header-commands-DOb6WsfD.js} +5 -5
- package/dist/{page-header-commands-DjzFEq3E.js.map → page-header-commands-DOb6WsfD.js.map} +1 -1
- package/dist/pagination-BL25hu2s.js +158 -0
- package/dist/pagination-BL25hu2s.js.map +1 -0
- package/dist/{popover-Di55PyAI.js → popover-gnTOhbFM.js} +69 -66
- package/dist/popover-gnTOhbFM.js.map +1 -0
- package/dist/popover-menu-Cn9rUkdc.js +100 -0
- package/dist/popover-menu-Cn9rUkdc.js.map +1 -0
- package/dist/{popover.recipes-Bdyhj2db.js → popover.recipes-D3j8R8Yp.js} +17 -10
- package/dist/popover.recipes-D3j8R8Yp.js.map +1 -0
- package/dist/{primitives-B-CkiEMU.js → primitives-BFK08r9M.js} +45 -44
- package/dist/primitives-BFK08r9M.js.map +1 -0
- package/dist/primitives.js +4 -4
- package/dist/{progress-rnS8-uAW.js → progress-B1VnCT0K.js} +5 -5
- package/dist/{progress-rnS8-uAW.js.map → progress-B1VnCT0K.js.map} +1 -1
- package/dist/{receipt-D0oswZ0p.js → receipt-BVSOH3Xo.js} +9 -6
- package/dist/{receipt-D0oswZ0p.js.map → receipt-BVSOH3Xo.js.map} +1 -1
- package/dist/{rich-text-DvGulsNJ.js → rich-text-GOUyKQ-s.js} +3 -3
- package/dist/{rich-text-DvGulsNJ.js.map → rich-text-GOUyKQ-s.js.map} +1 -1
- package/dist/{rich-text-editor-sMU_Scqm.js → rich-text-editor-cRLC-eBK.js} +418 -426
- package/dist/rich-text-editor-cRLC-eBK.js.map +1 -0
- package/dist/rich-text-editor-toolbar-DfXg0-VC.js +94 -0
- package/dist/rich-text-editor-toolbar-DfXg0-VC.js.map +1 -0
- package/dist/{scroll-area-Bt_vXY2b.js → scroll-area-DcI-M1UT.js} +2 -2
- package/dist/{scroll-area-Bt_vXY2b.js.map → scroll-area-DcI-M1UT.js.map} +1 -1
- package/dist/{separator-C8DlRGwF.js → separator-BDV-Y648.js} +3 -3
- package/dist/{separator-C8DlRGwF.js.map → separator-BDV-Y648.js.map} +1 -1
- package/dist/{separator-CYHnjsAb.js → separator-Bom7NsGO.js} +2 -2
- package/dist/{separator-CYHnjsAb.js.map → separator-Bom7NsGO.js.map} +1 -1
- package/dist/services/actions.js +1 -1
- package/dist/{settings-CQW3b-Cu.js → settings-ybnjVwbd.js} +20 -19
- package/dist/settings-ybnjVwbd.js.map +1 -0
- package/dist/{sheet-4SEvVYzA.js → sheet-ijlsjq-n.js} +76 -73
- package/dist/sheet-ijlsjq-n.js.map +1 -0
- package/dist/{sidebar-C7WWR29L.js → sidebar-Db6gkh3U.js} +183 -182
- package/dist/sidebar-Db6gkh3U.js.map +1 -0
- package/dist/{sidebar-d7Dg80ln.js → sidebar-DkTO4VTO.js} +14 -13
- package/dist/{sidebar-d7Dg80ln.js.map → sidebar-DkTO4VTO.js.map} +1 -1
- package/dist/{skeleton-Cz890JZF.js → skeleton-Byjnt7qr.js} +3 -3
- package/dist/{skeleton-Cz890JZF.js.map → skeleton-Byjnt7qr.js.map} +1 -1
- package/dist/smart-card-DiC5aac3.js +604 -0
- package/dist/smart-card-DiC5aac3.js.map +1 -0
- package/dist/{structure-DC2dygdA.js → structure-BmisBK-3.js} +2 -2
- package/dist/{structure-DC2dygdA.js.map → structure-BmisBK-3.js.map} +1 -1
- package/dist/style.css +1 -1
- package/dist/table-BweFy_P9.js +1530 -0
- package/dist/table-BweFy_P9.js.map +1 -0
- package/dist/{table-CIKyLUsy.js → table-DsfzoUia.js} +75 -63
- package/dist/table-DsfzoUia.js.map +1 -0
- package/dist/{tabs-DwBJfjxX.js → tabs-CDocW5D1.js} +14 -13
- package/dist/tabs-CDocW5D1.js.map +1 -0
- package/dist/text-inputs-f9Ia-aCi.js +353 -0
- package/dist/text-inputs-f9Ia-aCi.js.map +1 -0
- package/dist/theme-mode-css-BB-_RYab.js +14 -0
- package/dist/theme-mode-css-BB-_RYab.js.map +1 -0
- package/dist/theme-scope-BJ6eE2xt.js +50 -0
- package/dist/theme-scope-BJ6eE2xt.js.map +1 -0
- package/dist/theme.css +285 -228
- package/dist/themes/green.css +16 -12
- package/dist/timelines-CwM_9IhD.js +457 -0
- package/dist/timelines-CwM_9IhD.js.map +1 -0
- package/dist/{tone-recipes-CPoExcTE.js → tone-recipes-BPsRAvhu.js} +5 -2
- package/dist/tone-recipes-BPsRAvhu.js.map +1 -0
- package/dist/{tooltip-CsfgrfS7.js → tooltip-yiRJUFjp.js} +4 -4
- package/dist/{tooltip-CsfgrfS7.js.map → tooltip-yiRJUFjp.js.map} +1 -1
- package/dist/{tree-BiKhg8AY.js → tree-WnKQzwbq.js} +9 -9
- package/dist/{tree-BiKhg8AY.js.map → tree-WnKQzwbq.js.map} +1 -1
- package/dist/typography/rich-text.js +1 -1
- package/dist/{typography-DTRkE9zL.js → typography-UTnveOEy.js} +6 -6
- package/dist/typography-UTnveOEy.js.map +1 -0
- package/dist/typography.js +2 -2
- package/dist/{ui-provider-1D_NSYzO.js → ui-provider-C_U0Xma4.js} +3 -3
- package/dist/ui-provider-C_U0Xma4.js.map +1 -0
- package/dist/ui-provider.js +2 -2
- package/dist/{upload-BO8-CLN6.js → upload-CXyxmQBP.js} +13 -12
- package/dist/upload-CXyxmQBP.js.map +1 -0
- package/dist/{upload-queue-EOC8g1gf.js → upload-queue-Boscubn9.js} +11 -9
- package/dist/upload-queue-Boscubn9.js.map +1 -0
- package/dist/{usage-card-obRaBskq.js → usage-card-BhO5eqkX.js} +53 -37
- package/dist/usage-card-BhO5eqkX.js.map +1 -0
- package/dist/use-popup-focus-recovery-C0QPvgOR.js +36 -0
- package/dist/use-popup-focus-recovery-C0QPvgOR.js.map +1 -0
- package/dist/{utils-l5LpDw2z.js → utils-BRhFDwuU.js} +59 -44
- package/dist/utils-BRhFDwuU.js.map +1 -0
- package/dist/{value-inputs-TAYMX111.js → value-inputs-TaX4OjNk.js} +268 -252
- package/dist/value-inputs-TaX4OjNk.js.map +1 -0
- package/dist/{value-typography-b8wpz1eX.js → value-typography-BP8OG6h5.js} +2 -2
- package/dist/{value-typography-b8wpz1eX.js.map → value-typography-BP8OG6h5.js.map} +1 -1
- package/dist/{workspace-DH0v0KcB.js → workspace-B-OEm3Kf.js} +34 -33
- package/dist/workspace-B-OEm3Kf.js.map +1 -0
- package/docs/consumer-skill/SKILL.md +3 -3
- package/docs/consumer-skill/references/agents-md.md +1 -1
- package/docs/consumer-skill/references/composition.md +8 -6
- package/docs/consumer-skill/references/installation.md +6 -0
- package/docs/consumer-skill/references/integration.md +4 -3
- package/docs/consumer-skill/references/public-api.json +105 -2
- package/docs/consumer-skill/references/review.md +7 -0
- package/docs/consumer-skill/references/theming.md +71 -6
- package/docs/consumer-skill/references/tokens.json +1 -1
- package/docs/consumer-skill/references/workflows.md +26 -0
- package/docs/consumer-skill/scripts/composition-policy.mjs +3 -2
- package/docs/consumer-skill/scripts/surface-policy.mjs +11 -0
- package/package.json +8 -4
- package/dist/accordion-B6a3vVgA.js.map +0 -1
- package/dist/action-menu-TzCoSlwL.js +0 -280
- package/dist/action-menu-TzCoSlwL.js.map +0 -1
- package/dist/affordance-geometry.generated-B5iu-Mkr.js +0 -69
- package/dist/affordance-geometry.generated-B5iu-Mkr.js.map +0 -1
- package/dist/ai-artifact-BMJdv-6q.js +0 -1115
- package/dist/ai-artifact-BMJdv-6q.js.map +0 -1
- package/dist/attachment-BtfhGm8i.js +0 -245
- package/dist/attachment-BtfhGm8i.js.map +0 -1
- package/dist/auth-CYxKfo69.js.map +0 -1
- package/dist/avatar-BBnEJIx8.js.map +0 -1
- package/dist/badge-MrKVNzW9.js.map +0 -1
- package/dist/batch-action-bar-BZGDG-Si.js.map +0 -1
- package/dist/breadcrumbs-D5t7I023.js.map +0 -1
- package/dist/buttons-SbIcm1HJ.js.map +0 -1
- package/dist/cards-CiiHpKYd.js +0 -66
- package/dist/cards-CiiHpKYd.js.map +0 -1
- package/dist/chart-QfrARkXl.js.map +0 -1
- package/dist/choice-inputs-t6w3ATNz.js.map +0 -1
- package/dist/code-block-Dgbu-CU3.js.map +0 -1
- package/dist/combobox-2Ic8N9bL.js +0 -278
- package/dist/combobox-2Ic8N9bL.js.map +0 -1
- package/dist/combobox-DLl0bfiq.js.map +0 -1
- package/dist/comments-BpDuCUUu.js.map +0 -1
- package/dist/data-display-DafIvCl5.js.map +0 -1
- package/dist/date-picker-CF-DtUpF.js.map +0 -1
- package/dist/date-pickers-BmzxJl5l.js +0 -174
- package/dist/date-pickers-BmzxJl5l.js.map +0 -1
- package/dist/display-DsQTVzMz.js.map +0 -1
- package/dist/dropdown-menu-E2qmdC7o.js +0 -193
- package/dist/dropdown-menu-E2qmdC7o.js.map +0 -1
- package/dist/editable-text-recipe-Bkm6wKHp.js +0 -10
- package/dist/editable-text-recipe-Bkm6wKHp.js.map +0 -1
- package/dist/feedback-qNuMBtRH.js +0 -233
- package/dist/feedback-qNuMBtRH.js.map +0 -1
- package/dist/field-affordance-recipes-qQeIf4lG.js.map +0 -1
- package/dist/filters-BkHH53uv.js.map +0 -1
- package/dist/form-field-DUt4UxSV.js.map +0 -1
- package/dist/form-sizing-By94KzXE.js.map +0 -1
- package/dist/forms-numeric-C0bvjRPZ.js.map +0 -1
- package/dist/header-BOefOKd1.js.map +0 -1
- package/dist/input-DWhBBBww.js +0 -262
- package/dist/input-DWhBBBww.js.map +0 -1
- package/dist/input-Ddi_LSYv.js +0 -20
- package/dist/input-Ddi_LSYv.js.map +0 -1
- package/dist/interaction-recipes-CHr0dJUs.js.map +0 -1
- package/dist/item-DEmDiTlD.js +0 -265
- package/dist/item-DEmDiTlD.js.map +0 -1
- package/dist/media-gallery-DcTtAaeC.js.map +0 -1
- package/dist/mentions-D-uyCh01.js.map +0 -1
- package/dist/message-CdHgIWKf.js.map +0 -1
- package/dist/metadata-list-X5rYAKSB.js.map +0 -1
- package/dist/navigation-D3KwXmaq.js.map +0 -1
- package/dist/navigation-HJf5zxlH.js.map +0 -1
- package/dist/overflow-tab-bar-sQHXLlwQ.js.map +0 -1
- package/dist/overlays-I0axtYA6.js.map +0 -1
- package/dist/pagination-3bPA_a6K.js +0 -149
- package/dist/pagination-3bPA_a6K.js.map +0 -1
- package/dist/popover-Di55PyAI.js.map +0 -1
- package/dist/popover-menu-B71Tn2Qz.js +0 -99
- package/dist/popover-menu-B71Tn2Qz.js.map +0 -1
- package/dist/popover.recipes-Bdyhj2db.js.map +0 -1
- package/dist/primitives-B-CkiEMU.js.map +0 -1
- package/dist/rich-text-editor-sMU_Scqm.js.map +0 -1
- package/dist/rich-text-editor.recipes-CadiF_Uu.js +0 -88
- package/dist/rich-text-editor.recipes-CadiF_Uu.js.map +0 -1
- package/dist/settings-CQW3b-Cu.js.map +0 -1
- package/dist/sheet-4SEvVYzA.js.map +0 -1
- package/dist/sidebar-C7WWR29L.js.map +0 -1
- package/dist/smart-card-lFKxn5Hu.js +0 -595
- package/dist/smart-card-lFKxn5Hu.js.map +0 -1
- package/dist/spinner-fa3h1Aif.js +0 -80
- package/dist/spinner-fa3h1Aif.js.map +0 -1
- package/dist/table-CIKyLUsy.js.map +0 -1
- package/dist/table-CrcLN9Io.js +0 -1458
- package/dist/table-CrcLN9Io.js.map +0 -1
- package/dist/tabs-DwBJfjxX.js.map +0 -1
- package/dist/text-inputs-aaK9wcDT.js +0 -326
- package/dist/text-inputs-aaK9wcDT.js.map +0 -1
- package/dist/theme-scope-kStaAer0.js +0 -39
- package/dist/theme-scope-kStaAer0.js.map +0 -1
- package/dist/timelines-C_SBwHNP.js +0 -442
- package/dist/timelines-C_SBwHNP.js.map +0 -1
- package/dist/tone-recipes-CPoExcTE.js.map +0 -1
- package/dist/typography-DTRkE9zL.js.map +0 -1
- package/dist/ui-provider-1D_NSYzO.js.map +0 -1
- package/dist/upload-BO8-CLN6.js.map +0 -1
- package/dist/upload-queue-EOC8g1gf.js.map +0 -1
- package/dist/usage-card-obRaBskq.js.map +0 -1
- package/dist/utils-l5LpDw2z.js.map +0 -1
- package/dist/value-inputs-TAYMX111.js.map +0 -1
- package/dist/workspace-DH0v0KcB.js.map +0 -1
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useStrings as e } from "./lib/strings.js";
|
|
3
|
-
import { t } from "./utils-l5LpDw2z.js";
|
|
4
|
-
import { n, t as r } from "./feedback-qNuMBtRH.js";
|
|
5
|
-
import { t as i } from "./collection-content-uK16Grv0.js";
|
|
6
|
-
import { a, i as o, l as s, n as c, o as l, r as u, t as d } from "./command-kNR20o7x.js";
|
|
7
|
-
import { c as f, i as p, o as m, r as h, t as g } from "./popover-Di55PyAI.js";
|
|
8
|
-
import * as _ from "react";
|
|
9
|
-
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
10
|
-
//#region src/components/base/popover-menu/popover-menu.types.ts
|
|
11
|
-
var x = {
|
|
12
|
-
searchPlaceholder: "Search…",
|
|
13
|
-
empty: "No results.",
|
|
14
|
-
loading: "Loading…",
|
|
15
|
-
retry: "Retry"
|
|
16
|
-
};
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/components/base/popover-menu/popover-menu.tsx
|
|
19
|
-
function S({ density: S = "default", trigger: C, items: w, onSelect: T, open: E, onOpenChange: D, search: O = !0, searchValue: k, onSearchChange: A, loading: j = !1, error: M, onRetry: N, header: P, footer: F, empty: I, loadingSlot: L, renderItem: R, strings: z, align: B = "start", sideOffset: V, contentClassName: H, contentLabel: U, contentLabelledBy: W }) {
|
|
20
|
-
let G = e(x, z), K = _.useRef(null), q = _.useRef(null), J = _.useRef(!1), Y = _.useRef(null), X = _.useMemo(() => new Map(w.filter((e) => e.searchValue !== void 0).map((e) => [e.value, e.searchValue])), [w]), Z = _.useCallback((e, t, n) => X.has(e) ? s(X.get(e), t) : s(e, t, n), [X]);
|
|
21
|
-
return /* @__PURE__ */ b(m, {
|
|
22
|
-
open: E,
|
|
23
|
-
onOpenChange: (e, t) => {
|
|
24
|
-
J.current = !e && t.reason === "escape-key", D?.(e);
|
|
25
|
-
},
|
|
26
|
-
onOpenChangeComplete: (e) => {
|
|
27
|
-
!e && J.current && (J.current = !1, q.current?.focus({ preventScroll: !0 }));
|
|
28
|
-
},
|
|
29
|
-
children: [/* @__PURE__ */ y(f, {
|
|
30
|
-
ref: q,
|
|
31
|
-
render: C
|
|
32
|
-
}), /* @__PURE__ */ y(g, {
|
|
33
|
-
ref: Y,
|
|
34
|
-
"aria-label": W ? void 0 : U ?? G.searchPlaceholder,
|
|
35
|
-
"aria-labelledby": W,
|
|
36
|
-
align: B,
|
|
37
|
-
sideOffset: V,
|
|
38
|
-
type: "menu",
|
|
39
|
-
inset: "flush",
|
|
40
|
-
className: t("popover-menu--component", "w-56 gap-0 overflow-hidden", H),
|
|
41
|
-
children: /* @__PURE__ */ b(d, {
|
|
42
|
-
shouldFilter: !A,
|
|
43
|
-
filter: Z,
|
|
44
|
-
inset: "flush",
|
|
45
|
-
className: "popover-menu--collection",
|
|
46
|
-
children: [
|
|
47
|
-
!!P && /* @__PURE__ */ y(p, {
|
|
48
|
-
className: "popover-menu--header",
|
|
49
|
-
children: P
|
|
50
|
-
}),
|
|
51
|
-
!!O && /* @__PURE__ */ y(o, {
|
|
52
|
-
ref: K,
|
|
53
|
-
placeholder: G.searchPlaceholder,
|
|
54
|
-
value: k,
|
|
55
|
-
onValueChange: A
|
|
56
|
-
}),
|
|
57
|
-
/* @__PURE__ */ y(l, {
|
|
58
|
-
"aria-busy": j || void 0,
|
|
59
|
-
children: j ? L === void 0 ? /* @__PURE__ */ y(n, { label: G.loading }) : /* @__PURE__ */ y("div", {
|
|
60
|
-
role: "status",
|
|
61
|
-
"aria-live": "polite",
|
|
62
|
-
children: L
|
|
63
|
-
}) : M ? /* @__PURE__ */ y(r, {
|
|
64
|
-
variant: "inline",
|
|
65
|
-
description: M,
|
|
66
|
-
onRetry: N ? () => {
|
|
67
|
-
(K.current ?? Y.current)?.focus(), N();
|
|
68
|
-
} : void 0,
|
|
69
|
-
retryLabel: G.retry ?? "Retry"
|
|
70
|
-
}) : /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(c, { children: I ?? G.empty }), w.length > 0 && /* @__PURE__ */ y(u, { children: w.map((e) => /* @__PURE__ */ y(a, {
|
|
71
|
-
density: S,
|
|
72
|
-
value: e.value,
|
|
73
|
-
keywords: e.searchValue === void 0 ? [e.label, e.description].filter((e) => typeof e == "string") : [e.searchValue],
|
|
74
|
-
onSelect: () => T(e),
|
|
75
|
-
disabled: e.disabled,
|
|
76
|
-
"data-checked": e.selected || void 0,
|
|
77
|
-
className: "data-[checked=true]:**:[svg]:text-primary-accent",
|
|
78
|
-
children: ({ isHighlighted: t }) => R ? R(e, { isHighlighted: t }) : /* @__PURE__ */ y(i, {
|
|
79
|
-
label: e.label,
|
|
80
|
-
description: e.description,
|
|
81
|
-
leading: e.icon,
|
|
82
|
-
leadingClassName: "[&_svg]:size-icon"
|
|
83
|
-
})
|
|
84
|
-
}, e.value)) })] })
|
|
85
|
-
}),
|
|
86
|
-
!!F && /* @__PURE__ */ y(h, {
|
|
87
|
-
className: "popover-menu--footer justify-start",
|
|
88
|
-
children: F
|
|
89
|
-
})
|
|
90
|
-
]
|
|
91
|
-
})
|
|
92
|
-
})]
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
S.displayName = "PopoverMenu";
|
|
96
|
-
//#endregion
|
|
97
|
-
export { x as n, S as t };
|
|
98
|
-
|
|
99
|
-
//# sourceMappingURL=popover-menu-B71Tn2Qz.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"popover-menu-B71Tn2Qz.js","names":["React","_Fragment","ErrorState","CollectionContent","CommandInput","commandFilter","CommandEmpty","CommandList","CommandGroup","Command","PopoverTrigger","PopoverHeader","Popover","PopoverFooter","PopoverContent","React$1","Fragment$1","defaultPopoverMenuStrings","PopoverMenu","stringsProp","strings","useStrings","searchRef","triggerRef","keyboardDismissal","contentRef","searchOverrides","items","item","filter","value","search","keywords","next","details","onOpenChange","trigger","contentLabelledBy","contentLabel","cn","contentClassName","onSearchChange","header","searchValue","loading","loadingSlot","LoadingState","error","onRetry","empty","CommandItem","onSelect","renderItem","footer"],"sources":["../src/components/base/popover-menu/popover-menu.types.ts","../src/components/base/popover-menu/popover-menu.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nexport interface PopoverMenuItem<T = unknown> {\n\t/** Unique identifier; remains distinct from visible search labels. */\n\tvalue: string;\n\t/** Visible label rendered in the row. Override entirely via `renderItem`. */\n\tlabel: ReactNode;\n\t/** Optional secondary line rendered under the label. */\n\tdescription?: ReactNode;\n\t/** Leading icon — keep small (size-icon-md/size-icon max). */\n\ticon?: ReactNode;\n\t/** Show the trailing checkmark when `true`. */\n\tselected?: boolean;\n\t/** Disable the row. */\n\tdisabled?: boolean;\n\t/** Explicit search keywords, useful when the label is structured content. */\n\tsearchValue?: string;\n\t/** Arbitrary payload for `onSelect` consumers. */\n\tdata?: T;\n}\n\nexport interface PopoverMenuStrings {\n\t/** Placeholder for the search input (when `search` is enabled). */\n\tsearchPlaceholder: string;\n\t/** Empty-state copy when filtering yields no items. */\n\tempty: string;\n\t/** Loading-state copy. */\n\tloading: string;\n\t/** Retry action copy when a resource fails. */\n\tretry?: string;\n}\n\nexport const defaultPopoverMenuStrings: PopoverMenuStrings = {\n\tsearchPlaceholder: 'Search…',\n\tempty: 'No results.',\n\tloading: 'Loading…',\n\tretry: 'Retry',\n};\n","import { commandFilter } from '../../../lib/command-filter';\n/**\n * PopoverMenu — blocks wrapper around `base/popover` + `base/command`.\n *\n * Captures the recurring \"trigger → optional header → search → command list\"\n * pattern used by filter facets, operator selects, and similar pickers\n * across the library.\n *\n * Slots (all optional):\n * - `header` — rendered above the search input / list\n * - `footer` — rendered below the list (e.g. confirm/clear buttons)\n * - `empty` — replaces the default empty-state copy\n * - `loading` — replaces the list when `loading` is true\n *\n * Render-prop:\n * - `renderItem={(item, ctx) => ReactNode}` — full control over a row\n *\n * Strings:\n * - `strings={{ searchPlaceholder, empty, loading }}` — merged with defaults\n *\n * For headless usage (custom UI against the same selection state),\n * compose `base/popover` + `base/command` directly.\n */\nimport * as React from 'react';\n\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from '../command';\nimport {\n\tPopover,\n\tPopoverContent,\n PopoverHeader,\n PopoverFooter,\n\tPopoverTrigger,\n} from '../popover';\nimport { LoadingState, ErrorState } from '../feedback';\nimport { useStrings, type StringsProp } from '../../../lib/strings';\nimport { cn } from '../../../lib/utils';\nimport { type CollectionDensity } from '../popover/popover.recipes';\nimport { CollectionContent } from '../popover/collection-content';\n\nimport {\n\tdefaultPopoverMenuStrings,\n\ttype PopoverMenuItem,\n\ttype PopoverMenuStrings,\n} from './popover-menu.types';\n\nexport interface PopoverMenuRenderItemContext {\n\t/** True when the item is the user's currently-active match (keyboard or pointer highlight). */\n\tisHighlighted: boolean;\n}\n\nexport interface PopoverMenuProps<T = unknown> {\n\t/** Vertical row rhythm. Compact and comfortable preserve primary label size and inline room. */\n\tdensity?: CollectionDensity;\n\t/** Trigger element. The popover anchors to it. Pass any clickable. */\n\ttrigger: React.ReactNode;\n\t/** Items to render in the list. */\n\titems: ReadonlyArray<PopoverMenuItem<T>>;\n\t/** Selection callback — fires on row click / Enter. */\n\tonSelect: (item: PopoverMenuItem<T>) => void;\n\n\t/** Controlled open state. Omit for uncontrolled. */\n\topen?: boolean;\n\t/** Open-state callback for controlled / uncontrolled flows. */\n\tonOpenChange?: (open: boolean) => void;\n\n\t/** Show the search input above the list. Default: true. */\n\tsearch?: boolean;\n\t/** Search input value (controlled). */\n\tsearchValue?: string;\n\t/** Search input change callback. */\n\tonSearchChange?: (value: string) => void;\n\n\t/** Async loading flag — replaces stale options and the empty state. */\n\tloading?: boolean;\n\t/** Resource failure replaces the list. The application owns retry and fetching. */\n\terror?: React.ReactNode;\n\tonRetry?: () => void;\n\n\t/** Optional pre-list slot (e.g. a label / eyebrow). */\n\theader?: React.ReactNode;\n\t/** Optional post-list slot (e.g. confirm / clear buttons). */\n\tfooter?: React.ReactNode;\n\t/** Override empty-state slot (defaults to `strings.empty`). */\n\tempty?: React.ReactNode;\n\t/** Override loading slot (defaults to spinner + `strings.loading`). */\n\tloadingSlot?: React.ReactNode;\n\n\t/** Per-item render override. */\n\trenderItem?: (\n\t\titem: PopoverMenuItem<T>,\n\t\tctx: PopoverMenuRenderItemContext,\n\t) => React.ReactNode;\n\n\t/** Override copy. Deep-merged over defaults. */\n\tstrings?: StringsProp<PopoverMenuStrings>;\n\n\t/** Popover content positioning props (forwarded). */\n\talign?: React.ComponentProps<typeof PopoverContent>['align'];\n\t/** Distance from the trigger, in pixels. */\n\tsideOffset?: React.ComponentProps<typeof PopoverContent>['sideOffset'];\n\n\t/** Width override for the popover content. Default: w-56. */\n\tcontentClassName?: string;\n /** Accessible name for the popup. Defaults to the localized search label. */\n contentLabel?: string;\n /** ID of a consumer-owned title used instead of contentLabel. */\n contentLabelledBy?: string;\n}\n\nexport function PopoverMenu<T = unknown>({\n\tdensity = 'default',\n\ttrigger,\n\titems,\n\tonSelect,\n\topen,\n\tonOpenChange,\n\tsearch = true,\n\tsearchValue,\n\tonSearchChange,\n\tloading = false,\n\terror,\n\tonRetry,\n\theader,\n\tfooter,\n\tempty,\n\tloadingSlot,\n\trenderItem,\n\tstrings: stringsProp,\n\talign = 'start',\n\tsideOffset,\n\tcontentClassName,\n contentLabel,\n contentLabelledBy,\n}: PopoverMenuProps<T>) {\n\tconst strings = useStrings(defaultPopoverMenuStrings, stringsProp);\n\tconst searchRef = React.useRef<HTMLInputElement>(null);\n\tconst triggerRef = React.useRef<HTMLButtonElement>(null);\n\tconst keyboardDismissal = React.useRef(false);\n\tconst contentRef = React.useRef<HTMLDivElement>(null);\n const searchOverrides = React.useMemo(() => new Map(\n items.filter(item => item.searchValue !== undefined).map(item => [item.value, item.searchValue!]),\n ), [items]);\n const filter = React.useCallback((value: string, search: string, keywords?: string[]) => (\n searchOverrides.has(value)\n ? commandFilter(searchOverrides.get(value)!, search)\n : commandFilter(value, search, keywords)\n ), [searchOverrides]);\n\n\treturn (\n\t\t<Popover open={open} onOpenChange={(next, details) => {\n keyboardDismissal.current = !next && details.reason === 'escape-key';\n onOpenChange?.(next);\n }} onOpenChangeComplete={next => {\n // Rapid reopen during a focus-out exit can retain Base UI's no-return flag.\n // Restore only an accepted, completed Escape dismissal; outside focus stays owned.\n if (!next && keyboardDismissal.current) {\n keyboardDismissal.current = false;\n triggerRef.current?.focus({ preventScroll: true });\n }\n }}>\n\t\t\t<PopoverTrigger ref={triggerRef} render={trigger as React.ReactElement} />\n\t\t\t<PopoverContent\n\t\t\t\tref={contentRef}\n\t\t\t\taria-label={contentLabelledBy ? undefined : contentLabel ?? strings.searchPlaceholder}\n aria-labelledby={contentLabelledBy}\n align={align}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\ttype=\"menu\"\n\t\t\t\tinset=\"flush\"\n\t\t\t\tclassName={cn('popover-menu--component', 'w-56 gap-0 overflow-hidden', contentClassName)}\n\t\t\t>\n\t\t\t\t<Command\n\t\t\t\t\tshouldFilter={!onSearchChange}\n filter={filter}\n\t\t\t\t\tinset=\"flush\"\n\t\t\t\t\tclassName=\"popover-menu--collection\"\n\t\t\t\t>\n\t\t\t\t\t{!!header && (\n\t\t\t\t\t\t<PopoverHeader className=\"popover-menu--header\">\n\t\t\t\t\t\t\t{header}\n\t\t\t\t\t\t</PopoverHeader>\n\t\t\t\t\t)}\n\n\t\t\t\t\t{!!search && (\n\t\t\t\t\t\t<CommandInput\n\t\t\t\t\t\t\tref={searchRef}\n\t\t\t\t\t\t\tplaceholder={strings.searchPlaceholder}\n\t\t\t\t\t\t\tvalue={searchValue}\n\t\t\t\t\t\t\tonValueChange={onSearchChange}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<CommandList aria-busy={loading || undefined}>\n\t\t\t\t\t\t{loading ? (loadingSlot !== undefined ? <div role=\"status\" aria-live=\"polite\">{loadingSlot}</div> : <LoadingState label={strings.loading} />) : error ? <ErrorState variant=\"inline\" description={error} onRetry={onRetry ? () => {\n // Retry feedback is replaced by loading. Keep focus on persistent anatomy\n // before its button is removed, including in search-free pickers.\n (searchRef.current ?? contentRef.current)?.focus();\n onRetry();\n } : undefined} retryLabel={strings.retry ?? 'Retry'} /> : <>\n\n\t\t\t\t\t\t<CommandEmpty>{empty ?? strings.empty}</CommandEmpty>\n\n\t\t\t\t\t\t{items.length > 0 && (\n\t\t\t\t\t\t\t<CommandGroup>\n\t\t\t\t\t\t\t\t{items.map((item) => (\n\t\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\t\t\t\tdensity={density}\n\t\t\t\t\t\t\t\t\t\tvalue={item.value}\n keywords={item.searchValue !== undefined ? [item.searchValue] : [item.label, item.description].filter((value): value is string => typeof value === 'string')}\n\t\t\t\t\t\t\t\t\t\tonSelect={() => onSelect(item)}\n\t\t\t\t\t\t\t\t\t\tdisabled={item.disabled}\n\t\t\t\t\t\t\t\t\t\tdata-checked={item.selected || undefined}\n\t\t\t\t\t\t\t\t\t\tclassName=\"data-[checked=true]:**:[svg]:text-primary-accent\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{({ isHighlighted }) => renderItem\n\t\t\t\t\t\t\t\t\t\t\t? renderItem(item, { isHighlighted })\n\t\t\t\t\t\t\t\t\t\t\t: (\n\t\t\t\t\t\t\t\t\t\t\t\t<CollectionContent label={item.label} description={item.description} leading={item.icon} leadingClassName=\"[&_svg]:size-icon\"/>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</CommandGroup>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t</>}\n\t\t\t\t\t</CommandList>\n\n\t\t\t\t\t{/* The public surface anatomy owns header and footer bands. */}\n\t\t\t\t\t{!!footer && (\n\t\t\t\t\t\t<PopoverFooter className=\"popover-menu--footer justify-start\">\n\t\t\t\t\t\t\t{footer}\n\t\t\t\t\t\t</PopoverFooter>\n\t\t\t\t\t)}\n\t\t\t\t</Command>\n\t\t\t</PopoverContent>\n\t\t</Popover>\n\t);\n}\n\nPopoverMenu.displayName = 'PopoverMenu';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"popover.recipes-Bdyhj2db.js","names":["surfaceDividerRecipes","popoverRecipes","surfaceInsetClasses","collectionDensityClasses","collectionRowClasses","density","rowBlockPaddingClasses","collectionRecipes"],"sources":["../src/components/base/popover/popover.recipes.ts"],"sourcesContent":["import { surfaceDividerRecipes } from '../../../lib/surface-recipes';\nimport { rowBlockPaddingClasses, type RowDensity } from '../../../lib/row-recipes';\n/** Shared anchored-surface chrome; Menu and Popover retain their own accessible behavior. */\nexport const popoverRecipes = {\n surface: `box-border rounded-radius ${surfaceDividerRecipes.anchored.shell} bg-popover text-popover-foreground shadow-md ring-0`,\n display: 'p-surface',\n menu: 'p-surface-xs',\n // Collection bands share the list shell; text bodies add the row inset once.\n menuRegion: 'px-surface-xs py-space-md',\n separator: `mx-0 my-space-xs h-px w-full shrink-0 ${surfaceDividerRecipes.anchored.separator}`,\n row: 'box-border min-h-control rounded-inner px-row-x gap-space-sm font-medium leading-tight',\n} as const;\nexport type PopoverContentType = 'display' | 'menu';\n\n/** One surface inset vocabulary for Popover, Command and their collections. */\nexport const surfaceInsetClasses = {\n default: popoverRecipes.display,\n compact: popoverRecipes.menu,\n flush: 'p-0',\n} as const;\n\n/** Collection density changes vertical rhythm; inline room and primary text stay stable. */\nexport type CollectionDensity = RowDensity;\n\nconst collectionDensityClasses: Record<CollectionDensity, string> = {\n default: '',\n compact: 'min-h-control-sm',\n comfortable: 'min-h-control-lg',\n};\n\nexport function collectionRowClasses(density: CollectionDensity = 'default'): string {\n return `${popoverRecipes.row} ${collectionDensityClasses[density]} ${rowBlockPaddingClasses[density]}`;\n}\n\n/** Shared interactive collection states, independent of Menu/listbox state ownership. */\nexport const collectionRecipes = {\n icons: '[&_svg]:pointer-events-none [&_svg]:size-icon [&_svg]:shrink-0',\n interactive: 'relative flex cursor-default items-center outline-none select-none transition-colors',\n highlighted: 'data-highlighted:bg-accent data-highlighted:text-accent-foreground data-highlighted:[&_svg]:text-accent-foreground',\n disabled: 'data-disabled:pointer-events-none data-disabled:opacity-50',\n destructive: 'data-[variant=destructive]:text-destructive data-[variant=destructive]:data-highlighted:bg-destructive/10 data-[variant=destructive]:data-highlighted:text-destructive dark:data-[variant=destructive]:data-highlighted:bg-destructive/10 data-[variant=destructive]:[&_svg]:text-destructive data-[variant=destructive]:data-highlighted:[&_svg]:text-destructive',\n // Compatibility for existing table and overflow-tab ActionMenu consumers.\n tableRow: 'min-h-action-xs py-space-2xs',\n} as const;\n"],"mappings":";;;AAGA,IAAaC,IAAiB;CAC7B,SAAS,6BAA6BD,EAAsB,SAAS,MAAM;CAC3E,SAAS;CACT,MAAM;CAEN,YAAY;CACZ,WAAW,yCAAyCA,EAAsB,SAAS;CACnF,KAAK;AACN,GAIaE,IAAsB;CAClC,SAASD,EAAe;CACxB,SAASA,EAAe;CACxB,OAAO;AACR,GAKME,IAA8D;CACnE,SAAS;CACT,SAAS;CACT,aAAa;AACd;AAEA,SAAgBC,EAAqB,IAA6B,WAAmB;CACpF,OAAO,GAAGH,EAAe,IAAI,GAAGE,EAAyBE,GAAS,GAAGC,EAAuBD;AAC7F;AAGA,IAAaE,IAAoB;CAChC,OAAO;CACP,aAAa;CACb,aAAa;CACb,UAAU;CACV,aAAa;CAEb,UAAU;AACX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"primitives-B-CkiEMU.js","names":["_Fragment","useFormattingConfig","useTypographyConfig","cn","RunningTextContext","useInRunningText","inlineLinkClassName","linkUnderlineClassName","resolveTextClassNames","useValueTypography","formatWithMinusSign","formatDuration","emptyValueTypography","formatInitials","Fragment$1","VALUE_ROLE","SECONDARY_ROLE","MONO_ROLE","isEmptyValue","children","ValueText","props","resolved","valueRole","empty","typography","weight","Text","numeric","hookClassName","className","emptyLabel","Value","SecondaryValue","MutedValue","MonoValue","EmptyValue","WORD_SEPARATOR","NAME_CONNECTOR","LETTER_MATCHER","LETTERS_MATCHER","normalizeNameWhitespace","value","getLetters","getFirstLetter","match","isFormattedSegment","first","segment","letters","isAllUpper","isAllLower","isFormattedName","word","formatNameSegment","before","after","formatNameWord","formatName","normalized","options","Name","rawValue","content","Initials","Link","inText","defaultTextSize","EmptyContact","_href","_target","_rel","_download","_hrefLang","_ping","_referrerPolicy","_media","_type","spanProps","contactProps","Email","query","subject","body","href","display","normalizeTel","Phone","normalizeUrl","Url","isExternal","external","resolvedTarget","target","resolvedRel","rel","FILE_SIZE_ROLE","FILE_SIZE_UNITS","FILE_SIZE_UNIT_MULTIPLIER","normalizeFileSizeValue","from","formatFileSize","locale","bytes","displayValue","unitIndex","FileSize","formatting","label","DURATION_ROLE","Duration","maximumFractionDigits","DIMENSIONS_ROLE","parseDimensionPart","parsed","formatDimensions","parsedWidth","width","parsedHeight","height","parsedDepth","depth","formatter","values","separator","unit","Dimensions","index","part"],"sources":["../src/components/primitives/value.tsx","../src/components/primitives/name.tsx","../src/components/primitives/initials.tsx","../src/components/primitives/link.tsx","../src/components/primitives/file-size.tsx","../src/components/primitives/duration.tsx","../src/components/primitives/dimensions.tsx"],"sourcesContent":["import { type ComponentPropsWithoutRef, type ReactNode, type Ref } from 'react';\n\nimport { Text, type TextProps } from '../typography';\nimport type { TextSize } from '../../lib/ui-provider';\nimport { EMPTY } from '../../lib/format';\nimport { cn } from '../../lib/utils';\n\nimport { emptyValueTypography, useValueTypography, type ValueTypographyRole } from './value-typography';\n\ntype SpanProps = Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'color'>;\n/** Value colour roles: foreground, secondary, or the surrounding text colour. */\nexport type ValueType = Extract<TextProps['type'], 'main' | 'secondary' | 'inherit'>;\n\nexport interface ValueProps extends SpanProps {\n\tchildren?: ReactNode;\n\t/** Rendered with the shared empty treatment when children are absent. Defaults to an em dash. */\n\temptyLabel?: ReactNode;\n\t/**\n\t * Text size. A standalone value uses the provider text size; inside running\n\t * text (`Text`, `Heading`, labels, links, other values) it inherits the size.\n\t */\n\tsize?: TextSize;\n\talign?: TextProps['align'];\n\t/** Font weight. Defaults to the component's role weight; inside running text, the surrounding weight. */\n\tweight?: TextProps['weight'];\n\t/** Colour role. Defaults to the component's role; inside running text `Value` and `MonoValue` take the surrounding colour. */\n\ttype?: ValueType;\n\tref?: Ref<HTMLSpanElement>;\n}\n\nconst VALUE_ROLE: ValueTypographyRole = { type: 'main', weight: 'regular' };\nconst SECONDARY_ROLE: ValueTypographyRole = { type: 'secondary', weight: 'regular', keepType: true };\nconst MONO_ROLE: ValueTypographyRole = { type: 'main', weight: 'medium', inTextLineHeight: 'none' };\n\nfunction isEmptyValue(children: ReactNode) {\n\treturn children === null || children === undefined || children === '';\n}\n\ninterface ValueTextProps extends ValueProps {\n\tvalueRole: ValueTypographyRole;\n\thookClassName: string;\n\tnumeric?: boolean;\n}\n\n/** Shared span for the value family: role resolution plus the empty treatment. */\nfunction ValueText({ valueRole, hookClassName, numeric = false, children, emptyLabel = EMPTY, size, align, weight, type, className, ref, ...props }: ValueTextProps) {\n\tconst resolved = useValueTypography({ size, type, weight }, valueRole);\n\tconst empty = isEmptyValue(children);\n\tconst typography = empty ? emptyValueTypography(resolved, weight) : resolved;\n\treturn (\n\t\t<Text\n\t\t\tref={ref}\n\t\t\ttag=\"span\"\n\t\t\tsize={typography.size}\n\t\t\talign={align}\n\t\t\tweight={typography.weight}\n\t\t\ttype={typography.type}\n\t\t\tlineHeight={typography.lineHeight}\n\t\t\tnumeric={numeric && !empty}\n\t\t\tclassName={cn(hookClassName, className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{empty ? emptyLabel : children}\n\t\t</Text>\n\t);\n}\n\n/**\n * An ordinary displayed fact: foreground, regular weight. Inside running text it\n * takes the sentence's size, colour and weight.\n */\nexport function Value(props: ValueProps) {\n\treturn <ValueText {...props} valueRole={VALUE_ROLE} hookClassName=\"value--component inline min-w-0\" />;\n}\n\n/** Supporting detail in the secondary colour. Inside running text it keeps the colour and takes the size and weight. */\nexport function SecondaryValue(props: ValueProps) {\n\treturn <ValueText {...props} valueRole={SECONDARY_ROLE} hookClassName=\"secondary-value--component inline min-w-0\" />;\n}\n\n/** A note that recedes further than secondary text. */\nexport function MutedValue(props: ValueProps) {\n\treturn <ValueText {...props} valueRole={SECONDARY_ROLE} hookClassName=\"muted-value--component inline min-w-0 opacity-80\" />;\n}\n\n/**\n * An identifier or code (SKU, reference, tracking number, key) in the monospace\n * family. Standalone it is foreground medium at the provider size; inside running\n * text only the family changes, so an SKU in a description matches the words\n * around it. Amounts and dates belong to the number primitives, which keep the\n * sans font with tabular figures.\n */\nexport function MonoValue(props: ValueProps) {\n\treturn <ValueText {...props} valueRole={MONO_ROLE} numeric hookClassName=\"mono-value--component inline min-w-0 break-words\" />;\n}\n\nexport interface EmptyValueProps extends Omit<ValueProps, 'emptyLabel'> {\n\tref?: Ref<HTMLSpanElement>;\n}\n\n/**\n * An intentionally absent value: secondary colour, regular weight. Every value\n * primitive renders its missing state with this treatment.\n */\nexport function EmptyValue({ children = EMPTY, ...props }: EmptyValueProps) {\n\treturn <ValueText {...props} valueRole={SECONDARY_ROLE} emptyLabel={EMPTY} hookClassName=\"empty-value--component inline min-w-0\">{children}</ValueText>;\n}\n","import { type ReactNode } from 'react';\n\nimport { cn } from '../../lib/utils';\n\nimport { Value, type ValueProps } from './value';\n\nconst WORD_SEPARATOR = /(\\s+)/u;\nconst NAME_CONNECTOR = /([-'])/u;\nconst LETTER_MATCHER = /\\p{L}/u;\nconst LETTERS_MATCHER = /\\p{L}/gu;\n\nexport interface NameFormatOptions {\n\t/** Force title-casing even when the name already looks intentionally cased. */\n\tforce?: boolean;\n}\n\nexport interface NameProps extends Omit<ValueProps, 'children'> {\n\t/** Raw name value to normalize for display. */\n\tvalue?: string | null;\n\t/** String children are normalized when value is not provided. */\n\tchildren?: ReactNode;\n\t/** Force title-casing even when the name already looks intentionally cased. */\n\tforce?: boolean;\n}\n\nfunction normalizeNameWhitespace(value: string) {\n\treturn value.trim().replace(/\\s+/g, ' ');\n}\n\nfunction getLetters(value: string) {\n\treturn value.match(LETTERS_MATCHER)?.join('') ?? '';\n}\n\nfunction getFirstLetter(value: string) {\n\tconst match = LETTER_MATCHER.exec(value);\n\tif (!match) return null;\n\treturn {\n\t\tindex: match.index,\n\t\tvalue: match[0],\n\t};\n}\n\nfunction isFormattedSegment(segment: string) {\n\tconst first = getFirstLetter(segment);\n\tif (!first) return true;\n\n\tconst letters = getLetters(segment);\n\tif (letters.length <= 1) return first.value === first.value.toLocaleUpperCase();\n\n\tconst isAllUpper = letters === letters.toLocaleUpperCase();\n\tconst isAllLower = letters === letters.toLocaleLowerCase();\n\n\treturn first.value === first.value.toLocaleUpperCase() && !isAllUpper && !isAllLower;\n}\n\nfunction isFormattedName(value: string) {\n\treturn normalizeNameWhitespace(value)\n\t\t.split(WORD_SEPARATOR)\n\t\t.filter((word) => word.trim() !== '')\n\t\t.every((word) =>\n\t\t\tword\n\t\t\t\t.split(NAME_CONNECTOR)\n\t\t\t\t.filter((segment) => segment !== '-' && segment !== \"'\")\n\t\t\t\t.every(isFormattedSegment),\n\t\t);\n}\n\nfunction formatNameSegment(segment: string) {\n\tconst first = getFirstLetter(segment);\n\tif (!first) return segment;\n\n\tconst before = segment.slice(0, first.index);\n\tconst after = segment.slice(first.index + first.value.length);\n\n\treturn `${before}${first.value.toLocaleUpperCase()}${after.toLocaleLowerCase()}`;\n}\n\nfunction formatNameWord(word: string) {\n\treturn word\n\t\t.split(NAME_CONNECTOR)\n\t\t.map((segment) => (segment === '-' || segment === \"'\" ? segment : formatNameSegment(segment)))\n\t\t.join('');\n}\n\nexport function formatName(value: string | null | undefined, options: NameFormatOptions = {}) {\n\tif (value === null || value === undefined) return '';\n\n\tconst normalized = normalizeNameWhitespace(value);\n\tif (!normalized) return '';\n\tif (!options.force && isFormattedName(normalized)) return normalized;\n\n\treturn normalized\n\t\t.split(WORD_SEPARATOR)\n\t\t.map((word) => (word.trim() === '' ? word : formatNameWord(word)))\n\t\t.join('');\n}\n\nexport function Name({\n\tvalue,\n\tchildren,\n\tforce,\n\tclassName,\n\tref,\n\t...props\n}: NameProps) {\n\tconst rawValue = value ?? (typeof children === 'string' ? children : undefined);\n\tconst content = rawValue === undefined ? children : formatName(rawValue, { force });\n\n\treturn (\n\t\t<Value ref={ref} className={cn('name--component', className)} {...props}>\n\t\t\t{content}\n\t\t</Value>\n\t);\n}\n","import { cn } from '../../lib/utils';\n\nimport { Value, type ValueProps } from './value';\nimport {\n\tformatInitials,\n\ttype InitialsMaxCharacters,\n\ttype InitialsStrategy,\n} from './initials-format';\n\nexport interface InitialsProps extends Omit<ValueProps, 'children'> {\n\t/** Person, organization, or resource name used to derive initials. */\n\tvalue?: string | null;\n\t/** First + last word by default; use first-words to preserve the first N words. */\n\tstrategy?: InitialsStrategy;\n\t/** Maximum visible characters. Defaults to 2. */\n\tmaxCharacters?: InitialsMaxCharacters;\n\t/** Optional BCP-47 locale used for locale-sensitive uppercasing. */\n\tlocale?: string;\n\t/** Returned when no usable letter or number exists. Defaults to an empty string. */\n\tfallback?: string;\n\t/** Defaults to `inherit`: the avatar or chip that hosts the initials owns their size. */\n\tsize?: ValueProps['size'];\n\t/** Defaults to `inherit`: the host owns the colour, such as an avatar fallback tone. */\n\ttype?: ValueProps['type'];\n\t/** Defaults to `inherit`: the host owns the weight. */\n\tweight?: ValueProps['weight'];\n}\n\n/**\n * Semantic displayed initials for identities and avatar fallbacks. They take the\n * size, colour and weight of the avatar or chip that hosts them.\n */\nexport function Initials({\n\tvalue,\n\tstrategy,\n\tmaxCharacters,\n\tlocale,\n\tfallback,\n\tsize = 'inherit',\n\ttype = 'inherit',\n\tweight = 'inherit',\n\tclassName,\n\tref,\n\t...props\n}: InitialsProps) {\n\treturn (\n\t\t<Value\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tsize={size}\n\t\t\ttype={type}\n\t\t\tweight={weight}\n\t\t\tclassName={cn('initials--component', className)}\n\t\t>\n\t\t\t{formatInitials(value, {\n\t\t\t\tstrategy,\n\t\t\t\tmaxCharacters,\n\t\t\t\tlocale,\n\t\t\t\tfallback,\n\t\t\t})}\n\t\t</Value>\n\t);\n}\n","import { type AnchorHTMLAttributes, type ReactNode, type Ref } from 'react';\n\nimport { useTypographyConfig } from '../../lib/ui-provider';\nimport { EMPTY } from '../../lib/format';\nimport { cn } from '../../lib/utils';\nimport { RunningTextContext, useInRunningText } from '../typography/running-text';\nimport { inlineLinkClassName, linkUnderlineClassName } from '../typography/text-link';\nimport { resolveTextClassNames } from '../typography/text.styles';\n\nimport { EmptyValue } from './value';\n\nexport interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n\tchildren?: ReactNode;\n\t/** Rendered instead of a dead link when there is nothing to show. Defaults to an em dash. */\n\temptyLabel?: ReactNode;\n\tref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * Link-coloured inline value. Standalone it uses the provider text size with an\n * underline on hover. Inside running text it takes the sentence's size, weight\n * and leading and stays underlined, because colour alone does not set a link\n * apart from the words around it.\n */\nexport function Link({\n\tchildren,\n\temptyLabel = EMPTY,\n\tclassName,\n\tref,\n\t...props\n}: LinkProps) {\n\tconst inText = useInRunningText();\n\tconst { defaultTextSize } = useTypographyConfig();\n\tconst content =\n\t\tchildren === null || children === undefined || children === '' ? emptyLabel : children;\n\n\treturn (\n\t\t<a\n\t\t\tref={ref}\n\t\t\tdata-typography=\"link\"\n\t\t\tclassName={cn(\n\t\t\t\tresolveTextClassNames({\n\t\t\t\t\ttype: null,\n\t\t\t\t\tsize: inText ? 'inherit' : defaultTextSize,\n\t\t\t\t\tweight: null,\n\t\t\t\t\talign: null,\n\t\t\t\t\tlineHeight: inText ? null : 'normal',\n\t\t\t\t}),\n\t\t\t\t'link--component text-link-color wrap-anywhere',\n\t\t\t\tinlineLinkClassName,\n\t\t\t\tinText ? `${linkUnderlineClassName} hover:decoration-transparent` : 'no-underline underline-offset-[0.2em] hover:underline',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<RunningTextContext.Provider value>{content}</RunningTextContext.Provider>\n\t\t</a>\n\t);\n}\n\ntype ContactSpanProps = Omit<LinkProps, 'children' | 'emptyLabel' | 'ref' | 'href' | 'target' | 'rel' | 'download' | 'hrefLang' | 'ping' | 'referrerPolicy' | 'media' | 'type'>;\n\n/**\n * The missing contact value: the shared empty treatment, never a dead link.\n * Global attributes (ARIA, data, id, title) still reach the rendered span.\n */\nfunction EmptyContact({ className, emptyLabel, ref, contactProps }: { className: string; emptyLabel: ReactNode; ref?: Ref<HTMLElement>; contactProps: LinkProps }) {\n\tconst { href: _href, target: _target, rel: _rel, download: _download, hrefLang: _hrefLang, ping: _ping, referrerPolicy: _referrerPolicy, media: _media, type: _type, ...spanProps } = contactProps;\n\treturn <EmptyValue {...(spanProps as ContactSpanProps)} ref={ref as Ref<HTMLSpanElement>} className={className}>{emptyLabel}</EmptyValue>;\n}\n\nexport interface EmailProps extends Omit<LinkProps, 'href' | 'children' | 'ref'> {\n\tvalue?: string | null;\n\tdisplay?: ReactNode;\n\tsubject?: string;\n\tbody?: string;\n\tref?: Ref<HTMLElement>;\n}\n\nexport function Email({\n\tvalue,\n\tdisplay,\n\tsubject,\n\tbody,\n\tclassName,\n\temptyLabel = EMPTY,\n\tref,\n\t...props\n}: EmailProps) {\n\tif (!value) return <EmptyContact ref={ref} className={cn('email--component', className)} emptyLabel={emptyLabel} contactProps={props} />;\n\n\tconst query = new URLSearchParams();\n\tif (subject) query.set('subject', subject);\n\tif (body) query.set('body', body);\n\tconst href = `mailto:${value}${query.size ? `?${query.toString()}` : ''}`;\n\n\treturn (\n\t\t<Link ref={ref as Ref<HTMLAnchorElement>} className={cn('email--component', className)} href={href} emptyLabel={emptyLabel} {...props}>\n\t\t\t{display ?? value}\n\t\t</Link>\n\t);\n}\n\nexport interface PhoneProps extends Omit<LinkProps, 'href' | 'children' | 'ref'> {\n\tvalue?: string | null;\n\tdisplay?: ReactNode;\n\tref?: Ref<HTMLElement>;\n}\n\nfunction normalizeTel(value: string) {\n\treturn value.replace(/[^\\d+*#;,.]/g, '');\n}\n\nexport function Phone({\n\tvalue,\n\tdisplay,\n\tclassName,\n\temptyLabel = EMPTY,\n\tref,\n\t...props\n}: PhoneProps) {\n\tif (!value) return <EmptyContact ref={ref} className={cn('phone--component', className)} emptyLabel={emptyLabel} contactProps={props} />;\n\n\treturn (\n\t\t<Link ref={ref as Ref<HTMLAnchorElement>} className={cn('phone--component', className)} href={`tel:${normalizeTel(value)}`} emptyLabel={emptyLabel} {...props}>\n\t\t\t{display ?? value}\n\t\t</Link>\n\t);\n}\n\nexport interface UrlProps extends Omit<LinkProps, 'href' | 'children' | 'ref'> {\n\tvalue?: string | null;\n\tdisplay?: ReactNode;\n\texternal?: boolean;\n\tref?: Ref<HTMLElement>;\n}\n\nfunction normalizeUrl(value: string) {\n\tif (/^[a-z][a-z\\d+\\-.]*:/i.test(value) || value.startsWith('/') || value.startsWith('#')) return value;\n\treturn `https://${value}`;\n}\n\nexport function Url({\n\tvalue,\n\tdisplay,\n\texternal,\n\ttarget,\n\trel,\n\tclassName,\n\temptyLabel = EMPTY,\n\tref,\n\t...props\n}: UrlProps) {\n\tif (!value) return <EmptyContact ref={ref} className={cn('url--component', className)} emptyLabel={emptyLabel} contactProps={{ ...props, target, rel }} />;\n\n\tconst href = normalizeUrl(value);\n\tconst isExternal = external ?? /^https?:\\/\\//i.test(href);\n\tconst resolvedTarget = target ?? (isExternal ? '_blank' : undefined);\n\tconst resolvedRel = rel ?? (isExternal ? 'noreferrer' : undefined);\n\n\treturn (\n\t\t<Link\n\t\t\tref={ref as Ref<HTMLAnchorElement>}\n\t\t\tclassName={cn('url--component', className)}\n\t\t\thref={href}\n\t\t\ttarget={resolvedTarget}\n\t\t\trel={resolvedRel}\n\t\t\temptyLabel={emptyLabel}\n\t\t\t{...props}\n\t\t>\n\t\t\t{display ?? value}\n\t\t</Link>\n\t);\n}\n","import { type ComponentPropsWithoutRef, type ReactNode, type Ref } from 'react';\n\nimport { Text, type TextProps } from '../typography';\nimport type { TextSize } from '../../lib/ui-provider';\nimport { EMPTY } from '../../lib/format';\nimport { useFormattingConfig } from '../../lib/ui-provider';\nimport { cn } from '../../lib/utils';\n\nimport { emptyValueTypography, useValueTypography, type ValueTypographyRole } from './value-typography';\n\ntype SpanProps = Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'color'>;\n\nexport type FileSizeUnit = 'bytes' | 'kb' | 'mb' | 'gb' | 'tb';\n\nexport interface FileSizeProps extends SpanProps {\n\tvalue?: number | null;\n\tfrom?: FileSizeUnit;\n\tlocale?: string;\n\t/** Rendered with the shared empty treatment when the value is absent or not positive. Defaults to an em dash. */\n\temptyLabel?: ReactNode;\n\t/** Text size. Defaults to the provider text size; inside running text, the surrounding size. */\n\tsize?: TextSize;\n\t/** Text alignment. Defaults to `right` so columns of sizes line up. */\n\talign?: TextProps['align'];\n\t/** Font weight. Defaults to `regular`; inside running text, the surrounding weight. */\n\tweight?: TextProps['weight'];\n\t/** Colour role. Defaults to `main`; inside running text, the surrounding colour. */\n\ttype?: TextProps['type'];\n\tref?: Ref<HTMLSpanElement>;\n}\n\nconst FILE_SIZE_ROLE: ValueTypographyRole = { type: 'main', weight: 'regular' };\n\nconst FILE_SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\nconst FILE_SIZE_UNIT_MULTIPLIER: Record<FileSizeUnit, number> = {\n\tbytes: 1,\n\tkb: 1024,\n\tmb: 1024 ** 2,\n\tgb: 1024 ** 3,\n\ttb: 1024 ** 4,\n};\n\nexport interface FileSizeFormatOptions {\n\tfrom?: FileSizeUnit;\n\tlocale?: string;\n}\n\nfunction normalizeFileSizeValue(value?: number | null, from: FileSizeUnit = 'bytes') {\n\tif (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) return null;\n\treturn value * FILE_SIZE_UNIT_MULTIPLIER[from];\n}\n\nexport function formatFileSize(\n\tvalue?: number | null,\n\toptions?: FileSizeFormatOptions | string,\n): string | null {\n\tconst locale = typeof options === 'string' ? options : options?.locale;\n\tconst from = typeof options === 'string' ? 'bytes' : options?.from ?? 'bytes';\n\tconst bytes = normalizeFileSizeValue(value, from);\n\tif (bytes === null) return null;\n\n\tlet displayValue = bytes;\n\tlet unitIndex = 0;\n\twhile (displayValue >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n\t\tdisplayValue /= 1024;\n\t\tunitIndex += 1;\n\t}\n\n\tconst formattedValue = new Intl.NumberFormat(locale, {\n\t\tmaximumFractionDigits: unitIndex === 0 ? 0 : 1,\n\t\tminimumFractionDigits: 0,\n\t}).format(displayValue);\n\n\treturn `${formattedValue} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n\n/** A byte count in the largest readable unit, sans UI font with tabular figures. */\nexport function FileSize({\n\tvalue,\n\tfrom = 'bytes',\n\tlocale,\n\temptyLabel = EMPTY,\n\tsize,\n\talign = 'right',\n\tweight,\n\ttype,\n\tclassName,\n\tref,\n\t...props\n}: FileSizeProps) {\n\tconst formatting = useFormattingConfig();\n\tconst resolved = useValueTypography({ size, type, weight }, FILE_SIZE_ROLE);\n\tconst label = formatFileSize(value, { from, locale: locale ?? formatting.locale });\n\tconst typography = label === null ? emptyValueTypography(resolved, weight) : resolved;\n\n\treturn (\n\t\t<Text\n\t\t\tref={ref}\n\t\t\ttag=\"span\"\n\t\t\tsize={typography.size}\n\t\t\talign={align}\n\t\t\tweight={typography.weight}\n\t\t\ttype={typography.type}\n\t\t\tlineHeight={typography.lineHeight}\n\t\t\tclassName={cn('file-size--component inline tabular-nums', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{label ?? emptyLabel}\n\t\t</Text>\n\t);\n}\n","import { type ComponentPropsWithoutRef, type ReactNode, type Ref } from 'react';\n\nimport { Text, type TextProps } from '../typography';\nimport type { TextSize } from '../../lib/ui-provider';\nimport {\n\tEMPTY,\n\tformatDuration,\n\ttype DurationUnit,\n\ttype DurationUnitDisplay,\n} from '../../lib/format';\nimport { useFormattingConfig } from '../../lib/ui-provider';\nimport { cn } from '../../lib/utils';\n\nimport { emptyValueTypography, useValueTypography, type ValueTypographyRole } from './value-typography';\n\ntype SpanProps = Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'color'>;\n\nexport interface DurationProps extends SpanProps {\n\tvalue?: number | null;\n\tfrom?: DurationUnit;\n\tlocale?: string;\n\tmaxParts?: number;\n\tunitDisplay?: DurationUnitDisplay;\n\tminimumFractionDigits?: number;\n\tmaximumFractionDigits?: number;\n\t/** Rendered with the shared empty treatment when the value is absent. Defaults to an em dash. */\n\temptyLabel?: ReactNode;\n\t/** Text size. Defaults to the provider text size; inside running text, the surrounding size. */\n\tsize?: TextSize;\n\t/** Text alignment. Defaults to `right` so columns of durations line up. */\n\talign?: TextProps['align'];\n\t/** Font weight. Defaults to `regular`; inside running text, the surrounding weight. */\n\tweight?: TextProps['weight'];\n\t/** Colour role. Defaults to `main`; inside running text, the surrounding colour. */\n\ttype?: TextProps['type'];\n\tref?: Ref<HTMLSpanElement>;\n}\n\nconst DURATION_ROLE: ValueTypographyRole = { type: 'main', weight: 'regular' };\n\n/** An elapsed span in localized units, sans UI font with tabular figures. */\nexport function Duration({\n\tvalue,\n\tfrom = 'seconds',\n\tlocale,\n\tmaxParts = 2,\n\tunitDisplay = 'narrow',\n\tminimumFractionDigits,\n\tmaximumFractionDigits,\n\temptyLabel = EMPTY,\n\tsize,\n\talign = 'right',\n\tweight,\n\ttype,\n\tclassName,\n\tref,\n\t...props\n}: DurationProps) {\n\tconst formatting = useFormattingConfig();\n\tconst resolved = useValueTypography({ size, type, weight }, DURATION_ROLE);\n\tconst label = value === null || value === undefined\n\t\t? null\n\t\t: formatDuration(value, {\n\t\t\t\tfrom,\n\t\t\t\tlocale: locale ?? formatting.locale,\n\t\t\t\tmaxParts,\n\t\t\t\tunitDisplay,\n\t\t\t\tminimumFractionDigits,\n\t\t\t\tmaximumFractionDigits: maximumFractionDigits ?? (\n\t\t\t\t\tfrom === 'milliseconds' ? 1 : undefined\n\t\t\t\t),\n\t\t\t});\n\n\tconst empty = label === null || label === EMPTY;\n\tconst typography = empty ? emptyValueTypography(resolved, weight) : resolved;\n\n\treturn (\n\t\t<Text\n\t\t\tref={ref}\n\t\t\ttag=\"span\"\n\t\t\tsize={typography.size}\n\t\t\talign={align}\n\t\t\tweight={typography.weight}\n\t\t\ttype={typography.type}\n\t\t\tlineHeight={typography.lineHeight}\n\t\t\tclassName={cn('duration--component inline tabular-nums', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{empty ? emptyLabel : label}\n\t\t</Text>\n\t);\n}\n\nexport { formatDuration } from '../../lib/format';\nexport type { DurationUnit, DurationUnitDisplay, FormatDurationOptions } from '../../lib/format';\n","import { type ComponentPropsWithoutRef, type ReactNode, type Ref } from 'react';\n\nimport { Text, type TextProps } from '../typography';\nimport type { TextSize } from '../../lib/ui-provider';\nimport { EMPTY, formatWithMinusSign } from '../../lib/format';\nimport { useFormattingConfig } from '../../lib/ui-provider';\nimport { cn } from '../../lib/utils';\n\nimport { emptyValueTypography, useValueTypography, type ValueTypographyRole } from './value-typography';\n\ntype SpanProps = Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'color'>;\ntype DimensionPart = number | string | null | undefined;\n\nexport interface FormatDimensionsOptions {\n\tdepth?: DimensionPart;\n\tunit?: string;\n\tseparator?: string;\n\tlocale?: string;\n\toptions?: Intl.NumberFormatOptions;\n}\n\nexport interface DimensionsProps extends SpanProps {\n\twidth?: DimensionPart;\n\theight?: DimensionPart;\n\tdepth?: DimensionPart;\n\tunit?: ReactNode;\n\tseparator?: ReactNode;\n\tlocale?: string;\n\toptions?: Intl.NumberFormatOptions;\n\t/** Rendered with the shared empty treatment when width or height is missing. Defaults to an em dash. */\n\temptyLabel?: ReactNode;\n\t/** Text size. Defaults to the provider text size; inside running text, the surrounding size. */\n\tsize?: TextSize;\n\t/** Text alignment. Defaults to `right` so columns of readings line up. */\n\talign?: TextProps['align'];\n\t/** Font weight. Defaults to `regular`; inside running text, the surrounding weight. */\n\tweight?: TextProps['weight'];\n\t/** Colour role. Defaults to `main`; inside running text, the surrounding colour. */\n\ttype?: TextProps['type'];\n\tref?: Ref<HTMLSpanElement>;\n}\n\nconst DIMENSIONS_ROLE: ValueTypographyRole = { type: 'main', weight: 'regular' };\n\nfunction parseDimensionPart(value: DimensionPart): number | null {\n\tif (value === null || value === undefined || value === '') return null;\n\tif (typeof value === 'number') return Number.isFinite(value) ? value : null;\n\tconst normalized = value.trim().replace(',', '.');\n\tif (!normalized) return null;\n\tconst parsed = Number(normalized);\n\treturn Number.isFinite(parsed) ? parsed : null;\n}\n\nexport function formatDimensions(\n\twidth: DimensionPart,\n\theight: DimensionPart,\n\t{\n\t\tdepth,\n\t\tunit,\n\t\tseparator = ' × ',\n\t\tlocale,\n\t\toptions,\n\t}: FormatDimensionsOptions = {},\n): string | null {\n\tconst parsedWidth = parseDimensionPart(width);\n\tconst parsedHeight = parseDimensionPart(height);\n\tconst parsedDepth = parseDimensionPart(depth);\n\tif (parsedWidth === null || parsedHeight === null) return null;\n\tif (depth !== null && depth !== undefined && depth !== '' && parsedDepth === null) return null;\n\n\tconst formatter = new Intl.NumberFormat(locale, options);\n\tconst values = [parsedWidth, parsedHeight];\n\tif (parsedDepth !== null) values.push(parsedDepth);\n\tconst label = values.map((value) => formatWithMinusSign(formatter, value)).join(separator);\n\treturn unit ? `${label} ${unit}` : label;\n}\n\n/** A width × height (× depth) reading with localized numbers, sans UI font with tabular figures. */\nexport function Dimensions({\n\twidth,\n\theight,\n\tdepth,\n\tunit,\n\tseparator = ' × ',\n\tlocale,\n\toptions,\n\temptyLabel = EMPTY,\n\tsize,\n\talign = 'right',\n\tweight,\n\ttype,\n\tclassName,\n\tref,\n\t...props\n}: DimensionsProps) {\n\tconst formatting = useFormattingConfig();\n\tconst resolved = useValueTypography({ size, type, weight }, DIMENSIONS_ROLE);\n\tconst label = formatDimensions(width, height, {\n\t\tdepth,\n\t\tseparator: typeof separator === 'string' ? separator : ' × ',\n\t\tlocale: locale ?? formatting.locale,\n\t\toptions,\n\t});\n\n\tconst typography = label === null ? emptyValueTypography(resolved, weight) : resolved;\n\n\treturn (\n\t\t<Text\n\t\t\tref={ref}\n\t\t\ttag=\"span\"\n\t\t\tsize={typography.size}\n\t\t\talign={align}\n\t\t\tweight={typography.weight}\n\t\t\ttype={typography.type}\n\t\t\tlineHeight={typography.lineHeight}\n\t\t\tclassName={cn('dimensions--component inline tabular-nums', className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{label === null ? emptyLabel : (\n\t\t\t\t<>\n\t\t\t\t\t{typeof separator === 'string' ? label : label.split(' × ').map((part, index) => (\n\t\t\t\t\t\t<span key={`${part}-${index}`}>\n\t\t\t\t\t\t\t{index > 0 && separator}\n\t\t\t\t\t\t\t{part}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t))}\n\t\t\t\t\t{!!unit && <> {unit}</>}\n\t\t\t\t</>\n\t\t\t)}\n\t\t</Text>\n\t);\n}\n"],"mappings":";;;;;;;;;;AA8BA,IAAMe,IAAkC;CAAE,MAAM;CAAQ,QAAQ;AAAU,GACpEC,IAAsC;CAAE,MAAM;CAAa,QAAQ;CAAW,UAAU;AAAK,GAC7FC,IAAiC;CAAE,MAAM;CAAQ,QAAQ;CAAU,kBAAkB;AAAO;AAElG,SAASC,EAAa,GAAqB;CAC1C,OAAOC,KAAa,QAAkCA,MAAa;AACpE;AASA,SAASC,EAAU,EAAE,cAAW,kBAAe,aAAU,IAAO,aAAU,gBAAA,KAAoB,SAAM,UAAO,WAAQ,SAAM,cAAW,QAAK,GAAGC,KAAyB;CACpK,IAAMC,IAAWb,EAAmB;EAAE;EAAM;EAAM;CAAO,GAAGc,CAAS,GAC/DC,IAAQN,EAAaC,CAAQ,GAC7BM,IAAaD,IAAQZ,EAAqBU,GAAUI,CAAM,IAAIJ;CACpE,OACC,kBAACK,GAAD;EACM;EACL,KAAI;EACJ,MAAMF,EAAW;EACV;EACP,QAAQA,EAAW;EACnB,MAAMA,EAAW;EACjB,YAAYA,EAAW;EACvB,SAASG,KAAW,CAACJ;EACrB,WAAWrB,EAAG0B,GAAeC,CAAS;EACtC,GAAIT;EAEH,UAAAG,IAAQO,IAAaZ;CACjB,CAAA;AAER;AAMA,SAAgBa,EAAM,GAAmB;CACxC,OAAO,kBAACZ,GAAD;EAAW,GAAIC;EAAO,WAAWN;EAAY,eAAc;CAAmC,CAAA;AACtG;AAGA,SAAgBkB,EAAe,GAAmB;CACjD,OAAO,kBAACb,GAAD;EAAW,GAAIC;EAAO,WAAWL;EAAgB,eAAc;CAA6C,CAAA;AACpH;AAGA,SAAgBkB,EAAW,GAAmB;CAC7C,OAAO,kBAACd,GAAD;EAAW,GAAIC;EAAO,WAAWL;EAAgB,eAAc;CAAoD,CAAA;AAC3H;AASA,SAAgBmB,EAAU,GAAmB;CAC5C,OAAO,kBAACf,GAAD;EAAW,GAAIC;EAAO,WAAWJ;EAAW,SAAA;EAAQ,eAAc;CAAoD,CAAA;AAC9H;AAUA,SAAgBmB,EAAW,EAAE,cAAA,KAAkB,GAAGf,KAA0B;CAC3E,OAAO,kBAACD,GAAD;EAAW,GAAIC;EAAO,WAAWL;EAAgB,YAAA;EAAmB,eAAc;EAAyC;CAAoB,CAAA;AACvJ;;;ACpGA,IAAMqB,IAAiB,UACjBC,IAAiB,WACjBC,IAAiB,UACjBC,KAAkB;AAgBxB,SAASC,EAAwB,GAAe;CAC/C,OAAOC,EAAM,KAAK,CAAC,CAAC,QAAQ,QAAQ,GAAG;AACxC;AAEA,SAASC,EAAW,GAAe;CAClC,OAAOD,EAAM,MAAMF,EAAe,CAAC,EAAE,KAAK,EAAE,KAAK;AAClD;AAEA,SAASI,EAAe,GAAe;CACtC,IAAMC,IAAQN,EAAe,KAAKG,CAAK;CAEvC,OADKG,IACE;EACN,OAAOA,EAAM;EACb,OAAOA,EAAM;CACd,IAJmB;AAKpB;AAEA,SAASC,EAAmB,GAAiB;CAC5C,IAAMC,IAAQH,EAAeI,CAAO;CACpC,IAAI,CAACD,GAAO,OAAO;CAEnB,IAAME,IAAUN,EAAWK,CAAO;CAClC,IAAIC,EAAQ,UAAU,GAAG,OAAOF,EAAM,UAAUA,EAAM,MAAM,kBAAkB;CAE9E,IAAMG,IAAaD,MAAYA,EAAQ,kBAAkB,GACnDE,IAAaF,MAAYA,EAAQ,kBAAkB;CAEzD,OAAOF,EAAM,UAAUA,EAAM,MAAM,kBAAkB,KAAK,CAACG,KAAc,CAACC;AAC3E;AAEA,SAASC,EAAgB,GAAe;CACvC,OAAOX,EAAwBC,CAAK,CAAC,CACnC,MAAML,CAAc,CAAC,CACrB,QAAQ,MAASgB,EAAK,KAAK,MAAM,EAAE,CAAC,CACpC,OAAO,MACPA,EACE,MAAMf,CAAc,CAAC,CACrB,QAAQ,MAAYU,MAAY,OAAOA,MAAY,GAAG,CAAC,CACvD,MAAMF,CAAkB,CAC3B;AACF;AAEA,SAASQ,EAAkB,GAAiB;CAC3C,IAAMP,IAAQH,EAAeI,CAAO;CACpC,IAAI,CAACD,GAAO,OAAOC;CAEnB,IAAMO,IAASP,EAAQ,MAAM,GAAGD,EAAM,KAAK,GACrCS,IAAQR,EAAQ,MAAMD,EAAM,QAAQA,EAAM,MAAM,MAAM;CAE5D,OAAO,GAAGQ,IAASR,EAAM,MAAM,kBAAkB,IAAIS,EAAM,kBAAkB;AAC9E;AAEA,SAASC,EAAe,GAAc;CACrC,OAAOJ,EACL,MAAMf,CAAc,CAAC,CACrB,KAAK,MAAaU,MAAY,OAAOA,MAAY,MAAMA,IAAUM,EAAkBN,CAAO,CAAE,CAAC,CAC7F,KAAK,EAAE;AACV;AAEA,SAAgBU,EAAW,GAAkC,IAA6B,CAAC,GAAG;CAC7F,IAAIhB,KAAU,MAA6B,OAAO;CAElD,IAAMiB,IAAalB,EAAwBC,CAAK;CAIhD,OAHKiB,IACD,CAACC,EAAQ,SAASR,EAAgBO,CAAU,IAAUA,IAEnDA,EACL,MAAMtB,CAAc,CAAC,CACrB,KAAK,MAAUgB,EAAK,KAAK,MAAM,KAAKA,IAAOI,EAAeJ,CAAI,CAAE,CAAC,CACjE,KAAK,EAAE,IANe;AAOzB;AAEA,SAAgBQ,EAAK,EACpB,UACA,aACA,UACA,cACA,QACA,GAAGxC,KACU;CACb,IAAMyC,IAAWpB,MAAU,OAAOvB,KAAa,WAAWA,IAAW,KAAA,IAC/D4C,IAAUD,MAAa,KAAA,IAAY3C,IAAWuC,EAAWI,GAAU,EAAE,SAAM,CAAC;CAElF,OACC,kBAAC9B,GAAD;EAAY;EAAK,WAAW7B,EAAG,mBAAmB2B,CAAS;EAAG,GAAIT;EAChE,UAAA0C;CACK,CAAA;AAET;;;ACjFA,SAAgBC,EAAS,EACxB,UACA,aACA,kBACA,WACA,aACA,UAAO,WACP,UAAO,WACP,YAAS,WACT,cACA,QACA,GAAG3C,KACc;CACjB,OACC,kBAACW,GAAD;EACM;EACL,GAAIX;EACE;EACA;EACE;EACR,WAAWlB,EAAG,uBAAuB2B,CAAS;EAE7C,UAAAjB,EAAe6B,GAAO;GACtB;GACA;GACA;GACA;EACD,CAAC;CACK,CAAA;AAET;;;ACtCA,SAAgBuB,EAAK,EACpB,aACA,gBAAA,KACA,cACA,QACA,GAAG5C,KACU;CACb,IAAM6C,IAAS7D,EAAiB,GAC1B,EAAE,uBAAoBH,EAAoB,GAC1C6D,IACL5C,KAAa,QAAkCA,MAAa,KAAKY,IAAaZ;CAE/E,OACC,kBAAC,KAAD;EACM;EACL,mBAAgB;EAChB,WAAWhB,EACVK,EAAsB;GACrB,MAAM;GACN,MAAM0D,IAAS,YAAYC;GAC3B,QAAQ;GACR,OAAO;GACP,YAAYD,IAAS,OAAO;EAC7B,CAAC,GACD,iDACA5D,GACA4D,IAAS,GAAG3D,EAAuB,iCAAiC,yDACpEuB,CACD;EACA,GAAIT;EAEJ,UAAA,kBAACjB,EAAmB,UAApB;GAA6B,OAAA;GAAO,UAAA2D;EAAqC,CAAA;CACvE,CAAA;AAEL;AAQA,SAASK,EAAa,EAAE,cAAW,eAAY,QAAK,mBAA+G;CAClK,IAAM,EAAE,MAAMC,GAAO,QAAQC,GAAS,KAAKC,GAAM,UAAUC,GAAW,UAAUC,GAAW,MAAMC,GAAO,gBAAgBC,GAAiB,OAAOC,GAAQ,MAAMC,GAAO,GAAGC,MAAcC;CACtL,OAAO,kBAAC3C,GAAD;EAAY,GAAK0C;EAAqC;EAAwC;EAAY,UAAA/C;CAAuB,CAAA;AACzI;AAUA,SAAgBiD,EAAM,EACrB,UACA,YACA,YACA,SACA,cACA,gBAAA,KACA,QACA,GAAG3D,KACW;CACd,IAAI,CAACqB,GAAO,OAAO,kBAAC0B,GAAD;EAAmB;EAAK,WAAWjE,EAAG,oBAAoB2B,CAAS;EAAe;EAAY,cAAcT;CAAQ,CAAA;CAEvI,IAAM4D,IAAQ,IAAI,gBAAgB;CAElC,AADIC,KAASD,EAAM,IAAI,WAAWC,CAAO,GACrCC,KAAMF,EAAM,IAAI,QAAQE,CAAI;CAChC,IAAMC,IAAO,UAAU1C,IAAQuC,EAAM,OAAO,IAAIA,EAAM,SAAS,MAAM;CAErE,OACC,kBAAChB,GAAD;EAAW;EAA+B,WAAW9D,EAAG,oBAAoB2B,CAAS;EAAS;EAAkB;EAAY,GAAIT;EAC9H,UAAAgE,KAAW3C;CACP,CAAA;AAER;AAQA,SAAS4C,EAAa,GAAe;CACpC,OAAO5C,EAAM,QAAQ,gBAAgB,EAAE;AACxC;AAEA,SAAgB6C,EAAM,EACrB,UACA,YACA,cACA,gBAAA,KACA,QACA,GAAGlE,KACW;CAGd,OAFKqB,IAGJ,kBAACuB,GAAD;EAAW;EAA+B,WAAW9D,EAAG,oBAAoB2B,CAAS;EAAG,MAAM,OAAOwD,EAAa5C,CAAK;EAAiB;EAAY,GAAIrB;EACtJ,UAAAgE,KAAW3C;CACP,CAAA,IALY,kBAAC0B,GAAD;EAAmB;EAAK,WAAWjE,EAAG,oBAAoB2B,CAAS;EAAe;EAAY,cAAcT;CAAQ,CAAA;AAOxI;AASA,SAASmE,EAAa,GAAe;CAEpC,OADI,uBAAuB,KAAK9C,CAAK,KAAKA,EAAM,WAAW,GAAG,KAAKA,EAAM,WAAW,GAAG,IAAUA,IAC1F,WAAWA;AACnB;AAEA,SAAgB+C,EAAI,EACnB,UACA,YACA,aACA,WACA,QACA,cACA,gBAAA,KACA,QACA,GAAGpE,KACS;CACZ,IAAI,CAACqB,GAAO,OAAO,kBAAC0B,GAAD;EAAmB;EAAK,WAAWjE,EAAG,kBAAkB2B,CAAS;EAAe;EAAY,cAAc;GAAE,GAAGT;GAAO;GAAQ;EAAI;CAAI,CAAA;CAEzJ,IAAM+D,IAAOI,EAAa9C,CAAK,GACzBgD,IAAaC,KAAY,gBAAgB,KAAKP,CAAI,GAClDQ,IAAiBC,MAAWH,IAAa,WAAW,KAAA,IACpDI,IAAcC,MAAQL,IAAa,eAAe,KAAA;CAExD,OACC,kBAACzB,GAAD;EACM;EACL,WAAW9D,EAAG,kBAAkB2B,CAAS;EACnC;EACN,QAAQ8D;EACR,KAAKE;EACO;EACZ,GAAIzE;EAEH,UAAAgE,KAAW3C;CACP,CAAA;AAER;;;AC9IA,IAAMsD,IAAsC;CAAE,MAAM;CAAQ,QAAQ;AAAU,GAExEC,IAAkB;CAAC;CAAK;CAAM;CAAM;CAAM;AAAI,GAC9CC,IAA0D;CAC/D,OAAO;CACP,IAAI;CACJ,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,QAAQ;AACb;AAOA,SAASC,EAAuB,GAAuB,IAAqB,SAAS;CAEpF,OADI,OAAOzD,KAAU,YAAY,CAAC,OAAO,SAASA,CAAK,KAAKA,KAAS,IAAU,OACxEA,IAAQwD,EAA0BE;AAC1C;AAEA,SAAgBC,EACf,GACA,GACgB;CAChB,IAAMC,IAAS,OAAO1C,KAAY,WAAWA,IAAUA,GAAS,QAE1D2C,IAAQJ,EAAuBzD,GADxB,OAAOkB,KAAY,WAAW,UAAUA,GAAS,QAAQ,OACtB;CAChD,IAAI2C,MAAU,MAAM,OAAO;CAE3B,IAAIC,IAAeD,GACfE,IAAY;CAChB,OAAOD,KAAgB,QAAQC,IAAYR,EAAgB,SAAS,IAEnE,AADA,KAAgB,MAChB,KAAa;CAQd,OAAO,GALgB,IAAI,KAAK,aAAaK,GAAQ;EACpD,uBAAuBG,MAAc,IAAI,IAAI;EAC7C,uBAAuB;CACxB,CAAC,CAAC,CAAC,OAAOD,CAEA,EAAe,GAAGP,EAAgBQ;AAC7C;AAGA,SAAgBC,GAAS,EACxB,UACA,UAAO,SACP,WACA,gBAAA,KACA,SACA,WAAQ,SACR,WACA,SACA,cACA,QACA,GAAGrF,KACc;CACjB,IAAMsF,IAAa1G,EAAoB,GACjCqB,IAAWb,EAAmB;EAAE;EAAM;EAAM;CAAO,GAAGuF,CAAc,GACpEY,IAAQP,EAAe3D,GAAO;EAAE;EAAM,QAAQ4D,KAAUK,EAAW;CAAO,CAAC,GAC3ElF,IAAamF,MAAU,OAAOhG,EAAqBU,GAAUI,CAAM,IAAIJ;CAE7E,OACC,kBAACK,GAAD;EACM;EACL,KAAI;EACJ,MAAMF,EAAW;EACV;EACP,QAAQA,EAAW;EACnB,MAAMA,EAAW;EACjB,YAAYA,EAAW;EACvB,WAAWtB,EAAG,4CAA4C2B,CAAS;EACnE,GAAIT;EAEH,UAAAuF,KAAS7E;CACL,CAAA;AAER;;;ACxEA,IAAM8E,KAAqC;CAAE,MAAM;CAAQ,QAAQ;AAAU;AAG7E,SAAgBC,GAAS,EACxB,UACA,UAAO,WACP,WACA,cAAW,GACX,iBAAc,UACd,0BACA,0BACA,gBAAA,KACA,SACA,WAAQ,SACR,WACA,SACA,cACA,QACA,GAAGzF,KACc;CACjB,IAAMsF,IAAa1G,EAAoB,GACjCqB,IAAWb,EAAmB;EAAE;EAAM;EAAM;CAAO,GAAGoG,EAAa,GACnED,IAAQlE,KAAU,OACrB,OACA/B,EAAe+B,GAAO;EACtB;EACA,QAAQ4D,KAAUK,EAAW;EAC7B;EACA;EACA;EACA,uBAAuBI,MACtBX,MAAS,iBAAiB,IAAI,KAAA;CAEhC,CAAC,GAEG5E,IAAQoF,MAAU,QAAQA,MAAA,KAC1BnF,IAAaD,IAAQZ,EAAqBU,GAAUI,CAAM,IAAIJ;CAEpE,OACC,kBAACK,GAAD;EACM;EACL,KAAI;EACJ,MAAMF,EAAW;EACV;EACP,QAAQA,EAAW;EACnB,MAAMA,EAAW;EACjB,YAAYA,EAAW;EACvB,WAAWtB,EAAG,2CAA2C2B,CAAS;EAClE,GAAIT;EAEH,UAAAG,IAAQO,IAAa6E;CACjB,CAAA;AAER;;;ACjDA,IAAMI,KAAuC;CAAE,MAAM;CAAQ,QAAQ;AAAU;AAE/E,SAASC,EAAmB,GAAqC;CAChE,IAAIvE,KAAU,QAA+BA,MAAU,IAAI,OAAO;CAClE,IAAI,OAAOA,KAAU,UAAU,OAAO,OAAO,SAASA,CAAK,IAAIA,IAAQ;CACvE,IAAMiB,IAAajB,EAAM,KAAK,CAAC,CAAC,QAAQ,KAAK,GAAG;CAChD,IAAI,CAACiB,GAAY,OAAO;CACxB,IAAMuD,IAAS,OAAOvD,CAAU;CAChC,OAAO,OAAO,SAASuD,CAAM,IAAIA,IAAS;AAC3C;AAEA,SAAgBC,EACf,GACA,GACA,EACC,UACA,SACA,eAAY,OACZ,WACA,eAC4B,CAAC,GACd;CAChB,IAAMC,IAAcH,EAAmBI,CAAK,GACtCC,IAAeL,EAAmBM,CAAM,GACxCC,IAAcP,EAAmBQ,CAAK;CAE5C,IADIL,MAAgB,QAAQE,MAAiB,QACzCG,KAAU,QAA+BA,MAAU,MAAMD,MAAgB,MAAM,OAAO;CAE1F,IAAME,IAAY,IAAI,KAAK,aAAapB,GAAQ1C,CAAO,GACjD+D,IAAS,CAACP,GAAaE,CAAY;CACzC,AAAIE,MAAgB,QAAMG,EAAO,KAAKH,CAAW;CACjD,IAAMZ,IAAQe,EAAO,KAAK,MAAUjH,EAAoBgH,GAAWhF,CAAK,CAAC,CAAC,CAAC,KAAKkF,CAAS;CACzF,OAAOC,IAAO,GAAGjB,EAAM,GAAGiB,MAASjB;AACpC;AAGA,SAAgBkB,GAAW,EAC1B,UACA,WACA,UACA,SACA,eAAY,OACZ,WACA,YACA,gBAAA,KACA,SACA,WAAQ,SACR,WACA,SACA,cACA,QACA,GAAGzG,KACgB;CACnB,IAAMsF,IAAa1G,EAAoB,GACjCqB,IAAWb,EAAmB;EAAE;EAAM;EAAM;CAAO,GAAGuG,EAAe,GACrEJ,IAAQO,EAAiBE,GAAOE,GAAQ;EAC7C;EACA,WAAW,OAAOK,KAAc,WAAWA,IAAY;EACvD,QAAQtB,KAAUK,EAAW;EAC7B;CACD,CAAC,GAEKlF,IAAamF,MAAU,OAAOhG,EAAqBU,GAAUI,CAAM,IAAIJ;CAE7E,OACC,kBAACK,GAAD;EACM;EACL,KAAI;EACJ,MAAMF,EAAW;EACV;EACP,QAAQA,EAAW;EACnB,MAAMA,EAAW;EACjB,YAAYA,EAAW;EACvB,WAAWtB,EAAG,6CAA6C2B,CAAS;EACpE,GAAIT;EAEH,UAAAuF,MAAU,OAAO7E,IACjB,kBAAA/B,GAAA,EAAA,UAAA,CACE,OAAO4H,KAAc,WAAWhB,IAAQA,EAAM,MAAM,KAAK,CAAC,CAAC,KAAK,GAAM,MACtE,kBAAC,QAAD,EAAA,UAAA,CACEmB,IAAQ,KAAKH,GACbI,CACI,EAAA,GAHK,GAAGA,EAAK,GAAGD,GAGhB,CACN,GACA,CAAC,CAACF,KAAQ,kBAAA7H,GAAA,EAAA,UAAA,CAAE,KAAE6H,CAAO,EAAA,CAAA,CACrB,EAAA,CAAA;CAEE,CAAA;AAER"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rich-text-editor-sMU_Scqm.js","names":["NumberValue","_Fragment","_Fragment","EditorContent","StarterKit","cn","Button","Text","Stack","safeImageSrc","editableContentClassName","SecondaryValue","Number$1","Input","FormField","RichTextEditorToolbar","richTextEditorRecipes","defaultRichTextEditorStrings","Fragment$1","TiptapReact","StarterKitModule","readCaretContext","sel","range","startNode","startOffset","block","editable","text","cursor","prev","rect","r","replaceBeforeCaret","editor","selection","from","length","html","notifyChange","caret","remaining","take","previousTextNode","fragment","insertHtmlIntoEditable","current","node","CountsFooterText","chars","words","overLimit","maxLength","className","strings","CountsFooter","sourceMode","sourceValue","normalizeHtml","trimmed","value","toEditorContent","normalized","inlineReferenceChipClassName","NODE_NAME","deleteAdjacentReference","state","direction","$from","tr","inlineReferenceNode","getInlineReferenceNode","element","attributes","HTMLAttributes","dom","UPLOAD_ATTRIBUTE","UPLOAD_PLACEHOLDER_CLASS","PLACEHOLDER_PATTERN","stripUploadPlaceholders","acceptsImageFile","type","file","name","accept","entry","altFromFileName","imageFilesFrom","data","uploadSequence","useImageUploadQueue","uploads","setUploads","useState","notice","setNotice","jobs","useRef","job","forget","useCallback","id","upload","run","images","controller","pending","result","src","placed","adapterRef","error","refused","files","reason","message","interpolateString","ImageUploadStatus","failed","AlertCircle","Loader2","onRetry","onRemove","ImageUploadPortals","queue","target","createPortal","useImageInsertControl","inputRef","beforeOpenRef","beforeOpen","enabled","useMemo","ImagePlus","event","onFiles","ImageDetailsBar","inputId","useId","alt","onDismissNotice","onAltChange","positiveNumber","number","imageNode","imageUploadNode","getImageNode","getImageUploadNode","valueHtml","EditorContent$1","useTiptapEditor","StarterKit$1","TiptapRichTextEditor","forwardRef","stringsProp","useStrings","imagesEnabled","queueRef","editorInstanceRef","isFocused","setIsFocused","setSourceMode","setSourceValue","isFocusedRef","externalValueRef","onCaretChangeRef","onCaretChange","disabled","autoFocus","currentEditor","onValueChange","imagesRef","moved","at","view","useEffect","next","handler","useImperativeHandle","ref","emitValue","findNode","found","match","created","image","uploadQueue","imageInsert","toolbarItems","extraToolbarItems","activeImage","setActiveImage","sync","nodeBefore","nodeAfter","contentStyle","minHeight","compact","maxHeight","toggleSourceMode","handleSourceChange","toolbarButtons","Bold","Italic","Strikethrough","List","ListOrdered","Quote","Undo2","Redo2","countsFooter","showCounts","placeholderText","placeholder","placeholderNode","footerSlot","hasTiptapRuntime","serializeEditable","copy","removeUnsafeImages","imageAtSelection","startContainer","placeCaretAtPoint","doc","x","y","position","FallbackRichTextEditor","editableRef","savedRangeRef","activeAlt","setActiveAlt","setEditableRef","emitEditableChange","saved","syncActiveImage","handleInput","isEmpty","RichTextEditor","props"],"sources":["../src/components/features/rich-text-editor/partials/caret-helpers.ts","../src/components/features/rich-text-editor/partials/counts-footer.tsx","../src/components/features/rich-text-editor/partials/html-helpers.ts","../src/components/features/rich-text-editor/partials/inline-reference-node.ts","../src/components/features/rich-text-editor/partials/image-uploads.tsx","../src/components/features/rich-text-editor/partials/image-nodes.ts","../src/components/features/rich-text-editor/partials/rich-text-editor-tiptap.tsx","../src/components/features/rich-text-editor/partials/rich-text-editor-fallback.tsx","../src/components/features/rich-text-editor/rich-text-editor.tsx"],"sourcesContent":["/**\n * Caret-introspection helpers used by `<RichTextEditor>` to expose the\n * text before the caret and replace a leading run of characters with\n * inline HTML — the building blocks for `@`-mention chips and similar\n * inline triggers.\n */\nimport type { RichTextCaretContext, TiptapEditor } from '../rich-text-editor.types';\n\n/**\n * Read the current selection's caret context.\n *\n * Walks back from the caret through the current text node and any\n * preceding sibling text nodes inside the same block-level container\n * (paragraph / list-item / heading) collecting plain text. Returns the\n * accumulated text plus the caret's bounding rect when available.\n *\n * Returns `null` when there is no live selection or the selection isn't\n * a text caret inside a contenteditable.\n */\nexport function readCaretContext(): RichTextCaretContext | null {\n\tif (typeof window === 'undefined') return null;\n\tconst sel = window.getSelection();\n\tif (!sel || sel.rangeCount === 0) return null;\n\tconst range = sel.getRangeAt(0);\n\tif (!range.collapsed) return null;\n\n\tconst startNode = range.startContainer;\n\tconst startOffset = range.startOffset;\n\n\tlet block: Node | null = startNode;\n\twhile (block && block.nodeType !== Node.ELEMENT_NODE) {\n\t\tblock = block.parentNode;\n\t}\n\tif (!block) return null;\n\tconst editable =\n\t\t(block as Element).closest('[contenteditable=\"true\"]') ??\n\t\t(block as Element).closest('.ProseMirror');\n\tif (!editable) return null;\n\n\tlet text = '';\n\tif (startNode.nodeType === Node.TEXT_NODE) {\n\t\ttext = (startNode.textContent ?? '').slice(0, startOffset);\n\t}\n\n\tlet cursor: Node | null = startNode;\n\twhile (cursor && cursor !== editable && cursor !== block) {\n\t\tlet prev: Node | null = cursor.previousSibling;\n\t\twhile (prev) {\n\t\t\ttext = (prev.textContent ?? '') + text;\n\t\t\tprev = prev.previousSibling;\n\t\t}\n\t\tcursor = cursor.parentNode;\n\t\tif (cursor && (cursor as Element).matches?.('p, li, h1, h2, h3, h4, h5, h6, blockquote')) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlet rect: RichTextCaretContext['rect'];\n\tconst r = range.getBoundingClientRect();\n\tif (r && (r.top || r.left || r.right || r.bottom)) {\n\t\trect = { top: r.top, left: r.left, bottom: r.bottom, right: r.right };\n\t}\n\n\treturn { textBefore: text, rect };\n}\n\n/**\n * Extend the selection backwards by `length` characters, then insert\n * `html`. The selection extension means `editor.insertContent` (or the\n * fallback's `range.deleteContents()` + insert) replaces the trigger\n * range with the chip atomically — no manual text-content mutation, no\n * timing races between \"delete\" and \"insert\".\n */\nexport function replaceBeforeCaret(\n\teditor: TiptapEditor | null,\n\tlength: number,\n\thtml: string,\n\tnotifyChange: (next: string) => void,\n): void {\n\tif (typeof window === 'undefined') return;\n\n\tif (editor) {\n\t\t// ProseMirror owns its selection: focus() restores the stored caret and ignores a DOM range,\n\t\t// so replace the run before that caret in document positions, inside its text block.\n\t\tconst { selection } = editor.state;\n\t\tif (!selection.empty) return;\n\t\tconst from = selection.from - Math.min(length, selection.$from.parentOffset);\n\t\teditor.chain().focus().insertContentAt({ from, to: selection.from }, html).run();\n\t\tnotifyChange(editor.getHTML());\n\t\treturn;\n\t}\n\n\tconst sel = window.getSelection();\n\tif (!sel || sel.rangeCount === 0) return;\n\tconst caret = sel.getRangeAt(0);\n\tif (!caret.collapsed) return;\n\n\tlet remaining = length;\n\tlet startNode: Node = caret.startContainer;\n\tlet startOffset = caret.startOffset;\n\n\twhile (remaining > 0) {\n\t\tif (startNode.nodeType === Node.TEXT_NODE) {\n\t\t\tconst take = Math.min(startOffset, remaining);\n\t\t\tstartOffset -= take;\n\t\t\tremaining -= take;\n\t\t\tif (remaining === 0) break;\n\t\t}\n\t\tconst prev = previousTextNode(startNode);\n\t\tif (!prev) break;\n\t\tstartNode = prev;\n\t\tstartOffset = prev.textContent?.length ?? 0;\n\t}\n\n\tconst range = document.createRange();\n\trange.setStart(startNode, startOffset);\n\trange.setEnd(caret.endContainer, caret.endOffset);\n\tsel.removeAllRanges();\n\tsel.addRange(range);\n\n\trange.deleteContents();\n\tconst fragment = document.createRange().createContextualFragment(html);\n\trange.insertNode(fragment);\n\tsel.collapseToEnd();\n\tconst editable =\n\t\t(startNode as Element | null)?.parentElement?.closest?.('[contenteditable=\"true\"]') ?? null;\n\tif (editable) notifyChange((editable as HTMLElement).innerHTML);\n}\n\nexport function insertHtmlIntoEditable(editable: HTMLElement | null, html: string): void {\n\tif (typeof window === 'undefined' || !editable) return;\n\teditable.focus();\n\n\tconst sel = window.getSelection();\n\tif (!sel || sel.rangeCount === 0) {\n\t\teditable.insertAdjacentHTML('beforeend', html);\n\t\treturn;\n\t}\n\n\tconst range = sel.getRangeAt(0);\n\tif (!editable.contains(range.commonAncestorContainer)) {\n\t\teditable.insertAdjacentHTML('beforeend', html);\n\t\treturn;\n\t}\n\n\trange.deleteContents();\n\tconst fragment = document.createRange().createContextualFragment(html);\n\trange.insertNode(fragment);\n\trange.collapse(false);\n\tsel.removeAllRanges();\n\tsel.addRange(range);\n}\n\nfunction previousTextNode(node: Node): Node | null {\n\tlet current: Node | null = node;\n\twhile (current) {\n\t\tif (current.previousSibling) {\n\t\t\tcurrent = current.previousSibling;\n\t\t\twhile (current && current.lastChild) {\n\t\t\t\tcurrent = current.lastChild;\n\t\t\t}\n\t\t\tif (current && current.nodeType === Node.TEXT_NODE) return current;\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent = current.parentNode;\n\t\tif (!current || (current as Element).matches?.('p, li, h1, h2, h3, h4, h5, h6, blockquote, [contenteditable=\"true\"]')) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n","import { Number as NumberValue, SecondaryValue } from '../../../primitives';\nimport { Text } from '../../../typography';\nimport { cn } from '../../../../lib/utils';\n\nimport type { RichTextEditorStrings } from '../rich-text-editor.strings';\nimport type { TiptapEditor } from '../rich-text-editor.types';\n\nexport interface CountsFooterTextProps {\n\t/** Plain-text projection of the document, used for the character count. */\n\ttext: string;\n\t/** Character cap the count is measured against. */\n\tmaxLength?: number;\n\t/** Overrides this surface's own copy. */\n\tstrings: RichTextEditorStrings;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n}\n\nexport function CountsFooterText({ text, maxLength, strings, className }: CountsFooterTextProps) {\n\tconst chars = text.length;\n\tconst words = text.trim().length > 0 ? text.trim().split(/\\s+/).length : 0;\n\tconst overLimit = typeof maxLength === 'number' && chars > maxLength;\n\n\treturn (\n\t\t<div className={cn('counts-footer-text--component border-border flex items-center justify-end gap-space-lg border-t px-control py-space-sm', className)}>\n\t\t\t<Text\n\t\t\t\ttag=\"span\"\n\t\t\t\tsize=\"xs\"\n\t\t\t\ttype={overLimit ? 'error' : 'secondary'}\n\t\t\t\tweight={overLimit ? 'medium' : 'regular'}\n\t\t\t\tclassName={cn('tabular-nums')}\n\t\t\t>\n\t\t\t\t<NumberValue value={chars} size=\"xs\" type={overLimit ? 'error' : 'secondary'} align=\"left\" />\n\t\t\t\t{typeof maxLength === 'number' && (\n\t\t\t\t\t<> / <NumberValue value={maxLength} size=\"xs\" type={overLimit ? 'error' : 'secondary'} align=\"left\" /></>\n\t\t\t\t)} {strings.counts.characters}\n\t\t\t</Text>\n\t\t\t<SecondaryValue size=\"xs\" className=\"tabular-nums\">\n\t\t\t\t<NumberValue value={words} size=\"xs\" type=\"secondary\" align=\"left\" /> {strings.counts.words}\n\t\t\t</SecondaryValue>\n\t\t</div>\n\t);\n}\n\nCountsFooterText.displayName = 'CountsFooterText';\n\nexport interface CountsFooterProps {\n\t/** The editor instance, for reading counts directly. */\n\teditor: TiptapEditor;\n\t/** Whether the editor is showing HTML source. */\n\tsourceMode: boolean;\n\t/** Raw HTML while in source mode. */\n\tsourceValue: string;\n\t/** Character cap the count is measured against. */\n\tmaxLength?: number;\n\t/** Overrides this surface's own copy. */\n\tstrings: RichTextEditorStrings;\n}\n\nexport function CountsFooter({\n\teditor,\n\tsourceMode,\n\tsourceValue,\n\tmaxLength,\n\tstrings,\n}: CountsFooterProps) {\n\tconst text = sourceMode\n\t\t? sourceValue.replace(/<[^>]*>/g, '')\n\t\t: (editor?.getText() ?? '');\n\n\treturn <CountsFooterText text={text} maxLength={maxLength} strings={strings} />;\n}\n\nCountsFooter.displayName = 'CountsFooter';\n","/**\n * Plain HTML normalization shared by the TipTap and contenteditable\n * fallback editors. Keeping these out of the React tree means the\n * editor partials stay focused on rendering.\n */\n\nexport function normalizeHtml(value: string): string {\n\tconst trimmed = value.trim();\n\n\tif (trimmed === '' || trimmed === '<p></p>' || trimmed === '<p><br></p>') {\n\t\treturn '';\n\t}\n\n\treturn trimmed;\n}\n\nexport function toEditorContent(value: string): string {\n\tconst normalized = normalizeHtml(value);\n\treturn normalized === '' ? '<p></p>' : normalized;\n}\n","import * as TiptapReact from '@tiptap/react';\n\n/**\n * Inline references (`@person`, `#booking`) as one atomic editor token.\n *\n * The serialized HTML is the mentions contract written by `buildMentionHtml`\n * and read by `parseMentionsFromHtml`/`MentionContent`:\n *\n * <span class=\"rsc-mention\" data-ref-id=\"…\" data-ref-kind=\"…\" data-ref-tone=\"…\"\n * contenteditable=\"false\">@Label</span>\n *\n * Without this node the editor schema had no place for that span, so a picked\n * mention collapsed into plain text. Inside the editor the token keeps the\n * `.rsc-mention` hook, so mention-chip.css (the inline Badge utilities and\n * shared tone tints) draws it exactly as it draws serialized chips; it is\n * selectable as a unit, and Backspace/Delete remove it in one keystroke.\n */\n\nexport const inlineReferenceChipClassName = 'rsc-mention inline-reference--chip';\n\nconst NODE_NAME = 'inlineReference';\n\nfunction deleteAdjacentReference(direction: 'backward' | 'forward') {\n\treturn ({ editor }: { editor: TiptapReact.Editor }) => editor.commands.command(({ tr, state }) => {\n\t\tconst { selection } = state;\n\t\tif (!selection.empty) return false;\n\t\tconst { $from } = selection;\n\t\tconst node = direction === 'backward' ? $from.nodeBefore : $from.nodeAfter;\n\t\tif (node?.type.name !== NODE_NAME) return false;\n\t\tconst from = direction === 'backward' ? $from.pos - node.nodeSize : $from.pos;\n\t\ttr.delete(from, from + node.nodeSize);\n\t\treturn true;\n\t});\n}\n\nlet inlineReferenceNode: TiptapReact.Node | null = null;\n\n/** Created on first use, so the optional Tiptap runtime is only touched by the editor that needs it. */\nexport function getInlineReferenceNode(): TiptapReact.Node {\n\tinlineReferenceNode ??= TiptapReact.Node.create({\n\t\tname: NODE_NAME,\n\t\tgroup: 'inline',\n\t\tinline: true,\n\t\tatom: true,\n\t\tselectable: true,\n\t\tdraggable: false,\n\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\tid: { default: null, parseHTML: (element) => element.getAttribute('data-ref-id'), renderHTML: (attributes) => ({ 'data-ref-id': attributes.id }) },\n\t\t\t\tkind: { default: null, parseHTML: (element) => element.getAttribute('data-ref-kind'), renderHTML: (attributes) => (attributes.kind ? { 'data-ref-kind': attributes.kind } : {}) },\n\t\t\t\ttone: { default: null, parseHTML: (element) => element.getAttribute('data-ref-tone'), renderHTML: (attributes) => (attributes.tone ? { 'data-ref-tone': attributes.tone } : {}) },\n\t\t\t\tlabel: { default: '', parseHTML: (element) => element.textContent ?? '', renderHTML: () => ({}) },\n\t\t\t};\n\t\t},\n\n\t\tparseHTML() {\n\t\t\treturn [{ tag: 'span[data-ref-id]' }];\n\t\t},\n\n\t\trenderHTML({ node, HTMLAttributes }) {\n\t\t\treturn ['span', TiptapReact.mergeAttributes({ class: 'rsc-mention', contenteditable: 'false' }, HTMLAttributes), node.attrs.label as string];\n\t\t},\n\n\t\trenderText({ node }) {\n\t\t\treturn node.attrs.label as string;\n\t\t},\n\n\t\taddNodeView() {\n\t\t\treturn ({ node }) => {\n\t\t\t\tconst dom = document.createElement('span');\n\t\t\t\tdom.className = inlineReferenceChipClassName;\n\t\t\t\tdom.setAttribute('contenteditable', 'false');\n\t\t\t\tdom.setAttribute('data-ref-id', String(node.attrs.id ?? ''));\n\t\t\t\tif (node.attrs.kind) dom.setAttribute('data-ref-kind', String(node.attrs.kind));\n\t\t\t\tif (node.attrs.tone) dom.setAttribute('data-ref-tone', String(node.attrs.tone));\n\t\t\t\tdom.textContent = String(node.attrs.label ?? '');\n\t\t\t\treturn { dom };\n\t\t\t};\n\t\t},\n\n\t\taddKeyboardShortcuts() {\n\t\t\treturn {\n\t\t\t\tBackspace: deleteAdjacentReference('backward'),\n\t\t\t\tDelete: deleteAdjacentReference('forward'),\n\t\t\t};\n\t\t},\n\t});\n\treturn inlineReferenceNode;\n}\n","import { AlertCircle, ImagePlus, Loader2 } from 'lucide-react';\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type RefObject } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { Button } from '../../../base/buttons';\nimport { FormField } from '../../../base/forms';\nimport { Stack } from '../../../base/structure';\nimport { Input } from '../../../base/text-inputs';\nimport { Text } from '../../../typography';\nimport { safeImageSrc } from '../../../../lib/safe-image-src';\nimport { interpolateString } from '../../../../lib/strings';\n\nimport type { RichTextEditorStrings } from '../rich-text-editor.strings';\nimport type { RichTextEditorImages, RichTextEditorToolbarItem, RichTextImage } from '../rich-text-editor.types';\n\nexport const DEFAULT_IMAGE_ACCEPT = 'image/png,image/jpeg,image/gif,image/webp';\n\n/** Marks an upload placeholder in the editing surface; never part of the value. */\nexport const UPLOAD_ATTRIBUTE = 'data-rte-upload';\n\n/** The placeholder occupies a line of its own while its image uploads. */\nexport const UPLOAD_PLACEHOLDER_CLASS = 'rich-text-editor--upload my-space-xs flex min-h-control items-center rounded-inner border border-dashed border-input bg-muted/30 px-row-x py-row-y';\n\nconst PLACEHOLDER_PATTERN = new RegExp(`<span[^>]*\\\\b${UPLOAD_ATTRIBUTE}=\"[^\"]*\"[^>]*>[\\\\s\\\\S]*?</span>`, 'g');\n\n/** Removes upload placeholders from serialized editor HTML. */\nexport function stripUploadPlaceholders(html: string): string {\n\treturn html.includes(UPLOAD_ATTRIBUTE) ? html.replace(PLACEHOLDER_PATTERN, '') : html;\n}\n\nexport function acceptsImageFile(file: File, accept: string): boolean {\n\tconst type = file.type.toLowerCase();\n\tconst name = file.name.toLowerCase();\n\treturn accept.split(',').map((entry) => entry.trim().toLowerCase()).filter(Boolean).some((entry) => {\n\t\tif (entry.startsWith('.')) return name.endsWith(entry);\n\t\tif (entry.endsWith('/*')) return type.startsWith(entry.slice(0, -1));\n\t\treturn type === entry;\n\t});\n}\n\n/** A readable default description from the file name: `team-offsite_2026.jpg` → `team offsite 2026`. */\nexport function altFromFileName(name: string): string {\n\treturn name.replace(/\\.[^.]+$/, '').replace(/[-_]+/g, ' ').trim();\n}\n\n/** Image files carried by a paste or drop. */\nexport function imageFilesFrom(data: DataTransfer | null | undefined): File[] {\n\treturn Array.from(data?.files ?? []).filter((file) => file.type.startsWith('image/'));\n}\n\n/** How each editor engine puts placeholders and images into its document. */\nexport interface ImageUploadAdapter {\n\t/** Inserts an empty placeholder for `id` at the selection (or the drop point). */\n\tinsertPlaceholder: (id: string) => void;\n\t/** Swaps the placeholder for the uploaded image and reports the change. */\n\tresolvePlaceholder: (id: string, image: RichTextImage) => void;\n\t/** Removes the placeholder and reports the change. */\n\tremovePlaceholder: (id: string) => void;\n\t/** The placeholder's element, or null once the user has deleted it. */\n\tfindPlaceholder: (id: string) => HTMLElement | null;\n}\n\nexport interface PendingImageUpload {\n\tid: string;\n\tname: string;\n\tstatus: 'uploading' | 'error';\n}\n\nlet uploadSequence = 0;\n\n/**\n * The engine-agnostic upload lifecycle: validate, insert a placeholder, call\n * the consumer's `upload` with an abort signal, then swap in the image or keep\n * the placeholder in its error state for Retry or Remove.\n */\nexport function useImageUploadQueue(\n\timages: RichTextEditorImages | undefined,\n\tadapterRef: RefObject<ImageUploadAdapter | null>,\n\tstrings: RichTextEditorStrings['images'],\n) {\n\tconst [uploads, setUploads] = useState<PendingImageUpload[]>([]);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\tconst jobs = useRef(new Map<string, { file: File; controller?: AbortController }>());\n\n\tuseEffect(() => () => {\n\t\tfor (const job of jobs.current.values()) job.controller?.abort();\n\t}, []);\n\n\tconst forget = useCallback((id: string) => {\n\t\tjobs.current.get(id)?.controller?.abort();\n\t\tjobs.current.delete(id);\n\t\tsetUploads((current) => current.filter((upload) => upload.id !== id));\n\t}, []);\n\n\tconst run = useCallback(async (id: string) => {\n\t\tconst job = jobs.current.get(id);\n\t\tif (!job || !images) return;\n\t\tjob.controller?.abort();\n\t\tconst controller = new AbortController();\n\t\tjob.controller = controller;\n\t\tconst pending: PendingImageUpload = { id, name: job.file.name, status: 'uploading' };\n\t\tsetUploads((current) => (current.some((upload) => upload.id === id) ? current.map((upload) => (upload.id === id ? pending : upload)) : [...current, pending]));\n\t\ttry {\n\t\t\tconst result = await images.upload(job.file, { signal: controller.signal });\n\t\t\tif (controller.signal.aborted) return;\n\t\t\tconst src = safeImageSrc(result?.src);\n\t\t\tif (!src) throw new Error(`The uploaded image source for ${job.file.name} is not an allowed URL.`);\n\t\t\tconst placed = adapterRef.current?.findPlaceholder(id);\n\t\t\tforget(id);\n\t\t\tif (placed) {\n\t\t\t\tadapterRef.current?.resolvePlaceholder(id, {\n\t\t\t\t\tsrc,\n\t\t\t\t\talt: result.alt ?? altFromFileName(job.file.name),\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (controller.signal.aborted) return;\n\t\t\timages.onError?.(error, job.file);\n\t\t\tsetUploads((current) => current.map((upload) => (upload.id === id ? { ...upload, status: 'error' } : upload)));\n\t\t}\n\t}, [adapterRef, forget, images]);\n\n\tconst addFiles = useCallback((files: readonly File[]) => {\n\t\tif (!images) return;\n\t\tconst accept = images.accept ?? DEFAULT_IMAGE_ACCEPT;\n\t\tconst refused: string[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst reason = !acceptsImageFile(file, accept)\n\t\t\t\t? strings.unsupported\n\t\t\t\t: images.maxSize && file.size > images.maxSize ? strings.tooLarge : null;\n\t\t\tif (reason) {\n\t\t\t\tconst message = interpolateString(reason, { name: file.name });\n\t\t\t\trefused.push(message);\n\t\t\t\timages.onError?.(new Error(message), file);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tuploadSequence += 1;\n\t\t\tconst id = `upload-${uploadSequence}`;\n\t\t\tjobs.current.set(id, { file });\n\t\t\tadapterRef.current?.insertPlaceholder(id);\n\t\t\tvoid run(id);\n\t\t}\n\t\tsetNotice(refused.length > 0 ? refused.join(' ') : null);\n\t}, [adapterRef, images, run, strings.tooLarge, strings.unsupported]);\n\n\tconst retry = useCallback((id: string) => { void run(id); }, [run]);\n\n\tconst remove = useCallback((id: string) => {\n\t\tforget(id);\n\t\tadapterRef.current?.removePlaceholder(id);\n\t}, [adapterRef, forget]);\n\n\t/** Forgets uploads whose placeholder the user deleted while editing. */\n\tconst prune = useCallback(() => {\n\t\tfor (const id of Array.from(jobs.current.keys())) {\n\t\t\tif (!adapterRef.current?.findPlaceholder(id)) forget(id);\n\t\t}\n\t}, [adapterRef, forget]);\n\n\treturn { uploads, notice, dismissNotice: () => setNotice(null), addFiles, retry, remove, prune };\n}\n\nexport type ImageUploadQueue = ReturnType<typeof useImageUploadQueue>;\n\n/** Status inside a placeholder: uploading with Cancel, or the failure with Retry and Remove. */\nfunction ImageUploadStatus({ upload, strings, onRetry, onRemove }: {\n\tupload: PendingImageUpload;\n\tstrings: RichTextEditorStrings['images'];\n\tonRetry: () => void;\n\tonRemove: () => void;\n}) {\n\tconst failed = upload.status === 'error';\n\treturn (\n\t\t// The message keeps a readable width; on a narrow editor the actions wrap below it.\n\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\" wrap className=\"rich-text-editor--upload-status w-full min-w-0\" data-status={upload.status}>\n\t\t\t{failed\n\t\t\t\t? <AlertCircle className=\"size-icon shrink-0 text-destructive\" aria-hidden=\"true\" />\n\t\t\t\t: <Loader2 className=\"size-icon shrink-0 animate-spin text-muted-foreground motion-reduce:animate-none\" aria-hidden=\"true\" />}\n\t\t\t<Text tag=\"span\" size=\"xs\" type={failed ? 'error' : 'secondary'} role={failed ? 'alert' : 'status'} className=\"min-w-0 flex-1 basis-40 break-words\">\n\t\t\t\t{interpolateString(failed ? strings.failed : strings.uploading, { name: upload.name })}\n\t\t\t</Text>\n\t\t\t{failed && <Button type=\"button\" size=\"sm\" onClick={onRetry}>{strings.retry}</Button>}\n\t\t\t<Button type=\"button\" size=\"sm\" buttonStyle=\"ghost\" onClick={onRemove}>{failed ? strings.remove : strings.cancel}</Button>\n\t\t</Stack>\n\t);\n}\n\n/** Renders each pending upload's status into its placeholder in the editing surface. */\nexport function ImageUploadPortals({ queue, adapterRef, strings }: {\n\tqueue: ImageUploadQueue;\n\tadapterRef: RefObject<ImageUploadAdapter | null>;\n\tstrings: RichTextEditorStrings['images'];\n}) {\n\treturn (\n\t\t<>\n\t\t\t{queue.uploads.map((upload) => {\n\t\t\t\tconst target = adapterRef.current?.findPlaceholder(upload.id);\n\t\t\t\treturn target ? createPortal(\n\t\t\t\t\t<ImageUploadStatus upload={upload} strings={strings} onRetry={() => queue.retry(upload.id)} onRemove={() => queue.remove(upload.id)} />,\n\t\t\t\t\ttarget,\n\t\t\t\t\tupload.id,\n\t\t\t\t) : null;\n\t\t\t})}\n\t\t</>\n\t);\n}\n\n/** The Insert image toolbar control and its hidden file input. */\nexport function useImageInsertControl(\n\timages: RichTextEditorImages | undefined,\n\tstrings: RichTextEditorStrings['images'],\n\tonFiles: (files: File[]) => void,\n\tbeforeOpen?: () => void,\n) {\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\tconst beforeOpenRef = useRef(beforeOpen);\n\tbeforeOpenRef.current = beforeOpen;\n\tconst enabled = Boolean(images);\n\tconst item = useMemo<RichTextEditorToolbarItem | null>(() => (enabled ? {\n\t\tid: 'insert-image',\n\t\ticon: ImagePlus,\n\t\tlabel: strings.insert,\n\t\ttoggle: false,\n\t\tonClick: () => {\n\t\t\tbeforeOpenRef.current?.();\n\t\t\tinputRef.current?.click();\n\t\t},\n\t} : null), [enabled, strings.insert]);\n\tconst input = images ? (\n\t\t<input\n\t\t\tref={inputRef}\n\t\t\ttype=\"file\"\n\t\t\taccept={images.accept ?? DEFAULT_IMAGE_ACCEPT}\n\t\t\tmultiple\n\t\t\thidden\n\t\t\ttabIndex={-1}\n\t\t\taria-hidden=\"true\"\n\t\t\tonChange={(event) => {\n\t\t\t\tconst files = Array.from(event.target.files ?? []);\n\t\t\t\tevent.target.value = '';\n\t\t\t\tif (files.length > 0) onFiles(files);\n\t\t\t}}\n\t\t/>\n\t) : null;\n\treturn { item, input };\n}\n\n/** The description field for the image at the caret, and refused-file notices. */\nexport function ImageDetailsBar({ alt, onAltChange, onRemove, notice, onDismissNotice, strings }: {\n\talt: string | null;\n\tonAltChange: (alt: string) => void;\n\tonRemove: () => void;\n\tnotice: string | null;\n\tonDismissNotice: () => void;\n\tstrings: RichTextEditorStrings['images'];\n}) {\n\tconst inputId = useId();\n\tif (alt === null && !notice) return null;\n\treturn (\n\t\t<Stack gap=\"sm\" className=\"rich-text-editor--image-details border-t border-border/60 px-control py-space-sm\">\n\t\t\t{!!notice && (\n\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\">\n\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"error\" role=\"alert\" className=\"min-w-0 flex-1\">{notice}</Text>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" buttonStyle=\"ghost\" onClick={onDismissNotice}>{strings.remove}</Button>\n\t\t\t\t</Stack>\n\t\t\t)}\n\t\t\t{alt !== null && (\n\t\t\t\t// The action sits on the field's own row, so it lines up with the input, not the hint.\n\t\t\t\t<FormField label={strings.descriptionLabel} hint={strings.descriptionHint} htmlFor={inputId}>\n\t\t\t\t\t{/* A compound field: the fragment keeps FormField from labelling the row itself. */}\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\" wrap={false}>\n\t\t\t\t\t\t\t<Input id={inputId} value={alt} className=\"min-w-0 flex-1\" onChange={(event) => onAltChange(event.target.value)} />\n\t\t\t\t\t\t\t<Button type=\"button\" buttonStyle=\"outline\" onClick={onRemove}>{strings.removeImage}</Button>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</>\n\t\t\t\t</FormField>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n","import * as TiptapReact from '@tiptap/react';\n\nimport { safeImageSrc } from '../../../../lib/safe-image-src';\nimport { UPLOAD_ATTRIBUTE, UPLOAD_PLACEHOLDER_CLASS } from './image-uploads';\n\nfunction positiveNumber(value: string | null): number | null {\n\tconst number = Number(value);\n\treturn Number.isFinite(number) && number > 0 ? number : null;\n}\n\nlet imageNode: TiptapReact.Node | null = null;\nlet imageUploadNode: TiptapReact.Node | null = null;\n\n/**\n * An inline image whose source passes the package image policy; any other\n * `<img>` in loaded or pasted content is dropped. Serializes as a plain\n * `<img src alt width height>`, matching the contenteditable engine.\n */\nexport function getImageNode(): TiptapReact.Node {\n\timageNode ??= TiptapReact.Node.create({\n\t\tname: 'image',\n\t\tgroup: 'inline',\n\t\tinline: true,\n\t\tatom: true,\n\t\tselectable: true,\n\t\tdraggable: true,\n\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\tsrc: { default: null, parseHTML: (element) => safeImageSrc(element.getAttribute('src')) ?? null },\n\t\t\t\talt: { default: '', parseHTML: (element) => element.getAttribute('alt') ?? '' },\n\t\t\t\ttitle: { default: null },\n\t\t\t\twidth: { default: null, parseHTML: (element) => positiveNumber(element.getAttribute('width')) },\n\t\t\t\theight: { default: null, parseHTML: (element) => positiveNumber(element.getAttribute('height')) },\n\t\t\t};\n\t\t},\n\n\t\tparseHTML() {\n\t\t\treturn [{ tag: 'img[src]', getAttrs: (element) => (safeImageSrc((element as HTMLElement).getAttribute('src')) ? null : false) }];\n\t\t},\n\n\t\trenderHTML({ HTMLAttributes }) {\n\t\t\tconst src = safeImageSrc(HTMLAttributes.src);\n\t\t\treturn ['img', TiptapReact.mergeAttributes(HTMLAttributes, { src: src ?? null })];\n\t\t},\n\t});\n\treturn imageNode;\n}\n\n/**\n * The placeholder an image occupies while it uploads. It is never parsed from\n * HTML and the editor strips it from its value; the editor renders the\n * upload status into its node view.\n */\nexport function getImageUploadNode(): TiptapReact.Node {\n\timageUploadNode ??= TiptapReact.Node.create({\n\t\tname: 'imageUpload',\n\t\tgroup: 'inline',\n\t\tinline: true,\n\t\tatom: true,\n\t\tselectable: false,\n\n\t\taddAttributes() {\n\t\t\treturn { id: { default: null } };\n\t\t},\n\n\t\tparseHTML() {\n\t\t\treturn [];\n\t\t},\n\n\t\trenderHTML({ node }) {\n\t\t\treturn ['span', { [UPLOAD_ATTRIBUTE]: node.attrs.id as string }];\n\t\t},\n\n\t\taddNodeView() {\n\t\t\treturn ({ node }) => {\n\t\t\t\tconst dom = document.createElement('span');\n\t\t\t\tdom.setAttribute(UPLOAD_ATTRIBUTE, String(node.attrs.id));\n\t\t\t\tdom.setAttribute('contenteditable', 'false');\n\t\t\t\tdom.className = UPLOAD_PLACEHOLDER_CLASS;\n\t\t\t\t// The status UI is a React portal; keep ProseMirror out of it.\n\t\t\t\treturn { dom, ignoreMutation: () => true, stopEvent: () => true };\n\t\t\t};\n\t\t},\n\t});\n\treturn imageUploadNode;\n}\n","import {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport {\n\tBold,\n\tItalic,\n\tList,\n\tListOrdered,\n\tQuote,\n\tRedo2,\n\tStrikethrough,\n\tUndo2,\n} from 'lucide-react';\nimport * as TiptapReact from '@tiptap/react';\nimport * as StarterKitModule from '@tiptap/starter-kit';\n\nimport { richTextEditorRecipes } from '../rich-text-editor.recipes';\nimport { editableContentClassName } from '../../../typography/content-typography';\n\nimport { Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { defaultRichTextEditorStrings } from '../rich-text-editor.strings';\nimport type {\n\tRichTextEditorHandle,\n\tRichTextEditorProps,\n\tTiptapEditor,\n\tToolbarButtonConfig,\n} from '../rich-text-editor.types';\nimport { readCaretContext, replaceBeforeCaret } from './caret-helpers';\nimport { CountsFooter } from './counts-footer';\nimport { normalizeHtml, toEditorContent } from './html-helpers';\nimport { RichTextEditorToolbar } from './rich-text-editor-toolbar';\nimport { getInlineReferenceNode } from './inline-reference-node';\nimport { getImageNode, getImageUploadNode } from './image-nodes';\nimport {\n\tImageDetailsBar,\n\tImageUploadPortals,\n\timageFilesFrom,\n\tstripUploadPlaceholders,\n\tuseImageInsertControl,\n\tuseImageUploadQueue,\n\ttype ImageUploadAdapter,\n\ttype ImageUploadQueue,\n} from './image-uploads';\n\ntype ProseNode = { type: { name: string }; attrs: Record<string, unknown>; nodeSize: number };\n\n/** Value HTML: the editor's HTML without upload placeholders. */\nfunction valueHtml(editor: { getHTML: () => string } | null | undefined): string {\n\treturn normalizeHtml(stripUploadPlaceholders(editor?.getHTML() ?? ''));\n}\n\nconst EditorContent = TiptapReact.EditorContent;\nconst useTiptapEditor = TiptapReact.useEditor;\nconst StarterKit =\n\t'default' in StarterKitModule ? StarterKitModule.default : StarterKitModule;\n\nexport const TiptapRichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorProps>(function TiptapRichTextEditor(\n\t{\n\t\tvalue,\n\t\tonValueChange,\n\t\tplaceholder,\n\t\tcompact = false,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tdisabled = false,\n\t\tshowCounts = false,\n\t\tmaxLength,\n\t\textraToolbarItems,\n\t\ttoolbarTrailing,\n\t\tfooterSlot,\n\t\thideSourceToggle = false,\n\t\tautoFocus = false,\n\t\tclassName,\n\t\tonCaretChange,\n\t\tstrings: stringsProp,\n\t\timages,\n\t},\n\tref,\n) {\n\tconst strings = useStrings(defaultRichTextEditorStrings, stringsProp);\n\tconst imagesEnabled = Boolean(images);\n\tconst queueRef = useRef<ImageUploadQueue | null>(null);\n\tconst editorInstanceRef = useRef<TiptapEditor | null>(null);\n\tconst [isFocused, setIsFocused] = useState(false);\n\tconst [sourceMode, setSourceMode] = useState(false);\n\tconst [sourceValue, setSourceValue] = useState('');\n\tconst isFocusedRef = useRef(false);\n\tconst externalValueRef = useRef<string>(normalizeHtml(value));\n\tconst onCaretChangeRef = useRef(onCaretChange);\n\tonCaretChangeRef.current = onCaretChange;\n\n\tconst extensions = useMemo(\n\t\t() => [StarterKit, getInlineReferenceNode(), ...(imagesEnabled ? [getImageNode(), getImageUploadNode()] : [])],\n\t\t[imagesEnabled],\n\t);\n\tconst editor = useTiptapEditor({\n\t\textensions,\n\t\tcontent: toEditorContent(value),\n\t\teditable: !disabled,\n\t\timmediatelyRender: false,\n\t\tautofocus: autoFocus ? 'end' : false,\n\t\tonFocus: () => {\n\t\t\tisFocusedRef.current = true;\n\t\t\tsetIsFocused(true);\n\t\t},\n\t\tonBlur: () => {\n\t\t\tisFocusedRef.current = false;\n\t\t\tsetIsFocused(false);\n\t\t},\n\t\tonUpdate: ({ editor: currentEditor }: { editor: { getHTML: () => string } }) => {\n\t\t\tqueueRef.current?.prune();\n\t\t\tconst html = valueHtml(currentEditor);\n\t\t\tif (!isFocusedRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (html !== externalValueRef.current) {\n\t\t\t\texternalValueRef.current = html;\n\t\t\t\tonValueChange(html);\n\t\t\t}\n\n\t\t\tonCaretChangeRef.current?.();\n\t\t},\n\t\teditorProps: {\n\t\t\t// Image files from the clipboard or a drop go through the upload lifecycle.\n\t\t\thandlePaste: (_view: unknown, event: ClipboardEvent) => {\n\t\t\t\tconst files = imageFilesFrom(event.clipboardData);\n\t\t\t\tif (!queueRef.current || !imagesRef.current || files.length === 0) return false;\n\t\t\t\tqueueRef.current.addFiles(files);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\thandleDrop: (view: { posAtCoords: (coords: { left: number; top: number }) => { pos: number } | null }, event: DragEvent, _slice: unknown, moved: boolean) => {\n\t\t\t\tconst files = imageFilesFrom(event.dataTransfer);\n\t\t\t\tif (moved || !queueRef.current || !imagesRef.current || files.length === 0) return false;\n\t\t\t\tconst at = view.posAtCoords({ left: event.clientX, top: event.clientY });\n\t\t\t\tif (at) editorInstanceRef.current?.commands.setTextSelection(at.pos);\n\t\t\t\tqueueRef.current.addFiles(files);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tattributes: {\n\t\t\t\trole: 'textbox',\n\t\t\t\t'aria-label': strings.editorLabel,\n\t\t\t\t'aria-multiline': 'true',\n\t\t\t\tclass: editableContentClassName,\n\t\t\t},\n\t\t},\n\t// Image nodes join the schema only when images are enabled, which needs a new editor.\n\t}, [imagesEnabled]);\n\n\tuseEffect(() => {\n\t\tif (!editor) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = valueHtml(editor);\n\t\tconst next = normalizeHtml(value);\n\t\texternalValueRef.current = next;\n\n\t\tif (current !== next) {\n\t\t\teditor.commands.setContent(toEditorContent(next), { emitUpdate: false });\n\t\t}\n\t}, [editor, value]);\n\n\tuseEffect(() => {\n\t\tif (!editor) {\n\t\t\treturn;\n\t\t}\n\n\t\teditor.setEditable(!disabled);\n\t}, [disabled, editor]);\n\n\tuseEffect(() => {\n\t\tif (typeof document === 'undefined') return;\n\t\tconst handler = () => {\n\t\t\tif (!isFocusedRef.current) return;\n\t\t\tonCaretChangeRef.current?.();\n\t\t};\n\t\tdocument.addEventListener('selectionchange', handler);\n\t\treturn () => document.removeEventListener('selectionchange', handler);\n\t}, []);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\tfocus: () => {\n\t\t\t\teditor?.chain().focus().run();\n\t\t\t},\n\t\t\tgetHTML: () => valueHtml(editor),\n\t\t\tsetHTML: (html: string) => {\n\t\t\t\tconst next = normalizeHtml(html);\n\t\t\t\texternalValueRef.current = next;\n\t\t\t\teditor?.commands.setContent(toEditorContent(next), { emitUpdate: false });\n\t\t\t\tonValueChange(next);\n\t\t\t},\n\t\t\tinsertHTML: (html: string) => {\n\t\t\t\tif (!editor) return;\n\t\t\t\teditor.chain().focus().insertContent(html).run();\n\t\t\t},\n\t\t\tisEmpty: () => valueHtml(editor) === '',\n\t\t\tclear: () => {\n\t\t\t\texternalValueRef.current = '';\n\t\t\t\teditor?.commands.setContent('<p></p>', { emitUpdate: false });\n\t\t\t\tonValueChange('');\n\t\t\t},\n\t\t\tgetCaretContext: () => readCaretContext(),\n\t\t\treplaceBeforeCaret: (length: number, html: string) => {\n\t\t\t\treplaceBeforeCaret(editor, length, html, (next) => {\n\t\t\t\t\texternalValueRef.current = normalizeHtml(next);\n\t\t\t\t\tonValueChange(externalValueRef.current);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t\t[editor, onValueChange],\n\t);\n\n\teditorInstanceRef.current = editor ?? null;\n\tconst imagesRef = useRef(images);\n\timagesRef.current = images;\n\n\t/** Programmatic changes (an upload landing, a description edit) report the value themselves. */\n\tconst emitValue = useCallback(() => {\n\t\tif (!editor) return;\n\t\tconst html = valueHtml(editor);\n\t\tif (html === externalValueRef.current) return;\n\t\texternalValueRef.current = html;\n\t\tonValueChange(html);\n\t}, [editor, onValueChange]);\n\n\tconst findNode = useCallback((match: (node: ProseNode) => boolean) => {\n\t\tlet found: { pos: number; node: ProseNode } | null = null;\n\t\teditor?.state.doc.descendants((node: ProseNode, pos: number) => {\n\t\t\tif (!found && match(node)) found = { pos, node };\n\t\t\treturn !found;\n\t\t});\n\t\treturn found as { pos: number; node: ProseNode } | null;\n\t}, [editor]);\n\n\tconst adapterRef = useRef<ImageUploadAdapter | null>(null);\n\tadapterRef.current = editor ? {\n\t\tinsertPlaceholder: (id) => {\n\t\t\teditor.chain().focus().insertContent({ type: 'imageUpload', attrs: { id } }).run();\n\t\t},\n\t\tfindPlaceholder: (id) => editor.view.dom.querySelector<HTMLElement>(`[data-rte-upload=\"${id}\"]`),\n\t\tresolvePlaceholder: (id, image) => {\n\t\t\tconst at = findNode((node) => node.type.name === 'imageUpload' && node.attrs.id === id);\n\t\t\tif (!at) return;\n\t\t\tconst created = editor.schema.nodes.image.create({ src: image.src, alt: image.alt ?? '', width: image.width ?? null, height: image.height ?? null });\n\t\t\teditor.view.dispatch(editor.state.tr.replaceWith(at.pos, at.pos + at.node.nodeSize, created));\n\t\t\temitValue();\n\t\t},\n\t\tremovePlaceholder: (id) => {\n\t\t\tconst at = findNode((node) => node.type.name === 'imageUpload' && node.attrs.id === id);\n\t\t\tif (!at) return;\n\t\t\teditor.view.dispatch(editor.state.tr.delete(at.pos, at.pos + at.node.nodeSize));\n\t\t\temitValue();\n\t\t},\n\t} : null;\n\tconst uploadQueue = useImageUploadQueue(images, adapterRef, strings.images);\n\tqueueRef.current = imagesEnabled ? uploadQueue : null;\n\tconst imageInsert = useImageInsertControl(images, strings.images, uploadQueue.addFiles);\n\tconst toolbarItems = useMemo(\n\t\t() => (imageInsert.item ? [imageInsert.item, ...(extraToolbarItems ?? [])] : extraToolbarItems),\n\t\t[extraToolbarItems, imageInsert.item],\n\t);\n\n\t// The image the selection holds, or that sits beside a collapsed caret.\n\tconst [activeImage, setActiveImage] = useState<{ pos: number; alt: string } | null>(null);\n\tuseEffect(() => {\n\t\tif (!editor || !imagesEnabled) return;\n\t\tconst sync = () => {\n\t\t\tconst selection = editor.state.selection as unknown as { node?: ProseNode; empty: boolean; from: number; $from: { nodeBefore: ProseNode | null; nodeAfter: ProseNode | null } };\n\t\t\tlet next: { pos: number; alt: string } | null = null;\n\t\t\tif (selection.node?.type.name === 'image') next = { pos: selection.from, alt: String(selection.node.attrs.alt ?? '') };\n\t\t\telse if (selection.empty) {\n\t\t\t\tconst { nodeBefore, nodeAfter } = selection.$from;\n\t\t\t\tif (nodeBefore?.type.name === 'image') next = { pos: selection.from - nodeBefore.nodeSize, alt: String(nodeBefore.attrs.alt ?? '') };\n\t\t\t\telse if (nodeAfter?.type.name === 'image') next = { pos: selection.from, alt: String(nodeAfter.attrs.alt ?? '') };\n\t\t\t}\n\t\t\tsetActiveImage(next);\n\t\t};\n\t\teditor.on('selectionUpdate', sync);\n\t\teditor.on('update', sync);\n\t\treturn () => {\n\t\t\teditor.off('selectionUpdate', sync);\n\t\t\teditor.off('update', sync);\n\t\t};\n\t}, [editor, imagesEnabled]);\n\n\tconst contentStyle = useMemo(\n\t\t() => ({\n\t\t\tminHeight: minHeight ?? (compact ? '2rem' : '12rem'),\n\t\t\t...(maxHeight ? { maxHeight, overflowY: 'auto' as const } : {}),\n\t\t}),\n\t\t[compact, maxHeight, minHeight],\n\t);\n\n\tconst toggleSourceMode = useCallback(() => {\n\t\tif (!editor) return;\n\n\t\tif (sourceMode) {\n\t\t\tconst html = toEditorContent(sourceValue);\n\t\t\teditor.commands.setContent(html, { emitUpdate: false });\n\t\t\tconst normalized = normalizeHtml(sourceValue);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tonValueChange(normalized);\n\t\t\tsetSourceMode(false);\n\t\t} else {\n\t\t\tsetSourceValue(editor.getHTML());\n\t\t\tsetSourceMode(true);\n\t\t}\n\t}, [editor, onValueChange, sourceMode, sourceValue]);\n\n\tconst handleSourceChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\t\tconst next = e.target.value;\n\t\t\tsetSourceValue(next);\n\t\t\tconst normalized = normalizeHtml(next);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tonValueChange(normalized);\n\t\t},\n\t\t[onValueChange],\n\t);\n\n\tconst toolbarButtons = useMemo<ToolbarButtonConfig[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: 'bold',\n\t\t\t\ticon: Bold,\n\t\t\t\tlabel: strings.toolbar.bold,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('bold')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'italic',\n\t\t\t\ticon: Italic,\n\t\t\t\tlabel: strings.toolbar.italic,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('italic')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'strike',\n\t\t\t\ticon: Strikethrough,\n\t\t\t\tlabel: strings.toolbar.strike,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('strike')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'bullet-list',\n\t\t\t\ticon: List,\n\t\t\t\tlabel: strings.toolbar.bulletList,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('bulletList')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleBulletList().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'ordered-list',\n\t\t\t\ticon: ListOrdered,\n\t\t\t\tlabel: strings.toolbar.orderedList,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('orderedList')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleOrderedList().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'blockquote',\n\t\t\t\ticon: Quote,\n\t\t\t\tlabel: strings.toolbar.blockquote,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('blockquote')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleBlockquote().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'undo',\n\t\t\t\ticon: Undo2,\n\t\t\t\tlabel: strings.toolbar.undo,\n\t\t\t\tisActive: () => false,\n\t\t\t\trun: () => editor?.chain().focus().undo().run(),\n\t\t\t\tdisabled: !editor?.can().chain().focus().undo().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'redo',\n\t\t\t\ticon: Redo2,\n\t\t\t\tlabel: strings.toolbar.redo,\n\t\t\t\tisActive: () => false,\n\t\t\t\trun: () => editor?.chain().focus().redo().run(),\n\t\t\t\tdisabled: !editor?.can().chain().focus().redo().run(),\n\t\t\t},\n\t\t],\n\t\t[editor, strings],\n\t);\n\n\tconst countsFooter =\n\t\tshowCounts && editor ? (\n\t\t\t<CountsFooter\n\t\t\t\teditor={editor}\n\t\t\t\tsourceMode={sourceMode}\n\t\t\t\tsourceValue={sourceValue}\n\t\t\t\tmaxLength={maxLength}\n\t\t\t\tstrings={strings}\n\t\t\t/>\n\t\t) : null;\n\n\tconst placeholderText = typeof placeholder === 'string' ? placeholder : '';\n\tconst showPlaceholder =\n\t\tplaceholderText.length > 0 && !isFocused && Boolean(editor?.isEmpty);\n\tconst placeholderNode = showPlaceholder ? (\n\t\t<Text\n\t\t\ttag=\"span\"\n\t\t\tsize=\"sm\"\n\t\t\ttype=\"secondary\"\n\t\t\tclassName=\"pointer-events-none absolute inset-0 px-control py-control-y-offset\"\n\t\t>\n\t\t\t{placeholderText}\n\t\t</Text>\n\t) : null;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\trichTextEditorRecipes.frame,\n\t\t\t\tdisabled && richTextEditorRecipes.disabled,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<RichTextEditorToolbar\n\t\t\t\tbuttons={toolbarButtons}\n\t\t\t\textraToolbarItems={toolbarItems}\n\t\t\t\thideSourceToggle={hideSourceToggle}\n\t\t\t\tsourceMode={sourceMode}\n\t\t\t\ttoggleSourceMode={toggleSourceMode}\n\t\t\t\tdisabled={disabled}\n\t\t\t\thasEditor={Boolean(editor)}\n\t\t\t\ttoolbarTrailing={toolbarTrailing}\n\t\t\t\tstrings={strings}\n\t\t\t/>\n\n\t\t\t{sourceMode ? (\n\t\t\t\t<textarea\n\t\t\t\t\taria-label={strings.sourceLabel}\n\t\t\t\t\tvalue={sourceValue}\n\t\t\t\t\tonChange={handleSourceChange}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tspellCheck={false}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\trichTextEditorRecipes.source,\n\t\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t\t)}\n\t\t\t\t\tstyle={contentStyle}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div className=\"relative\" style={contentStyle}>\n\t\t\t\t\t{placeholderNode}\n\n\t\t\t\t\t<EditorContent\n\t\t\t\t\t\teditor={editor}\n\t\t\t\t\t\tclassName={richTextEditorRecipes.content}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{imagesEnabled && (\n\t\t\t\t<ImageDetailsBar\n\t\t\t\t\talt={activeImage ? activeImage.alt : null}\n\t\t\t\t\tonAltChange={(alt) => {\n\t\t\t\t\t\tif (!editor || !activeImage) return;\n\t\t\t\t\t\tconst node = editor.state.doc.nodeAt(activeImage.pos) as ProseNode | null;\n\t\t\t\t\t\tif (node?.type.name !== 'image') return;\n\t\t\t\t\t\teditor.view.dispatch(editor.state.tr.setNodeMarkup(activeImage.pos, undefined, { ...node.attrs, alt }));\n\t\t\t\t\t\tsetActiveImage({ ...activeImage, alt });\n\t\t\t\t\t\temitValue();\n\t\t\t\t\t}}\n\t\t\t\t\tonRemove={() => {\n\t\t\t\t\t\tif (!editor || !activeImage) return;\n\t\t\t\t\t\tconst node = editor.state.doc.nodeAt(activeImage.pos) as ProseNode | null;\n\t\t\t\t\t\tif (node?.type.name !== 'image') return;\n\t\t\t\t\t\teditor.view.dispatch(editor.state.tr.delete(activeImage.pos, activeImage.pos + node.nodeSize));\n\t\t\t\t\t\tsetActiveImage(null);\n\t\t\t\t\t\temitValue();\n\t\t\t\t\t\teditor.commands.focus();\n\t\t\t\t\t}}\n\t\t\t\t\tnotice={uploadQueue.notice}\n\t\t\t\t\tonDismissNotice={uploadQueue.dismissNotice}\n\t\t\t\t\tstrings={strings.images}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{!!footerSlot && (\n\t\t\t\t<div className=\"px-control pb-space-md pt-space-xs\">{footerSlot}</div>\n\t\t\t)}\n\n\t\t\t{countsFooter}\n\t\t\t{imageInsert.input}\n\t\t\t{imagesEnabled && <ImageUploadPortals queue={uploadQueue} adapterRef={adapterRef} strings={strings.images} />}\n\t\t</div>\n\t);\n});\n\nTiptapRichTextEditor.displayName = 'TiptapRichTextEditor';\n\n// Tiptap 3 exports EditorContent as React.memo (an object), so accept any component type.\nconst isComponentType = (value: unknown) =>\n\ttypeof value === 'function' || (typeof value === 'object' && value !== null && '$$typeof' in value);\n\nexport const hasTiptapRuntime =\n\tisComponentType(EditorContent) &&\n\ttypeof useTiptapEditor === 'function' &&\n\ttypeof StarterKit === 'object' &&\n\tStarterKit !== null;\n","import {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport {\n\tBold,\n\tItalic,\n\tList,\n\tListOrdered,\n\tQuote,\n\tRedo2,\n\tStrikethrough,\n\tUndo2,\n} from 'lucide-react';\n\nimport { richTextEditorRecipes } from '../rich-text-editor.recipes';\nimport { editableContentClassName } from '../../../typography/content-typography';\n\nimport { Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { defaultRichTextEditorStrings } from '../rich-text-editor.strings';\nimport type {\n\tRichTextEditorHandle,\n\tRichTextEditorProps,\n\tToolbarButtonConfig,\n} from '../rich-text-editor.types';\nimport {\n\tinsertHtmlIntoEditable,\n\treadCaretContext,\n\treplaceBeforeCaret,\n} from './caret-helpers';\nimport { CountsFooterText } from './counts-footer';\nimport { normalizeHtml, toEditorContent } from './html-helpers';\nimport { RichTextEditorToolbar } from './rich-text-editor-toolbar';\nimport {\n\tImageDetailsBar,\n\tImageUploadPortals,\n\tUPLOAD_ATTRIBUTE,\n\tUPLOAD_PLACEHOLDER_CLASS,\n\timageFilesFrom,\n\tuseImageInsertControl,\n\tuseImageUploadQueue,\n\ttype ImageUploadAdapter,\n} from './image-uploads';\nimport { safeImageSrc } from '../../../../lib/safe-image-src';\n\n/** The editable's HTML without upload placeholders, which are never part of the value. */\nfunction serializeEditable(editable: HTMLElement | null): string {\n\tif (!editable) return '';\n\tif (!editable.querySelector(`[${UPLOAD_ATTRIBUTE}]`)) return editable.innerHTML;\n\tconst copy = editable.cloneNode(true) as HTMLElement;\n\tfor (const placeholder of Array.from(copy.querySelectorAll(`[${UPLOAD_ATTRIBUTE}]`))) placeholder.remove();\n\treturn copy.innerHTML;\n}\n\n/** Pasted markup may carry images; keep only those whose source passes the image policy. */\nfunction removeUnsafeImages(editable: HTMLElement): void {\n\tfor (const image of Array.from(editable.querySelectorAll('img'))) {\n\t\tif (!safeImageSrc(image.getAttribute('src'))) image.remove();\n\t}\n}\n\n/** The image the selection touches, or that sits right beside a collapsed caret. */\nfunction imageAtSelection(editable: HTMLElement): HTMLImageElement | null {\n\tconst selection = window.getSelection();\n\tif (!selection || selection.rangeCount === 0) return null;\n\tconst range = selection.getRangeAt(0);\n\tif (!editable.contains(range.commonAncestorContainer)) return null;\n\tfor (const image of Array.from(editable.querySelectorAll('img'))) {\n\t\tif (range.intersectsNode(image) && !range.collapsed) return image;\n\t}\n\tif (!range.collapsed) return null;\n\tconst { startContainer, startOffset } = range;\n\tconst neighbours = startContainer.nodeType === Node.TEXT_NODE\n\t\t? [startOffset === 0 ? startContainer.previousSibling : null, startOffset === (startContainer.textContent?.length ?? 0) ? startContainer.nextSibling : null]\n\t\t: [startContainer.childNodes[startOffset - 1] ?? null, startContainer.childNodes[startOffset] ?? null];\n\treturn (neighbours.find((node) => node instanceof HTMLImageElement) as HTMLImageElement | undefined) ?? null;\n}\n\n/** Places the caret where a drop happened. */\nfunction placeCaretAtPoint(x: number, y: number): void {\n\tconst doc = document as Document & {\n\t\tcaretRangeFromPoint?: (x: number, y: number) => Range | null;\n\t\tcaretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null;\n\t};\n\tlet range = doc.caretRangeFromPoint?.(x, y) ?? null;\n\tif (!range) {\n\t\tconst position = doc.caretPositionFromPoint?.(x, y);\n\t\tif (position) {\n\t\t\trange = document.createRange();\n\t\t\trange.setStart(position.offsetNode, position.offset);\n\t\t}\n\t}\n\tif (!range) return;\n\trange.collapse(true);\n\tconst selection = window.getSelection();\n\tselection?.removeAllRanges();\n\tselection?.addRange(range);\n}\n\n/**\n * Fallback editor used when the TipTap runtime is unavailable (e.g. in\n * environments where the package failed to load). Renders a\n * `contenteditable` surface with the same imperative handle so callers\n * never need to care which variant they got.\n */\nexport const FallbackRichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorProps>(function FallbackRichTextEditor(\n\t{\n\t\tvalue,\n\t\tonValueChange,\n\t\tplaceholder,\n\t\tcompact = false,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tdisabled = false,\n\t\tshowCounts = false,\n\t\tmaxLength,\n\t\textraToolbarItems,\n\t\ttoolbarTrailing,\n\t\tfooterSlot,\n\t\thideSourceToggle = false,\n\t\tautoFocus = false,\n\t\tclassName,\n\t\tonCaretChange,\n\t\tstrings: stringsProp,\n\t\timages,\n\t},\n\tref,\n) {\n\tconst strings = useStrings(defaultRichTextEditorStrings, stringsProp);\n\tconst editableRef = useRef<HTMLDivElement>(null);\n\tconst savedRangeRef = useRef<Range | null>(null);\n\tconst [activeImage, setActiveImage] = useState<HTMLImageElement | null>(null);\n\tconst [activeAlt, setActiveAlt] = useState('');\n\tconst [isFocused, setIsFocused] = useState(false);\n\tconst [sourceMode, setSourceMode] = useState(false);\n\tconst [sourceValue, setSourceValue] = useState('');\n\tconst externalValueRef = useRef<string>(normalizeHtml(value));\n\tconst onCaretChangeRef = useRef(onCaretChange);\n\tonCaretChangeRef.current = onCaretChange;\n\n\tconst setEditableRef = useCallback((node: HTMLDivElement | null) => {\n\t\teditableRef.current = node;\n\t\tif (node && node.innerHTML === '') {\n\t\t\tnode.innerHTML = toEditorContent(externalValueRef.current);\n\t\t}\n\t}, []);\n\n\tuseEffect(() => {\n\t\tconst editable = editableRef.current;\n\t\tif (!editable || isFocused) return;\n\t\tconst next = toEditorContent(value);\n\t\tif (normalizeHtml(serializeEditable(editable)) !== normalizeHtml(next)) {\n\t\t\teditable.innerHTML = next;\n\t\t}\n\t\texternalValueRef.current = normalizeHtml(value);\n\t}, [isFocused, value]);\n\n\tuseEffect(() => {\n\t\tif (!autoFocus) return;\n\t\teditableRef.current?.focus();\n\t}, [autoFocus]);\n\n\tconst emitEditableChange = useCallback(() => {\n\t\tconst editable = editableRef.current;\n\t\tconst html = normalizeHtml(serializeEditable(editable));\n\t\texternalValueRef.current = html;\n\t\tonValueChange(html);\n\t\tonCaretChangeRef.current?.();\n\t}, [onValueChange]);\n\n\tconst adapterRef = useRef<ImageUploadAdapter | null>(null);\n\tadapterRef.current = {\n\t\tinsertPlaceholder: (id) => {\n\t\t\tconst editable = editableRef.current;\n\t\t\tif (!editable) return;\n\t\t\tconst saved = savedRangeRef.current;\n\t\t\tif (saved && editable.contains(saved.commonAncestorContainer) && !editable.contains(document.activeElement)) {\n\t\t\t\teditable.focus();\n\t\t\t\tconst selection = window.getSelection();\n\t\t\t\tselection?.removeAllRanges();\n\t\t\t\tselection?.addRange(saved);\n\t\t\t}\n\t\t\tinsertHtmlIntoEditable(editable, `<span ${UPLOAD_ATTRIBUTE}=\"${id}\" contenteditable=\"false\" class=\"${UPLOAD_PLACEHOLDER_CLASS}\"></span>`);\n\t\t},\n\t\tfindPlaceholder: (id) => editableRef.current?.querySelector<HTMLElement>(`[${UPLOAD_ATTRIBUTE}=\"${id}\"]`) ?? null,\n\t\tresolvePlaceholder: (id, image) => {\n\t\t\tconst placeholder = editableRef.current?.querySelector(`[${UPLOAD_ATTRIBUTE}=\"${id}\"]`);\n\t\t\tif (!placeholder) return;\n\t\t\tconst element = document.createElement('img');\n\t\t\telement.setAttribute('src', image.src);\n\t\t\telement.setAttribute('alt', image.alt ?? '');\n\t\t\tif (image.width) element.setAttribute('width', String(image.width));\n\t\t\tif (image.height) element.setAttribute('height', String(image.height));\n\t\t\tplaceholder.replaceWith(element);\n\t\t\temitEditableChange();\n\t\t},\n\t\tremovePlaceholder: (id) => {\n\t\t\teditableRef.current?.querySelector(`[${UPLOAD_ATTRIBUTE}=\"${id}\"]`)?.remove();\n\t\t\temitEditableChange();\n\t\t},\n\t};\n\tconst uploadQueue = useImageUploadQueue(images, adapterRef, strings.images);\n\tconst imageInsert = useImageInsertControl(images, strings.images, uploadQueue.addFiles, () => {\n\t\tconst selection = window.getSelection();\n\t\tconst range = selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : null;\n\t\tsavedRangeRef.current = range && editableRef.current?.contains(range.commonAncestorContainer) ? range.cloneRange() : null;\n\t});\n\tconst toolbarItems = useMemo(\n\t\t() => (imageInsert.item ? [imageInsert.item, ...(extraToolbarItems ?? [])] : extraToolbarItems),\n\t\t[extraToolbarItems, imageInsert.item],\n\t);\n\n\tconst syncActiveImage = useCallback(() => {\n\t\tconst editable = editableRef.current;\n\t\tif (!images || !editable) return;\n\t\t// Typing in the description field moves the selection out; keep the image then.\n\t\tconst selection = window.getSelection();\n\t\tif (selection && selection.rangeCount > 0 && !editable.contains(selection.getRangeAt(0).commonAncestorContainer)) return;\n\t\tconst image = imageAtSelection(editable);\n\t\tsetActiveImage(image);\n\t\tsetActiveAlt(image?.getAttribute('alt') ?? '');\n\t}, [images]);\n\n\tuseEffect(() => {\n\t\tif (!images || typeof document === 'undefined') return;\n\t\tdocument.addEventListener('selectionchange', syncActiveImage);\n\t\treturn () => document.removeEventListener('selectionchange', syncActiveImage);\n\t}, [images, syncActiveImage]);\n\n\tconst handleInput = useCallback(() => {\n\t\tconst editable = editableRef.current;\n\t\tif (images && editable) {\n\t\t\tremoveUnsafeImages(editable);\n\t\t\tuploadQueue.prune();\n\t\t\tif (activeImage && !activeImage.isConnected) setActiveImage(null);\n\t\t}\n\t\temitEditableChange();\n\t}, [activeImage, emitEditableChange, images, uploadQueue]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\tfocus: () => editableRef.current?.focus(),\n\t\t\tgetHTML: () => normalizeHtml(serializeEditable(editableRef.current)),\n\t\t\tsetHTML: (html: string) => {\n\t\t\t\tconst next = normalizeHtml(html);\n\t\t\t\texternalValueRef.current = next;\n\t\t\t\tif (editableRef.current) {\n\t\t\t\t\teditableRef.current.innerHTML = toEditorContent(next);\n\t\t\t\t}\n\t\t\t\tonValueChange(next);\n\t\t\t},\n\t\t\tinsertHTML: (html: string) => {\n\t\t\t\tinsertHtmlIntoEditable(editableRef.current, html);\n\t\t\t\temitEditableChange();\n\t\t\t},\n\t\t\tisEmpty: () => normalizeHtml(serializeEditable(editableRef.current)) === '',\n\t\t\tclear: () => {\n\t\t\t\texternalValueRef.current = '';\n\t\t\t\tif (editableRef.current) editableRef.current.innerHTML = '<p></p>';\n\t\t\t\tonValueChange('');\n\t\t\t},\n\t\t\tgetCaretContext: () => readCaretContext(),\n\t\t\treplaceBeforeCaret: (length: number, html: string) => {\n\t\t\t\treplaceBeforeCaret(null, length, html, () => emitEditableChange());\n\t\t\t},\n\t\t}),\n\t\t[emitEditableChange, onValueChange],\n\t);\n\n\tconst contentStyle = useMemo(\n\t\t() => ({\n\t\t\tminHeight: minHeight ?? (compact ? '2rem' : '12rem'),\n\t\t\t...(maxHeight ? { maxHeight, overflowY: 'auto' as const } : {}),\n\t\t}),\n\t\t[compact, maxHeight, minHeight],\n\t);\n\n\tconst toggleSourceMode = useCallback(() => {\n\t\tif (sourceMode) {\n\t\t\tconst normalized = normalizeHtml(sourceValue);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tif (editableRef.current) {\n\t\t\t\teditableRef.current.innerHTML = toEditorContent(normalized);\n\t\t\t}\n\t\t\tonValueChange(normalized);\n\t\t\tsetSourceMode(false);\n\t\t\treturn;\n\t\t}\n\t\tsetSourceValue(editableRef.current?.innerHTML ?? toEditorContent(value));\n\t\tsetSourceMode(true);\n\t}, [onValueChange, sourceMode, sourceValue, value]);\n\n\tconst handleSourceChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\t\tconst next = e.target.value;\n\t\t\tsetSourceValue(next);\n\t\t\tconst normalized = normalizeHtml(next);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tonValueChange(normalized);\n\t\t},\n\t\t[onValueChange],\n\t);\n\n\tconst placeholderText = typeof placeholder === 'string' ? placeholder : '';\n\tconst isEmpty = normalizeHtml(externalValueRef.current) === '' && uploadQueue.uploads.length === 0;\n\tconst placeholderNode =\n\t\tplaceholderText.length > 0 && !isFocused && isEmpty ? (\n\t\t\t<Text\n\t\t\t\ttag=\"span\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\ttype=\"secondary\"\n\t\t\t\tclassName=\"pointer-events-none absolute inset-0 px-control py-control-y-offset\"\n\t\t\t>\n\t\t\t\t{placeholderText}\n\t\t\t</Text>\n\t\t) : null;\n\n\tconst toolbarButtons = useMemo<ToolbarButtonConfig[]>(\n\t\t() => [\n\t\t\t{ id: 'bold', toggle: true, icon: Bold, label: strings.toolbar.bold, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'italic', toggle: true, icon: Italic, label: strings.toolbar.italic, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'strike', toggle: true, icon: Strikethrough, label: strings.toolbar.strike, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'bullet-list', toggle: true, icon: List, label: strings.toolbar.bulletList, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'ordered-list', toggle: true, icon: ListOrdered, label: strings.toolbar.orderedList, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'blockquote', toggle: true, icon: Quote, label: strings.toolbar.blockquote, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'undo', icon: Undo2, label: strings.toolbar.undo, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'redo', icon: Redo2, label: strings.toolbar.redo, isActive: () => false, run: () => undefined, disabled: true },\n\t\t],\n\t\t[strings],\n\t);\n\n\tconst text = sourceMode\n\t\t? sourceValue.replace(/<[^>]*>/g, '')\n\t\t: (editableRef.current?.innerText ?? normalizeHtml(value).replace(/<[^>]*>/g, ''));\n\tconst countsFooter =\n\t\tshowCounts ? (\n\t\t\t<CountsFooterText text={text} maxLength={maxLength} strings={strings} />\n\t\t) : null;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\trichTextEditorRecipes.frame,\n\t\t\t\tdisabled && richTextEditorRecipes.disabled,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<RichTextEditorToolbar\n\t\t\t\tbuttons={toolbarButtons}\n\t\t\t\textraToolbarItems={toolbarItems}\n\t\t\t\thideSourceToggle={hideSourceToggle}\n\t\t\t\tsourceMode={sourceMode}\n\t\t\t\ttoggleSourceMode={toggleSourceMode}\n\t\t\t\tdisabled={disabled}\n\t\t\t\thasEditor\n\t\t\t\ttoolbarTrailing={toolbarTrailing}\n\t\t\t\tstrings={strings}\n\t\t\t/>\n\n\t\t\t{sourceMode ? (\n\t\t\t\t<textarea\n\t\t\t\t\taria-label={strings.sourceLabel}\n\t\t\t\t\tvalue={sourceValue}\n\t\t\t\t\tonChange={handleSourceChange}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tspellCheck={false}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\trichTextEditorRecipes.source,\n\t\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t\t)}\n\t\t\t\t\tstyle={contentStyle}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div className=\"relative\" style={contentStyle}>\n\t\t\t\t\t{placeholderNode}\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={setEditableRef}\n\t\t\t\t\t\trole=\"textbox\"\n\t\t\t\t\t\taria-label={strings.editorLabel}\n\t\t\t\t\t\taria-multiline=\"true\"\n\t\t\t\t\t\tcontentEditable={!disabled}\n\t\t\t\t\t\tsuppressContentEditableWarning\n\t\t\t\t\t\tonInput={handleInput}\n\t\t\t\t\t\tonKeyUp={() => onCaretChangeRef.current?.()}\n\t\t\t\t\t\tonMouseUp={() => onCaretChangeRef.current?.()}\n\t\t\t\t\t\tonClick={images ? (event) => {\n\t\t\t\t\t\t\t// A click on an image selects it, so the description field follows.\n\t\t\t\t\t\t\tif (!(event.target instanceof HTMLImageElement)) return;\n\t\t\t\t\t\t\tconst range = document.createRange();\n\t\t\t\t\t\t\trange.selectNode(event.target);\n\t\t\t\t\t\t\tconst selection = window.getSelection();\n\t\t\t\t\t\t\tselection?.removeAllRanges();\n\t\t\t\t\t\t\tselection?.addRange(range);\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonPaste={images ? (event) => {\n\t\t\t\t\t\t\tconst files = imageFilesFrom(event.clipboardData);\n\t\t\t\t\t\t\tif (files.length === 0) return;\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tuploadQueue.addFiles(files);\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonDragOver={images ? (event) => {\n\t\t\t\t\t\t\tif (Array.from(event.dataTransfer.types).includes('Files')) event.preventDefault();\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonDrop={images ? (event) => {\n\t\t\t\t\t\t\tconst files = imageFilesFrom(event.dataTransfer);\n\t\t\t\t\t\t\tif (files.length === 0) return;\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\teditableRef.current?.focus();\n\t\t\t\t\t\t\tplaceCaretAtPoint(event.clientX, event.clientY);\n\t\t\t\t\t\t\tuploadQueue.addFiles(files);\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonFocus={() => setIsFocused(true)}\n\t\t\t\t\t\tonBlur={() => setIsFocused(false)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\teditableContentClassName,\n\t\t\t\t\t\t\t'h-full min-h-full',\n\t\t\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{!!images && (\n\t\t\t\t<ImageDetailsBar\n\t\t\t\t\talt={activeImage ? activeAlt : null}\n\t\t\t\t\tonAltChange={(alt) => {\n\t\t\t\t\t\tsetActiveAlt(alt);\n\t\t\t\t\t\tactiveImage?.setAttribute('alt', alt);\n\t\t\t\t\t\temitEditableChange();\n\t\t\t\t\t}}\n\t\t\t\t\tonRemove={() => {\n\t\t\t\t\t\tactiveImage?.remove();\n\t\t\t\t\t\tsetActiveImage(null);\n\t\t\t\t\t\temitEditableChange();\n\t\t\t\t\t\teditableRef.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t\tnotice={uploadQueue.notice}\n\t\t\t\t\tonDismissNotice={uploadQueue.dismissNotice}\n\t\t\t\t\tstrings={strings.images}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{!!footerSlot && (\n\t\t\t\t<div className=\"px-control pb-space-md pt-space-xs\">{footerSlot}</div>\n\t\t\t)}\n\n\t\t\t{countsFooter}\n\t\t\t{imageInsert.input}\n\t\t\t<ImageUploadPortals queue={uploadQueue} adapterRef={adapterRef} strings={strings.images} />\n\t\t</div>\n\t);\n});\n\nFallbackRichTextEditor.displayName = 'FallbackRichTextEditor';\n","/**\n * Public `<RichTextEditor>` shell — picks the TipTap-backed editor when\n * the runtime is loaded and falls back to a plain `contenteditable`\n * surface otherwise. Both variants implement the same imperative\n * `RichTextEditorHandle`, so callers don't have to branch.\n *\n * Heavy lifting lives in `partials/`:\n * - `partials/rich-text-editor-tiptap.tsx` — TipTap variant\n * - `partials/rich-text-editor-fallback.tsx` — contenteditable variant\n * - `partials/rich-text-editor-toolbar.tsx` — shared toolbar\n * - `partials/counts-footer.tsx` — char/word counts\n * - `partials/caret-helpers.ts` — caret introspection\n * - `partials/html-helpers.ts` — HTML normalization\n */\nimport { forwardRef } from 'react';\n\nimport {\n\tFallbackRichTextEditor,\n\tTiptapRichTextEditor,\n\thasTiptapRuntime,\n} from './partials';\nimport type {\n\tRichTextEditorHandle,\n\tRichTextEditorProps,\n} from './rich-text-editor.types';\n\nexport const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorProps>(function RichTextEditor(\n\tprops,\n\tref,\n) {\n\tif (!hasTiptapRuntime) {\n\t\treturn <FallbackRichTextEditor className=\"rich-text-editor--component\" {...props} ref={ref} />;\n\t}\n\n\treturn <TiptapRichTextEditor {...props} ref={ref} />;\n});\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport type {\n\tRichTextEditorProps,\n\tRichTextEditorHandle,\n\tRichTextEditorToolbarItem,\n\tRichTextCaretContext,\n} from './rich-text-editor.types';\n"],"mappings":"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"}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { t as e } from "./utils-l5LpDw2z.js";
|
|
3
|
-
import { n as t } from "./buttons-SbIcm1HJ.js";
|
|
4
|
-
import { n } from "./text.styles-g4He6UIW.js";
|
|
5
|
-
import { t as r } from "./interaction-recipes-CHr0dJUs.js";
|
|
6
|
-
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
7
|
-
import { Code2 as s } from "lucide-react";
|
|
8
|
-
//#region src/components/features/rich-text-editor/partials/rich-text-editor-toolbar.tsx
|
|
9
|
-
function c({ buttons: n, extraToolbarItems: c, hideSourceToggle: l = !1, sourceMode: u, toggleSourceMode: d, disabled: f = !1, hasEditor: p = !0, toolbarTrailing: m, strings: h, className: g }) {
|
|
10
|
-
let _ = (c?.length ?? 0) > 0;
|
|
11
|
-
return /* @__PURE__ */ o("div", {
|
|
12
|
-
className: e("rich-text-editor-toolbar--component border-border flex flex-wrap items-center gap-space-xs border-b p-surface-xs", g),
|
|
13
|
-
children: [
|
|
14
|
-
n.map((e) => {
|
|
15
|
-
let n = e.icon, i = e.isActive();
|
|
16
|
-
return /* @__PURE__ */ a(t, {
|
|
17
|
-
type: "button",
|
|
18
|
-
tone: "secondary",
|
|
19
|
-
buttonStyle: "ghost",
|
|
20
|
-
size: "sm",
|
|
21
|
-
iconOnly: !0,
|
|
22
|
-
className: i ? r.togglePressed : r.toggleHoverButton,
|
|
23
|
-
onClick: e.run,
|
|
24
|
-
disabled: f || !p || u || e.disabled,
|
|
25
|
-
"aria-pressed": e.toggle ? i : void 0,
|
|
26
|
-
"aria-label": e.label,
|
|
27
|
-
title: e.label,
|
|
28
|
-
children: /* @__PURE__ */ a(n, { className: "size-icon" })
|
|
29
|
-
}, e.id);
|
|
30
|
-
}),
|
|
31
|
-
!l && /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("div", { className: "bg-border mx-space-xs size-icon w-px" }), /* @__PURE__ */ a(t, {
|
|
32
|
-
type: "button",
|
|
33
|
-
tone: "secondary",
|
|
34
|
-
buttonStyle: "ghost",
|
|
35
|
-
size: "sm",
|
|
36
|
-
iconOnly: !0,
|
|
37
|
-
className: u ? r.togglePressed : r.toggleHoverButton,
|
|
38
|
-
onClick: d,
|
|
39
|
-
disabled: f || !p,
|
|
40
|
-
"aria-pressed": u,
|
|
41
|
-
"aria-label": h.toolbar.sourceCode,
|
|
42
|
-
title: h.toolbar.sourceCode,
|
|
43
|
-
children: /* @__PURE__ */ a(s, { className: "size-icon" })
|
|
44
|
-
})] }),
|
|
45
|
-
_ && /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("div", { className: "bg-border mx-space-xs size-icon w-px" }), c?.map((e) => {
|
|
46
|
-
let n = e.icon, i = e.isActive?.() ?? !1, o = e.toggle ?? e.isActive !== void 0;
|
|
47
|
-
return /* @__PURE__ */ a(t, {
|
|
48
|
-
type: "button",
|
|
49
|
-
tone: "secondary",
|
|
50
|
-
buttonStyle: "ghost",
|
|
51
|
-
size: "sm",
|
|
52
|
-
iconOnly: !0,
|
|
53
|
-
className: i ? r.togglePressed : r.toggleHoverButton,
|
|
54
|
-
onClick: e.onClick,
|
|
55
|
-
disabled: f || !p || u || e.disabled,
|
|
56
|
-
"aria-pressed": o ? i : void 0,
|
|
57
|
-
"aria-label": e.label,
|
|
58
|
-
title: e.label,
|
|
59
|
-
children: /* @__PURE__ */ a(n, { className: "size-icon" })
|
|
60
|
-
}, e.id);
|
|
61
|
-
})] }),
|
|
62
|
-
!!m && /* @__PURE__ */ a("div", {
|
|
63
|
-
className: "ml-auto flex items-center gap-space-xs",
|
|
64
|
-
children: m
|
|
65
|
-
})
|
|
66
|
-
]
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
c.displayName = "RichTextEditorToolbar";
|
|
70
|
-
//#endregion
|
|
71
|
-
//#region src/components/features/rich-text-editor/rich-text-editor.recipes.ts
|
|
72
|
-
var l = {
|
|
73
|
-
source: e("rich-text-editor--source box-border m-0 block min-h-0 w-full resize-y rounded-none border-0 bg-transparent px-control py-control-y-offset outline-none disabled:cursor-not-allowed disabled:opacity-50", n({
|
|
74
|
-
type: "main",
|
|
75
|
-
size: "xs",
|
|
76
|
-
weight: "regular",
|
|
77
|
-
align: "left",
|
|
78
|
-
lineHeight: "relaxed",
|
|
79
|
-
numeric: !0
|
|
80
|
-
})),
|
|
81
|
-
frame: "min-w-0 overflow-hidden border-input bg-background rounded-inner border",
|
|
82
|
-
disabled: "opacity-50",
|
|
83
|
-
content: "h-full [&_.ProseMirror]:h-full [&_.ProseMirror]:min-h-full [&_.ProseMirror]:outline-none"
|
|
84
|
-
};
|
|
85
|
-
//#endregion
|
|
86
|
-
export { c as n, l as t };
|
|
87
|
-
|
|
88
|
-
//# sourceMappingURL=rich-text-editor.recipes-CadiF_Uu.js.map
|