From 5ef8de018e009ac1497aaca7b4d8c283a0cc7653 Mon Sep 17 00:00:00 2001 From: Untone Date: Fri, 11 Oct 2024 02:50:38 +0300 Subject: [PATCH] editor toolbar debug wip --- src/components/Editor/Editor.stories.tsx | 2 +- src/components/Editor/MicroEditor.stories.tsx | 2 +- src/components/Editor/MiniEditor.stories.tsx | 2 +- .../Toolbar/BlockquoteBubbleMenu.stories.tsx | 58 +++ .../Toolbar/EditorFloatingMenu.module.scss | 20 +- .../Toolbar/EditorFloatingMenu.stories.tsx | 56 +++ .../Editor/Toolbar/EditorFloatingMenu.tsx | 36 +- .../Toolbar/FigureBubbleMenu.stories.tsx | 58 +++ .../Editor/Toolbar/FullBubbleMenu.stores.tsx | 59 +++ .../Editor/Toolbar/FullBubbleMenu.tsx | 2 +- .../Toolbar/IncutBubbleMenu.stories.tsx | 56 +++ .../Editor/Toolbar/InsertLinkForm.stories.tsx | 51 +++ .../Editor/Toolbar/Menu/Menu.module.scss | 14 - src/components/Editor/Toolbar/Menu/Menu.tsx | 44 -- src/components/Editor/Toolbar/Menu/index.ts | 1 - .../Toolbar/MicroBubbleMenu.stories.tsx | 35 ++ .../Editor/Toolbar/TextBubbleMenu.module.scss | 97 ----- .../Editor/Toolbar/TextBubbleMenu.tsx | 404 ------------------ .../Editor/Toolbar/ToolbarControl.stories.tsx | 66 +++ .../_shared/Popover/Popover.stoires.tsx | 43 ++ 20 files changed, 533 insertions(+), 573 deletions(-) create mode 100644 src/components/Editor/Toolbar/BlockquoteBubbleMenu.stories.tsx create mode 100644 src/components/Editor/Toolbar/EditorFloatingMenu.stories.tsx create mode 100644 src/components/Editor/Toolbar/FigureBubbleMenu.stories.tsx create mode 100644 src/components/Editor/Toolbar/FullBubbleMenu.stores.tsx create mode 100644 src/components/Editor/Toolbar/IncutBubbleMenu.stories.tsx create mode 100644 src/components/Editor/Toolbar/InsertLinkForm.stories.tsx delete mode 100644 src/components/Editor/Toolbar/Menu/Menu.module.scss delete mode 100644 src/components/Editor/Toolbar/Menu/Menu.tsx delete mode 100644 src/components/Editor/Toolbar/Menu/index.ts create mode 100644 src/components/Editor/Toolbar/MicroBubbleMenu.stories.tsx delete mode 100644 src/components/Editor/Toolbar/TextBubbleMenu.module.scss delete mode 100644 src/components/Editor/Toolbar/TextBubbleMenu.tsx create mode 100644 src/components/Editor/Toolbar/ToolbarControl.stories.tsx create mode 100644 src/components/_shared/Popover/Popover.stoires.tsx diff --git a/src/components/Editor/Editor.stories.tsx b/src/components/Editor/Editor.stories.tsx index 3203bf14..1d842e38 100644 --- a/src/components/Editor/Editor.stories.tsx +++ b/src/components/Editor/Editor.stories.tsx @@ -2,7 +2,7 @@ import { Meta, StoryObj } from 'storybook-solidjs' import { EditorComponent } from './Editor' const meta: Meta = { - title: 'Components/Editor', + title: 'Editor/Editor', component: EditorComponent, argTypes: { content: { diff --git a/src/components/Editor/MicroEditor.stories.tsx b/src/components/Editor/MicroEditor.stories.tsx index da31bd3f..210942e3 100644 --- a/src/components/Editor/MicroEditor.stories.tsx +++ b/src/components/Editor/MicroEditor.stories.tsx @@ -2,7 +2,7 @@ import { Meta, StoryObj } from 'storybook-solidjs' import { MicroEditor } from './MicroEditor' const meta: Meta = { - title: 'Components/MicroEditor', + title: 'Editor/MicroEditor', component: MicroEditor, argTypes: { content: { diff --git a/src/components/Editor/MiniEditor.stories.tsx b/src/components/Editor/MiniEditor.stories.tsx index 80e227de..c4454b44 100644 --- a/src/components/Editor/MiniEditor.stories.tsx +++ b/src/components/Editor/MiniEditor.stories.tsx @@ -2,7 +2,7 @@ import { Meta, StoryObj } from 'storybook-solidjs' import MiniEditor from './MiniEditor' const meta: Meta = { - title: 'Components/MiniEditor', + title: 'Editor/MiniEditor', component: MiniEditor, argTypes: { content: { diff --git a/src/components/Editor/Toolbar/BlockquoteBubbleMenu.stories.tsx b/src/components/Editor/Toolbar/BlockquoteBubbleMenu.stories.tsx new file mode 100644 index 00000000..059e99c6 --- /dev/null +++ b/src/components/Editor/Toolbar/BlockquoteBubbleMenu.stories.tsx @@ -0,0 +1,58 @@ +import { Editor } from '@tiptap/core' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { BlockquoteBubbleMenu } from './BlockquoteBubbleMenu' + +const meta: Meta = { + title: 'Editor/Toolbar/BlockquoteBubbleMenu', + component: BlockquoteBubbleMenu, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit], + content: '
Это пример цитаты
' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +
+ ) + } +} + +export const LeftAligned: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + editor().commands.setBlockQuoteFloat('left') + return ( +
+ console.log('Ref:', el)} /> +

Цитата выровнена по левому краю

+
+ ) + } +} + +export const RightAligned: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + editor().commands.setBlockQuoteFloat('right') + return ( +
+ console.log('Ref:', el)} /> +

Цитата выровнена по правому краю

+
+ ) + } +} diff --git a/src/components/Editor/Toolbar/EditorFloatingMenu.module.scss b/src/components/Editor/Toolbar/EditorFloatingMenu.module.scss index a897551e..5aeb21bb 100644 --- a/src/components/Editor/Toolbar/EditorFloatingMenu.module.scss +++ b/src/components/Editor/Toolbar/EditorFloatingMenu.module.scss @@ -4,7 +4,7 @@ vertical-align: middle; padding-top: 5px; - button { + .actionButton { opacity: 0.3; transition: opacity 0.3s ease-in-out; @@ -19,9 +19,25 @@ position: absolute; top: -4px; min-width: 64vw; + + .innerMenu { + display: flex; + flex-direction: row; + + .icon { + opacity: 0.5; + display: block; + transition: opacity 0.3s ease-in-out; + + &:hover { + opacity: 1; + } + } + } } + } :global(.tippy-box) { line-height: 1.3; -} +} \ No newline at end of file diff --git a/src/components/Editor/Toolbar/EditorFloatingMenu.stories.tsx b/src/components/Editor/Toolbar/EditorFloatingMenu.stories.tsx new file mode 100644 index 00000000..f245a6c0 --- /dev/null +++ b/src/components/Editor/Toolbar/EditorFloatingMenu.stories.tsx @@ -0,0 +1,56 @@ +import { Editor } from '@tiptap/core' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { EditorFloatingMenu } from './EditorFloatingMenu' + +const meta: Meta = { + title: 'Editor/Toolbar/EditorFloatingMenu', + component: EditorFloatingMenu, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit], + content: '

Нажмите на кнопку "+" для открытия меню

' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +
+ ) + } +} + +export const OpenMenu: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +

Меню открыто. Выберите опцию для вставки.

+
+ ) + } +} + +export const WithImageUpload: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +

Нажмите на кнопку "Изображение" для открытия модального окна загрузки.

+
+ ) + } +} diff --git a/src/components/Editor/Toolbar/EditorFloatingMenu.tsx b/src/components/Editor/Toolbar/EditorFloatingMenu.tsx index 7f368551..634e79c0 100644 --- a/src/components/Editor/Toolbar/EditorFloatingMenu.tsx +++ b/src/components/Editor/Toolbar/EditorFloatingMenu.tsx @@ -4,12 +4,12 @@ import { UploadModalContent } from '~/components/Upload/UploadModalContent/Uploa import { renderUploadedImage } from '~/components/Upload/renderUploadedImage' import { InlineForm } from '~/components/_shared/InlineForm/InlineForm' import { Modal } from '~/components/_shared/Modal/Modal' +import { Popover } from '~/components/_shared/Popover/Popover' import { useUI } from '~/context/ui' import { useOutsideClickHandler } from '~/lib/useOutsideClickHandler' import { UploadedFile } from '~/types/upload' import { useLocalize } from '../../../context/localize' import { Icon } from '../../_shared/Icon' -import { Menu, type MenuItem } from './Menu/Menu' import styles from './EditorFloatingMenu.module.scss' @@ -45,7 +45,7 @@ const validateEmbed = (value: string): boolean => { export const EditorFloatingMenu = (props: FloatingMenuProps) => { const { t } = useLocalize() const { showModal } = useUI() - const [selectedMenuItem, setSelectedMenuItem] = createSignal() + const [selectedMenuItem, setSelectedMenuItem] = createSignal() const [menuOpen, setMenuOpen] = createSignal(false) const [menuRef, setMenuRef] = createSignal() const [plusButtonRef, setPlusButtonRef] = createSignal() @@ -96,6 +96,32 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => { renderUploadedImage(props.editor, image) } + const PlusButtonMenu = () => ( +
+ + {(triggerRef: (el: HTMLElement) => void) => ( + + )} + + + {(triggerRef: (el: HTMLElement) => void) => ( + + )} + + + {(triggerRef: (el: HTMLElement) => void) => ( + + )} + +
+ ) + return ( <>
@@ -105,11 +131,7 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => {
- { - setSelectedMenuItem(value as MenuItem) - }} - /> + = { + title: 'Editor/Toolbar/FigureBubbleMenu', + component: FigureBubbleMenu, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit, Image], + content: + '
Пример изображения
Подпись к изображению
' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +
+ ) + } +} + +export const WithAlignment: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +

Используйте кнопки выравнивания для изменения позиции изображения

+
+ ) + } +} + +export const WithCaption: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +

Нажмите на кнопку "Добавить подпись" для добавления подписи к изображению

+
+ ) + } +} diff --git a/src/components/Editor/Toolbar/FullBubbleMenu.stores.tsx b/src/components/Editor/Toolbar/FullBubbleMenu.stores.tsx new file mode 100644 index 00000000..1f935e48 --- /dev/null +++ b/src/components/Editor/Toolbar/FullBubbleMenu.stores.tsx @@ -0,0 +1,59 @@ +import { Editor } from '@tiptap/core' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { FullBubbleMenu } from './FullBubbleMenu' + +const meta: Meta = { + title: 'Editor/Toolbar/FullBubbleMenu', + component: FullBubbleMenu, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit], + content: '

Пример текста для редактирования

' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + const [shouldShow, setShouldShow] = createSignal(true) + return ( +
+ editor()} shouldShow={() => shouldShow()} /> + +
+ ) + } +} + +export const CommonMarkup: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ editor()} shouldShow={() => true} isCommonMarkup={true} /> +
+ ) + } +} + +export const WithFigcaption: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + editor().commands.setContent('
Подпись к изображению
') + return ( +
+ editor()} shouldShow={() => true} /> +
+ ) + } +} diff --git a/src/components/Editor/Toolbar/FullBubbleMenu.tsx b/src/components/Editor/Toolbar/FullBubbleMenu.tsx index 4be6100d..a33e8ddc 100644 --- a/src/components/Editor/Toolbar/FullBubbleMenu.tsx +++ b/src/components/Editor/Toolbar/FullBubbleMenu.tsx @@ -13,7 +13,7 @@ import styles from './FullBubbleMenu.module.scss' type FullBubbleMenuProps = { editor: () => Editor | undefined - ref: (el: HTMLDivElement) => void + ref?: (el: HTMLDivElement) => void shouldShow: Accessor isCommonMarkup?: boolean } diff --git a/src/components/Editor/Toolbar/IncutBubbleMenu.stories.tsx b/src/components/Editor/Toolbar/IncutBubbleMenu.stories.tsx new file mode 100644 index 00000000..1fd95609 --- /dev/null +++ b/src/components/Editor/Toolbar/IncutBubbleMenu.stories.tsx @@ -0,0 +1,56 @@ +import { Editor } from '@tiptap/core' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { IncutBubbleMenu } from './IncutBubbleMenu' + +const meta: Meta = { + title: 'Editor/Toolbar/IncutBubbleMenu', + component: IncutBubbleMenu, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit], + content: '

Пример текста для вставки

' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +
+ ) + } +} + +export const WithBackgroundSelection: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +

Нажмите на кнопку "Substrate" для выбора фона

+
+ ) + } +} + +export const WithFloatOptions: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( +
+ console.log('Ref:', el)} /> +

Используйте кнопки выравнивания для изменения позиции вставки

+
+ ) + } +} diff --git a/src/components/Editor/Toolbar/InsertLinkForm.stories.tsx b/src/components/Editor/Toolbar/InsertLinkForm.stories.tsx new file mode 100644 index 00000000..f7ef23d6 --- /dev/null +++ b/src/components/Editor/Toolbar/InsertLinkForm.stories.tsx @@ -0,0 +1,51 @@ +import { Editor } from '@tiptap/core' +import Link from '@tiptap/extension-link' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { InsertLinkForm } from './InsertLinkForm' + +const meta: Meta = { + title: 'Editor/Toolbar/InsertLinkForm', + component: InsertLinkForm, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit, Link], + content: '

Текст с ссылкой

' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( + console.log('Форма закрыта')} + onSubmit={(value) => console.log('Отправлено:', value)} + onRemove={() => console.log('Ссылка удалена')} + /> + ) + } +} + +export const WithInitialLink: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + editor().commands.setTextSelection({ from: 10, to: 16 }) + return ( + console.log('Форма закрыта')} + onSubmit={(value) => console.log('Отправлено:', value)} + onRemove={() => console.log('Ссылка удалена')} + /> + ) + } +} diff --git a/src/components/Editor/Toolbar/Menu/Menu.module.scss b/src/components/Editor/Toolbar/Menu/Menu.module.scss deleted file mode 100644 index 6d47e83d..00000000 --- a/src/components/Editor/Toolbar/Menu/Menu.module.scss +++ /dev/null @@ -1,14 +0,0 @@ -.Menu { - display: flex; - flex-direction: row; - - .icon { - opacity: 0.5; - display: block; - transition: opacity 0.3s ease-in-out; - - &:hover { - opacity: 1; - } - } -} diff --git a/src/components/Editor/Toolbar/Menu/Menu.tsx b/src/components/Editor/Toolbar/Menu/Menu.tsx deleted file mode 100644 index 4a4791c5..00000000 --- a/src/components/Editor/Toolbar/Menu/Menu.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { useLocalize } from '~/context/localize' -import { Icon } from '../../../_shared/Icon' -import { Popover } from '../../../_shared/Popover' - -import styles from './Menu.module.scss' - -export type MenuItem = 'image' | 'embed' | 'horizontal-rule' - -type Props = { - selectedItem: (value: string) => void -} - -export const Menu = (props: Props) => { - const { t } = useLocalize() - const setSelectedMenuItem = (value: MenuItem) => { - props.selectedItem(value) - } - - return ( -
- - {(triggerRef: (el: HTMLElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLElement) => void) => ( - - )} - -
- ) -} diff --git a/src/components/Editor/Toolbar/Menu/index.ts b/src/components/Editor/Toolbar/Menu/index.ts deleted file mode 100644 index 8a8c93b5..00000000 --- a/src/components/Editor/Toolbar/Menu/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Menu } from './Menu' diff --git a/src/components/Editor/Toolbar/MicroBubbleMenu.stories.tsx b/src/components/Editor/Toolbar/MicroBubbleMenu.stories.tsx new file mode 100644 index 00000000..24ceffa8 --- /dev/null +++ b/src/components/Editor/Toolbar/MicroBubbleMenu.stories.tsx @@ -0,0 +1,35 @@ +import { Editor } from '@tiptap/core' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { MicroBubbleMenu } from './MicroBubbleMenu' + +const meta: Meta = { + title: 'Editor/Toolbar/MicroBubbleMenu', + component: MicroBubbleMenu, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit], + content: '

Выделите этот текст, чтобы увидеть MicroBubbleMenu

' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return + } +} + +export const WithoutBorders: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return + } +} diff --git a/src/components/Editor/Toolbar/TextBubbleMenu.module.scss b/src/components/Editor/Toolbar/TextBubbleMenu.module.scss deleted file mode 100644 index d3293e45..00000000 --- a/src/components/Editor/Toolbar/TextBubbleMenu.module.scss +++ /dev/null @@ -1,97 +0,0 @@ -.TextBubbleMenu { - background: var(--editor-bubble-menu-background); - box-shadow: 0 4px 10px rgba(var(--default-color), 0.25); - - &.growWidth { - min-width: 460px; - } - - .bubbleMenuButton { - display: inline-flex; - align-items: center; - justify-content: center; - flex-wrap: nowrap; - opacity: 0.5; - padding: 1rem; - - .triangle { - margin-left: 4px; - } - - .toggleHighlight { - display: inline-block; - width: 20px; - height: 20px; - border-radius: 50%; - background: #f6e3a1; - } - - img { - filter: var(--icon-filter); - } - } - - .bubbleMenuButtonActive { - opacity: 1; - } - - .delimiter { - background: var(--default-color); - display: inline-block; - height: 1.4em; - margin: 0 0.2em; - vertical-align: text-bottom; - width: 1px; - } - - .dropDownHolder { - position: relative; - cursor: pointer; - display: inline-flex; - flex-flow: row nowrap; - align-items: center; - - .dropDown { - position: absolute; - padding: 6px; - top: calc(100% + 8px); - left: 50%; - transform: translateX(-50%); - box-shadow: 0 4px 10px rgb(0 0 0 / 25%); - background: var(--background-color); - color: var(--default-color); - - & > header { - font-size: 10px; - border-bottom: 1px solid #898c94; - } - - .actions { - display: flex; - align-items: center; - justify-content: flex-start; - gap: 12px; - flex-wrap: nowrap; - margin-bottom: 8px; - - &:last-child { - margin-bottom: 0; - } - - .bubbleMenuButton { - min-width: 40px; - } - } - } - } - - .dropDownEnter, - .dropDownExit { - height: 0; - color: transparent; - } - - .noWrap { - white-space: nowrap; - } -} diff --git a/src/components/Editor/Toolbar/TextBubbleMenu.tsx b/src/components/Editor/Toolbar/TextBubbleMenu.tsx deleted file mode 100644 index b02553d9..00000000 --- a/src/components/Editor/Toolbar/TextBubbleMenu.tsx +++ /dev/null @@ -1,404 +0,0 @@ -import type { Editor } from '@tiptap/core' -import { clsx } from 'clsx' -import { Accessor, Match, Show, Switch, createEffect, createSignal, on, onCleanup, onMount } from 'solid-js' -import { createEditorTransaction } from 'solid-tiptap' -import { useLocalize } from '../../../context/localize' -import { Icon } from '../../_shared/Icon' -import { Popover } from '../../_shared/Popover' -import { MiniEditor } from '../MiniEditor' -import { InsertLinkForm } from './InsertLinkForm' - -import styles from './TextBubbleMenu.module.scss' - -type BubbleMenuProps = { - editor: Editor - isCommonMarkup: boolean - ref: (el: HTMLDivElement) => void - shouldShow: Accessor -} - -export const TextBubbleMenu = (props: BubbleMenuProps) => { - const { t } = useLocalize() - - const isActive = (name: string, attributes?: Record) => - createEditorTransaction( - () => props.editor, - (e) => e?.isActive(name, attributes) - ) - - const [textSizeBubbleOpen, setTextSizeBubbleOpen] = createSignal(false) - const [listBubbleOpen, setListBubbleOpen] = createSignal(false) - const [linkEditorOpen, setLinkEditorOpen] = createSignal(false) - const [footnoteEditorOpen, setFootnoteEditorOpen] = createSignal(false) - const [footNote, setFootNote] = createSignal() - - createEffect( - on(props.shouldShow, (show?: boolean) => { - if (!show) { - setFootNote() - setFootnoteEditorOpen(false) - } - }) - ) - - const isBold = isActive('bold') - const isItalic = isActive('italic') - const isH1 = isActive('heading', { level: 2 }) - const isH2 = isActive('heading', { level: 3 }) - const isH3 = isActive('heading', { level: 4 }) - const isQuote = isActive('blockquote', { 'data-type': 'quote' }) - const isPunchLine = isActive('blockquote', { 'data-type': 'punchline' }) - const isOrderedList = isActive('isOrderedList') - const isBulletList = isActive('isBulletList') - const isLink = isActive('link') - const isHighlight = isActive('highlight') - const isFootnote = isActive('footnote') - const isIncut = isActive('article') - - const toggleTextSizePopup = () => { - if (listBubbleOpen()) { - setListBubbleOpen(false) - } - setTextSizeBubbleOpen((prev) => !prev) - } - const toggleListPopup = () => { - if (textSizeBubbleOpen()) { - setTextSizeBubbleOpen(false) - } - setListBubbleOpen((prev) => !prev) - } - const handleKeyDown = (event: KeyboardEvent) => { - if (event.code === 'KeyK' && (event.metaKey || event.ctrlKey) && !props.editor.state.selection.empty) { - event.preventDefault() - setLinkEditorOpen(true) - } - } - - const updateCurrentFootnoteValue = createEditorTransaction( - () => props.editor, - (ed) => { - if (!isFootnote()) { - return - } - const value = ed.getAttributes('footnote').value - setFootNote(value) - } - ) - - const handleAddFootnote = (value: string) => { - if (footNote()) { - props.editor.chain().focus().updateFootnote({ value }).run() - } else { - props.editor.chain().focus().setFootnote({ value }).run() - } - setFootNote() - setFootnoteEditorOpen(false) - } - - const handleOpenFootnoteEditor = () => { - updateCurrentFootnoteValue() - setFootnoteEditorOpen(true) - } - - const handleSetPunchline = () => { - if (isPunchLine()) { - props.editor.chain().focus().toggleBlockquote('punchline').run() - } - props.editor.chain().focus().toggleBlockquote('quote').run() - toggleTextSizePopup() - } - const handleSetQuote = () => { - if (isQuote()) { - props.editor.chain().focus().toggleBlockquote('quote').run() - } - props.editor.chain().focus().toggleBlockquote('punchline').run() - toggleTextSizePopup() - } - - onMount(() => { - window.addEventListener('keydown', handleKeyDown) - onCleanup(() => { - window.removeEventListener('keydown', handleKeyDown) - }) - }) - - return ( -
- - - setLinkEditorOpen(false)} /> - - - handleAddFootnote(value)} - content={footNote()} - onCancel={() => setFootnoteEditorOpen(false)} - /> - - - <> - - <> -
- - -
-
{t('Headers')}
-
- - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - -
-
{t('Quotes')}
-
- - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - -
-
{t('squib')}
-
- - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - -
-
-
-
-
- - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - -
- - {t('Add url')}
}> - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - <> - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - -
-
- - -
-
{t('Lists')}
-
- - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - - - {(triggerRef: (el: HTMLButtonElement) => void) => ( - - )} - -
-
-
-
- - - - - -
- ) -} diff --git a/src/components/Editor/Toolbar/ToolbarControl.stories.tsx b/src/components/Editor/Toolbar/ToolbarControl.stories.tsx new file mode 100644 index 00000000..3e7f18c1 --- /dev/null +++ b/src/components/Editor/Toolbar/ToolbarControl.stories.tsx @@ -0,0 +1,66 @@ +import { Editor } from '@tiptap/core' +import StarterKit from '@tiptap/starter-kit' +import { createSignal } from 'solid-js' +import type { Meta, StoryObj } from 'storybook-solidjs' +import { Icon } from '~/components/_shared/Icon/Icon' +import { ToolbarControl } from './ToolbarControl' + +const meta: Meta = { + title: 'Editor/Toolbar/ToolbarControl', + component: ToolbarControl, + tags: ['autodocs'] +} + +export default meta +type Story = StoryObj + +const createMockEditor = () => { + return new Editor({ + extensions: [StarterKit], + content: '

Пример текста

' + }) +} + +export const Default: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( + console.log('Изменено')} + > + + + ) + } +} + +export const Active: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( + console.log('Изменено')} + isActive={() => true} + > + + + ) + } +} + +export const WithoutCaption: Story = { + render: () => { + const [editor] = createSignal(createMockEditor()) + return ( + console.log('Изменено')}> + + + ) + } +} diff --git a/src/components/_shared/Popover/Popover.stoires.tsx b/src/components/_shared/Popover/Popover.stoires.tsx new file mode 100644 index 00000000..07f209a4 --- /dev/null +++ b/src/components/_shared/Popover/Popover.stoires.tsx @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from 'storybook-solidjs' +import { Popover } from './Popover' + +const meta: Meta = { + title: 'atoms/Popover', + component: Popover, + tags: ['autodocs'] +} + +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: () => ( + + {(setTooltipEl) => } + + ) +} + +export const WithJSXContent: Story = { + render: () => ( + +

Заголовок подсказки

+

Это более сложное содержимое подсказки

+
+ } + > + {(setTooltipEl) => } + + ) +} + +export const Disabled: Story = { + render: () => ( + + {(setTooltipEl) => } + + ) +}