{"version":3,"sources":["../src/index.ts","../src/suggestion.ts","../src/findSuggestionMatch.ts"],"sourcesContent":["import { Suggestion } from './suggestion.js'\n\nexport * from './findSuggestionMatch.js'\nexport * from './suggestion.js'\n\nexport default Suggestion\n","import type { Editor, Range } from '@tiptap/core'\nimport type { EditorState } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\nimport { findSuggestionMatch as defaultFindSuggestionMatch } from './findSuggestionMatch.js'\n\nexport interface SuggestionOptions<I = any, TSelected = any> {\n  /**\n   * The plugin key for the suggestion plugin.\n   * @default 'suggestion'\n   * @example 'mention'\n   */\n  pluginKey?: PluginKey\n\n  /**\n   * The editor instance.\n   * @default null\n   */\n  editor: Editor\n\n  /**\n   * The character that triggers the suggestion.\n   * @default '@'\n   * @example '#'\n   */\n  char?: string\n\n  /**\n   * Allow spaces in the suggestion query. Not compatible with `allowToIncludeChar`. Will be disabled if `allowToIncludeChar` is set to `true`.\n   * @default false\n   * @example true\n   */\n  allowSpaces?: boolean\n\n  /**\n   * Allow the character to be included in the suggestion query. Not compatible with `allowSpaces`.\n   * @default false\n   */\n  allowToIncludeChar?: boolean\n\n  /**\n   * Allow prefixes in the suggestion query.\n   * @default [' ']\n   * @example [' ', '@']\n   */\n  allowedPrefixes?: string[] | null\n\n  /**\n   * Only match suggestions at the start of the line.\n   * @default false\n   * @example true\n   */\n  startOfLine?: boolean\n\n  /**\n   * The tag name of the decoration node.\n   * @default 'span'\n   * @example 'div'\n   */\n  decorationTag?: string\n\n  /**\n   * The class name of the decoration node.\n   * @default 'suggestion'\n   * @example 'mention'\n   */\n  decorationClass?: string\n\n  /**\n   * Creates a decoration with the provided content.\n   * @param decorationContent - The content to display in the decoration\n   * @default \"\" - Creates an empty decoration if no content provided\n   */\n  decorationContent?: string\n\n  /**\n   * The class name of the decoration node when it is empty.\n   * @default 'is-empty'\n   * @example 'is-empty'\n   */\n  decorationEmptyClass?: string\n\n  /**\n   * A function that is called when a suggestion is selected.\n   * @param props The props object.\n   * @param props.editor The editor instance.\n   * @param props.range The range of the suggestion.\n   * @param props.props The props of the selected suggestion.\n   * @returns void\n   * @example ({ editor, range, props }) => { props.command(props.props) }\n   */\n  command?: (props: { editor: Editor; range: Range; props: TSelected }) => void\n\n  /**\n   * A function that returns the suggestion items in form of an array.\n   * @param props The props object.\n   * @param props.editor The editor instance.\n   * @param props.query The current suggestion query.\n   * @returns An array of suggestion items.\n   * @example ({ editor, query }) => [{ id: 1, label: 'John Doe' }]\n   */\n  items?: (props: { query: string; editor: Editor }) => I[] | Promise<I[]>\n\n  /**\n   * The render function for the suggestion.\n   * @returns An object with render functions.\n   */\n  render?: () => {\n    onBeforeStart?: (props: SuggestionProps<I, TSelected>) => void\n    onStart?: (props: SuggestionProps<I, TSelected>) => void\n    onBeforeUpdate?: (props: SuggestionProps<I, TSelected>) => void\n    onUpdate?: (props: SuggestionProps<I, TSelected>) => void\n    onExit?: (props: SuggestionProps<I, TSelected>) => void\n    onKeyDown?: (props: SuggestionKeyDownProps) => boolean\n  }\n\n  /**\n   * A function that returns a boolean to indicate if the suggestion should be active.\n   * @param props The props object.\n   * @returns {boolean}\n   */\n  allow?: (props: { editor: Editor; state: EditorState; range: Range; isActive?: boolean }) => boolean\n  findSuggestionMatch?: typeof defaultFindSuggestionMatch\n}\n\nexport interface SuggestionProps<I = any, TSelected = any> {\n  /**\n   * The editor instance.\n   */\n  editor: Editor\n\n  /**\n   * The range of the suggestion.\n   */\n  range: Range\n\n  /**\n   * The current suggestion query.\n   */\n  query: string\n\n  /**\n   * The current suggestion text.\n   */\n  text: string\n\n  /**\n   * The suggestion items array.\n   */\n  items: I[]\n\n  /**\n   * A function that is called when a suggestion is selected.\n   * @param props The props object.\n   * @returns void\n   */\n  command: (props: TSelected) => void\n\n  /**\n   * The decoration node HTML element\n   * @default null\n   */\n  decorationNode: Element | null\n\n  /**\n   * The function that returns the client rect\n   * @default null\n   * @example () => new DOMRect(0, 0, 0, 0)\n   */\n  clientRect?: (() => DOMRect | null) | null\n}\n\nexport interface SuggestionKeyDownProps {\n  view: EditorView\n  event: KeyboardEvent\n  range: Range\n}\n\nexport const SuggestionPluginKey = new PluginKey('suggestion')\n\n/**\n * This utility allows you to create suggestions.\n * @see https://tiptap.dev/api/utilities/suggestion\n */\nexport function Suggestion<I = any, TSelected = any>({\n  pluginKey = SuggestionPluginKey,\n  editor,\n  char = '@',\n  allowSpaces = false,\n  allowToIncludeChar = false,\n  allowedPrefixes = [' '],\n  startOfLine = false,\n  decorationTag = 'span',\n  decorationClass = 'suggestion',\n  decorationContent = '',\n  decorationEmptyClass = 'is-empty',\n  command = () => null,\n  items = () => [],\n  render = () => ({}),\n  allow = () => true,\n  findSuggestionMatch = defaultFindSuggestionMatch,\n}: SuggestionOptions<I, TSelected>) {\n  let props: SuggestionProps<I, TSelected> | undefined\n  const renderer = render?.()\n\n  const plugin: Plugin<any> = new Plugin({\n    key: pluginKey,\n\n    view() {\n      return {\n        update: async (view, prevState) => {\n          const prev = this.key?.getState(prevState)\n          const next = this.key?.getState(view.state)\n\n          // See how the state changed\n          const moved = prev.active && next.active && prev.range.from !== next.range.from\n          const started = !prev.active && next.active\n          const stopped = prev.active && !next.active\n          const changed = !started && !stopped && prev.query !== next.query\n\n          const handleStart = started || (moved && changed)\n          const handleChange = changed || moved\n          const handleExit = stopped || (moved && changed)\n\n          // Cancel when suggestion isn't active\n          if (!handleStart && !handleChange && !handleExit) {\n            return\n          }\n\n          const state = handleExit && !handleStart ? prev : next\n          const decorationNode = view.dom.querySelector(`[data-decoration-id=\"${state.decorationId}\"]`)\n\n          props = {\n            editor,\n            range: state.range,\n            query: state.query,\n            text: state.text,\n            items: [],\n            command: commandProps => {\n              return command({\n                editor,\n                range: state.range,\n                props: commandProps,\n              })\n            },\n            decorationNode,\n            // virtual node for positioning\n            // this can be used for building popups without a DOM node\n            clientRect: decorationNode\n              ? () => {\n                  // because of `items` can be asynchrounous we’ll search for the current decoration node\n                  const { decorationId } = this.key?.getState(editor.state) // eslint-disable-line\n                  const currentDecorationNode = view.dom.querySelector(`[data-decoration-id=\"${decorationId}\"]`)\n\n                  return currentDecorationNode?.getBoundingClientRect() || null\n                }\n              : null,\n          }\n\n          if (handleStart) {\n            renderer?.onBeforeStart?.(props)\n          }\n\n          if (handleChange) {\n            renderer?.onBeforeUpdate?.(props)\n          }\n\n          if (handleChange || handleStart) {\n            props.items = await items({\n              editor,\n              query: state.query,\n            })\n          }\n\n          if (handleExit) {\n            renderer?.onExit?.(props)\n          }\n\n          if (handleChange) {\n            renderer?.onUpdate?.(props)\n          }\n\n          if (handleStart) {\n            renderer?.onStart?.(props)\n          }\n        },\n\n        destroy: () => {\n          if (!props) {\n            return\n          }\n\n          renderer?.onExit?.(props)\n        },\n      }\n    },\n\n    state: {\n      // Initialize the plugin's internal state.\n      init() {\n        const state: {\n          active: boolean\n          range: Range\n          query: null | string\n          text: null | string\n          composing: boolean\n          decorationId?: string | null\n        } = {\n          active: false,\n          range: {\n            from: 0,\n            to: 0,\n          },\n          query: null,\n          text: null,\n          composing: false,\n        }\n\n        return state\n      },\n\n      // Apply changes to the plugin state from a view transaction.\n      apply(transaction, prev, _oldState, state) {\n        const { isEditable } = editor\n        const { composing } = editor.view\n        const { selection } = transaction\n        const { empty, from } = selection\n        const next = { ...prev }\n\n        next.composing = composing\n\n        // We can only be suggesting if the view is editable, and:\n        //   * there is no selection, or\n        //   * a composition is active (see: https://github.com/ueberdosis/tiptap/issues/1449)\n        if (isEditable && (empty || editor.view.composing)) {\n          // Reset active state if we just left the previous suggestion range\n          if ((from < prev.range.from || from > prev.range.to) && !composing && !prev.composing) {\n            next.active = false\n          }\n\n          // Try to match against where our cursor currently is\n          const match = findSuggestionMatch({\n            char,\n            allowSpaces,\n            allowToIncludeChar,\n            allowedPrefixes,\n            startOfLine,\n            $position: selection.$from,\n          })\n          const decorationId = `id_${Math.floor(Math.random() * 0xffffffff)}`\n\n          // If we found a match, update the current state to show it\n          if (\n            match &&\n            allow({\n              editor,\n              state,\n              range: match.range,\n              isActive: prev.active,\n            })\n          ) {\n            next.active = true\n            next.decorationId = prev.decorationId ? prev.decorationId : decorationId\n            next.range = match.range\n            next.query = match.query\n            next.text = match.text\n          } else {\n            next.active = false\n          }\n        } else {\n          next.active = false\n        }\n\n        // Make sure to empty the range if suggestion is inactive\n        if (!next.active) {\n          next.decorationId = null\n          next.range = { from: 0, to: 0 }\n          next.query = null\n          next.text = null\n        }\n\n        return next\n      },\n    },\n\n    props: {\n      // Call the keydown hook if suggestion is active.\n      handleKeyDown(view, event) {\n        const { active, range } = plugin.getState(view.state)\n\n        if (!active) {\n          return false\n        }\n\n        return renderer?.onKeyDown?.({ view, event, range }) || false\n      },\n\n      // Setup decorator on the currently active suggestion.\n      decorations(state) {\n        const { active, range, decorationId, query } = plugin.getState(state)\n\n        if (!active) {\n          return null\n        }\n\n        const isEmpty = !query?.length\n        const classNames = [decorationClass]\n\n        if (isEmpty) {\n          classNames.push(decorationEmptyClass)\n        }\n\n        return DecorationSet.create(state.doc, [\n          Decoration.inline(range.from, range.to, {\n            nodeName: decorationTag,\n            class: classNames.join(' '),\n            'data-decoration-id': decorationId,\n            'data-decoration-content': decorationContent,\n          }),\n        ])\n      },\n    },\n  })\n\n  return plugin\n}\n","import type { Range } from '@tiptap/core'\nimport { escapeForRegEx } from '@tiptap/core'\nimport type { ResolvedPos } from '@tiptap/pm/model'\n\nexport interface Trigger {\n  char: string\n  allowSpaces: boolean\n  allowToIncludeChar: boolean\n  allowedPrefixes: string[] | null\n  startOfLine: boolean\n  $position: ResolvedPos\n}\n\nexport type SuggestionMatch = {\n  range: Range\n  query: string\n  text: string\n} | null\n\nexport function findSuggestionMatch(config: Trigger): SuggestionMatch {\n  const { char, allowSpaces: allowSpacesOption, allowToIncludeChar, allowedPrefixes, startOfLine, $position } = config\n\n  const allowSpaces = allowSpacesOption && !allowToIncludeChar\n\n  const escapedChar = escapeForRegEx(char)\n  const suffix = new RegExp(`\\\\s${escapedChar}$`)\n  const prefix = startOfLine ? '^' : ''\n  const finalEscapedChar = allowToIncludeChar ? '' : escapedChar\n  const regexp = allowSpaces\n    ? new RegExp(`${prefix}${escapedChar}.*?(?=\\\\s${finalEscapedChar}|$)`, 'gm')\n    : new RegExp(`${prefix}(?:^)?${escapedChar}[^\\\\s${finalEscapedChar}]*`, 'gm')\n\n  const text = $position.nodeBefore?.isText && $position.nodeBefore.text\n\n  if (!text) {\n    return null\n  }\n\n  const textFrom = $position.pos - text.length\n  const match = Array.from(text.matchAll(regexp)).pop()\n\n  if (!match || match.input === undefined || match.index === undefined) {\n    return null\n  }\n\n  // JavaScript doesn't have lookbehinds. This hacks a check that first character\n  // is a space or the start of the line\n  const matchPrefix = match.input.slice(Math.max(0, match.index - 1), match.index)\n  const matchPrefixIsAllowed = new RegExp(`^[${allowedPrefixes?.join('')}\\0]?$`).test(matchPrefix)\n\n  if (allowedPrefixes !== null && !matchPrefixIsAllowed) {\n    return null\n  }\n\n  // The absolute position of the match in the document\n  const from = textFrom + match.index\n  let to = from + match[0].length\n\n  // Edge case handling; if spaces are allowed and we're directly in between\n  // two triggers\n  if (allowSpaces && suffix.test(text.slice(to - 1, to + 1))) {\n    match[0] += ' '\n    to += 1\n  }\n\n  // If the $position is located within the matched substring, return that range\n  if (from < $position.pos && to >= $position.pos) {\n    return {\n      range: {\n        from,\n        to,\n      },\n      query: match[0].slice(char.length),\n      text: match[0],\n    }\n  }\n\n  return null\n}\n"],"mappings":"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","names":["findSuggestionMatch","_a"]}