diff --git a/public/icons/down-triangle.svg b/public/icons/down-triangle.svg new file mode 100644 index 00000000..3f2eff6f --- /dev/null +++ b/public/icons/down-triangle.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/editor-blockquote.svg b/public/icons/editor-blockquote.svg new file mode 100644 index 00000000..b6e52b40 --- /dev/null +++ b/public/icons/editor-blockquote.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/editor-h3.svg b/public/icons/editor-h3.svg new file mode 100644 index 00000000..fc72e9de --- /dev/null +++ b/public/icons/editor-h3.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 2efeb1de..b265d116 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -235,5 +235,7 @@ "Short opening": "Short opening", "Write an article": "Write an article", "Enter URL address": "Enter URL address", - "Invalid url format": "Invalid url format" + "Invalid url format": "Invalid url format", + "Headers": "Headers", + "Quotes": "Quotes" } diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 8bfa43ef..5cb1f3f8 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -253,5 +253,7 @@ "Short opening": "Небольшое вступление, чтобы заинтересовать читателя", "Write an article": "Написать статью", "Enter URL address": "Введите адрес ссылки", - "Invalid url format": "Неверный формат ссылки" + "Invalid url format": "Неверный формат ссылки", + "Headers": "Заголовки", + "Quotes": "Цитаты" } diff --git a/src/components/Editor/Editor.tsx b/src/components/Editor/Editor.tsx index 34e1b83e..4d92d858 100644 --- a/src/components/Editor/Editor.tsx +++ b/src/components/Editor/Editor.tsx @@ -26,9 +26,9 @@ import { Image } from '@tiptap/extension-image' import { Paragraph } from '@tiptap/extension-paragraph' import Focus from '@tiptap/extension-focus' import { TrailingNode } from './extensions/TrailingNode' -import './Prosemirror.scss' import { EditorBubbleMenu } from './EditorBubbleMenu' import { EditorFloatingMenu } from './EditorFloatingMenu' +import './Prosemirror.scss' type EditorProps = { initialContent?: string @@ -75,6 +75,9 @@ export const Editor = (props: EditorProps) => { Link.configure({ openOnClick: false }), + Heading.configure({ + levels: [1, 2, 3] + }), BubbleMenu.configure({ element: bubbleMenuRef.current }), diff --git a/src/components/Editor/EditorBubbleMenu.module.scss b/src/components/Editor/EditorBubbleMenu.module.scss index 6f2a5aa7..47a11cab 100644 --- a/src/components/Editor/EditorBubbleMenu.module.scss +++ b/src/components/Editor/EditorBubbleMenu.module.scss @@ -3,10 +3,15 @@ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25); .bubbleMenuButton { + display: inline-flex; + align-items: center; + justify-content: center; + flex-wrap: nowrap; opacity: 0.5; padding: 1rem; } + &:hover, .bubbleMenuButtonActive { opacity: 1; } @@ -48,4 +53,48 @@ color: red; font-size: 0.7em; } + + .dropDownHolder { + position: relative; + cursor: pointer; + display: inline-flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + + .dropDown { + position: absolute; + padding: 6px; + top: calc(100% + 8px); + left: 50%; + transform: translateX(-50%); + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25); + background: #fff; + color: #898c94; + + & > header { + font-size: 10px; + border-bottom: 1px solid #898c94; + } + + .actions { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + flex-wrap: nowrap; + margin-bottom: 16px; + + .bubbleMenuButton { + min-width: 40px; + } + } + } + } + + .dropDownEnter, + .dropDownExit { + height: 0; + color: transparent; + } } diff --git a/src/components/Editor/EditorBubbleMenu.tsx b/src/components/Editor/EditorBubbleMenu.tsx index 067c2e70..1ba2d472 100644 --- a/src/components/Editor/EditorBubbleMenu.tsx +++ b/src/components/Editor/EditorBubbleMenu.tsx @@ -1,9 +1,9 @@ +import { createEffect, createSignal, Show } from 'solid-js' import type { Editor } from '@tiptap/core' import styles from './EditorBubbleMenu.module.scss' import { Icon } from '../_shared/Icon' import { clsx } from 'clsx' import { createEditorTransaction } from 'solid-tiptap' -import { createSignal } from 'solid-js' import { useLocalize } from '../../context/localize' import validateUrl from '../../utils/validateUrl' @@ -14,6 +14,7 @@ type BubbleMenuProps = { export const EditorBubbleMenu = (props: BubbleMenuProps) => { const { t } = useLocalize() + const [textSizeBubbleOpen, setTextSizeBubbleOpen] = createSignal(false) const [linkEditorOpen, setLinkEditorOpen] = createSignal(false) const [url, setUrl] = createSignal('') const [prevUrl, setPrevUrl] = createSignal(null) @@ -23,6 +24,28 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => { () => props.editor, (editor) => editor && editor.isActive('bold') ) + const isItalic = createEditorTransaction( + () => props.editor, + (editor) => editor && editor.isActive('italic') + ) + + //props.editor.isActive('heading', { level: 1 }) - либо инлайново либо как-то возвращать что активно + const isHOne = createEditorTransaction( + () => props.editor, + (editor) => editor && editor.isActive('heading', { level: 1 }) + ) + const isHTwo = createEditorTransaction( + () => props.editor, + (editor) => editor && editor.isActive('heading', { level: 2 }) + ) + const isHThree = createEditorTransaction( + () => props.editor, + (editor) => editor && editor.isActive('heading', { level: 3 }) + ) + const isBlockQuote = createEditorTransaction( + () => props.editor, + (editor) => editor && editor.isActive('blockquote') + ) const isLink = createEditorTransaction( () => props.editor, (editor) => { @@ -68,7 +91,7 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => { - @@ -76,9 +99,87 @@ export const EditorBubbleMenu = (props: BubbleMenuProps) => { ) : ( <> +
+ + +
+
{t('Headers')}
+
+ + + +
+
{t('Quotes')}
+
+ +
+
+
+
+
+ +
+ - - - -
D
- -
- diff --git a/src/components/Editor/Prosemirror.scss b/src/components/Editor/Prosemirror.scss index b38fe3fc..23c12835 100644 --- a/src/components/Editor/Prosemirror.scss +++ b/src/components/Editor/Prosemirror.scss @@ -1,5 +1,13 @@ .ProseMirror { outline: none; + + blockquote { + border-left: 2px solid; + @include font-size(1.6rem); + + margin: 1.5em 0; + padding-left: 1.6em; + } } .ProseMirror p.is-editor-empty:first-child::before { diff --git a/src/components/Nav/Snackbar.module.scss b/src/components/Nav/Snackbar.module.scss index ae76b39a..019b372f 100644 --- a/src/components/Nav/Snackbar.module.scss +++ b/src/components/Nav/Snackbar.module.scss @@ -15,10 +15,4 @@ display: flex; align-items: center; justify-content: center; - - &.enter, - &.exitTo { - height: 0; - color: transparent; - } }