@tiptap/extension-mention 2.11.7 → 3.0.0-beta.0
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/LICENSE.md +21 -0
- package/README.md +5 -1
- package/dist/index.cjs +203 -180
- package/dist/index.cjs.map +1 -1
- package/dist/{mention.d.ts → index.d.cts} +12 -10
- package/dist/index.d.ts +79 -4
- package/dist/index.js +167 -172
- package/dist/index.js.map +1 -1
- package/package.json +14 -12
- package/src/mention.ts +32 -30
- package/dist/index.d.ts.map +0 -1
- package/dist/index.umd.js +0 -189
- package/dist/index.umd.js.map +0 -1
- package/dist/mention.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,181 +1,176 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
HTMLAttributes: {},
|
|
20
|
-
renderText({ options, node }) {
|
|
21
|
-
var _a;
|
|
22
|
-
return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
|
|
23
|
-
},
|
|
24
|
-
deleteTriggerWithBackspace: false,
|
|
25
|
-
renderHTML({ options, node }) {
|
|
26
|
-
var _a;
|
|
27
|
-
return [
|
|
28
|
-
'span',
|
|
29
|
-
mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),
|
|
30
|
-
`${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`,
|
|
31
|
-
];
|
|
32
|
-
},
|
|
33
|
-
suggestion: {
|
|
34
|
-
char: '@',
|
|
35
|
-
pluginKey: MentionPluginKey,
|
|
36
|
-
command: ({ editor, range, props }) => {
|
|
37
|
-
var _a, _b, _c;
|
|
38
|
-
// increase range.to by one when the next node is of type "text"
|
|
39
|
-
// and starts with a space character
|
|
40
|
-
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
41
|
-
const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
|
|
42
|
-
if (overrideSpace) {
|
|
43
|
-
range.to += 1;
|
|
44
|
-
}
|
|
45
|
-
editor
|
|
46
|
-
.chain()
|
|
47
|
-
.focus()
|
|
48
|
-
.insertContentAt(range, [
|
|
49
|
-
{
|
|
50
|
-
type: this.name,
|
|
51
|
-
attrs: props,
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
type: 'text',
|
|
55
|
-
text: ' ',
|
|
56
|
-
},
|
|
57
|
-
])
|
|
58
|
-
.run();
|
|
59
|
-
// get reference to `window` object from editor element, to support cross-frame JS usage
|
|
60
|
-
(_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
|
|
61
|
-
},
|
|
62
|
-
allow: ({ state, range }) => {
|
|
63
|
-
const $from = state.doc.resolve(range.from);
|
|
64
|
-
const type = state.schema.nodes[this.name];
|
|
65
|
-
const allow = !!$from.parent.type.contentMatch.matchType(type);
|
|
66
|
-
return allow;
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
},
|
|
71
|
-
group: 'inline',
|
|
72
|
-
inline: true,
|
|
73
|
-
selectable: false,
|
|
74
|
-
atom: true,
|
|
75
|
-
addAttributes() {
|
|
76
|
-
return {
|
|
77
|
-
id: {
|
|
78
|
-
default: null,
|
|
79
|
-
parseHTML: element => element.getAttribute('data-id'),
|
|
80
|
-
renderHTML: attributes => {
|
|
81
|
-
if (!attributes.id) {
|
|
82
|
-
return {};
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
'data-id': attributes.id,
|
|
86
|
-
};
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
label: {
|
|
90
|
-
default: null,
|
|
91
|
-
parseHTML: element => element.getAttribute('data-label'),
|
|
92
|
-
renderHTML: attributes => {
|
|
93
|
-
if (!attributes.label) {
|
|
94
|
-
return {};
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
'data-label': attributes.label,
|
|
98
|
-
};
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
},
|
|
103
|
-
parseHTML() {
|
|
1
|
+
// src/mention.ts
|
|
2
|
+
import { mergeAttributes, Node } from "@tiptap/core";
|
|
3
|
+
import { PluginKey } from "@tiptap/pm/state";
|
|
4
|
+
import Suggestion from "@tiptap/suggestion";
|
|
5
|
+
var MentionPluginKey = new PluginKey("mention");
|
|
6
|
+
var Mention = Node.create({
|
|
7
|
+
name: "mention",
|
|
8
|
+
priority: 101,
|
|
9
|
+
addOptions() {
|
|
10
|
+
return {
|
|
11
|
+
HTMLAttributes: {},
|
|
12
|
+
renderText({ options, node }) {
|
|
13
|
+
var _a;
|
|
14
|
+
return `${options.suggestion.char}${(_a = node.attrs.label) != null ? _a : node.attrs.id}`;
|
|
15
|
+
},
|
|
16
|
+
deleteTriggerWithBackspace: false,
|
|
17
|
+
renderHTML({ options, node }) {
|
|
18
|
+
var _a;
|
|
104
19
|
return [
|
|
20
|
+
"span",
|
|
21
|
+
mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),
|
|
22
|
+
`${options.suggestion.char}${(_a = node.attrs.label) != null ? _a : node.attrs.id}`
|
|
23
|
+
];
|
|
24
|
+
},
|
|
25
|
+
suggestion: {
|
|
26
|
+
char: "@",
|
|
27
|
+
pluginKey: MentionPluginKey,
|
|
28
|
+
command: ({ editor, range, props }) => {
|
|
29
|
+
var _a, _b, _c;
|
|
30
|
+
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
|
31
|
+
const overrideSpace = (_a = nodeAfter == null ? void 0 : nodeAfter.text) == null ? void 0 : _a.startsWith(" ");
|
|
32
|
+
if (overrideSpace) {
|
|
33
|
+
range.to += 1;
|
|
34
|
+
}
|
|
35
|
+
editor.chain().focus().insertContentAt(range, [
|
|
105
36
|
{
|
|
106
|
-
|
|
37
|
+
type: this.name,
|
|
38
|
+
attrs: props
|
|
107
39
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
];
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text: " "
|
|
43
|
+
}
|
|
44
|
+
]).run();
|
|
45
|
+
(_c = (_b = editor.view.dom.ownerDocument.defaultView) == null ? void 0 : _b.getSelection()) == null ? void 0 : _c.collapseToEnd();
|
|
46
|
+
},
|
|
47
|
+
allow: ({ state, range }) => {
|
|
48
|
+
const $from = state.doc.resolve(range.from);
|
|
49
|
+
const type = state.schema.nodes[this.name];
|
|
50
|
+
const allow = !!$from.parent.type.contentMatch.matchType(type);
|
|
51
|
+
return allow;
|
|
121
52
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
group: "inline",
|
|
57
|
+
inline: true,
|
|
58
|
+
selectable: false,
|
|
59
|
+
atom: true,
|
|
60
|
+
addAttributes() {
|
|
61
|
+
return {
|
|
62
|
+
id: {
|
|
63
|
+
default: null,
|
|
64
|
+
parseHTML: (element) => element.getAttribute("data-id"),
|
|
65
|
+
renderHTML: (attributes) => {
|
|
66
|
+
if (!attributes.id) {
|
|
67
|
+
return {};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
"data-id": attributes.id
|
|
71
|
+
};
|
|
134
72
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
73
|
+
},
|
|
74
|
+
label: {
|
|
75
|
+
default: null,
|
|
76
|
+
parseHTML: (element) => element.getAttribute("data-label"),
|
|
77
|
+
renderHTML: (attributes) => {
|
|
78
|
+
if (!attributes.label) {
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
"data-label": attributes.label
|
|
83
|
+
};
|
|
144
84
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
parseHTML() {
|
|
89
|
+
return [
|
|
90
|
+
{
|
|
91
|
+
tag: `span[data-type="${this.name}"]`
|
|
92
|
+
}
|
|
93
|
+
];
|
|
94
|
+
},
|
|
95
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
96
|
+
if (this.options.renderLabel !== void 0) {
|
|
97
|
+
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
|
98
|
+
return [
|
|
99
|
+
"span",
|
|
100
|
+
mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
101
|
+
this.options.renderLabel({
|
|
102
|
+
options: this.options,
|
|
103
|
+
node
|
|
104
|
+
})
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
const mergedOptions = { ...this.options };
|
|
108
|
+
mergedOptions.HTMLAttributes = mergeAttributes(
|
|
109
|
+
{ "data-type": this.name },
|
|
110
|
+
this.options.HTMLAttributes,
|
|
111
|
+
HTMLAttributes
|
|
112
|
+
);
|
|
113
|
+
const html = this.options.renderHTML({
|
|
114
|
+
options: mergedOptions,
|
|
115
|
+
node
|
|
116
|
+
});
|
|
117
|
+
if (typeof html === "string") {
|
|
118
|
+
return ["span", mergeAttributes({ "data-type": this.name }, this.options.HTMLAttributes, HTMLAttributes), html];
|
|
119
|
+
}
|
|
120
|
+
return html;
|
|
121
|
+
},
|
|
122
|
+
renderText({ node }) {
|
|
123
|
+
if (this.options.renderLabel !== void 0) {
|
|
124
|
+
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
|
125
|
+
return this.options.renderLabel({
|
|
126
|
+
options: this.options,
|
|
127
|
+
node
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return this.options.renderText({
|
|
131
|
+
options: this.options,
|
|
132
|
+
node
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
addKeyboardShortcuts() {
|
|
136
|
+
return {
|
|
137
|
+
Backspace: () => this.editor.commands.command(({ tr, state }) => {
|
|
138
|
+
let isMention = false;
|
|
139
|
+
const { selection } = state;
|
|
140
|
+
const { empty, anchor } = selection;
|
|
141
|
+
if (!empty) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
|
145
|
+
if (node.type.name === this.name) {
|
|
146
|
+
isMention = true;
|
|
147
|
+
tr.insertText(
|
|
148
|
+
this.options.deleteTriggerWithBackspace ? "" : this.options.suggestion.char || "",
|
|
149
|
+
pos,
|
|
150
|
+
pos + node.nodeSize
|
|
151
|
+
);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
148
154
|
});
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
isMention = true;
|
|
162
|
-
tr.insertText(this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '', pos, pos + node.nodeSize);
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
return isMention;
|
|
167
|
-
}),
|
|
168
|
-
};
|
|
169
|
-
},
|
|
170
|
-
addProseMirrorPlugins() {
|
|
171
|
-
return [
|
|
172
|
-
Suggestion({
|
|
173
|
-
editor: this.editor,
|
|
174
|
-
...this.options.suggestion,
|
|
175
|
-
}),
|
|
176
|
-
];
|
|
177
|
-
},
|
|
155
|
+
return isMention;
|
|
156
|
+
})
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
addProseMirrorPlugins() {
|
|
160
|
+
return [
|
|
161
|
+
Suggestion({
|
|
162
|
+
editor: this.editor,
|
|
163
|
+
...this.options.suggestion
|
|
164
|
+
})
|
|
165
|
+
];
|
|
166
|
+
}
|
|
178
167
|
});
|
|
179
168
|
|
|
180
|
-
|
|
181
|
-
|
|
169
|
+
// src/index.ts
|
|
170
|
+
var index_default = Mention;
|
|
171
|
+
export {
|
|
172
|
+
Mention,
|
|
173
|
+
MentionPluginKey,
|
|
174
|
+
index_default as default
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=index.js.map
|
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,"sources":["../src/mention.ts","../src/index.ts"],"sourcesContent":["import { mergeAttributes, Node } from '@tiptap/core'\nimport type { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { PluginKey } from '@tiptap/pm/state'\nimport type { SuggestionOptions } from '@tiptap/suggestion'\nimport Suggestion 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(\n { 'data-type': this.name },\n this.options.HTMLAttributes,\n HTMLAttributes,\n )\n const html = this.options.renderHTML({\n options: mergedOptions,\n node,\n })\n\n if (typeof html === 'string') {\n return ['span', mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), html]\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: () =>\n 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","import { Mention } from './mention.js'\n\nexport * from './mention.js'\n\nexport default Mention\n"],"mappings":";AAAA,SAAS,iBAAiB,YAAY;AAEtC,SAAS,iBAAiB;AAE1B,OAAO,gBAAgB;AAmEhB,IAAM,mBAAmB,IAAI,UAAU,SAAS;AAMhD,IAAM,UAAU,KAAK,OAAuB;AAAA,EACjD,MAAM;AAAA,EAEN,UAAU;AAAA,EAEV,aAAa;AACX,WAAO;AAAA,MACL,gBAAgB,CAAC;AAAA,MACjB,WAAW,EAAE,SAAS,KAAK,GAAG;AArFpC;AAsFQ,eAAO,GAAG,QAAQ,WAAW,IAAI,IAAG,UAAK,MAAM,UAAX,YAAoB,KAAK,MAAM,EAAE;AAAA,MACvE;AAAA,MACA,4BAA4B;AAAA,MAC5B,WAAW,EAAE,SAAS,KAAK,GAAG;AAzFpC;AA0FQ,eAAO;AAAA,UACL;AAAA,UACA,gBAAgB,KAAK,gBAAgB,QAAQ,cAAc;AAAA,UAC3D,GAAG,QAAQ,WAAW,IAAI,IAAG,UAAK,MAAM,UAAX,YAAoB,KAAK,MAAM,EAAE;AAAA,QAChE;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACV,MAAM;AAAA,QACN,WAAW;AAAA,QACX,SAAS,CAAC,EAAE,QAAQ,OAAO,MAAM,MAAM;AAnG/C;AAsGU,gBAAM,YAAY,OAAO,KAAK,MAAM,UAAU,IAAI;AAClD,gBAAM,iBAAgB,4CAAW,SAAX,mBAAiB,WAAW;AAElD,cAAI,eAAe;AACjB,kBAAM,MAAM;AAAA,UACd;AAEA,iBACG,MAAM,EACN,MAAM,EACN,gBAAgB,OAAO;AAAA,YACtB;AAAA,cACE,MAAM,KAAK;AAAA,cACX,OAAO;AAAA,YACT;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF,CAAC,EACA,IAAI;AAGP,6BAAO,KAAK,IAAI,cAAc,gBAA9B,mBAA2C,mBAA3C,mBAA2D;AAAA,QAC7D;AAAA,QACA,OAAO,CAAC,EAAE,OAAO,MAAM,MAAM;AAC3B,gBAAM,QAAQ,MAAM,IAAI,QAAQ,MAAM,IAAI;AAC1C,gBAAM,OAAO,MAAM,OAAO,MAAM,KAAK,IAAI;AACzC,gBAAM,QAAQ,CAAC,CAAC,MAAM,OAAO,KAAK,aAAa,UAAU,IAAI;AAE7D,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,EAEP,QAAQ;AAAA,EAER,YAAY;AAAA,EAEZ,MAAM;AAAA,EAEN,gBAAgB;AACd,WAAO;AAAA,MACL,IAAI;AAAA,QACF,SAAS;AAAA,QACT,WAAW,aAAW,QAAQ,aAAa,SAAS;AAAA,QACpD,YAAY,gBAAc;AACxB,cAAI,CAAC,WAAW,IAAI;AAClB,mBAAO,CAAC;AAAA,UACV;AAEA,iBAAO;AAAA,YACL,WAAW,WAAW;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,MAEA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,aAAW,QAAQ,aAAa,YAAY;AAAA,QACvD,YAAY,gBAAc;AACxB,cAAI,CAAC,WAAW,OAAO;AACrB,mBAAO,CAAC;AAAA,UACV;AAEA,iBAAO;AAAA,YACL,cAAc,WAAW;AAAA,UAC3B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO;AAAA,MACL;AAAA,QACE,KAAK,mBAAmB,KAAK,IAAI;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,EAAE,MAAM,eAAe,GAAG;AACnC,QAAI,KAAK,QAAQ,gBAAgB,QAAW;AAC1C,cAAQ,KAAK,iEAAiE;AAC9E,aAAO;AAAA,QACL;AAAA,QACA,gBAAgB,EAAE,aAAa,KAAK,KAAK,GAAG,KAAK,QAAQ,gBAAgB,cAAc;AAAA,QACvF,KAAK,QAAQ,YAAY;AAAA,UACvB,SAAS,KAAK;AAAA,UACd;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,gBAAgB,EAAE,GAAG,KAAK,QAAQ;AAExC,kBAAc,iBAAiB;AAAA,MAC7B,EAAE,aAAa,KAAK,KAAK;AAAA,MACzB,KAAK,QAAQ;AAAA,MACb;AAAA,IACF;AACA,UAAM,OAAO,KAAK,QAAQ,WAAW;AAAA,MACnC,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAED,QAAI,OAAO,SAAS,UAAU;AAC5B,aAAO,CAAC,QAAQ,gBAAgB,EAAE,aAAa,KAAK,KAAK,GAAG,KAAK,QAAQ,gBAAgB,cAAc,GAAG,IAAI;AAAA,IAChH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,EAAE,KAAK,GAAG;AACnB,QAAI,KAAK,QAAQ,gBAAgB,QAAW;AAC1C,cAAQ,KAAK,iEAAiE;AAC9E,aAAO,KAAK,QAAQ,YAAY;AAAA,QAC9B,SAAS,KAAK;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,KAAK,QAAQ,WAAW;AAAA,MAC7B,SAAS,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,uBAAuB;AACrB,WAAO;AAAA,MACL,WAAW,MACT,KAAK,OAAO,SAAS,QAAQ,CAAC,EAAE,IAAI,MAAM,MAAM;AAC9C,YAAI,YAAY;AAChB,cAAM,EAAE,UAAU,IAAI;AACtB,cAAM,EAAE,OAAO,OAAO,IAAI;AAE1B,YAAI,CAAC,OAAO;AACV,iBAAO;AAAA,QACT;AAEA,cAAM,IAAI,aAAa,SAAS,GAAG,QAAQ,CAAC,MAAM,QAAQ;AACxD,cAAI,KAAK,KAAK,SAAS,KAAK,MAAM;AAChC,wBAAY;AACZ,eAAG;AAAA,cACD,KAAK,QAAQ,6BAA6B,KAAK,KAAK,QAAQ,WAAW,QAAQ;AAAA,cAC/E;AAAA,cACA,MAAM,KAAK;AAAA,YACb;AAEA,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AAED,eAAO;AAAA,MACT,CAAC;AAAA,IACL;AAAA,EACF;AAAA,EAEA,wBAAwB;AACtB,WAAO;AAAA,MACL,WAAW;AAAA,QACT,QAAQ,KAAK;AAAA,QACb,GAAG,KAAK,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AACF,CAAC;;;ACxQD,IAAO,gBAAQ;","names":[]}
|
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": "
|
|
4
|
+
"version": "3.0.0-beta.0",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -15,28 +15,30 @@
|
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
18
|
-
"types":
|
|
18
|
+
"types": {
|
|
19
|
+
"import": "./dist/index.d.ts",
|
|
20
|
+
"require": "./dist/index.d.cts"
|
|
21
|
+
},
|
|
19
22
|
"import": "./dist/index.js",
|
|
20
23
|
"require": "./dist/index.cjs"
|
|
21
24
|
}
|
|
22
25
|
},
|
|
23
26
|
"main": "dist/index.cjs",
|
|
24
27
|
"module": "dist/index.js",
|
|
25
|
-
"umd": "dist/index.umd.js",
|
|
26
28
|
"types": "dist/index.d.ts",
|
|
27
29
|
"files": [
|
|
28
30
|
"src",
|
|
29
31
|
"dist"
|
|
30
32
|
],
|
|
31
33
|
"devDependencies": {
|
|
32
|
-
"@tiptap/core": "^
|
|
33
|
-
"@tiptap/pm": "^
|
|
34
|
-
"@tiptap/suggestion": "^
|
|
34
|
+
"@tiptap/core": "^3.0.0-beta.0",
|
|
35
|
+
"@tiptap/pm": "^3.0.0-beta.0",
|
|
36
|
+
"@tiptap/suggestion": "^3.0.0-beta.0"
|
|
35
37
|
},
|
|
36
38
|
"peerDependencies": {
|
|
37
|
-
"@tiptap/core": "^
|
|
38
|
-
"@tiptap/pm": "^
|
|
39
|
-
"@tiptap/suggestion": "^
|
|
39
|
+
"@tiptap/core": "^3.0.0-beta.0",
|
|
40
|
+
"@tiptap/pm": "^3.0.0-beta.0",
|
|
41
|
+
"@tiptap/suggestion": "^3.0.0-beta.0"
|
|
40
42
|
},
|
|
41
43
|
"repository": {
|
|
42
44
|
"type": "git",
|
|
@@ -44,7 +46,7 @@
|
|
|
44
46
|
"directory": "packages/extension-mention"
|
|
45
47
|
},
|
|
46
48
|
"scripts": {
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
+
"build": "tsup",
|
|
50
|
+
"lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
|
|
49
51
|
}
|
|
50
|
-
}
|
|
52
|
+
}
|
package/src/mention.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { mergeAttributes, Node } from '@tiptap/core'
|
|
2
|
-
import { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
2
|
+
import type { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
3
3
|
import { PluginKey } from '@tiptap/pm/state'
|
|
4
|
-
import
|
|
4
|
+
import type { SuggestionOptions } from '@tiptap/suggestion'
|
|
5
|
+
import Suggestion from '@tiptap/suggestion'
|
|
5
6
|
|
|
6
7
|
// See `addAttributes` below
|
|
7
8
|
export interface MentionNodeAttrs {
|
|
@@ -9,12 +10,12 @@ export interface MentionNodeAttrs {
|
|
|
9
10
|
* The identifier for the selected item that was mentioned, stored as a `data-id`
|
|
10
11
|
* attribute.
|
|
11
12
|
*/
|
|
12
|
-
id: string | null
|
|
13
|
+
id: string | null
|
|
13
14
|
/**
|
|
14
15
|
* The label to be rendered by the editor as the displayed text for this mentioned
|
|
15
16
|
* item, if provided. Stored as a `data-label` attribute. See `renderLabel`.
|
|
16
17
|
*/
|
|
17
|
-
label?: string | null
|
|
18
|
+
label?: string | null
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> = {
|
|
@@ -197,18 +198,18 @@ export const Mention = Node.create<MentionOptions>({
|
|
|
197
198
|
}
|
|
198
199
|
const mergedOptions = { ...this.options }
|
|
199
200
|
|
|
200
|
-
mergedOptions.HTMLAttributes = mergeAttributes(
|
|
201
|
+
mergedOptions.HTMLAttributes = mergeAttributes(
|
|
202
|
+
{ 'data-type': this.name },
|
|
203
|
+
this.options.HTMLAttributes,
|
|
204
|
+
HTMLAttributes,
|
|
205
|
+
)
|
|
201
206
|
const html = this.options.renderHTML({
|
|
202
207
|
options: mergedOptions,
|
|
203
208
|
node,
|
|
204
209
|
})
|
|
205
210
|
|
|
206
211
|
if (typeof html === 'string') {
|
|
207
|
-
return [
|
|
208
|
-
'span',
|
|
209
|
-
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
|
210
|
-
html,
|
|
211
|
-
]
|
|
212
|
+
return ['span', mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes), html]
|
|
212
213
|
}
|
|
213
214
|
return html
|
|
214
215
|
},
|
|
@@ -229,30 +230,31 @@ export const Mention = Node.create<MentionOptions>({
|
|
|
229
230
|
|
|
230
231
|
addKeyboardShortcuts() {
|
|
231
232
|
return {
|
|
232
|
-
Backspace: () =>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (!empty) {
|
|
238
|
-
return false
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
|
242
|
-
if (node.type.name === this.name) {
|
|
243
|
-
isMention = true
|
|
244
|
-
tr.insertText(
|
|
245
|
-
this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',
|
|
246
|
-
pos,
|
|
247
|
-
pos + node.nodeSize,
|
|
248
|
-
)
|
|
233
|
+
Backspace: () =>
|
|
234
|
+
this.editor.commands.command(({ tr, state }) => {
|
|
235
|
+
let isMention = false
|
|
236
|
+
const { selection } = state
|
|
237
|
+
const { empty, anchor } = selection
|
|
249
238
|
|
|
239
|
+
if (!empty) {
|
|
250
240
|
return false
|
|
251
241
|
}
|
|
252
|
-
})
|
|
253
242
|
|
|
254
|
-
|
|
255
|
-
|
|
243
|
+
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
|
244
|
+
if (node.type.name === this.name) {
|
|
245
|
+
isMention = true
|
|
246
|
+
tr.insertText(
|
|
247
|
+
this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',
|
|
248
|
+
pos,
|
|
249
|
+
pos + node.nodeSize,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
return false
|
|
253
|
+
}
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
return isMention
|
|
257
|
+
}),
|
|
256
258
|
}
|
|
257
259
|
},
|
|
258
260
|
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,cAAc,cAAc,CAAA;AAE5B,eAAe,OAAO,CAAA"}
|