扩展
从 @tiptap-pro/extension-slot 导入 Slot、BlockSlot 和 InlineSlot。
Slot
安装两个 Slot 节点、命令、索引和编辑行为。扩展和存储名称为 slot。
Slot.configure({ validators: { registeredPerson } })选项(SlotOptions)
blockSlot(Node):块节点扩展。默认值为BlockSlot。inlineSlot(Node):行内节点扩展。默认值为InlineSlot。generateId(() => string):创建文档唯一 ID。默认使用 UUID 生成器。validators(Record<string, SlotValidator>):命名字段验证器。默认值为{};注册前引用的验证器不可用。crossFieldValidators(Record<string, CrossFieldValidator>):命名跨字段验证器。默认值为{};注册前引用的验证器不可用。getValidationContext(() => unknown):每次验证请求捕获一次应用数据。默认返回undefined。shortcuts(false | SlotShortcuts):类型化创建和可选的分隔符转换。默认使用{{{立即创建行内 Slot,使用[[[创建块 Slot。设置为false可禁用所有 Slot 输入规则。resolveInputRuleSlot(SlotInputRuleResolver):插入前解析匹配的快捷方式。默认返回undefined,保留捕获内容和快捷方式配置。参见解析输入规则。onSlotsUpdate((event: SlotsUpdateEvent) => void):slotsUpdate监听器。默认为空操作。onActiveSlotChange((event: ActiveSlotChangeEvent) => void):activeSlotChange监听器。默认为空操作。onValidationUpdate((event: SlotValidationUpdateEvent) => void):slotValidationUpdate监听器。默认为空操作。onValidationError((event: SlotValidationErrorEvent) => void):slotValidationError监听器。默认为空操作。onCommandRejected((event: SlotCommandRejectedEvent) => void):slotCommandRejected监听器。默认为空操作。
这里的 Node 是来自 @tiptap/core 的扩展类型。请参阅验证器和事件负载。
配置规则
- 只注册一次
Slot。通过其选项传入定制节点;不要再单独注册这些节点。 - 两个节点选项都是必需的,并在编辑器创建时固定。它们不接受
false。 - 自定义节点必须保留其名称、属性和 schema 行为。
- 无效节点实例、重复注册和无效快捷方式会导致初始化失败。
- ID 生成会最多重试冲突五次。失败时会以
idGenerationFailed拒绝命令。
BlockSlot 和 InlineSlot
普通 Tiptap 节点扩展,支持 .configure() 和 .extend()。
选项
HTMLAttributes(Record<string, string>):外层元素的属性。默认值为{}。必需的data-slot-*属性优先。
节点属性
id(string | null):文档范围内区分大小写的标识符。默认值为null;命令会生成缺失的 ID。导入时缺失或重复的 ID 会产生验证问题。config(SlotConfig):嵌入式配置。默认值为{}。格式错误的导入 JSON 会保留以便诊断。
| 属性 | BlockSlot | InlineSlot |
|---|---|---|
| 节点名称 | blockSlot | inlineSlot |
| 分组 | block | inline |
inline | false | true |
| 内容表达式 | block+ | inline* |
defining | true | true |
isolating | true | true |
| 空内容 | 一个空段落 | 无子节点 |
块 Slot 要求 schema 中包含 paragraph。有关 NodeView 和 HTML 定制,请参阅渲染。
在行内 Slot 中,Backspace 和 Delete 会删除完整的字素(包括 emoji 和组合字符),同时保留 Slot 包装器。
SlotShortcuts
属性
inline?(SlotShortcut | false):行内规则。默认值为{ create: '{{{' }。设置为false可禁用此类型。block?(SlotShortcut | false):块规则。默认值为{ create: '[[[' }。设置为false可禁用此类型。
输入第三个 { 会立即在光标处创建空的行内 Slot,并将光标放入其中。在其他内容为空的文本块中输入第三个 [ 会将其替换为包含空段落的块 Slot,并将光标放入该段落。两条规则都不需要结束分隔符或 Enter。创建块不会消耗周围文本。
SlotShortcut
create?(string | false):立即创建触发符。行内默认为{{{,块默认为[[[。设置为false可禁用创建,同时保留成对规则。open?(string):可选的非空成对开始分隔符。需要close。close?(string):可选的非空成对结束分隔符,且必须不同于open。需要open。config?(SlotConfig):新 Slot 的配置。默认值为{}。
配置会与默认值合并。例如,添加行内 open: '{{', close: '}}' 对会保留两个立即创建规则。此时 {{name}} 会将现有文字转换为 Slot;{{{ 会立即打开空的行内字段。被拒绝的三字符触发符不会随后被较短的成对开始分隔符消耗。
成对开始分隔符不能通过前缀相互重叠。立即触发符也不能通过前缀相互重叠,成对开始分隔符不能等于或以已启用的创建触发符开头。配置此类成对分隔符前,请禁用冲突的 create 触发符。
对于成对转换,捕获的文本会成为 Slot 内容,同时保留文本标记。块分隔符对必须占据整个文本块。转换被拒绝时会保留字面输入;粘贴不会触发这些规则。跨越行内原子(例如 mention 或 Variable)的分隔符对会被 Tiptap 输入规则运行器跳过;这些匹配不会调用解析器。
// Retain paired conversion, but disable immediate creation for both kinds.
Slot.configure({
shortcuts: {
inline: { create: false, open: '{{', close: '}}' },
block: { create: false, open: '[[', close: ']]' },
},
})resolveInputRuleSlot
使用此同步回调,根据捕获的输入和当前应用上下文选择 Slot 的 ID、配置和初始内容。它会在插入前运行,而不是作为 Slot 已创建的通知。它只由已配置的输入规则使用;普通的 insertSlot 和 wrapInSlot 调用不会调用它。
Slot.configure({
shortcuts: { inline: { open: '{{', close: '}}' } },
resolveInputRuleSlot({ kind, text, defaults }) {
if (kind !== 'inline' || text.trim() !== 'customer-name') {
return undefined
}
return {
config: {
...defaults.config,
label: 'Customer name',
placeholder: 'Enter the customer’s name',
required: true,
},
content: [],
}
},
})输入 {{customer-name}} 会创建带生成 ID 的空必填字段。其他匹配文本使用普通转换。回调也可以通过闭包读取应用数据,例如选择预设,或拒绝为当前操作者创建字段。
参数(SlotInputRuleContext)
editor(Editor):检查当前文档、Schema 和扩展存储。不要从回调中分发命令。kind('inline' | 'block'):快捷方式选择的类型。回调不能更改它。content(JSONContent[]):不带分隔符的捕获行内内容,同时保留文本标记。保留格式时应使用此结构化值。不支持跨原子的匹配。text(string):不带分隔符且不自动修剪的完整捕获文本。适合匹配customer-name等名称。delimiters({ open: string; close: string }):匹配的分隔符对。立即创建时,open是触发符,close为''。range({ from: number; to: number }):当前文档中被替换的范围。块转换会替换整个文本块。待处理输入可能尚未存在于该文档中;content和text包含完整捕获内容。defaults({ config: SlotConfig; content: JSONContent[] }):快捷方式配置(或{})以及准备插入的内容。对于块 Slot,捕获的行内内容会包裹在段落中。
JSON 输入是不可变快照。请返回新对象,不要修改它们。回调必须同步,并且不能写入编辑器。
立即创建也会调用此解析器,传入 text: '' 和 content: []。行内 Slot 的默认内容为空,块 Slot 的默认内容为空段落。插入后,光标会移到 Slot 内容的开头;如果内容是单独的可选原子,则改为选中该原子。返回 false 会保留字面触发符。
返回值(SlotInputRuleResult | false | undefined)
undefined:使用默认值。false:保留完整字面输入,包括分隔符。这是有意拒绝,不会触发拒绝事件。- 包含以下任意覆盖项的对象:
id?(string):显式唯一且非空的 ID。省略时使用generateId。config?(SlotConfig):整体替换默认配置。显式展开defaults.config以进行合并。content?(JSONContent[]):替换初始内容,可以包含 Slot schema 中有效的任意节点和标记。省略时保留defaults.content,即使返回的配置包含defaultContent。[]会创建空的行内 Slot,或创建包含空段落的块 Slot。
结果不能更改类型或插入位置。Slot 插入仍会经过 insertSlot,包括 ID、Schema 和内容保护检查。与普通插入一样,验证约束不会阻止插入。
回调抛出的错误、Promise 和格式错误的结果会拒绝转换,并触发 slotCommandRejected,其中 command: 'insertSlot'、code: 'invalidInput'。插入被拒绝时使用已有代码,例如 schemaMismatch 或 protected。不会插入部分 Slot。输入规则撤销仍然可用。
存储(SlotStorage)
editor.storage.slot 中的只读 getter。
snapshot(SlotSnapshot):当前文档和 Slot 索引。activeSlot(SlotEntry | null):选区头部最内层的 Slot,或选中的 Slot 节点。在 Slot 外部时为null。validation(SlotValidationState):当前验证生命周期和结果。
SlotValidationState
status('unvalidated' | 'pending' | 'current'):初始为'unvalidated'。验证需要显式请求。snapshotId(string | null):正在验证或持有当前结果的快照;其他情况为null。result(SlotValidationResult | null):当前结果;未验证或待处理时为null。
文档编辑(包括插件追加的编辑)会刷新快照并清除缓存验证结果。选区变化不会。请参阅读取类型。