添加列表样式及缩进菜单
This commit is contained in:
@@ -20,13 +20,21 @@ import { Superscript } from "../common/Superscript.ts";
|
||||
import { FontColor } from "../common/FontColor.ts";
|
||||
import { Highlight } from "../common/Highlight.ts";
|
||||
|
||||
import { Redo } from "./base/Redo";
|
||||
import { Undo } from "./base/Undo";
|
||||
import { FormatPainter } from "./base/FormatPainter";
|
||||
import { ClearFormat } from "./base/ClearFormat";
|
||||
import { Redo } from "./base/Redo.ts";
|
||||
import { Undo } from "./base/Undo.ts";
|
||||
|
||||
import { FontFamily } from "./base/FontFamily";
|
||||
import { FontSize } from "./base/FontSize";
|
||||
import { FormatPainter } from "./base/FormatPainter.ts";
|
||||
import { ClearFormat } from "./base/ClearFormat.ts";
|
||||
|
||||
import { FontFamily } from "./base/FontFamily.ts";
|
||||
import { FontSize } from "./base/FontSize.ts";
|
||||
|
||||
import { OrderedList } from "./base/OrderedList.ts";
|
||||
import { BulletList } from "./base/BulletList.ts";
|
||||
import { TaskList } from "./base/TaskList.ts";
|
||||
import { Indent } from "./base/Indent.ts";
|
||||
import { Outdent } from "./base/Outdent.ts";
|
||||
import { LineHeight } from "./base/LineHeight.ts";
|
||||
|
||||
/**
|
||||
* 传统菜单栏
|
||||
@@ -63,6 +71,13 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
||||
baseMenuFontColor!: FontColor;
|
||||
baseMenuHighlight!: Highlight;
|
||||
|
||||
baseMenuOrderedList!: OrderedList;
|
||||
baseMenuBulletList!: BulletList;
|
||||
baseMenuTaskList!: TaskList;
|
||||
baseMenuIndent!: Indent;
|
||||
baseMenuOutdent!: Outdent;
|
||||
baseMenuLineHeight!: LineHeight;
|
||||
|
||||
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
||||
super();
|
||||
this.defaultToolbarMenus = defaultToolbarMenus;
|
||||
@@ -184,6 +199,24 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
||||
|
||||
this.baseMenuHighlight = new Highlight({ menuType: "color", enable: true });
|
||||
this.eventComponents.push(this.baseMenuHighlight);
|
||||
|
||||
this.baseMenuOrderedList = new OrderedList({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuOrderedList);
|
||||
|
||||
this.baseMenuBulletList = new BulletList({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuBulletList);
|
||||
|
||||
this.baseMenuTaskList = new TaskList({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuTaskList);
|
||||
|
||||
this.baseMenuIndent = new Indent({ menuType: "button", enable: true });
|
||||
this.eventComponents.push(this.baseMenuIndent);
|
||||
|
||||
this.baseMenuOutdent = new Outdent({ menuType: "button", enable: true });
|
||||
this.eventComponents.push(this.baseMenuOutdent);
|
||||
|
||||
this.baseMenuLineHeight = new LineHeight({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuLineHeight);
|
||||
}
|
||||
/**
|
||||
* 创建基础菜单
|
||||
@@ -221,5 +254,15 @@ export class Classic extends HTMLElement implements UAIEditorEventListener {
|
||||
group2.appendChild(this.baseMenuSuperscript);
|
||||
group2.appendChild(this.baseMenuFontColor);
|
||||
group2.appendChild(this.baseMenuHighlight);
|
||||
|
||||
const group3 = document.createElement("div");
|
||||
group3.classList.add("uai-classic-virtual-group");
|
||||
this.classicMenuBaseGroup.appendChild(group3);
|
||||
group3.appendChild(this.baseMenuOrderedList);
|
||||
group3.appendChild(this.baseMenuBulletList);
|
||||
group3.appendChild(this.baseMenuTaskList);
|
||||
group3.appendChild(this.baseMenuIndent);
|
||||
group3.appendChild(this.baseMenuOutdent);
|
||||
group3.appendChild(this.baseMenuLineHeight);
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,21 @@ import { Superscript } from "../common/Superscript.ts";
|
||||
import { FontColor } from "../common/FontColor.ts";
|
||||
import { Highlight } from "../common/Highlight.ts";
|
||||
|
||||
import { Redo } from "./base/Redo";
|
||||
import { Undo } from "./base/Undo";
|
||||
import { Redo } from "./base/Redo.ts";
|
||||
import { Undo } from "./base/Undo.ts";
|
||||
|
||||
import { FormatPainter } from "./base/FormatPainter";
|
||||
import { ClearFormat } from "./base/ClearFormat";
|
||||
import { FormatPainter } from "./base/FormatPainter.ts";
|
||||
import { ClearFormat } from "./base/ClearFormat.ts";
|
||||
|
||||
import { FontFamily } from "./base/FontFamily";
|
||||
import { FontSize } from "./base/FontSize";
|
||||
import { FontFamily } from "./base/FontFamily.ts";
|
||||
import { FontSize } from "./base/FontSize.ts";
|
||||
|
||||
import { OrderedList } from "./base/OrderedList.ts";
|
||||
import { BulletList } from "./base/BulletList.ts";
|
||||
import { TaskList } from "./base/TaskList.ts";
|
||||
import { Indent } from "./base/Indent.ts";
|
||||
import { Outdent } from "./base/Outdent.ts";
|
||||
import { LineHeight } from "./base/LineHeight.ts";
|
||||
|
||||
/**
|
||||
* 经典菜单栏
|
||||
@@ -65,6 +72,13 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
||||
baseMenuFontColor!: FontColor;
|
||||
baseMenuHighlight!: Highlight;
|
||||
|
||||
baseMenuOrderedList!: OrderedList;
|
||||
baseMenuBulletList!: BulletList;
|
||||
baseMenuTaskList!: TaskList;
|
||||
baseMenuIndent!: Indent;
|
||||
baseMenuOutdent!: Outdent;
|
||||
baseMenuLineHeight!: LineHeight;
|
||||
|
||||
constructor(defaultToolbarMenus: Record<string, any>[]) {
|
||||
super();
|
||||
this.defaultToolbarMenus = defaultToolbarMenus;
|
||||
@@ -206,6 +220,24 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
||||
|
||||
this.baseMenuHighlight = new Highlight({ menuType: "color", enable: true });
|
||||
this.eventComponents.push(this.baseMenuHighlight);
|
||||
|
||||
this.baseMenuOrderedList = new OrderedList({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuOrderedList);
|
||||
|
||||
this.baseMenuBulletList = new BulletList({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuBulletList);
|
||||
|
||||
this.baseMenuTaskList = new TaskList({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuTaskList);
|
||||
|
||||
this.baseMenuIndent = new Indent({ menuType: "button", enable: true });
|
||||
this.eventComponents.push(this.baseMenuIndent);
|
||||
|
||||
this.baseMenuOutdent = new Outdent({ menuType: "button", enable: true });
|
||||
this.eventComponents.push(this.baseMenuOutdent);
|
||||
|
||||
this.baseMenuLineHeight = new LineHeight({ menuType: "popup", enable: true });
|
||||
this.eventComponents.push(this.baseMenuLineHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,5 +292,19 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener {
|
||||
group2row2.appendChild(this.baseMenuSuperscript);
|
||||
group2row2.appendChild(this.baseMenuFontColor);
|
||||
group2row2.appendChild(this.baseMenuHighlight);
|
||||
|
||||
const group3 = document.createElement("div");
|
||||
group3.classList.add("uai-ribbon-virtual-group");
|
||||
this.ribbonMenuBaseGroup.appendChild(group3);
|
||||
|
||||
const group3row1 = document.createElement("div");
|
||||
group3row1.classList.add("uai-ribbon-virtual-group-row");
|
||||
group3.appendChild(group3row1);
|
||||
group3row1.appendChild(this.baseMenuOrderedList);
|
||||
group3row1.appendChild(this.baseMenuBulletList);
|
||||
group3row1.appendChild(this.baseMenuTaskList);
|
||||
group3row1.appendChild(this.baseMenuIndent);
|
||||
group3row1.appendChild(this.baseMenuOutdent);
|
||||
group3row1.appendChild(this.baseMenuLineHeight);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
|
||||
import icon0 from "../../../../assets/icons/bullet-list.svg";
|
||||
import icon1 from "../../../../assets/icons/bullet-list-disc.svg";
|
||||
import icon2 from "../../../../assets/icons/bullet-list-circle.svg";
|
||||
import icon3 from "../../../../assets/icons/bullet-list-square.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 BulletList extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "popup",
|
||||
enable: true,
|
||||
icon: icon0,
|
||||
hideText: true,
|
||||
text: t('list.bullet.text'),
|
||||
tooltip: t('list.bullet.text'),
|
||||
shortcut: "Ctrl+Shift+8",
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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);
|
||||
|
||||
// 定义按钮点击事件,切换无序列表状态
|
||||
this.menuButton.menuButtonContent.addEventListener("click", () => {
|
||||
if (this.menuButtonOptions.enable) {
|
||||
const listType = 'disc';
|
||||
if (event.editor.isActive('bulletList')) {
|
||||
// 设置无序列表
|
||||
if (event.editor.getAttributes('bulletList').listType === listType) {
|
||||
event.editor.chain().focus().toggleBulletList().run();
|
||||
} else {
|
||||
event.editor.chain().focus().updateAttributes('bulletList', { listType }).run();
|
||||
}
|
||||
} else {
|
||||
// 切换无序列表
|
||||
event.editor.chain().focus().toggleBulletList().updateAttributes('bulletList', { listType }).run();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 下拉选择
|
||||
if (this.menuButtonOptions.enable && this.menuButton.menuButtonArrow) {
|
||||
this.tippyInstance = tippy(this.menuButton.menuButtonArrow, {
|
||||
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-ordered-list");
|
||||
|
||||
const group = document.createElement("div");
|
||||
group.classList.add("uai-ordered-list-group");
|
||||
|
||||
// 定义下拉选项
|
||||
const listOptions = [
|
||||
{ label: t('list.bullet.disc'), value: 'disc', icon: icon1 },
|
||||
{ label: t('list.bullet.circle'), value: 'circle', icon: icon2 },
|
||||
{ label: t('list.bullet.square'), value: 'square', icon: icon3 }
|
||||
]
|
||||
|
||||
// 添加下拉选项
|
||||
listOptions.forEach(option => {
|
||||
const item = document.createElement("div");
|
||||
item.classList.add("uai-ordered-list-item");
|
||||
item.innerHTML = `<img src="${option.icon}" />`
|
||||
|
||||
tippy(item, {
|
||||
appendTo: item,
|
||||
content: option.label,
|
||||
theme: 'uai-tips',
|
||||
placement: "top",
|
||||
arrow: true,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
// 下拉选项添加点击事件,设置对应的无序列表样式
|
||||
item.addEventListener("click", () => {
|
||||
const listType = option.value;
|
||||
if (event.editor.isActive('bulletList')) {
|
||||
if (event.editor.getAttributes('bulletList').listType === listType) {
|
||||
event.editor.chain().focus().toggleBulletList().run();
|
||||
} else {
|
||||
event.editor.chain().focus().updateAttributes('bulletList', { listType }).run();
|
||||
}
|
||||
} else {
|
||||
event.editor.chain().focus().toggleBulletList().updateAttributes('bulletList', { listType }).run();
|
||||
}
|
||||
this.tippyInstance.hide();
|
||||
})
|
||||
|
||||
group.appendChild(item);
|
||||
})
|
||||
|
||||
container.appendChild(group);
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
import icon from "../../../../assets/icons/indent.svg";
|
||||
import { t } from "i18next";
|
||||
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||
import { EditorEvents } from "@tiptap/core";
|
||||
|
||||
/**
|
||||
* 基础菜单:向右缩进
|
||||
*/
|
||||
export class Indent extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "button",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: true,
|
||||
text: t('base.indent'),
|
||||
tooltip: t('base.indent'),
|
||||
shortcut: "Tab",
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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().indent().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,120 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
|
||||
import icon from "../../../../assets/icons/line-height.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 LineHeight extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "popup",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: true,
|
||||
text: t('base.lineHeight.text'),
|
||||
tooltip: t('base.lineHeight.text'),
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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);
|
||||
|
||||
// 定义按钮点击事件,设置当前内容的行高为默认行高
|
||||
this.menuButton.menuButtonContent.addEventListener("click", () => {
|
||||
if (this.menuButtonOptions.enable) {
|
||||
const height = options.dicts?.lineHeights?.[0];
|
||||
if (height) {
|
||||
event.editor.chain().focus().setLineHeight(+height.value).run();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 添加可选的行高信息
|
||||
if (this.menuButtonOptions.enable && this.menuButton.menuButtonArrow) {
|
||||
this.tippyInstance = tippy(this.menuButton.menuButtonArrow, {
|
||||
content: this.createContainer(event, options),
|
||||
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-popup-action-list");
|
||||
|
||||
// 设置所有可选行高
|
||||
options.dicts?.lineHeights?.forEach(height => {
|
||||
const item = document.createElement("div");
|
||||
item.classList.add("uai-popup-action-item");
|
||||
item.innerHTML = `${height.label}`;
|
||||
// 添加点击事件,设置内容行高
|
||||
item.addEventListener('click', () => {
|
||||
event.editor.chain().focus().setLineHeight(+height.value).run();
|
||||
this.tippyInstance.hide();
|
||||
});
|
||||
container.appendChild(item);
|
||||
})
|
||||
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
|
||||
import icon0 from "../../../../assets/icons/ordered-list.svg";
|
||||
import icon1 from "../../../../assets/icons/ordered-list-decimal.svg";
|
||||
import icon2 from "../../../../assets/icons/ordered-list-decimal-leading-zero.svg";
|
||||
import icon3 from "../../../../assets/icons/ordered-list-lower-roman.svg";
|
||||
import icon4 from "../../../../assets/icons/ordered-list-upper-roman.svg";
|
||||
import icon5 from "../../../../assets/icons/ordered-list-lower-latin.svg";
|
||||
import icon6 from "../../../../assets/icons/ordered-list-upper-latin.svg";
|
||||
import icon7 from "../../../../assets/icons/ordered-list-trad-chinese-informal.svg";
|
||||
import icon8 from "../../../../assets/icons/ordered-list-simp-chinese-formal.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 OrderedList extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "popup",
|
||||
enable: true,
|
||||
icon: icon0,
|
||||
hideText: true,
|
||||
text: t('list.ordered.text'),
|
||||
tooltip: t('list.ordered.text'),
|
||||
shortcut: "Ctrl+Shift+7",
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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);
|
||||
|
||||
// 定义按钮点击事件,切换有序列表状态
|
||||
this.menuButton.menuButtonContent.addEventListener("click", () => {
|
||||
if (this.menuButtonOptions.enable) {
|
||||
const listType = 'decimal';
|
||||
if (event.editor.isActive('orderedList')) {
|
||||
// 设置有序列表
|
||||
if (event.editor.getAttributes('orderedList').type === listType) {
|
||||
event.editor.chain().focus().toggleOrderedList().run();
|
||||
} else {
|
||||
event.editor.chain().focus().updateAttributes('orderedList', { "type": listType }).run();
|
||||
}
|
||||
} else {
|
||||
// 切换有序列表
|
||||
event.editor.chain().focus().toggleOrderedList().updateAttributes('orderedList', { "type": listType }).run();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 下拉选择
|
||||
if (this.menuButtonOptions.enable && this.menuButton.menuButtonArrow) {
|
||||
this.tippyInstance = tippy(this.menuButton.menuButtonArrow, {
|
||||
content: this.createContainer(event, options),
|
||||
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-ordered-list");
|
||||
|
||||
const group = document.createElement("div");
|
||||
group.classList.add("uai-ordered-list-group");
|
||||
|
||||
// 定义下拉选项
|
||||
const listOptions = [
|
||||
{ label: t('list.ordered.decimal'), value: 'decimal', icon: icon1 },
|
||||
{ label: t('list.ordered.decimalLeadingZero'), value: 'decimal-leading-zero', icon: icon2 },
|
||||
{ label: t('list.ordered.lowerRoman'), value: 'lower-roman', icon: icon3 },
|
||||
{ label: t('list.ordered.upperRoman'), value: 'upper-roman', icon: icon4 },
|
||||
{ label: t('list.ordered.lowerLatin'), value: 'lower-latin', icon: icon5 },
|
||||
{ label: t('list.ordered.upperLatin'), value: 'upper-latin', icon: icon6 },
|
||||
{ label: t('list.ordered.tradChineseInformal'), value: 'trad-chinese-informal', icon: icon7 },
|
||||
{ label: t('list.ordered.simpChineseFormal'), value: 'simp-chinese-formal', icon: icon8 },
|
||||
]
|
||||
|
||||
// 添加下拉选项
|
||||
listOptions.forEach(option => {
|
||||
const item = document.createElement("div");
|
||||
item.classList.add("uai-ordered-list-item");
|
||||
item.innerHTML = `<img src="${option.icon}" />`
|
||||
|
||||
tippy(item, {
|
||||
appendTo: item,
|
||||
content: option.label,
|
||||
theme: 'uai-tips',
|
||||
placement: "top",
|
||||
arrow: true,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
// 下拉选项添加点击事件,设置对应的有序列表样式
|
||||
item.addEventListener("click", () => {
|
||||
const listType = option.value;
|
||||
if (event.editor.isActive('orderedList')) {
|
||||
if (event.editor.getAttributes('orderedList').type === listType) {
|
||||
event.editor.chain().focus().toggleOrderedList().run();
|
||||
} else {
|
||||
event.editor.chain().focus().updateAttributes('orderedList', { "type": listType }).run();
|
||||
}
|
||||
} else {
|
||||
event.editor.chain().focus().toggleOrderedList().updateAttributes('orderedList', { "type": listType }).run();
|
||||
}
|
||||
this.tippyInstance.hide();
|
||||
})
|
||||
|
||||
group.appendChild(item);
|
||||
})
|
||||
|
||||
container.appendChild(group);
|
||||
return container
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
import icon from "../../../../assets/icons/outdent.svg";
|
||||
import { t } from "i18next";
|
||||
import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts";
|
||||
import { EditorEvents } from "@tiptap/core";
|
||||
|
||||
/**
|
||||
* 基础菜单:向左缩进
|
||||
*/
|
||||
export class Outdent extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "button",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: true,
|
||||
text: t('base.outdent'),
|
||||
tooltip: t('base.outdent'),
|
||||
shortcut: "Shift+Tab",
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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().outdent().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,97 @@
|
||||
// Copyright (c) 2024-present AI-Labs
|
||||
|
||||
// @ ts-nocheck
|
||||
import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts";
|
||||
|
||||
import icon from "../../../../assets/icons/task-list.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 TaskList extends HTMLElement implements UAIEditorEventListener {
|
||||
// 按钮选项
|
||||
menuButtonOptions: MenuButtonOptions = {
|
||||
menuType: "popup",
|
||||
enable: true,
|
||||
icon: icon,
|
||||
hideText: true,
|
||||
text: t('list.task.text'),
|
||||
tooltip: t('list.task.text'),
|
||||
shortcut: "Ctrl+Shift+9",
|
||||
}
|
||||
|
||||
// 功能按钮
|
||||
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);
|
||||
|
||||
this.menuButton.menuButtonContent.addEventListener("click", () => {
|
||||
if (this.menuButtonOptions.enable) {
|
||||
event.editor.chain().focus().toggleTaskList().run();
|
||||
}
|
||||
})
|
||||
|
||||
if (this.menuButtonOptions.enable && this.menuButton.menuButtonArrow) {
|
||||
this.tippyInstance = tippy(this.menuButton.menuButtonArrow, {
|
||||
content: this.createContainer(event, options),
|
||||
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);
|
||||
}
|
||||
|
||||
createContainer(event: EditorEvents["create"], options: UAIEditorOptions) {
|
||||
const container = document.createElement("div");
|
||||
container.classList.add("uai-ordered-list");
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user