diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 5696fd0f..b3c06777 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -17,8 +17,6 @@ import { BulletList } from '@tiptap/extension-bullet-list' import { OrderedList } from '@tiptap/extension-ordered-list' import { ListItem } from '@tiptap/extension-list-item' import { CharacterCount } from '@tiptap/extension-character-count' -import { Collaboration } from '@tiptap/extension-collaboration' -import { CollaborationCursor } from '@tiptap/extension-collaboration-cursor' import { Placeholder } from '@tiptap/extension-placeholder' import { Gapcursor } from '@tiptap/extension-gapcursor' import { HardBreak } from '@tiptap/extension-hard-break' @@ -32,7 +30,7 @@ import { Image } from '@tiptap/extension-image' import { Paragraph } from '@tiptap/extension-paragraph' import Focus from '@tiptap/extension-focus' import { TrailingNode } from './extensions/TrailingNode' -import { EditorBubbleMenu } from './EditorBubbleMenu' +import { EditorBubbleMenu } from './EditorBubbleMenu/EditorBubbleMenu' import { EditorFloatingMenu } from './EditorFloatingMenu' import './Prosemirror.scss' @@ -119,7 +117,6 @@ export const Editor = (props: EditorProps) => { Heading, Highlight, Image, - Link, Youtube, TrailingNode ] diff --git a/src/components/Editor/EditorBubbleMenu.module.scss b/src/components/Editor/EditorBubbleMenu/EditorBubbleMenu.module.scss similarity index 91% rename from src/components/Editor/EditorBubbleMenu.module.scss rename to src/components/Editor/EditorBubbleMenu/EditorBubbleMenu.module.scss index effd55df..3b607f45 100644 --- a/src/components/Editor/EditorBubbleMenu.module.scss +++ b/src/components/Editor/EditorBubbleMenu/EditorBubbleMenu.module.scss @@ -1,6 +1,6 @@ .bubbleMenu { background: #fff; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25); + box-shadow: 0 4px 10px rgba(#000, 0.25); .bubbleMenuButton { display: inline-flex; @@ -23,7 +23,6 @@ } } - &:hover, .bubbleMenuButtonActive { opacity: 1; } @@ -64,6 +63,12 @@ padding: 6px 11px; color: red; font-size: 0.7em; + position: absolute; + bottom: -3rem; + left: 0; + right: 0; + background: #fff; + box-shadow: 0 4px 10px rgba(#000, 0.25); } .dropDownHolder { diff --git a/src/components/Editor/EditorBubbleMenu.tsx b/src/components/Editor/EditorBubbleMenu/EditorBubbleMenu.tsx similarity index 84% rename from src/components/Editor/EditorBubbleMenu.tsx rename to src/components/Editor/EditorBubbleMenu/EditorBubbleMenu.tsx index 73dfaa0b..8de91a56 100644 --- a/src/components/Editor/EditorBubbleMenu.tsx +++ b/src/components/Editor/EditorBubbleMenu/EditorBubbleMenu.tsx @@ -1,11 +1,11 @@ import { Switch, Match, createSignal, Show } from 'solid-js' import type { Editor } from '@tiptap/core' import styles from './EditorBubbleMenu.module.scss' -import { Icon } from '../_shared/Icon' +import { Icon } from '../../_shared/Icon' import { clsx } from 'clsx' import { createEditorTransaction } from 'solid-tiptap' -import { useLocalize } from '../../context/localize' -import validateUrl from '../../utils/validateUrl' +import { useLocalize } from '../../../context/localize' +import validateUrl from '../../../utils/validateUrl' type BubbleMenuProps = { editor: Editor @@ -18,17 +18,13 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => { const [listBubbleOpen, setListBubbleOpen] = createSignal(false) const [linkEditorOpen, setLinkEditorOpen] = createSignal(false) const [url, setUrl] = createSignal('') - const [prevUrl, setPrevUrl] = createSignal(null) const [linkError, setLinkError] = createSignal(null) - const isActive = (name: string, attributes?: {}, checkPrevUrl?: boolean) => + const isActive = (name: string, attributes?: {}) => createEditorTransaction( () => props.editor, (editor) => { - editor && editor.isActive(name, attributes) - if (checkPrevUrl) { - setPrevUrl(editor && editor.getAttributes('link').href) - } + return editor && editor.isActive(name, attributes) } ) @@ -40,23 +36,46 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => { const isBlockQuote = isActive('blockquote') const isOrderedList = isActive('isOrderedList') const isBulletList = isActive('isBulletList') - const isLink = isActive('link', {}, true) + const isLink = isActive('link') + + //TODO: вынести логику линки в отдельный компонент + const toggleLinkForm = () => { + setLinkError(null) + setLinkEditorOpen(true) + } + + const currentUrl = createEditorTransaction( + () => props.editor, + (editor) => { + return (editor && editor.getAttributes('link').href) || '' + } + ) const clearLinkForm = () => { + if (currentUrl()) { + props.editor.chain().focus().unsetLink().run() + } setUrl('') setLinkEditorOpen(false) } - - const handleSubmitLink = (e) => { - e.preventDefault() - if (url().length > 1 && validateUrl(url())) { - props.editor.chain().focus().toggleLink({ href: url() }).run() - clearLinkForm() + const handleUrlChange = (value) => { + setUrl(value) + } + const handleSubmitLink = () => { + if (validateUrl(url())) { + props.editor.chain().focus().setLink({ href: url() }).run() + setLinkEditorOpen(false) } else { setLinkError(t('Invalid url format')) } } + const handleKeyPress = (event) => { + const key = event.key + if (key === 'Enter') handleSubmitLink() + if (key === 'Esc') clearLinkForm() + } + const toggleTextSizePopup = () => { if (listBubbleOpen()) setListBubbleOpen(false) setTextSizeBubbleOpen((prev) => !prev) @@ -72,21 +91,22 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => { <> -
handleSubmitLink(e)} class={styles.linkForm}> +
setUrl(e.currentTarget.value)} + value={currentUrl()} + onKeyPress={(e) => handleKeyPress(e)} + onChange={(e) => handleUrlChange(e.currentTarget.value)} /> - - +
{linkError() &&
{linkError()}
}
@@ -181,9 +201,7 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => {