@multiplatform.one/rich-text 6.1.0 → 6.3.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/README.md +60 -0
- package/dist/cjs/RichEditor.cjs +84 -9
- package/dist/cjs/RichEditor.native.js +422 -35
- package/dist/cjs/RichEditor.native.js.map +1 -1
- package/dist/cjs/RichTextEditor/index.cjs +18 -2
- package/dist/cjs/RichTextEditor/index.native.js +18 -2
- package/dist/cjs/RichTextEditor/index.native.js.map +1 -1
- package/dist/cjs/constants.cjs +52 -29
- package/dist/cjs/constants.native.js +59 -29
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/editor/BlockDragHandle.cjs +22 -7
- package/dist/cjs/editor/BlockDragHandle.native.js +41 -7
- package/dist/cjs/editor/BlockDragHandle.native.js.map +1 -1
- package/dist/cjs/editor/SlashCommands.cjs +249 -293
- package/dist/cjs/editor/SlashCommands.native.js +306 -340
- package/dist/cjs/editor/SlashCommands.native.js.map +1 -1
- package/dist/cjs/editor/TentapEditor.native.js +44 -12
- package/dist/cjs/editor/TentapEditor.native.js.map +1 -1
- package/dist/cjs/editor/TiptapEditor.cjs +140 -33
- package/dist/cjs/editor/TiptapEditor.native.js +153 -33
- package/dist/cjs/editor/TiptapEditor.native.js.map +1 -1
- package/dist/cjs/editor/blockAnchor.cjs +43 -0
- package/dist/cjs/editor/blockAnchor.native.js +68 -0
- package/dist/cjs/editor/blockAnchor.native.js.map +1 -0
- package/dist/cjs/editor/codeBlockPreview.cjs +230 -0
- package/dist/cjs/editor/codeBlockPreview.native.js +265 -0
- package/dist/cjs/editor/codeBlockPreview.native.js.map +1 -0
- package/dist/cjs/editor/editorStyles.cjs +203 -34
- package/dist/cjs/editor/editorStyles.native.js +203 -34
- package/dist/cjs/editor/editorStyles.native.js.map +1 -1
- package/dist/cjs/editor/emoji.cjs +128 -0
- package/dist/cjs/editor/emoji.native.js +184 -0
- package/dist/cjs/editor/emoji.native.js.map +1 -0
- package/dist/cjs/editor/lazyKatex.cjs +78 -0
- package/dist/cjs/editor/lazyKatex.native.js +117 -0
- package/dist/cjs/editor/lazyKatex.native.js.map +1 -0
- package/dist/cjs/editor/markdown.cjs +216 -0
- package/dist/cjs/editor/markdown.native.js +278 -0
- package/dist/cjs/editor/markdown.native.js.map +1 -0
- package/dist/cjs/editor/mathematics.cjs +168 -0
- package/dist/cjs/editor/mathematics.native.js +202 -0
- package/dist/cjs/editor/mathematics.native.js.map +1 -0
- package/dist/cjs/editor/media.cjs +138 -0
- package/dist/cjs/editor/media.native.js +172 -0
- package/dist/cjs/editor/media.native.js.map +1 -0
- package/dist/cjs/editor/mentions.cjs +73 -0
- package/dist/cjs/editor/mentions.native.js +84 -0
- package/dist/cjs/editor/mentions.native.js.map +1 -0
- package/dist/cjs/editor/pasteCleanup.cjs +83 -0
- package/dist/cjs/editor/pasteCleanup.native.js +175 -0
- package/dist/cjs/editor/pasteCleanup.native.js.map +1 -0
- package/dist/cjs/editor/suggestionPopup.cjs +297 -0
- package/dist/cjs/editor/suggestionPopup.native.js +327 -0
- package/dist/cjs/editor/suggestionPopup.native.js.map +1 -0
- package/dist/cjs/preview.cjs +263 -0
- package/dist/cjs/preview.native.js +294 -0
- package/dist/cjs/preview.native.js.map +1 -0
- package/dist/cjs/shared/t.cjs +53 -0
- package/dist/cjs/shared/t.native.js +56 -0
- package/dist/cjs/shared/t.native.js.map +1 -0
- package/dist/cjs/shared/url.cjs +35 -0
- package/dist/cjs/shared/url.native.js +38 -0
- package/dist/cjs/shared/url.native.js.map +1 -0
- package/dist/cjs/styled.cjs +13 -6
- package/dist/cjs/styled.native.js +13 -6
- package/dist/cjs/styled.native.js.map +1 -1
- package/dist/cjs/toolbar/BubbleToolbar.cjs +10 -8
- package/dist/cjs/toolbar/BubbleToolbar.native.js +10 -8
- package/dist/cjs/toolbar/BubbleToolbar.native.js.map +1 -1
- package/dist/cjs/toolbar/CodeBlockBubble.cjs +59 -23
- package/dist/cjs/toolbar/CodeBlockBubble.native.js +71 -25
- package/dist/cjs/toolbar/CodeBlockBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/ColorPicker.cjs +19 -54
- package/dist/cjs/toolbar/ColorPicker.native.js +81 -179
- package/dist/cjs/toolbar/ColorPicker.native.js.map +1 -1
- package/dist/cjs/toolbar/FixedToolbar.cjs +33 -10
- package/dist/cjs/toolbar/FixedToolbar.native.js +46 -54
- package/dist/cjs/toolbar/FixedToolbar.native.js.map +1 -1
- package/dist/cjs/toolbar/HeadingPicker.cjs +32 -39
- package/dist/cjs/toolbar/HeadingPicker.native.js +61 -51
- package/dist/cjs/toolbar/HeadingPicker.native.js.map +1 -1
- package/dist/cjs/toolbar/ImageBubble.cjs +20 -43
- package/dist/cjs/toolbar/ImageBubble.native.js +20 -43
- package/dist/cjs/toolbar/ImageBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/ImageDialog.cjs +5 -4
- package/dist/cjs/toolbar/ImageDialog.native.js +76 -65
- package/dist/cjs/toolbar/ImageDialog.native.js.map +1 -1
- package/dist/cjs/toolbar/LinkBubble.cjs +23 -70
- package/dist/cjs/toolbar/LinkBubble.native.js +23 -70
- package/dist/cjs/toolbar/LinkBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/LinkDialog.cjs +19 -18
- package/dist/cjs/toolbar/LinkDialog.native.js +86 -83
- package/dist/cjs/toolbar/LinkDialog.native.js.map +1 -1
- package/dist/cjs/toolbar/ListPicker.cjs +32 -43
- package/dist/cjs/toolbar/ListPicker.native.js +43 -44
- package/dist/cjs/toolbar/ListPicker.native.js.map +1 -1
- package/dist/cjs/toolbar/MathBubble.cjs +159 -0
- package/dist/cjs/toolbar/MathBubble.native.js +169 -0
- package/dist/cjs/toolbar/MathBubble.native.js.map +1 -0
- package/dist/cjs/toolbar/MoreDropdown.cjs +51 -98
- package/dist/cjs/toolbar/MoreDropdown.native.js +73 -98
- package/dist/cjs/toolbar/MoreDropdown.native.js.map +1 -1
- package/dist/cjs/toolbar/StatusBar.cjs +19 -10
- package/dist/cjs/toolbar/StatusBar.native.js +19 -10
- package/dist/cjs/toolbar/StatusBar.native.js.map +1 -1
- package/dist/cjs/toolbar/TableBubble.cjs +77 -95
- package/dist/cjs/toolbar/TableBubble.native.js +73 -71
- package/dist/cjs/toolbar/TableBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/ToolbarButton.cjs +86 -21
- package/dist/cjs/toolbar/ToolbarButton.native.js +14 -4
- package/dist/cjs/toolbar/ToolbarButton.native.js.map +1 -1
- package/dist/cjs/toolbar/icons.cjs +111 -468
- package/dist/cjs/toolbar/shortcuts.cjs +73 -24
- package/dist/cjs/toolbar/shortcuts.native.js +73 -24
- package/dist/cjs/toolbar/shortcuts.native.js.map +1 -1
- package/dist/cjs/toolbar/useHorizontalScroll.cjs +25 -5
- package/dist/cjs/toolbar/useHorizontalScroll.native.js +25 -5
- package/dist/cjs/toolbar/useHorizontalScroll.native.js.map +1 -1
- package/dist/cjs/toolbar/useRovingFocus.cjs +80 -0
- package/dist/cjs/toolbar/useRovingFocus.native.js +113 -0
- package/dist/cjs/toolbar/useRovingFocus.native.js.map +1 -0
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/esm/RichEditor.mjs +85 -10
- package/dist/esm/RichEditor.mjs.map +1 -1
- package/dist/esm/RichEditor.native.js +425 -38
- package/dist/esm/RichEditor.native.js.map +1 -1
- package/dist/esm/RichTextEditor/index.mjs +18 -2
- package/dist/esm/RichTextEditor/index.mjs.map +1 -1
- package/dist/esm/RichTextEditor/index.native.js +18 -2
- package/dist/esm/RichTextEditor/index.native.js.map +1 -1
- package/dist/esm/constants.mjs +47 -29
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +54 -29
- package/dist/esm/constants.native.js.map +1 -1
- package/dist/esm/editor/BlockDragHandle.mjs +22 -7
- package/dist/esm/editor/BlockDragHandle.mjs.map +1 -1
- package/dist/esm/editor/BlockDragHandle.native.js +41 -7
- package/dist/esm/editor/BlockDragHandle.native.js.map +1 -1
- package/dist/esm/editor/SlashCommands.mjs +250 -294
- package/dist/esm/editor/SlashCommands.mjs.map +1 -1
- package/dist/esm/editor/SlashCommands.native.js +307 -341
- package/dist/esm/editor/SlashCommands.native.js.map +1 -1
- package/dist/esm/editor/TentapEditor.native.js +45 -13
- package/dist/esm/editor/TentapEditor.native.js.map +1 -1
- package/dist/esm/editor/TiptapEditor.mjs +142 -35
- package/dist/esm/editor/TiptapEditor.mjs.map +1 -1
- package/dist/esm/editor/TiptapEditor.native.js +155 -35
- package/dist/esm/editor/TiptapEditor.native.js.map +1 -1
- package/dist/esm/editor/blockAnchor.mjs +18 -0
- package/dist/esm/editor/blockAnchor.mjs.map +1 -0
- package/dist/esm/editor/blockAnchor.native.js +40 -0
- package/dist/esm/editor/blockAnchor.native.js.map +1 -0
- package/dist/esm/editor/codeBlockPreview.mjs +190 -0
- package/dist/esm/editor/codeBlockPreview.mjs.map +1 -0
- package/dist/esm/editor/codeBlockPreview.native.js +222 -0
- package/dist/esm/editor/codeBlockPreview.native.js.map +1 -0
- package/dist/esm/editor/editorStyles.mjs +203 -34
- package/dist/esm/editor/editorStyles.mjs.map +1 -1
- package/dist/esm/editor/editorStyles.native.js +203 -34
- package/dist/esm/editor/editorStyles.native.js.map +1 -1
- package/dist/esm/editor/emoji.mjs +88 -0
- package/dist/esm/editor/emoji.mjs.map +1 -0
- package/dist/esm/editor/emoji.native.js +141 -0
- package/dist/esm/editor/emoji.native.js.map +1 -0
- package/dist/esm/editor/lazyKatex.mjs +40 -0
- package/dist/esm/editor/lazyKatex.mjs.map +1 -0
- package/dist/esm/editor/lazyKatex.native.js +76 -0
- package/dist/esm/editor/lazyKatex.native.js.map +1 -0
- package/dist/esm/editor/markdown.mjs +179 -0
- package/dist/esm/editor/markdown.mjs.map +1 -0
- package/dist/esm/editor/markdown.native.js +238 -0
- package/dist/esm/editor/markdown.native.js.map +1 -0
- package/dist/esm/editor/mathematics.mjs +142 -0
- package/dist/esm/editor/mathematics.mjs.map +1 -0
- package/dist/esm/editor/mathematics.native.js +173 -0
- package/dist/esm/editor/mathematics.native.js.map +1 -0
- package/dist/esm/editor/media.mjs +113 -0
- package/dist/esm/editor/media.mjs.map +1 -0
- package/dist/esm/editor/media.native.js +144 -0
- package/dist/esm/editor/media.native.js.map +1 -0
- package/dist/esm/editor/mentions.mjs +37 -0
- package/dist/esm/editor/mentions.mjs.map +1 -0
- package/dist/esm/editor/mentions.native.js +45 -0
- package/dist/esm/editor/mentions.native.js.map +1 -0
- package/dist/esm/editor/pasteCleanup.mjs +57 -0
- package/dist/esm/editor/pasteCleanup.mjs.map +1 -0
- package/dist/esm/editor/pasteCleanup.native.js +146 -0
- package/dist/esm/editor/pasteCleanup.native.js.map +1 -0
- package/dist/esm/editor/suggestionPopup.mjs +268 -0
- package/dist/esm/editor/suggestionPopup.mjs.map +1 -0
- package/dist/esm/editor/suggestionPopup.native.js +295 -0
- package/dist/esm/editor/suggestionPopup.native.js.map +1 -0
- package/dist/esm/preview.mjs +236 -0
- package/dist/esm/preview.mjs.map +1 -0
- package/dist/esm/preview.native.js +264 -0
- package/dist/esm/preview.native.js.map +1 -0
- package/dist/esm/shared/t.mjs +17 -0
- package/dist/esm/shared/t.mjs.map +1 -0
- package/dist/esm/shared/t.native.js +17 -0
- package/dist/esm/shared/t.native.js.map +1 -0
- package/dist/esm/shared/url.mjs +10 -0
- package/dist/esm/shared/url.mjs.map +1 -0
- package/dist/esm/shared/url.native.js +10 -0
- package/dist/esm/shared/url.native.js.map +1 -0
- package/dist/esm/styled.mjs +13 -6
- package/dist/esm/styled.mjs.map +1 -1
- package/dist/esm/styled.native.js +13 -6
- package/dist/esm/styled.native.js.map +1 -1
- package/dist/esm/toolbar/BubbleToolbar.mjs +11 -9
- package/dist/esm/toolbar/BubbleToolbar.mjs.map +1 -1
- package/dist/esm/toolbar/BubbleToolbar.native.js +11 -9
- package/dist/esm/toolbar/BubbleToolbar.native.js.map +1 -1
- package/dist/esm/toolbar/CodeBlockBubble.mjs +60 -24
- package/dist/esm/toolbar/CodeBlockBubble.mjs.map +1 -1
- package/dist/esm/toolbar/CodeBlockBubble.native.js +72 -26
- package/dist/esm/toolbar/CodeBlockBubble.native.js.map +1 -1
- package/dist/esm/toolbar/ColorPicker.mjs +21 -56
- package/dist/esm/toolbar/ColorPicker.mjs.map +1 -1
- package/dist/esm/toolbar/ColorPicker.native.js +82 -180
- package/dist/esm/toolbar/ColorPicker.native.js.map +1 -1
- package/dist/esm/toolbar/FixedToolbar.mjs +34 -11
- package/dist/esm/toolbar/FixedToolbar.mjs.map +1 -1
- package/dist/esm/toolbar/FixedToolbar.native.js +47 -55
- package/dist/esm/toolbar/FixedToolbar.native.js.map +1 -1
- package/dist/esm/toolbar/HeadingPicker.mjs +34 -41
- package/dist/esm/toolbar/HeadingPicker.mjs.map +1 -1
- package/dist/esm/toolbar/HeadingPicker.native.js +63 -53
- package/dist/esm/toolbar/HeadingPicker.native.js.map +1 -1
- package/dist/esm/toolbar/ImageBubble.mjs +20 -43
- package/dist/esm/toolbar/ImageBubble.mjs.map +1 -1
- package/dist/esm/toolbar/ImageBubble.native.js +20 -43
- package/dist/esm/toolbar/ImageBubble.native.js.map +1 -1
- package/dist/esm/toolbar/ImageDialog.mjs +5 -4
- package/dist/esm/toolbar/ImageDialog.mjs.map +1 -1
- package/dist/esm/toolbar/ImageDialog.native.js +75 -64
- package/dist/esm/toolbar/ImageDialog.native.js.map +1 -1
- package/dist/esm/toolbar/LinkBubble.mjs +23 -70
- package/dist/esm/toolbar/LinkBubble.mjs.map +1 -1
- package/dist/esm/toolbar/LinkBubble.native.js +23 -70
- package/dist/esm/toolbar/LinkBubble.native.js.map +1 -1
- package/dist/esm/toolbar/LinkDialog.mjs +17 -16
- package/dist/esm/toolbar/LinkDialog.mjs.map +1 -1
- package/dist/esm/toolbar/LinkDialog.native.js +84 -80
- package/dist/esm/toolbar/LinkDialog.native.js.map +1 -1
- package/dist/esm/toolbar/ListPicker.mjs +33 -44
- package/dist/esm/toolbar/ListPicker.mjs.map +1 -1
- package/dist/esm/toolbar/ListPicker.native.js +44 -45
- package/dist/esm/toolbar/ListPicker.native.js.map +1 -1
- package/dist/esm/toolbar/MathBubble.mjs +134 -0
- package/dist/esm/toolbar/MathBubble.mjs.map +1 -0
- package/dist/esm/toolbar/MathBubble.native.js +141 -0
- package/dist/esm/toolbar/MathBubble.native.js.map +1 -0
- package/dist/esm/toolbar/MoreDropdown.mjs +50 -97
- package/dist/esm/toolbar/MoreDropdown.mjs.map +1 -1
- package/dist/esm/toolbar/MoreDropdown.native.js +72 -97
- package/dist/esm/toolbar/MoreDropdown.native.js.map +1 -1
- package/dist/esm/toolbar/StatusBar.mjs +19 -10
- package/dist/esm/toolbar/StatusBar.mjs.map +1 -1
- package/dist/esm/toolbar/StatusBar.native.js +19 -10
- package/dist/esm/toolbar/StatusBar.native.js.map +1 -1
- package/dist/esm/toolbar/TableBubble.mjs +77 -95
- package/dist/esm/toolbar/TableBubble.mjs.map +1 -1
- package/dist/esm/toolbar/TableBubble.native.js +73 -71
- package/dist/esm/toolbar/TableBubble.native.js.map +1 -1
- package/dist/esm/toolbar/ToolbarButton.mjs +87 -22
- package/dist/esm/toolbar/ToolbarButton.mjs.map +1 -1
- package/dist/esm/toolbar/ToolbarButton.native.js +14 -4
- package/dist/esm/toolbar/ToolbarButton.native.js.map +1 -1
- package/dist/esm/toolbar/icons.mjs +109 -469
- package/dist/esm/toolbar/icons.mjs.map +1 -1
- package/dist/esm/toolbar/shortcuts.mjs +73 -24
- package/dist/esm/toolbar/shortcuts.mjs.map +1 -1
- package/dist/esm/toolbar/shortcuts.native.js +73 -24
- package/dist/esm/toolbar/shortcuts.native.js.map +1 -1
- package/dist/esm/toolbar/useHorizontalScroll.mjs +25 -6
- package/dist/esm/toolbar/useHorizontalScroll.mjs.map +1 -1
- package/dist/esm/toolbar/useHorizontalScroll.native.js +25 -6
- package/dist/esm/toolbar/useHorizontalScroll.native.js.map +1 -1
- package/dist/esm/toolbar/useRovingFocus.mjs +55 -0
- package/dist/esm/toolbar/useRovingFocus.mjs.map +1 -0
- package/dist/esm/toolbar/useRovingFocus.native.js +85 -0
- package/dist/esm/toolbar/useRovingFocus.native.js.map +1 -0
- package/dist/esm/types.mjs.map +1 -1
- package/dist/esm/types.native.js.map +1 -1
- package/dist/jsx/RichEditor.mjs +85 -10
- package/dist/jsx/RichEditor.mjs.map +1 -1
- package/dist/jsx/RichEditor.native.js +422 -35
- package/dist/jsx/RichEditor.native.js.map +1 -1
- package/dist/jsx/RichTextEditor/index.mjs +18 -2
- package/dist/jsx/RichTextEditor/index.mjs.map +1 -1
- package/dist/jsx/RichTextEditor/index.native.js +18 -2
- package/dist/jsx/RichTextEditor/index.native.js.map +1 -1
- package/dist/jsx/constants.mjs +47 -29
- package/dist/jsx/constants.mjs.map +1 -1
- package/dist/jsx/constants.native.js +59 -29
- package/dist/jsx/constants.native.js.map +1 -1
- package/dist/jsx/editor/BlockDragHandle.mjs +22 -7
- package/dist/jsx/editor/BlockDragHandle.mjs.map +1 -1
- package/dist/jsx/editor/BlockDragHandle.native.js +41 -7
- package/dist/jsx/editor/BlockDragHandle.native.js.map +1 -1
- package/dist/jsx/editor/SlashCommands.mjs +250 -294
- package/dist/jsx/editor/SlashCommands.mjs.map +1 -1
- package/dist/jsx/editor/SlashCommands.native.js +306 -340
- package/dist/jsx/editor/SlashCommands.native.js.map +1 -1
- package/dist/jsx/editor/TentapEditor.native.js +44 -12
- package/dist/jsx/editor/TentapEditor.native.js.map +1 -1
- package/dist/jsx/editor/TiptapEditor.mjs +142 -35
- package/dist/jsx/editor/TiptapEditor.mjs.map +1 -1
- package/dist/jsx/editor/TiptapEditor.native.js +153 -33
- package/dist/jsx/editor/TiptapEditor.native.js.map +1 -1
- package/dist/jsx/editor/blockAnchor.mjs +18 -0
- package/dist/jsx/editor/blockAnchor.mjs.map +1 -0
- package/dist/jsx/editor/blockAnchor.native.js +68 -0
- package/dist/jsx/editor/blockAnchor.native.js.map +1 -0
- package/dist/jsx/editor/codeBlockPreview.mjs +190 -0
- package/dist/jsx/editor/codeBlockPreview.mjs.map +1 -0
- package/dist/jsx/editor/codeBlockPreview.native.js +265 -0
- package/dist/jsx/editor/codeBlockPreview.native.js.map +1 -0
- package/dist/jsx/editor/editorStyles.mjs +203 -34
- package/dist/jsx/editor/editorStyles.mjs.map +1 -1
- package/dist/jsx/editor/editorStyles.native.js +203 -34
- package/dist/jsx/editor/editorStyles.native.js.map +1 -1
- package/dist/jsx/editor/emoji.mjs +88 -0
- package/dist/jsx/editor/emoji.mjs.map +1 -0
- package/dist/jsx/editor/emoji.native.js +184 -0
- package/dist/jsx/editor/emoji.native.js.map +1 -0
- package/dist/jsx/editor/lazyKatex.mjs +40 -0
- package/dist/jsx/editor/lazyKatex.mjs.map +1 -0
- package/dist/jsx/editor/lazyKatex.native.js +117 -0
- package/dist/jsx/editor/lazyKatex.native.js.map +1 -0
- package/dist/jsx/editor/markdown.mjs +179 -0
- package/dist/jsx/editor/markdown.mjs.map +1 -0
- package/dist/jsx/editor/markdown.native.js +278 -0
- package/dist/jsx/editor/markdown.native.js.map +1 -0
- package/dist/jsx/editor/mathematics.mjs +142 -0
- package/dist/jsx/editor/mathematics.mjs.map +1 -0
- package/dist/jsx/editor/mathematics.native.js +202 -0
- package/dist/jsx/editor/mathematics.native.js.map +1 -0
- package/dist/jsx/editor/media.mjs +113 -0
- package/dist/jsx/editor/media.mjs.map +1 -0
- package/dist/jsx/editor/media.native.js +172 -0
- package/dist/jsx/editor/media.native.js.map +1 -0
- package/dist/jsx/editor/mentions.mjs +37 -0
- package/dist/jsx/editor/mentions.mjs.map +1 -0
- package/dist/jsx/editor/mentions.native.js +84 -0
- package/dist/jsx/editor/mentions.native.js.map +1 -0
- package/dist/jsx/editor/pasteCleanup.mjs +57 -0
- package/dist/jsx/editor/pasteCleanup.mjs.map +1 -0
- package/dist/jsx/editor/pasteCleanup.native.js +175 -0
- package/dist/jsx/editor/pasteCleanup.native.js.map +1 -0
- package/dist/jsx/editor/suggestionPopup.mjs +268 -0
- package/dist/jsx/editor/suggestionPopup.mjs.map +1 -0
- package/dist/jsx/editor/suggestionPopup.native.js +327 -0
- package/dist/jsx/editor/suggestionPopup.native.js.map +1 -0
- package/dist/jsx/preview.mjs +236 -0
- package/dist/jsx/preview.mjs.map +1 -0
- package/dist/jsx/preview.native.js +294 -0
- package/dist/jsx/preview.native.js.map +1 -0
- package/dist/jsx/shared/t.mjs +17 -0
- package/dist/jsx/shared/t.mjs.map +1 -0
- package/dist/jsx/shared/t.native.js +56 -0
- package/dist/jsx/shared/t.native.js.map +1 -0
- package/dist/jsx/shared/url.mjs +10 -0
- package/dist/jsx/shared/url.mjs.map +1 -0
- package/dist/jsx/shared/url.native.js +38 -0
- package/dist/jsx/shared/url.native.js.map +1 -0
- package/dist/jsx/styled.mjs +13 -6
- package/dist/jsx/styled.mjs.map +1 -1
- package/dist/jsx/styled.native.js +13 -6
- package/dist/jsx/styled.native.js.map +1 -1
- package/dist/jsx/toolbar/BubbleToolbar.mjs +11 -9
- package/dist/jsx/toolbar/BubbleToolbar.mjs.map +1 -1
- package/dist/jsx/toolbar/BubbleToolbar.native.js +10 -8
- package/dist/jsx/toolbar/BubbleToolbar.native.js.map +1 -1
- package/dist/jsx/toolbar/CodeBlockBubble.mjs +60 -24
- package/dist/jsx/toolbar/CodeBlockBubble.mjs.map +1 -1
- package/dist/jsx/toolbar/CodeBlockBubble.native.js +71 -25
- package/dist/jsx/toolbar/CodeBlockBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/ColorPicker.mjs +21 -56
- package/dist/jsx/toolbar/ColorPicker.mjs.map +1 -1
- package/dist/jsx/toolbar/ColorPicker.native.js +81 -179
- package/dist/jsx/toolbar/ColorPicker.native.js.map +1 -1
- package/dist/jsx/toolbar/FixedToolbar.mjs +34 -11
- package/dist/jsx/toolbar/FixedToolbar.mjs.map +1 -1
- package/dist/jsx/toolbar/FixedToolbar.native.js +46 -54
- package/dist/jsx/toolbar/FixedToolbar.native.js.map +1 -1
- package/dist/jsx/toolbar/HeadingPicker.mjs +34 -41
- package/dist/jsx/toolbar/HeadingPicker.mjs.map +1 -1
- package/dist/jsx/toolbar/HeadingPicker.native.js +61 -51
- package/dist/jsx/toolbar/HeadingPicker.native.js.map +1 -1
- package/dist/jsx/toolbar/ImageBubble.mjs +20 -43
- package/dist/jsx/toolbar/ImageBubble.mjs.map +1 -1
- package/dist/jsx/toolbar/ImageBubble.native.js +20 -43
- package/dist/jsx/toolbar/ImageBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/ImageDialog.mjs +5 -4
- package/dist/jsx/toolbar/ImageDialog.mjs.map +1 -1
- package/dist/jsx/toolbar/ImageDialog.native.js +76 -65
- package/dist/jsx/toolbar/ImageDialog.native.js.map +1 -1
- package/dist/jsx/toolbar/LinkBubble.mjs +23 -70
- package/dist/jsx/toolbar/LinkBubble.mjs.map +1 -1
- package/dist/jsx/toolbar/LinkBubble.native.js +23 -70
- package/dist/jsx/toolbar/LinkBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/LinkDialog.mjs +17 -16
- package/dist/jsx/toolbar/LinkDialog.mjs.map +1 -1
- package/dist/jsx/toolbar/LinkDialog.native.js +86 -83
- package/dist/jsx/toolbar/LinkDialog.native.js.map +1 -1
- package/dist/jsx/toolbar/ListPicker.mjs +33 -44
- package/dist/jsx/toolbar/ListPicker.mjs.map +1 -1
- package/dist/jsx/toolbar/ListPicker.native.js +43 -44
- package/dist/jsx/toolbar/ListPicker.native.js.map +1 -1
- package/dist/jsx/toolbar/MathBubble.mjs +134 -0
- package/dist/jsx/toolbar/MathBubble.mjs.map +1 -0
- package/dist/jsx/toolbar/MathBubble.native.js +169 -0
- package/dist/jsx/toolbar/MathBubble.native.js.map +1 -0
- package/dist/jsx/toolbar/MoreDropdown.mjs +50 -97
- package/dist/jsx/toolbar/MoreDropdown.mjs.map +1 -1
- package/dist/jsx/toolbar/MoreDropdown.native.js +73 -98
- package/dist/jsx/toolbar/MoreDropdown.native.js.map +1 -1
- package/dist/jsx/toolbar/StatusBar.mjs +19 -10
- package/dist/jsx/toolbar/StatusBar.mjs.map +1 -1
- package/dist/jsx/toolbar/StatusBar.native.js +19 -10
- package/dist/jsx/toolbar/StatusBar.native.js.map +1 -1
- package/dist/jsx/toolbar/TableBubble.mjs +77 -95
- package/dist/jsx/toolbar/TableBubble.mjs.map +1 -1
- package/dist/jsx/toolbar/TableBubble.native.js +73 -71
- package/dist/jsx/toolbar/TableBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/ToolbarButton.mjs +87 -22
- package/dist/jsx/toolbar/ToolbarButton.mjs.map +1 -1
- package/dist/jsx/toolbar/ToolbarButton.native.js +14 -4
- package/dist/jsx/toolbar/ToolbarButton.native.js.map +1 -1
- package/dist/jsx/toolbar/icons.mjs +109 -469
- package/dist/jsx/toolbar/icons.mjs.map +1 -1
- package/dist/jsx/toolbar/shortcuts.mjs +73 -24
- package/dist/jsx/toolbar/shortcuts.mjs.map +1 -1
- package/dist/jsx/toolbar/shortcuts.native.js +73 -24
- package/dist/jsx/toolbar/shortcuts.native.js.map +1 -1
- package/dist/jsx/toolbar/useHorizontalScroll.mjs +25 -6
- package/dist/jsx/toolbar/useHorizontalScroll.mjs.map +1 -1
- package/dist/jsx/toolbar/useHorizontalScroll.native.js +25 -5
- package/dist/jsx/toolbar/useHorizontalScroll.native.js.map +1 -1
- package/dist/jsx/toolbar/useRovingFocus.mjs +55 -0
- package/dist/jsx/toolbar/useRovingFocus.mjs.map +1 -0
- package/dist/jsx/toolbar/useRovingFocus.native.js +113 -0
- package/dist/jsx/toolbar/useRovingFocus.native.js.map +1 -0
- package/dist/jsx/types.mjs.map +1 -1
- package/dist/jsx/types.native.js.map +1 -1
- package/package.json +28 -13
- package/src/RichEditor.native.tsx +451 -49
- package/src/RichEditor.stories.tsx +158 -0
- package/src/RichEditor.tsx +121 -7
- package/src/RichTextEditor/index.tsx +41 -3
- package/src/RichTextEditor/richTextEditor.spec.tsx +11 -4
- package/src/constants.ts +86 -24
- package/src/editor/BlockDragHandle.ts +30 -5
- package/src/editor/SlashCommands.tsx +228 -293
- package/src/editor/TentapEditor.native.tsx +68 -17
- package/src/editor/TiptapEditor.tsx +187 -22
- package/src/editor/blockAnchor.spec.ts +70 -0
- package/src/editor/blockAnchor.ts +42 -0
- package/src/editor/codeBlockPreview.spec.ts +144 -0
- package/src/editor/codeBlockPreview.ts +266 -0
- package/src/editor/css.d.ts +2 -0
- package/src/editor/details.spec.ts +48 -0
- package/src/editor/editorStyles.spec.ts +25 -0
- package/src/editor/editorStyles.ts +218 -34
- package/src/editor/emoji.spec.ts +88 -0
- package/src/editor/emoji.ts +147 -0
- package/src/editor/emojilib.d.ts +16 -0
- package/src/editor/lazyKatex.spec.ts +38 -0
- package/src/editor/lazyKatex.ts +68 -0
- package/src/editor/markdown.spec.ts +196 -0
- package/src/editor/markdown.ts +249 -0
- package/src/editor/mathematics.spec.ts +97 -0
- package/src/editor/mathematics.ts +179 -0
- package/src/editor/media.spec.ts +121 -0
- package/src/editor/media.ts +133 -0
- package/src/editor/mentions.spec.ts +41 -0
- package/src/editor/mentions.ts +55 -0
- package/src/editor/pasteCleanup.spec.ts +84 -0
- package/src/editor/pasteCleanup.ts +124 -0
- package/src/editor/suggestionPopup.spec.tsx +105 -0
- package/src/editor/suggestionPopup.tsx +414 -0
- package/src/editor/tiptapEditor.spec.tsx +15 -8
- package/src/exports.spec.ts +4 -2
- package/src/index.ts +7 -1
- package/src/integration.spec.tsx +38 -9
- package/src/preview.spec.ts +130 -0
- package/src/preview.ts +287 -0
- package/src/richEditor.spec.tsx +10 -3
- package/src/shared/t.ts +25 -0
- package/src/shared/url.ts +16 -0
- package/src/styled.ts +13 -6
- package/src/toolbar/BubbleToolbar.tsx +11 -8
- package/src/toolbar/CodeBlockBubble.tsx +66 -28
- package/src/toolbar/ColorPicker.native.tsx +126 -0
- package/src/toolbar/ColorPicker.tsx +23 -67
- package/src/toolbar/FixedToolbar.native.tsx +51 -51
- package/src/toolbar/FixedToolbar.tsx +54 -10
- package/src/toolbar/HeadingPicker.tsx +46 -38
- package/src/toolbar/ImageBubble.tsx +26 -44
- package/src/toolbar/ImageDialog.native.tsx +97 -0
- package/src/toolbar/ImageDialog.tsx +5 -4
- package/src/toolbar/LinkBubble.tsx +27 -64
- package/src/toolbar/LinkDialog.native.tsx +117 -0
- package/src/toolbar/LinkDialog.tsx +28 -24
- package/src/toolbar/ListPicker.tsx +47 -43
- package/src/toolbar/MathBubble.tsx +140 -0
- package/src/toolbar/MoreDropdown.tsx +53 -60
- package/src/toolbar/StatusBar.tsx +13 -8
- package/src/toolbar/TableBubble.tsx +82 -94
- package/src/toolbar/ToolbarButton.native.tsx +14 -4
- package/src/toolbar/ToolbarButton.tsx +98 -19
- package/src/toolbar/bubbleToolbar.spec.tsx +2 -1
- package/src/toolbar/fixedToolbar.spec.tsx +4 -2
- package/src/toolbar/icons.tsx +113 -323
- package/src/toolbar/shortcuts.ts +77 -24
- package/src/toolbar/toolbarPrimitives.spec.tsx +29 -1
- package/src/toolbar/toolbarSubComponents.spec.tsx +4 -2
- package/src/toolbar/useHorizontalScroll.spec.ts +67 -0
- package/src/toolbar/useHorizontalScroll.tsx +39 -12
- package/src/toolbar/useRovingFocus.spec.tsx +100 -0
- package/src/toolbar/useRovingFocus.ts +82 -0
- package/src/types.spec.ts +40 -1
- package/src/types.ts +28 -0
- package/types/RichEditor.d.ts +51 -0
- package/types/RichEditor.d.ts.map +1 -0
- package/types/RichEditor.native.d.ts +59 -0
- package/types/RichEditor.native.d.ts.map +1 -0
- package/types/RichTextEditor/index.d.ts +71 -0
- package/types/RichTextEditor/index.d.ts.map +1 -0
- package/types/constants.d.ts +49 -0
- package/types/constants.d.ts.map +1 -0
- package/types/context.d.ts +10 -0
- package/types/context.d.ts.map +1 -0
- package/types/editor/BlockDragHandle.d.ts +8 -0
- package/types/editor/BlockDragHandle.d.ts.map +1 -0
- package/types/editor/MarkdownPaste.d.ts +8 -0
- package/types/editor/MarkdownPaste.d.ts.map +1 -0
- package/types/editor/SlashCommands.d.ts +24 -0
- package/types/editor/SlashCommands.d.ts.map +1 -0
- package/types/editor/TentapEditor.native.d.ts +21 -0
- package/types/editor/TentapEditor.native.d.ts.map +1 -0
- package/types/editor/TiptapEditor.d.ts +24 -0
- package/types/editor/TiptapEditor.d.ts.map +1 -0
- package/types/editor/blockAnchor.d.ts +25 -0
- package/types/editor/blockAnchor.d.ts.map +1 -0
- package/types/editor/codeBlockPreview.d.ts +51 -0
- package/types/editor/codeBlockPreview.d.ts.map +1 -0
- package/types/editor/editorStyles.d.ts +25 -0
- package/types/editor/editorStyles.d.ts.map +1 -0
- package/types/editor/emoji.d.ts +45 -0
- package/types/editor/emoji.d.ts.map +1 -0
- package/types/editor/index.d.ts +11 -0
- package/types/editor/index.d.ts.map +1 -0
- package/types/editor/lazyKatex.d.ts +33 -0
- package/types/editor/lazyKatex.d.ts.map +1 -0
- package/types/editor/markdown.d.ts +24 -0
- package/types/editor/markdown.d.ts.map +1 -0
- package/types/editor/mathematics.d.ts +44 -0
- package/types/editor/mathematics.d.ts.map +1 -0
- package/types/editor/media.d.ts +32 -0
- package/types/editor/media.d.ts.map +1 -0
- package/types/editor/mentions.d.ts +15 -0
- package/types/editor/mentions.d.ts.map +1 -0
- package/types/editor/pasteCleanup.d.ts +24 -0
- package/types/editor/pasteCleanup.d.ts.map +1 -0
- package/types/editor/suggestionPopup.d.ts +113 -0
- package/types/editor/suggestionPopup.d.ts.map +1 -0
- package/types/editor/types.d.ts +80 -0
- package/types/editor/types.d.ts.map +1 -0
- package/types/editor/useEditorState.d.ts +19 -0
- package/types/editor/useEditorState.d.ts.map +1 -0
- package/types/index.d.ts +11 -0
- package/types/index.d.ts.map +1 -0
- package/types/preview.d.ts +44 -0
- package/types/preview.d.ts.map +1 -0
- package/types/shared/t.d.ts +10 -0
- package/types/shared/t.d.ts.map +1 -0
- package/types/shared/url.d.ts +9 -0
- package/types/shared/url.d.ts.map +1 -0
- package/types/styled.d.ts +40 -0
- package/types/styled.d.ts.map +1 -0
- package/types/toolbar/BubbleToolbar.d.ts +23 -0
- package/types/toolbar/BubbleToolbar.d.ts.map +1 -0
- package/types/toolbar/CodeBlockBubble.d.ts +10 -0
- package/types/toolbar/CodeBlockBubble.d.ts.map +1 -0
- package/types/toolbar/ColorPicker.d.ts +15 -0
- package/types/toolbar/ColorPicker.d.ts.map +1 -0
- package/types/toolbar/ColorPicker.native.d.ts +20 -0
- package/types/toolbar/ColorPicker.native.d.ts.map +1 -0
- package/types/toolbar/FixedToolbar.d.ts +32 -0
- package/types/toolbar/FixedToolbar.d.ts.map +1 -0
- package/types/toolbar/FixedToolbar.native.d.ts +30 -0
- package/types/toolbar/FixedToolbar.native.d.ts.map +1 -0
- package/types/toolbar/HeadingPicker.d.ts +14 -0
- package/types/toolbar/HeadingPicker.d.ts.map +1 -0
- package/types/toolbar/ImageBubble.d.ts +10 -0
- package/types/toolbar/ImageBubble.d.ts.map +1 -0
- package/types/toolbar/ImageDialog.d.ts +12 -0
- package/types/toolbar/ImageDialog.d.ts.map +1 -0
- package/types/toolbar/ImageDialog.native.d.ts +15 -0
- package/types/toolbar/ImageDialog.native.d.ts.map +1 -0
- package/types/toolbar/LinkBubble.d.ts +10 -0
- package/types/toolbar/LinkBubble.d.ts.map +1 -0
- package/types/toolbar/LinkDialog.d.ts +20 -0
- package/types/toolbar/LinkDialog.d.ts.map +1 -0
- package/types/toolbar/LinkDialog.native.d.ts +18 -0
- package/types/toolbar/LinkDialog.native.d.ts.map +1 -0
- package/types/toolbar/ListPicker.d.ts +14 -0
- package/types/toolbar/ListPicker.d.ts.map +1 -0
- package/types/toolbar/MathBubble.d.ts +11 -0
- package/types/toolbar/MathBubble.d.ts.map +1 -0
- package/types/toolbar/MoreDropdown.d.ts +13 -0
- package/types/toolbar/MoreDropdown.d.ts.map +1 -0
- package/types/toolbar/ResizeHandle.d.ts +11 -0
- package/types/toolbar/ResizeHandle.d.ts.map +1 -0
- package/types/toolbar/StatusBar.d.ts +11 -0
- package/types/toolbar/StatusBar.d.ts.map +1 -0
- package/types/toolbar/TableBubble.d.ts +10 -0
- package/types/toolbar/TableBubble.d.ts.map +1 -0
- package/types/toolbar/ToolbarButton.d.ts +35 -0
- package/types/toolbar/ToolbarButton.d.ts.map +1 -0
- package/types/toolbar/ToolbarButton.native.d.ts +30 -0
- package/types/toolbar/ToolbarButton.native.d.ts.map +1 -0
- package/types/toolbar/ToolbarGroup.d.ts +14 -0
- package/types/toolbar/ToolbarGroup.d.ts.map +1 -0
- package/types/toolbar/icons.d.ts +52 -0
- package/types/toolbar/icons.d.ts.map +1 -0
- package/types/toolbar/icons.native.d.ts +41 -0
- package/types/toolbar/icons.native.d.ts.map +1 -0
- package/types/toolbar/shortcuts.d.ts +34 -0
- package/types/toolbar/shortcuts.d.ts.map +1 -0
- package/types/toolbar/useHorizontalScroll.d.ts +43 -0
- package/types/toolbar/useHorizontalScroll.d.ts.map +1 -0
- package/types/toolbar/useRovingFocus.d.ts +10 -0
- package/types/toolbar/useRovingFocus.d.ts.map +1 -0
- package/types/types.d.ts +125 -0
- package/types/types.d.ts.map +1 -0
- package/dist/cjs/RichEditor.stories.cjs +0 -327
- package/dist/cjs/RichEditor.stories.native.js +0 -342
- package/dist/cjs/RichEditor.stories.native.js.map +0 -1
- package/dist/esm/RichEditor.stories.mjs +0 -291
- package/dist/esm/RichEditor.stories.mjs.map +0 -1
- package/dist/esm/RichEditor.stories.native.js +0 -303
- package/dist/esm/RichEditor.stories.native.js.map +0 -1
- package/dist/jsx/RichEditor.stories.mjs +0 -291
- package/dist/jsx/RichEditor.stories.mjs.map +0 -1
- package/dist/jsx/RichEditor.stories.native.js +0 -342
- package/dist/jsx/RichEditor.stories.native.js.map +0 -1
|
@@ -13,7 +13,14 @@
|
|
|
13
13
|
* No BubbleToolbar (10Tap does not support floating menus).
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
forwardRef,
|
|
18
|
+
useCallback,
|
|
19
|
+
useEffect,
|
|
20
|
+
useImperativeHandle,
|
|
21
|
+
useRef,
|
|
22
|
+
type ForwardedRef,
|
|
23
|
+
} from "react";
|
|
17
24
|
import { StyleSheet, useColorScheme } from "react-native";
|
|
18
25
|
import {
|
|
19
26
|
RichText,
|
|
@@ -29,15 +36,17 @@ import {
|
|
|
29
36
|
darkEditorCss,
|
|
30
37
|
darkEditorTheme,
|
|
31
38
|
} from "@10play/tentap-editor";
|
|
32
|
-
import { View, useThemeName } from "tamagui";
|
|
39
|
+
import { View, useTheme, useThemeName } from "tamagui";
|
|
33
40
|
import type { RichEditorProps, RichEditorRef, EditorCommand } from "../types";
|
|
34
41
|
import { RichEditorContext } from "../context";
|
|
42
|
+
import { PALETTE_THEME_TOKENS } from "../constants";
|
|
43
|
+
import { t } from "../shared/t";
|
|
35
44
|
import { getEditorStateFromBridge } from "./useEditorState";
|
|
36
45
|
|
|
37
46
|
function useNativeEditorDarkMode(): boolean {
|
|
38
47
|
const themeName = useThemeName();
|
|
39
48
|
const osScheme = useColorScheme();
|
|
40
|
-
if (themeName
|
|
49
|
+
if (themeName) {
|
|
41
50
|
return String(themeName).startsWith("dark");
|
|
42
51
|
}
|
|
43
52
|
return osScheme === "dark";
|
|
@@ -47,23 +56,32 @@ function useNativeEditorDarkMode(): boolean {
|
|
|
47
56
|
// TentapEditor
|
|
48
57
|
// ===========================================================================
|
|
49
58
|
|
|
50
|
-
export
|
|
59
|
+
export interface TentapEditorProps extends RichEditorProps {
|
|
60
|
+
/** Fill the available space (fullscreen modal) instead of using minHeight */
|
|
61
|
+
fill?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Avoid `forwardRef<A, B>(...)` — Metro/Babel TSX can parse the `>` as JSX and
|
|
65
|
+
// throw "Missing initializer in const declaration". Cast instead.
|
|
66
|
+
export const TentapEditor = forwardRef(
|
|
51
67
|
(
|
|
52
68
|
{
|
|
53
69
|
initialContent = "",
|
|
54
70
|
initialJSON,
|
|
55
|
-
placeholder
|
|
71
|
+
placeholder: placeholderProp,
|
|
56
72
|
editable = true,
|
|
57
73
|
autoFocus = false,
|
|
58
74
|
onChange,
|
|
59
75
|
onStateChange,
|
|
60
76
|
minHeight = 150,
|
|
61
77
|
maxHeight,
|
|
78
|
+
fill = false,
|
|
62
79
|
hasError: _hasError,
|
|
63
|
-
},
|
|
64
|
-
ref
|
|
80
|
+
}: TentapEditorProps,
|
|
81
|
+
ref: ForwardedRef<RichEditorRef>,
|
|
65
82
|
) => {
|
|
66
83
|
const ctx = RichEditorContext.useStyledContext();
|
|
84
|
+
const placeholder = placeholderProp ?? t("Start writing...");
|
|
67
85
|
const isDarkMode = useNativeEditorDarkMode();
|
|
68
86
|
const cachedHtml = useRef<string>("");
|
|
69
87
|
const cachedJson = useRef<any>(null);
|
|
@@ -82,7 +100,9 @@ export const TentapEditor = forwardRef<RichEditorRef, RichEditorProps>(
|
|
|
82
100
|
}),
|
|
83
101
|
],
|
|
84
102
|
theme: isDarkMode ? darkEditorTheme : undefined,
|
|
85
|
-
|
|
103
|
+
// Tentap accepts HTML string OR a ProseMirror JSON object. Never
|
|
104
|
+
// JSON.stringify the object — that loads as broken HTML and wipes the doc.
|
|
105
|
+
initialContent: (initialJSON as any) ?? initialContent,
|
|
86
106
|
autofocus: autoFocus,
|
|
87
107
|
editable,
|
|
88
108
|
onChange: async () => {
|
|
@@ -111,6 +131,22 @@ export const TentapEditor = forwardRef<RichEditorRef, RichEditorProps>(
|
|
|
111
131
|
return () => clearTimeout(id);
|
|
112
132
|
}, [editor, isDarkMode]);
|
|
113
133
|
|
|
134
|
+
// Web-authored color/highlight marks store theme custom properties
|
|
135
|
+
// (`var(--red11)`); the 10Tap webview has no tamagui stylesheet, so
|
|
136
|
+
// define the palette vars there from the active theme (Axiom 5: same
|
|
137
|
+
// tokens, resolved once per scheme).
|
|
138
|
+
const theme = useTheme();
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
const id = setTimeout(() => {
|
|
141
|
+
const decls = PALETTE_THEME_TOKENS.map((token) => {
|
|
142
|
+
const value = (theme as any)[token]?.val;
|
|
143
|
+
return value ? `--${token}: ${value};` : "";
|
|
144
|
+
}).join(" ");
|
|
145
|
+
editor.injectCSS(`:root { ${decls} }`, "multiplatform-tentap-palette");
|
|
146
|
+
}, 150);
|
|
147
|
+
return () => clearTimeout(id);
|
|
148
|
+
}, [editor, theme]);
|
|
149
|
+
|
|
114
150
|
// Subscribe to editor state updates
|
|
115
151
|
useEffect(() => {
|
|
116
152
|
const unsubscribe = editor._subscribeToEditorStateUpdate((state: any) => {
|
|
@@ -209,13 +245,24 @@ export const TentapEditor = forwardRef<RichEditorRef, RichEditorProps>(
|
|
|
209
245
|
break;
|
|
210
246
|
|
|
211
247
|
case "textColor":
|
|
212
|
-
|
|
213
|
-
|
|
248
|
+
// null clears (Default swatch); undefined/missing is a no-op so a
|
|
249
|
+
// bare toolbar tap cannot call setColor(undefined) and wipe content
|
|
250
|
+
// (SB-N-ios-25).
|
|
251
|
+
if (payload && "color" in payload) {
|
|
252
|
+
if (typeof payload.color === "string" && payload.color.length > 0) {
|
|
253
|
+
editor.setColor(payload.color);
|
|
254
|
+
} else {
|
|
255
|
+
editor.unsetColor();
|
|
256
|
+
}
|
|
214
257
|
}
|
|
215
258
|
break;
|
|
216
259
|
case "highlight":
|
|
217
|
-
if (payload
|
|
218
|
-
|
|
260
|
+
if (payload && "color" in payload) {
|
|
261
|
+
if (typeof payload.color === "string" && payload.color.length > 0) {
|
|
262
|
+
editor.setHighlight(payload.color);
|
|
263
|
+
} else {
|
|
264
|
+
editor.unsetHighlight();
|
|
265
|
+
}
|
|
219
266
|
}
|
|
220
267
|
break;
|
|
221
268
|
|
|
@@ -238,7 +285,7 @@ export const TentapEditor = forwardRef<RichEditorRef, RichEditorProps>(
|
|
|
238
285
|
getHTML: () => cachedHtml.current,
|
|
239
286
|
getJSON: () => cachedJson.current,
|
|
240
287
|
setHTML: (html: string) => editor.setContent(html),
|
|
241
|
-
setJSON: (json: any) => editor.setContent(
|
|
288
|
+
setJSON: (json: any) => editor.setContent(json),
|
|
242
289
|
focus: () => editor.focus(),
|
|
243
290
|
blur: () => editor.blur(),
|
|
244
291
|
}),
|
|
@@ -247,13 +294,14 @@ export const TentapEditor = forwardRef<RichEditorRef, RichEditorProps>(
|
|
|
247
294
|
|
|
248
295
|
return (
|
|
249
296
|
<View
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
297
|
+
flex={fill ? 1 : undefined}
|
|
298
|
+
minHeight={fill ? undefined : minHeight}
|
|
299
|
+
maxHeight={fill ? undefined : maxHeight}
|
|
300
|
+
backgroundColor={ctx.disabled ? "$color3" : fill ? "$background" : "$color2"}
|
|
253
301
|
overflow="hidden"
|
|
254
302
|
opacity={ctx.disabled ? 0.5 : 1}
|
|
255
303
|
>
|
|
256
|
-
<RichText editor={editor} style={styles.editor} />
|
|
304
|
+
<RichText editor={editor} style={fill ? styles.editorFill : styles.editor} />
|
|
257
305
|
</View>
|
|
258
306
|
);
|
|
259
307
|
},
|
|
@@ -266,4 +314,7 @@ const styles = StyleSheet.create({
|
|
|
266
314
|
flex: 1,
|
|
267
315
|
minHeight: 150,
|
|
268
316
|
},
|
|
317
|
+
editorFill: {
|
|
318
|
+
flex: 1,
|
|
319
|
+
},
|
|
269
320
|
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
memo,
|
|
14
14
|
useCallback,
|
|
15
15
|
useEffect,
|
|
16
|
+
useId,
|
|
16
17
|
useImperativeHandle,
|
|
17
18
|
useMemo,
|
|
18
19
|
useRef,
|
|
@@ -31,35 +32,51 @@ import { Superscript } from "@tiptap/extension-superscript";
|
|
|
31
32
|
import TaskList from "@tiptap/extension-task-list";
|
|
32
33
|
import TaskItem from "@tiptap/extension-task-item";
|
|
33
34
|
import Image from "@tiptap/extension-image";
|
|
34
|
-
import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
|
|
35
35
|
import Typography from "@tiptap/extension-typography";
|
|
36
36
|
import CharacterCount from "@tiptap/extension-character-count";
|
|
37
|
+
import { Details, DetailsContent, DetailsSummary } from "@tiptap/extension-details";
|
|
37
38
|
|
|
38
39
|
import { Table } from "@tiptap/extension-table";
|
|
39
40
|
import { TableRow } from "@tiptap/extension-table-row";
|
|
40
41
|
import { TableHeader } from "@tiptap/extension-table-header";
|
|
41
42
|
import { TableCell } from "@tiptap/extension-table-cell";
|
|
42
43
|
import { common, createLowlight } from "lowlight";
|
|
43
|
-
import
|
|
44
|
-
import { marked } from "marked";
|
|
45
|
-
import { View, styled } from "tamagui";
|
|
44
|
+
import { View, getTokens, styled, useTheme, useThemeName } from "tamagui";
|
|
46
45
|
import { isWeb } from "@tamagui/constants";
|
|
46
|
+
import { menuRowFrame, useResolvedKnobs } from "@multiplatform.one/theme";
|
|
47
|
+
import { clampRadiusForLargeComponent } from "@multiplatform.one/forms";
|
|
47
48
|
import type { RichEditorProps, RichEditorRef, EditorCommand } from "../types";
|
|
48
49
|
import { defaultEditorState } from "../types";
|
|
49
50
|
import { RichEditorContext } from "../context";
|
|
51
|
+
import { t } from "../shared/t";
|
|
50
52
|
import { getEditorCSS } from "./editorStyles";
|
|
51
53
|
import { SlashCommands } from "./SlashCommands";
|
|
52
54
|
import { MarkdownPaste } from "./MarkdownPaste";
|
|
53
55
|
import { BlockDragHandle } from "./BlockDragHandle";
|
|
56
|
+
import { MediaUpload } from "./media";
|
|
57
|
+
import { createMentionExtension } from "./mentions";
|
|
58
|
+
import { EmojiSuggestion } from "./emoji";
|
|
59
|
+
import { InlineMath } from "./mathematics";
|
|
60
|
+
import { CodeBlockWithPreview, PreviewChromeStore, setPreviewChrome } from "./codeBlockPreview";
|
|
61
|
+
import { htmlToMarkdown, markdownToHtml } from "./markdown";
|
|
62
|
+
import { cleanPastedHtml } from "./pasteCleanup";
|
|
63
|
+
import {
|
|
64
|
+
SuggestionChromeStore,
|
|
65
|
+
fallbackSuggestionChrome,
|
|
66
|
+
type SuggestionChrome,
|
|
67
|
+
} from "./suggestionPopup";
|
|
54
68
|
import { getEditorStateFromTiptap } from "./useEditorState";
|
|
55
69
|
import { BubbleToolbar } from "../toolbar/BubbleToolbar";
|
|
56
70
|
import { LinkBubble } from "../toolbar/LinkBubble";
|
|
57
71
|
import { CodeBlockBubble } from "../toolbar/CodeBlockBubble";
|
|
58
72
|
import { ImageBubble } from "../toolbar/ImageBubble";
|
|
59
73
|
import { TableBubble } from "../toolbar/TableBubble";
|
|
74
|
+
import { MathBubble } from "../toolbar/MathBubble";
|
|
60
75
|
|
|
61
76
|
const lowlight = createLowlight(common);
|
|
62
|
-
|
|
77
|
+
|
|
78
|
+
/** Enter/exit fade for bubbles and suggestion popups (0 when animation none) */
|
|
79
|
+
const MOTION_MS = 120;
|
|
63
80
|
|
|
64
81
|
/**
|
|
65
82
|
* Tab / Shift-Tab indentation inside code blocks.
|
|
@@ -222,6 +239,8 @@ export interface TiptapEditorProps extends RichEditorProps {
|
|
|
222
239
|
headingFontFamily?: string;
|
|
223
240
|
/** Current editing mode: richtext (WYSIWYG) or markdown (raw source) */
|
|
224
241
|
editorMode?: "richtext" | "markdown";
|
|
242
|
+
/** Fullscreen mode: content fills the flex parent and scrolls internally */
|
|
243
|
+
fullscreen?: boolean;
|
|
225
244
|
}
|
|
226
245
|
|
|
227
246
|
// ===========================================================================
|
|
@@ -245,7 +264,7 @@ export const TiptapEditor = memo(
|
|
|
245
264
|
{
|
|
246
265
|
initialContent = "",
|
|
247
266
|
initialJSON,
|
|
248
|
-
placeholder
|
|
267
|
+
placeholder: placeholderProp,
|
|
249
268
|
editable = true,
|
|
250
269
|
autoFocus = false,
|
|
251
270
|
onChange,
|
|
@@ -259,10 +278,15 @@ export const TiptapEditor = memo(
|
|
|
259
278
|
bodyFontFamily,
|
|
260
279
|
headingFontFamily,
|
|
261
280
|
editorMode = "richtext",
|
|
281
|
+
fullscreen = false,
|
|
282
|
+
onImageUpload,
|
|
283
|
+
onFileUpload,
|
|
284
|
+
mentions,
|
|
262
285
|
},
|
|
263
286
|
ref,
|
|
264
287
|
) => {
|
|
265
288
|
const _ctx = RichEditorContext.useStyledContext();
|
|
289
|
+
const placeholder = placeholderProp ?? t("Start writing...");
|
|
266
290
|
const internalRef = useRef<RichEditorRef>(null);
|
|
267
291
|
const stateRafRef = useRef<number>(0);
|
|
268
292
|
const changeRafRef = useRef<number>(0);
|
|
@@ -270,6 +294,24 @@ export const TiptapEditor = memo(
|
|
|
270
294
|
const onChangeRef = useRef(onChange);
|
|
271
295
|
const [markdownSource, setMarkdownSource] = useState("");
|
|
272
296
|
const prevModeRef = useRef(editorMode);
|
|
297
|
+
const theme = useTheme();
|
|
298
|
+
const themeName = useThemeName();
|
|
299
|
+
const { knobProps } = useResolvedKnobs();
|
|
300
|
+
const motionMs = knobProps.transition !== undefined ? MOTION_MS : 0;
|
|
301
|
+
const scopeClass = `rt-scope-${useId().replace(/[^a-zA-Z0-9-]/g, "")}`;
|
|
302
|
+
|
|
303
|
+
// Mention wiring is captured at mount (the extension list is fixed);
|
|
304
|
+
// the items function stays live through this ref.
|
|
305
|
+
const mentionsRef = useRef(mentions);
|
|
306
|
+
mentionsRef.current = mentions;
|
|
307
|
+
const [mentionExtension] = useState(() =>
|
|
308
|
+
mentions
|
|
309
|
+
? createMentionExtension({
|
|
310
|
+
trigger: mentions.trigger,
|
|
311
|
+
items: (query) => mentionsRef.current?.items(query) ?? [],
|
|
312
|
+
})
|
|
313
|
+
: null,
|
|
314
|
+
);
|
|
273
315
|
|
|
274
316
|
useEffect(() => {
|
|
275
317
|
onStateChangeRef.current = onStateChange;
|
|
@@ -302,7 +344,7 @@ export const TiptapEditor = memo(
|
|
|
302
344
|
codeBlock: false,
|
|
303
345
|
hardBreak: false,
|
|
304
346
|
}),
|
|
305
|
-
|
|
347
|
+
CodeBlockWithPreview.configure({
|
|
306
348
|
lowlight,
|
|
307
349
|
exitOnTripleEnter: true,
|
|
308
350
|
exitOnArrowDown: false,
|
|
@@ -310,10 +352,30 @@ export const TiptapEditor = memo(
|
|
|
310
352
|
ParagraphEnterKeys,
|
|
311
353
|
CodeBlockTabIndent,
|
|
312
354
|
ListItemKeys,
|
|
313
|
-
|
|
355
|
+
// superscriptTwo/Three would mangle typed TeX (`$E=mc^2$` became
|
|
356
|
+
// `E=mc²` before the math input rule ran) — off, rest stays.
|
|
357
|
+
Typography.configure({
|
|
358
|
+
superscriptTwo: false,
|
|
359
|
+
superscriptThree: false,
|
|
360
|
+
}),
|
|
314
361
|
CharacterCount,
|
|
315
362
|
SlashCommands,
|
|
316
363
|
MarkdownPaste,
|
|
364
|
+
MediaUpload,
|
|
365
|
+
SuggestionChromeStore,
|
|
366
|
+
PreviewChromeStore,
|
|
367
|
+
EmojiSuggestion,
|
|
368
|
+
InlineMath,
|
|
369
|
+
// Collapsible sections (GitLab <details> parity). persist: true
|
|
370
|
+
// is the extension's supported mode: its node view re-syncs the
|
|
371
|
+
// open state from node.attrs on every update, so ephemeral
|
|
372
|
+
// (persist: false) toggles get reverted by the next transaction.
|
|
373
|
+
// The open state therefore lives in the doc and serializes as
|
|
374
|
+
// `<details open>` — valid GitLab markdown.
|
|
375
|
+
Details.configure({ persist: true }),
|
|
376
|
+
DetailsSummary,
|
|
377
|
+
DetailsContent,
|
|
378
|
+
...(mentionExtension ? [mentionExtension] : []),
|
|
317
379
|
BlockDragHandle,
|
|
318
380
|
Table.configure({ resizable: true }),
|
|
319
381
|
TableRow,
|
|
@@ -345,6 +407,17 @@ export const TiptapEditor = memo(
|
|
|
345
407
|
content: initialJSON || initialContent,
|
|
346
408
|
editable,
|
|
347
409
|
autofocus: autoFocus,
|
|
410
|
+
// No htmlFor target exists for the contenteditable — name it directly
|
|
411
|
+
// (axe aria-input-field-name); placeholder doubles as the name.
|
|
412
|
+
editorProps: {
|
|
413
|
+
attributes: {
|
|
414
|
+
role: "textbox",
|
|
415
|
+
"aria-multiline": "true",
|
|
416
|
+
"aria-label": placeholder || t("Rich text editor"),
|
|
417
|
+
},
|
|
418
|
+
// Strip Google Docs / Word clipboard junk before ProseMirror parses
|
|
419
|
+
transformPastedHTML: cleanPastedHtml,
|
|
420
|
+
},
|
|
348
421
|
injectCSS: false,
|
|
349
422
|
immediatelyRender: false,
|
|
350
423
|
shouldRerenderOnTransaction: false,
|
|
@@ -366,24 +439,76 @@ export const TiptapEditor = memo(
|
|
|
366
439
|
onBlur: () => onBlur?.(),
|
|
367
440
|
});
|
|
368
441
|
|
|
442
|
+
// Keep upload handlers live in editor storage (paste/drop + slash image)
|
|
443
|
+
useEffect(() => {
|
|
444
|
+
if (!editor) return;
|
|
445
|
+
editor.storage.mediaUpload.handlers = { onImageUpload, onFileUpload };
|
|
446
|
+
}, [editor, onImageUpload, onFileUpload]);
|
|
447
|
+
|
|
448
|
+
// Push resolved theme + knob chrome for the DOM-portaled suggestion
|
|
449
|
+
// popups (slash / mention): every color and structural role arrives
|
|
450
|
+
// resolved -- the popups never invent their own values.
|
|
451
|
+
useEffect(() => {
|
|
452
|
+
if (!editor) return;
|
|
453
|
+
const radiusToken = clampRadiusForLargeComponent(knobProps.borderRadius.borderRadius, 4);
|
|
454
|
+
const radiusValue =
|
|
455
|
+
typeof radiusToken === "number"
|
|
456
|
+
? radiusToken
|
|
457
|
+
: ((getTokens().radius as any)?.[radiusToken]?.val ?? fallbackSuggestionChrome.radius);
|
|
458
|
+
// LC-16: the DOM popup rows share menuRowFrame geometry — resolve
|
|
459
|
+
// its paddingHorizontal token to px here (theme scope) and push it.
|
|
460
|
+
const rowPadToken = menuRowFrame.paddingHorizontal as string;
|
|
461
|
+
const rowPaddingX =
|
|
462
|
+
(getTokens().space as any)?.[rowPadToken]?.val ?? fallbackSuggestionChrome.rowPaddingX;
|
|
463
|
+
// Elevation rides the theme's scheme-aware shadow tokens (Axiom 5) —
|
|
464
|
+
// the same channel the popover family resolves, never a raw rgba.
|
|
465
|
+
const shadowMain = theme.shadow2?.val;
|
|
466
|
+
const shadowSoft = theme.shadow1?.val;
|
|
467
|
+
const chrome: SuggestionChrome = {
|
|
468
|
+
background: theme.background?.val ?? fallbackSuggestionChrome.background,
|
|
469
|
+
borderColor: theme.borderColor?.val ?? fallbackSuggestionChrome.borderColor,
|
|
470
|
+
activeBackground: theme.color4?.val ?? fallbackSuggestionChrome.activeBackground,
|
|
471
|
+
iconTileBackground: theme.color3?.val ?? fallbackSuggestionChrome.iconTileBackground,
|
|
472
|
+
titleColor: theme.color12?.val ?? fallbackSuggestionChrome.titleColor,
|
|
473
|
+
descriptionColor: theme.color11?.val ?? fallbackSuggestionChrome.descriptionColor,
|
|
474
|
+
radius: typeof radiusValue === "number" ? radiusValue : fallbackSuggestionChrome.radius,
|
|
475
|
+
shadow:
|
|
476
|
+
shadowMain && shadowSoft
|
|
477
|
+
? `0px 8px 28px ${shadowMain}, 0px 2px 6px ${shadowSoft}`
|
|
478
|
+
: fallbackSuggestionChrome.shadow,
|
|
479
|
+
motionMs,
|
|
480
|
+
rowPaddingX:
|
|
481
|
+
typeof rowPaddingX === "number" ? rowPaddingX : fallbackSuggestionChrome.rowPaddingX,
|
|
482
|
+
};
|
|
483
|
+
editor.storage.suggestionChrome.value = chrome;
|
|
484
|
+
}, [editor, theme, knobProps.borderRadius.borderRadius, motionMs]);
|
|
485
|
+
|
|
486
|
+
// Push the resolved color scheme for block previews (mermaid/math):
|
|
487
|
+
// the node views subscribe and re-render diagrams on a theme flip.
|
|
488
|
+
useEffect(() => {
|
|
489
|
+
if (!editor) return;
|
|
490
|
+
setPreviewChrome(editor, {
|
|
491
|
+
scheme: String(themeName).startsWith("dark") ? "dark" : "light",
|
|
492
|
+
fontFamily: bodyFontFamily,
|
|
493
|
+
});
|
|
494
|
+
}, [editor, themeName, bodyFontFamily]);
|
|
495
|
+
|
|
369
496
|
useEffect(() => {
|
|
370
497
|
if (!editor) return;
|
|
371
498
|
if (prevModeRef.current === editorMode) return;
|
|
372
499
|
prevModeRef.current = editorMode;
|
|
373
500
|
|
|
374
501
|
if (editorMode === "markdown") {
|
|
375
|
-
setMarkdownSource(
|
|
502
|
+
setMarkdownSource(htmlToMarkdown(editor.getHTML()));
|
|
376
503
|
} else {
|
|
377
|
-
|
|
378
|
-
editor.commands.setContent(html);
|
|
504
|
+
editor.commands.setContent(markdownToHtml(markdownSource));
|
|
379
505
|
}
|
|
380
506
|
}, [editorMode, editor, markdownSource]);
|
|
381
507
|
|
|
382
508
|
const handleMarkdownChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
383
509
|
const md = e.target.value;
|
|
384
510
|
setMarkdownSource(md);
|
|
385
|
-
|
|
386
|
-
onChangeRef.current?.(html, null);
|
|
511
|
+
onChangeRef.current?.(markdownToHtml(md), null);
|
|
387
512
|
}, []);
|
|
388
513
|
|
|
389
514
|
const executeCommand = useCallback(
|
|
@@ -457,9 +582,22 @@ export const TiptapEditor = memo(
|
|
|
457
582
|
break;
|
|
458
583
|
case "link":
|
|
459
584
|
if (payload?.href) {
|
|
460
|
-
|
|
585
|
+
if (editor.state.selection.empty && !editor.isActive("link")) {
|
|
586
|
+
// GitLab parity: with nothing selected, insert the URL
|
|
587
|
+
// itself as linked text instead of silently no-oping
|
|
588
|
+
chain
|
|
589
|
+
.insertContent({
|
|
590
|
+
type: "text",
|
|
591
|
+
text: payload.text ?? payload.href,
|
|
592
|
+
marks: [{ type: "link", attrs: { href: payload.href } }],
|
|
593
|
+
})
|
|
594
|
+
.run();
|
|
595
|
+
} else {
|
|
596
|
+
// Cursor inside an existing link updates the whole link
|
|
597
|
+
chain.extendMarkRange("link").setLink({ href: payload.href }).run();
|
|
598
|
+
}
|
|
461
599
|
} else {
|
|
462
|
-
chain.unsetLink().run();
|
|
600
|
+
chain.extendMarkRange("link").unsetLink().run();
|
|
463
601
|
}
|
|
464
602
|
break;
|
|
465
603
|
case "undo":
|
|
@@ -562,20 +700,35 @@ export const TiptapEditor = memo(
|
|
|
562
700
|
(internalRef as any).current = refMethods;
|
|
563
701
|
|
|
564
702
|
const editorCSS = useMemo(
|
|
565
|
-
() =>
|
|
566
|
-
|
|
703
|
+
() =>
|
|
704
|
+
getEditorCSS({
|
|
705
|
+
minHeight,
|
|
706
|
+
maxHeight,
|
|
707
|
+
bodyFontFamily,
|
|
708
|
+
headingFontFamily,
|
|
709
|
+
fullscreen,
|
|
710
|
+
motionMs,
|
|
711
|
+
scopeClass,
|
|
712
|
+
}),
|
|
713
|
+
[minHeight, maxHeight, bodyFontFamily, headingFontFamily, fullscreen, motionMs, scopeClass],
|
|
567
714
|
);
|
|
568
715
|
|
|
569
716
|
if (editorMode === "markdown") {
|
|
570
717
|
return (
|
|
571
|
-
<EditorContainer
|
|
718
|
+
<EditorContainer
|
|
719
|
+
minHeight={fullscreen ? 0 : minHeight}
|
|
720
|
+
maxHeight={fullscreen ? undefined : maxHeight}
|
|
721
|
+
overflow="hidden"
|
|
722
|
+
>
|
|
572
723
|
<textarea
|
|
573
724
|
value={markdownSource}
|
|
574
725
|
onChange={handleMarkdownChange}
|
|
726
|
+
aria-label={t("Markdown source")}
|
|
575
727
|
style={{
|
|
576
728
|
width: "100%",
|
|
577
|
-
minHeight: minHeight,
|
|
578
|
-
maxHeight: maxHeight || undefined,
|
|
729
|
+
minHeight: fullscreen ? 0 : minHeight,
|
|
730
|
+
maxHeight: fullscreen ? undefined : maxHeight || undefined,
|
|
731
|
+
flex: fullscreen ? "1 1 0%" : undefined,
|
|
579
732
|
padding: "12px 12px 12px 16px",
|
|
580
733
|
border: "none",
|
|
581
734
|
outline: "none",
|
|
@@ -595,7 +748,12 @@ export const TiptapEditor = memo(
|
|
|
595
748
|
}
|
|
596
749
|
|
|
597
750
|
return (
|
|
598
|
-
<EditorContainer
|
|
751
|
+
<EditorContainer
|
|
752
|
+
className={scopeClass}
|
|
753
|
+
minHeight={fullscreen ? 0 : minHeight}
|
|
754
|
+
maxHeight={fullscreen ? undefined : maxHeight}
|
|
755
|
+
overflow="hidden"
|
|
756
|
+
>
|
|
599
757
|
{isWeb && <style>{editorCSS}</style>}
|
|
600
758
|
{showBubbleToolbar && (
|
|
601
759
|
<>
|
|
@@ -606,7 +764,14 @@ export const TiptapEditor = memo(
|
|
|
606
764
|
<TableBubble editor={editor} />
|
|
607
765
|
</>
|
|
608
766
|
)}
|
|
609
|
-
|
|
767
|
+
{/* Always mounted (unlike the optional bubbles): it is the ONLY
|
|
768
|
+
edit path for inline math atoms — without it a typed `$x$`
|
|
769
|
+
node would be a dead end. */}
|
|
770
|
+
{editable && <MathBubble editor={editor} />}
|
|
771
|
+
<EditorContent
|
|
772
|
+
editor={editor}
|
|
773
|
+
style={fullscreen ? { flex: "1 1 0%", minHeight: 0, overflowY: "auto" } : undefined}
|
|
774
|
+
/>
|
|
610
775
|
</EditorContainer>
|
|
611
776
|
);
|
|
612
777
|
},
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block-rect bubble anchoring against a headless Tiptap editor.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
6
|
+
import { Editor } from "@tiptap/core";
|
|
7
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
8
|
+
import { Table } from "@tiptap/extension-table";
|
|
9
|
+
import { TableRow } from "@tiptap/extension-table-row";
|
|
10
|
+
import { TableHeader } from "@tiptap/extension-table-header";
|
|
11
|
+
import { TableCell } from "@tiptap/extension-table-cell";
|
|
12
|
+
import { TextSelection } from "@tiptap/pm/state";
|
|
13
|
+
import { getBlockVirtualElement } from "./blockAnchor";
|
|
14
|
+
|
|
15
|
+
function createEditor(content: string) {
|
|
16
|
+
return new Editor({
|
|
17
|
+
element: document.createElement("div"),
|
|
18
|
+
extensions: [StarterKit, Table, TableRow, TableHeader, TableCell],
|
|
19
|
+
content,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Places the text cursor inside the first node of the given type */
|
|
24
|
+
function placeCursorIn(editor: Editor, nodeTypeName: string) {
|
|
25
|
+
let target = -1;
|
|
26
|
+
editor.state.doc.descendants((node, pos) => {
|
|
27
|
+
if (target === -1 && node.type.name === nodeTypeName) target = pos + 1;
|
|
28
|
+
return target === -1;
|
|
29
|
+
});
|
|
30
|
+
if (target === -1) throw new Error(`no ${nodeTypeName} in doc`);
|
|
31
|
+
const selection = TextSelection.near(editor.state.doc.resolve(target + 1));
|
|
32
|
+
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe("getBlockVirtualElement", () => {
|
|
36
|
+
it("returns the table DOM element when the cursor is inside a table", () => {
|
|
37
|
+
const editor = createEditor(
|
|
38
|
+
"<p>before</p><table><tr><th>h</th></tr><tr><td>cell</td></tr></table>",
|
|
39
|
+
);
|
|
40
|
+
placeCursorIn(editor, "table");
|
|
41
|
+
|
|
42
|
+
const ref = getBlockVirtualElement(editor, "table");
|
|
43
|
+
expect(ref).not.toBeNull();
|
|
44
|
+
expect((ref!.contextElement as HTMLElement).tagName).toBe("TABLE");
|
|
45
|
+
// The anchor rect delegates to the block's live rect
|
|
46
|
+
expect(typeof ref!.getBoundingClientRect().width).toBe("number");
|
|
47
|
+
editor.destroy();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("returns the pre element when the cursor is inside a code block", () => {
|
|
51
|
+
const editor = createEditor("<p>before</p><pre><code>const a = 1;</code></pre>");
|
|
52
|
+
placeCursorIn(editor, "codeBlock");
|
|
53
|
+
|
|
54
|
+
const ref = getBlockVirtualElement(editor, "codeBlock");
|
|
55
|
+
expect(ref).not.toBeNull();
|
|
56
|
+
expect((ref!.contextElement as HTMLElement).tagName).toBe("PRE");
|
|
57
|
+
editor.destroy();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("returns null when the selection is outside the block type", () => {
|
|
61
|
+
const editor = createEditor("<p>plain paragraph</p><table><tr><td>cell</td></tr></table>");
|
|
62
|
+
// Cursor starts in the first paragraph by default
|
|
63
|
+
const selection = TextSelection.near(editor.state.doc.resolve(1));
|
|
64
|
+
editor.view.dispatch(editor.state.tr.setSelection(selection));
|
|
65
|
+
|
|
66
|
+
expect(getBlockVirtualElement(editor, "table")).toBeNull();
|
|
67
|
+
expect(getBlockVirtualElement(editor, "codeBlock")).toBeNull();
|
|
68
|
+
editor.destroy();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block-rect anchoring for bubble menus (web).
|
|
3
|
+
*
|
|
4
|
+
* Tiptap's BubbleMenu anchors to the text caret by default. For tall blocks
|
|
5
|
+
* (tables, code blocks) that puts the bubble INSIDE the block box — hovering
|
|
6
|
+
* over the first table row / first code line, where it traps pointer events
|
|
7
|
+
* and chases the caret on every keystroke. Anchoring to the block's own DOM
|
|
8
|
+
* rect keeps the bubble outside the block (above it, or flipped below by
|
|
9
|
+
* floating-ui), so block content stays clickable and the bubble holds still
|
|
10
|
+
* while typing. GitLab's content editor anchors its table/code chrome the
|
|
11
|
+
* same way.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Editor } from "@tiptap/core";
|
|
15
|
+
|
|
16
|
+
interface BlockVirtualElement {
|
|
17
|
+
getBoundingClientRect: () => DOMRect;
|
|
18
|
+
contextElement: Element;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Returns a floating-ui VirtualElement for the nearest ancestor node of
|
|
23
|
+
* `nodeTypeName` containing the selection, or null when the selection is
|
|
24
|
+
* not inside one (the bubble is hidden by `shouldShow` in that case).
|
|
25
|
+
*/
|
|
26
|
+
export function getBlockVirtualElement(
|
|
27
|
+
editor: Editor,
|
|
28
|
+
nodeTypeName: string,
|
|
29
|
+
): BlockVirtualElement | null {
|
|
30
|
+
const { $from } = editor.state.selection;
|
|
31
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
32
|
+
if ($from.node(depth).type.name !== nodeTypeName) continue;
|
|
33
|
+
const dom = editor.view.nodeDOM($from.before(depth));
|
|
34
|
+
if (dom instanceof HTMLElement) {
|
|
35
|
+
return {
|
|
36
|
+
getBoundingClientRect: () => dom.getBoundingClientRect(),
|
|
37
|
+
contextElement: dom,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|