diff --git a/docs/api/nodes/mention.md b/docs/api/nodes/mention.md index 8f9fb062f..b9911dbd7 100644 --- a/docs/api/nodes/mention.md +++ b/docs/api/nodes/mention.md @@ -42,17 +42,31 @@ Mention.configure({ }) ``` -### renderLabel -Define how a mention label should be rendered. +### renderText +Define how a mention text should be rendered. ```js Mention.configure({ - renderLabel({ options, node }) { + renderText({ options, node }) { return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}` } }) ``` +### renderHTML +Define how a mention html element should be rendered, this is useful if you want to render an element other than `span` (e.g `a`) + +```js +Mention.configure({ + renderHTML({ options, node }) { + return [ + "a", + { href: '/profile/1' }, + `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`, + ]; + } +}) +``` ### suggestion [Read more](/api/utilities/suggestion) diff --git a/packages/extension-mention/src/mention.ts b/packages/extension-mention/src/mention.ts index 97aea2957..2938cfb02 100644 --- a/packages/extension-mention/src/mention.ts +++ b/packages/extension-mention/src/mention.ts @@ -1,11 +1,14 @@ import { mergeAttributes, Node } from '@tiptap/core' -import { Node as ProseMirrorNode } from '@tiptap/pm/model' +import { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model' import { PluginKey } from '@tiptap/pm/state' import Suggestion, { SuggestionOptions } from '@tiptap/suggestion' export type MentionOptions = { HTMLAttributes: Record - renderLabel: (props: { options: MentionOptions; node: ProseMirrorNode }) => string + /** @deprecated use renderText and renderHTML instead */ + renderLabel?: (props: { options: MentionOptions; node: ProseMirrorNode }) => string + renderText: (props: { options: MentionOptions; node: ProseMirrorNode }) => string + renderHTML: (props: { options: MentionOptions; node: ProseMirrorNode }) => DOMOutputSpec suggestion: Omit } @@ -17,9 +20,16 @@ export const Mention = Node.create({ addOptions() { return { HTMLAttributes: {}, - renderLabel({ options, node }) { + renderText({ options, node }) { return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}` }, + renderHTML({ options, node }) { + return [ + 'span', + this.HTMLAttributes, + `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`, + ] + }, suggestion: { char: '@', pluginKey: MentionPluginKey, @@ -110,18 +120,41 @@ export const Mention = Node.create({ }, renderHTML({ node, HTMLAttributes }) { - return [ - 'span', - mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), - this.options.renderLabel({ - options: this.options, - node, - }), - ] + if (this.options.renderLabel !== undefined) { + console.warn('renderLabel is deprecated use renderText and renderHTML instead') + return [ + 'span', + mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), + this.options.renderLabel({ + options: this.options, + node, + }), + ] + } + const html = this.options.renderHTML({ + options: this.options, + node, + }) + + if (typeof html === 'string') { + return [ + 'span', + mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), + html, + ] + } + return html }, renderText({ node }) { - return this.options.renderLabel({ + if (this.options.renderLabel !== undefined) { + console.warn('renderLabel is deprecated use renderText and renderHTML instead') + return this.options.renderLabel({ + options: this.options, + node, + }) + } + return this.options.renderText({ options: this.options, node, })