@keboola/design 11.9.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +34 -8
- package/CHANGELOG.md +155 -0
- package/COMPONENT-API.md +337 -289
- package/README.md +11 -1
- package/dist/{AIKit-ELIsegJz.js → AIKit-BD4r7ff-.js} +404 -243
- package/dist/AIKit-BD4r7ff-.js.map +1 -0
- package/dist/{Alert-BsIM_oFK.js → Alert-UI-CIs-1.js} +16 -16
- package/dist/Alert-UI-CIs-1.js.map +1 -0
- package/dist/{AlertModal-BGJdaRRj.js → AlertModal-Th2khjPi.js} +5 -5
- package/dist/AlertModal-Th2khjPi.js.map +1 -0
- package/dist/{AppShell-DRgJxpXW.js → AppShell-WSQabK8r.js} +15 -52
- package/dist/AppShell-WSQabK8r.js.map +1 -0
- package/dist/{AutoSaveTextarea-BeuWuszr.js → AutoSaveTextarea-C5iIr2Ts.js} +2 -2
- package/dist/{AutoSaveTextarea-BeuWuszr.js.map → AutoSaveTextarea-C5iIr2Ts.js.map} +1 -1
- package/dist/{Badge-o5jURtpB.js → Badge-DIjhwPvh.js} +4 -9
- package/dist/Badge-DIjhwPvh.js.map +1 -0
- package/dist/{BrandEditor-BsTBM3s6.js → BrandEditor-BU23Vl8V.js} +7 -7
- package/dist/{BrandEditor-BsTBM3s6.js.map → BrandEditor-BU23Vl8V.js.map} +1 -1
- package/dist/{BrandLogo-CoKBk4MI.js → BrandLogo-CKpVSZb6.js} +4 -4
- package/dist/BrandLogo-CKpVSZb6.js.map +1 -0
- package/dist/{Breadcrumb-xqEUxfwn.js → Breadcrumb-p9HtMLCc.js} +8 -14
- package/dist/Breadcrumb-p9HtMLCc.js.map +1 -0
- package/dist/{Button-DsRrU5F1.js → Button-Ca4Q3VJU.js} +31 -13
- package/dist/Button-Ca4Q3VJU.js.map +1 -0
- package/dist/{Calendar-cG5NIJ4O.js → Calendar-DFtmZzbF.js} +99 -99
- package/dist/Calendar-DFtmZzbF.js.map +1 -0
- package/dist/{Card-Dyo7055Q.js → Card-Cr9MBNHu.js} +4 -4
- package/dist/Card-Cr9MBNHu.js.map +1 -0
- package/dist/{Checkbox-Dq5fPNrO.js → Checkbox-8yIIgY7g.js} +4 -4
- package/dist/Checkbox-8yIIgY7g.js.map +1 -0
- package/dist/{Clipboard-BZitKiSA.js → Clipboard-_xf6hMDD.js} +2 -2
- package/dist/{Clipboard-BZitKiSA.js.map → Clipboard-_xf6hMDD.js.map} +1 -1
- package/dist/{ClipboardButton-KHQnPEh_.js → ClipboardButton-DHa1trtI.js} +4 -4
- package/dist/{ClipboardButton-KHQnPEh_.js.map → ClipboardButton-DHa1trtI.js.map} +1 -1
- package/dist/{CodeEditor-BJKJXA0c.js → CodeEditor-BSo-oLFG.js} +55 -165
- package/dist/CodeEditor-BSo-oLFG.js.map +1 -0
- package/dist/{ColorInput-Bj3dfPFA.js → ColorInput-DSMqrs2-.js} +12 -27
- package/dist/ColorInput-DSMqrs2-.js.map +1 -0
- package/dist/{ColorModeSwitch-CWt-DZGC.js → ColorModeSwitch-D7EuWyJz.js} +7 -17
- package/dist/ColorModeSwitch-D7EuWyJz.js.map +1 -0
- package/dist/Combobox-CxRAYOBt.js +1069 -0
- package/dist/Combobox-CxRAYOBt.js.map +1 -0
- package/dist/{Command-BDU3C1gg.js → Command-BU_cVurn.js} +4 -4
- package/dist/{Command-BDU3C1gg.js.map → Command-BU_cVurn.js.map} +1 -1
- package/dist/{CopyField-BHRQUyuF.js → CopyField-6_c-NdLO.js} +17 -53
- package/dist/{CopyField-BHRQUyuF.js.map → CopyField-6_c-NdLO.js.map} +1 -1
- package/dist/{DateInput-B6N8g0ra.js → DateInput-DyEErfJf.js} +6 -6
- package/dist/{DateInput-B6N8g0ra.js.map → DateInput-DyEErfJf.js.map} +1 -1
- package/dist/{DatePicker-nA8YdE84.js → DatePicker-CtSa9b3V.js} +3 -3
- package/dist/{DatePicker-nA8YdE84.js.map → DatePicker-CtSa9b3V.js.map} +1 -1
- package/dist/{DateRangeInput-7M9Z4cVO.js → DateRangeInput-Dg7-VUd9.js} +10 -14
- package/dist/DateRangeInput-Dg7-VUd9.js.map +1 -0
- package/dist/{DateRangePicker-DjSUFjh4.js → DateRangePicker-BoPnh4aH.js} +9 -13
- package/dist/DateRangePicker-BoPnh4aH.js.map +1 -0
- package/dist/DiffView-ppTIzh2h.js.map +1 -1
- package/dist/{DropdownMenu-CgVwhDvl.js → DropdownMenu-gRM-A8qU.js} +3 -3
- package/dist/DropdownMenu-gRM-A8qU.js.map +1 -0
- package/dist/{FieldItem-DZGIdiXE.js → FieldItem-2wMXQ0Qw.js} +12 -25
- package/dist/FieldItem-2wMXQ0Qw.js.map +1 -0
- package/dist/{FieldItem-vhIJW4pj.d.ts → FieldItem-CPN1xjN5.d.ts} +11 -25
- package/dist/{FileUpload-DYQCTGjU.js → FileUpload-C83tXuE2.js} +11 -16
- package/dist/{FileUpload-DYQCTGjU.js.map → FileUpload-C83tXuE2.js.map} +1 -1
- package/dist/{Form-CcK7dRrC.js → Form-95rVLfX8.js} +15 -23
- package/dist/{Form-CcK7dRrC.js.map → Form-95rVLfX8.js.map} +1 -1
- package/dist/{FormGroup-DR_gZ25-.js → FormGroup-CmNiAtU6.js} +11 -17
- package/dist/FormGroup-CmNiAtU6.js.map +1 -0
- package/dist/{FullScreenModal-CN9nAs72.js → FullScreenModal-CD7mYeTz.js} +15 -29
- package/dist/FullScreenModal-CD7mYeTz.js.map +1 -0
- package/dist/{HoverCard-B9ZMJxjn.js → HoverCard-B8OKu9XZ.js} +2 -2
- package/dist/{HoverCard-B9ZMJxjn.js.map → HoverCard-B8OKu9XZ.js.map} +1 -1
- package/dist/{InputGroup-Do8K2hvD.js → InputGroup-B4QOPxHl.js} +11 -13
- package/dist/InputGroup-B4QOPxHl.js.map +1 -0
- package/dist/{Kbd-LCFMumoq.js → Kbd-J4n1J6i4.js} +23 -13
- package/dist/Kbd-J4n1J6i4.js.map +1 -0
- package/dist/{MarkedText-DNGEUVWc.js → MarkedText-DlmlJO0u.js} +2 -2
- package/dist/{MarkedText-DNGEUVWc.js.map → MarkedText-DlmlJO0u.js.map} +1 -1
- package/dist/{MermaidDiagram-ZG0iiDV_.js → MermaidDiagram-BQvz6bhv.js} +16 -34
- package/dist/MermaidDiagram-BQvz6bhv.js.map +1 -0
- package/dist/{Modal-I3VWk2oo.js → Modal-Driyqs_N.js} +17 -34
- package/dist/Modal-Driyqs_N.js.map +1 -0
- package/dist/{ModalTitle-CeLM_mX9.js → ModalTitle-BxopkIoQ.js} +3 -3
- package/dist/ModalTitle-BxopkIoQ.js.map +1 -0
- package/dist/{MultiActionButtonGroup-CYZ8IgSf.js → MultiActionButtonGroup-BPnmzBtw.js} +3 -3
- package/dist/{MultiActionButtonGroup-CYZ8IgSf.js.map → MultiActionButtonGroup-BPnmzBtw.js.map} +1 -1
- package/dist/{Navbar-Liy1TPI7.js → Navbar-B_DNpv5s.js} +9 -13
- package/dist/{Navbar-Liy1TPI7.js.map → Navbar-B_DNpv5s.js.map} +1 -1
- package/dist/{OtpInput-CbbymqYs.js → OtpInput-I8B8Vjdl.js} +2 -2
- package/dist/{OtpInput-CbbymqYs.js.map → OtpInput-I8B8Vjdl.js.map} +1 -1
- package/dist/{PageHeader-Q3IpCnQd.js → PageHeader-CgfyXpf1.js} +13 -26
- package/dist/PageHeader-CgfyXpf1.js.map +1 -0
- package/dist/{PageLayout-DSVM-ASz.js → PageLayout-DiAAILuS.js} +12 -20
- package/dist/PageLayout-DiAAILuS.js.map +1 -0
- package/dist/{PageToolbar-BKVJiDAL.js → PageToolbar-DOAtAnfL.js} +12 -42
- package/dist/PageToolbar-DOAtAnfL.js.map +1 -0
- package/dist/{Pagination-C_b7Xhey.js → Pagination-LaSg-5cl.js} +3 -3
- package/dist/{Pagination-C_b7Xhey.js.map → Pagination-LaSg-5cl.js.map} +1 -1
- package/dist/{Popconfirm-5pBzT_HQ.js → Popconfirm-SLz0zodk.js} +3 -3
- package/dist/{Popconfirm-5pBzT_HQ.js.map → Popconfirm-SLz0zodk.js.map} +1 -1
- package/dist/{Popover-BEbQrC_P.js → Popover-CEk915I1.js} +4 -3
- package/dist/Popover-CEk915I1.js.map +1 -0
- package/dist/{RadioGroup-Byc2mym4.js → RadioGroup-CBPRLRN0.js} +4 -4
- package/dist/{RadioGroup-Byc2mym4.js.map → RadioGroup-CBPRLRN0.js.map} +1 -1
- package/dist/{Search-Dhig_hPD.js → Search-DmkQo716.js} +3 -3
- package/dist/{Search-Dhig_hPD.js.map → Search-DmkQo716.js.map} +1 -1
- package/dist/{SearchInput-92r2bkA7.js → SearchInput-CEfQDNl3.js} +8 -13
- package/dist/SearchInput-CEfQDNl3.js.map +1 -0
- package/dist/{SectionNav-CNLJsiVG.js → SectionNav-B_qf0AXi.js} +10 -42
- package/dist/SectionNav-B_qf0AXi.js.map +1 -0
- package/dist/{Select-DV3Hak_l.js → Select-ByRvkZ3D.js} +8 -11
- package/dist/{Select-DV3Hak_l.js.map → Select-ByRvkZ3D.js.map} +1 -1
- package/dist/{Sheet-OparjIi-.js → Sheet-C-yXk5Da.js} +5 -9
- package/dist/Sheet-C-yXk5Da.js.map +1 -0
- package/dist/{Sidebar-CLEbBtNY.js → Sidebar-Ds0E6PbR.js} +16 -33
- package/dist/Sidebar-Ds0E6PbR.js.map +1 -0
- package/dist/{Slider-DLclvRws.js → Slider-DWdu9NuM.js} +3 -3
- package/dist/{Slider-DLclvRws.js.map → Slider-DWdu9NuM.js.map} +1 -1
- package/dist/{Stepper-C8sm9ZFM.js → Stepper-BLkLhfnd.js} +6 -9
- package/dist/{Stepper-C8sm9ZFM.js.map → Stepper-BLkLhfnd.js.map} +1 -1
- package/dist/{Switch-B0WdGSjz.js → Switch-DZvNePOm.js} +2 -2
- package/dist/{Switch-B0WdGSjz.js.map → Switch-DZvNePOm.js.map} +1 -1
- package/dist/{Table-CvYuTuNU.js → Table-BaVT5Tkn.js} +6 -11
- package/dist/{Table-CvYuTuNU.js.map → Table-BaVT5Tkn.js.map} +1 -1
- package/dist/{Tabs-eB974xJf.js → Tabs-Dt9oLYHC.js} +3 -3
- package/dist/{Tabs-eB974xJf.js.map → Tabs-Dt9oLYHC.js.map} +1 -1
- package/dist/{TextInput-CFTf4Cz1.js → TextInput-CDG2XpBl.js} +10 -14
- package/dist/TextInput-CDG2XpBl.js.map +1 -0
- package/dist/{ThemeProvider-DAmNn9Sd.js → ThemeProvider-DXsxFg1U.js} +13 -31
- package/dist/ThemeProvider-DXsxFg1U.js.map +1 -0
- package/dist/{TimePicker-BGeqc-Ed.js → TimePicker-CDGYrRxi.js} +2 -2
- package/dist/{TimePicker-BGeqc-Ed.js.map → TimePicker-CDGYrRxi.js.map} +1 -1
- package/dist/{Timeline-C8-wnRRr.js → Timeline-B-I6sb0M.js} +2 -2
- package/dist/{Timeline-C8-wnRRr.js.map → Timeline-B-I6sb0M.js.map} +1 -1
- package/dist/{Toast-Dr6Uw7ao.js → Toast-PfQf3vj-.js} +2 -2
- package/dist/{Toast-Dr6Uw7ao.js.map → Toast-PfQf3vj-.js.map} +1 -1
- package/dist/{Workbench-UR2FBC7I.js → Workbench-DmZzpkj7.js} +2 -2
- package/dist/{Workbench-UR2FBC7I.js.map → Workbench-DmZzpkj7.js.map} +1 -1
- package/dist/{ZoomableSvg-BZlk3PFJ.js → ZoomableSvg-BzXVfgnI.js} +5 -19
- package/dist/ZoomableSvg-BzXVfgnI.js.map +1 -0
- package/dist/charts.d.ts +21 -52
- package/dist/charts.js +13 -39
- package/dist/charts.js.map +1 -1
- package/dist/{context-D7X470dy.js → context-U293r3v-.js} +5 -9
- package/dist/context-U293r3v-.js.map +1 -0
- package/dist/editors.d.ts +27 -124
- package/dist/editors.js +29 -71
- package/dist/editors.js.map +1 -1
- package/dist/{findLiteralMatches-BGBw8Vbl.js → findLiteralMatches-DgGLzyG0.js} +8 -20
- package/dist/findLiteralMatches-DgGLzyG0.js.map +1 -0
- package/dist/flint.d.ts +3 -6
- package/dist/flint.js +31 -80
- package/dist/flint.js.map +1 -1
- package/dist/{icons-Cek151jC.js → icons-wcA70iQx.js} +105 -2
- package/dist/icons-wcA70iQx.js.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -2
- package/dist/{index-m-kQEWiY.d.ts → index-B7k-09i1.d.ts} +14 -2
- package/dist/index.d.ts +1151 -1838
- package/dist/index.js +68 -67
- package/dist/internal/blocks/AIKit.js +2 -2
- package/dist/internal/blocks/AppShell.js +1 -1
- package/dist/internal/blocks/AuthLayout.js +7 -27
- package/dist/internal/blocks/AuthLayout.js.map +1 -1
- package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
- package/dist/internal/blocks/BrandEditor.js +1 -1
- package/dist/internal/blocks/ChartPanel.js +4 -8
- package/dist/internal/blocks/ChartPanel.js.map +1 -1
- package/dist/internal/blocks/ChipEditor.js +13 -21
- package/dist/internal/blocks/ChipEditor.js.map +1 -1
- package/dist/internal/blocks/ClipboardButton.js +1 -1
- package/dist/internal/blocks/ColorInput.js +1 -1
- package/dist/internal/blocks/ColorModeSwitch.js +1 -1
- package/dist/internal/blocks/Command.js +1 -1
- package/dist/internal/blocks/CopyField.js +1 -1
- package/dist/internal/blocks/DashboardHero.js +4 -7
- package/dist/internal/blocks/DashboardHero.js.map +1 -1
- package/dist/internal/blocks/DateInput.js +1 -1
- package/dist/internal/blocks/DateRangeInput.js +1 -1
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
- package/dist/internal/blocks/EmptyState.js +5 -9
- package/dist/internal/blocks/EmptyState.js.map +1 -1
- package/dist/internal/blocks/ErrorState.js +5 -9
- package/dist/internal/blocks/ErrorState.js.map +1 -1
- package/dist/internal/blocks/ExportMenu.js +6 -10
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- package/dist/internal/blocks/Form/connectors/ComboboxField.js +40 -0
- package/dist/internal/blocks/Form/connectors/ComboboxField.js.map +1 -0
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +5 -22
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -1
- package/dist/internal/blocks/Form.js +1 -1
- package/dist/internal/blocks/FormGroup.js +1 -1
- package/dist/internal/blocks/GoogleButton.js +1 -1
- package/dist/internal/blocks/MicrosoftButton.js +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
- package/dist/internal/blocks/MultiCombobox.js +161 -154
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +1 -1
- package/dist/internal/blocks/OtpInput.js +1 -1
- package/dist/internal/blocks/PageHeader.js +1 -1
- package/dist/internal/blocks/PageLayout.js +1 -1
- package/dist/internal/blocks/PageToolbar.js +1 -1
- package/dist/internal/blocks/PasswordInput.js +4 -4
- package/dist/internal/blocks/PasswordInput.js.map +1 -1
- package/dist/internal/blocks/SearchInput.js +1 -1
- package/dist/internal/blocks/SearchInputWithNavigation.js +4 -4
- package/dist/internal/blocks/SectionNav.js +1 -1
- package/dist/internal/blocks/SplitButton.js +3 -3
- package/dist/internal/blocks/StatCard.js +4 -8
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +1 -1
- package/dist/internal/blocks/Textarea.js +2 -2
- package/dist/internal/blocks/TimeInput.js +5 -5
- package/dist/internal/blocks/TimeInput.js.map +1 -1
- package/dist/internal/components/Alert.js +1 -1
- package/dist/internal/components/AlertModal.js +1 -1
- package/dist/internal/components/Avatar.js +1 -1
- package/dist/internal/components/Badge.js +1 -1
- package/dist/internal/components/BrandLogo.js +1 -1
- package/dist/internal/components/Breadcrumb.js +1 -1
- package/dist/internal/components/Button.js +1 -1
- package/dist/internal/components/ButtonGroup.js.map +1 -1
- package/dist/internal/components/Calendar.js +1 -1
- package/dist/internal/components/Card.js +1 -1
- package/dist/internal/components/Checkbox.js +1 -1
- package/dist/internal/components/Clipboard.js +1 -1
- package/dist/internal/components/CollapsiblePanel.js +2 -2
- package/dist/internal/components/Combobox.js +2 -2
- package/dist/internal/components/DatePicker.js +1 -1
- package/dist/internal/components/DateRangePicker.js +1 -1
- package/dist/internal/components/DropdownMenu.js +1 -1
- package/dist/internal/components/FileUpload.js +1 -1
- package/dist/internal/components/FullScreenModal.js +1 -1
- package/dist/internal/components/HoverCard.js +1 -1
- package/dist/internal/components/InputGroup.js +1 -1
- package/dist/internal/components/Kbd.js +1 -1
- package/dist/internal/components/MarkedText.js +1 -1
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +1 -1
- package/dist/internal/components/Modal.js +1 -1
- package/dist/internal/components/Navbar.js +1 -1
- package/dist/internal/components/Pagination.js +1 -1
- package/dist/internal/components/PanelWithDetails.js +1 -1
- package/dist/internal/components/Popconfirm.js +1 -1
- package/dist/internal/components/Popover.js +1 -1
- package/dist/internal/components/RadioGroup.js +1 -1
- package/dist/internal/components/Search.js +1 -1
- package/dist/internal/components/Select.js +1 -1
- package/dist/internal/components/Separator.js.map +1 -1
- package/dist/internal/components/Sheet.js +1 -1
- package/dist/internal/components/Sidebar.js +1 -1
- package/dist/internal/components/Skeleton/Skeleton.js +5 -9
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Slider.js +1 -1
- package/dist/internal/components/SpotlightBackdrop.js +3 -8
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/StatusDot.js +8 -15
- package/dist/internal/components/StatusDot.js.map +1 -1
- package/dist/internal/components/Stepper.js +1 -1
- package/dist/internal/components/Switch.js +1 -1
- package/dist/internal/components/Table.js +1 -1
- package/dist/internal/components/Tabs.js +1 -1
- package/dist/internal/components/ThemeProvider.js +3 -3
- package/dist/internal/components/TimePicker.js +1 -1
- package/dist/internal/components/Timeline.js +1 -1
- package/dist/internal/components/Toast.js +2 -2
- package/dist/internal/components/Tooltip.js +1 -1
- package/dist/internal/components/Truncated.js +4 -8
- package/dist/internal/components/Truncated.js.map +1 -1
- package/dist/internal/components/Workbench.js +1 -1
- package/dist/internal/components/ZoomableSvg.js +1 -1
- package/dist/internal/hooks/useScrollbarPosition.js +1 -1
- package/dist/internal/hooks/useStableCallback.js +4 -13
- package/dist/internal/hooks/useStableCallback.js.map +1 -1
- package/dist/internal/utils.js +2 -2
- package/dist/markdown-editor.d.ts +15 -37
- package/dist/markdown-editor.js +17 -23
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +4 -6
- package/dist/mermaid.js +1 -1
- package/dist/rjsf.d.ts +9 -19
- package/dist/rjsf.js +44 -84
- package/dist/rjsf.js.map +1 -1
- package/dist/{styles-BAFscjSV.js → styles-gzcjOyKv.js} +6 -6
- package/dist/styles-gzcjOyKv.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/svgTransforms-Dw2hRA-i.js +51 -0
- package/dist/svgTransforms-Dw2hRA-i.js.map +1 -0
- package/dist/testing.d.ts +3 -10
- package/dist/testing.js +5 -12
- package/dist/testing.js.map +1 -1
- package/dist/themeTokens-7DEab0kp.js +31 -0
- package/dist/themeTokens-7DEab0kp.js.map +1 -0
- package/dist/{toast-DIC0iNRf.js → toast-CyXEdaCZ.js} +3 -3
- package/dist/toast-CyXEdaCZ.js.map +1 -0
- package/dist/{themeScopeContext-D7fSyb06.js → useColorSchemeState-Cw4MCXUs.js} +14 -14
- package/dist/useColorSchemeState-Cw4MCXUs.js.map +1 -0
- package/dist/{useControllableState-M6494mCT.js → useControllableState-CUYXMsfz.js} +3 -7
- package/dist/useControllableState-CUYXMsfz.js.map +1 -0
- package/dist/useElement-D-RjrGa4.js +21 -0
- package/dist/useElement-D-RjrGa4.js.map +1 -0
- package/dist/useThemeAttributes-B199Regy.js +67 -0
- package/dist/useThemeAttributes-B199Regy.js.map +1 -0
- package/dist/{utils-BW4AE8VP.js → utils-Bd28bWgm.js} +31 -26
- package/dist/utils-Bd28bWgm.js.map +1 -0
- package/dist/vega.d.ts +8 -30
- package/dist/vega.js +5 -13
- package/dist/vega.js.map +1 -1
- package/dist/{vegaTheme-CSvFEMBl.js → vegaTheme-VQMWTlBw.js} +7 -21
- package/dist/vegaTheme-VQMWTlBw.js.map +1 -0
- package/package.json +10 -9
- package/src/styles.css +120 -14
- package/src/theme.css +126 -6
- package/dist/AIKit-ELIsegJz.js.map +0 -1
- package/dist/Alert-BsIM_oFK.js.map +0 -1
- package/dist/AlertModal-BGJdaRRj.js.map +0 -1
- package/dist/AppShell-DRgJxpXW.js.map +0 -1
- package/dist/Badge-o5jURtpB.js.map +0 -1
- package/dist/BrandLogo-CoKBk4MI.js.map +0 -1
- package/dist/Breadcrumb-xqEUxfwn.js.map +0 -1
- package/dist/Button-DsRrU5F1.js.map +0 -1
- package/dist/Calendar-cG5NIJ4O.js.map +0 -1
- package/dist/Card-Dyo7055Q.js.map +0 -1
- package/dist/Checkbox-Dq5fPNrO.js.map +0 -1
- package/dist/CodeEditor-BJKJXA0c.js.map +0 -1
- package/dist/ColorInput-Bj3dfPFA.js.map +0 -1
- package/dist/ColorModeSwitch-CWt-DZGC.js.map +0 -1
- package/dist/Combobox-D8PrEqTG.js +0 -619
- package/dist/Combobox-D8PrEqTG.js.map +0 -1
- package/dist/DateRangeInput-7M9Z4cVO.js.map +0 -1
- package/dist/DateRangePicker-DjSUFjh4.js.map +0 -1
- package/dist/DropdownMenu-CgVwhDvl.js.map +0 -1
- package/dist/FieldItem-DZGIdiXE.js.map +0 -1
- package/dist/FormGroup-DR_gZ25-.js.map +0 -1
- package/dist/FullScreenModal-CN9nAs72.js.map +0 -1
- package/dist/InputGroup-Do8K2hvD.js.map +0 -1
- package/dist/Kbd-LCFMumoq.js.map +0 -1
- package/dist/MermaidDiagram-ZG0iiDV_.js.map +0 -1
- package/dist/Modal-I3VWk2oo.js.map +0 -1
- package/dist/ModalTitle-CeLM_mX9.js.map +0 -1
- package/dist/PageHeader-Q3IpCnQd.js.map +0 -1
- package/dist/PageLayout-DSVM-ASz.js.map +0 -1
- package/dist/PageToolbar-BKVJiDAL.js.map +0 -1
- package/dist/Popover-BEbQrC_P.js.map +0 -1
- package/dist/SearchInput-92r2bkA7.js.map +0 -1
- package/dist/SectionNav-CNLJsiVG.js.map +0 -1
- package/dist/Sheet-OparjIi-.js.map +0 -1
- package/dist/Sidebar-CLEbBtNY.js.map +0 -1
- package/dist/TextInput-CFTf4Cz1.js.map +0 -1
- package/dist/ThemeProvider-DAmNn9Sd.js.map +0 -1
- package/dist/ZoomableSvg-BZlk3PFJ.js.map +0 -1
- package/dist/context-D7X470dy.js.map +0 -1
- package/dist/findLiteralMatches-BGBw8Vbl.js.map +0 -1
- package/dist/icons-Cek151jC.js.map +0 -1
- package/dist/styles-BAFscjSV.js.map +0 -1
- package/dist/svgTransforms-CJAYPk7o.js +0 -81
- package/dist/svgTransforms-CJAYPk7o.js.map +0 -1
- package/dist/themeScopeContext-D7fSyb06.js.map +0 -1
- package/dist/themeTokens-qP1-55O7.js +0 -119
- package/dist/themeTokens-qP1-55O7.js.map +0 -1
- package/dist/toast-DIC0iNRf.js.map +0 -1
- package/dist/useControllableState-M6494mCT.js.map +0 -1
- package/dist/useElement-BK3AAiIf.js +0 -24
- package/dist/useElement-BK3AAiIf.js.map +0 -1
- package/dist/utils-BW4AE8VP.js.map +0 -1
- package/dist/vegaTheme-CSvFEMBl.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-editor.js","names":["ListIcon","LinkIcon","ListIcon"],"sources":["../src/blocks/MarkdownEditor/context.ts","../src/blocks/MarkdownEditor/nodes/ImageNodeComponent.tsx","../src/blocks/MarkdownEditor/nodes/ImageNode.tsx","../src/blocks/MarkdownEditor/nodes/MermaidNodeComponent.tsx","../src/blocks/MarkdownEditor/nodes/MermaidNode.tsx","../src/blocks/MarkdownEditor/plugins/ImagePastePlugin.tsx","../src/blocks/MarkdownEditor/plugins/KeyboardPlugin.tsx","../src/blocks/MarkdownEditor/transformers.ts","../src/blocks/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/ToolbarButton.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/LinkPanel.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/ToolbarDivider.tsx","../src/blocks/MarkdownEditor/plugins/ToolbarPlugin.tsx","../src/blocks/MarkdownEditor/theme.ts","../src/blocks/MarkdownEditor/MarkdownEditor.tsx"],"sourcesContent":["import { createContext, use } from 'react';\nimport type { ReactNode } from 'react';\n\ntype ImageRenderer = (props: { src: string; alt: string }) => ReactNode;\n\nconst ImageRendererContext = createContext<ImageRenderer | null>(null);\n\nexport const ImageRendererProvider = ImageRendererContext;\n\nexport const useImageRenderer = (): ImageRenderer | null => use(ImageRendererContext);\n","import { useImageRenderer } from '../context';\n\nconst isPlaceholder = (src: string) => src.startsWith('upload-placeholder-');\n\nexport const ImageNodeComponent = ({ src, alt }: { src: string; alt: string }) => {\n const renderer = useImageRenderer();\n\n if (isPlaceholder(src)) {\n return (\n <span className=\"tw:inline-flex tw:items-center tw:gap-1 tw:rounded tw:bg-neutral-100 tw:px-2 tw:py-1 tw:text-xs tw:text-neutral-400\">\n Uploading image…\n </span>\n );\n }\n\n if (renderer) return <>{renderer({ src, alt })}</>;\n return <img src={src} alt={alt} />;\n};\n","/* eslint-disable react/only-export-components -- Lexical convention: $create/$is helpers co-locate with node */\nimport type { ReactNode } from 'react';\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from 'lexical';\nimport { DecoratorNode } from 'lexical';\n\nimport { ImageNodeComponent } from './ImageNodeComponent';\n\ntype SerializedImageNode = Spread<{ src: string; altText: string }, SerializedLexicalNode>;\n\nexport class ImageNode extends DecoratorNode<ReactNode> {\n __src: string;\n __altText: string;\n\n static override getType(): string {\n return 'image';\n }\n\n static override clone(node: ImageNode): ImageNode {\n return new ImageNode(node.__src, node.__altText, node.__key);\n }\n\n constructor(src: string, altText: string, key?: NodeKey) {\n super(key);\n this.__src = src;\n this.__altText = altText;\n }\n\n getSrc(): string {\n return this.__src;\n }\n\n getAlt(): string {\n return this.__altText;\n }\n\n setSrc(src: string): void {\n const writable = this.getWritable();\n writable.__src = src;\n }\n\n setAlt(altText: string): void {\n const writable = this.getWritable();\n writable.__altText = altText;\n }\n\n override createDOM(config: EditorConfig): HTMLElement {\n const span = document.createElement('span');\n const className = config.theme.image;\n if (typeof className === 'string') {\n span.className = className;\n }\n return span;\n }\n\n override updateDOM(): boolean {\n return false;\n }\n\n override decorate(): ReactNode {\n return <ImageNodeComponent src={this.__src} alt={this.__altText} />;\n }\n\n override isInline(): boolean {\n return true;\n }\n\n static override importJSON(serializedNode: SerializedImageNode): ImageNode {\n return $createImageNode(serializedNode.src, serializedNode.altText);\n }\n\n override exportJSON(): SerializedImageNode {\n return {\n type: 'image',\n version: 1,\n src: this.__src,\n altText: this.__altText,\n };\n }\n\n override exportDOM(): DOMExportOutput {\n const element = document.createElement('img');\n element.setAttribute('src', this.__src);\n element.setAttribute('alt', this.__altText);\n return { element };\n }\n\n static override importDOM(): DOMConversionMap | null {\n return {\n img: () => ({\n conversion: (domNode: HTMLElement) => {\n const src = domNode.getAttribute('src') || '';\n const alt = domNode.getAttribute('alt') || '';\n return { node: $createImageNode(src, alt) };\n },\n priority: 0,\n }),\n };\n }\n}\n\nexport const $createImageNode = (src: string, altText: string): ImageNode => {\n return new ImageNode(src, altText);\n};\n\nexport const $isImageNode = (node: LexicalNode | null | undefined): node is ImageNode => {\n return node instanceof ImageNode;\n};\n","import { lazy, Suspense } from 'react';\n\nimport { Skeleton } from '../../../components/Skeleton/Skeleton';\n\nconst MermaidDiagram = lazy(() =>\n import('../../../blocks/MermaidDiagram/MermaidDiagram').then(\n (m) => ({ default: m.MermaidDiagram }),\n (error: unknown) => {\n // Falling back to raw code on chunk-load failure (typically a stale tab after deploy).\n // Logging so we don't silently swap implementations.\n console.error('[MarkdownEditor] failed to load MermaidDiagram chunk', error);\n return {\n default: ({ code }: { code: string }) => (\n <pre>\n <code>{code}</code>\n </pre>\n ),\n };\n },\n ),\n);\n\nexport const MermaidNodeComponent = ({ code }: { code: string }) => {\n return (\n <Suspense\n fallback={\n <div className=\"tw:my-3 tw:overflow-hidden tw:rounded-card tw:border tw:border-neutral-150 tw:bg-neutral-50 tw:p-6\">\n <Skeleton className=\"tw:h-40\" />\n </div>\n }\n >\n <MermaidDiagram code={code} />\n </Suspense>\n );\n};\n","/* eslint-disable react/only-export-components -- Lexical convention: $create/$is helpers co-locate with node */\nimport type { ReactNode } from 'react';\nimport type { LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical';\nimport { DecoratorNode } from 'lexical';\n\nimport { MermaidNodeComponent } from './MermaidNodeComponent';\n\ntype SerializedMermaidNode = Spread<{ code: string }, SerializedLexicalNode>;\n\nexport class MermaidNode extends DecoratorNode<ReactNode> {\n __code: string;\n\n static override getType(): string {\n return 'mermaid';\n }\n\n static override clone(node: MermaidNode): MermaidNode {\n return new MermaidNode(node.__code, node.__key);\n }\n\n constructor(code: string, key?: NodeKey) {\n super(key);\n this.__code = code;\n }\n\n getCode(): string {\n return this.__code;\n }\n\n setCode(code: string): void {\n const writable = this.getWritable();\n writable.__code = code;\n }\n\n override createDOM(): HTMLElement {\n const div = document.createElement('div');\n div.setAttribute('data-lexical-mermaid', 'true');\n return div;\n }\n\n override updateDOM(): boolean {\n return false;\n }\n\n override decorate(): ReactNode {\n return <MermaidNodeComponent code={this.__code} />;\n }\n\n override isInline(): boolean {\n return false;\n }\n\n static override importJSON(serializedNode: SerializedMermaidNode): MermaidNode {\n return $createMermaidNode(serializedNode.code);\n }\n\n override exportJSON(): SerializedMermaidNode {\n return {\n type: 'mermaid',\n version: 1,\n code: this.__code,\n };\n }\n}\n\nexport const $createMermaidNode = (code: string): MermaidNode => {\n return new MermaidNode(code);\n};\n\nexport const $isMermaidNode = (node: LexicalNode | null | undefined): node is MermaidNode => {\n return node instanceof MermaidNode;\n};\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport type { NodeKey } from 'lexical';\nimport {\n $getNodeByKey,\n $insertNodes,\n COMMAND_PRIORITY_CRITICAL,\n DROP_COMMAND,\n PASTE_COMMAND,\n} from 'lexical';\n\nimport { toast } from '../../../components/Toast/toast';\nimport { useStableCallback } from '../../../hooks/useStableCallback';\nimport { $createImageNode, $isImageNode } from '../nodes/ImageNode';\n\nconst ACCEPTED_IMAGE_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n];\n\nconst MAX_IMAGE_SIZE = 10 * 1024 * 1024; // 10 MB\n\nconst PLACEHOLDER_PREFIX = 'upload-placeholder-';\n\nconst generatePlaceholderId = (): string => {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n};\n\nconst isAcceptedImageType = (type: string) => ACCEPTED_IMAGE_TYPES.includes(type);\n\nconst getImageFilesFromDataTransfer = (dataTransfer: DataTransfer | null): File[] => {\n if (!dataTransfer) return [];\n\n if (dataTransfer.items.length > 0) {\n const files: File[] = [];\n for (const item of dataTransfer.items) {\n if (item.kind === 'file' && isAcceptedImageType(item.type)) {\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) return files;\n }\n\n return Array.from(dataTransfer.files).filter((file) => isAcceptedImageType(file.type));\n};\n\nconst escapeMarkdownAlt = (text: string) => text.replace(/[[\\]()]/g, '');\n\ntype ImagePastePluginProps = {\n onImageUpload?: (file: File) => Promise<{ url: string }>;\n};\n\nexport const ImagePastePlugin = ({ onImageUpload }: ImagePastePluginProps) => {\n const [editor] = useLexicalComposerContext();\n // Whether an uploader is configured at all — the commands below must decline\n // paste and drop when it isn't, so Lexical falls back to its default handling.\n // A boolean, so it only changes identity when the prop appears or disappears.\n const canUploadImages = onImageUpload != null;\n const uploadImage = useStableCallback((file: File) => onImageUpload?.(file));\n\n useEffect(() => {\n const uploadFile = (file: File) => {\n if (!canUploadImages) return;\n\n if (file.size > MAX_IMAGE_SIZE) {\n toast.error(`Image \"${file.name}\" is too large. Maximum size is 10 MB.`);\n return;\n }\n\n // Insert placeholder and start upload outside the command handler\n // to avoid nested editor.update() batching issues\n let nodeKey: NodeKey | null = null;\n\n editor.update(() => {\n const placeholderNode = $createImageNode(\n `${PLACEHOLDER_PREFIX}${generatePlaceholderId()}`,\n 'Uploading image\\u2026',\n );\n $insertNodes([placeholderNode]);\n nodeKey = placeholderNode.getKey();\n });\n\n if (!nodeKey) return;\n const capturedKey: NodeKey = nodeKey;\n\n uploadImage(file)\n ?.then(({ url }) => {\n editor.update(() => {\n const node = $getNodeByKey(capturedKey);\n if ($isImageNode(node)) {\n const altText = escapeMarkdownAlt(file.name.replace(/\\.[^.]+$/, '') || 'image');\n node.setSrc(url);\n node.setAlt(altText);\n }\n });\n })\n .catch((error: unknown) => {\n console.error('[MarkdownEditor] image upload failed', error);\n toast.error(`Failed to upload \"${file.name}\". Please try again.`);\n editor.update(() => {\n const node = $getNodeByKey(capturedKey);\n if (node) node.remove();\n });\n });\n };\n\n const removePaste = editor.registerCommand(\n PASTE_COMMAND,\n (event) => {\n if (!canUploadImages) return false;\n if (!(event instanceof ClipboardEvent)) return false;\n const files = getImageFilesFromDataTransfer(event.clipboardData);\n if (files.length === 0) return false;\n\n event.preventDefault();\n // Defer upload to next microtask to escape the command handler's update context\n Promise.resolve().then(() => files.forEach(uploadFile));\n return true;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n const removeDrop = editor.registerCommand(\n DROP_COMMAND,\n (event: DragEvent) => {\n if (!canUploadImages) return false;\n const files = getImageFilesFromDataTransfer(event.dataTransfer);\n if (files.length === 0) return false;\n\n event.preventDefault();\n // Defer upload to next microtask to escape the command handler's update context\n Promise.resolve().then(() => files.forEach(uploadFile));\n return true;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n return () => {\n removePaste();\n removeDrop();\n };\n }, [editor, canUploadImages, uploadImage]);\n\n return null;\n};\n","import { useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_HIGH, KEY_DOWN_COMMAND } from 'lexical';\n\nimport { useStableCallback } from '../../../hooks/useStableCallback';\n\ntype KeyboardPluginProps = {\n /** Invoked directly on Cmd/Ctrl+Enter (explicit commit shortcut, no blur). */\n onSave?: () => void;\n /**\n * Invoked on Escape in inline-edit mode. Per the inline-editable-text pattern spec\n * (evviku/design-system-docs), Escape reverts the in-progress edit — callers reset\n * `value` to the last-committed state inside this handler.\n */\n onCancel?: () => void;\n /**\n * When true, plain Enter blurs the editor instead of inserting a paragraph break.\n * For `saveOnBlur` callers this commits via blur; for non-saveOnBlur callers Enter\n * just exits edit mode. Shift+Enter still inserts a soft line break.\n */\n singleLine?: boolean;\n /**\n * When true, Escape blurs the editor (exits edit mode). Enable only for inline-edit\n * patterns (`singleLine` or `saveOnBlur`); in full-toolbar mode Esc stays a no-op so\n * existing call sites don't lose focus on a stray keypress.\n */\n blurOnEscape?: boolean;\n /**\n * Set to `true` before the plugin programmatically blurs on Escape so the wrapper's\n * blur handler can skip its `onSave` — otherwise blur-after-cancel would commit the\n * value we just reverted. Reset by the consumer on read.\n */\n skipBlurSaveRef?: RefObject<boolean>;\n};\n\nexport const KeyboardPlugin = ({\n onSave,\n onCancel,\n singleLine,\n blurOnEscape,\n skipBlurSaveRef,\n}: KeyboardPluginProps) => {\n const [editor] = useLexicalComposerContext();\n const handleSave = useStableCallback(() => onSave?.());\n const handleCancel = useStableCallback(() => onCancel?.());\n const singleLineRef = useRef(singleLine);\n singleLineRef.current = singleLine;\n const blurOnEscapeRef = useRef(blurOnEscape);\n blurOnEscapeRef.current = blurOnEscape;\n const skipBlurSaveExternalRef = skipBlurSaveRef;\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (event.key === 'Enter' && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n handleSave();\n return true;\n }\n if (event.key === 'Enter' && !event.shiftKey && !event.altKey && singleLineRef.current) {\n event.preventDefault();\n editor.getRootElement()?.blur();\n return true;\n }\n if (event.key === 'Escape' && blurOnEscapeRef.current) {\n // Suppress blur-driven onSave so the post-blur save doesn't commit the value we just reverted.\n if (skipBlurSaveExternalRef) skipBlurSaveExternalRef.current = true;\n handleCancel();\n editor.getRootElement()?.blur();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_HIGH,\n );\n }, [editor, skipBlurSaveExternalRef, handleSave, handleCancel]);\n\n return null;\n};\n","import type {\n ElementTransformer,\n MultilineElementTransformer,\n TextMatchTransformer,\n Transformer,\n} from '@lexical/markdown';\nimport { CHECK_LIST, TRANSFORMERS } from '@lexical/markdown';\nimport {\n $createHorizontalRuleNode,\n $isHorizontalRuleNode,\n HorizontalRuleNode,\n} from '@lexical/react/LexicalHorizontalRuleNode';\n\nimport { $createImageNode, $isImageNode, ImageNode } from './nodes/ImageNode';\nimport { $createMermaidNode, $isMermaidNode, MermaidNode } from './nodes/MermaidNode';\n\n/** Markdown image: `` */\nconst IMAGE: TextMatchTransformer = {\n dependencies: [ImageNode],\n export: (node) => {\n if (!$isImageNode(node)) return null;\n return `})`;\n },\n importRegExp: /!\\[([^\\]]*)\\]\\(([^)]+)\\)/,\n regExp: /!\\[([^\\]]*)\\]\\(([^)]+)\\)$/,\n replace: (textNode, match) => {\n const [, alt = '', src = ''] = match;\n const imageNode = $createImageNode(src, alt);\n textNode.replace(imageNode);\n },\n trigger: ')',\n type: 'text-match',\n};\n\n/** Horizontal rule: `---`, `***`, or `___` */\nconst HORIZONTAL_RULE: ElementTransformer = {\n dependencies: [HorizontalRuleNode],\n export: (node) => {\n return $isHorizontalRuleNode(node) ? '---' : null;\n },\n regExp: /^(---|\\*\\*\\*|___)$/,\n replace: (parentNode) => {\n const node = $createHorizontalRuleNode();\n parentNode.replace(node);\n },\n type: 'element',\n};\n\n/** Fenced mermaid block: ` ```mermaid ... ``` ` → MermaidNode (rendered as diagram) */\nconst MERMAID: MultilineElementTransformer = {\n dependencies: [MermaidNode],\n export: (node) => {\n if (!$isMermaidNode(node)) return null;\n return '```mermaid\\n' + node.getCode() + '\\n```';\n },\n regExpStart: /^[ \\t]*(`{3,})mermaid(?:\\s.*)?$/,\n regExpEnd: {\n optional: true,\n regExp: /^[ \\t]*`{3,}$/,\n },\n replace: (rootNode, _children, _startMatch, _endMatch, linesInBetween) => {\n if (!linesInBetween) return;\n const code = linesInBetween.join('\\n').trim();\n if (code) {\n rootNode.append($createMermaidNode(code));\n }\n },\n handleImportAfterStartMatch: ({\n lines,\n rootNode,\n startLineIndex,\n startMatch,\n }): [boolean, number] => {\n const fence = startMatch[1];\n if (!fence) return [false, startLineIndex];\n const fenceLength = fence.trim().length;\n const endRegex = new RegExp(`^[ \\\\t]*\\`{${fenceLength},}$`);\n\n for (let i = startLineIndex + 1; i < lines.length; i++) {\n if (endRegex.test(lines[i] ?? '')) {\n const code = lines\n .slice(startLineIndex + 1, i)\n .join('\\n')\n .trim();\n if (code) {\n rootNode.append($createMermaidNode(code));\n }\n return [true, i];\n }\n }\n\n // No closing fence — consume remaining lines\n const code = lines\n .slice(startLineIndex + 1)\n .join('\\n')\n .trim();\n if (code) {\n rootNode.append($createMermaidNode(code));\n }\n return [true, lines.length - 1];\n },\n type: 'multiline-element',\n};\n\n/**\n * Custom transformers = our additions + built-in Lexical transformers.\n * MERMAID is placed before TRANSFORMERS so it intercepts ` ```mermaid ``` ` before the generic CODE transformer.\n * IMAGE is placed before built-in LINK to prevent `` from being parsed as `!` + link.\n */\nexport const CUSTOM_TRANSFORMERS: Transformer[] = [\n IMAGE,\n HORIZONTAL_RULE,\n CHECK_LIST,\n MERMAID,\n ...TRANSFORMERS,\n];\n\n/**\n * No transformers = plain text. `singleLine` mode edits entity names / titles, which are\n * plain text, not markdown. Parsing inline formatting here corrupts ordinary names: e.g.\n * `staging_chargebee_invoices` would render the `_chargebee_` span as italics, and Lexical\n * escapes the underscores on export (`\\_`) to prevent exactly that — but those backslashes\n * then leak into the persisted name. Dropping every transformer keeps `_`, `*`, `` ` ``, `~`\n * literal on both import and export; pair the empty set with `unescapeMarkdownText` on export\n * to strip Lexical's escaping (see MarkdownSyncPlugin).\n */\nexport const SINGLE_LINE_TRANSFORMERS: Transformer[] = [];\n\n// --- Table pre/post-processing ---\n// GFM tables can't round-trip through Lexical's markdown (no built-in table transformer).\n// We wrap them in fenced code blocks on import and unwrap on export to preserve them exactly.\n\nconst TABLE_FENCE_LANG = '__kbc_table__';\n\nconst isTableLine = (line: string): boolean => {\n const trimmed = line.trim();\n return trimmed.startsWith('|') && trimmed.endsWith('|');\n};\n\nconst CODE_FENCE_REGEX = /^[ \\t]*`{3,}/;\n\n/** Wrap GFM tables in code fences so they survive Lexical's markdown round-trip. */\nexport const preprocessMarkdown = (markdown: string): string => {\n const lines = markdown.split('\\n');\n const result: string[] = [];\n let tableLines: string[] = [];\n let insideCodeFence = false;\n\n const flushTable = () => {\n if (tableLines.length >= 2) {\n result.push(`\\`\\`\\`${TABLE_FENCE_LANG}`);\n result.push(...tableLines);\n result.push('```');\n } else {\n // Single pipe line isn't a table — keep as-is\n result.push(...tableLines);\n }\n tableLines = [];\n };\n\n for (const line of lines) {\n if (CODE_FENCE_REGEX.test(line)) {\n if (tableLines.length > 0) flushTable();\n insideCodeFence = !insideCodeFence;\n result.push(line);\n continue;\n }\n\n if (insideCodeFence) {\n result.push(line);\n continue;\n }\n\n if (isTableLine(line)) {\n tableLines.push(line);\n } else {\n if (tableLines.length > 0) flushTable();\n result.push(line);\n }\n }\n if (tableLines.length > 0) flushTable();\n\n return result.join('\\n');\n};\n\n/** Unwrap code-fenced tables back to raw GFM table markdown. */\nexport const postprocessMarkdown = (markdown: string): string => {\n const regex = new RegExp(`\\`\\`\\`${TABLE_FENCE_LANG}\\\\n([\\\\s\\\\S]*?)\\\\n\\`\\`\\``, 'g');\n return markdown.replace(regex, '$1');\n};\n\n/**\n * Reverses the backslash-escaping Lexical applies to markdown punctuation (`* _ ` ~ \\`) when\n * exporting text nodes. Used for `singleLine` (plain-text) mode, where the export value is a\n * bare entity name — the escaping would otherwise persist as literal backslashes in the name.\n */\nexport const unescapeMarkdownText = (markdown: string): string =>\n markdown.replace(/\\\\([*_`~\\\\])/g, '$1');\n","import { useEffect, useRef } from 'react';\nimport type { Transformer } from '@lexical/markdown';\nimport { $convertFromMarkdownString, $convertToMarkdownString } from '@lexical/markdown';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\n\nimport { useStableCallback } from '../../../hooks/useStableCallback';\nimport {\n CUSTOM_TRANSFORMERS,\n postprocessMarkdown,\n preprocessMarkdown,\n unescapeMarkdownText,\n} from '../transformers';\n\nconst IMPORT_TAG = 'markdown-import';\n\ntype MarkdownSyncPluginProps = {\n value: string;\n editable: boolean;\n onChange?: (markdown: string) => void;\n transformers?: Transformer[];\n /**\n * Plain-text mode: export a bare entity name instead of markdown. Unescapes the punctuation\n * Lexical escapes on export (`\\_` → `_`), so names with underscores don't persist backslashes.\n */\n singleLine?: boolean;\n};\n\nexport const MarkdownSyncPlugin = ({\n value,\n editable,\n onChange,\n transformers = CUSTOM_TRANSFORMERS,\n singleLine = false,\n}: MarkdownSyncPluginProps) => {\n const [editor] = useLexicalComposerContext();\n const lastExportedRef = useRef(value);\n const handleChange = useStableCallback((markdown: string) => onChange?.(markdown));\n const transformersRef = useRef(transformers);\n transformersRef.current = transformers;\n const singleLineRef = useRef(singleLine);\n singleLineRef.current = singleLine;\n\n // Sync editable state — only when it actually changes\n useEffect(() => {\n editor.setEditable(editable);\n }, [editor, editable]);\n\n // Import: external value -> editor state\n useEffect(() => {\n if (value === lastExportedRef.current) return;\n lastExportedRef.current = value;\n\n editor.update(\n () => {\n $convertFromMarkdownString(preprocessMarkdown(value), transformersRef.current);\n },\n { tag: IMPORT_TAG },\n );\n }, [editor, value]);\n\n // Export: editor state -> onChange (subscription)\n useEffect(() => {\n return editor.registerUpdateListener(({ tags }) => {\n if (tags.has(IMPORT_TAG)) return;\n\n editor.getEditorState().read(() => {\n const raw = $convertToMarkdownString(transformersRef.current);\n const markdown = singleLineRef.current\n ? unescapeMarkdownText(raw)\n : postprocessMarkdown(raw);\n if (markdown !== lastExportedRef.current) {\n lastExportedRef.current = markdown;\n handleChange(markdown);\n }\n });\n });\n }, [editor, handleChange]);\n\n return null;\n};\n","import { useRef } from 'react';\nimport {\n $getSelection,\n $setSelection,\n type BaseSelection,\n type ElementFormatType,\n FORMAT_ELEMENT_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nimport { DropdownMenu } from '../../../../components/DropdownMenu';\nimport { Tooltip } from '../../../../components/Tooltip';\nimport {\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n ChevronDown,\n type LucideIcon,\n} from '../../../../icons';\nimport { cn } from '../../../../utils';\n\nconst ALIGNMENT_OPTIONS: { value: ElementFormatType; label: string; icon: LucideIcon }[] = [\n { value: 'left', label: 'Left', icon: AlignLeft },\n { value: 'center', label: 'Center', icon: AlignCenter },\n { value: 'right', label: 'Right', icon: AlignRight },\n { value: 'justify', label: 'Justify', icon: AlignJustify },\n];\n\nconst ALIGNMENT_ICONS: Record<string, LucideIcon> = Object.fromEntries(\n ALIGNMENT_OPTIONS.map(({ value, icon }) => [value, icon]),\n);\n\nexport const AlignmentDropdown = ({\n editor,\n alignment,\n}: {\n editor: LexicalEditor;\n alignment: ElementFormatType;\n}) => {\n const savedSelectionRef = useRef<BaseSelection | null>(null);\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n savedSelectionRef.current = selection ? selection.clone() : null;\n });\n }\n };\n\n const handleSelect = (align: ElementFormatType) => {\n // Restore selection and dispatch within the same update so the command sees\n // the restored selection (otherwise dispatchCommand may race with the queued\n // $setSelection and apply the format to the wrong block).\n editor.update(() => {\n if (savedSelectionRef.current) {\n $setSelection(savedSelectionRef.current);\n }\n editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, align);\n });\n };\n\n const CurrentAlignmentIcon = ALIGNMENT_ICONS[alignment] ?? AlignLeft;\n\n return (\n <DropdownMenu onOpenChange={handleOpenChange}>\n <Tooltip tooltip=\"Text alignment\" placement=\"top\" triggerAsChild>\n <DropdownMenu.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n 'tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground',\n 'tw:hover:bg-accent',\n )}\n >\n <CurrentAlignmentIcon className=\"tw:size-4\" />\n <ChevronDown className=\"tw:size-3\" />\n </button>\n </DropdownMenu.Trigger>\n </Tooltip>\n <DropdownMenu.Content align=\"start\" className=\"tw:min-w-32\">\n {ALIGNMENT_OPTIONS.map(({ value, label, icon: IconComp }) => (\n <DropdownMenu.Item\n key={value}\n onSelect={() => handleSelect(value)}\n className={cn(\n 'tw:flex tw:items-center tw:gap-2',\n alignment === value && 'tw:bg-secondary-50 tw:text-secondary-500',\n )}\n >\n <IconComp className=\"tw:size-4\" />\n {label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu>\n );\n};\n","import { useRef } from 'react';\nimport { $createCodeNode } from '@lexical/code';\nimport { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from '@lexical/list';\nimport { $createHeadingNode, $createQuoteNode } from '@lexical/rich-text';\nimport { $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n $setSelection,\n type BaseSelection,\n type LexicalEditor,\n} from 'lexical';\n\nimport { DropdownMenu } from '../../../../components/DropdownMenu';\nimport { Tooltip } from '../../../../components/Tooltip';\nimport {\n ChevronDown,\n Heading1,\n Heading2,\n Heading3,\n List as ListIcon,\n ListOrdered,\n type LucideIcon,\n Quote,\n SquareCode,\n Type,\n} from '../../../../icons';\nimport { cn } from '../../../../utils';\n\nconst BLOCK_TYPE_META = {\n paragraph: { label: 'Normal', icon: Type satisfies LucideIcon, selectable: true },\n h1: { label: 'Heading 1', icon: Heading1 satisfies LucideIcon, selectable: true },\n h2: { label: 'Heading 2', icon: Heading2 satisfies LucideIcon, selectable: true },\n h3: { label: 'Heading 3', icon: Heading3 satisfies LucideIcon, selectable: true },\n bullet: { label: 'Bullet List', icon: ListIcon satisfies LucideIcon, selectable: false },\n number: { label: 'Numbered List', icon: ListOrdered satisfies LucideIcon, selectable: false },\n quote: { label: 'Quote', icon: Quote satisfies LucideIcon, selectable: false },\n code: { label: 'Code Block', icon: SquareCode satisfies LucideIcon, selectable: false },\n} as const;\n\ntype BlockType = keyof typeof BLOCK_TYPE_META;\n\nconst BLOCK_TYPE_OPTIONS = (\n Object.entries(BLOCK_TYPE_META) as [BlockType, (typeof BLOCK_TYPE_META)[BlockType]][]\n)\n .filter(([, meta]) => meta.selectable)\n .map(([value, { label, icon }]) => ({ value, label, icon }));\n\nconst isBlockType = (value: string): value is BlockType =>\n Object.prototype.hasOwnProperty.call(BLOCK_TYPE_META, value);\n\nexport const BlockTypeDropdown = ({\n editor,\n blockType,\n}: {\n editor: LexicalEditor;\n blockType: string;\n}) => {\n const savedSelectionRef = useRef<BaseSelection | null>(null);\n const currentMeta = isBlockType(blockType) ? BLOCK_TYPE_META[blockType] : null;\n const CurrentBlockIcon = currentMeta?.icon ?? Type;\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n savedSelectionRef.current = selection ? selection.clone() : null;\n });\n }\n };\n\n const handleSelect = (type: BlockType) => {\n editor.update(() => {\n if (savedSelectionRef.current) {\n $setSelection(savedSelectionRef.current);\n }\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n if (type === 'bullet') {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n return;\n }\n if (type === 'number') {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n return;\n }\n\n const anchorNode = selection.anchor.getNode();\n const element = $getNearestBlockElementAncestorOrThrow(anchorNode);\n\n const newNode =\n type === 'h1' || type === 'h2' || type === 'h3'\n ? $createHeadingNode(type)\n : type === 'quote'\n ? $createQuoteNode()\n : type === 'code'\n ? $createCodeNode()\n : $createParagraphNode();\n\n element.getChildren().forEach((child) => newNode.append(child));\n element.replace(newNode);\n });\n };\n\n return (\n <DropdownMenu onOpenChange={handleOpenChange}>\n <Tooltip tooltip=\"Change block type\" placement=\"top\" triggerAsChild>\n <DropdownMenu.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n 'tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1.5 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground',\n 'tw:hover:bg-accent',\n )}\n >\n <CurrentBlockIcon className=\"tw:size-4\" />\n {currentMeta?.label ?? 'Normal'}\n <ChevronDown className=\"tw:size-3\" />\n </button>\n </DropdownMenu.Trigger>\n </Tooltip>\n <DropdownMenu.Content align=\"start\" className=\"tw:min-w-40\">\n {BLOCK_TYPE_OPTIONS.map(({ value, label, icon: IconComp }) => (\n <DropdownMenu.Item\n key={value}\n onSelect={() => handleSelect(value)}\n className={cn(\n 'tw:flex tw:items-center tw:gap-2',\n blockType === value && 'tw:bg-secondary-50 tw:text-secondary-500',\n )}\n >\n <IconComp className=\"tw:size-4\" />\n {label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Tooltip } from '../../../../components/Tooltip';\nimport { cn } from '../../../../utils';\n\nexport const ToolbarButton = ({\n active,\n disabled,\n onClick,\n tooltip,\n children,\n className: extraClassName,\n}: {\n active?: boolean;\n disabled?: boolean;\n onClick: () => void;\n tooltip: ReactNode;\n children: ReactNode;\n className?: string;\n}) => (\n <Tooltip tooltip={tooltip} placement=\"top\" triggerAsChild>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className={cn(\n 'tw:flex tw:h-7 tw:min-w-7 tw:cursor-pointer tw:items-center tw:justify-center tw:rounded tw:border-0 tw:bg-transparent tw:px-1 tw:text-xs tw:text-muted-foreground',\n 'tw:hover:bg-accent tw:disabled:cursor-not-allowed tw:disabled:opacity-30',\n active && 'tw:bg-secondary-100 tw:text-secondary-500',\n extraClassName,\n )}\n >\n {children}\n </button>\n </Tooltip>\n);\n","import { useRef, useState } from 'react';\nimport type { KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { $createLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';\nimport {\n $createTextNode,\n $getSelection,\n $isRangeSelection,\n $setSelection,\n type BaseSelection,\n type LexicalEditor,\n} from 'lexical';\n\nimport { FormGroup } from '../../../../blocks/FormGroup';\nimport { TextInput } from '../../../../blocks/TextInput';\nimport { Button } from '../../../../components/Button';\nimport { ButtonGroup } from '../../../../components/ButtonGroup';\nimport { Label } from '../../../../components/Label';\nimport { Link as LinkIcon } from '../../../../icons';\n\nimport { ToolbarButton } from './ToolbarButton';\n\nconst insertLink = (\n editor: LexicalEditor,\n url: string,\n label: string,\n savedSelection: BaseSelection | null,\n) => {\n editor.update(() => {\n $setSelection(savedSelection);\n const selection = $getSelection();\n\n if ($isRangeSelection(selection)) {\n const selectedText = selection.getTextContent();\n if (selectedText && label === selectedText) {\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, url);\n return;\n }\n }\n\n const linkNode = $createLinkNode(url);\n const textNode = $createTextNode(label || url);\n linkNode.append(textNode);\n\n if ($isRangeSelection(selection)) {\n selection.insertNodes([linkNode]);\n }\n });\n};\n\nexport const LinkPanel = ({ editor, isLink }: { editor: LexicalEditor; isLink: boolean }) => {\n const [open, setOpen] = useState(false);\n const [url, setUrl] = useState('');\n const [label, setLabel] = useState('');\n const savedSelectionRef = useRef<BaseSelection | null>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n const handleOpen = () => {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n savedSelectionRef.current = selection ? selection.clone() : null;\n\n if ($isRangeSelection(selection)) {\n const text = selection.getTextContent();\n if (text) setLabel(text);\n }\n });\n setOpen(true);\n };\n\n const handleClose = () => {\n setOpen(false);\n setUrl('');\n setLabel('');\n savedSelectionRef.current = null;\n editor.focus();\n };\n\n const handleSubmit = () => {\n const trimmedUrl = url.trim();\n if (!trimmedUrl) return;\n\n insertLink(editor, trimmedUrl, label.trim(), savedSelectionRef.current);\n handleClose();\n };\n\n const handleKeyDown = (e: ReactKeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleSubmit();\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n handleClose();\n }\n };\n\n if (isLink) {\n return (\n <ToolbarButton\n active\n onClick={() => editor.dispatchCommand(TOGGLE_LINK_COMMAND, null)}\n tooltip=\"Remove Link\"\n >\n <LinkIcon className=\"tw:size-4\" />\n </ToolbarButton>\n );\n }\n\n return (\n <div className=\"tw:relative\">\n <ToolbarButton active={open} onClick={handleOpen} tooltip=\"Insert Link\">\n <LinkIcon className=\"tw:size-4\" />\n </ToolbarButton>\n {open && (\n <div\n ref={panelRef}\n className=\"tw:absolute tw:left-0 tw:top-full tw:z-50 tw:mt-1 tw:w-80 tw:rounded-md tw:border tw:border-border tw:bg-popover tw:p-3 tw:text-popover-foreground tw:shadow-lg\"\n >\n <div className=\"tw:flex tw:flex-col tw:gap-2\">\n <FormGroup>\n <Label htmlFor=\"link-label\" className=\"tw:mb-1 tw:text-xs\">\n Label\n </Label>\n <TextInput\n id=\"link-label\"\n autoFocus\n placeholder=\"Link text\"\n value={label}\n onValueChange={setLabel}\n onKeyDown={handleKeyDown}\n variant=\"secondary\"\n />\n </FormGroup>\n <FormGroup>\n <Label htmlFor=\"link-url\" className=\"tw:mb-1 tw:text-xs\">\n URL\n </Label>\n <TextInput\n id=\"link-url\"\n placeholder=\"https://…\"\n value={url}\n onValueChange={setUrl}\n onKeyDown={handleKeyDown}\n variant=\"secondary\"\n />\n </FormGroup>\n <ButtonGroup>\n <Button size=\"small\" variant=\"outline\" onClick={handleClose}>\n Cancel\n </Button>\n <Button size=\"small\" onClick={handleSubmit} disabled={!url.trim()}>\n Add link\n </Button>\n </ButtonGroup>\n </div>\n </div>\n )}\n </div>\n );\n};\n","export const ToolbarDivider = () => <div className=\"tw:mx-0.5 tw:h-5 tw:w-px tw:bg-border\" />;\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { $createCodeNode, $isCodeNode } from '@lexical/code';\nimport { $isLinkNode } from '@lexical/link';\nimport {\n $isListNode,\n INSERT_ORDERED_LIST_COMMAND,\n INSERT_UNORDERED_LIST_COMMAND,\n REMOVE_LIST_COMMAND,\n} from '@lexical/list';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { $createQuoteNode, $isHeadingNode, $isQuoteNode } from '@lexical/rich-text';\nimport { $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n type ElementFormatType,\n FORMAT_TEXT_COMMAND,\n} from 'lexical';\n\nimport {\n Bold,\n Code,\n Italic,\n List as ListIcon,\n ListOrdered,\n Quote,\n SquareCode,\n Strikethrough,\n Underline,\n} from '../../../icons';\n\nimport { AlignmentDropdown } from './toolbar/AlignmentDropdown';\nimport { BlockTypeDropdown } from './toolbar/BlockTypeDropdown';\nimport { LinkPanel } from './toolbar/LinkPanel';\nimport { ToolbarButton } from './toolbar/ToolbarButton';\nimport { ToolbarDivider } from './toolbar/ToolbarDivider';\n\nconst ELEMENT_FORMAT_TYPES = ['left', 'center', 'right', 'justify', 'start', 'end', ''] as const;\n\nconst isElementFormatType = (value: string): value is ElementFormatType =>\n (ELEMENT_FORMAT_TYPES as readonly string[]).includes(value);\n\nconst toElementFormatType = (value: string): ElementFormatType =>\n isElementFormatType(value) ? value : 'left';\n\nexport const ToolbarPlugin = () => {\n const [editor] = useLexicalComposerContext();\n const [isBold, setIsBold] = useState(false);\n const [isItalic, setIsItalic] = useState(false);\n const [isUnderline, setIsUnderline] = useState(false);\n const [isStrikethrough, setIsStrikethrough] = useState(false);\n const [isCode, setIsCode] = useState(false);\n const [isLink, setIsLink] = useState(false);\n const [blockType, setBlockType] = useState<string>('paragraph');\n const [alignment, setAlignment] = useState<ElementFormatType>('left');\n const [isVisible, setIsVisible] = useState(false);\n const [position, setPosition] = useState<{ top: number; left: number } | null>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const isMouseDownRef = useRef(false);\n const hasSelectionRef = useRef(false);\n\n const updatePosition = useCallback(() => {\n const nativeSelection = window.getSelection();\n if (!nativeSelection || nativeSelection.rangeCount === 0) return;\n const range = nativeSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n if (rect.width > 0) {\n const toolbarWidth = toolbarRef.current?.offsetWidth ?? 300;\n setPosition({\n top: rect.top + window.scrollY - 8,\n left: Math.max(8, rect.left + window.scrollX + rect.width / 2 - toolbarWidth / 2),\n });\n }\n }, []);\n\n useEffect(() => {\n const handleMouseDown = () => {\n isMouseDownRef.current = true;\n };\n const handleMouseUp = () => {\n isMouseDownRef.current = false;\n if (hasSelectionRef.current) {\n setIsVisible(true);\n }\n };\n document.addEventListener('mousedown', handleMouseDown);\n document.addEventListener('mouseup', handleMouseUp);\n return () => {\n document.removeEventListener('mousedown', handleMouseDown);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n }, []);\n\n const updateToolbar = useCallback(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n hasSelectionRef.current = false;\n setIsVisible(false);\n return;\n }\n\n const hasSelection = !selection.isCollapsed() && selection.getTextContent().length > 0;\n hasSelectionRef.current = hasSelection;\n\n if (!hasSelection) {\n setIsVisible(false);\n } else if (!isMouseDownRef.current) {\n setIsVisible(true);\n }\n\n if (hasSelection) {\n updatePosition();\n }\n\n setIsBold(selection.hasFormat('bold'));\n setIsItalic(selection.hasFormat('italic'));\n setIsUnderline(selection.hasFormat('underline'));\n setIsStrikethrough(selection.hasFormat('strikethrough'));\n setIsCode(selection.hasFormat('code'));\n\n const node = selection.anchor.getNode();\n const parent = node.getParent();\n setIsLink($isLinkNode(parent) || $isLinkNode(node));\n\n const blockElement = $getNearestBlockElementAncestorOrThrow(node);\n\n if ($isListNode(blockElement)) {\n const listType = blockElement.getListType();\n setBlockType(listType === 'number' ? 'number' : 'bullet');\n } else if ($isHeadingNode(blockElement)) {\n setBlockType(blockElement.getTag());\n } else if ($isCodeNode(blockElement)) {\n setBlockType('code');\n } else if ($isQuoteNode(blockElement)) {\n setBlockType('quote');\n } else {\n setBlockType('paragraph');\n }\n\n setAlignment(toElementFormatType(blockElement.getFormatType()));\n }, [updatePosition]);\n\n useEffect(() => {\n const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n updateToolbar();\n });\n });\n\n return () => {\n unregisterUpdate();\n };\n }, [editor, updateToolbar]);\n\n if (!isVisible || !position) return null;\n\n return createPortal(\n <div\n ref={toolbarRef}\n role=\"toolbar\"\n aria-label=\"Formatting options\"\n onMouseDown={(e) => e.preventDefault()}\n style={{ top: position.top, left: position.left }}\n className=\"tw:absolute tw:z-[1060] tw:flex tw:-translate-y-full tw:items-center tw:gap-0.5 tw:rounded-lg tw:border tw:border-border tw:bg-popover tw:px-1.5 tw:py-1 tw:text-popover-foreground tw:shadow-lg\"\n >\n <BlockTypeDropdown editor={editor} blockType={blockType} />\n\n <ToolbarDivider />\n\n <ToolbarButton\n active={isBold}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold')}\n tooltip=\"Bold (Ctrl+B)\"\n >\n <Bold className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isItalic}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic')}\n tooltip=\"Italic (Ctrl+I)\"\n >\n <Italic className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isUnderline}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline')}\n tooltip=\"Underline (Ctrl+U)\"\n >\n <Underline className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isStrikethrough}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough')}\n tooltip=\"Strikethrough\"\n >\n <Strikethrough className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isCode}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'code')}\n tooltip=\"Inline Code\"\n >\n <Code className=\"tw:size-4\" />\n </ToolbarButton>\n\n <ToolbarDivider />\n\n <LinkPanel editor={editor} isLink={isLink} />\n\n <ToolbarDivider />\n\n <ToolbarButton\n active={blockType === 'bullet'}\n onClick={() => {\n if (blockType === 'bullet') {\n editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n } else {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n }\n }}\n tooltip=\"Bullet List\"\n >\n <ListIcon className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={blockType === 'number'}\n onClick={() => {\n if (blockType === 'number') {\n editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n } else {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n }\n }}\n tooltip=\"Numbered List\"\n >\n <ListOrdered className=\"tw:size-4\" />\n </ToolbarButton>\n\n <ToolbarDivider />\n\n <AlignmentDropdown editor={editor} alignment={alignment} />\n\n <ToolbarDivider />\n\n <ToolbarButton\n active={blockType === 'quote'}\n onClick={() => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchorNode = selection.anchor.getNode();\n const element = $getNearestBlockElementAncestorOrThrow(anchorNode);\n const newNode = blockType === 'quote' ? $createParagraphNode() : $createQuoteNode();\n element.getChildren().forEach((child) => newNode.append(child));\n element.replace(newNode);\n });\n }}\n tooltip=\"Quote\"\n >\n <Quote className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={blockType === 'code'}\n onClick={() => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchorNode = selection.anchor.getNode();\n const element = $getNearestBlockElementAncestorOrThrow(anchorNode);\n const newNode = blockType === 'code' ? $createParagraphNode() : $createCodeNode();\n element.getChildren().forEach((child) => newNode.append(child));\n element.replace(newNode);\n });\n }}\n tooltip=\"Code Block\"\n >\n <SquareCode className=\"tw:size-4\" />\n </ToolbarButton>\n </div>,\n document.body,\n );\n};\n","import type { EditorThemeClasses } from 'lexical';\n\n/**\n * Lexical editor theme — maps node types to CSS classes.\n * The editor container uses `tw:prose` so semantic elements (headings, lists, blockquotes, etc.)\n * are styled by Tailwind Typography. We only need explicit classes for text formatting\n * (bold, italic, etc.) because Lexical renders those as `<span>` elements.\n */\nexport const editorTheme: EditorThemeClasses = {\n link: 'tw:cursor-pointer tw:!text-primary tw:underline',\n text: {\n bold: 'tw:font-bold',\n italic: 'tw:italic',\n strikethrough: 'tw:line-through',\n underline: 'tw:underline',\n code: 'tw:rounded tw:bg-muted tw:px-1 tw:py-0.5 tw:font-mono tw:text-[0.85em]',\n },\n list: {\n ol: 'tw:!list-decimal',\n ul: 'tw:!list-disc',\n checklist: 'tw:!list-none tw:!pl-0',\n listitemChecked: [\n 'tw:relative tw:!pl-6 tw:list-none tw:outline-hidden tw:line-through tw:text-muted-foreground',\n 'tw:before:content-[\"\"] tw:before:absolute tw:before:left-0 tw:before:top-[3px]',\n 'tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid',\n 'tw:before:bg-primary tw:before:border-primary tw:before:cursor-pointer',\n 'tw:after:content-[\"\"] tw:after:absolute tw:after:left-[5.5px] tw:after:top-[5.5px]',\n 'tw:after:w-1 tw:after:h-2 tw:after:border-primary-foreground tw:after:border-solid',\n 'tw:after:border-r-[1.5px] tw:after:border-b-[1.5px] tw:after:border-t-0 tw:after:border-l-0',\n 'tw:after:rotate-45',\n ].join(' '),\n listitemUnchecked: [\n 'tw:relative tw:!pl-6 tw:list-none tw:outline-hidden',\n 'tw:before:content-[\"\"] tw:before:absolute tw:before:left-0 tw:before:top-[3px]',\n 'tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid',\n 'tw:before:border-input tw:before:bg-background tw:before:cursor-pointer',\n ].join(' '),\n },\n};\n","import { useRef, useState } from 'react';\nimport type { FocusEvent, ReactNode } from 'react';\nimport { CodeNode } from '@lexical/code';\nimport { LinkNode } from '@lexical/link';\nimport { ListItemNode, ListNode } from '@lexical/list';\nimport { $convertFromMarkdownString } from '@lexical/markdown';\nimport { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';\nimport { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';\nimport { ClickableLinkPlugin } from '@lexical/react/LexicalClickableLinkPlugin';\nimport type { InitialConfigType } from '@lexical/react/LexicalComposer';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';\nimport { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';\nimport { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';\nimport { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';\nimport { ListPlugin } from '@lexical/react/LexicalListPlugin';\nimport { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\n\nimport { cn } from '../../utils';\n\nimport { ImageNode } from './nodes/ImageNode';\nimport { MermaidNode } from './nodes/MermaidNode';\nimport { ImagePastePlugin } from './plugins/ImagePastePlugin';\nimport { KeyboardPlugin } from './plugins/KeyboardPlugin';\nimport { MarkdownSyncPlugin } from './plugins/MarkdownSyncPlugin';\nimport { ToolbarPlugin } from './plugins/ToolbarPlugin';\nimport { ImageRendererProvider } from './context';\nimport { editorTheme } from './theme';\nimport { CUSTOM_TRANSFORMERS, preprocessMarkdown, SINGLE_LINE_TRANSFORMERS } from './transformers';\n\nexport type MarkdownEditorProps = {\n /** Markdown string (controlled) */\n value: string;\n onChange?: (markdown: string) => void;\n /**\n * Renders content but never accepts input. Use for permanent view-only contexts\n * (e.g. a current user lacks edit permission). Toolbar is hidden.\n */\n readOnly?: boolean;\n /**\n * Temporarily blocks input but signals intent to re-enable\n * (e.g. while a save is in flight). Functionally identical to `readOnly` today.\n */\n disabled?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n /** Invoked on Cmd/Ctrl+Enter — typically used to commit a form. */\n onSave?: () => void;\n /**\n * Invoked on Escape in inline-edit mode (`singleLine || saveOnBlur`). Per the\n * inline-editable-text pattern spec, Esc reverts the in-progress edit — callers\n * reset `value` to the last-committed state inside this handler.\n */\n onCancel?: () => void;\n /**\n * Async image upload. Resolved URL is embedded as the image src\n * (`` in the underlying markdown).\n */\n onImageUpload?: (file: File) => Promise<{ url: string }>;\n className?: string;\n imageRenderer?: (props: { src: string; alt: string }) => ReactNode;\n showToolbar?: boolean;\n /**\n * Strips the prose typography wrapper, removes the min-height, and tightens padding so\n * the editor visually blends with surrounding text. Use for inline / Linear-style edit\n * affordances inside headings, list rows, or table cells. Pair with `className` to set\n * the caller's typography.\n */\n compact?: boolean;\n /**\n * Calls `onSave` when focus leaves the editor (and is not moved into the toolbar).\n * `onChange` already keeps the caller's value in sync — `onSave` is the \"commit\" signal.\n */\n saveOnBlur?: boolean;\n /**\n * Disables block-level markdown (lists, headings, code blocks, HR) and makes a plain\n * Enter press trigger `onSave` and blur the editor. Shift+Enter still inserts a soft\n * line break. Use for editable titles.\n */\n singleLine?: boolean;\n /**\n * Clamps content to 2 lines (truncating with an ellipsis) in the display (not-focused)\n * state; focus expands the editor to full height (no clamp). `line-clamp` is self-gating,\n * so short/empty content renders fully with no truncation. Per the inline-editable-text\n * pattern spec for description-style slots.\n */\n clampDisplay?: boolean;\n /**\n * Minimum visible height in lines. `1` renders as a single line that grows with\n * content (Linear/Slack/GitHub-PR-comment pattern); `0` removes the floor entirely.\n * Omit to keep the default ~4-line floor. Ignored in `compact` mode (which has no floor).\n */\n minRows?: number;\n};\n\nconst EDITOR_NODES = [\n ImageNode,\n MermaidNode,\n HeadingNode,\n QuoteNode,\n ListNode,\n ListItemNode,\n CodeNode,\n LinkNode,\n HorizontalRuleNode,\n];\n\nexport const MarkdownEditor = ({\n value,\n onChange,\n readOnly = false,\n placeholder,\n autoFocus = false,\n disabled = false,\n onSave,\n onCancel,\n onImageUpload,\n className,\n imageRenderer,\n showToolbar = false,\n compact = false,\n saveOnBlur = false,\n singleLine = false,\n clampDisplay = false,\n minRows,\n}: MarkdownEditorProps) => {\n const editable = !readOnly && !disabled;\n const transformers = singleLine ? SINGLE_LINE_TRANSFORMERS : CUSTOM_TRANSFORMERS;\n const useDefaultMinHeight = !compact && minRows === undefined;\n const customMinHeight =\n !compact && minRows !== undefined ? { minHeight: `${minRows * 1.75}em` } : undefined;\n\n // Lexical reads editorState only on first render; later prop changes are applied by MarkdownSyncPlugin.\n const [initialConfig] = useState<InitialConfigType>(() => ({\n namespace: 'MarkdownEditor',\n theme: editorTheme,\n nodes: EDITOR_NODES,\n onError: (error: Error) => {\n console.error('[MarkdownEditor] uncaught editor error', error);\n },\n editable,\n editorState: () => {\n $convertFromMarkdownString(preprocessMarkdown(value), transformers);\n },\n }));\n\n // Set to `true` by KeyboardPlugin before it programmatically blurs on Escape so the\n // blur handler can skip its `onSave` — otherwise blur-after-cancel would commit the\n // value we just reverted. Reset on read inside handleBlur.\n const skipBlurSaveRef = useRef(false);\n\n const handleBlur =\n saveOnBlur && onSave\n ? (event: FocusEvent<HTMLDivElement>) => {\n if (skipBlurSaveRef.current) {\n skipBlurSaveRef.current = false;\n return;\n }\n // Only fire when focus leaves the editor wrapper entirely (not when moving into the toolbar).\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {\n onSave();\n }\n }\n : undefined;\n\n return (\n <LexicalComposer initialConfig={initialConfig}>\n <ImageRendererProvider value={imageRenderer ?? null}>\n <div\n className={cn(\n !compact && 'tw:prose',\n // Compact mode drops `tw:prose`, so Lexical's <p> wrappers fall back to the browser\n // default `margin: 1em 0` — visually huge at heading sizes. Zero them, and use the\n // adjacent-sibling selector for paragraph spacing so single-paragraph blocks (titles,\n // short descriptions) stay tight while multi-paragraph blocks still breathe.\n compact && 'tw:[&_p]:m-0 tw:[&_p+p]:mt-2',\n // Display-state clamp: 2 lines, dropped in focus-within so editing expands to full\n // height. line-clamp is self-gating (no effect below 3 lines), so short/empty content\n // renders clean; a CSS fade can't gate on overflow without JS, so it's omitted.\n clampDisplay && 'tw:[&:not(:focus-within)]:line-clamp-2',\n className,\n )}\n onBlur={handleBlur}\n >\n {showToolbar && editable && <ToolbarPlugin />}\n <div\n className={cn(\n 'tw:relative tw:rounded-md tw:transition-colors',\n // In compact mode the padding lets the hover bg / focus ring extend past the text,\n // but a matching negative margin shifts the wrapper outward so the text itself stays\n // aligned with the parent's content edge (i.e. with where static text would render).\n compact ? 'tw:px-1.5 tw:py-0.5 tw:-mx-1.5 tw:-my-0.5' : 'tw:p-2',\n editable &&\n 'tw:cursor-text tw:hover:bg-muted tw:focus-within:ring-2 tw:focus-within:ring-ring/40',\n )}\n >\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n className={cn('tw:outline-hidden', useDefaultMinHeight && 'tw:min-h-[100px]')}\n style={customMinHeight}\n aria-placeholder={placeholder ?? ''}\n placeholder={\n placeholder ? (\n <div\n className={cn(\n 'tw:pointer-events-none tw:absolute tw:select-none tw:text-muted-foreground',\n compact\n ? 'tw:left-1.5 tw:top-0.5'\n : 'tw:left-2 tw:top-[calc(0.5rem+0.35em)]',\n )}\n >\n {placeholder}\n </div>\n ) : (\n <div />\n )\n }\n />\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </div>\n <HistoryPlugin />\n <LinkPlugin />\n <ClickableLinkPlugin newTab />\n {!singleLine && <ListPlugin />}\n {!singleLine && <CheckListPlugin />}\n {!singleLine && <HorizontalRulePlugin />}\n <TabIndentationPlugin />\n <MarkdownShortcutPlugin transformers={transformers} />\n <MarkdownSyncPlugin\n value={value}\n editable={editable}\n onChange={onChange}\n transformers={transformers}\n singleLine={singleLine}\n />\n <ImagePastePlugin onImageUpload={onImageUpload} />\n <KeyboardPlugin\n onSave={onSave}\n onCancel={onCancel}\n singleLine={singleLine}\n blurOnEscape={singleLine || saveOnBlur}\n skipBlurSaveRef={skipBlurSaveRef}\n />\n {autoFocus && <AutoFocusPlugin />}\n </div>\n </ImageRendererProvider>\n </LexicalComposer>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"markdown-editor.js","names":["ListIcon","LinkIcon","ListIcon"],"sources":["../src/blocks/MarkdownEditor/context.ts","../src/blocks/MarkdownEditor/nodes/ImageNodeComponent.tsx","../src/blocks/MarkdownEditor/nodes/ImageNode.tsx","../src/blocks/MarkdownEditor/nodes/MermaidNodeComponent.tsx","../src/blocks/MarkdownEditor/nodes/MermaidNode.tsx","../src/blocks/MarkdownEditor/plugins/ImagePastePlugin.tsx","../src/blocks/MarkdownEditor/plugins/KeyboardPlugin.tsx","../src/blocks/MarkdownEditor/transformers.ts","../src/blocks/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/ToolbarButton.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/LinkPanel.tsx","../src/blocks/MarkdownEditor/plugins/toolbar/ToolbarDivider.tsx","../src/blocks/MarkdownEditor/plugins/ToolbarPlugin.tsx","../src/blocks/MarkdownEditor/theme.ts","../src/blocks/MarkdownEditor/MarkdownEditor.tsx"],"sourcesContent":["import { createContext, use } from 'react';\nimport type { ReactNode } from 'react';\n\ntype ImageRenderer = (props: { src: string; alt: string }) => ReactNode;\n\nconst ImageRendererContext = createContext<ImageRenderer | null>(null);\n\nexport const ImageRendererProvider = ImageRendererContext;\n\nexport const useImageRenderer = (): ImageRenderer | null => use(ImageRendererContext);\n","import { useImageRenderer } from '../context';\n\nconst isPlaceholder = (src: string) => src.startsWith('upload-placeholder-');\n\nexport const ImageNodeComponent = ({ src, alt }: { src: string; alt: string }) => {\n const renderer = useImageRenderer();\n\n if (isPlaceholder(src)) {\n return (\n <span className=\"tw:inline-flex tw:items-center tw:gap-1 tw:rounded tw:bg-neutral-100 tw:px-2 tw:py-1 tw:text-xs tw:text-neutral-400\">\n Uploading image…\n </span>\n );\n }\n\n if (renderer) return <>{renderer({ src, alt })}</>;\n return <img src={src} alt={alt} />;\n};\n","/* eslint-disable react/only-export-components -- Lexical convention: $create/$is helpers co-locate with node */\nimport type { ReactNode } from 'react';\nimport type {\n DOMConversionMap,\n DOMExportOutput,\n EditorConfig,\n LexicalNode,\n NodeKey,\n SerializedLexicalNode,\n Spread,\n} from 'lexical';\nimport { DecoratorNode } from 'lexical';\n\nimport { ImageNodeComponent } from './ImageNodeComponent';\n\ntype SerializedImageNode = Spread<{ src: string; altText: string }, SerializedLexicalNode>;\n\nexport class ImageNode extends DecoratorNode<ReactNode> {\n __src: string;\n __altText: string;\n\n static override getType(): string {\n return 'image';\n }\n\n static override clone(node: ImageNode): ImageNode {\n return new ImageNode(node.__src, node.__altText, node.__key);\n }\n\n constructor(src: string, altText: string, key?: NodeKey) {\n super(key);\n this.__src = src;\n this.__altText = altText;\n }\n\n getSrc(): string {\n return this.__src;\n }\n\n getAlt(): string {\n return this.__altText;\n }\n\n setSrc(src: string): void {\n const writable = this.getWritable();\n writable.__src = src;\n }\n\n setAlt(altText: string): void {\n const writable = this.getWritable();\n writable.__altText = altText;\n }\n\n override createDOM(config: EditorConfig): HTMLElement {\n const span = document.createElement('span');\n const className = config.theme.image;\n if (typeof className === 'string') {\n span.className = className;\n }\n return span;\n }\n\n override updateDOM(): boolean {\n return false;\n }\n\n override decorate(): ReactNode {\n return <ImageNodeComponent src={this.__src} alt={this.__altText} />;\n }\n\n override isInline(): boolean {\n return true;\n }\n\n static override importJSON(serializedNode: SerializedImageNode): ImageNode {\n return $createImageNode(serializedNode.src, serializedNode.altText);\n }\n\n override exportJSON(): SerializedImageNode {\n return {\n type: 'image',\n version: 1,\n src: this.__src,\n altText: this.__altText,\n };\n }\n\n override exportDOM(): DOMExportOutput {\n const element = document.createElement('img');\n element.setAttribute('src', this.__src);\n element.setAttribute('alt', this.__altText);\n return { element };\n }\n\n static override importDOM(): DOMConversionMap | null {\n return {\n img: () => ({\n conversion: (domNode: HTMLElement) => {\n const src = domNode.getAttribute('src') || '';\n const alt = domNode.getAttribute('alt') || '';\n return { node: $createImageNode(src, alt) };\n },\n priority: 0,\n }),\n };\n }\n}\n\nexport const $createImageNode = (src: string, altText: string): ImageNode => {\n return new ImageNode(src, altText);\n};\n\nexport const $isImageNode = (node: LexicalNode | null | undefined): node is ImageNode => {\n return node instanceof ImageNode;\n};\n","import { lazy, Suspense } from 'react';\n\nimport { Skeleton } from '../../../components/Skeleton/Skeleton';\n\nconst MermaidDiagram = lazy(() =>\n import('../../../blocks/MermaidDiagram/MermaidDiagram').then(\n (m) => ({ default: m.MermaidDiagram }),\n (error: unknown) => {\n // Falling back to raw code on chunk-load failure (typically a stale tab after deploy).\n // Logging so we don't silently swap implementations.\n console.error('[MarkdownEditor] failed to load MermaidDiagram chunk', error);\n return {\n default: ({ code }: { code: string }) => (\n <pre>\n <code>{code}</code>\n </pre>\n ),\n };\n },\n ),\n);\n\nexport const MermaidNodeComponent = ({ code }: { code: string }) => {\n return (\n <Suspense\n fallback={\n <div className=\"tw:my-3 tw:overflow-hidden tw:rounded-card tw:border tw:border-neutral-150 tw:bg-neutral-50 tw:p-6\">\n <Skeleton className=\"tw:h-40\" />\n </div>\n }\n >\n <MermaidDiagram code={code} />\n </Suspense>\n );\n};\n","/* eslint-disable react/only-export-components -- Lexical convention: $create/$is helpers co-locate with node */\nimport type { ReactNode } from 'react';\nimport type { LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical';\nimport { DecoratorNode } from 'lexical';\n\nimport { MermaidNodeComponent } from './MermaidNodeComponent';\n\ntype SerializedMermaidNode = Spread<{ code: string }, SerializedLexicalNode>;\n\nexport class MermaidNode extends DecoratorNode<ReactNode> {\n __code: string;\n\n static override getType(): string {\n return 'mermaid';\n }\n\n static override clone(node: MermaidNode): MermaidNode {\n return new MermaidNode(node.__code, node.__key);\n }\n\n constructor(code: string, key?: NodeKey) {\n super(key);\n this.__code = code;\n }\n\n getCode(): string {\n return this.__code;\n }\n\n setCode(code: string): void {\n const writable = this.getWritable();\n writable.__code = code;\n }\n\n override createDOM(): HTMLElement {\n const div = document.createElement('div');\n div.setAttribute('data-lexical-mermaid', 'true');\n return div;\n }\n\n override updateDOM(): boolean {\n return false;\n }\n\n override decorate(): ReactNode {\n return <MermaidNodeComponent code={this.__code} />;\n }\n\n override isInline(): boolean {\n return false;\n }\n\n static override importJSON(serializedNode: SerializedMermaidNode): MermaidNode {\n return $createMermaidNode(serializedNode.code);\n }\n\n override exportJSON(): SerializedMermaidNode {\n return {\n type: 'mermaid',\n version: 1,\n code: this.__code,\n };\n }\n}\n\nexport const $createMermaidNode = (code: string): MermaidNode => {\n return new MermaidNode(code);\n};\n\nexport const $isMermaidNode = (node: LexicalNode | null | undefined): node is MermaidNode => {\n return node instanceof MermaidNode;\n};\n","import { useEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport type { NodeKey } from 'lexical';\nimport {\n $getNodeByKey,\n $insertNodes,\n COMMAND_PRIORITY_CRITICAL,\n DROP_COMMAND,\n PASTE_COMMAND,\n} from 'lexical';\n\nimport { toast } from '../../../components/Toast/toast';\nimport { useStableCallback } from '../../../hooks/useStableCallback';\nimport { $createImageNode, $isImageNode } from '../nodes/ImageNode';\n\nconst ACCEPTED_IMAGE_TYPES = [\n 'image/png',\n 'image/jpeg',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n];\n\nconst MAX_IMAGE_SIZE = 10 * 1024 * 1024; // 10 MB\n\nconst PLACEHOLDER_PREFIX = 'upload-placeholder-';\n\nconst generatePlaceholderId = (): string => {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n};\n\nconst isAcceptedImageType = (type: string) => ACCEPTED_IMAGE_TYPES.includes(type);\n\nconst getImageFilesFromDataTransfer = (dataTransfer: DataTransfer | null): File[] => {\n if (!dataTransfer) return [];\n\n if (dataTransfer.items.length > 0) {\n const files: File[] = [];\n for (const item of dataTransfer.items) {\n if (item.kind === 'file' && isAcceptedImageType(item.type)) {\n const file = item.getAsFile();\n if (file) files.push(file);\n }\n }\n if (files.length > 0) return files;\n }\n\n return Array.from(dataTransfer.files).filter((file) => isAcceptedImageType(file.type));\n};\n\nconst escapeMarkdownAlt = (text: string) => text.replace(/[[\\]()]/g, '');\n\ntype ImagePastePluginProps = {\n onImageUpload?: (file: File) => Promise<{ url: string }>;\n};\n\nexport const ImagePastePlugin = ({ onImageUpload }: ImagePastePluginProps) => {\n const [editor] = useLexicalComposerContext();\n // Whether an uploader is configured at all — the commands below must decline\n // paste and drop when it isn't, so Lexical falls back to its default handling.\n // A boolean, so it only changes identity when the prop appears or disappears.\n const canUploadImages = onImageUpload != null;\n const uploadImage = useStableCallback((file: File) => onImageUpload?.(file));\n\n useEffect(() => {\n const uploadFile = (file: File) => {\n if (!canUploadImages) return;\n\n if (file.size > MAX_IMAGE_SIZE) {\n toast.error(`Image \"${file.name}\" is too large. Maximum size is 10 MB.`);\n return;\n }\n\n // Insert placeholder and start upload outside the command handler\n // to avoid nested editor.update() batching issues\n let nodeKey: NodeKey | null = null;\n\n editor.update(() => {\n const placeholderNode = $createImageNode(\n `${PLACEHOLDER_PREFIX}${generatePlaceholderId()}`,\n 'Uploading image\\u2026',\n );\n $insertNodes([placeholderNode]);\n nodeKey = placeholderNode.getKey();\n });\n\n if (!nodeKey) return;\n const capturedKey: NodeKey = nodeKey;\n\n uploadImage(file)\n ?.then(({ url }) => {\n editor.update(() => {\n const node = $getNodeByKey(capturedKey);\n if ($isImageNode(node)) {\n const altText = escapeMarkdownAlt(file.name.replace(/\\.[^.]+$/, '') || 'image');\n node.setSrc(url);\n node.setAlt(altText);\n }\n });\n })\n .catch((error: unknown) => {\n console.error('[MarkdownEditor] image upload failed', error);\n toast.error(`Failed to upload \"${file.name}\". Please try again.`);\n editor.update(() => {\n const node = $getNodeByKey(capturedKey);\n if (node) node.remove();\n });\n });\n };\n\n const removePaste = editor.registerCommand(\n PASTE_COMMAND,\n (event) => {\n if (!canUploadImages) return false;\n if (!(event instanceof ClipboardEvent)) return false;\n const files = getImageFilesFromDataTransfer(event.clipboardData);\n if (files.length === 0) return false;\n\n event.preventDefault();\n // Defer upload to next microtask to escape the command handler's update context\n Promise.resolve().then(() => files.forEach(uploadFile));\n return true;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n const removeDrop = editor.registerCommand(\n DROP_COMMAND,\n (event: DragEvent) => {\n if (!canUploadImages) return false;\n const files = getImageFilesFromDataTransfer(event.dataTransfer);\n if (files.length === 0) return false;\n\n event.preventDefault();\n // Defer upload to next microtask to escape the command handler's update context\n Promise.resolve().then(() => files.forEach(uploadFile));\n return true;\n },\n COMMAND_PRIORITY_CRITICAL,\n );\n\n return () => {\n removePaste();\n removeDrop();\n };\n }, [editor, canUploadImages, uploadImage]);\n\n return null;\n};\n","import { useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { COMMAND_PRIORITY_HIGH, KEY_DOWN_COMMAND } from 'lexical';\n\nimport { useStableCallback } from '../../../hooks/useStableCallback';\n\ntype KeyboardPluginProps = {\n /** Invoked on Cmd/Ctrl+Enter, without blurring. */\n onSave?: () => void;\n /** Escape in inline-edit mode. Callers reset `value` to the last-committed state here. */\n onCancel?: () => void;\n /** Plain Enter blurs the editor instead of breaking the paragraph; Shift+Enter still breaks. */\n singleLine?: boolean;\n /** Escape blurs the editor. Inline-edit only; elsewhere a stray Esc must keep focus. */\n blurOnEscape?: boolean;\n /**\n * Set before the Escape blur so the blur handler skips `onSave` on the reverted value.\n * The consumer resets it on read.\n */\n skipBlurSaveRef?: RefObject<boolean>;\n};\n\nexport const KeyboardPlugin = ({\n onSave,\n onCancel,\n singleLine,\n blurOnEscape,\n skipBlurSaveRef,\n}: KeyboardPluginProps) => {\n const [editor] = useLexicalComposerContext();\n const handleSave = useStableCallback(() => onSave?.());\n const handleCancel = useStableCallback(() => onCancel?.());\n const singleLineRef = useRef(singleLine);\n singleLineRef.current = singleLine;\n const blurOnEscapeRef = useRef(blurOnEscape);\n blurOnEscapeRef.current = blurOnEscape;\n const skipBlurSaveExternalRef = skipBlurSaveRef;\n\n useEffect(() => {\n return editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event: KeyboardEvent) => {\n if (event.key === 'Enter' && (event.ctrlKey || event.metaKey)) {\n event.preventDefault();\n handleSave();\n return true;\n }\n if (event.key === 'Enter' && !event.shiftKey && !event.altKey && singleLineRef.current) {\n event.preventDefault();\n editor.getRootElement()?.blur();\n return true;\n }\n if (event.key === 'Escape' && blurOnEscapeRef.current) {\n if (skipBlurSaveExternalRef) skipBlurSaveExternalRef.current = true;\n handleCancel();\n editor.getRootElement()?.blur();\n return true;\n }\n return false;\n },\n COMMAND_PRIORITY_HIGH,\n );\n }, [editor, skipBlurSaveExternalRef, handleSave, handleCancel]);\n\n return null;\n};\n","import type {\n ElementTransformer,\n MultilineElementTransformer,\n TextMatchTransformer,\n Transformer,\n} from '@lexical/markdown';\nimport { CHECK_LIST, TRANSFORMERS } from '@lexical/markdown';\nimport {\n $createHorizontalRuleNode,\n $isHorizontalRuleNode,\n HorizontalRuleNode,\n} from '@lexical/react/LexicalHorizontalRuleNode';\n\nimport { $createImageNode, $isImageNode, ImageNode } from './nodes/ImageNode';\nimport { $createMermaidNode, $isMermaidNode, MermaidNode } from './nodes/MermaidNode';\n\n/** Markdown image: `` */\nconst IMAGE: TextMatchTransformer = {\n dependencies: [ImageNode],\n export: (node) => {\n if (!$isImageNode(node)) return null;\n return `})`;\n },\n importRegExp: /!\\[([^\\]]*)\\]\\(([^)]+)\\)/,\n regExp: /!\\[([^\\]]*)\\]\\(([^)]+)\\)$/,\n replace: (textNode, match) => {\n const [, alt = '', src = ''] = match;\n const imageNode = $createImageNode(src, alt);\n textNode.replace(imageNode);\n },\n trigger: ')',\n type: 'text-match',\n};\n\n/** Horizontal rule: `---`, `***`, or `___` */\nconst HORIZONTAL_RULE: ElementTransformer = {\n dependencies: [HorizontalRuleNode],\n export: (node) => {\n return $isHorizontalRuleNode(node) ? '---' : null;\n },\n regExp: /^(---|\\*\\*\\*|___)$/,\n replace: (parentNode) => {\n const node = $createHorizontalRuleNode();\n parentNode.replace(node);\n },\n type: 'element',\n};\n\n/** Fenced mermaid block: ` ```mermaid ... ``` ` → MermaidNode (rendered as diagram) */\nconst MERMAID: MultilineElementTransformer = {\n dependencies: [MermaidNode],\n export: (node) => {\n if (!$isMermaidNode(node)) return null;\n return '```mermaid\\n' + node.getCode() + '\\n```';\n },\n regExpStart: /^[ \\t]*(`{3,})mermaid(?:\\s.*)?$/,\n regExpEnd: {\n optional: true,\n regExp: /^[ \\t]*`{3,}$/,\n },\n replace: (rootNode, _children, _startMatch, _endMatch, linesInBetween) => {\n if (!linesInBetween) return;\n const code = linesInBetween.join('\\n').trim();\n if (code) {\n rootNode.append($createMermaidNode(code));\n }\n },\n handleImportAfterStartMatch: ({\n lines,\n rootNode,\n startLineIndex,\n startMatch,\n }): [boolean, number] => {\n const fence = startMatch[1];\n if (!fence) return [false, startLineIndex];\n const fenceLength = fence.trim().length;\n const endRegex = new RegExp(`^[ \\\\t]*\\`{${fenceLength},}$`);\n\n for (let i = startLineIndex + 1; i < lines.length; i++) {\n if (endRegex.test(lines[i] ?? '')) {\n const code = lines\n .slice(startLineIndex + 1, i)\n .join('\\n')\n .trim();\n if (code) {\n rootNode.append($createMermaidNode(code));\n }\n return [true, i];\n }\n }\n\n // No closing fence — consume remaining lines\n const code = lines\n .slice(startLineIndex + 1)\n .join('\\n')\n .trim();\n if (code) {\n rootNode.append($createMermaidNode(code));\n }\n return [true, lines.length - 1];\n },\n type: 'multiline-element',\n};\n\n/**\n * Our transformers plus Lexical's built-ins; order matters.\n *\n * - MERMAID precedes TRANSFORMERS, so it wins over the generic CODE transformer.\n * - IMAGE precedes LINK, so `` is not parsed as `!` + link.\n */\nexport const CUSTOM_TRANSFORMERS: Transformer[] = [\n IMAGE,\n HORIZONTAL_RULE,\n CHECK_LIST,\n MERMAID,\n ...TRANSFORMERS,\n];\n\n/**\n * No transformers: `singleLine` mode edits plain-text entity names, not markdown.\n *\n * - Inline formatting would corrupt names like `a_b_c` (italics, then `\\_` on export).\n * - Pair with `unescapeMarkdownText` on export (see MarkdownSyncPlugin).\n */\nexport const SINGLE_LINE_TRANSFORMERS: Transformer[] = [];\n\n// GFM tables have no Lexical transformer: fenced on import, unfenced on export.\n\nconst TABLE_FENCE_LANG = '__kbc_table__';\n\nconst isTableLine = (line: string): boolean => {\n const trimmed = line.trim();\n return trimmed.startsWith('|') && trimmed.endsWith('|');\n};\n\nconst CODE_FENCE_REGEX = /^[ \\t]*`{3,}/;\n\n/** Wrap GFM tables in code fences so they survive Lexical's markdown round-trip. */\nexport const preprocessMarkdown = (markdown: string): string => {\n const lines = markdown.split('\\n');\n const result: string[] = [];\n let tableLines: string[] = [];\n let insideCodeFence = false;\n\n const flushTable = () => {\n if (tableLines.length >= 2) {\n result.push(`\\`\\`\\`${TABLE_FENCE_LANG}`);\n result.push(...tableLines);\n result.push('```');\n } else {\n // Single pipe line isn't a table — keep as-is\n result.push(...tableLines);\n }\n tableLines = [];\n };\n\n for (const line of lines) {\n if (CODE_FENCE_REGEX.test(line)) {\n if (tableLines.length > 0) flushTable();\n insideCodeFence = !insideCodeFence;\n result.push(line);\n continue;\n }\n\n if (insideCodeFence) {\n result.push(line);\n continue;\n }\n\n if (isTableLine(line)) {\n tableLines.push(line);\n } else {\n if (tableLines.length > 0) flushTable();\n result.push(line);\n }\n }\n if (tableLines.length > 0) flushTable();\n\n return result.join('\\n');\n};\n\n/** Unwrap code-fenced tables back to raw GFM table markdown. */\nexport const postprocessMarkdown = (markdown: string): string => {\n const regex = new RegExp(`\\`\\`\\`${TABLE_FENCE_LANG}\\\\n([\\\\s\\\\S]*?)\\\\n\\`\\`\\``, 'g');\n return markdown.replace(regex, '$1');\n};\n\n/** Reverses Lexical's export escaping of `* _ ` ~ \\`, for `singleLine` plain-text names. */\nexport const unescapeMarkdownText = (markdown: string): string =>\n markdown.replace(/\\\\([*_`~\\\\])/g, '$1');\n","import { useEffect, useRef } from 'react';\nimport type { Transformer } from '@lexical/markdown';\nimport { $convertFromMarkdownString, $convertToMarkdownString } from '@lexical/markdown';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\n\nimport { useStableCallback } from '../../../hooks/useStableCallback';\nimport {\n CUSTOM_TRANSFORMERS,\n postprocessMarkdown,\n preprocessMarkdown,\n unescapeMarkdownText,\n} from '../transformers';\n\nconst IMPORT_TAG = 'markdown-import';\n\ntype MarkdownSyncPluginProps = {\n value: string;\n editable: boolean;\n onChange?: (markdown: string) => void;\n transformers?: Transformer[];\n /**\n * Plain-text mode: export a bare entity name instead of markdown. Unescapes the punctuation\n * Lexical escapes on export (`\\_` → `_`), so names with underscores don't persist backslashes.\n */\n singleLine?: boolean;\n};\n\nexport const MarkdownSyncPlugin = ({\n value,\n editable,\n onChange,\n transformers = CUSTOM_TRANSFORMERS,\n singleLine = false,\n}: MarkdownSyncPluginProps) => {\n const [editor] = useLexicalComposerContext();\n const lastExportedRef = useRef(value);\n const handleChange = useStableCallback((markdown: string) => onChange?.(markdown));\n const transformersRef = useRef(transformers);\n transformersRef.current = transformers;\n const singleLineRef = useRef(singleLine);\n singleLineRef.current = singleLine;\n\n // Sync editable state — only when it actually changes\n useEffect(() => {\n editor.setEditable(editable);\n }, [editor, editable]);\n\n // Import: external value -> editor state\n useEffect(() => {\n if (value === lastExportedRef.current) return;\n lastExportedRef.current = value;\n\n editor.update(\n () => {\n $convertFromMarkdownString(preprocessMarkdown(value), transformersRef.current);\n },\n { tag: IMPORT_TAG },\n );\n }, [editor, value]);\n\n // Export: editor state -> onChange (subscription)\n useEffect(() => {\n return editor.registerUpdateListener(({ tags }) => {\n if (tags.has(IMPORT_TAG)) return;\n\n editor.getEditorState().read(() => {\n const raw = $convertToMarkdownString(transformersRef.current);\n const markdown = singleLineRef.current\n ? unescapeMarkdownText(raw)\n : postprocessMarkdown(raw);\n if (markdown !== lastExportedRef.current) {\n lastExportedRef.current = markdown;\n handleChange(markdown);\n }\n });\n });\n }, [editor, handleChange]);\n\n return null;\n};\n","import { useRef } from 'react';\nimport {\n $getSelection,\n $setSelection,\n type BaseSelection,\n type ElementFormatType,\n FORMAT_ELEMENT_COMMAND,\n type LexicalEditor,\n} from 'lexical';\n\nimport { DropdownMenu } from '../../../../components/DropdownMenu';\nimport { Tooltip } from '../../../../components/Tooltip';\nimport {\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n ChevronDown,\n type LucideIcon,\n} from '../../../../icons';\nimport { cn } from '../../../../utils';\n\nconst ALIGNMENT_OPTIONS: { value: ElementFormatType; label: string; icon: LucideIcon }[] = [\n { value: 'left', label: 'Left', icon: AlignLeft },\n { value: 'center', label: 'Center', icon: AlignCenter },\n { value: 'right', label: 'Right', icon: AlignRight },\n { value: 'justify', label: 'Justify', icon: AlignJustify },\n];\n\nconst ALIGNMENT_ICONS: Record<string, LucideIcon> = Object.fromEntries(\n ALIGNMENT_OPTIONS.map(({ value, icon }) => [value, icon]),\n);\n\nexport const AlignmentDropdown = ({\n editor,\n alignment,\n}: {\n editor: LexicalEditor;\n alignment: ElementFormatType;\n}) => {\n const savedSelectionRef = useRef<BaseSelection | null>(null);\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n savedSelectionRef.current = selection ? selection.clone() : null;\n });\n }\n };\n\n const handleSelect = (align: ElementFormatType) => {\n // Restore selection and dispatch within the same update so the command sees\n // the restored selection (otherwise dispatchCommand may race with the queued\n // $setSelection and apply the format to the wrong block).\n editor.update(() => {\n if (savedSelectionRef.current) {\n $setSelection(savedSelectionRef.current);\n }\n editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, align);\n });\n };\n\n const CurrentAlignmentIcon = ALIGNMENT_ICONS[alignment] ?? AlignLeft;\n\n return (\n <DropdownMenu onOpenChange={handleOpenChange}>\n <Tooltip tooltip=\"Text alignment\" placement=\"top\" triggerAsChild>\n <DropdownMenu.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n 'tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground',\n 'tw:hover:bg-accent',\n )}\n >\n <CurrentAlignmentIcon className=\"tw:size-4\" />\n <ChevronDown className=\"tw:size-3\" />\n </button>\n </DropdownMenu.Trigger>\n </Tooltip>\n <DropdownMenu.Content align=\"start\" className=\"tw:min-w-32\">\n {ALIGNMENT_OPTIONS.map(({ value, label, icon: IconComp }) => (\n <DropdownMenu.Item\n key={value}\n onSelect={() => handleSelect(value)}\n className={cn(\n 'tw:flex tw:items-center tw:gap-2',\n alignment === value && 'tw:bg-secondary-50 tw:text-secondary-500',\n )}\n >\n <IconComp className=\"tw:size-4\" />\n {label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu>\n );\n};\n","import { useRef } from 'react';\nimport { $createCodeNode } from '@lexical/code';\nimport { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from '@lexical/list';\nimport { $createHeadingNode, $createQuoteNode } from '@lexical/rich-text';\nimport { $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n $setSelection,\n type BaseSelection,\n type LexicalEditor,\n} from 'lexical';\n\nimport { DropdownMenu } from '../../../../components/DropdownMenu';\nimport { Tooltip } from '../../../../components/Tooltip';\nimport {\n ChevronDown,\n Heading1,\n Heading2,\n Heading3,\n List as ListIcon,\n ListOrdered,\n type LucideIcon,\n Quote,\n SquareCode,\n Type,\n} from '../../../../icons';\nimport { cn } from '../../../../utils';\n\nconst BLOCK_TYPE_META = {\n paragraph: { label: 'Normal', icon: Type satisfies LucideIcon, selectable: true },\n h1: { label: 'Heading 1', icon: Heading1 satisfies LucideIcon, selectable: true },\n h2: { label: 'Heading 2', icon: Heading2 satisfies LucideIcon, selectable: true },\n h3: { label: 'Heading 3', icon: Heading3 satisfies LucideIcon, selectable: true },\n bullet: { label: 'Bullet List', icon: ListIcon satisfies LucideIcon, selectable: false },\n number: { label: 'Numbered List', icon: ListOrdered satisfies LucideIcon, selectable: false },\n quote: { label: 'Quote', icon: Quote satisfies LucideIcon, selectable: false },\n code: { label: 'Code Block', icon: SquareCode satisfies LucideIcon, selectable: false },\n} as const;\n\ntype BlockType = keyof typeof BLOCK_TYPE_META;\n\nconst BLOCK_TYPE_OPTIONS = (\n Object.entries(BLOCK_TYPE_META) as [BlockType, (typeof BLOCK_TYPE_META)[BlockType]][]\n)\n .filter(([, meta]) => meta.selectable)\n .map(([value, { label, icon }]) => ({ value, label, icon }));\n\nconst isBlockType = (value: string): value is BlockType =>\n Object.prototype.hasOwnProperty.call(BLOCK_TYPE_META, value);\n\nexport const BlockTypeDropdown = ({\n editor,\n blockType,\n}: {\n editor: LexicalEditor;\n blockType: string;\n}) => {\n const savedSelectionRef = useRef<BaseSelection | null>(null);\n const currentMeta = isBlockType(blockType) ? BLOCK_TYPE_META[blockType] : null;\n const CurrentBlockIcon = currentMeta?.icon ?? Type;\n\n const handleOpenChange = (open: boolean) => {\n if (open) {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n savedSelectionRef.current = selection ? selection.clone() : null;\n });\n }\n };\n\n const handleSelect = (type: BlockType) => {\n editor.update(() => {\n if (savedSelectionRef.current) {\n $setSelection(savedSelectionRef.current);\n }\n\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n\n if (type === 'bullet') {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n return;\n }\n if (type === 'number') {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n return;\n }\n\n const anchorNode = selection.anchor.getNode();\n const element = $getNearestBlockElementAncestorOrThrow(anchorNode);\n\n const newNode =\n type === 'h1' || type === 'h2' || type === 'h3'\n ? $createHeadingNode(type)\n : type === 'quote'\n ? $createQuoteNode()\n : type === 'code'\n ? $createCodeNode()\n : $createParagraphNode();\n\n element.getChildren().forEach((child) => newNode.append(child));\n element.replace(newNode);\n });\n };\n\n return (\n <DropdownMenu onOpenChange={handleOpenChange}>\n <Tooltip tooltip=\"Change block type\" placement=\"top\" triggerAsChild>\n <DropdownMenu.Trigger asChild>\n <button\n type=\"button\"\n className={cn(\n 'tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1.5 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground',\n 'tw:hover:bg-accent',\n )}\n >\n <CurrentBlockIcon className=\"tw:size-4\" />\n {currentMeta?.label ?? 'Normal'}\n <ChevronDown className=\"tw:size-3\" />\n </button>\n </DropdownMenu.Trigger>\n </Tooltip>\n <DropdownMenu.Content align=\"start\" className=\"tw:min-w-40\">\n {BLOCK_TYPE_OPTIONS.map(({ value, label, icon: IconComp }) => (\n <DropdownMenu.Item\n key={value}\n onSelect={() => handleSelect(value)}\n className={cn(\n 'tw:flex tw:items-center tw:gap-2',\n blockType === value && 'tw:bg-secondary-50 tw:text-secondary-500',\n )}\n >\n <IconComp className=\"tw:size-4\" />\n {label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Tooltip } from '../../../../components/Tooltip';\nimport { cn } from '../../../../utils';\n\nexport const ToolbarButton = ({\n active,\n disabled,\n onClick,\n tooltip,\n children,\n className: extraClassName,\n}: {\n active?: boolean;\n disabled?: boolean;\n onClick: () => void;\n tooltip: ReactNode;\n children: ReactNode;\n className?: string;\n}) => (\n <Tooltip tooltip={tooltip} placement=\"top\" triggerAsChild>\n <button\n type=\"button\"\n disabled={disabled}\n onClick={onClick}\n className={cn(\n 'tw:flex tw:h-7 tw:min-w-7 tw:cursor-pointer tw:items-center tw:justify-center tw:rounded tw:border-0 tw:bg-transparent tw:px-1 tw:text-xs tw:text-muted-foreground',\n 'tw:hover:bg-accent tw:disabled:cursor-not-allowed tw:disabled:opacity-30',\n active && 'tw:bg-secondary-100 tw:text-secondary-500',\n extraClassName,\n )}\n >\n {children}\n </button>\n </Tooltip>\n);\n","import { useRef, useState } from 'react';\nimport type { KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { $createLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';\nimport {\n $createTextNode,\n $getSelection,\n $isRangeSelection,\n $setSelection,\n type BaseSelection,\n type LexicalEditor,\n} from 'lexical';\n\nimport { FormGroup } from '../../../../blocks/FormGroup';\nimport { TextInput } from '../../../../blocks/TextInput';\nimport { Button } from '../../../../components/Button';\nimport { ButtonGroup } from '../../../../components/ButtonGroup';\nimport { Label } from '../../../../components/Label';\nimport { Link as LinkIcon } from '../../../../icons';\n\nimport { ToolbarButton } from './ToolbarButton';\n\nconst insertLink = (\n editor: LexicalEditor,\n url: string,\n label: string,\n savedSelection: BaseSelection | null,\n) => {\n editor.update(() => {\n $setSelection(savedSelection);\n const selection = $getSelection();\n\n if ($isRangeSelection(selection)) {\n const selectedText = selection.getTextContent();\n if (selectedText && label === selectedText) {\n editor.dispatchCommand(TOGGLE_LINK_COMMAND, url);\n return;\n }\n }\n\n const linkNode = $createLinkNode(url);\n const textNode = $createTextNode(label || url);\n linkNode.append(textNode);\n\n if ($isRangeSelection(selection)) {\n selection.insertNodes([linkNode]);\n }\n });\n};\n\nexport const LinkPanel = ({ editor, isLink }: { editor: LexicalEditor; isLink: boolean }) => {\n const [open, setOpen] = useState(false);\n const [url, setUrl] = useState('');\n const [label, setLabel] = useState('');\n const savedSelectionRef = useRef<BaseSelection | null>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n\n const handleOpen = () => {\n editor.getEditorState().read(() => {\n const selection = $getSelection();\n savedSelectionRef.current = selection ? selection.clone() : null;\n\n if ($isRangeSelection(selection)) {\n const text = selection.getTextContent();\n if (text) setLabel(text);\n }\n });\n setOpen(true);\n };\n\n const handleClose = () => {\n setOpen(false);\n setUrl('');\n setLabel('');\n savedSelectionRef.current = null;\n editor.focus();\n };\n\n const handleSubmit = () => {\n const trimmedUrl = url.trim();\n if (!trimmedUrl) return;\n\n insertLink(editor, trimmedUrl, label.trim(), savedSelectionRef.current);\n handleClose();\n };\n\n const handleKeyDown = (e: ReactKeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleSubmit();\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n handleClose();\n }\n };\n\n if (isLink) {\n return (\n <ToolbarButton\n active\n onClick={() => editor.dispatchCommand(TOGGLE_LINK_COMMAND, null)}\n tooltip=\"Remove Link\"\n >\n <LinkIcon className=\"tw:size-4\" />\n </ToolbarButton>\n );\n }\n\n return (\n <div className=\"tw:relative\">\n <ToolbarButton active={open} onClick={handleOpen} tooltip=\"Insert Link\">\n <LinkIcon className=\"tw:size-4\" />\n </ToolbarButton>\n {open && (\n <div\n ref={panelRef}\n className=\"tw:absolute tw:left-0 tw:top-full tw:z-50 tw:mt-1 tw:w-80 tw:rounded-md tw:border tw:border-border tw:bg-popover tw:p-3 tw:text-popover-foreground tw:shadow-lg\"\n >\n <div className=\"tw:flex tw:flex-col tw:gap-2\">\n <FormGroup>\n <Label htmlFor=\"link-label\" className=\"tw:mb-1 tw:text-xs\">\n Label\n </Label>\n <TextInput\n id=\"link-label\"\n autoFocus\n placeholder=\"Link text\"\n value={label}\n onValueChange={setLabel}\n onKeyDown={handleKeyDown}\n variant=\"secondary\"\n />\n </FormGroup>\n <FormGroup>\n <Label htmlFor=\"link-url\" className=\"tw:mb-1 tw:text-xs\">\n URL\n </Label>\n <TextInput\n id=\"link-url\"\n placeholder=\"https://…\"\n value={url}\n onValueChange={setUrl}\n onKeyDown={handleKeyDown}\n variant=\"secondary\"\n />\n </FormGroup>\n <ButtonGroup>\n <Button size=\"small\" variant=\"outline\" onClick={handleClose}>\n Cancel\n </Button>\n <Button size=\"small\" onClick={handleSubmit} disabled={!url.trim()}>\n Add link\n </Button>\n </ButtonGroup>\n </div>\n </div>\n )}\n </div>\n );\n};\n","export const ToolbarDivider = () => <div className=\"tw:mx-0.5 tw:h-5 tw:w-px tw:bg-border\" />;\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { $createCodeNode, $isCodeNode } from '@lexical/code';\nimport { $isLinkNode } from '@lexical/link';\nimport {\n $isListNode,\n INSERT_ORDERED_LIST_COMMAND,\n INSERT_UNORDERED_LIST_COMMAND,\n REMOVE_LIST_COMMAND,\n} from '@lexical/list';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport { $createQuoteNode, $isHeadingNode, $isQuoteNode } from '@lexical/rich-text';\nimport { $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n type ElementFormatType,\n FORMAT_TEXT_COMMAND,\n} from 'lexical';\n\nimport {\n Bold,\n Code,\n Italic,\n List as ListIcon,\n ListOrdered,\n Quote,\n SquareCode,\n Strikethrough,\n Underline,\n} from '../../../icons';\n\nimport { AlignmentDropdown } from './toolbar/AlignmentDropdown';\nimport { BlockTypeDropdown } from './toolbar/BlockTypeDropdown';\nimport { LinkPanel } from './toolbar/LinkPanel';\nimport { ToolbarButton } from './toolbar/ToolbarButton';\nimport { ToolbarDivider } from './toolbar/ToolbarDivider';\n\nconst ELEMENT_FORMAT_TYPES = ['left', 'center', 'right', 'justify', 'start', 'end', ''] as const;\n\nconst isElementFormatType = (value: string): value is ElementFormatType =>\n (ELEMENT_FORMAT_TYPES as readonly string[]).includes(value);\n\nconst toElementFormatType = (value: string): ElementFormatType =>\n isElementFormatType(value) ? value : 'left';\n\nexport const ToolbarPlugin = () => {\n const [editor] = useLexicalComposerContext();\n const [isBold, setIsBold] = useState(false);\n const [isItalic, setIsItalic] = useState(false);\n const [isUnderline, setIsUnderline] = useState(false);\n const [isStrikethrough, setIsStrikethrough] = useState(false);\n const [isCode, setIsCode] = useState(false);\n const [isLink, setIsLink] = useState(false);\n const [blockType, setBlockType] = useState<string>('paragraph');\n const [alignment, setAlignment] = useState<ElementFormatType>('left');\n const [isVisible, setIsVisible] = useState(false);\n const [position, setPosition] = useState<{ top: number; left: number } | null>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const isMouseDownRef = useRef(false);\n const hasSelectionRef = useRef(false);\n\n const updatePosition = useCallback(() => {\n const nativeSelection = window.getSelection();\n if (!nativeSelection || nativeSelection.rangeCount === 0) return;\n const range = nativeSelection.getRangeAt(0);\n const rect = range.getBoundingClientRect();\n if (rect.width > 0) {\n const toolbarWidth = toolbarRef.current?.offsetWidth ?? 300;\n setPosition({\n top: rect.top + window.scrollY - 8,\n left: Math.max(8, rect.left + window.scrollX + rect.width / 2 - toolbarWidth / 2),\n });\n }\n }, []);\n\n useEffect(() => {\n const handleMouseDown = () => {\n isMouseDownRef.current = true;\n };\n const handleMouseUp = () => {\n isMouseDownRef.current = false;\n if (hasSelectionRef.current) {\n setIsVisible(true);\n }\n };\n document.addEventListener('mousedown', handleMouseDown);\n document.addEventListener('mouseup', handleMouseUp);\n return () => {\n document.removeEventListener('mousedown', handleMouseDown);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n }, []);\n\n const updateToolbar = useCallback(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) {\n hasSelectionRef.current = false;\n setIsVisible(false);\n return;\n }\n\n const hasSelection = !selection.isCollapsed() && selection.getTextContent().length > 0;\n hasSelectionRef.current = hasSelection;\n\n if (!hasSelection) {\n setIsVisible(false);\n } else if (!isMouseDownRef.current) {\n setIsVisible(true);\n }\n\n if (hasSelection) {\n updatePosition();\n }\n\n setIsBold(selection.hasFormat('bold'));\n setIsItalic(selection.hasFormat('italic'));\n setIsUnderline(selection.hasFormat('underline'));\n setIsStrikethrough(selection.hasFormat('strikethrough'));\n setIsCode(selection.hasFormat('code'));\n\n const node = selection.anchor.getNode();\n const parent = node.getParent();\n setIsLink($isLinkNode(parent) || $isLinkNode(node));\n\n const blockElement = $getNearestBlockElementAncestorOrThrow(node);\n\n if ($isListNode(blockElement)) {\n const listType = blockElement.getListType();\n setBlockType(listType === 'number' ? 'number' : 'bullet');\n } else if ($isHeadingNode(blockElement)) {\n setBlockType(blockElement.getTag());\n } else if ($isCodeNode(blockElement)) {\n setBlockType('code');\n } else if ($isQuoteNode(blockElement)) {\n setBlockType('quote');\n } else {\n setBlockType('paragraph');\n }\n\n setAlignment(toElementFormatType(blockElement.getFormatType()));\n }, [updatePosition]);\n\n useEffect(() => {\n const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {\n editorState.read(() => {\n updateToolbar();\n });\n });\n\n return () => {\n unregisterUpdate();\n };\n }, [editor, updateToolbar]);\n\n if (!isVisible || !position) return null;\n\n return createPortal(\n <div\n ref={toolbarRef}\n role=\"toolbar\"\n aria-label=\"Formatting options\"\n onMouseDown={(e) => e.preventDefault()}\n style={{ top: position.top, left: position.left }}\n className=\"tw:absolute tw:z-[1060] tw:flex tw:-translate-y-full tw:items-center tw:gap-0.5 tw:rounded-lg tw:border tw:border-border tw:bg-popover tw:px-1.5 tw:py-1 tw:text-popover-foreground tw:shadow-lg\"\n >\n <BlockTypeDropdown editor={editor} blockType={blockType} />\n\n <ToolbarDivider />\n\n <ToolbarButton\n active={isBold}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold')}\n tooltip=\"Bold (Ctrl+B)\"\n >\n <Bold className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isItalic}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic')}\n tooltip=\"Italic (Ctrl+I)\"\n >\n <Italic className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isUnderline}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline')}\n tooltip=\"Underline (Ctrl+U)\"\n >\n <Underline className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isStrikethrough}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough')}\n tooltip=\"Strikethrough\"\n >\n <Strikethrough className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={isCode}\n onClick={() => editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'code')}\n tooltip=\"Inline Code\"\n >\n <Code className=\"tw:size-4\" />\n </ToolbarButton>\n\n <ToolbarDivider />\n\n <LinkPanel editor={editor} isLink={isLink} />\n\n <ToolbarDivider />\n\n <ToolbarButton\n active={blockType === 'bullet'}\n onClick={() => {\n if (blockType === 'bullet') {\n editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n } else {\n editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n }\n }}\n tooltip=\"Bullet List\"\n >\n <ListIcon className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={blockType === 'number'}\n onClick={() => {\n if (blockType === 'number') {\n editor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n } else {\n editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n }\n }}\n tooltip=\"Numbered List\"\n >\n <ListOrdered className=\"tw:size-4\" />\n </ToolbarButton>\n\n <ToolbarDivider />\n\n <AlignmentDropdown editor={editor} alignment={alignment} />\n\n <ToolbarDivider />\n\n <ToolbarButton\n active={blockType === 'quote'}\n onClick={() => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchorNode = selection.anchor.getNode();\n const element = $getNearestBlockElementAncestorOrThrow(anchorNode);\n const newNode = blockType === 'quote' ? $createParagraphNode() : $createQuoteNode();\n element.getChildren().forEach((child) => newNode.append(child));\n element.replace(newNode);\n });\n }}\n tooltip=\"Quote\"\n >\n <Quote className=\"tw:size-4\" />\n </ToolbarButton>\n <ToolbarButton\n active={blockType === 'code'}\n onClick={() => {\n editor.update(() => {\n const selection = $getSelection();\n if (!$isRangeSelection(selection)) return;\n const anchorNode = selection.anchor.getNode();\n const element = $getNearestBlockElementAncestorOrThrow(anchorNode);\n const newNode = blockType === 'code' ? $createParagraphNode() : $createCodeNode();\n element.getChildren().forEach((child) => newNode.append(child));\n element.replace(newNode);\n });\n }}\n tooltip=\"Code Block\"\n >\n <SquareCode className=\"tw:size-4\" />\n </ToolbarButton>\n </div>,\n document.body,\n );\n};\n","import type { EditorThemeClasses } from 'lexical';\n\n/**\n * Lexical editor theme — maps node types to CSS classes.\n * The editor container uses `tw:prose` so semantic elements (headings, lists, blockquotes, etc.)\n * are styled by Tailwind Typography. We only need explicit classes for text formatting\n * (bold, italic, etc.) because Lexical renders those as `<span>` elements.\n */\nexport const editorTheme: EditorThemeClasses = {\n link: 'tw:cursor-pointer tw:!text-primary tw:underline',\n text: {\n bold: 'tw:font-bold',\n italic: 'tw:italic',\n strikethrough: 'tw:line-through',\n underline: 'tw:underline',\n code: 'tw:rounded tw:bg-muted tw:px-1 tw:py-0.5 tw:font-mono tw:text-[0.85em]',\n },\n list: {\n ol: 'tw:!list-decimal',\n ul: 'tw:!list-disc',\n checklist: 'tw:!list-none tw:!pl-0',\n listitemChecked: [\n 'tw:relative tw:!pl-6 tw:list-none tw:outline-hidden tw:line-through tw:text-muted-foreground',\n 'tw:before:content-[\"\"] tw:before:absolute tw:before:left-0 tw:before:top-[3px]',\n 'tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid',\n 'tw:before:bg-primary tw:before:border-primary tw:before:cursor-pointer',\n 'tw:after:content-[\"\"] tw:after:absolute tw:after:left-[5.5px] tw:after:top-[5.5px]',\n 'tw:after:w-1 tw:after:h-2 tw:after:border-primary-foreground tw:after:border-solid',\n 'tw:after:border-r-[1.5px] tw:after:border-b-[1.5px] tw:after:border-t-0 tw:after:border-l-0',\n 'tw:after:rotate-45',\n ].join(' '),\n listitemUnchecked: [\n 'tw:relative tw:!pl-6 tw:list-none tw:outline-hidden',\n 'tw:before:content-[\"\"] tw:before:absolute tw:before:left-0 tw:before:top-[3px]',\n 'tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid',\n 'tw:before:border-input tw:before:bg-background tw:before:cursor-pointer',\n ].join(' '),\n },\n};\n","import { useRef, useState } from 'react';\nimport type { FocusEvent, ReactNode } from 'react';\nimport { CodeNode } from '@lexical/code';\nimport { LinkNode } from '@lexical/link';\nimport { ListItemNode, ListNode } from '@lexical/list';\nimport { $convertFromMarkdownString } from '@lexical/markdown';\nimport { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';\nimport { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';\nimport { ClickableLinkPlugin } from '@lexical/react/LexicalClickableLinkPlugin';\nimport type { InitialConfigType } from '@lexical/react/LexicalComposer';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';\nimport { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';\nimport { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';\nimport { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';\nimport { ListPlugin } from '@lexical/react/LexicalListPlugin';\nimport { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';\nimport { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';\nimport { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\n\nimport { cn } from '../../utils';\n\nimport { ImageNode } from './nodes/ImageNode';\nimport { MermaidNode } from './nodes/MermaidNode';\nimport { ImagePastePlugin } from './plugins/ImagePastePlugin';\nimport { KeyboardPlugin } from './plugins/KeyboardPlugin';\nimport { MarkdownSyncPlugin } from './plugins/MarkdownSyncPlugin';\nimport { ToolbarPlugin } from './plugins/ToolbarPlugin';\nimport { ImageRendererProvider } from './context';\nimport { editorTheme } from './theme';\nimport { CUSTOM_TRANSFORMERS, preprocessMarkdown, SINGLE_LINE_TRANSFORMERS } from './transformers';\n\nexport type MarkdownEditorProps = {\n /** Markdown string (controlled) */\n value: string;\n onChange?: (markdown: string) => void;\n /** Permanent view-only (e.g. no edit permission). Hides the toolbar. */\n readOnly?: boolean;\n /** Temporary block (e.g. save in flight). Behaves like `readOnly`. */\n disabled?: boolean;\n placeholder?: string;\n autoFocus?: boolean;\n /** Invoked on Cmd/Ctrl+Enter. */\n onSave?: () => void;\n /**\n * Escape in inline-edit mode (`singleLine || saveOnBlur`).\n * Callers reset `value` to the last-committed state here.\n */\n onCancel?: () => void;\n /** The resolved URL becomes the image src in the markdown. */\n onImageUpload?: (file: File) => Promise<{ url: string }>;\n className?: string;\n imageRenderer?: (props: { src: string; alt: string }) => ReactNode;\n showToolbar?: boolean;\n /**\n * No prose wrapper, min-height or padding — blends into surrounding text for inline editing.\n * Set typography via `className`.\n */\n compact?: boolean;\n /** Calls `onSave` when focus leaves the editor (the toolbar doesn't count). */\n saveOnBlur?: boolean;\n /**\n * No block-level markdown; Enter blurs the editor, Shift+Enter inserts a soft break.\n * Use for editable titles.\n */\n singleLine?: boolean;\n /** Clamps to 2 lines with an ellipsis while not focused; focus shows everything. */\n clampDisplay?: boolean;\n /**\n * Minimum height in lines; `0` removes the floor. Default ~4 lines.\n * Ignored in `compact` mode.\n */\n minRows?: number;\n};\n\nconst EDITOR_NODES = [\n ImageNode,\n MermaidNode,\n HeadingNode,\n QuoteNode,\n ListNode,\n ListItemNode,\n CodeNode,\n LinkNode,\n HorizontalRuleNode,\n];\n\nexport const MarkdownEditor = ({\n value,\n onChange,\n readOnly = false,\n placeholder,\n autoFocus = false,\n disabled = false,\n onSave,\n onCancel,\n onImageUpload,\n className,\n imageRenderer,\n showToolbar = false,\n compact = false,\n saveOnBlur = false,\n singleLine = false,\n clampDisplay = false,\n minRows,\n}: MarkdownEditorProps) => {\n const editable = !readOnly && !disabled;\n const transformers = singleLine ? SINGLE_LINE_TRANSFORMERS : CUSTOM_TRANSFORMERS;\n const useDefaultMinHeight = !compact && minRows === undefined;\n const customMinHeight =\n !compact && minRows !== undefined ? { minHeight: `${minRows * 1.75}em` } : undefined;\n\n // Lexical reads editorState only on first render; later prop changes are applied by MarkdownSyncPlugin.\n const [initialConfig] = useState<InitialConfigType>(() => ({\n namespace: 'MarkdownEditor',\n theme: editorTheme,\n nodes: EDITOR_NODES,\n onError: (error: Error) => {\n console.error('[MarkdownEditor] uncaught editor error', error);\n },\n editable,\n editorState: () => {\n $convertFromMarkdownString(preprocessMarkdown(value), transformers);\n },\n }));\n\n // Set by KeyboardPlugin before its Escape blur, so the blur doesn't commit the reverted value.\n const skipBlurSaveRef = useRef(false);\n\n const handleBlur =\n saveOnBlur && onSave\n ? (event: FocusEvent<HTMLDivElement>) => {\n if (skipBlurSaveRef.current) {\n skipBlurSaveRef.current = false;\n return;\n }\n // Focus moving into the toolbar doesn't count.\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {\n onSave();\n }\n }\n : undefined;\n\n return (\n <LexicalComposer initialConfig={initialConfig}>\n <ImageRendererProvider value={imageRenderer ?? null}>\n <div\n className={cn(\n !compact && 'tw:prose',\n // Without `tw:prose`, <p> gets the browser's `margin: 1em 0`; space only between paragraphs.\n compact && 'tw:[&_p]:m-0 tw:[&_p+p]:mt-2',\n // No fade: CSS can't gate one on overflow.\n clampDisplay && 'tw:[&:not(:focus-within)]:line-clamp-2',\n className,\n )}\n onBlur={handleBlur}\n >\n {showToolbar && editable && <ToolbarPlugin />}\n <div\n className={cn(\n 'tw:relative tw:rounded-md tw:transition-colors',\n // Compact: the negative margin cancels the padding, so the text stays aligned with static text.\n compact ? 'tw:px-1.5 tw:py-0.5 tw:-mx-1.5 tw:-my-0.5' : 'tw:p-2',\n editable &&\n 'tw:cursor-text tw:hover:bg-muted tw:focus-within:ring-2 tw:focus-within:ring-ring/40',\n )}\n >\n <RichTextPlugin\n contentEditable={\n <ContentEditable\n className={cn('tw:outline-hidden', useDefaultMinHeight && 'tw:min-h-[100px]')}\n style={customMinHeight}\n aria-placeholder={placeholder ?? ''}\n placeholder={\n placeholder ? (\n <div\n className={cn(\n 'tw:pointer-events-none tw:absolute tw:select-none tw:text-muted-foreground',\n compact\n ? 'tw:left-1.5 tw:top-0.5'\n : 'tw:left-2 tw:top-[calc(0.5rem+0.35em)]',\n )}\n >\n {placeholder}\n </div>\n ) : (\n <div />\n )\n }\n />\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </div>\n <HistoryPlugin />\n <LinkPlugin />\n <ClickableLinkPlugin newTab />\n {!singleLine && <ListPlugin />}\n {!singleLine && <CheckListPlugin />}\n {!singleLine && <HorizontalRulePlugin />}\n <TabIndentationPlugin />\n <MarkdownShortcutPlugin transformers={transformers} />\n <MarkdownSyncPlugin\n value={value}\n editable={editable}\n onChange={onChange}\n transformers={transformers}\n singleLine={singleLine}\n />\n <ImagePastePlugin onImageUpload={onImageUpload} />\n <KeyboardPlugin\n onSave={onSave}\n onCancel={onCancel}\n singleLine={singleLine}\n blurOnEscape={singleLine || saveOnBlur}\n skipBlurSaveRef={skipBlurSaveRef}\n />\n {autoFocus && <AutoFocusPlugin />}\n </div>\n </ImageRendererProvider>\n </LexicalComposer>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAM,uBAAuB,cAAoC,IAAI;AAErE,MAAa,wBAAwB;AAErC,MAAa,yBAA+C,IAAI,oBAAoB;;;ACPpF,MAAM,iBAAiB,QAAgB,IAAI,WAAW,qBAAqB;AAE3E,MAAa,sBAAsB,EAAE,KAAK,UAAwC;CAChF,MAAM,WAAW,iBAAiB;CAElC,IAAI,cAAc,GAAG,GACnB,OACE,oBAAC,QAAD;EAAM,WAAU;EAAsH,UAAA;CAEhI,CAAA;CAIV,IAAI,UAAU,OAAO,oBAAA,YAAA,EAAA,UAAG,SAAS;EAAE;EAAK;CAAI,CAAC,EAAI,CAAA;CACjD,OAAO,oBAAC,OAAD;EAAU;EAAU;CAAM,CAAA;AACnC;;;ACAA,IAAa,YAAb,MAAa,kBAAkB,cAAyB;CACtD;CACA;CAEA,OAAgB,UAAkB;EAChC,OAAO;CACT;CAEA,OAAgB,MAAM,MAA4B;EAChD,OAAO,IAAI,UAAU,KAAK,OAAO,KAAK,WAAW,KAAK,KAAK;CAC7D;CAEA,YAAY,KAAa,SAAiB,KAAe;EACvD,MAAM,GAAG;EACT,KAAK,QAAQ;EACb,KAAK,YAAY;CACnB;CAEA,SAAiB;EACf,OAAO,KAAK;CACd;CAEA,SAAiB;EACf,OAAO,KAAK;CACd;CAEA,OAAO,KAAmB;EACxB,MAAM,WAAW,KAAK,YAAY;EAClC,SAAS,QAAQ;CACnB;CAEA,OAAO,SAAuB;EAC5B,MAAM,WAAW,KAAK,YAAY;EAClC,SAAS,YAAY;CACvB;CAEA,UAAmB,QAAmC;EACpD,MAAM,OAAO,SAAS,cAAc,MAAM;EAC1C,MAAM,YAAY,OAAO,MAAM;EAC/B,IAAI,OAAO,cAAc,UACvB,KAAK,YAAY;EAEnB,OAAO;CACT;CAEA,YAA8B;EAC5B,OAAO;CACT;CAEA,WAA+B;EAC7B,OAAO,oBAAC,oBAAD;GAAoB,KAAK,KAAK;GAAO,KAAK,KAAK;EAAY,CAAA;CACpE;CAEA,WAA6B;EAC3B,OAAO;CACT;CAEA,OAAgB,WAAW,gBAAgD;EACzE,OAAO,iBAAiB,eAAe,KAAK,eAAe,OAAO;CACpE;CAEA,aAA2C;EACzC,OAAO;GACL,MAAM;GACN,SAAS;GACT,KAAK,KAAK;GACV,SAAS,KAAK;EAChB;CACF;CAEA,YAAsC;EACpC,MAAM,UAAU,SAAS,cAAc,KAAK;EAC5C,QAAQ,aAAa,OAAO,KAAK,KAAK;EACtC,QAAQ,aAAa,OAAO,KAAK,SAAS;EAC1C,OAAO,EAAE,QAAQ;CACnB;CAEA,OAAgB,YAAqC;EACnD,OAAO,EACL,YAAY;GACV,aAAa,YAAyB;IACpC,MAAM,MAAM,QAAQ,aAAa,KAAK,KAAK;IAC3C,MAAM,MAAM,QAAQ,aAAa,KAAK,KAAK;IAC3C,OAAO,EAAE,MAAM,iBAAiB,KAAK,GAAG,EAAE;GAC5C;GACA,UAAU;EACZ,GACF;CACF;AACF;AAEA,MAAa,oBAAoB,KAAa,YAA+B;CAC3E,OAAO,IAAI,UAAU,KAAK,OAAO;AACnC;AAEA,MAAa,gBAAgB,SAA4D;CACvF,OAAO,gBAAgB;AACzB;;;AC9GA,MAAM,iBAAiB,WACrB,OAAO,+BAAgD,CAAA,MAAA,MAAA,EAAA,sBAAA,CAAA,CAAC,MACrD,OAAO,EAAE,SAAS,EAAE,eAAe,KACnC,UAAmB;CAGlB,QAAQ,MAAM,wDAAwD,KAAK;CAC3E,OAAO,EACL,UAAU,EAAE,WACV,oBAAC,OAAD,EAAA,UACE,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA,EACf,CAAA,EAET;AACF,CACF,CACF;AAEA,MAAa,wBAAwB,EAAE,WAA6B;CAClE,OACE,oBAAC,UAAD;EACE,UACE,oBAAC,OAAD;GAAK,WAAU;GACb,UAAA,oBAAC,UAAD,EAAU,WAAU,UAAW,CAAA;EAC5B,CAAA;EAGP,UAAA,oBAAC,gBAAD,EAAsB,KAAO,CAAA;CACrB,CAAA;AAEd;;;ACzBA,IAAa,cAAb,MAAa,oBAAoB,cAAyB;CACxD;CAEA,OAAgB,UAAkB;EAChC,OAAO;CACT;CAEA,OAAgB,MAAM,MAAgC;EACpD,OAAO,IAAI,YAAY,KAAK,QAAQ,KAAK,KAAK;CAChD;CAEA,YAAY,MAAc,KAAe;EACvC,MAAM,GAAG;EACT,KAAK,SAAS;CAChB;CAEA,UAAkB;EAChB,OAAO,KAAK;CACd;CAEA,QAAQ,MAAoB;EAC1B,MAAM,WAAW,KAAK,YAAY;EAClC,SAAS,SAAS;CACpB;CAEA,YAAkC;EAChC,MAAM,MAAM,SAAS,cAAc,KAAK;EACxC,IAAI,aAAa,wBAAwB,MAAM;EAC/C,OAAO;CACT;CAEA,YAA8B;EAC5B,OAAO;CACT;CAEA,WAA+B;EAC7B,OAAO,oBAAC,sBAAD,EAAsB,MAAM,KAAK,OAAS,CAAA;CACnD;CAEA,WAA6B;EAC3B,OAAO;CACT;CAEA,OAAgB,WAAW,gBAAoD;EAC7E,OAAO,mBAAmB,eAAe,IAAI;CAC/C;CAEA,aAA6C;EAC3C,OAAO;GACL,MAAM;GACN,SAAS;GACT,MAAM,KAAK;EACb;CACF;AACF;AAEA,MAAa,sBAAsB,SAA8B;CAC/D,OAAO,IAAI,YAAY,IAAI;AAC7B;AAEA,MAAa,kBAAkB,SAA8D;CAC3F,OAAO,gBAAgB;AACzB;;;ACxDA,MAAM,uBAAuB;CAC3B;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,iBAAiB;AAEvB,MAAM,qBAAqB;AAE3B,MAAM,8BAAsC;CAC1C,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAChE,OAAO,OAAO,WAAW;CAE3B,OAAO,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5D;AAEA,MAAM,uBAAuB,SAAiB,qBAAqB,SAAS,IAAI;AAEhF,MAAM,iCAAiC,iBAA8C;CACnF,IAAI,CAAC,cAAc,OAAO,CAAC;CAE3B,IAAI,aAAa,MAAM,SAAS,GAAG;EACjC,MAAM,QAAgB,CAAC;EACvB,KAAK,MAAM,QAAQ,aAAa,OAC9B,IAAI,KAAK,SAAS,UAAU,oBAAoB,KAAK,IAAI,GAAG;GAC1D,MAAM,OAAO,KAAK,UAAU;GAC5B,IAAI,MAAM,MAAM,KAAK,IAAI;EAC3B;EAEF,IAAI,MAAM,SAAS,GAAG,OAAO;CAC/B;CAEA,OAAO,MAAM,KAAK,aAAa,KAAK,CAAC,CAAC,QAAQ,SAAS,oBAAoB,KAAK,IAAI,CAAC;AACvF;AAEA,MAAM,qBAAqB,SAAiB,KAAK,QAAQ,YAAY,EAAE;AAMvE,MAAa,oBAAoB,EAAE,oBAA2C;CAC5E,MAAM,CAAC,UAAU,0BAA0B;CAI3C,MAAM,kBAAkB,iBAAiB;CACzC,MAAM,cAAc,mBAAmB,SAAe,gBAAgB,IAAI,CAAC;CAE3E,gBAAgB;EACd,MAAM,cAAc,SAAe;GACjC,IAAI,CAAC,iBAAiB;GAEtB,IAAI,KAAK,OAAO,gBAAgB;IAC9B,MAAM,MAAM,UAAU,KAAK,KAAK,uCAAuC;IACvE;GACF;GAIA,IAAI,UAA0B;GAE9B,OAAO,aAAa;IAClB,MAAM,kBAAkB,iBACtB,GAAG,qBAAqB,sBAAsB,KAC9C,kBACF;IACA,aAAa,CAAC,eAAe,CAAC;IAC9B,UAAU,gBAAgB,OAAO;GACnC,CAAC;GAED,IAAI,CAAC,SAAS;GACd,MAAM,cAAuB;GAE7B,YAAY,IAAI,CAAC,EACb,MAAM,EAAE,UAAU;IAClB,OAAO,aAAa;KAClB,MAAM,OAAO,cAAc,WAAW;KACtC,IAAI,aAAa,IAAI,GAAG;MACtB,MAAM,UAAU,kBAAkB,KAAK,KAAK,QAAQ,YAAY,EAAE,KAAK,OAAO;MAC9E,KAAK,OAAO,GAAG;MACf,KAAK,OAAO,OAAO;KACrB;IACF,CAAC;GACH,CAAC,CAAC,CACD,OAAO,UAAmB;IACzB,QAAQ,MAAM,wCAAwC,KAAK;IAC3D,MAAM,MAAM,qBAAqB,KAAK,KAAK,qBAAqB;IAChE,OAAO,aAAa;KAClB,MAAM,OAAO,cAAc,WAAW;KACtC,IAAI,MAAM,KAAK,OAAO;IACxB,CAAC;GACH,CAAC;EACL;EAEA,MAAM,cAAc,OAAO,gBACzB,gBACC,UAAU;GACT,IAAI,CAAC,iBAAiB,OAAO;GAC7B,IAAI,EAAE,iBAAiB,iBAAiB,OAAO;GAC/C,MAAM,QAAQ,8BAA8B,MAAM,aAAa;GAC/D,IAAI,MAAM,WAAW,GAAG,OAAO;GAE/B,MAAM,eAAe;GAErB,QAAQ,QAAQ,CAAC,CAAC,WAAW,MAAM,QAAQ,UAAU,CAAC;GACtD,OAAO;EACT,GACA,yBACF;EAEA,MAAM,aAAa,OAAO,gBACxB,eACC,UAAqB;GACpB,IAAI,CAAC,iBAAiB,OAAO;GAC7B,MAAM,QAAQ,8BAA8B,MAAM,YAAY;GAC9D,IAAI,MAAM,WAAW,GAAG,OAAO;GAE/B,MAAM,eAAe;GAErB,QAAQ,QAAQ,CAAC,CAAC,WAAW,MAAM,QAAQ,UAAU,CAAC;GACtD,OAAO;EACT,GACA,yBACF;EAEA,aAAa;GACX,YAAY;GACZ,WAAW;EACb;CACF,GAAG;EAAC;EAAQ;EAAiB;CAAW,CAAC;CAEzC,OAAO;AACT;;;AChIA,MAAa,kBAAkB,EAC7B,QACA,UACA,YACA,cACA,sBACyB;CACzB,MAAM,CAAC,UAAU,0BAA0B;CAC3C,MAAM,aAAa,wBAAwB,SAAS,CAAC;CACrD,MAAM,eAAe,wBAAwB,WAAW,CAAC;CACzD,MAAM,gBAAgB,OAAO,UAAU;CACvC,cAAc,UAAU;CACxB,MAAM,kBAAkB,OAAO,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,0BAA0B;CAEhC,gBAAgB;EACd,OAAO,OAAO,gBACZ,mBACC,UAAyB;GACxB,IAAI,MAAM,QAAQ,YAAY,MAAM,WAAW,MAAM,UAAU;IAC7D,MAAM,eAAe;IACrB,WAAW;IACX,OAAO;GACT;GACA,IAAI,MAAM,QAAQ,WAAW,CAAC,MAAM,YAAY,CAAC,MAAM,UAAU,cAAc,SAAS;IACtF,MAAM,eAAe;IACrB,OAAO,eAAe,CAAC,EAAE,KAAK;IAC9B,OAAO;GACT;GACA,IAAI,MAAM,QAAQ,YAAY,gBAAgB,SAAS;IACrD,IAAI,yBAAyB,wBAAwB,UAAU;IAC/D,aAAa;IACb,OAAO,eAAe,CAAC,EAAE,KAAK;IAC9B,OAAO;GACT;GACA,OAAO;EACT,GACA,qBACF;CACF,GAAG;EAAC;EAAQ;EAAyB;EAAY;CAAY,CAAC;CAE9D,OAAO;AACT;;;;;;;AC4CA,MAAa,sBAAqC;CAChD;EA7FA,cAAc,CAAC,SAAS;EACxB,SAAS,SAAS;GAChB,IAAI,CAAC,aAAa,IAAI,GAAG,OAAO;GAChC,OAAO,KAAK,KAAK,OAAO,EAAE,IAAI,KAAK,OAAO,EAAE;EAC9C;EACA,cAAc;EACd,QAAQ;EACR,UAAU,UAAU,UAAU;GAC5B,MAAM,GAAG,MAAM,IAAI,MAAM,MAAM;GAC/B,MAAM,YAAY,iBAAiB,KAAK,GAAG;GAC3C,SAAS,QAAQ,SAAS;EAC5B;EACA,SAAS;EACT,MAAM;CAgFN;CACA;EA5EA,cAAc,CAAC,kBAAkB;EACjC,SAAS,SAAS;GAChB,OAAO,sBAAsB,IAAI,IAAI,QAAQ;EAC/C;EACA,QAAQ;EACR,UAAU,eAAe;GACvB,MAAM,OAAO,0BAA0B;GACvC,WAAW,QAAQ,IAAI;EACzB;EACA,MAAM;CAmEN;CACA;CACA;EAhEA,cAAc,CAAC,WAAW;EAC1B,SAAS,SAAS;GAChB,IAAI,CAAC,eAAe,IAAI,GAAG,OAAO;GAClC,OAAO,iBAAiB,KAAK,QAAQ,IAAI;EAC3C;EACA,aAAa;EACb,WAAW;GACT,UAAU;GACV,QAAQ;EACV;EACA,UAAU,UAAU,WAAW,aAAa,WAAW,mBAAmB;GACxE,IAAI,CAAC,gBAAgB;GACrB,MAAM,OAAO,eAAe,KAAK,IAAI,CAAC,CAAC,KAAK;GAC5C,IAAI,MACF,SAAS,OAAO,mBAAmB,IAAI,CAAC;EAE5C;EACA,8BAA8B,EAC5B,OACA,UACA,gBACA,iBACuB;GACvB,MAAM,QAAQ,WAAW;GACzB,IAAI,CAAC,OAAO,OAAO,CAAC,OAAO,cAAc;GACzC,MAAM,cAAc,MAAM,KAAK,CAAC,CAAC;GACjC,MAAM,WAAW,IAAI,OAAO,cAAc,YAAY,IAAI;GAE1D,KAAK,IAAI,IAAI,iBAAiB,GAAG,IAAI,MAAM,QAAQ,KACjD,IAAI,SAAS,KAAK,MAAM,MAAM,EAAE,GAAG;IACjC,MAAM,OAAO,MACV,MAAM,iBAAiB,GAAG,CAAC,CAAC,CAC5B,KAAK,IAAI,CAAC,CACV,KAAK;IACR,IAAI,MACF,SAAS,OAAO,mBAAmB,IAAI,CAAC;IAE1C,OAAO,CAAC,MAAM,CAAC;GACjB;GAIF,MAAM,OAAO,MACV,MAAM,iBAAiB,CAAC,CAAC,CACzB,KAAK,IAAI,CAAC,CACV,KAAK;GACR,IAAI,MACF,SAAS,OAAO,mBAAmB,IAAI,CAAC;GAE1C,OAAO,CAAC,MAAM,MAAM,SAAS,CAAC;EAChC;EACA,MAAM;CAaN;CACA,GAAG;AACL;;;;;;;AAQA,MAAa,2BAA0C,CAAC;AAIxD,MAAM,mBAAmB;AAEzB,MAAM,eAAe,SAA0B;CAC7C,MAAM,UAAU,KAAK,KAAK;CAC1B,OAAO,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG;AACxD;AAEA,MAAM,mBAAmB;;AAGzB,MAAa,sBAAsB,aAA6B;CAC9D,MAAM,QAAQ,SAAS,MAAM,IAAI;CACjC,MAAM,SAAmB,CAAC;CAC1B,IAAI,aAAuB,CAAC;CAC5B,IAAI,kBAAkB;CAEtB,MAAM,mBAAmB;EACvB,IAAI,WAAW,UAAU,GAAG;GAC1B,OAAO,KAAK,SAAS,kBAAkB;GACvC,OAAO,KAAK,GAAG,UAAU;GACzB,OAAO,KAAK,KAAK;EACnB,OAEE,OAAO,KAAK,GAAG,UAAU;EAE3B,aAAa,CAAC;CAChB;CAEA,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,iBAAiB,KAAK,IAAI,GAAG;GAC/B,IAAI,WAAW,SAAS,GAAG,WAAW;GACtC,kBAAkB,CAAC;GACnB,OAAO,KAAK,IAAI;GAChB;EACF;EAEA,IAAI,iBAAiB;GACnB,OAAO,KAAK,IAAI;GAChB;EACF;EAEA,IAAI,YAAY,IAAI,GAClB,WAAW,KAAK,IAAI;OACf;GACL,IAAI,WAAW,SAAS,GAAG,WAAW;GACtC,OAAO,KAAK,IAAI;EAClB;CACF;CACA,IAAI,WAAW,SAAS,GAAG,WAAW;CAEtC,OAAO,OAAO,KAAK,IAAI;AACzB;;AAGA,MAAa,uBAAuB,aAA6B;CAC/D,MAAM,QAAQ,IAAI,OAAO,SAAS,iBAAiB,2BAA2B,GAAG;CACjF,OAAO,SAAS,QAAQ,OAAO,IAAI;AACrC;;AAGA,MAAa,wBAAwB,aACnC,SAAS,QAAQ,iBAAiB,IAAI;;;AChLxC,MAAM,aAAa;AAcnB,MAAa,sBAAsB,EACjC,OACA,UACA,UACA,eAAe,qBACf,aAAa,YACgB;CAC7B,MAAM,CAAC,UAAU,0BAA0B;CAC3C,MAAM,kBAAkB,OAAO,KAAK;CACpC,MAAM,eAAe,mBAAmB,aAAqB,WAAW,QAAQ,CAAC;CACjF,MAAM,kBAAkB,OAAO,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,gBAAgB,OAAO,UAAU;CACvC,cAAc,UAAU;CAGxB,gBAAgB;EACd,OAAO,YAAY,QAAQ;CAC7B,GAAG,CAAC,QAAQ,QAAQ,CAAC;CAGrB,gBAAgB;EACd,IAAI,UAAU,gBAAgB,SAAS;EACvC,gBAAgB,UAAU;EAE1B,OAAO,aACC;GACJ,2BAA2B,mBAAmB,KAAK,GAAG,gBAAgB,OAAO;EAC/E,GACA,EAAE,KAAK,WAAW,CACpB;CACF,GAAG,CAAC,QAAQ,KAAK,CAAC;CAGlB,gBAAgB;EACd,OAAO,OAAO,wBAAwB,EAAE,WAAW;GACjD,IAAI,KAAK,IAAI,UAAU,GAAG;GAE1B,OAAO,eAAe,CAAC,CAAC,WAAW;IACjC,MAAM,MAAM,yBAAyB,gBAAgB,OAAO;IAC5D,MAAM,WAAW,cAAc,UAC3B,qBAAqB,GAAG,IACxB,oBAAoB,GAAG;IAC3B,IAAI,aAAa,gBAAgB,SAAS;KACxC,gBAAgB,UAAU;KAC1B,aAAa,QAAQ;IACvB;GACF,CAAC;EACH,CAAC;CACH,GAAG,CAAC,QAAQ,YAAY,CAAC;CAEzB,OAAO;AACT;;;ACzDA,MAAM,oBAAqF;CACzF;EAAE,OAAO;EAAQ,OAAO;EAAQ,MAAM;CAAU;CAChD;EAAE,OAAO;EAAU,OAAO;EAAU,MAAM;CAAY;CACtD;EAAE,OAAO;EAAS,OAAO;EAAS,MAAM;CAAW;CACnD;EAAE,OAAO;EAAW,OAAO;EAAW,MAAM;CAAa;AAC3D;AAEA,MAAM,kBAA8C,OAAO,YACzD,kBAAkB,KAAK,EAAE,OAAO,WAAW,CAAC,OAAO,IAAI,CAAC,CAC1D;AAEA,MAAa,qBAAqB,EAChC,QACA,gBAII;CACJ,MAAM,oBAAoB,OAA6B,IAAI;CAE3D,MAAM,oBAAoB,SAAkB;EAC1C,IAAI,MACF,OAAO,eAAe,CAAC,CAAC,WAAW;GACjC,MAAM,YAAY,cAAc;GAChC,kBAAkB,UAAU,YAAY,UAAU,MAAM,IAAI;EAC9D,CAAC;CAEL;CAEA,MAAM,gBAAgB,UAA6B;EAIjD,OAAO,aAAa;GAClB,IAAI,kBAAkB,SACpB,cAAc,kBAAkB,OAAO;GAEzC,OAAO,gBAAgB,wBAAwB,KAAK;EACtD,CAAC;CACH;CAEA,MAAM,uBAAuB,gBAAgB,cAAc;CAE3D,OACE,qBAAC,cAAD;EAAc,cAAc;EAA5B,UAAA,CACE,oBAAC,SAAD;GAAS,SAAQ;GAAiB,WAAU;GAAM,gBAAA;GAChD,UAAA,oBAAC,aAAa,SAAd;IAAsB,SAAA;IACpB,UAAA,qBAAC,UAAD;KACE,MAAK;KACL,WAAW,GACT,oJACA,oBACF;KALF,UAAA,CAOE,oBAAC,sBAAD,EAAsB,WAAU,YAAa,CAAA,GAC7C,oBAAC,aAAD,EAAa,WAAU,YAAa,CAAA,CAC9B;;GACY,CAAA;EACf,CAAA,GACT,oBAAC,aAAa,SAAd;GAAsB,OAAM;GAAQ,WAAU;GAC3C,UAAA,kBAAkB,KAAK,EAAE,OAAO,OAAO,MAAM,eAC5C,qBAAC,aAAa,MAAd;IAEE,gBAAgB,aAAa,KAAK;IAClC,WAAW,GACT,oCACA,cAAc,SAAS,0CACzB;IANF,UAAA,CAQE,oBAAC,UAAD,EAAU,WAAU,YAAa,CAAA,GAChC,KACgB;GATZ,GAAA,KASY,CACpB;EACmB,CAAA,CACV;;AAElB;;;ACpEA,MAAM,kBAAkB;CACtB,WAAW;EAAE,OAAO;EAAU,MAAM;EAA2B,YAAY;CAAK;CAChF,IAAI;EAAE,OAAO;EAAa,MAAM;EAA+B,YAAY;CAAK;CAChF,IAAI;EAAE,OAAO;EAAa,MAAM;EAA+B,YAAY;CAAK;CAChF,IAAI;EAAE,OAAO;EAAa,MAAM;EAA+B,YAAY;CAAK;CAChF,QAAQ;EAAE,OAAO;EAAe,MAAMA;EAA+B,YAAY;CAAM;CACvF,QAAQ;EAAE,OAAO;EAAiB,MAAM;EAAkC,YAAY;CAAM;CAC5F,OAAO;EAAE,OAAO;EAAS,MAAM;EAA4B,YAAY;CAAM;CAC7E,MAAM;EAAE,OAAO;EAAc,MAAM;EAAiC,YAAY;CAAM;AACxF;AAIA,MAAM,qBACJ,OAAO,QAAQ,eAAe,CAAC,CAE9B,QAAQ,GAAG,UAAU,KAAK,UAAU,CAAC,CACrC,KAAK,CAAC,OAAO,EAAE,OAAO,aAAa;CAAE;CAAO;CAAO;AAAK,EAAE;AAE7D,MAAM,eAAe,UACnB,OAAO,UAAU,eAAe,KAAK,iBAAiB,KAAK;AAE7D,MAAa,qBAAqB,EAChC,QACA,gBAII;CACJ,MAAM,oBAAoB,OAA6B,IAAI;CAC3D,MAAM,cAAc,YAAY,SAAS,IAAI,gBAAgB,aAAa;CAC1E,MAAM,mBAAmB,aAAa,QAAQ;CAE9C,MAAM,oBAAoB,SAAkB;EAC1C,IAAI,MACF,OAAO,eAAe,CAAC,CAAC,WAAW;GACjC,MAAM,YAAY,cAAc;GAChC,kBAAkB,UAAU,YAAY,UAAU,MAAM,IAAI;EAC9D,CAAC;CAEL;CAEA,MAAM,gBAAgB,SAAoB;EACxC,OAAO,aAAa;GAClB,IAAI,kBAAkB,SACpB,cAAc,kBAAkB,OAAO;GAGzC,MAAM,YAAY,cAAc;GAChC,IAAI,CAAC,kBAAkB,SAAS,GAAG;GAEnC,IAAI,SAAS,UAAU;IACrB,OAAO,gBAAgB,+BAA+B,KAAA,CAAS;IAC/D;GACF;GACA,IAAI,SAAS,UAAU;IACrB,OAAO,gBAAgB,6BAA6B,KAAA,CAAS;IAC7D;GACF;GAEA,MAAM,aAAa,UAAU,OAAO,QAAQ;GAC5C,MAAM,UAAU,uCAAuC,UAAU;GAEjE,MAAM,UACJ,SAAS,QAAQ,SAAS,QAAQ,SAAS,OACvC,mBAAmB,IAAI,IACvB,SAAS,UACP,iBAAiB,IACjB,SAAS,SACP,gBAAgB,IAChB,qBAAqB;GAE/B,QAAQ,YAAY,CAAC,CAAC,SAAS,UAAU,QAAQ,OAAO,KAAK,CAAC;GAC9D,QAAQ,QAAQ,OAAO;EACzB,CAAC;CACH;CAEA,OACE,qBAAC,cAAD;EAAc,cAAc;EAA5B,UAAA,CACE,oBAAC,SAAD;GAAS,SAAQ;GAAoB,WAAU;GAAM,gBAAA;GACnD,UAAA,oBAAC,aAAa,SAAd;IAAsB,SAAA;IACpB,UAAA,qBAAC,UAAD;KACE,MAAK;KACL,WAAW,GACT,sJACA,oBACF;KALF,UAAA;MAOE,oBAAC,kBAAD,EAAkB,WAAU,YAAa,CAAA;MACxC,aAAa,SAAS;MACvB,oBAAC,aAAD,EAAa,WAAU,YAAa,CAAA;KAC9B;;GACY,CAAA;EACf,CAAA,GACT,oBAAC,aAAa,SAAd;GAAsB,OAAM;GAAQ,WAAU;GAC3C,UAAA,mBAAmB,KAAK,EAAE,OAAO,OAAO,MAAM,eAC7C,qBAAC,aAAa,MAAd;IAEE,gBAAgB,aAAa,KAAK;IAClC,WAAW,GACT,oCACA,cAAc,SAAS,0CACzB;IANF,UAAA,CAQE,oBAAC,UAAD,EAAU,WAAU,YAAa,CAAA,GAChC,KACgB;GATZ,GAAA,KASY,CACpB;EACmB,CAAA,CACV;;AAElB;;;ACxIA,MAAa,iBAAiB,EAC5B,QACA,UACA,SACA,SACA,UACA,WAAW,qBASX,oBAAC,SAAD;CAAkB;CAAS,WAAU;CAAM,gBAAA;CACzC,UAAA,oBAAC,UAAD;EACE,MAAK;EACK;EACD;EACT,WAAW,GACT,sKACA,4EACA,UAAU,6CACV,cACF;EAEC;CACK,CAAA;AACD,CAAA;;;ACbX,MAAM,cACJ,QACA,KACA,OACA,mBACG;CACH,OAAO,aAAa;EAClB,cAAc,cAAc;EAC5B,MAAM,YAAY,cAAc;EAEhC,IAAI,kBAAkB,SAAS,GAAG;GAChC,MAAM,eAAe,UAAU,eAAe;GAC9C,IAAI,gBAAgB,UAAU,cAAc;IAC1C,OAAO,gBAAgB,qBAAqB,GAAG;IAC/C;GACF;EACF;EAEA,MAAM,WAAW,gBAAgB,GAAG;EACpC,MAAM,WAAW,gBAAgB,SAAS,GAAG;EAC7C,SAAS,OAAO,QAAQ;EAExB,IAAI,kBAAkB,SAAS,GAC7B,UAAU,YAAY,CAAC,QAAQ,CAAC;CAEpC,CAAC;AACH;AAEA,MAAa,aAAa,EAAE,QAAQ,aAAyD;CAC3F,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,KAAK,UAAU,SAAS,EAAE;CACjC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,oBAAoB,OAA6B,IAAI;CAC3D,MAAM,WAAW,OAAuB,IAAI;CAE5C,MAAM,mBAAmB;EACvB,OAAO,eAAe,CAAC,CAAC,WAAW;GACjC,MAAM,YAAY,cAAc;GAChC,kBAAkB,UAAU,YAAY,UAAU,MAAM,IAAI;GAE5D,IAAI,kBAAkB,SAAS,GAAG;IAChC,MAAM,OAAO,UAAU,eAAe;IACtC,IAAI,MAAM,SAAS,IAAI;GACzB;EACF,CAAC;EACD,QAAQ,IAAI;CACd;CAEA,MAAM,oBAAoB;EACxB,QAAQ,KAAK;EACb,OAAO,EAAE;EACT,SAAS,EAAE;EACX,kBAAkB,UAAU;EAC5B,OAAO,MAAM;CACf;CAEA,MAAM,qBAAqB;EACzB,MAAM,aAAa,IAAI,KAAK;EAC5B,IAAI,CAAC,YAAY;EAEjB,WAAW,QAAQ,YAAY,MAAM,KAAK,GAAG,kBAAkB,OAAO;EACtE,YAAY;CACd;CAEA,MAAM,iBAAiB,MAA0B;EAC/C,IAAI,EAAE,QAAQ,SAAS;GACrB,EAAE,eAAe;GACjB,aAAa;EACf;EACA,IAAI,EAAE,QAAQ,UAAU;GACtB,EAAE,eAAe;GACjB,YAAY;EACd;CACF;CAEA,IAAI,QACF,OACE,oBAAC,eAAD;EACE,QAAA;EACA,eAAe,OAAO,gBAAgB,qBAAqB,IAAI;EAC/D,SAAQ;EAER,UAAA,oBAACC,MAAD,EAAU,WAAU,YAAa,CAAA;CACpB,CAAA;CAInB,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,eAAD;GAAe,QAAQ;GAAM,SAAS;GAAY,SAAQ;GACxD,UAAA,oBAACA,MAAD,EAAU,WAAU,YAAa,CAAA;EACpB,CAAA,GACd,QACC,oBAAC,OAAD;GACE,KAAK;GACL,WAAU;GAEV,UAAA,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,OAAD;MAAO,SAAQ;MAAa,WAAU;MAAqB,UAAA;KAEpD,CAAA,GACP,oBAAC,WAAD;MACE,IAAG;MACH,WAAA;MACA,aAAY;MACZ,OAAO;MACP,eAAe;MACf,WAAW;MACX,SAAQ;KACT,CAAA,CACQ,EAAA,CAAA;KACX,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,OAAD;MAAO,SAAQ;MAAW,WAAU;MAAqB,UAAA;KAElD,CAAA,GACP,oBAAC,WAAD;MACE,IAAG;MACH,aAAY;MACZ,OAAO;MACP,eAAe;MACf,WAAW;MACX,SAAQ;KACT,CAAA,CACQ,EAAA,CAAA;KACX,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,QAAD;MAAQ,MAAK;MAAQ,SAAQ;MAAU,SAAS;MAAa,UAAA;KAErD,CAAA,GACR,oBAAC,QAAD;MAAQ,MAAK;MAAQ,SAAS;MAAc,UAAU,CAAC,IAAI,KAAK;MAAG,UAAA;KAE3D,CAAA,CACG,EAAA,CAAA;IACV;;EACF,CAAA,CAEJ;;AAET;;;AC/JA,MAAa,uBAAuB,oBAAC,OAAD,EAAK,WAAU,wCAAyC,CAAA;;;ACuC5F,MAAM,uBAAuB;CAAC;CAAQ;CAAU;CAAS;CAAW;CAAS;CAAO;AAAE;AAEtF,MAAM,uBAAuB,UAC1B,qBAA2C,SAAS,KAAK;AAE5D,MAAM,uBAAuB,UAC3B,oBAAoB,KAAK,IAAI,QAAQ;AAEvC,MAAa,sBAAsB;CACjC,MAAM,CAAC,UAAU,0BAA0B;CAC3C,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAC9C,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CACpD,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,KAAK;CAC5D,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAC1C,MAAM,CAAC,WAAW,gBAAgB,SAAiB,WAAW;CAC9D,MAAM,CAAC,WAAW,gBAAgB,SAA4B,MAAM;CACpE,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,CAAC,UAAU,eAAe,SAA+C,IAAI;CACnF,MAAM,aAAa,OAAuB,IAAI;CAC9C,MAAM,iBAAiB,OAAO,KAAK;CACnC,MAAM,kBAAkB,OAAO,KAAK;CAEpC,MAAM,iBAAiB,kBAAkB;EACvC,MAAM,kBAAkB,OAAO,aAAa;EAC5C,IAAI,CAAC,mBAAmB,gBAAgB,eAAe,GAAG;EAE1D,MAAM,OADQ,gBAAgB,WAAW,CACxB,CAAC,CAAC,sBAAsB;EACzC,IAAI,KAAK,QAAQ,GAAG;GAClB,MAAM,eAAe,WAAW,SAAS,eAAe;GACxD,YAAY;IACV,KAAK,KAAK,MAAM,OAAO,UAAU;IACjC,MAAM,KAAK,IAAI,GAAG,KAAK,OAAO,OAAO,UAAU,KAAK,QAAQ,IAAI,eAAe,CAAC;GAClF,CAAC;EACH;CACF,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,MAAM,wBAAwB;GAC5B,eAAe,UAAU;EAC3B;EACA,MAAM,sBAAsB;GAC1B,eAAe,UAAU;GACzB,IAAI,gBAAgB,SAClB,aAAa,IAAI;EAErB;EACA,SAAS,iBAAiB,aAAa,eAAe;EACtD,SAAS,iBAAiB,WAAW,aAAa;EAClD,aAAa;GACX,SAAS,oBAAoB,aAAa,eAAe;GACzD,SAAS,oBAAoB,WAAW,aAAa;EACvD;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB,kBAAkB;EACtC,MAAM,YAAY,cAAc;EAChC,IAAI,CAAC,kBAAkB,SAAS,GAAG;GACjC,gBAAgB,UAAU;GAC1B,aAAa,KAAK;GAClB;EACF;EAEA,MAAM,eAAe,CAAC,UAAU,YAAY,KAAK,UAAU,eAAe,CAAC,CAAC,SAAS;EACrF,gBAAgB,UAAU;EAE1B,IAAI,CAAC,cACH,aAAa,KAAK;OACb,IAAI,CAAC,eAAe,SACzB,aAAa,IAAI;EAGnB,IAAI,cACF,eAAe;EAGjB,UAAU,UAAU,UAAU,MAAM,CAAC;EACrC,YAAY,UAAU,UAAU,QAAQ,CAAC;EACzC,eAAe,UAAU,UAAU,WAAW,CAAC;EAC/C,mBAAmB,UAAU,UAAU,eAAe,CAAC;EACvD,UAAU,UAAU,UAAU,MAAM,CAAC;EAErC,MAAM,OAAO,UAAU,OAAO,QAAQ;EACtC,MAAM,SAAS,KAAK,UAAU;EAC9B,UAAU,YAAY,MAAM,KAAK,YAAY,IAAI,CAAC;EAElD,MAAM,eAAe,uCAAuC,IAAI;EAEhE,IAAI,YAAY,YAAY,GAAG;GAC7B,MAAM,WAAW,aAAa,YAAY;GAC1C,aAAa,aAAa,WAAW,WAAW,QAAQ;EAC1D,OAAO,IAAI,eAAe,YAAY,GACpC,aAAa,aAAa,OAAO,CAAC;OAC7B,IAAI,YAAY,YAAY,GACjC,aAAa,MAAM;OACd,IAAI,aAAa,YAAY,GAClC,aAAa,OAAO;OAEpB,aAAa,WAAW;EAG1B,aAAa,oBAAoB,aAAa,cAAc,CAAC,CAAC;CAChE,GAAG,CAAC,cAAc,CAAC;CAEnB,gBAAgB;EACd,MAAM,mBAAmB,OAAO,wBAAwB,EAAE,kBAAkB;GAC1E,YAAY,WAAW;IACrB,cAAc;GAChB,CAAC;EACH,CAAC;EAED,aAAa;GACX,iBAAiB;EACnB;CACF,GAAG,CAAC,QAAQ,aAAa,CAAC;CAE1B,IAAI,CAAC,aAAa,CAAC,UAAU,OAAO;CAEpC,OAAO,aACL,qBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,cAAW;EACX,cAAc,MAAM,EAAE,eAAe;EACrC,OAAO;GAAE,KAAK,SAAS;GAAK,MAAM,SAAS;EAAK;EAChD,WAAU;EANZ,UAAA;GAQE,oBAAC,mBAAD;IAA2B;IAAmB;GAAY,CAAA;GAE1D,oBAAC,gBAAD,CAAiB,CAAA;GAEjB,oBAAC,eAAD;IACE,QAAQ;IACR,eAAe,OAAO,gBAAgB,qBAAqB,MAAM;IACjE,SAAQ;IAER,UAAA,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA;GAChB,CAAA;GACf,oBAAC,eAAD;IACE,QAAQ;IACR,eAAe,OAAO,gBAAgB,qBAAqB,QAAQ;IACnE,SAAQ;IAER,UAAA,oBAAC,QAAD,EAAQ,WAAU,YAAa,CAAA;GAClB,CAAA;GACf,oBAAC,eAAD;IACE,QAAQ;IACR,eAAe,OAAO,gBAAgB,qBAAqB,WAAW;IACtE,SAAQ;IAER,UAAA,oBAAC,WAAD,EAAW,WAAU,YAAa,CAAA;GACrB,CAAA;GACf,oBAAC,eAAD;IACE,QAAQ;IACR,eAAe,OAAO,gBAAgB,qBAAqB,eAAe;IAC1E,SAAQ;IAER,UAAA,oBAAC,eAAD,EAAe,WAAU,YAAa,CAAA;GACzB,CAAA;GACf,oBAAC,eAAD;IACE,QAAQ;IACR,eAAe,OAAO,gBAAgB,qBAAqB,MAAM;IACjE,SAAQ;IAER,UAAA,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA;GAChB,CAAA;GAEf,oBAAC,gBAAD,CAAiB,CAAA;GAEjB,oBAAC,WAAD;IAAmB;IAAgB;GAAS,CAAA;GAE5C,oBAAC,gBAAD,CAAiB,CAAA;GAEjB,oBAAC,eAAD;IACE,QAAQ,cAAc;IACtB,eAAe;KACb,IAAI,cAAc,UAChB,OAAO,gBAAgB,qBAAqB,KAAA,CAAS;UAErD,OAAO,gBAAgB,+BAA+B,KAAA,CAAS;IAEnE;IACA,SAAQ;IAER,UAAA,oBAACC,MAAD,EAAU,WAAU,YAAa,CAAA;GACpB,CAAA;GACf,oBAAC,eAAD;IACE,QAAQ,cAAc;IACtB,eAAe;KACb,IAAI,cAAc,UAChB,OAAO,gBAAgB,qBAAqB,KAAA,CAAS;UAErD,OAAO,gBAAgB,6BAA6B,KAAA,CAAS;IAEjE;IACA,SAAQ;IAER,UAAA,oBAAC,aAAD,EAAa,WAAU,YAAa,CAAA;GACvB,CAAA;GAEf,oBAAC,gBAAD,CAAiB,CAAA;GAEjB,oBAAC,mBAAD;IAA2B;IAAmB;GAAY,CAAA;GAE1D,oBAAC,gBAAD,CAAiB,CAAA;GAEjB,oBAAC,eAAD;IACE,QAAQ,cAAc;IACtB,eAAe;KACb,OAAO,aAAa;MAClB,MAAM,YAAY,cAAc;MAChC,IAAI,CAAC,kBAAkB,SAAS,GAAG;MACnC,MAAM,aAAa,UAAU,OAAO,QAAQ;MAC5C,MAAM,UAAU,uCAAuC,UAAU;MACjE,MAAM,UAAU,cAAc,UAAU,qBAAqB,IAAI,iBAAiB;MAClF,QAAQ,YAAY,CAAC,CAAC,SAAS,UAAU,QAAQ,OAAO,KAAK,CAAC;MAC9D,QAAQ,QAAQ,OAAO;KACzB,CAAC;IACH;IACA,SAAQ;IAER,UAAA,oBAAC,OAAD,EAAO,WAAU,YAAa,CAAA;GACjB,CAAA;GACf,oBAAC,eAAD;IACE,QAAQ,cAAc;IACtB,eAAe;KACb,OAAO,aAAa;MAClB,MAAM,YAAY,cAAc;MAChC,IAAI,CAAC,kBAAkB,SAAS,GAAG;MACnC,MAAM,aAAa,UAAU,OAAO,QAAQ;MAC5C,MAAM,UAAU,uCAAuC,UAAU;MACjE,MAAM,UAAU,cAAc,SAAS,qBAAqB,IAAI,gBAAgB;MAChF,QAAQ,YAAY,CAAC,CAAC,SAAS,UAAU,QAAQ,OAAO,KAAK,CAAC;MAC9D,QAAQ,QAAQ,OAAO;KACzB,CAAC;IACH;IACA,SAAQ;IAER,UAAA,oBAAC,YAAD,EAAY,WAAU,YAAa,CAAA;GACtB,CAAA;EACZ;CACL,CAAA,GAAA,SAAS,IACX;AACF;;;;;;;;;ACnRA,MAAa,cAAkC;CAC7C,MAAM;CACN,MAAM;EACJ,MAAM;EACN,QAAQ;EACR,eAAe;EACf,WAAW;EACX,MAAM;CACR;CACA,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,WAAW;EACX,iBAAiB;GACf;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,GAAG;EACV,mBAAmB;GACjB;GACA;GACA;GACA;EACF,CAAC,CAAC,KAAK,GAAG;CACZ;AACF;;;ACwCA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAa,kBAAkB,EAC7B,OACA,UACA,WAAW,OACX,aACA,YAAY,OACZ,WAAW,OACX,QACA,UACA,eACA,WACA,eACA,cAAc,OACd,UAAU,OACV,aAAa,OACb,aAAa,OACb,eAAe,OACf,cACyB;CACzB,MAAM,WAAW,CAAC,YAAY,CAAC;CAC/B,MAAM,eAAe,aAAa,2BAA2B;CAC7D,MAAM,sBAAsB,CAAC,WAAW,YAAY,KAAA;CACpD,MAAM,kBACJ,CAAC,WAAW,YAAY,KAAA,IAAY,EAAE,WAAW,GAAG,UAAU,KAAK,IAAI,IAAI,KAAA;CAG7E,MAAM,CAAC,iBAAiB,gBAAmC;EACzD,WAAW;EACX,OAAO;EACP,OAAO;EACP,UAAU,UAAiB;GACzB,QAAQ,MAAM,0CAA0C,KAAK;EAC/D;EACA;EACA,mBAAmB;GACjB,2BAA2B,mBAAmB,KAAK,GAAG,YAAY;EACpE;CACF,EAAE;CAGF,MAAM,kBAAkB,OAAO,KAAK;CAEpC,MAAM,aACJ,cAAc,UACT,UAAsC;EACrC,IAAI,gBAAgB,SAAS;GAC3B,gBAAgB,UAAU;GAC1B;EACF;EAEA,IAAI,CAAC,MAAM,cAAc,SAAS,MAAM,aAA4B,GAClE,OAAO;CAEX,IACA,KAAA;CAEN,OACE,oBAAC,iBAAD;EAAgC;EAC9B,UAAA,oBAAC,uBAAD;GAAuB,OAAO,iBAAiB;GAC7C,UAAA,qBAAC,OAAD;IACE,WAAW,GACT,CAAC,WAAW,YAEZ,WAAW,gCAEX,gBAAgB,0CAChB,SACF;IACA,QAAQ;IATV,UAAA;KAWG,eAAe,YAAY,oBAAC,eAAD,CAAgB,CAAA;KAC5C,oBAAC,OAAD;MACE,WAAW,GACT,kDAEA,UAAU,8CAA8C,UACxD,YACE,sFACJ;MAEA,UAAA,oBAAC,gBAAD;OACE,iBACE,oBAAC,iBAAD;QACE,WAAW,GAAG,qBAAqB,uBAAuB,kBAAkB;QAC5E,OAAO;QACP,oBAAkB,eAAe;QACjC,aACE,cACE,oBAAC,OAAD;SACE,WAAW,GACT,8EACA,UACI,2BACA,wCACN;SAEC,UAAA;QACE,CAAA,IAEL,oBAAC,OAAD,CAAM,CAAA;OAGX,CAAA;OAEH,eAAe;MAChB,CAAA;KACE,CAAA;KACL,oBAAC,eAAD,CAAgB,CAAA;KAChB,oBAAC,YAAD,CAAa,CAAA;KACb,oBAAC,qBAAD,EAAqB,QAAA,KAAQ,CAAA;KAC5B,CAAC,cAAc,oBAAC,YAAD,CAAa,CAAA;KAC5B,CAAC,cAAc,oBAAC,iBAAD,CAAkB,CAAA;KACjC,CAAC,cAAc,oBAAC,sBAAD,CAAuB,CAAA;KACvC,oBAAC,sBAAD,CAAuB,CAAA;KACvB,oBAAC,wBAAD,EAAsC,aAAe,CAAA;KACrD,oBAAC,oBAAD;MACS;MACG;MACA;MACI;MACF;KACb,CAAA;KACD,oBAAC,kBAAD,EAAiC,cAAgB,CAAA;KACjD,oBAAC,gBAAD;MACU;MACE;MACE;MACZ,cAAc,cAAc;MACX;KAClB,CAAA;KACA,aAAa,oBAAC,iBAAD,CAAkB,CAAA;IAC7B;;EACgB,CAAA;CACR,CAAA;AAErB"}
|
package/dist/mermaid.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
//#region src/blocks/MermaidDiagram/MermaidDiagram.d.ts
|
|
3
3
|
type Props = {
|
|
4
|
-
/** Mermaid
|
|
5
|
-
*
|
|
6
|
-
* by mermaid's dayjs parser — use `dateFormat YYYY-MM-DD HH:mm` with `axisFormat %H:%M` instead. */
|
|
4
|
+
/** Mermaid source. Gantt time-only `dateFormat HH:mm` is unsupported — use
|
|
5
|
+
* `dateFormat YYYY-MM-DD HH:mm` with `axisFormat %H:%M`. */
|
|
7
6
|
code: string;
|
|
8
|
-
/** Extra toolbar controls
|
|
9
|
-
* Receives the sanitized SVG. Omit to keep the default toolbar. */
|
|
7
|
+
/** Extra toolbar controls forwarded to `ZoomableSvg`; receives the sanitized SVG. */
|
|
10
8
|
renderActions?: (safeSvg: string) => ReactNode;
|
|
11
9
|
};
|
|
12
|
-
declare const MermaidDiagram: ({ code, renderActions }: Props) => import("react
|
|
10
|
+
declare const MermaidDiagram: ({ code, renderActions }: Props) => import("react").JSX.Element;
|
|
13
11
|
//#endregion
|
|
14
12
|
export { MermaidDiagram };
|
|
15
13
|
//# sourceMappingURL=mermaid.d.ts.map
|
package/dist/mermaid.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MermaidDiagram } from "./MermaidDiagram-
|
|
1
|
+
import { MermaidDiagram } from "./MermaidDiagram-BQvz6bhv.js";
|
|
2
2
|
export { MermaidDiagram };
|
package/dist/rjsf.d.ts
CHANGED
|
@@ -10,32 +10,22 @@ declare const RjsfSchemaEditor: ({ schema, value, onChange, readOnly, inForm, gl
|
|
|
10
10
|
onChange: (value: Record<string, unknown>) => void;
|
|
11
11
|
readOnly: boolean;
|
|
12
12
|
inForm?: boolean;
|
|
13
|
-
/**
|
|
13
|
+
/** Values from image_parameters.global_config; matching fields are disabled. */
|
|
14
14
|
globalConfig?: Record<string, unknown> | null;
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* - Merged one level deep over the root form data, so an entry the form itself carries keeps
|
|
19
|
-
* the keys this does not name.
|
|
20
|
-
* - Never part of `value`: it reaches no widget's `formData`, no validation, and no `onChange`.
|
|
21
|
-
* - A visible computed field derived only from it is a view, so it does not write itself back.
|
|
22
|
-
* Hidden `template`/`watch` helpers still write — that is what feeds `options.dependencies`.
|
|
23
|
-
* - Declare a stable set of keys, empty entries included: a key that comes and goes flips such
|
|
24
|
-
* a field between viewing its value and saving it.
|
|
25
|
-
*/
|
|
15
|
+
/** Read-only `watch` entries merged one level deep over form data; never in `value` or validation.
|
|
16
|
+
* Keep the key set stable: a key that comes and goes flips a computed field between view and save. */
|
|
26
17
|
rootContext?: Record<string, Record<string, unknown>>;
|
|
27
|
-
/**
|
|
28
|
-
* Returns true when valid, false when there are errors. */
|
|
18
|
+
/** Receives a validate function that shows errors inline and returns validity. */
|
|
29
19
|
onRegisterValidate?: (validate: () => boolean) => void;
|
|
30
|
-
/** Host
|
|
20
|
+
/** Host widgets (e.g. sync-action, async-select), merged over the built-in registry. */
|
|
31
21
|
widgets?: RegistryWidgetsType;
|
|
32
|
-
/** Host
|
|
22
|
+
/** Host fields (e.g. sshForm), merged over the built-in registry. */
|
|
33
23
|
fields?: RegistryFieldsType;
|
|
34
|
-
/**
|
|
24
|
+
/** Defaults to plain text. */
|
|
35
25
|
renderMarkdown?: RenderMarkdown;
|
|
36
|
-
/**
|
|
26
|
+
/** Password fields render as plain text inputs. */
|
|
37
27
|
hasProtectedDefaultBranch?: boolean;
|
|
38
|
-
}) => import("react
|
|
28
|
+
}) => import("react").JSX.Element;
|
|
39
29
|
//#endregion
|
|
40
30
|
//#region src/blocks/RjsfSchemaEditor/RootFormDataContext.d.ts
|
|
41
31
|
declare const useRootFormData: () => Record<string, unknown>;
|