pref: optimize the toolbar space and fold the same type of function (#5683)

#### What type of PR is this?

/kind improvement
/area editor
/milestone 2.15.x

#### What this PR does / why we need it:

本 PR 对富文本编辑器中工具栏和冒泡菜单进行精简。

- 对默认富文本冒泡菜单及顶部工具栏相同类型的功能进行了折叠。
- 删除在 text 的冒泡菜单中,不属于当前选中文本的功能,例如转换为代码块等,这些实际上是段落的功能,并非是文本的功能。而 textAlign 目前也仅仅用在标题和行上,因此也移除。

#### How to test it?

查看默认富文本编辑器工具栏中,折叠的功能是否正常。选中文本,查看文本中是否不包含段落相关的功能。

#### Which issue(s) this PR fixes:

Fixes #5669 

#### Does this PR introduce a user-facing change?
```release-note
对默认富文本编辑器中的工具栏进行折叠及精简优化。
```
pull/5746/head
Takagi 2024-04-18 17:30:06 +08:00 committed by GitHub
parent fdc2453cc8
commit ac6896d0f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 84 additions and 122 deletions

View File

@ -1,4 +1,4 @@
import type { Editor } from "@/tiptap/vue-3"; import { type Editor } from "@/tiptap/vue-3";
import TiptapTextAlign from "@tiptap/extension-text-align"; import TiptapTextAlign from "@tiptap/extension-text-align";
import type { TextAlignOptions } from "@tiptap/extension-text-align"; import type { TextAlignOptions } from "@tiptap/extension-text-align";
import ToolbarItem from "@/components/toolbar/ToolbarItem.vue"; import ToolbarItem from "@/components/toolbar/ToolbarItem.vue";
@ -9,59 +9,90 @@ import MdiFormatAlignJustify from "~icons/mdi/format-align-justify";
import { markRaw } from "vue"; import { markRaw } from "vue";
import { i18n } from "@/locales"; import { i18n } from "@/locales";
import type { ExtensionOptions } from "@/types"; import type { ExtensionOptions } from "@/types";
import ToolbarSubItem from "@/components/toolbar/ToolbarSubItem.vue";
const iconComponent = {
left: MdiFormatAlignLeft,
center: MdiFormatAlignCenter,
right: MdiFormatAlignRight,
justify: MdiFormatAlignJustify,
};
const getIcon = (editor: Editor) => {
let icon = MdiFormatAlignLeft;
Object.entries(iconComponent).forEach(([key, value]) => {
if (editor.isActive({ textAlign: key })) {
icon = value;
return;
}
});
return icon;
};
const TextAlign = TiptapTextAlign.extend<ExtensionOptions & TextAlignOptions>({ const TextAlign = TiptapTextAlign.extend<ExtensionOptions & TextAlignOptions>({
addOptions() { addOptions() {
return { return {
...this.parent?.(), ...this.parent?.(),
getToolbarItems({ editor }: { editor: Editor }) { getToolbarItems({ editor }: { editor: Editor }) {
return [ return {
{ priority: 180,
priority: 180, component: markRaw(ToolbarItem),
component: markRaw(ToolbarItem), props: {
props: { editor,
editor, isActive: false,
isActive: editor.isActive({ textAlign: "left" }), icon: markRaw(getIcon(editor)),
icon: markRaw(MdiFormatAlignLeft), title: i18n.global.t("editor.common.align_method"),
title: i18n.global.t("editor.common.align_left"),
action: () => editor.chain().focus().setTextAlign("left").run(),
},
}, },
{ children: [
priority: 190, {
component: markRaw(ToolbarItem), priority: 0,
props: { component: markRaw(ToolbarSubItem),
editor, props: {
isActive: editor.isActive({ textAlign: "center" }), editor,
icon: markRaw(MdiFormatAlignCenter), isActive: editor.isActive({ textAlign: "left" }),
title: i18n.global.t("editor.common.align_center"), icon: markRaw(MdiFormatAlignLeft),
action: () => editor.chain().focus().setTextAlign("center").run(), title: i18n.global.t("editor.common.align_left"),
action: () => editor.chain().focus().setTextAlign("left").run(),
},
}, },
}, {
{ priority: 10,
priority: 200, component: markRaw(ToolbarSubItem),
component: markRaw(ToolbarItem), props: {
props: { editor,
editor, isActive: editor.isActive({ textAlign: "center" }),
isActive: editor.isActive({ textAlign: "right" }), icon: markRaw(MdiFormatAlignCenter),
icon: markRaw(MdiFormatAlignRight), title: i18n.global.t("editor.common.align_center"),
title: i18n.global.t("editor.common.align_right"), action: () =>
action: () => editor.chain().focus().setTextAlign("right").run(), editor.chain().focus().setTextAlign("center").run(),
},
}, },
}, {
{ priority: 20,
priority: 210, component: markRaw(ToolbarSubItem),
component: markRaw(ToolbarItem), props: {
props: { editor,
editor, isActive: editor.isActive({ textAlign: "right" }),
isActive: editor.isActive({ textAlign: "justify" }), icon: markRaw(MdiFormatAlignRight),
icon: markRaw(MdiFormatAlignJustify), title: i18n.global.t("editor.common.align_right"),
title: i18n.global.t("editor.common.align_justify"), action: () =>
action: () => editor.chain().focus().setTextAlign("right").run(),
editor.chain().focus().setTextAlign("justify").run(), },
}, },
}, {
]; priority: 30,
component: markRaw(ToolbarSubItem),
props: {
editor,
isActive: editor.isActive({ textAlign: "justify" }),
icon: markRaw(MdiFormatAlignJustify),
title: i18n.global.t("editor.common.align_justify"),
action: () =>
editor.chain().focus().setTextAlign("justify").run(),
},
},
],
};
}, },
}; };
}, },

View File

@ -4,9 +4,7 @@ import { markRaw } from "vue";
import ColorBubbleItem from "@/extensions/color/ColorBubbleItem.vue"; import ColorBubbleItem from "@/extensions/color/ColorBubbleItem.vue";
import HighlightBubbleItem from "@/extensions/highlight/HighlightBubbleItem.vue"; import HighlightBubbleItem from "@/extensions/highlight/HighlightBubbleItem.vue";
import LinkBubbleButton from "@/extensions/link/LinkBubbleButton.vue"; import LinkBubbleButton from "@/extensions/link/LinkBubbleButton.vue";
import MdiFormatQuoteOpen from "~icons/mdi/format-quote-open";
import MdiCodeTags from "~icons/mdi/code-tags"; import MdiCodeTags from "~icons/mdi/code-tags";
import MdiCodeBracesBox from "~icons/mdi/code-braces-box";
import MdiFormatColor from "~icons/mdi/format-color"; import MdiFormatColor from "~icons/mdi/format-color";
import MdiFormatColorHighlight from "~icons/mdi/format-color-highlight"; import MdiFormatColorHighlight from "~icons/mdi/format-color-highlight";
import MdiFormatItalic from "~icons/mdi/format-italic"; import MdiFormatItalic from "~icons/mdi/format-italic";
@ -15,10 +13,6 @@ import MdiShare from "~icons/mdi/share";
import MdiFormatStrikethrough from "~icons/mdi/format-strikethrough"; import MdiFormatStrikethrough from "~icons/mdi/format-strikethrough";
import MdiFormatSubscript from "~icons/mdi/format-subscript"; import MdiFormatSubscript from "~icons/mdi/format-subscript";
import MdiFormatSuperscript from "~icons/mdi/format-superscript"; import MdiFormatSuperscript from "~icons/mdi/format-superscript";
import MdiFormatAlignLeft from "~icons/mdi/format-align-left";
import MdiFormatAlignCenter from "~icons/mdi/format-align-center";
import MdiFormatAlignRight from "~icons/mdi/format-align-right";
import MdiFormatAlignJustify from "~icons/mdi/format-align-justify";
import MdiFormatUnderline from "~icons/mdi/format-underline"; import MdiFormatUnderline from "~icons/mdi/format-underline";
import { isActive, isTextSelection } from "@/tiptap/vue-3"; import { isActive, isTextSelection } from "@/tiptap/vue-3";
import type { EditorState } from "@/tiptap/pm"; import type { EditorState } from "@/tiptap/pm";
@ -125,7 +119,7 @@ const Text = TiptapText.extend<ExtensionOptions>({
}, },
}, },
{ {
priority: 51, priority: 60,
component: markRaw(ColorBubbleItem), component: markRaw(ColorBubbleItem),
props: { props: {
isActive: ({ editor }) => editor.isActive("color"), isActive: ({ editor }) => editor.isActive("color"),
@ -134,18 +128,7 @@ const Text = TiptapText.extend<ExtensionOptions>({
}, },
}, },
{ {
priority: 60, priority: 70,
props: {
isActive: ({ editor }) => editor.isActive("blockquote"),
icon: markRaw(MdiFormatQuoteOpen),
title: i18n.global.t("editor.common.quote"),
action: ({ editor }) => {
return editor.commands.toggleBlockquote();
},
},
},
{
priority: 80,
props: { props: {
isActive: ({ editor }) => editor.isActive("code"), isActive: ({ editor }) => editor.isActive("code"),
icon: markRaw(MdiCodeTags), icon: markRaw(MdiCodeTags),
@ -155,17 +138,7 @@ const Text = TiptapText.extend<ExtensionOptions>({
}, },
}, },
{ {
priority: 90, priority: 80,
props: {
isActive: ({ editor }) => editor.isActive("codeBlock"),
icon: markRaw(MdiCodeBracesBox),
title: i18n.global.t("editor.common.codeblock"),
action: ({ editor }) =>
editor.chain().focus().toggleCodeBlock().run(),
},
},
{
priority: 100,
props: { props: {
isActive: ({ editor }) => editor.isActive("superscript"), isActive: ({ editor }) => editor.isActive("superscript"),
icon: markRaw(MdiFormatSuperscript), icon: markRaw(MdiFormatSuperscript),
@ -175,7 +148,7 @@ const Text = TiptapText.extend<ExtensionOptions>({
}, },
}, },
{ {
priority: 110, priority: 90,
props: { props: {
isActive: ({ editor }) => editor.isActive("subscript"), isActive: ({ editor }) => editor.isActive("subscript"),
icon: markRaw(MdiFormatSubscript), icon: markRaw(MdiFormatSubscript),
@ -185,58 +158,14 @@ const Text = TiptapText.extend<ExtensionOptions>({
}, },
}, },
{ {
priority: 120, priority: 100,
props: {
isActive: ({ editor }) =>
editor.isActive({ textAlign: "left" }),
icon: markRaw(MdiFormatAlignLeft),
title: i18n.global.t("editor.common.align_left"),
action: ({ editor }) =>
editor.chain().focus().setTextAlign("left").run(),
},
},
{
priority: 130,
props: {
isActive: ({ editor }) =>
editor.isActive({ textAlign: "center" }),
icon: markRaw(MdiFormatAlignCenter),
title: i18n.global.t("editor.common.align_center"),
action: ({ editor }) =>
editor.chain().focus().setTextAlign("center").run(),
},
},
{
priority: 140,
props: {
isActive: ({ editor }) =>
editor.isActive({ textAlign: "right" }),
icon: markRaw(MdiFormatAlignRight),
title: i18n.global.t("editor.common.align_right"),
action: ({ editor }) =>
editor.chain().focus().setTextAlign("right").run(),
},
},
{
priority: 150,
props: {
isActive: ({ editor }) =>
editor.isActive({ textAlign: "justify" }),
icon: markRaw(MdiFormatAlignJustify),
title: i18n.global.t("editor.common.align_justify"),
action: ({ editor }) =>
editor.chain().focus().setTextAlign("justify").run(),
},
},
{
priority: 160,
component: markRaw(LinkBubbleButton), component: markRaw(LinkBubbleButton),
props: { props: {
isActive: ({ editor }) => editor.isActive("link"), isActive: ({ editor }) => editor.isActive("link"),
}, },
}, },
{ {
priority: 170, priority: 110,
props: { props: {
isActive: () => false, isActive: () => false,
visible: ({ editor }) => editor.isActive("link"), visible: ({ editor }) => editor.isActive("link"),
@ -246,7 +175,7 @@ const Text = TiptapText.extend<ExtensionOptions>({
}, },
}, },
{ {
priority: 180, priority: 120,
props: { props: {
isActive: () => false, isActive: () => false,
visible: ({ editor }) => editor.isActive("link"), visible: ({ editor }) => editor.isActive("link"),

View File

@ -91,6 +91,7 @@ editor:
color_picker: color_picker:
more_color: More more_color: More
common: common:
align_method: Align method
align_left: Align left align_left: Align left
align_center: Align center align_center: Align center
align_right: Align right align_right: Align right

View File

@ -91,6 +91,7 @@ editor:
color_picker: color_picker:
more_color: 更多颜色 more_color: 更多颜色
common: common:
align_method: 对齐方式
align_left: 左对齐 align_left: 左对齐
align_center: 居中 align_center: 居中
align_right: 右对齐 align_right: 右对齐