Merge pull request #4082 from moham96/develop

Allow the mention extension to have custom renderHTML
This commit is contained in:
Jan Thurau 2023-11-22 21:31:42 +01:00 committed by GitHub
commit 3e9f9a6d24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 15 deletions

View File

@ -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)

View File

@ -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<string, any>
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<SuggestionOptions, 'editor'>
}
@ -17,9 +20,16 @@ export const Mention = Node.create<MentionOptions>({
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<MentionOptions>({
},
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,
})