umbraco-tiptap-toolbar-extension
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseUmbraco Tiptap Toolbar Extension
Umbraco Tiptap 工具栏扩展
What is it?
什么是Tiptap工具栏扩展?
A Tiptap Toolbar Extension adds buttons or controls to the Rich Text Editor's toolbar. It provides an method that runs when clicked, and can indicate active/disabled states. Several "kinds" are available: (simple toggle), (color selection), (dropdown menu), and (style selection dropdown).
executebuttoncolorPickerButtonmenustyleMenuTiptap工具栏扩展可为富文本编辑器的工具栏添加按钮或控件。它提供了一个方法,点击时会运行,并且可以指示激活/禁用状态。有多种类型可供选择:(简单切换按钮)、(颜色选择器按钮)、(下拉菜单)和(样式选择下拉菜单)。
executebuttoncolorPickerButtonmenustyleMenuDocumentation
文档参考
Always fetch the latest docs before implementing:
- Extension Types: https://docs.umbraco.com/umbraco-cms/customizing/extending-overview/extension-types
- Rich Text Editor: https://docs.umbraco.com/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor
- Tiptap Docs: https://tiptap.dev/docs/editor/extensions/overview
- Foundation: https://docs.umbraco.com/umbraco-cms/customizing/foundation
在开始实现前,请务必获取最新的官方文档:
- 扩展类型:https://docs.umbraco.com/umbraco-cms/customizing/extending-overview/extension-types
- 富文本编辑器:https://docs.umbraco.com/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor
- Tiptap 文档:https://tiptap.dev/docs/editor/extensions/overview
- 基础框架:https://docs.umbraco.com/umbraco-cms/customizing/foundation
Related Skills
相关技能
-
Tiptap Extension: For adding editor functionality
- Reference skill:
umbraco-tiptap-extension
- Reference skill:
-
Modals: When toolbar buttons open modal dialogs
- Reference skill:
umbraco-modals
- Reference skill:
-
Tiptap 扩展:用于添加编辑器功能
- 参考技能:
umbraco-tiptap-extension
- 参考技能:
-
模态框:当工具栏按钮需要打开模态对话框时使用
- 参考技能:
umbraco-modals
- 参考技能:
Workflow
实现流程
- Fetch docs - Use WebFetch on the URLs above
- Ask questions - Button, menu, or color picker? What action to execute?
- Generate files - Create manifest + API class based on latest docs
- Explain - Show what was created and how to test
- 获取文档 - 通过WebFetch获取上述链接的最新文档
- 确认需求 - 确定是按钮、菜单还是颜色选择器?需要执行什么操作?
- 生成文件 - 根据最新文档创建清单文件(manifest)和API类
- 说明解释 - 展示创建的内容以及测试方法
Minimal Examples
最简示例
Button Kind Manifest (manifests.ts)
按钮类型清单文件(manifests.ts)
typescript
import type { ManifestTiptapToolbarExtensionButtonKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionButtonKind = {
type: 'tiptapToolbarExtension',
kind: 'button',
alias: 'My.TiptapToolbar.Bold',
name: 'Bold Toolbar Button',
api: () => import('./bold.tiptap-toolbar-api.js'),
forExtensions: ['Umb.Tiptap.Bold'], // Links to the tiptap extension
meta: {
alias: 'bold',
icon: 'icon-bold',
label: 'Bold',
},
};
export const manifests = [manifest];typescript
import type { ManifestTiptapToolbarExtensionButtonKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionButtonKind = {
type: 'tiptapToolbarExtension',
kind: 'button',
alias: 'My.TiptapToolbar.Bold',
name: 'Bold Toolbar Button',
api: () => import('./bold.tiptap-toolbar-api.js'),
forExtensions: ['Umb.Tiptap.Bold'], // Links to the tiptap extension
meta: {
alias: 'bold',
icon: 'icon-bold',
label: 'Bold',
},
};
export const manifests = [manifest];Button API (bold.tiptap-toolbar-api.ts)
按钮API文件(bold.tiptap-toolbar-api.ts)
typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@tiptap/core';
export default class BoldToolbarApi extends UmbTiptapToolbarElementApiBase {
execute(editor?: Editor) {
editor?.chain().focus().toggleBold().run();
}
}typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@tiptap/core';
export default class BoldToolbarApi extends UmbTiptapToolbarElementApiBase {
execute(editor?: Editor) {
editor?.chain().focus().toggleBold().run();
}
}Button with Custom Active/Disabled State
自定义激活/禁用状态的按钮
typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@tiptap/core';
export default class CustomToolbarApi extends UmbTiptapToolbarElementApiBase {
execute(editor?: Editor) {
editor?.chain().focus().toggleHighlight().run();
}
// Override to customize active state detection
isActive(editor?: Editor): boolean {
return editor?.isActive('highlight') ?? false;
}
// Override to customize disabled state
isDisabled(editor?: Editor): boolean {
return !editor?.can().toggleHighlight() ?? true;
}
}typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@tiptap/core';
export default class CustomToolbarApi extends UmbTiptapToolbarElementApiBase {
execute(editor?: Editor) {
editor?.chain().focus().toggleHighlight().run();
}
// 重写方法自定义激活状态检测
isActive(editor?: Editor): boolean {
return editor?.isActive('highlight') ?? false;
}
// 重写方法自定义禁用状态
isDisabled(editor?: Editor): boolean {
return !editor?.can().toggleHighlight() ?? true;
}
}Menu Kind Manifest
菜单类型清单文件
typescript
import type { ManifestTiptapToolbarExtensionMenuKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionMenuKind = {
type: 'tiptapToolbarExtension',
kind: 'menu',
alias: 'My.TiptapToolbar.Headings',
name: 'Headings Menu',
api: () => import('./headings.tiptap-toolbar-api.js'),
forExtensions: ['Umb.Tiptap.Heading'],
meta: {
alias: 'headings',
icon: 'icon-heading',
label: 'Headings',
look: 'text', // 'icon' or 'text'
},
items: [
{ label: 'Heading 1', data: { level: 1 } },
{ label: 'Heading 2', data: { level: 2 } },
{ label: 'Heading 3', data: { level: 3 } },
{ label: 'Paragraph', data: { level: 0 } },
],
};typescript
import type { ManifestTiptapToolbarExtensionMenuKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionMenuKind = {
type: 'tiptapToolbarExtension',
kind: 'menu',
alias: 'My.TiptapToolbar.Headings',
name: 'Headings Menu',
api: () => import('./headings.tiptap-toolbar-api.js'),
forExtensions: ['Umb.Tiptap.Heading'],
meta: {
alias: 'headings',
icon: 'icon-heading',
label: 'Headings',
look: 'text', // 'icon' or 'text'
},
items: [
{ label: 'Heading 1', data: { level: 1 } },
{ label: 'Heading 2', data: { level: 2 } },
{ label: 'Heading 3', data: { level: 3 } },
{ label: 'Paragraph', data: { level: 0 } },
],
};Menu API
菜单API文件
typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@tiptap/core';
export default class HeadingsToolbarApi extends UmbTiptapToolbarElementApiBase {
execute(editor?: Editor, level?: number) {
if (level === 0) {
editor?.chain().focus().setParagraph().run();
} else {
editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run();
}
}
isActive(editor?: Editor, level?: number): boolean {
if (level === 0) {
return editor?.isActive('paragraph') ?? false;
}
return editor?.isActive('heading', { level }) ?? false;
}
}typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import type { Editor } from '@tiptap/core';
export default class HeadingsToolbarApi extends UmbTiptapToolbarElementApiBase {
execute(editor?: Editor, level?: number) {
if (level === 0) {
editor?.chain().focus().setParagraph().run();
} else {
editor?.chain().focus().toggleHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 }).run();
}
}
isActive(editor?: Editor, level?: number): boolean {
if (level === 0) {
return editor?.isActive('paragraph') ?? false;
}
return editor?.isActive('heading', { level }) ?? false;
}
}Style Menu Kind
样式菜单类型
typescript
import type { ManifestTiptapToolbarExtensionStyleMenuKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionStyleMenuKind = {
type: 'tiptapToolbarExtension',
kind: 'styleMenu',
alias: 'My.TiptapToolbar.Styles',
name: 'Style Menu',
api: () => import('./styles.tiptap-toolbar-api.js'),
meta: {
alias: 'styles',
icon: 'icon-palette',
label: 'Styles',
},
items: [
{
label: 'Lead Paragraph',
data: { class: 'lead' },
appearance: { style: 'font-size: 1.2em' },
},
{
label: 'Small Text',
data: { class: 'small' },
appearance: { style: 'font-size: 0.85em' },
},
{
label: 'Highlight Box',
data: { class: 'highlight-box' },
},
],
};typescript
import type { ManifestTiptapToolbarExtensionStyleMenuKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionStyleMenuKind = {
type: 'tiptapToolbarExtension',
kind: 'styleMenu',
alias: 'My.TiptapToolbar.Styles',
name: 'Style Menu',
api: () => import('./styles.tiptap-toolbar-api.js'),
meta: {
alias: 'styles',
icon: 'icon-palette',
label: 'Styles',
},
items: [
{
label: 'Lead Paragraph',
data: { class: 'lead' },
appearance: { style: 'font-size: 1.2em' },
},
{
label: 'Small Text',
data: { class: 'small' },
appearance: { style: 'font-size: 0.85em' },
},
{
label: 'Highlight Box',
data: { class: 'highlight-box' },
},
],
};Color Picker Button Kind
颜色选择器按钮类型
typescript
import type { ManifestTiptapToolbarExtensionColorPickerButtonKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionColorPickerButtonKind = {
type: 'tiptapToolbarExtension',
kind: 'colorPickerButton',
alias: 'My.TiptapToolbar.TextColor',
name: 'Text Color',
api: () => import('./text-color.tiptap-toolbar-api.js'),
meta: {
alias: 'textColor',
icon: 'icon-palette',
label: 'Text Color',
},
};typescript
import type { ManifestTiptapToolbarExtensionColorPickerButtonKind } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapToolbarExtensionColorPickerButtonKind = {
type: 'tiptapToolbarExtension',
kind: 'colorPickerButton',
alias: 'My.TiptapToolbar.TextColor',
name: 'Text Color',
api: () => import('./text-color.tiptap-toolbar-api.js'),
meta: {
alias: 'textColor',
icon: 'icon-palette',
label: 'Text Color',
},
};Toolbar Button Opening Modal
打开模态框的工具栏按钮
typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import type { Editor } from '@tiptap/core';
export default class LinkToolbarApi extends UmbTiptapToolbarElementApiBase {
async execute(editor?: Editor) {
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
const modal = modalManager.open(this, MY_LINK_MODAL, {
data: {
currentHref: editor?.getAttributes('link').href,
},
});
const result = await modal.onSubmit();
if (result?.href) {
editor?.chain().focus().setLink({ href: result.href }).run();
}
}
}typescript
import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import type { Editor } from '@tiptap/core';
export default class LinkToolbarApi extends UmbTiptapToolbarElementApiBase {
async execute(editor?: Editor) {
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
const modal = modalManager.open(this, MY_LINK_MODAL, {
data: {
currentHref: editor?.getAttributes('link').href,
},
});
const result = await modal.onSubmit();
if (result?.href) {
editor?.chain().focus().setLink({ href: result.href }).run();
}
}
}Toolbar Extension Kinds
工具栏扩展类型
| Kind | Use Case |
|---|---|
| Simple toggle button |
| Color selection |
| Dropdown with options |
| Style/class selection |
| 类型 | 使用场景 |
|---|---|
| 简单切换按钮 |
| 颜色选择 |
| 带选项的下拉菜单 |
| 样式/类选择 |
Meta Properties
元属性
| Property | Description |
|---|---|
| Used for isActive detection |
| Toolbar button icon |
| Tooltip text |
| (menu only) 'icon' or 'text' |
That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.
| 属性 | 说明 |
|---|---|
| 用于激活状态检测 |
| 工具栏按钮图标 |
| 提示文本(Tooltip) |
| (仅菜单类型)可选'icon'或'text' |
就是这样!请始终获取最新文档,示例保持最简,生成可直接运行的完整代码。