Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

prosemirror-suggest

Package Overview
Dependencies
Maintainers
1
Versions
273
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prosemirror-suggest

Primitives for building your prosemirror suggestion and autocomplete functionality

  • 0.6.4-ci.1573124774.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
41K
decreased by-6.17%
Maintainers
1
Weekly downloads
 
Created
Source

prosemirror-suggest

npm bundle size (scoped) npm

Primitives for building your prosemirror suggestion and autocomplete functionality.

The problem

You want to create a plugin for your prosemirror editor that responds to an activation character to create suggestions or options or actions for the user. Doing this from scratch can be difficult.

This solution

prosemirror-suggest provides the suggestion primitives needed for building this functionality into your editor. You might be building user mentions, emoji search, an actions dropdown or anything that extracts a query from the editor after the activation character(s).

This implementation doesn't attempt to be magical. There's still a lot of work that goes into setting up your configuration. However, with this toolkit, you you will be building on a well-tested foundation with a structured API.

Installation

prosemirror-view is a peer dependency of prosemirror-suggest and needs to be installed as well.

yarn add prosemirror-suggest prosemirror-view

Getting Started

prosemirror-suggest uses configuration objects called Suggester's to define the behaviour of the suggestions you create. By calling the exported suggest method with all required Suggester's the functionality is added to the editor in one plugin.

In the following example we're creating an emoji suggestion plugin that responds to the colon character with a query and presents a list of matching emojis based on the query typed so far.

import { Suggester, suggest } from 'prosemirror-suggest';

const maxResults = 10;
let selectedIndex = 0;
let emojiList: string[] = [];
let showSuggestions = false;

const suggestEmojis: Suggester = {
  // By default decorations are used to highlight the currently matched
  // suggestion in the dom.
  // In this example we don't need decorations (in fact they cause problems when the
  // emoji string replaces the query text in the dom).
  noDecorations: true,
  char: ':', // The character to match against
  name: 'emoji-suggestion', // a unique name
  appendText: '', // Text to append to the created match

  // Keybindings are similar to prosemirror keymaps with a few extra niceties.
  // The key identifier can also include modifiers (e.g.) `Cmd-Space: () => false`
  // Return true to prevent any further keyboard handlers from running.
  keyBindings: {
    ArrowUp: () => {
      selectedIndex = rotateSelectionBackwards(selectedIndex, emojiList.length);
    },
    ArrowDown: () => {
      selectedIndex = rotateSelectionForwards(selectedIndex, emojiList.length);
    },
    Enter: ({ command }) => {
      if (showSuggestions) {
        command(emojiList[selectedIndex]);
      }
    },
    Esc: () => {
      showSuggestions = false;
    },
  },

  onChange: params => {
    const query = params.query.full;
    emojiList = sortEmojiMatches({ query, maxResults });
    selectedIndex = 0;
    showSuggestions = true;
  },

  onExit: () => {
    showSuggestions = false;
    emojiList = [];
    selectedIndex = 0;
  },

  // Create a  function that is passed into the change, exit and keybinding handlers.
  // This is useful when these handlers are called in a different part of the app.
  createCommand: ({ match, view }) => {
    return (emoji, skinVariation) => {
      if (!emoji) {
        throw new Error('An emoji is required when calling the emoji suggestions command');
      }

      const tr = view.state.tr;
      const { from, end: to } = match.range;
      tr.insertText(emoji, from, to);
      view.dispatch(tr);
    };
  },
};

// Create the plugin with the above configuration. It also supports multiple plugins being added.
const suggestionPlugin = suggest(suggestEmojis);

// Include the plugin in the created editor state.
const state = EditorState.create({ schema, plugins: [suggestionPlugin] });

You can see this example brought to life in the remirror codebase under the @remirror/extension-emoji and the @remirror/extension-mention packages.

The following examples are available for you to try out on the docs site

Search emoji on : key

The emojis are inserted as plain text. It’s up to you whether you insert the emoji as a node, mark or plaintext.

A gif showing emoji being inserted after typing the colon (:) key. First a laughing emoji then a heart and finally the poop emoji

Editable mention on @ key

Each mention is a mark that wraps the mentioned text with a spec property of inclusive: false

A gif showing mentions being suggested as the user types with editing supported


Core API

suggest

This creates a suggestion plugin with all the suggestions provided.

Signature:

suggest: <GSchema extends import("prosemirror-model").Schema<string, string> = any>(...suggesters: Suggester<import("@remirror/core-types").AnyFunction<void>>[]) => Plugin<SuggestState<any>, GSchema>

The priority of the suggestions is the order in which they are passed into this function.

const plugin = suggest(two, one, three);

In the above example two will be checked first, then one and then three.

Only one suggestion can match at any given time. The order and specificity of the regex parameters help determines which suggestion will be active.


Suggester

This Suggester interface defines all the options required to create a suggestion within your editor.

Signature:

export interface Suggester<GCommand extends AnyFunction<void> = AnyFunction<void>>
Properties
PropertyTypeDescription
appendTextstringText to append after the mention has been added.
charstringThe activation character(s) to match against.
ignoredClassNamestringSet a class for the ignored suggestion decoration.
ignoredTagstringSet a tag for the ignored suggestion decoration.
invalidPrefixCharactersRegExp | stringA regex expression used to invalidate the text directly before the match.
keyBindingsSuggestKeyBindingMap<GCommand>An object that describes how certain key bindings should be handled.
matchOffsetnumberSets the characters that need to be present after the initial character match before a match is triggered.
namestringA unique identifier for the suggester.
noDecorationsbooleanWhen true, decorations are not created when this mention is being edited..
startOfLinebooleanWhether to only match from the start of the line
suggestClassNamestringClass name to use for the decoration (while the suggestion is still being written)
suggestTagstringTag for the prosemirror decoration which wraps an active match.
supportedCharactersRegExp | stringA regex containing all supported characters when within a suggestion.
validPrefixCharactersRegExp | stringA regex expression used to validate the text directly before the match.
Methods
MethodDescription
createCommand(params)Create the suggested actions which are made available to the onExit and ononChange handlers.
onChange(params)Called whenever a suggestion becomes active or changes in anyway.
onCharacterEntry(params)Called for each character entry and can be used to disable certain characters.
onExit(params)Called when a suggestion is exited with the pre-exit match value.

The options are passed to the suggest method which uses them.


Package API

Enumerations

EnumerationDescription
ChangeReasonThe potential reason for changes
ExitReasonThe potential reasons for an exit of a mention.

Interfaces

InterfaceDescription
AddIgnoredParamsThe parameters needed for the SuggestIgnoreParams.addIgnored() action method available to the suggest plugin handlers.
CompareMatchParamsA parameter builder interface which compares the previous and next match.
CreateSuggestCommandParamsThe parameters passed into the createSuggest suggester property.
FromToEndParamsA parameter builder interface describing a from/to/end range.
KeyboardEventParamsA parameter builder interface describing the event which triggers the keyboard event handler.
MatchValueThe match value with the full and partial text.
OnKeyDownParamsThe parameters required by the .
ReasonMatchParamsA parameter builder interface which adds the match property.
ReasonParamsA parameter builder interface indicating the reason the handler was called.
RemoveIgnoredParamsThe parameters needed for the action method available to the suggest plugin handlers.
SuggestCallbackParams
SuggestChangeHandlerParamsThe parameters passed to the Suggester.onChange() method.
SuggestCharacterEntryParamsThe parameters passed to the Suggester.onCharacterEntry() method.
SuggestCommandParamsA parameter builder interface which adds the command property.
SuggesterThis Suggester interface defines all the options required to create a suggestion within your editor.
SuggesterParams
SuggestExitHandlerParamsThe parameters passed to the Suggester.onExit() method.
SuggestIgnoreParamsA parameter builder interface describing the ignore methods available to the Suggester handlers.
SuggestKeyBindingParamsThe parameters required by the SuggestKeyBinding method.
SuggestMarkParamsA special parameter needed when creating editable suggester using prosemirror Marks. The method should be called when removing a suggestion that was identified by a prosemirror Mark.
SuggestReasonMapA mapping of the handler matches with their reasons for occurring within the suggest state.
SuggestStateMatchDescribes the properties of a match which includes range and the text as well as information of the suggester that created the match.
SuggestStateMatchParamsA parameter builder interface describing match found by the suggest plugin.
SuggestStateMatchReason

Variables

VariableDescription
createRegexFromSuggesterCreate a regex expression to evaluate matches directly from the suggester properties.
DEFAULT_SUGGEST_ACTIONS
DEFAULT_SUGGESTER
escapeChar
getRegexPrefixFind regex prefix when depending on whether the mention only supports the start of a line or not
getSuggestPluginStateGet the state of the suggest plugin.
isChangeIs this a change in the current suggestion (added or deleted characters)?
isChangeReason
isEntryAre we entering a new suggestion?
isExitAre we exiting a suggestion?
isExitReasonCheck that the passed in value is an ExitReason
isInvalidSplitReasonChecks that the reason was caused by a split at a point where there is no query.
isJumpIs this a jump from one suggestion to another?
isJumpReasonChecks to see if this is a jump reason.
isMoveHas the cursor moved within the current suggestion (added or deleted characters)?
isRemovedReasonChecks that the reason was caused by a deletion.
isSplitReasonChecks that the reason passed is a split reason. This typically means that we should default to a partial update / creation of the mention.
isValidMatchTrue when the match is currently active (i.e. it's query has a value)
regexToStringConvert a RegExp into a string
selectionOutsideMatchTrue when the current selection is outside the match.
suggestThis creates a suggestion plugin with all the suggestions provided.

Type Aliases

Type AliasDescription
SuggestKeyBindingA method for performing actions when a certain key / pattern is pressed.
SuggestKeyBindingMapThe keybindings shape for the Suggester.keyBindings property.
SuggestReplacementTypeDetermines whether to replace the full match or the partial match (up to the cursor position).

FAQs

Package last updated on 07 Nov 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc