添加字体设置菜单
This commit is contained in:
@@ -11,11 +11,17 @@ import { Classic } from "./menus/toolbar/Classic.ts";
|
|||||||
import { ScrollableDiv } from "./menus/toolbar/ScrollableDiv.ts";
|
import { ScrollableDiv } from "./menus/toolbar/ScrollableDiv.ts";
|
||||||
import { MenuButton } from "./menus/MenuButton.ts";
|
import { MenuButton } from "./menus/MenuButton.ts";
|
||||||
|
|
||||||
|
import { FontSizeIncrease } from "./menus/common/FontSizeIncrease.ts";
|
||||||
|
import { FontSizeDecrease } from "./menus/common/FontSizeDecrease.ts";
|
||||||
|
|
||||||
import { Undo } from "./menus/toolbar/base/Undo.ts";
|
import { Undo } from "./menus/toolbar/base/Undo.ts";
|
||||||
import { Redo } from "./menus/toolbar/base/Redo.ts";
|
import { Redo } from "./menus/toolbar/base/Redo.ts";
|
||||||
import { FormatPainter } from "./menus/toolbar/base/FormatPainter.ts";
|
import { FormatPainter } from "./menus/toolbar/base/FormatPainter.ts";
|
||||||
import { ClearFormat } from "./menus/toolbar/base/ClearFormat.ts";
|
import { ClearFormat } from "./menus/toolbar/base/ClearFormat.ts";
|
||||||
|
|
||||||
|
import { FontFamily } from "./menus/toolbar/base/FontFamily.ts";
|
||||||
|
import { FontSize } from "./menus/toolbar/base/FontSize.ts";
|
||||||
|
|
||||||
// 注册组件
|
// 注册组件
|
||||||
defineCustomElement('uai-editor-header', Header);
|
defineCustomElement('uai-editor-header', Header);
|
||||||
defineCustomElement('uai-editor-editor', Editor);
|
defineCustomElement('uai-editor-editor', Editor);
|
||||||
@@ -27,7 +33,13 @@ defineCustomElement('uai-editor-classic-menu', Classic);
|
|||||||
defineCustomElement('uai-editor-scrollable-div', ScrollableDiv);
|
defineCustomElement('uai-editor-scrollable-div', ScrollableDiv);
|
||||||
defineCustomElement('uai-editor-menu-button', MenuButton);
|
defineCustomElement('uai-editor-menu-button', MenuButton);
|
||||||
|
|
||||||
|
defineCustomElement('uai-editor-common-menu-font-size-increase', FontSizeIncrease);
|
||||||
|
defineCustomElement('uai-editor-common-menu-font-size-decrease', FontSizeDecrease);
|
||||||
|
|
||||||
defineCustomElement('uai-editor-base-menu-undo', Undo);
|
defineCustomElement('uai-editor-base-menu-undo', Undo);
|
||||||
defineCustomElement('uai-editor-base-menu-redo', Redo);
|
defineCustomElement('uai-editor-base-menu-redo', Redo);
|
||||||
defineCustomElement('uai-editor-base-menu-format-painter', FormatPainter);
|
defineCustomElement('uai-editor-base-menu-format-painter', FormatPainter);
|
||||||
defineCustomElement('uai-editor-base-menu-clear-format', ClearFormat);
|
defineCustomElement('uai-editor-base-menu-clear-format', ClearFormat);
|
||||||
|
|
||||||
|
defineCustomElement('uai-editor-base-menu-font-family', FontFamily);
|
||||||
|
defineCustomElement('uai-editor-base-menu-font-size', FontSize);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import tippy, { Instance, Props } from "tippy.js";
|
|||||||
* 菜单按钮选项
|
* 菜单按钮选项
|
||||||
*/
|
*/
|
||||||
export type MenuButtonOptions = {
|
export type MenuButtonOptions = {
|
||||||
menuType: "button",
|
menuType: "button" | "select",
|
||||||
enable: boolean,
|
enable: boolean,
|
||||||
className?: string,
|
className?: string,
|
||||||
header?: "ribbon" | "classic",
|
header?: "ribbon" | "classic",
|
||||||
@@ -55,6 +55,10 @@ export class MenuButton extends HTMLElement implements UAIEditorEventListener {
|
|||||||
// 按钮
|
// 按钮
|
||||||
this.createMenuButton()
|
this.createMenuButton()
|
||||||
}
|
}
|
||||||
|
if (this.menuButtonOptions.menuType === "select") {
|
||||||
|
// 下拉选择
|
||||||
|
this.createMenuSelect()
|
||||||
|
}
|
||||||
|
|
||||||
// 提示信息
|
// 提示信息
|
||||||
var tipsContent = this.menuButtonOptions.tooltip;
|
var tipsContent = this.menuButtonOptions.tooltip;
|
||||||
@@ -129,4 +133,17 @@ export class MenuButton extends HTMLElement implements UAIEditorEventListener {
|
|||||||
this.menuButtonContent.appendChild(menuButtonText);
|
this.menuButtonContent.appendChild(menuButtonText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建下拉选择框
|
||||||
|
*/
|
||||||
|
createMenuSelect() {
|
||||||
|
this.menuButton = document.createElement("div");
|
||||||
|
this.menuButton.classList.add("uai-menu-button");
|
||||||
|
this.container.appendChild(this.menuButton);
|
||||||
|
|
||||||
|
this.menuButtonContent = document.createElement("select");
|
||||||
|
this.menuButtonContent.classList.add("uai-button-content");
|
||||||
|
this.menuButton.appendChild(this.menuButtonContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (c) 2024-present AI-Labs
|
||||||
|
|
||||||
|
// @ ts-nocheck
|
||||||
|
import { MenuButton, MenuButtonOptions } from "../MenuButton.ts";
|
||||||
|
import icon from "../../../assets/icons/font-size-decrease.svg";
|
||||||
|
import { t } from "i18next";
|
||||||
|
import { UAIEditorEventListener, UAIEditorOptions } from "../../../core/UAIEditor.ts";
|
||||||
|
import { EditorEvents } from "@tiptap/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共菜单:减小字号
|
||||||
|
*/
|
||||||
|
export class FontSizeDecrease extends HTMLElement implements UAIEditorEventListener {
|
||||||
|
// 按钮选项
|
||||||
|
menuButtonOptions: MenuButtonOptions = {
|
||||||
|
menuType: "button",
|
||||||
|
enable: true,
|
||||||
|
icon: icon,
|
||||||
|
hideText: true,
|
||||||
|
text: t('base.fontSize.decrease'),
|
||||||
|
tooltip: t('base.fontSize.decrease'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 功能按钮
|
||||||
|
menuButton: MenuButton;
|
||||||
|
|
||||||
|
constructor(options: MenuButtonOptions) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// 初始化功能按钮选项
|
||||||
|
this.menuButtonOptions = { ...this.menuButtonOptions, ...options };
|
||||||
|
|
||||||
|
// 创建功能按钮
|
||||||
|
this.menuButton = new MenuButton(this.menuButtonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义创建方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onCreate(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onCreate(event, options);
|
||||||
|
this.appendChild(this.menuButton);
|
||||||
|
|
||||||
|
// 定义按钮点击事件,设置减小字号
|
||||||
|
this.addEventListener("click", () => {
|
||||||
|
if (this.menuButtonOptions.enable) {
|
||||||
|
// 获取当前字号
|
||||||
|
var fontSize = event.editor.getAttributes('textStyle').fontSize;
|
||||||
|
if (fontSize) {
|
||||||
|
const size = options.dicts?.fontSizes?.find(({ value }) => value === fontSize);
|
||||||
|
if (!size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取比当前字号小的字号
|
||||||
|
const nextFont = options.dicts?.fontSizes?.find(({ order }) => order === +size.order - 1);
|
||||||
|
if (nextFont) {
|
||||||
|
event.editor.chain().focus().setFontSize(nextFont.value).run();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.editor.chain().focus().setFontSize("12pt").run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义Transaction监听方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onTransaction(event, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditableChange(editable: boolean) {
|
||||||
|
this.menuButtonOptions.enable = editable;
|
||||||
|
this.menuButton.onEditableChange(editable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright (c) 2024-present AI-Labs
|
||||||
|
|
||||||
|
// @ ts-nocheck
|
||||||
|
import { MenuButton, MenuButtonOptions } from "../MenuButton.ts";
|
||||||
|
import icon from "../../../assets/icons/font-size-increase.svg";
|
||||||
|
import { t } from "i18next";
|
||||||
|
import { UAIEditorEventListener, UAIEditorOptions } from "../../../core/UAIEditor.ts";
|
||||||
|
import { EditorEvents } from "@tiptap/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共菜单:增大字号
|
||||||
|
*/
|
||||||
|
export class FontSizeIncrease extends HTMLElement implements UAIEditorEventListener {
|
||||||
|
// 按钮选项
|
||||||
|
menuButtonOptions: MenuButtonOptions = {
|
||||||
|
menuType: "button",
|
||||||
|
enable: true,
|
||||||
|
icon: icon,
|
||||||
|
hideText: true,
|
||||||
|
text: t('base.fontSize.increase'),
|
||||||
|
tooltip: t('base.fontSize.increase'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 功能按钮
|
||||||
|
menuButton: MenuButton;
|
||||||
|
|
||||||
|
constructor(options: MenuButtonOptions) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// 初始化功能按钮选项
|
||||||
|
this.menuButtonOptions = { ...this.menuButtonOptions, ...options };
|
||||||
|
|
||||||
|
// 创建功能按钮
|
||||||
|
this.menuButton = new MenuButton(this.menuButtonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义创建方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onCreate(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onCreate(event, options);
|
||||||
|
this.appendChild(this.menuButton);
|
||||||
|
|
||||||
|
// 定义按钮点击事件,设置增大字号
|
||||||
|
this.addEventListener("click", () => {
|
||||||
|
if (this.menuButtonOptions.enable) {
|
||||||
|
// 获取当前字号
|
||||||
|
var fontSize = event.editor.getAttributes('textStyle').fontSize;
|
||||||
|
if (fontSize) {
|
||||||
|
const size = options.dicts?.fontSizes?.find(({ value }) => value === fontSize);
|
||||||
|
if (!size) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取比当前字号大的字号
|
||||||
|
const nextFont = options.dicts?.fontSizes?.find(({ order }) => order === +size.order + 1);
|
||||||
|
if (nextFont) {
|
||||||
|
event.editor.chain().focus().setFontSize(nextFont.value).run();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.editor.chain().focus().setFontSize("18px").run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义Transaction监听方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onTransaction(event, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditableChange(editable: boolean) {
|
||||||
|
this.menuButtonOptions.enable = editable;
|
||||||
|
this.menuButton.onEditableChange(editable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7,11 +7,17 @@ import { UAIEditorEventListener, UAIEditorOptions } from "../../../core/UAIEdito
|
|||||||
import menuIcon from "../../../assets/icons/menu.svg";
|
import menuIcon from "../../../assets/icons/menu.svg";
|
||||||
import { ScrollableDiv } from "./ScrollableDiv";
|
import { ScrollableDiv } from "./ScrollableDiv";
|
||||||
|
|
||||||
|
import { FontSizeIncrease } from "../common/FontSizeIncrease.ts";
|
||||||
|
import { FontSizeDecrease } from "../common/FontSizeDecrease.ts";
|
||||||
|
|
||||||
import { Redo } from "./base/Redo";
|
import { Redo } from "./base/Redo";
|
||||||
import { Undo } from "./base/Undo";
|
import { Undo } from "./base/Undo";
|
||||||
import { FormatPainter } from "./base/FormatPainter";
|
import { FormatPainter } from "./base/FormatPainter";
|
||||||
import { ClearFormat } from "./base/ClearFormat";
|
import { ClearFormat } from "./base/ClearFormat";
|
||||||
|
|
||||||
|
import { FontFamily } from "./base/FontFamily";
|
||||||
|
import { FontSize } from "./base/FontSize";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 传统菜单栏
|
* 传统菜单栏
|
||||||
*/
|
*/
|
||||||
@@ -33,6 +39,11 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
|||||||
baseMenuFormatPainter!: FormatPainter;
|
baseMenuFormatPainter!: FormatPainter;
|
||||||
baseMenuClearFormat!: ClearFormat;
|
baseMenuClearFormat!: ClearFormat;
|
||||||
|
|
||||||
|
baseMenuFontFamily!: FontFamily;
|
||||||
|
baseMenuFontSize!: FontSize;
|
||||||
|
baseMenuFontSizeIncrease!: FontSizeIncrease;
|
||||||
|
baseMenuFontSizeDecrease!: FontSizeDecrease;
|
||||||
|
|
||||||
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
||||||
super();
|
super();
|
||||||
this.defaultToolbarMenus = defaultToolbarMenus;
|
this.defaultToolbarMenus = defaultToolbarMenus;
|
||||||
@@ -118,6 +129,18 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
|||||||
|
|
||||||
this.baseMenuClearFormat = new ClearFormat({ menuType: "button", enable: true });
|
this.baseMenuClearFormat = new ClearFormat({ menuType: "button", enable: true });
|
||||||
this.eventComponents.push(this.baseMenuClearFormat);
|
this.eventComponents.push(this.baseMenuClearFormat);
|
||||||
|
|
||||||
|
this.baseMenuFontFamily = new FontFamily({ menuType: "select", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontFamily);
|
||||||
|
|
||||||
|
this.baseMenuFontSize = new FontSize({ menuType: "select", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontSize);
|
||||||
|
|
||||||
|
this.baseMenuFontSizeIncrease = new FontSizeIncrease({ menuType: "button", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontSizeIncrease);
|
||||||
|
|
||||||
|
this.baseMenuFontSizeDecrease = new FontSizeDecrease({ menuType: "button", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontSizeDecrease);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建基础菜单
|
* 创建基础菜单
|
||||||
@@ -139,5 +162,13 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
|||||||
group1.appendChild(this.baseMenuRedo);
|
group1.appendChild(this.baseMenuRedo);
|
||||||
group1.appendChild(this.baseMenuFormatPainter);
|
group1.appendChild(this.baseMenuFormatPainter);
|
||||||
group1.appendChild(this.baseMenuClearFormat);
|
group1.appendChild(this.baseMenuClearFormat);
|
||||||
|
|
||||||
|
const group2 = document.createElement("div");
|
||||||
|
group2.classList.add("uai-classic-virtual-group");
|
||||||
|
this.classicMenuBaseGroup.appendChild(group2);
|
||||||
|
group2.appendChild(this.baseMenuFontFamily);
|
||||||
|
group2.appendChild(this.baseMenuFontSize);
|
||||||
|
group2.appendChild(this.baseMenuFontSizeIncrease);
|
||||||
|
group2.appendChild(this.baseMenuFontSizeDecrease);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,12 +7,18 @@ import { UAIEditorEventListener, UAIEditorOptions } from "../../../core/UAIEdito
|
|||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import { ScrollableDiv } from "./ScrollableDiv";
|
import { ScrollableDiv } from "./ScrollableDiv";
|
||||||
|
|
||||||
|
import { FontSizeIncrease } from "../common/FontSizeIncrease.ts";
|
||||||
|
import { FontSizeDecrease } from "../common/FontSizeDecrease.ts";
|
||||||
|
|
||||||
import { Redo } from "./base/Redo";
|
import { Redo } from "./base/Redo";
|
||||||
import { Undo } from "./base/Undo";
|
import { Undo } from "./base/Undo";
|
||||||
|
|
||||||
import { FormatPainter } from "./base/FormatPainter";
|
import { FormatPainter } from "./base/FormatPainter";
|
||||||
import { ClearFormat } from "./base/ClearFormat";
|
import { ClearFormat } from "./base/ClearFormat";
|
||||||
|
|
||||||
|
import { FontFamily } from "./base/FontFamily";
|
||||||
|
import { FontSize } from "./base/FontSize";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 经典菜单栏
|
* 经典菜单栏
|
||||||
*/
|
*/
|
||||||
@@ -32,10 +38,14 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
|||||||
// 基础菜单
|
// 基础菜单
|
||||||
baseMenuUndo!: Undo;
|
baseMenuUndo!: Undo;
|
||||||
baseMenuRedo!: Redo;
|
baseMenuRedo!: Redo;
|
||||||
|
|
||||||
baseMenuFormatPainter!: FormatPainter;
|
baseMenuFormatPainter!: FormatPainter;
|
||||||
baseMenuClearFormat!: ClearFormat;
|
baseMenuClearFormat!: ClearFormat;
|
||||||
|
|
||||||
|
baseMenuFontFamily!: FontFamily;
|
||||||
|
baseMenuFontSize!: FontSize;
|
||||||
|
baseMenuFontSizeIncrease!: FontSizeIncrease;
|
||||||
|
baseMenuFontSizeDecrease!: FontSizeDecrease;
|
||||||
|
|
||||||
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
||||||
super();
|
super();
|
||||||
this.defaultToolbarMenus = defaultToolbarMenus;
|
this.defaultToolbarMenus = defaultToolbarMenus;
|
||||||
@@ -141,6 +151,18 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
|||||||
|
|
||||||
this.baseMenuClearFormat = new ClearFormat({ menuType: "button", enable: true });
|
this.baseMenuClearFormat = new ClearFormat({ menuType: "button", enable: true });
|
||||||
this.eventComponents.push(this.baseMenuClearFormat);
|
this.eventComponents.push(this.baseMenuClearFormat);
|
||||||
|
|
||||||
|
this.baseMenuFontFamily = new FontFamily({ menuType: "select", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontFamily);
|
||||||
|
|
||||||
|
this.baseMenuFontSize = new FontSize({ menuType: "select", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontSize);
|
||||||
|
|
||||||
|
this.baseMenuFontSizeIncrease = new FontSizeIncrease({ menuType: "button", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontSizeIncrease);
|
||||||
|
|
||||||
|
this.baseMenuFontSizeDecrease = new FontSizeDecrease({ menuType: "button", enable: true });
|
||||||
|
this.eventComponents.push(this.baseMenuFontSizeDecrease);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -171,5 +193,18 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
|||||||
group1.appendChild(group1row2);
|
group1.appendChild(group1row2);
|
||||||
group1row2.appendChild(this.baseMenuFormatPainter);
|
group1row2.appendChild(this.baseMenuFormatPainter);
|
||||||
group1row2.appendChild(this.baseMenuClearFormat);
|
group1row2.appendChild(this.baseMenuClearFormat);
|
||||||
|
|
||||||
|
const group2 = document.createElement("div");
|
||||||
|
group2.classList.add("uai-ribbon-virtual-group");
|
||||||
|
this.ribbonMenuBaseGroup.appendChild(group2);
|
||||||
|
|
||||||
|
const group2row1 = document.createElement("div");
|
||||||
|
group2row1.classList.add("uai-ribbon-virtual-group-row");
|
||||||
|
group2.appendChild(group2row1);
|
||||||
|
group2row1.appendChild(this.baseMenuFontFamily);
|
||||||
|
group2row1.appendChild(this.baseMenuFontSize);
|
||||||
|
group2row1.appendChild(this.baseMenuFontSizeIncrease);
|
||||||
|
group2row1.appendChild(this.baseMenuFontSizeDecrease);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (c) 2024-present AI-Labs
|
||||||
|
|
||||||
|
// @ ts-nocheck
|
||||||
|
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||||
|
import { t } from "i18next";
|
||||||
|
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||||
|
import { EditorEvents } from "@tiptap/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础菜单:设置字体
|
||||||
|
*/
|
||||||
|
export class FontFamily extends HTMLElement implements UAIEditorEventListener {
|
||||||
|
// 按钮选项
|
||||||
|
menuButtonOptions: MenuButtonOptions = {
|
||||||
|
menuType: "select",
|
||||||
|
enable: true,
|
||||||
|
hideText: true,
|
||||||
|
text: t('base.fontFamily.text'),
|
||||||
|
tooltip: t('base.fontFamily.text'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 功能按钮
|
||||||
|
menuButton: MenuButton;
|
||||||
|
|
||||||
|
constructor(options: MenuButtonOptions) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// 初始化功能按钮选项
|
||||||
|
this.menuButtonOptions = { ...this.menuButtonOptions, ...options };
|
||||||
|
|
||||||
|
// 创建功能按钮
|
||||||
|
this.menuButton = new MenuButton(this.menuButtonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义创建方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onCreate(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onCreate(event, options);
|
||||||
|
this.menuButton.container.classList.add("uai-editor-menu-select");
|
||||||
|
this.menuButton.menuButtonContent.style.fontSize = "11px";
|
||||||
|
this.menuButton.menuButtonContent.style.width = "125px";
|
||||||
|
// 设置可选字体
|
||||||
|
options.dicts?.fontFamilies?.forEach(font => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.label = font.label;
|
||||||
|
option.value = `${font.value}`;
|
||||||
|
(this.menuButton.menuButtonContent as HTMLSelectElement).options.add(option);
|
||||||
|
})
|
||||||
|
this.appendChild(this.menuButton);
|
||||||
|
|
||||||
|
// 定义按钮点击事件,设置当前内容的字体
|
||||||
|
this.addEventListener("change", (e: Event) => {
|
||||||
|
if (this.menuButtonOptions.enable) {
|
||||||
|
const fontFamily = (e.target as HTMLSelectElement).value;
|
||||||
|
if (fontFamily === "") {
|
||||||
|
event.editor.chain().focus().unsetFontFamily().run();
|
||||||
|
} else {
|
||||||
|
event.editor.chain().focus().setFontFamily(fontFamily).run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义Transaction监听方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onTransaction(event, options);
|
||||||
|
if (this.menuButton.menuButtonContent && this.menuButtonOptions.enable) {
|
||||||
|
var fontFamily = event.editor.getAttributes('textStyle').fontFamily;
|
||||||
|
// 清除所有选项的选中状态
|
||||||
|
(this.menuButton.menuButtonContent as HTMLSelectElement).querySelectorAll("option").forEach(option => {
|
||||||
|
option.selected = false;
|
||||||
|
});
|
||||||
|
// 设置指定值的选项为选中状态
|
||||||
|
const optionToSelect = (this.menuButton.menuButtonContent as HTMLSelectElement).querySelector(`option[value="${fontFamily}"]`) as HTMLOptionElement;
|
||||||
|
if (optionToSelect) {
|
||||||
|
optionToSelect.selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditableChange(editable: boolean) {
|
||||||
|
this.menuButtonOptions.enable = editable;
|
||||||
|
this.menuButton.onEditableChange(editable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
// Copyright (c) 2024-present AI-Labs
|
||||||
|
|
||||||
|
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||||
|
import { t } from "i18next";
|
||||||
|
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||||
|
import { EditorEvents } from "@tiptap/core";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基础菜单:设置字号
|
||||||
|
*/
|
||||||
|
export class FontSize extends HTMLElement implements UAIEditorEventListener {
|
||||||
|
// 按钮选项
|
||||||
|
menuButtonOptions: MenuButtonOptions = {
|
||||||
|
menuType: "select",
|
||||||
|
enable: true,
|
||||||
|
hideText: true,
|
||||||
|
text: t('base.fontSize.text'),
|
||||||
|
tooltip: t('base.fontSize.text'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 功能按钮
|
||||||
|
menuButton: MenuButton;
|
||||||
|
|
||||||
|
constructor(options: MenuButtonOptions) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// 初始化功能按钮选项
|
||||||
|
this.menuButtonOptions = { ...this.menuButtonOptions, ...options };
|
||||||
|
|
||||||
|
// 创建功能按钮
|
||||||
|
this.menuButton = new MenuButton(this.menuButtonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义创建方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onCreate(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onCreate(event, options);
|
||||||
|
this.menuButton.container.classList.add("uai-editor-menu-select");
|
||||||
|
this.menuButton.menuButtonContent.style.fontSize = "11px";
|
||||||
|
this.menuButton.menuButtonContent.style.width = "65px";
|
||||||
|
// 设置可选字号
|
||||||
|
options.dicts?.fontSizes?.forEach(font => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.label = `${font.label}`;
|
||||||
|
option.value = `${font.value}`;
|
||||||
|
(this.menuButton.menuButtonContent as HTMLSelectElement).options.add(option);
|
||||||
|
})
|
||||||
|
this.appendChild(this.menuButton);
|
||||||
|
|
||||||
|
// 定义按钮点击事件,设置当前内容的字号
|
||||||
|
this.addEventListener("change", (e: Event) => {
|
||||||
|
if (this.menuButtonOptions.enable) {
|
||||||
|
const fontSize = (e.target as HTMLSelectElement).value;
|
||||||
|
if (fontSize === "") {
|
||||||
|
event.editor.chain().focus().unsetFontSize().run();
|
||||||
|
} else {
|
||||||
|
event.editor.chain().focus().setFontSize(fontSize).run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义Transaction监听方法
|
||||||
|
* @param event
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) {
|
||||||
|
this.menuButton.onTransaction(event, options);
|
||||||
|
if (this.menuButton.menuButtonContent && this.menuButtonOptions.enable) {
|
||||||
|
var fontSize = event.editor.getAttributes('textStyle').fontSize;
|
||||||
|
// 清除所有选项的选中状态
|
||||||
|
(this.menuButton.menuButtonContent as HTMLSelectElement).querySelectorAll("option").forEach(option => {
|
||||||
|
option.selected = false;
|
||||||
|
});
|
||||||
|
// 设置指定值的选项为选中状态
|
||||||
|
const optionToSelect = (this.menuButton.menuButtonContent as HTMLSelectElement).querySelector(`option[value="${fontSize}"]`) as HTMLOptionElement;
|
||||||
|
if (optionToSelect) {
|
||||||
|
optionToSelect.selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditableChange(editable: boolean) {
|
||||||
|
this.menuButtonOptions.enable = editable;
|
||||||
|
this.menuButton.onEditableChange(editable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -5,7 +5,10 @@ import { Extensions } from "@tiptap/core";
|
|||||||
import { UAIEditor, UAIEditorOptions } from "./UAIEditor";
|
import { UAIEditor, UAIEditorOptions } from "./UAIEditor";
|
||||||
|
|
||||||
import { StarterKit } from "@tiptap/starter-kit";
|
import { StarterKit } from "@tiptap/starter-kit";
|
||||||
|
import { FontFamily } from "@tiptap/extension-font-family";
|
||||||
|
import { TextStyle } from "@tiptap/extension-text-style";
|
||||||
|
|
||||||
|
import FontSize from "../extensions/FontSize.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义编辑器的所有自定义扩展组件
|
* 定义编辑器的所有自定义扩展组件
|
||||||
@@ -19,6 +22,11 @@ export const allExtensions = (uaiEditor: UAIEditor, _options: UAIEditorOptions):
|
|||||||
bulletList: false,
|
bulletList: false,
|
||||||
orderedList: false,
|
orderedList: false,
|
||||||
}),
|
}),
|
||||||
|
FontFamily,
|
||||||
|
FontSize.configure({
|
||||||
|
|
||||||
|
}),
|
||||||
|
TextStyle,
|
||||||
];
|
];
|
||||||
|
|
||||||
return extensions;
|
return extensions;
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (c) 2024-present AI-Labs
|
||||||
|
|
||||||
|
import { Extension } from '@tiptap/core'
|
||||||
|
|
||||||
|
export interface FontSizeOptions {
|
||||||
|
types: string[]
|
||||||
|
defaultFontSize: string
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@tiptap/core' {
|
||||||
|
interface Commands<ReturnType> {
|
||||||
|
setFontSize: {
|
||||||
|
/**
|
||||||
|
* 设置字体大小
|
||||||
|
*/
|
||||||
|
setFontSize: (fontSize: any) => ReturnType
|
||||||
|
}
|
||||||
|
unsetFontSize: {
|
||||||
|
/**
|
||||||
|
* 取消字体大小设置
|
||||||
|
*/
|
||||||
|
unsetFontSize: () => ReturnType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Extension.create<FontSizeOptions>({
|
||||||
|
name: 'fontSize',
|
||||||
|
addOptions() {
|
||||||
|
return {
|
||||||
|
types: ['textStyle'],
|
||||||
|
defaultFontSize: '14px',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addGlobalAttributes() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
types: this.options.types,
|
||||||
|
attributes: {
|
||||||
|
fontSize: {
|
||||||
|
default: this.options.defaultFontSize,
|
||||||
|
parseHTML: (element) =>
|
||||||
|
element.style.fontSize || this.options.defaultFontSize,
|
||||||
|
renderHTML: (attributes) => {
|
||||||
|
if (attributes.fontSize === this.options.defaultFontSize) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
return { style: `font-size: ${attributes.fontSize}` }
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
addCommands() {
|
||||||
|
return {
|
||||||
|
setFontSize:
|
||||||
|
(fontSize) =>
|
||||||
|
({ chain }) => {
|
||||||
|
return chain().setMark('textStyle', { fontSize }).run()
|
||||||
|
},
|
||||||
|
unsetFontSize:
|
||||||
|
() =>
|
||||||
|
({ chain }) => {
|
||||||
|
return chain().setMark('textStyle', { fontSize: null }).removeEmptyTextStyle().run()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user