diff options
Diffstat (limited to 'src/view/com/composer/text-input/TextInput.web.tsx')
-rw-r--r-- | src/view/com/composer/text-input/TextInput.web.tsx | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx index fa742d258..8ec4fefa8 100644 --- a/src/view/com/composer/text-input/TextInput.web.tsx +++ b/src/view/com/composer/text-input/TextInput.web.tsx @@ -11,6 +11,7 @@ import {Paragraph} from '@tiptap/extension-paragraph' import {Placeholder} from '@tiptap/extension-placeholder' import {Text as TiptapText} from '@tiptap/extension-text' import {generateJSON} from '@tiptap/html' +import {Fragment, Node, Slice} from '@tiptap/pm/model' import {EditorContent, JSONContent, useEditor} from '@tiptap/react' import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle' @@ -23,8 +24,8 @@ import { } from '#/view/com/composer/text-input/text-input-util' import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter' import {atoms as a, useAlf} from '#/alf' +import {normalizeTextStyles} from '#/alf/typography' import {Portal} from '#/components/Portal' -import {normalizeTextStyles} from '#/components/Typography' import {Text} from '../../util/text/Text' import {createSuggestion} from './web/Autocomplete' import {Emoji} from './web/EmojiPicker.web' @@ -166,6 +167,11 @@ export const TextInput = React.forwardRef(function TextInputImpl( const editor = useEditor( { extensions, + coreExtensionOptions: { + clipboardTextSerializer: { + blockSeparator: '\n', + }, + }, onFocus() { onFocus?.() }, @@ -173,6 +179,20 @@ export const TextInput = React.forwardRef(function TextInputImpl( attributes: { class: modeClass, }, + clipboardTextParser: (text, context) => { + const blocks = text.split(/(?:\r\n?|\n)/) + const nodes: Node[] = blocks.map(line => { + return Node.fromJSON( + context.doc.type.schema, + line.length > 0 + ? {type: 'paragraph', content: [{type: 'text', text: line}]} + : {type: 'paragraph', content: []}, + ) + }) + + const fragment = Fragment.fromArray(nodes) + return Slice.maxOpen(fragment) + }, handlePaste: (view, event) => { const clipboardData = event.clipboardData let preventDefault = false @@ -205,6 +225,7 @@ export const TextInput = React.forwardRef(function TextInputImpl( autofocus: 'end', editable: true, injectCSS: true, + shouldRerenderOnTransaction: false, onCreate({editor: editorProp}) { // HACK // the 'enter' animation sometimes causes autofocus to fail @@ -297,15 +318,9 @@ export const TextInput = React.forwardRef(function TextInputImpl( style.lineHeight = style.lineHeight ? ((style.lineHeight + 'px') as unknown as number) : undefined + style.minHeight = webForceMinHeight ? 140 : undefined return style - }, [t, fonts]) - - React.useLayoutEffect(() => { - let node = editor?.view.dom - if (node) { - node.style.minHeight = webForceMinHeight ? '140px' : '' - } - }, [editor, webForceMinHeight]) + }, [t, fonts, webForceMinHeight]) return ( <> |