For sure matches Mention
This commit is contained in:
@@ -17,15 +17,18 @@ export interface MentionNodeAttrs {
|
||||
* The identifier for the selected item that was mentioned, stored as a `data-id`
|
||||
* attribute.
|
||||
*/
|
||||
id: string | null;
|
||||
id: string | null
|
||||
/**
|
||||
* The label to be rendered by the editor as the displayed text for this mentioned
|
||||
* item, if provided. Stored as a `data-label` attribute. See `renderLabel`.
|
||||
*/
|
||||
label?: string | null;
|
||||
label?: string | null
|
||||
}
|
||||
|
||||
export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> = {
|
||||
export type MentionOptions<
|
||||
SuggestionItem = any,
|
||||
Attrs extends Record<string, any> = MentionNodeAttrs,
|
||||
> = {
|
||||
/**
|
||||
* The HTML attributes for a mention node.
|
||||
* @default {}
|
||||
@@ -40,7 +43,10 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
|
||||
* @returns The label
|
||||
* @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
|
||||
*/
|
||||
renderLabel?: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => string
|
||||
renderLabel?: (props: {
|
||||
options: MentionOptions<SuggestionItem, Attrs>
|
||||
node: ProseMirrorNode
|
||||
}) => string
|
||||
|
||||
/**
|
||||
* A function to render the text of a mention.
|
||||
@@ -48,7 +54,10 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
|
||||
* @returns The text
|
||||
* @example ({ options, node }) => `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
|
||||
*/
|
||||
renderText: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => string
|
||||
renderText: (props: {
|
||||
options: MentionOptions<SuggestionItem, Attrs>
|
||||
node: ProseMirrorNode
|
||||
}) => string
|
||||
|
||||
/**
|
||||
* A function to render the HTML of a mention.
|
||||
@@ -56,7 +65,10 @@ export type MentionOptions<SuggestionItem = any, Attrs extends Record<string, an
|
||||
* @returns The HTML as a ProseMirror DOM Output Spec
|
||||
* @example ({ options, node }) => ['span', { 'data-type': 'mention' }, `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`]
|
||||
*/
|
||||
renderHTML: (props: { options: MentionOptions<SuggestionItem, Attrs>; node: ProseMirrorNode }) => DOMOutputSpec
|
||||
renderHTML: (props: {
|
||||
options: MentionOptions<SuggestionItem, Attrs>
|
||||
node: ProseMirrorNode
|
||||
}) => DOMOutputSpec
|
||||
|
||||
/**
|
||||
* Whether to delete the trigger character with backspace.
|
||||
@@ -133,15 +145,9 @@ export const Tags = Node.create<MentionOptions>({
|
||||
const $from = state.doc.resolve(range.from)
|
||||
const type = state.schema.nodes[this.name]
|
||||
const allow = !!$from.parent.type.contentMatch.matchType(type)
|
||||
console.log({
|
||||
allow,
|
||||
$from,
|
||||
state,
|
||||
})
|
||||
|
||||
return allow
|
||||
},
|
||||
findSuggestionMatch: findSuggestionMatch
|
||||
findSuggestionMatch: findSuggestionMatch,
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -196,10 +202,16 @@ export const Tags = Node.create<MentionOptions>({
|
||||
|
||||
renderHTML({node, HTMLAttributes}) {
|
||||
if (this.options.renderLabel !== undefined) {
|
||||
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
|
||||
console.warn(
|
||||
'renderLabel is deprecated use renderText and renderHTML instead',
|
||||
)
|
||||
return [
|
||||
'span',
|
||||
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
||||
mergeAttributes(
|
||||
{'data-type': this.name},
|
||||
this.options.HTMLAttributes,
|
||||
HTMLAttributes,
|
||||
),
|
||||
this.options.renderLabel({
|
||||
options: this.options,
|
||||
node,
|
||||
@@ -208,7 +220,11 @@ export const Tags = Node.create<MentionOptions>({
|
||||
}
|
||||
const mergedOptions = {...this.options}
|
||||
|
||||
mergedOptions.HTMLAttributes = mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes)
|
||||
mergedOptions.HTMLAttributes = mergeAttributes(
|
||||
{'data-type': this.name},
|
||||
this.options.HTMLAttributes,
|
||||
HTMLAttributes,
|
||||
)
|
||||
const html = this.options.renderHTML({
|
||||
options: mergedOptions,
|
||||
node,
|
||||
@@ -217,7 +233,11 @@ export const Tags = Node.create<MentionOptions>({
|
||||
if (typeof html === 'string') {
|
||||
return [
|
||||
'span',
|
||||
mergeAttributes({ 'data-type': this.name }, this.options.HTMLAttributes, HTMLAttributes),
|
||||
mergeAttributes(
|
||||
{'data-type': this.name},
|
||||
this.options.HTMLAttributes,
|
||||
HTMLAttributes,
|
||||
),
|
||||
html,
|
||||
]
|
||||
}
|
||||
@@ -226,7 +246,9 @@ export const Tags = Node.create<MentionOptions>({
|
||||
|
||||
renderText({node}) {
|
||||
if (this.options.renderLabel !== undefined) {
|
||||
console.warn('renderLabel is deprecated use renderText and renderHTML instead')
|
||||
console.warn(
|
||||
'renderLabel is deprecated use renderText and renderHTML instead',
|
||||
)
|
||||
return this.options.renderLabel({
|
||||
options: this.options,
|
||||
node,
|
||||
@@ -240,7 +262,8 @@ export const Tags = Node.create<MentionOptions>({
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Backspace: () => this.editor.commands.command(({ tr, state }) => {
|
||||
Backspace: () =>
|
||||
this.editor.commands.command(({tr, state}) => {
|
||||
let isMention = false
|
||||
const {selection} = state
|
||||
const {empty, anchor} = selection
|
||||
@@ -253,7 +276,9 @@ export const Tags = Node.create<MentionOptions>({
|
||||
if (node.type.name === this.name) {
|
||||
isMention = true
|
||||
tr.insertText(
|
||||
this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',
|
||||
this.options.deleteTriggerWithBackspace
|
||||
? ''
|
||||
: this.options.suggestion.char || '',
|
||||
pos,
|
||||
pos + node.nodeSize,
|
||||
)
|
||||
|
||||
@@ -42,9 +42,12 @@ export function findSuggestionMatch({
|
||||
|
||||
if (!tag || tag.length === 0 || tag.length > 64) return null
|
||||
|
||||
const leadingSpaceOffset = fullMatch.startsWith(' ') ? 1 : 0
|
||||
const hashtagOffset = 1
|
||||
|
||||
// The absolute position of the match in the document
|
||||
const from = textFrom + fullMatch.indexOf(tag)
|
||||
const to = from + tag.length + 1
|
||||
const from = textFrom + match.index + leadingSpaceOffset
|
||||
const to = from + tag.length + hashtagOffset
|
||||
|
||||
// If the $position is located within the matched substring, return that range
|
||||
if (from < $position.pos && to >= $position.pos) {
|
||||
@@ -54,7 +57,7 @@ export function findSuggestionMatch({
|
||||
to,
|
||||
},
|
||||
query: tag.replace(TRAILING_PUNCTUATION_REGEX, ''),
|
||||
text: fullMatch,
|
||||
text: fullMatch.replace(/^\s{1}/, ''),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user