@tiptap/extension-mention 2.22.3 → 2.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/mention.ts"],"sourcesContent":["import { mergeAttributes, Node } from '@tiptap/core'\nimport { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { PluginKey } from '@tiptap/pm/state'\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion'\n\n// See `addAttributes` below\nexport interface MentionNodeAttrs {\n /**\n * The identifier for the selected item that was mentioned, stored as a `data-id`\n * attribute.\n */\n id: string | null;\n /**\n * The label to be rendered by the editor as the displayed text for this mentioned\n * item, if provided. Stored as a `data-label` attribute. See `renderLabel`.\n */\n label?: string | null;\n}\n\nexport type MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> = {\n /**\n * The HTML attributes for a mention node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * A function to render the label of a mention.\n * @deprecated use renderText and renderHTML instead\n * @param props The render props\n * @returns The label\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderLabel?: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => string\n\n /**\n * A function to render the text of a mention.\n * @param props The render props\n * @returns The text\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderText: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => string\n\n /**\n * A function to render the HTML of a mention.\n * @param props The render props\n * @returns The HTML as a ProseMirror DOM Output Spec\n * @example ({ options, node }) => ['span', { 'data-type': 'mention' }, `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`]\n */\n renderHTML: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => DOMOutputSpec\n\n /**\n * Whether to delete the trigger character with backspace.\n * @default false\n */\n deleteTriggerWithBackspace: boolean\n\n /**\n * The suggestion options.\n * @default {}\n * @example { char: '@', pluginKey: MentionPluginKey, command: ({ editor, range, props }) => { ... } }\n */\n suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>\n}\n\n/**\n * The plugin key for the mention plugin.\n * @default 'mention'\n */\nexport const MentionPluginKey = new PluginKey('mention')\n\n/**\n * This extension allows you to insert mentions into the editor.\n * @see https://www.tiptap.dev/api/extensions/mention\n */\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n priority: 101,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderText({ options, node }) {\n return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n },\n deleteTriggerWithBackspace: false,\n renderHTML({ options, node }) {\n return [\n 'span',\n mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),\n `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`,\n ]\n },\n suggestion: {\n char: '@',\n pluginKey: MentionPluginKey,\n command: ({ editor, range, props }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: this.name,\n attrs: props,\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n // get reference to `window` object from editor element, to support cross-frame JS usage\n editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[this.name]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n },\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n }),\n ]\n }\n const mergedOptions = { ...this.options }\n\n mergedOptions.HTMLAttributes = mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes)\n const html = this.options.renderHTML({\n options: mergedOptions,\n node,\n })\n\n if (typeof html === 'string') {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n html,\n ]\n }\n return html\n },\n\n renderText({ node }) {\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return this.options.renderLabel({\n options: this.options,\n node,\n })\n }\n return this.options.renderText({\n options: this.options,\n node,\n })\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(\n this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',\n pos,\n pos + node.nodeSize,\n )\n\n return false\n }\n })\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ]\n },\n})\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/get-default-suggestion-attributes.ts","../src/mention.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { SuggestionOptions } from '@tiptap/suggestion'\n\n/**\n * Arguments for the `getSuggestionOptions` function\n * @see getSuggestionOptions\n */\nexport interface GetSuggestionOptionsOptions {\n /**\n * The Tiptap editor instance.\n */\n editor: Editor\n /**\n * The suggestion options configuration provided to the\n * `Mention` extension.\n */\n overrideSuggestionOptions: Omit<SuggestionOptions, 'editor'>\n /**\n * The name of the Mention extension\n */\n extensionName: string\n /**\n * The character that triggers the suggestion.\n * @default '@'\n */\n char?: string\n}\n\n/**\n * Returns the suggestion options for a trigger of the Mention extension. These\n * options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets\n * you define a different trigger that opens the Mention menu. For example,\n * you can define a `@` trigger to mention users and a `#` trigger to mention\n * tags.\n *\n * @param param0 The configured options for the suggestion\n * @returns\n */\nexport function getSuggestionOptions({\n editor: tiptapEditor,\n overrideSuggestionOptions,\n extensionName,\n char = '@',\n}: GetSuggestionOptionsOptions): SuggestionOptions {\n const pluginKey = new PluginKey()\n\n return {\n editor: tiptapEditor,\n char,\n pluginKey,\n command: ({ editor, range, props }: { editor: any; range: any; props: any }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: extensionName,\n attrs: { ...props, mentionSuggestionChar: char },\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n // get reference to `window` object from editor element, to support cross-frame JS usage\n editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }: { state: any; range: any }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[extensionName]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n ...overrideSuggestionOptions,\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { mergeAttributes, Node } from '@tiptap/core'\nimport type { DOMOutputSpec } from '@tiptap/pm/model'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { SuggestionOptions } from '@tiptap/suggestion'\nimport Suggestion from '@tiptap/suggestion'\n\nimport { getSuggestionOptions } from './utils/get-default-suggestion-attributes.js'\n\n// See `addAttributes` below\nexport interface MentionNodeAttrs {\n /**\n * The identifier for the selected item that was mentioned, stored as a `data-id`\n * attribute.\n */\n id: string | null;\n /**\n * The label to be rendered by the editor as the displayed text for this mentioned\n * item, if provided. Stored as a `data-label` attribute. See `renderLabel`.\n */\n label?: string | null\n /**\n * The character that triggers the suggestion, stored as\n * `data-mention-suggestion-char` attribute.\n */\n mentionSuggestionChar?: string\n}\n\nexport interface MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> {\n /**\n * The HTML attributes for a mention node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * A function to render the label of a mention.\n * @deprecated use renderText and renderHTML instead\n * @param props The render props\n * @returns The label\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderLabel?: (props: {\n options: MentionOptions<SuggestionItem, Attrs>\n node: ProseMirrorNode\n suggestion: SuggestionOptions | null\n }) => string\n\n /**\n * A function to render the text of a mention.\n * @param props The render props\n * @returns The text\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderText: (props: {\n options: MentionOptions<SuggestionItem, Attrs>\n node: ProseMirrorNode\n suggestion: SuggestionOptions | null\n }) => string\n\n /**\n * A function to render the HTML of a mention.\n * @param props The render props\n * @returns The HTML as a ProseMirror DOM Output Spec\n * @example ({ options, node }) => ['span', { 'data-type': 'mention' }, `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`]\n */\n renderHTML: (props: {\n options: MentionOptions<SuggestionItem, Attrs>\n node: ProseMirrorNode\n suggestion: SuggestionOptions | null\n }) => DOMOutputSpec\n\n /**\n * Whether to delete the trigger character with backspace.\n * @default false\n */\n deleteTriggerWithBackspace: boolean\n\n /**\n * The suggestion options, when you want to support multiple triggers.\n *\n * With this parameter, you can define multiple types of mention. For example, you can use the `@` character\n * to mention users and the `#` character to mention tags.\n *\n * @default [{ char: '@', pluginKey: MentionPluginKey }]\n * @example [{ char: '@', pluginKey: MentionPluginKey }, { char: '#', pluginKey: new PluginKey('hashtag') }]\n */\n suggestions: Array<Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>>\n\n /**\n * The suggestion options, when you want to support only one trigger. To support multiple triggers, use the\n * `suggestions` parameter instead.\n *\n * @default {}\n * @example { char: '@', pluginKey: MentionPluginKey, command: ({ editor, range, props }) => { ... } }\n */\n suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>\n}\n\ninterface GetSuggestionsOptions {\n editor?: Editor\n options: MentionOptions\n name: string\n}\n\n/**\n * Returns the suggestions for the mention extension.\n *\n * @param options The extension options\n * @returns the suggestions\n */\nfunction getSuggestions(options: GetSuggestionsOptions) {\n return (options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]).map(\n suggestion => getSuggestionOptions({\n // @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility\n editor: options.editor,\n overrideSuggestionOptions: suggestion,\n extensionName: options.name,\n char: suggestion.char,\n }),\n )\n}\n\n/**\n * Returns the suggestion options of the mention that has a given character trigger. If not\n * found, it returns the first suggestion.\n *\n * @param options The extension options\n * @param char The character that triggers the mention\n * @returns The suggestion options\n */\nfunction getSuggestionFromChar(options: GetSuggestionsOptions, char: string) {\n const suggestions = getSuggestions(options)\n\n const suggestion = suggestions.find(s => s.char === char)\n\n if (suggestion) {\n return suggestion\n }\n\n if (suggestions.length) {\n return suggestions[0]\n }\n\n return null\n}\n\n/**\n * This extension allows you to insert mentions into the editor.\n * @see https://www.tiptap.dev/api/extensions/mention\n */\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n priority: 101,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderText({ node, suggestion }) {\n return `${suggestion?.char ?? '@'}${node.attrs.label ?? node.attrs.id}`\n },\n deleteTriggerWithBackspace: false,\n renderHTML({ options, node, suggestion }) {\n return [\n 'span',\n mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),\n `${suggestion?.char ?? '@'}${node.attrs.label ?? node.attrs.id}`,\n ]\n },\n suggestions: [],\n suggestion: {},\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n\n // When there are multiple types of mentions, this attribute helps distinguish them\n mentionSuggestionChar: {\n default: '@',\n parseHTML: element => element.getAttribute('data-mention-suggestion-char'),\n renderHTML: attributes => {\n return {\n 'data-mention-suggestion-char': attributes.mentionSuggestionChar,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar)\n\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n suggestion,\n }),\n ]\n }\n const mergedOptions = { ...this.options }\n\n mergedOptions.HTMLAttributes = mergeAttributes(\n { 'data-type': this.name },\n this.options.HTMLAttributes,\n HTMLAttributes,\n )\n\n const html = this.options.renderHTML({\n options: mergedOptions,\n node,\n suggestion,\n })\n\n if (typeof html === 'string') {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n html,\n ]\n }\n return html\n },\n\n renderText({ node }) {\n const args = {\n options: this.options,\n node,\n suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar),\n }\n\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return this.options.renderLabel(args)\n }\n\n return this.options.renderText(args)\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(\n this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',\n pos,\n pos + node.nodeSize,\n )\n\n return false\n }\n })\n\n // Store node and position for later use\n let mentionNode = new ProseMirrorNode()\n let mentionPos = 0\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n mentionNode = node\n mentionPos = pos\n return false\n }\n })\n\n if (isMention) {\n tr.insertText(\n this.options.deleteTriggerWithBackspace ? '' : mentionNode.attrs.mentionSuggestionChar,\n mentionPos,\n mentionPos + mentionNode.nodeSize,\n )\n }\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n // Create a plugin for each suggestion configuration\n return getSuggestions(this).map(Suggestion)\n },\n})\n"],"names":["ProseMirrorNode"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,14 +1,95 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('@tiptap/pm/state'), require('@tiptap/suggestion')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', '@tiptap/pm/state', '@tiptap/suggestion'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-mention"] = {}, global.core, global.state, global.Suggestion));
5
- })(this, (function (exports, core, state, Suggestion) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('@tiptap/pm/model'), require('@tiptap/suggestion'), require('@tiptap/pm/state')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', '@tiptap/pm/model', '@tiptap/suggestion', '@tiptap/pm/state'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-mention"] = {}, global.core, global.model, global.Suggestion, global.state));
5
+ })(this, (function (exports, core, model, Suggestion, state) { 'use strict';
6
6
 
7
7
  /**
8
- * The plugin key for the mention plugin.
9
- * @default 'mention'
8
+ * Returns the suggestion options for a trigger of the Mention extension. These
9
+ * options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets
10
+ * you define a different trigger that opens the Mention menu. For example,
11
+ * you can define a `@` trigger to mention users and a `#` trigger to mention
12
+ * tags.
13
+ *
14
+ * @param param0 The configured options for the suggestion
15
+ * @returns
10
16
  */
11
- const MentionPluginKey = new state.PluginKey('mention');
17
+ function getSuggestionOptions({ editor: tiptapEditor, overrideSuggestionOptions, extensionName, char = '@', }) {
18
+ const pluginKey = new state.PluginKey();
19
+ return {
20
+ editor: tiptapEditor,
21
+ char,
22
+ pluginKey,
23
+ command: ({ editor, range, props }) => {
24
+ var _a, _b, _c;
25
+ // increase range.to by one when the next node is of type "text"
26
+ // and starts with a space character
27
+ const nodeAfter = editor.view.state.selection.$to.nodeAfter;
28
+ const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
29
+ if (overrideSpace) {
30
+ range.to += 1;
31
+ }
32
+ editor
33
+ .chain()
34
+ .focus()
35
+ .insertContentAt(range, [
36
+ {
37
+ type: extensionName,
38
+ attrs: { ...props, mentionSuggestionChar: char },
39
+ },
40
+ {
41
+ type: 'text',
42
+ text: ' ',
43
+ },
44
+ ])
45
+ .run();
46
+ // get reference to `window` object from editor element, to support cross-frame JS usage
47
+ (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
48
+ },
49
+ allow: ({ state, range }) => {
50
+ const $from = state.doc.resolve(range.from);
51
+ const type = state.schema.nodes[extensionName];
52
+ const allow = !!$from.parent.type.contentMatch.matchType(type);
53
+ return allow;
54
+ },
55
+ ...overrideSuggestionOptions,
56
+ };
57
+ }
58
+
59
+ /**
60
+ * Returns the suggestions for the mention extension.
61
+ *
62
+ * @param options The extension options
63
+ * @returns the suggestions
64
+ */
65
+ function getSuggestions(options) {
66
+ return (options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]).map(suggestion => getSuggestionOptions({
67
+ // @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility
68
+ editor: options.editor,
69
+ overrideSuggestionOptions: suggestion,
70
+ extensionName: options.name,
71
+ char: suggestion.char,
72
+ }));
73
+ }
74
+ /**
75
+ * Returns the suggestion options of the mention that has a given character trigger. If not
76
+ * found, it returns the first suggestion.
77
+ *
78
+ * @param options The extension options
79
+ * @param char The character that triggers the mention
80
+ * @returns The suggestion options
81
+ */
82
+ function getSuggestionFromChar(options, char) {
83
+ const suggestions = getSuggestions(options);
84
+ const suggestion = suggestions.find(s => s.char === char);
85
+ if (suggestion) {
86
+ return suggestion;
87
+ }
88
+ if (suggestions.length) {
89
+ return suggestions[0];
90
+ }
91
+ return null;
92
+ }
12
93
  /**
13
94
  * This extension allows you to insert mentions into the editor.
14
95
  * @see https://www.tiptap.dev/api/extensions/mention
@@ -19,55 +100,21 @@
19
100
  addOptions() {
20
101
  return {
21
102
  HTMLAttributes: {},
22
- renderText({ options, node }) {
23
- var _a;
24
- return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
103
+ renderText({ node, suggestion }) {
104
+ var _a, _b;
105
+ return `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : '@'}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`;
25
106
  },
26
107
  deleteTriggerWithBackspace: false,
27
- renderHTML({ options, node }) {
28
- var _a;
108
+ renderHTML({ options, node, suggestion }) {
109
+ var _a, _b;
29
110
  return [
30
111
  'span',
31
112
  core.mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),
32
- `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`,
113
+ `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : '@'}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`,
33
114
  ];
34
115
  },
35
- suggestion: {
36
- char: '@',
37
- pluginKey: MentionPluginKey,
38
- command: ({ editor, range, props }) => {
39
- var _a, _b, _c;
40
- // increase range.to by one when the next node is of type "text"
41
- // and starts with a space character
42
- const nodeAfter = editor.view.state.selection.$to.nodeAfter;
43
- const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
44
- if (overrideSpace) {
45
- range.to += 1;
46
- }
47
- editor
48
- .chain()
49
- .focus()
50
- .insertContentAt(range, [
51
- {
52
- type: this.name,
53
- attrs: props,
54
- },
55
- {
56
- type: 'text',
57
- text: ' ',
58
- },
59
- ])
60
- .run();
61
- // get reference to `window` object from editor element, to support cross-frame JS usage
62
- (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
63
- },
64
- allow: ({ state, range }) => {
65
- const $from = state.doc.resolve(range.from);
66
- const type = state.schema.nodes[this.name];
67
- const allow = !!$from.parent.type.contentMatch.matchType(type);
68
- return allow;
69
- },
70
- },
116
+ suggestions: [],
117
+ suggestion: {},
71
118
  };
72
119
  },
73
120
  group: 'inline',
@@ -100,6 +147,16 @@
100
147
  };
101
148
  },
102
149
  },
150
+ // When there are multiple types of mentions, this attribute helps distinguish them
151
+ mentionSuggestionChar: {
152
+ default: '@',
153
+ parseHTML: element => element.getAttribute('data-mention-suggestion-char'),
154
+ renderHTML: attributes => {
155
+ return {
156
+ 'data-mention-suggestion-char': attributes.mentionSuggestionChar,
157
+ };
158
+ },
159
+ },
103
160
  };
104
161
  },
105
162
  parseHTML() {
@@ -110,6 +167,7 @@
110
167
  ];
111
168
  },
112
169
  renderHTML({ node, HTMLAttributes }) {
170
+ const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar);
113
171
  if (this.options.renderLabel !== undefined) {
114
172
  console.warn('renderLabel is deprecated use renderText and renderHTML instead');
115
173
  return [
@@ -118,6 +176,7 @@
118
176
  this.options.renderLabel({
119
177
  options: this.options,
120
178
  node,
179
+ suggestion,
121
180
  }),
122
181
  ];
123
182
  }
@@ -126,6 +185,7 @@
126
185
  const html = this.options.renderHTML({
127
186
  options: mergedOptions,
128
187
  node,
188
+ suggestion,
129
189
  });
130
190
  if (typeof html === 'string') {
131
191
  return [
@@ -137,17 +197,16 @@
137
197
  return html;
138
198
  },
139
199
  renderText({ node }) {
200
+ const args = {
201
+ options: this.options,
202
+ node,
203
+ suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar),
204
+ };
140
205
  if (this.options.renderLabel !== undefined) {
141
206
  console.warn('renderLabel is deprecated use renderText and renderHTML instead');
142
- return this.options.renderLabel({
143
- options: this.options,
144
- node,
145
- });
207
+ return this.options.renderLabel(args);
146
208
  }
147
- return this.options.renderText({
148
- options: this.options,
149
- node,
150
- });
209
+ return this.options.renderText(args);
151
210
  },
152
211
  addKeyboardShortcuts() {
153
212
  return {
@@ -165,22 +224,31 @@
165
224
  return false;
166
225
  }
167
226
  });
227
+ // Store node and position for later use
228
+ let mentionNode = new model.Node();
229
+ let mentionPos = 0;
230
+ state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
231
+ if (node.type.name === this.name) {
232
+ isMention = true;
233
+ mentionNode = node;
234
+ mentionPos = pos;
235
+ return false;
236
+ }
237
+ });
238
+ if (isMention) {
239
+ tr.insertText(this.options.deleteTriggerWithBackspace ? '' : mentionNode.attrs.mentionSuggestionChar, mentionPos, mentionPos + mentionNode.nodeSize);
240
+ }
168
241
  return isMention;
169
242
  }),
170
243
  };
171
244
  },
172
245
  addProseMirrorPlugins() {
173
- return [
174
- Suggestion({
175
- editor: this.editor,
176
- ...this.options.suggestion,
177
- }),
178
- ];
246
+ // Create a plugin for each suggestion configuration
247
+ return getSuggestions(this).map(Suggestion);
179
248
  },
180
249
  });
181
250
 
182
251
  exports.Mention = Mention;
183
- exports.MentionPluginKey = MentionPluginKey;
184
252
  exports.default = Mention;
185
253
 
186
254
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/mention.ts"],"sourcesContent":["import { mergeAttributes, Node } from '@tiptap/core'\nimport { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { PluginKey } from '@tiptap/pm/state'\nimport Suggestion, { SuggestionOptions } from '@tiptap/suggestion'\n\n// See `addAttributes` below\nexport interface MentionNodeAttrs {\n /**\n * The identifier for the selected item that was mentioned, stored as a `data-id`\n * attribute.\n */\n id: string | null;\n /**\n * The label to be rendered by the editor as the displayed text for this mentioned\n * item, if provided. Stored as a `data-label` attribute. See `renderLabel`.\n */\n label?: string | null;\n}\n\nexport type MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> = {\n /**\n * The HTML attributes for a mention node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * A function to render the label of a mention.\n * @deprecated use renderText and renderHTML instead\n * @param props The render props\n * @returns The label\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderLabel?: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => string\n\n /**\n * A function to render the text of a mention.\n * @param props The render props\n * @returns The text\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderText: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => string\n\n /**\n * A function to render the HTML of a mention.\n * @param props The render props\n * @returns The HTML as a ProseMirror DOM Output Spec\n * @example ({ options, node }) => ['span', { 'data-type': 'mention' }, `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`]\n */\n renderHTML: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => DOMOutputSpec\n\n /**\n * Whether to delete the trigger character with backspace.\n * @default false\n */\n deleteTriggerWithBackspace: boolean\n\n /**\n * The suggestion options.\n * @default {}\n * @example { char: '@', pluginKey: MentionPluginKey, command: ({ editor, range, props }) => { ... } }\n */\n suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>\n}\n\n/**\n * The plugin key for the mention plugin.\n * @default 'mention'\n */\nexport const MentionPluginKey = new PluginKey('mention')\n\n/**\n * This extension allows you to insert mentions into the editor.\n * @see https://www.tiptap.dev/api/extensions/mention\n */\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n priority: 101,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderText({ options, node }) {\n return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n },\n deleteTriggerWithBackspace: false,\n renderHTML({ options, node }) {\n return [\n 'span',\n mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),\n `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`,\n ]\n },\n suggestion: {\n char: '@',\n pluginKey: MentionPluginKey,\n command: ({ editor, range, props }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: this.name,\n attrs: props,\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n // get reference to `window` object from editor element, to support cross-frame JS usage\n editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[this.name]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n },\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n }),\n ]\n }\n const mergedOptions = { ...this.options }\n\n mergedOptions.HTMLAttributes = mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes)\n const html = this.options.renderHTML({\n options: mergedOptions,\n node,\n })\n\n if (typeof html === 'string') {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n html,\n ]\n }\n return html\n },\n\n renderText({ node }) {\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return this.options.renderLabel({\n options: this.options,\n node,\n })\n }\n return this.options.renderText({\n options: this.options,\n node,\n })\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(\n this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',\n pos,\n pos + node.nodeSize,\n )\n\n return false\n }\n })\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ]\n },\n})\n"],"names":["PluginKey","Node","mergeAttributes"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/utils/get-default-suggestion-attributes.ts","../src/mention.ts"],"sourcesContent":["import type { Editor } from '@tiptap/core'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { SuggestionOptions } from '@tiptap/suggestion'\n\n/**\n * Arguments for the `getSuggestionOptions` function\n * @see getSuggestionOptions\n */\nexport interface GetSuggestionOptionsOptions {\n /**\n * The Tiptap editor instance.\n */\n editor: Editor\n /**\n * The suggestion options configuration provided to the\n * `Mention` extension.\n */\n overrideSuggestionOptions: Omit<SuggestionOptions, 'editor'>\n /**\n * The name of the Mention extension\n */\n extensionName: string\n /**\n * The character that triggers the suggestion.\n * @default '@'\n */\n char?: string\n}\n\n/**\n * Returns the suggestion options for a trigger of the Mention extension. These\n * options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets\n * you define a different trigger that opens the Mention menu. For example,\n * you can define a `@` trigger to mention users and a `#` trigger to mention\n * tags.\n *\n * @param param0 The configured options for the suggestion\n * @returns\n */\nexport function getSuggestionOptions({\n editor: tiptapEditor,\n overrideSuggestionOptions,\n extensionName,\n char = '@',\n}: GetSuggestionOptionsOptions): SuggestionOptions {\n const pluginKey = new PluginKey()\n\n return {\n editor: tiptapEditor,\n char,\n pluginKey,\n command: ({ editor, range, props }: { editor: any; range: any; props: any }) => {\n // increase range.to by one when the next node is of type \"text\"\n // and starts with a space character\n const nodeAfter = editor.view.state.selection.$to.nodeAfter\n const overrideSpace = nodeAfter?.text?.startsWith(' ')\n\n if (overrideSpace) {\n range.to += 1\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt(range, [\n {\n type: extensionName,\n attrs: { ...props, mentionSuggestionChar: char },\n },\n {\n type: 'text',\n text: ' ',\n },\n ])\n .run()\n\n // get reference to `window` object from editor element, to support cross-frame JS usage\n editor.view.dom.ownerDocument.defaultView?.getSelection()?.collapseToEnd()\n },\n allow: ({ state, range }: { state: any; range: any }) => {\n const $from = state.doc.resolve(range.from)\n const type = state.schema.nodes[extensionName]\n const allow = !!$from.parent.type.contentMatch.matchType(type)\n\n return allow\n },\n ...overrideSuggestionOptions,\n }\n}\n","import type { Editor } from '@tiptap/core'\nimport { mergeAttributes, Node } from '@tiptap/core'\nimport type { DOMOutputSpec } from '@tiptap/pm/model'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { SuggestionOptions } from '@tiptap/suggestion'\nimport Suggestion from '@tiptap/suggestion'\n\nimport { getSuggestionOptions } from './utils/get-default-suggestion-attributes.js'\n\n// See `addAttributes` below\nexport interface MentionNodeAttrs {\n /**\n * The identifier for the selected item that was mentioned, stored as a `data-id`\n * attribute.\n */\n id: string | null;\n /**\n * The label to be rendered by the editor as the displayed text for this mentioned\n * item, if provided. Stored as a `data-label` attribute. See `renderLabel`.\n */\n label?: string | null\n /**\n * The character that triggers the suggestion, stored as\n * `data-mention-suggestion-char` attribute.\n */\n mentionSuggestionChar?: string\n}\n\nexport interface MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> {\n /**\n * The HTML attributes for a mention node.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * A function to render the label of a mention.\n * @deprecated use renderText and renderHTML instead\n * @param props The render props\n * @returns The label\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderLabel?: (props: {\n options: MentionOptions<SuggestionItem, Attrs>\n node: ProseMirrorNode\n suggestion: SuggestionOptions | null\n }) => string\n\n /**\n * A function to render the text of a mention.\n * @param props The render props\n * @returns The text\n * @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`\n */\n renderText: (props: {\n options: MentionOptions<SuggestionItem, Attrs>\n node: ProseMirrorNode\n suggestion: SuggestionOptions | null\n }) => string\n\n /**\n * A function to render the HTML of a mention.\n * @param props The render props\n * @returns The HTML as a ProseMirror DOM Output Spec\n * @example ({ options, node }) => ['span', { 'data-type': 'mention' }, `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`]\n */\n renderHTML: (props: {\n options: MentionOptions<SuggestionItem, Attrs>\n node: ProseMirrorNode\n suggestion: SuggestionOptions | null\n }) => DOMOutputSpec\n\n /**\n * Whether to delete the trigger character with backspace.\n * @default false\n */\n deleteTriggerWithBackspace: boolean\n\n /**\n * The suggestion options, when you want to support multiple triggers.\n *\n * With this parameter, you can define multiple types of mention. For example, you can use the `@` character\n * to mention users and the `#` character to mention tags.\n *\n * @default [{ char: '@', pluginKey: MentionPluginKey }]\n * @example [{ char: '@', pluginKey: MentionPluginKey }, { char: '#', pluginKey: new PluginKey('hashtag') }]\n */\n suggestions: Array<Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>>\n\n /**\n * The suggestion options, when you want to support only one trigger. To support multiple triggers, use the\n * `suggestions` parameter instead.\n *\n * @default {}\n * @example { char: '@', pluginKey: MentionPluginKey, command: ({ editor, range, props }) => { ... } }\n */\n suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>\n}\n\ninterface GetSuggestionsOptions {\n editor?: Editor\n options: MentionOptions\n name: string\n}\n\n/**\n * Returns the suggestions for the mention extension.\n *\n * @param options The extension options\n * @returns the suggestions\n */\nfunction getSuggestions(options: GetSuggestionsOptions) {\n return (options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]).map(\n suggestion => getSuggestionOptions({\n // @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility\n editor: options.editor,\n overrideSuggestionOptions: suggestion,\n extensionName: options.name,\n char: suggestion.char,\n }),\n )\n}\n\n/**\n * Returns the suggestion options of the mention that has a given character trigger. If not\n * found, it returns the first suggestion.\n *\n * @param options The extension options\n * @param char The character that triggers the mention\n * @returns The suggestion options\n */\nfunction getSuggestionFromChar(options: GetSuggestionsOptions, char: string) {\n const suggestions = getSuggestions(options)\n\n const suggestion = suggestions.find(s => s.char === char)\n\n if (suggestion) {\n return suggestion\n }\n\n if (suggestions.length) {\n return suggestions[0]\n }\n\n return null\n}\n\n/**\n * This extension allows you to insert mentions into the editor.\n * @see https://www.tiptap.dev/api/extensions/mention\n */\nexport const Mention = Node.create<MentionOptions>({\n name: 'mention',\n\n priority: 101,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n renderText({ node, suggestion }) {\n return `${suggestion?.char ?? '@'}${node.attrs.label ?? node.attrs.id}`\n },\n deleteTriggerWithBackspace: false,\n renderHTML({ options, node, suggestion }) {\n return [\n 'span',\n mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),\n `${suggestion?.char ?? '@'}${node.attrs.label ?? node.attrs.id}`,\n ]\n },\n suggestions: [],\n suggestion: {},\n }\n },\n\n group: 'inline',\n\n inline: true,\n\n selectable: false,\n\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: element => element.getAttribute('data-id'),\n renderHTML: attributes => {\n if (!attributes.id) {\n return {}\n }\n\n return {\n 'data-id': attributes.id,\n }\n },\n },\n\n label: {\n default: null,\n parseHTML: element => element.getAttribute('data-label'),\n renderHTML: attributes => {\n if (!attributes.label) {\n return {}\n }\n\n return {\n 'data-label': attributes.label,\n }\n },\n },\n\n // When there are multiple types of mentions, this attribute helps distinguish them\n mentionSuggestionChar: {\n default: '@',\n parseHTML: element => element.getAttribute('data-mention-suggestion-char'),\n renderHTML: attributes => {\n return {\n 'data-mention-suggestion-char': attributes.mentionSuggestionChar,\n }\n },\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `span[data-type=\"${this.name}\"]`,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar)\n\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n this.options.renderLabel({\n options: this.options,\n node,\n suggestion,\n }),\n ]\n }\n const mergedOptions = { ...this.options }\n\n mergedOptions.HTMLAttributes = mergeAttributes(\n { 'data-type': this.name },\n this.options.HTMLAttributes,\n HTMLAttributes,\n )\n\n const html = this.options.renderHTML({\n options: mergedOptions,\n node,\n suggestion,\n })\n\n if (typeof html === 'string') {\n return [\n 'span',\n mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),\n html,\n ]\n }\n return html\n },\n\n renderText({ node }) {\n const args = {\n options: this.options,\n node,\n suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar),\n }\n\n if (this.options.renderLabel !== undefined) {\n console.warn('renderLabel is deprecated use renderText and renderHTML instead')\n return this.options.renderLabel(args)\n }\n\n return this.options.renderText(args)\n },\n\n addKeyboardShortcuts() {\n return {\n Backspace: () => this.editor.commands.command(({ tr, state }) => {\n let isMention = false\n const { selection } = state\n const { empty, anchor } = selection\n\n if (!empty) {\n return false\n }\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n tr.insertText(\n this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',\n pos,\n pos + node.nodeSize,\n )\n\n return false\n }\n })\n\n // Store node and position for later use\n let mentionNode = new ProseMirrorNode()\n let mentionPos = 0\n\n state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {\n if (node.type.name === this.name) {\n isMention = true\n mentionNode = node\n mentionPos = pos\n return false\n }\n })\n\n if (isMention) {\n tr.insertText(\n this.options.deleteTriggerWithBackspace ? '' : mentionNode.attrs.mentionSuggestionChar,\n mentionPos,\n mentionPos + mentionNode.nodeSize,\n )\n }\n\n return isMention\n }),\n }\n },\n\n addProseMirrorPlugins() {\n // Create a plugin for each suggestion configuration\n return getSuggestions(this).map(Suggestion)\n },\n})\n"],"names":["PluginKey","Node","mergeAttributes","ProseMirrorNode"],"mappings":"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"}
package/dist/mention.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Node } from '@tiptap/core';
2
- import { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model';
3
- import { PluginKey } from '@tiptap/pm/state';
4
- import { SuggestionOptions } from '@tiptap/suggestion';
2
+ import type { DOMOutputSpec } from '@tiptap/pm/model';
3
+ import { Node as ProseMirrorNode } from '@tiptap/pm/model';
4
+ import type { SuggestionOptions } from '@tiptap/suggestion';
5
5
  export interface MentionNodeAttrs {
6
6
  /**
7
7
  * The identifier for the selected item that was mentioned, stored as a `data-id`
@@ -13,8 +13,13 @@ export interface MentionNodeAttrs {
13
13
  * item, if provided. Stored as a `data-label` attribute. See `renderLabel`.
14
14
  */
15
15
  label?: string | null;
16
+ /**
17
+ * The character that triggers the suggestion, stored as
18
+ * `data-mention-suggestion-char` attribute.
19
+ */
20
+ mentionSuggestionChar?: string;
16
21
  }
17
- export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> = {
22
+ export interface MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> {
18
23
  /**
19
24
  * The HTML attributes for a mention node.
20
25
  * @default {}
@@ -31,6 +36,7 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
31
36
  renderLabel?: (props: {
32
37
  options: MentionOptions<SuggestionItem, Attrs>;
33
38
  node: ProseMirrorNode;
39
+ suggestion: SuggestionOptions | null;
34
40
  }) => string;
35
41
  /**
36
42
  * A function to render the text of a mention.
@@ -41,6 +47,7 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
41
47
  renderText: (props: {
42
48
  options: MentionOptions<SuggestionItem, Attrs>;
43
49
  node: ProseMirrorNode;
50
+ suggestion: SuggestionOptions | null;
44
51
  }) => string;
45
52
  /**
46
53
  * A function to render the HTML of a mention.
@@ -51,6 +58,7 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
51
58
  renderHTML: (props: {
52
59
  options: MentionOptions<SuggestionItem, Attrs>;
53
60
  node: ProseMirrorNode;
61
+ suggestion: SuggestionOptions | null;
54
62
  }) => DOMOutputSpec;
55
63
  /**
56
64
  * Whether to delete the trigger character with backspace.
@@ -58,17 +66,24 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
58
66
  */
59
67
  deleteTriggerWithBackspace: boolean;
60
68
  /**
61
- * The suggestion options.
69
+ * The suggestion options, when you want to support multiple triggers.
70
+ *
71
+ * With this parameter, you can define multiple types of mention. For example, you can use the `@` character
72
+ * to mention users and the `#` character to mention tags.
73
+ *
74
+ * @default [{ char: '@', pluginKey: MentionPluginKey }]
75
+ * @example [{ char: '@', pluginKey: MentionPluginKey }, { char: '#', pluginKey: new PluginKey('hashtag') }]
76
+ */
77
+ suggestions: Array<Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>>;
78
+ /**
79
+ * The suggestion options, when you want to support only one trigger. To support multiple triggers, use the
80
+ * `suggestions` parameter instead.
81
+ *
62
82
  * @default {}
63
83
  * @example { char: '@', pluginKey: MentionPluginKey, command: ({ editor, range, props }) => { ... } }
64
84
  */
65
85
  suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>;
66
- };
67
- /**
68
- * The plugin key for the mention plugin.
69
- * @default 'mention'
70
- */
71
- export declare const MentionPluginKey: PluginKey<any>;
86
+ }
72
87
  /**
73
88
  * This extension allows you to insert mentions into the editor.
74
89
  * @see https://www.tiptap.dev/api/extensions/mention
@@ -1 +1 @@
1
- {"version":3,"file":"mention.d.ts","sourceRoot":"","sources":["../src/mention.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,IAAI,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAGlE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,MAAM,cAAc,CAAC,cAAc,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB,IAAI;IACvG;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEnC;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,KAAK,MAAM,CAAA;IAE1G;;;;;OAKG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,KAAK,MAAM,CAAA;IAExG;;;;;OAKG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAAC,IAAI,EAAE,eAAe,CAAA;KAAE,KAAK,aAAa,CAAA;IAE/G;;;OAGG;IACH,0BAA0B,EAAE,OAAO,CAAA;IAEnC;;;;OAIG;IACH,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAA;CACrE,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gBAA2B,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,OAAO,kDA8LlB,CAAA"}
1
+ {"version":3,"file":"mention.d.ts","sourceRoot":"","sources":["../src/mention.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,IAAI,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAM3D,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,cAAc,CAAC,cAAc,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB;IACxG;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEnC;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QACpB,OAAO,EAAE,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAC9C,IAAI,EAAE,eAAe,CAAA;QACrB,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;KACrC,KAAK,MAAM,CAAA;IAEZ;;;;;OAKG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE;QAClB,OAAO,EAAE,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAC9C,IAAI,EAAE,eAAe,CAAA;QACrB,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;KACrC,KAAK,MAAM,CAAA;IAEZ;;;;;OAKG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE;QAClB,OAAO,EAAE,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;QAC9C,IAAI,EAAE,eAAe,CAAA;QACrB,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;KACrC,KAAK,aAAa,CAAA;IAEnB;;;OAGG;IACH,0BAA0B,EAAE,OAAO,CAAA;IAEnC;;;;;;;;OAQG;IACH,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;IAE5E;;;;;;OAMG;IACH,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAA;CACrE;AAkDD;;;GAGG;AACH,eAAO,MAAM,OAAO,kDA+LlB,CAAA"}
@@ -0,0 +1,38 @@
1
+ import type { Editor } from '@tiptap/core';
2
+ import type { SuggestionOptions } from '@tiptap/suggestion';
3
+ /**
4
+ * Arguments for the `getSuggestionOptions` function
5
+ * @see getSuggestionOptions
6
+ */
7
+ export interface GetSuggestionOptionsOptions {
8
+ /**
9
+ * The Tiptap editor instance.
10
+ */
11
+ editor: Editor;
12
+ /**
13
+ * The suggestion options configuration provided to the
14
+ * `Mention` extension.
15
+ */
16
+ overrideSuggestionOptions: Omit<SuggestionOptions, 'editor'>;
17
+ /**
18
+ * The name of the Mention extension
19
+ */
20
+ extensionName: string;
21
+ /**
22
+ * The character that triggers the suggestion.
23
+ * @default '@'
24
+ */
25
+ char?: string;
26
+ }
27
+ /**
28
+ * Returns the suggestion options for a trigger of the Mention extension. These
29
+ * options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets
30
+ * you define a different trigger that opens the Mention menu. For example,
31
+ * you can define a `@` trigger to mention users and a `#` trigger to mention
32
+ * tags.
33
+ *
34
+ * @param param0 The configured options for the suggestion
35
+ * @returns
36
+ */
37
+ export declare function getSuggestionOptions({ editor: tiptapEditor, overrideSuggestionOptions, extensionName, char, }: GetSuggestionOptionsOptions): SuggestionOptions;
38
+ //# sourceMappingURL=get-default-suggestion-attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-default-suggestion-attributes.d.ts","sourceRoot":"","sources":["../../src/utils/get-default-suggestion-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAE3D;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,yBAAyB,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;IAC5D;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EAAE,YAAY,EACpB,yBAAyB,EACzB,aAAa,EACb,IAAU,GACX,EAAE,2BAA2B,GAAG,iBAAiB,CA4CjD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-mention",
3
3
  "description": "mention extension for tiptap",
4
- "version": "2.22.3",
4
+ "version": "2.23.1",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -29,9 +29,9 @@
29
29
  "dist"
30
30
  ],
31
31
  "devDependencies": {
32
- "@tiptap/core": "^2.22.3",
33
- "@tiptap/pm": "^2.22.3",
34
- "@tiptap/suggestion": "^2.22.3"
32
+ "@tiptap/core": "^2.23.1",
33
+ "@tiptap/pm": "^2.23.1",
34
+ "@tiptap/suggestion": "^2.23.1"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@tiptap/core": "^2.7.0",