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 ### renderText
Define how a mention label should be rendered. Define how a mention text should be rendered.
```js ```js
Mention.configure({ Mention.configure({
renderLabel({ options, node }) { renderText({ options, node }) {
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}` 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 ### suggestion
[Read more](/api/utilities/suggestion) [Read more](/api/utilities/suggestion)

View File

@ -1,11 +1,14 @@
import { mergeAttributes, Node } from '@tiptap/core' 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 { PluginKey } from '@tiptap/pm/state'
import Suggestion, { SuggestionOptions } from '@tiptap/suggestion' import Suggestion, { SuggestionOptions } from '@tiptap/suggestion'
export type MentionOptions = { export type MentionOptions = {
HTMLAttributes: Record<string, any> 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'> suggestion: Omit<SuggestionOptions, 'editor'>
} }
@ -17,9 +20,16 @@ export const Mention = Node.create<MentionOptions>({
addOptions() { addOptions() {
return { return {
HTMLAttributes: {}, HTMLAttributes: {},
renderLabel({ options, node }) { renderText({ options, node }) {
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}` 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: { suggestion: {
char: '@', char: '@',
pluginKey: MentionPluginKey, pluginKey: MentionPluginKey,
@ -110,6 +120,8 @@ export const Mention = Node.create<MentionOptions>({
}, },
renderHTML({ node, HTMLAttributes }) { renderHTML({ node, HTMLAttributes }) {
if (this.options.renderLabel !== undefined) {
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
return [ return [
'span', 'span',
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
@ -118,13 +130,34 @@ export const Mention = Node.create<MentionOptions>({
node, 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 }) { renderText({ node }) {
if (this.options.renderLabel !== undefined) {
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
return this.options.renderLabel({ return this.options.renderLabel({
options: this.options, options: this.options,
node, node,
}) })
}
return this.options.renderText({
options: this.options,
node,
})
}, },
addKeyboardShortcuts() { addKeyboardShortcuts() {