添加插入表情及特殊符号菜单
This commit is contained in:
@@ -50,6 +50,9 @@ import { Link } from "./insert/Link.ts";
|
||||
import { Image } from "./insert/Image.ts";
|
||||
import { Video } from "./insert/Video.ts";
|
||||
import { Audio } from "./insert/Audio.ts";
|
||||
import { HardBreak } from "./insert/HardBreak.ts";
|
||||
import { Emoji } from "./insert/Emoji.ts";
|
||||
import { Symbol } from "./insert/Symbol.ts";
|
||||
|
||||
/**
|
||||
* 传统菜单栏
|
||||
@@ -111,6 +114,9 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
||||
insertMenuImage!: Image;
|
||||
insertMenuVideo!: Video;
|
||||
insertMenuAudio!: Audio;
|
||||
insertMenuHardBreak!: HardBreak;
|
||||
insertMenuEmoji!: Emoji;
|
||||
insertMenuSymbol!: Symbol;
|
||||
|
||||
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
||||
super();
|
||||
@@ -292,6 +298,15 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
||||
|
||||
this.insertMenuAudio = new Audio({ menuType: "button", enable: true, header: "classic", hideText: false });
|
||||
this.eventComponents.push(this.insertMenuAudio);
|
||||
|
||||
this.insertMenuHardBreak = new HardBreak({ menuType: "button", enable: true, header: "classic", hideText: false });
|
||||
this.eventComponents.push(this.insertMenuHardBreak);
|
||||
|
||||
this.insertMenuEmoji = new Emoji({ menuType: "popup", enable: true, header: "classic", hideText: false });
|
||||
this.eventComponents.push(this.insertMenuEmoji);
|
||||
|
||||
this.insertMenuSymbol = new Symbol({ menuType: "popup", enable: true, header: "classic", hideText: false });
|
||||
this.eventComponents.push(this.insertMenuSymbol);
|
||||
}
|
||||
/**
|
||||
* 创建基础菜单
|
||||
@@ -373,5 +388,12 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
||||
group1.appendChild(this.insertMenuImage);
|
||||
group1.appendChild(this.insertMenuVideo);
|
||||
group1.appendChild(this.insertMenuAudio);
|
||||
|
||||
const group2 = document.createElement("div");
|
||||
group2.classList.add("uai-classic-virtual-group");
|
||||
this.classicMenuInsertGroup.appendChild(group2);
|
||||
group2.appendChild(this.insertMenuHardBreak);
|
||||
group2.appendChild(this.insertMenuEmoji);
|
||||
group2.appendChild(this.insertMenuSymbol);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,9 @@ import { Link } from "./insert/Link.ts";
|
||||
import { Image } from "./insert/Image.ts";
|
||||
import { Video } from "./insert/Video.ts";
|
||||
import { Audio } from "./insert/Audio.ts";
|
||||
import { HardBreak } from "./insert/HardBreak.ts";
|
||||
import { Emoji } from "./insert/Emoji.ts";
|
||||
import { Symbol } from "./insert/Symbol.ts";
|
||||
|
||||
/**
|
||||
* 经典菜单栏
|
||||
@@ -114,6 +117,9 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
||||
insertMenuImage!: Image;
|
||||
insertMenuVideo!: Video;
|
||||
insertMenuAudio!: Audio;
|
||||
insertMenuHardBreak!: HardBreak;
|
||||
insertMenuEmoji!: Emoji;
|
||||
insertMenuSymbol!: Symbol;
|
||||
|
||||
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
||||
super();
|
||||
@@ -315,6 +321,15 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
||||
|
||||
this.insertMenuAudio = new Audio({ menuType: "button", enable: true, huge: true });
|
||||
this.eventComponents.push(this.insertMenuAudio);
|
||||
|
||||
this.insertMenuHardBreak = new HardBreak({ menuType: "button", enable: true, huge: true });
|
||||
this.eventComponents.push(this.insertMenuHardBreak);
|
||||
|
||||
this.insertMenuEmoji = new Emoji({ menuType: "popup", enable: true, huge: true, hideText: false });
|
||||
this.eventComponents.push(this.insertMenuEmoji);
|
||||
|
||||
this.insertMenuSymbol = new Symbol({ menuType: "popup", enable: true, huge: true, hideText: false });
|
||||
this.eventComponents.push(this.insertMenuSymbol);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -470,5 +485,12 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
||||
group1.appendChild(this.insertMenuImage);
|
||||
group1.appendChild(this.insertMenuVideo);
|
||||
group1.appendChild(this.insertMenuAudio);
|
||||
|
||||
const group2 = document.createElement("div");
|
||||
group2.classList.add("uai-ribbon-virtual-group");
|
||||
this.ribbonMenuInsertGroup.appendChild(group2);
|
||||
group2.appendChild(this.insertMenuHardBreak);
|
||||
group2.appendChild(this.insertMenuEmoji);
|
||||
group2.appendChild(this.insertMenuSymbol);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
import icon from "../../../../assets/icons/emoji.svg";
|
||||
import { t } from "i18next";
|
||||
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||
import { EditorEvents } from "@tiptap/core";
|
||||
import tippy, { Instance, Props } from "tippy.js";
|
||||
|
||||
/**
|
||||
* 插入菜单:插入表情
|
||||
*/
|
||||
export class Emoji extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "popup",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: true,
|
||||
text: t('insert.emoji'),
|
||||
tooltip: t('insert.emoji'),
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
menuButton: MenuButton;
|
||||
// 选项提示实例
|
||||
tippyInstance!: Instance<Props>;
|
||||
|
||||
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);
|
||||
|
||||
// 创建表情选择提示框
|
||||
if (this.menuButtonOptions.enable && this.menuButton.menuButtonArrow) {
|
||||
this.tippyInstance = tippy(this.menuButton.menuButton, {
|
||||
content: this.createContainer(event, options),
|
||||
appendTo: 'parent',
|
||||
placement: 'bottom',
|
||||
trigger: 'click',
|
||||
interactive: true,
|
||||
arrow: false,
|
||||
onShow: () => {
|
||||
this.menuButton.tippyInstance?.disable();
|
||||
},
|
||||
onHidden: () => {
|
||||
this.menuButton.tippyInstance?.enable();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建表情选择容器
|
||||
* @param event
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
createContainer(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("uai-emojis-container");
|
||||
// 添加所有可选表情
|
||||
options.dicts?.emojis?.forEach(emoji => {
|
||||
const groupTitle = document.createElement("div");
|
||||
groupTitle.classList.add("uai-emojis-group-title");
|
||||
groupTitle.innerHTML = emoji.label;
|
||||
container.appendChild(groupTitle);
|
||||
const groupContainer = document.createElement("div");
|
||||
groupContainer.classList.add("uai-emojis-group-container");
|
||||
container.appendChild(groupContainer);
|
||||
emoji.value.toString().split(" ").forEach(item => {
|
||||
const it = document.createElement("div");
|
||||
it.classList.add("uai-emojis-group-item");
|
||||
it.innerHTML = item;
|
||||
groupContainer.appendChild(it);
|
||||
it.addEventListener("click", () => {
|
||||
event.editor.chain().focus().insertContent(item).run();
|
||||
});
|
||||
})
|
||||
});
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
import icon from "../../../../assets/icons/hard-break.svg";
|
||||
import { t } from "i18next";
|
||||
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||
import { EditorEvents } from "@tiptap/core";
|
||||
|
||||
/**
|
||||
* 插入菜单:插入换行
|
||||
*/
|
||||
export class HardBreak extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "button",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: false,
|
||||
text: t('insert.hardBreak'),
|
||||
tooltip: t('insert.hardBreak'),
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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) {
|
||||
event.editor.chain().focus().setHardBreak().run();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义Transaction监听方法
|
||||
* @param event
|
||||
* @param options
|
||||
*/
|
||||
onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) {
|
||||
this.menuButton.onTransaction(event, options);
|
||||
if (this.menuButton.menuButton) {
|
||||
var disable = event.editor.isEditable;
|
||||
this.onEditableChange(disable);
|
||||
}
|
||||
}
|
||||
|
||||
onEditableChange(editable: boolean) {
|
||||
this.menuButtonOptions.enable = editable;
|
||||
this.menuButton.onEditableChange(editable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
import icon from "../../../../assets/icons/symbol.svg";
|
||||
import { t } from "i18next";
|
||||
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||
import { EditorEvents } from "@tiptap/core";
|
||||
import tippy, { Instance, Props } from "tippy.js";
|
||||
|
||||
/**
|
||||
* 插入菜单:插入符号
|
||||
*/
|
||||
export class Symbol extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "popup",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: true,
|
||||
text: t('insert.symbol'),
|
||||
tooltip: t('insert.symbol'),
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
menuButton: MenuButton;
|
||||
// 选项提示实例
|
||||
tippyInstance!: Instance<Props>;
|
||||
|
||||
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);
|
||||
|
||||
// 初始化特殊符号选项提示框
|
||||
if (this.menuButtonOptions.enable && this.menuButton.menuButtonArrow) {
|
||||
this.tippyInstance = tippy(this.menuButton.menuButton, {
|
||||
content: this.createContainer(event, options),
|
||||
appendTo: 'parent',
|
||||
placement: 'bottom',
|
||||
trigger: 'click',
|
||||
interactive: true,
|
||||
arrow: false,
|
||||
onShow: () => {
|
||||
this.menuButton.tippyInstance?.disable();
|
||||
},
|
||||
onHidden: () => {
|
||||
this.menuButton.tippyInstance?.enable();
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建特殊符号选择提示框
|
||||
* @param event
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
createContainer(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("uai-emojis-container");
|
||||
// 添加所有可选的特殊符号
|
||||
options.dicts?.symbols?.forEach(symbol => {
|
||||
const groupTitle = document.createElement("div");
|
||||
groupTitle.classList.add("uai-emojis-group-title");
|
||||
groupTitle.innerHTML = symbol.label;
|
||||
container.appendChild(groupTitle);
|
||||
const groupContainer = document.createElement("div");
|
||||
groupContainer.classList.add("uai-emojis-group-container");
|
||||
container.appendChild(groupContainer);
|
||||
symbol.value.toString().split("").forEach(item => {
|
||||
const it = document.createElement("div");
|
||||
it.classList.add("uai-emojis-group-item");
|
||||
it.innerHTML = item;
|
||||
groupContainer.appendChild(it);
|
||||
it.addEventListener("click", () => {
|
||||
event.editor.chain().focus().insertContent(item).run();
|
||||
});
|
||||
})
|
||||
});
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user