Skip to content

Commit

Permalink
Merge pull request #4082 from moham96/develop
Browse files Browse the repository at this point in the history
Allow the mention extension to have custom renderHTML
  • Loading branch information
janthurau authored Nov 22, 2023
2 parents 2bea9d1 + 6ff8323 commit 3e9f9a6
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
20 changes: 17 additions & 3 deletions docs/api/nodes/mention.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
57 changes: 45 additions & 12 deletions packages/extension-mention/src/mention.ts
Original file line number Diff line number Diff line change
@@ -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'>
}

Expand All @@ -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,
Expand Down Expand Up @@ -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,
})
Expand Down

0 comments on commit 3e9f9a6

Please sign in to comment.