diff --git a/src/components/Editor/InsertLinkForm/InsertLinkForm.tsx b/src/components/Editor/InsertLinkForm/InsertLinkForm.tsx index 601ad0ec..825be6ff 100644 --- a/src/components/Editor/InsertLinkForm/InsertLinkForm.tsx +++ b/src/components/Editor/InsertLinkForm/InsertLinkForm.tsx @@ -8,7 +8,6 @@ import { InlineForm } from '../InlineForm' type Props = { editor: Editor onClose: () => void - onFocus: (event: FocusEvent) => void } export const checkUrl = (url: string) => { @@ -62,7 +61,6 @@ export const InsertLinkForm = (props: Props) => { validate={(value) => (validateUrl(value) ? '' : t('Invalid url format'))} onSubmit={handleLinkFormSubmit} onClose={props.onClose} - onFocus={props.onFocus} /> ) diff --git a/src/components/Editor/MicroEditor/MicroEditor.tsx b/src/components/Editor/MicroEditor/MicroEditor.tsx index e16fcf33..48233335 100644 --- a/src/components/Editor/MicroEditor/MicroEditor.tsx +++ b/src/components/Editor/MicroEditor/MicroEditor.tsx @@ -63,15 +63,6 @@ export const MicroEditor = (props: MicroEditorProps): JSX.Element => { const [showLinkInput, setShowLinkInput] = createSignal(false) const [showSimpleMenu, setShowSimpleMenu] = createSignal(false) const [toolbarElement, setToolbarElement] = createSignal() - const [selectionRange, setSelectionRange] = createSignal(null) - - const handleLinkInputFocus = (event: FocusEvent) => { - event.preventDefault() - const selection = window.getSelection() - if (selection?.rangeCount) { - setSelectionRange(selection.getRangeAt(0)) - } - } const editor = createTiptapEditor(() => ({ element: editorElement()!, @@ -87,12 +78,32 @@ export const MicroEditor = (props: MicroEditorProps): JSX.Element => { content: props.content || '' })) + const selection = createEditorTransaction(editor, (instance) => instance?.state.selection) + const [storedSelection, setStoredSelection] = createSignal() + const recoverSelection = () => { + if (!storedSelection()?.empty) { + // TODO set selection range from stored + createEditorTransaction(editor, (instance?: Editor) => { + const r = selection() + if (instance && r) { + instance.state.selection.from === r.from + instance.state.selection.to === r.to + } + }) + } + } + const storeSelection = (event: Event) => { + event.preventDefault() + const selection = editor()?.state.selection + if (!selection?.empty) { + setStoredSelection(selection) + } + } + const isEmpty = useEditorIsEmpty(editor) const isFocused = useEditorIsFocused(editor) - const isTextSelection = createEditorTransaction(editor, (instance) => !instance?.state.selection.empty) const html = useEditorHTML(editor) - - createEffect(on([isTextSelection, showLinkInput],([selected, linkEditing]) => !linkEditing && setShowSimpleMenu(selected))) + createEffect(on([selection, showLinkInput], ([s, l]) => !l && setShowSimpleMenu(!s?.empty))) createEffect(on(html, (c?: string) => c && props.onChange?.(c))) createEffect(on(showLinkInput, (x?: boolean) => x && editor()?.chain().focus().run())) createReaction(on(toolbarElement, (t?: HTMLElement) => t?.addEventListener('mousedown', prevent))) @@ -117,46 +128,41 @@ export const MicroEditor = (props: MicroEditorProps): JSX.Element => { ref={setToolbarElement} >
- { - setShowLinkInput(false) - if (selectionRange()) { - const selection = window.getSelection() - selection?.removeAllRanges() - selection?.addRange(selectionRange()!) - } - }} - onFocus={handleLinkInputFocus} />} - > -
- instance.chain().focus().toggleBold().run()} - title={t('Bold')} - > - - - instance.chain().focus().toggleItalic().run()} - title={t('Italic')} - > - - - setShowLinkInput(!showLinkInput())} - title={t('Add url')} - isActive={showLinkInput} - > - - -
+
+ instance.chain().focus().toggleBold().run()} + title={t('Bold')} + > + + + instance.chain().focus().toggleItalic().run()} + title={t('Italic')} + > + + + setShowLinkInput(!showLinkInput())} + title={t('Add url')} + isActive={showLinkInput} + > + + +
+ + { + setShowLinkInput(false) + recoverSelection() + }} + />
@@ -164,7 +170,7 @@ export const MicroEditor = (props: MicroEditorProps): JSX.Element => { )} -
+
) diff --git a/src/components/Editor/MiniEditor/MiniEditor.tsx b/src/components/Editor/MiniEditor/MiniEditor.tsx index 011d951e..1be9af48 100644 --- a/src/components/Editor/MiniEditor/MiniEditor.tsx +++ b/src/components/Editor/MiniEditor/MiniEditor.tsx @@ -2,13 +2,10 @@ import type { Editor } from '@tiptap/core' import CharacterCount from '@tiptap/extension-character-count' import Placeholder from '@tiptap/extension-placeholder' import clsx from 'clsx' -import { type JSX, Show, createEffect, createSignal, onCleanup } from 'solid-js' +import { type JSX, Show, createEffect, createSignal, on, onCleanup } from 'solid-js' import { - createEditorTransaction, createTiptapEditor, useEditorHTML, - useEditorIsEmpty, - useEditorIsFocused } from 'solid-tiptap' import { Toolbar } from 'terracotta' import { Icon } from '~/components/_shared/Icon/Icon' @@ -63,7 +60,6 @@ export default function MiniEditor(props: MiniEditorProps): JSX.Element { const [editorElement, setEditorElement] = createSignal() const [counter, setCounter] = createSignal(0) const [showLinkInput, setShowLinkInput] = createSignal(false) - const [showSimpleMenu, setShowSimpleMenu] = createSignal(false) const { t } = useLocalize() const { showModal } = useUI() @@ -82,12 +78,9 @@ export default function MiniEditor(props: MiniEditorProps): JSX.Element { content: props.content || '' })) - const isEmpty = useEditorIsEmpty(editor) - const isFocused = useEditorIsFocused(editor) - const isTextSelection = createEditorTransaction(editor, (instance) => !instance?.state.selection.empty) const html = useEditorHTML(editor) - - createEffect(() => setShowSimpleMenu(isTextSelection())) + createEffect(on(html, (c?: string) => c && props.onChange?.(c))) + createEffect(on(showLinkInput, (x?: boolean) => x && editor()?.chain().focus().run())) createEffect(() => { const textLength = editor()?.getText().length || 0 @@ -112,77 +105,74 @@ export default function MiniEditor(props: MiniEditorProps): JSX.Element { }) return (
- - - - {(instance) => ( -
- setShowLinkInput(false)} />} - > -
- instance.chain().focus().toggleBold().run()} - title={t('Bold')} - > - - - instance.chain().focus().toggleItalic().run()} - title={t('Italic')} - > - - - - - - instance.chain().focus().toggleBlockquote().run()} - title={t('Add blockquote')} - > - - - showModal('simplifiedEditorUploadImage')} - title={t('Add image')} - > - - -
-
-
- )} -
-
-
-
+ + + {(instance) => ( +
+ setShowLinkInput(false)} />} + > +
+ instance.chain().focus().toggleBold().run()} + title={t('Bold')} + > + + + instance.chain().focus().toggleItalic().run()} + title={t('Italic')} + > + + + + + + instance.chain().focus().toggleBlockquote().run()} + title={t('Add blockquote')} + > + + + showModal('simplifiedEditorUploadImage')} + title={t('Add image')} + > + + +
+
+
+ )} +
+
+ 0}> {counter()} / {props.limit || '∞'} +
)