prosemirror-suggest
package prosemirror-suggest
class SuggestState
The prosemirror-suggest
state which manages the list of suggesters.
Signature:
export declare class SuggestState
SuggestState.(constructor)
Create the state for the prosemirror-suggest
plugin.
Signature:
constructor(suggesters: Suggester[]);
Parameters:
Parameter | Type | Description |
---|---|---|
suggesters | Suggester[] |
Remarks:
Each suggester must provide a name value which is globally unique since it acts as the identifier.
It is possible to register multiple suggesters with identical char
properties. The matched suggester is based on the specificity of the regex
and the order in which they are passed in. Earlier suggesters are prioritized.
property addIgnored
Ignores the match specified. Until the match is deleted no more onChange
handler will be triggered. It will be like the match doesn't exist.
Signature:
readonly addIgnored: ({ from, name, specific }: AddIgnoredProps) => void;
Remarks:
All we need to ignore is the match character. This means that any further matches from the activation character will be ignored.
property clearIgnored
Removes all the ignored sections of the document. Once this happens suggesters will be able to activate in the previously ignored sections.
Signature:
readonly clearIgnored: (name?: string) => void;
property decorationSet
The set of all decorations.
Signature:
get decorationSet(): DecorationSet;
property findMatchAtPosition
A helper method to check is a match exists for the provided suggester name at the provided position.
Signature:
readonly findMatchAtPosition: ($pos: ResolvedPos, name?: string) => SuggestMatch | undefined;
property findNextTextSelection
Find the next text selection from the current selection.
Signature:
readonly findNextTextSelection: (selection: Selection) => TextSelection | void;
property ignoreNextExit
This sets the next exit to not trigger the exit reason inside the onChange
callback.
This can be useful when you trigger a command, that exists the suggestion match and want to prevent further onChanges from occurring for the currently active suggester.
Signature:
readonly ignoreNextExit: () => void;
property match
Returns the current active suggester state field if one exists
Signature:
get match(): Readonly<SuggestMatch> | undefined;
property removed
True when the most recent change was to remove a mention.
Signature:
get removed(): boolean;
Remarks:
This is needed because sometimes removing a prosemirror Mark
has no effect. Hence we need to keep track of whether it's removed and then later in the apply step check that a removal has happened and reset the handlerMatches
to prevent an infinite loop.
property removeIgnored
Removes a single match character from the ignored decorations.
Signature:
readonly removeIgnored: ({ from, name }: RemoveIgnoredProps) => void;
Remarks:
After this point event handlers will begin to be called again for the match character.
property setMarkRemoved
Sets the removed property to be true.
This is useful when working with marks.
Signature:
readonly setMarkRemoved: () => void;
method addSuggester
Add a new suggest or replace it if it already exists.
Signature:
addSuggester(suggester: Suggester): () => void;
Parameters:
Parameter | Type | Description |
---|---|---|
suggester | Suggester |
Returns:
() => void
method apply
Applies updates to the state to be used within the plugins apply method.
Signature:
apply(props: TransactionProps & EditorStateProps): this;
Parameters:
Parameter | Type | Description |
---|---|---|
props | TransactionProps & EditorStateProps |
Returns:
this
method create
Create an instance of the SuggestState class.
Signature:
static create(suggesters: Suggester[]): SuggestState;
Parameters:
Parameter | Type | Description |
---|---|---|
suggesters | Suggester[] |
Returns:
method createDecorations
Handle the decorations which wrap the mention while it is active and not yet complete.
Signature:
createDecorations(state: EditorState): DecorationSet;
Parameters:
Parameter | Type | Description |
---|---|---|
state | EditorState |
Returns:
DecorationSet
method init
Initialize the SuggestState with a view which is stored for use later.
Signature:
init(view: EditorView): this;
Parameters:
Parameter | Type | Description |
---|---|---|
view | EditorView |
Returns:
this
method removeSuggester
Remove a suggester if it exists.
Signature:
removeSuggester(suggester: Suggester | string): void;
Parameters:
Parameter | Type | Description |
---|---|---|
suggester | Suggester | string |
Returns:
void
method toJSON
Signature:
toJSON(): SuggestMatch | undefined;
Returns:
SuggestMatch | undefined
enum ChangeReason
The potential reason for changes
Signature:
export declare enum ChangeReason
Enumeration Members:
Member | Value | Description |
---|---|---|
JumpBackward | "jump-backward-change" | The user has moved from one suggestion to another suggestion earlier in the document. |
JumpForward | "jump-forward-change" | The user has moved from one suggestion to another suggestion further along in the document. |
Move | "move" | The cursor was moved. |
SelectionInside | "selection-inside" | A change happened to the selection status which was not purely a move. The selection area may have been increased. |
Start | "start" | The user has entered or started a new suggestion. |
Text | "change-character" | A changed happened to the character. This can be addition, deletion or replacement. |
enum ExitReason
The potential reasons for an exit of a mention.
Signature:
export declare enum ExitReason
Enumeration Members:
Member | Value | Description |
---|---|---|
End | "exit-end" | The user has pasted some text with multiple characters or run a command that adds multiple characters.
|
InvalidSplit | "invalid-exit-split" | The user has pasted some text with multiple characters or run a command that adds multiple characters right after the initial multi-character. e.g. In this case it is best to remove the mention completely. |
JumpBackward | "jump-backward-exit" | The user has jumped to another suggestion which occurs before the previous suggestion in the editor. This can happen via a click, a keyboard jump (END) or a custom command. In this case since there is still an active suggestion it will trigger both an onExit and onChange call. |
JumpForward | "jump-forward-exit" | The user has jumped to another suggestion which occurs afterwards in the editor. This can be via a click, a keyboard jump or custom commands. In this case since there is still an active suggestion it will trigger both an onExit and onChange call. |
MoveEnd | "move-end" | User has moved out of the suggestion at the end. This can happen via using arrow keys, but can also be via the suggestion no longer matching as the user types, a mouse click or custom command. All that has changed is the cursor position. |
MoveStart | "move-start" | User has moved out of the suggestion but from the beginning. This can be via the arrow keys but can also be via a mouse click or custom command. All that changed is the cursor position. |
Removed | "delete" | The suggestion has been removed. |
SelectionOutside | "selection-outside" | The user has selected some text outside the current selection, this can trigger an exit. This can be from a triple click to select the line or Ctrl-A to select all. |
Split | "exit-split" | The user has pasted some text with multiple characters or run a command that adds multiple characters somewhere within the active suggestion. e.g.
|
function addSuggester()
Add a new suggester or replace it if the name already exists in the existing configuration.
Will return a function for disposing of the added suggester.
Signature:
export declare function addSuggester(state: EditorState, suggester: Suggester): () => void;
Parameters:
Parameter | Type | Description |
---|---|---|
state | EditorState | |
suggester | Suggester |
Returns:
() => void
function createRegexFromSuggester()
Create a regex expression which evaluate matches directly from the suggester properties.
Signature:
export declare function createRegexFromSuggester(props: CreateRegExpFromSuggesterProps): RegExp;
Parameters:
Parameter | Type | Description |
---|---|---|
props | CreateRegExpFromSuggesterProps |
Returns:
RegExp
function findFromSuggesters()
Find a match for the provided matchers.
Signature:
export declare function findFromSuggesters(props: FindFromSuggestersProps): SuggestMatch | undefined;
Parameters:
Parameter | Type | Description |
---|---|---|
props | FindFromSuggestersProps |
Returns:
SuggestMatch | undefined
function getSuggesterWithDefaults()
Takes the passed through suggester
and adds all the missing default values.
Signature:
export declare function getSuggesterWithDefaults(suggester: Suggester): Required<Suggester>;
Parameters:
Parameter | Type | Description |
---|---|---|
suggester | Suggester |
Returns:
Required<Suggester>
function getSuggestPluginState()
Get the state of the suggest plugin.
Signature:
export declare function getSuggestPluginState(state: EditorState): SuggestState;
Parameters:
Parameter | Type | Description |
---|---|---|
state | EditorState | the editor state. |
Returns:
function ignoreUpdateForSuggest()
Call this method with a transaction to skip the suggest plugin checks for the next update.
This can be used for updates that don't need to trigger a recheck of the suggest state.
Signature:
export declare function ignoreUpdateForSuggest(tr: Transaction): void;
Parameters:
Parameter | Type | Description |
---|---|---|
tr | Transaction |
Returns:
void
function isChangeReason()
Check that that the passed in value is a [[ChangeReason
]].
Signature:
export declare function isChangeReason(value: unknown): value is ChangeReason;
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown |
Returns:
value is ChangeReason
function isExitReason()
Check that the passed in value is an [[ExitReason
]].
Signature:
export declare function isExitReason(value: unknown): value is ExitReason;
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown |
Returns:
value is ExitReason
function isInvalidSplitReason()
Checks that the reason was caused by a split at a point where there is no query.
Signature:
export declare function isInvalidSplitReason(value?: unknown): value is ExitReason.InvalidSplit;
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown | (Optional) |
Returns:
value is ExitReason.InvalidSplit
function isJumpReason()
Checks to see if this is a jump reason.
Signature:
export declare function isJumpReason(map: SuggestReasonMap): map is Required<SuggestReasonMap>;
Parameters:
Parameter | Type | Description |
---|---|---|
map | SuggestReasonMap |
Returns:
map is Required<SuggestReasonMap>
function isRemovedReason()
Checks that the reason was caused by a deletion.
Signature:
export declare function isRemovedReason(value?: unknown): value is ExitReason.Removed;
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown | (Optional) |
Returns:
value is ExitReason.Removed
function isSelectionChangeReason()
Signature:
export declare function isSelectionChangeReason(value: unknown): value is (typeof selectionChangeReasons)[number];
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown |
Returns:
value is (typeof selectionChangeReasons)[number]
function isSelectionExitReason()
An exit which is caused by a change in the selection and no other change in the document.
Signature:
export declare function isSelectionExitReason(value: unknown): value is (typeof selectionExitReasons)[number];
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown |
Returns:
value is (typeof selectionExitReasons)[number]
function isSplitReason()
Checks that the reason passed is a split reason. This typically means that we should default to a partial update / creation of the mention.
Signature:
export declare function isSplitReason(value?: unknown): value is ExitReason.Split;
Parameters:
Parameter | Type | Description |
---|---|---|
value | unknown | (Optional) |
Returns:
value is ExitReason.Split
function isValidMatch()
True when the match is currently active (i.e. it's query has a value)
Signature:
export declare function isValidMatch(match: SuggestMatch | undefined): match is SuggestMatch;
Parameters:
Parameter | Type | Description |
---|---|---|
match | SuggestMatch | undefined |
Returns:
match is SuggestMatch
function markActiveInRange()
Check whether the mark is active anywhere between $from
and $end
.
Currently this is not doing exactly what it should. I've decided to be lazy and only check the following.
- Do any of the requested marks span the entire range using
rangeHasMarks
? - Does the starting position have a mark? - Does the cursor have a mark? - Does the end position have a mark?
In reality I should also check for each position within the range to see if a target mark is active but I won't for now.
Signature:
export declare function markActiveInRange(resolvedRange: Omit<ResolvedRangeWithCursor, '$cursor'>, marks: string[]): boolean;
Parameters:
Parameter | Type | Description |
---|---|---|
resolvedRange | Omit<ResolvedRangeWithCursor, '$cursor'> | |
marks | string[] |
Returns:
boolean
function positionHasMarks()
Check if the provided position has the given marks.
Signature:
export declare function positionHasMarks($pos: ResolvedPos, marks: string[]): boolean;
Parameters:
Parameter | Type | Description |
---|---|---|
$pos | ResolvedPos | |
marks | string[] |
Returns:
boolean
function rangeHasMarks()
Check if the entire matching range from
the start point all the way through to
the end point, has any of the provided marks that span it.
Signature:
export declare function rangeHasMarks(resolvedRange: Omit<ResolvedRangeWithCursor, '$cursor'>, marks: string[]): boolean;
Parameters:
Parameter | Type | Description |
---|---|---|
resolvedRange | Omit<ResolvedRangeWithCursor, '$cursor'> | |
marks | string[] |
Returns:
boolean
function removeSuggester()
Remove a suggester if it exists. Pass in the name or the full suggester object.
Signature:
export declare function removeSuggester(state: EditorState, suggester: Suggester | string): void;
Parameters:
Parameter | Type | Description |
---|---|---|
state | EditorState | |
suggester | Suggester | string |
Returns:
void
function selectionOutsideMatch()
True when the current selection is outside the match.
Signature:
export declare function selectionOutsideMatch(props: Partial<SuggestStateMatchProps> & SelectionProps): boolean;
Parameters:
Parameter | Type | Description |
---|---|---|
props | Partial<SuggestStateMatchProps> & SelectionProps |
Returns:
boolean
function suggest()
This creates a suggest plugin with all the suggesters that you provide.
The priority of the suggesters is the order in which they are passed into this function.
const plugin = suggest(two, one, three)
- Heretwo
will be checked first, thenone
and thenthree
.
Only one suggester can match at any given time. The order and specificity of the regex parameters help determines which suggester will be active.
Signature:
export declare function suggest(...suggesters: Suggester[]): Plugin<SuggestState>;
Parameters:
Parameter | Type | Description |
---|---|---|
suggesters | Suggester[] | a list of suggesters in the order they should be evaluated. |
Returns:
Plugin<SuggestState>
variable DEFAULT_SUGGESTER
The default value for the suggester.
Signature:
DEFAULT_SUGGESTER: PickPartial<Suggester>
variable IGNORE_SUGGEST_META_KEY
This can be added to the meta data of an update to let the suggestion plugin know that it should ignore the update.
Signature:
IGNORE_SUGGEST_META_KEY = "__ignore_prosemirror_suggest_update__"
interface AddIgnoredProps
The parameters needed for the [[SuggestIgnoreProps.addIgnored
]] action method available to the suggest plugin handlers.
Signature:
export interface AddIgnoredProps extends RemoveIgnoredProps
Extends: RemoveIgnoredProps
Remarks:
See: - [[RemoveIgnoredProps
]]
(Some inherited members may not be shown because they are not represented in the documentation.)
property from
The starting point of the match that should be ignored.
Signature:
from: number;
property specific
When false
this will ignore the range for all matching suggesters. When true the ignored suggesters will only be the ones provided by the name.
Signature:
specific?: boolean;
interface CompareMatchProps
A parameter builder interface which compares the previous and next match.
Signature:
export interface CompareMatchProps
Remarks:
It is used within the codebase to determine the kind of change that has occurred (i.e. change or exit see SuggestReasonMap) and the reason for that that change. See ExitReason ChangeReason
property next
The current match
Signature:
next: SuggestMatch;
property prev
The initial match
Signature:
prev: SuggestMatch;
interface DocChangedProps
Signature:
export interface DocChangedProps
property docChanged
true
when there was a changed in the editor content. -false
when only the selection changed.
TODO currently unused. Should be used to differentiate between a cursor exit using the keyboard navigation and a document update change typing invalid character, space, etc...
Signature:
docChanged: boolean;
interface EditorStateProps
A parameter builder interface containing the state
property.
Signature:
export interface EditorStateProps
property state
A snapshot of the prosemirror editor state.
Signature:
state: EditorState;
interface EditorViewProps
A parameter builder interface containing the view
property.
Signature:
export interface EditorViewProps
property view
An instance of the ProseMirror editor view
.
Signature:
view: EditorView;
interface MatchValue
The match value with the full and partial text.
Signature:
export interface MatchValue
Remarks:
For a suggester with a char @
then the following text @ab|c
where |
is the current cursor position will create a queryText with the following signature.
{ "full": "abc", "partial": "ab" }
property full
The complete match independent of the cursor position.
Signature:
full: string;
property partial
This value is a partial match which ends at the position of the cursor within the matching text.
Signature:
partial: string;
interface RangeWithCursor
A range with the cursor attached.
from
- describes the start position of the query, including the activation character. -to
- describes the end position of the match, so the point at which there is no longer an active suggest. -cursor
describes the cursor potion within that match.
Depending on the use case you can decide which is most important in your application.
If you want to replace the whole match regardless of cursor position, then from
and to
are all that you need.
If you want to split the match and only replace up until the cursor while preserving the remaining part of the match, then you can use from
, cursor
for the initial replacement and then take the value between cursor
and to
and append it in whatever way you feel works.
Signature:
export interface RangeWithCursor
property cursor
The current cursor position, which may not be at the end of the full match.
Signature:
cursor: number;
property from
The absolute starting point of the matching string.
Signature:
from: number;
property to
The absolute end of the matching string.
Signature:
to: number;
interface ReasonMatchProps
A parameter builder interface which adds the match property.
Signature:
export interface ReasonMatchProps
Remarks:
This is used to build parameters for Suggester handler methods.
property match
The match with its reason property.
Signature:
match: SuggestMatchWithReason;
interface ReasonProps
A parameter builder interface indicating the reason the handler was called.
Signature:
export interface ReasonProps
property changeReason
The reason for the change. Either this or change reason must have a value..
Signature:
changeReason?: ChangeReason;
property exitReason
The reason for the exit. Either this or the change reason must have a value.
Signature:
exitReason?: ExitReason;
interface RemoveIgnoredProps
The parameters needed for the action method available to the suggest plugin handlers.
Signature:
export interface RemoveIgnoredProps extends Pick<Suggester, 'name'>
Extends: Pick<Suggester, 'name'>
(Some inherited members may not be shown because they are not represented in the documentation.)
property from
The starting point of the match that should be ignored.
Signature:
from: number;
interface ResolvedPosProps
Signature:
export interface ResolvedPosProps
property $pos
A prosemirror resolved pos with provides helpful context methods when working with a position in the editor.
In prosemirror suggest this always uses the lower bound of the text selection.
Signature:
$pos: ResolvedPos;
interface ResolvedRangeWithCursor
Signature:
export interface ResolvedRangeWithCursor
property $cursor
The current cursor position as a [resolved position](https://prosemirror.net/docs/ref/\#model.Resolved\_Positions), which may not be at the end of the full match.
Signature:
$cursor: ResolvedPos;
property $from
The absolute starting point of the matching string as a [resolved position](https://prosemirror.net/docs/ref/\#model.Resolved\_Positions).
Signature:
$from: ResolvedPos;
property $to
The absolute end of the matching string as a [resolved position](https://prosemirror.net/docs/ref/\#model.Resolved\_Positions).
Signature:
$to: ResolvedPos;
interface SelectionProps
Signature:
export interface SelectionProps
property selection
The text editor selection
Signature:
selection: PMState.Selection;
interface SuggestChangeHandlerProps
The parameter passed to the [[Suggester.onChange
]] method. It the properties changeReason
and exitReason
which are available depending on whether this is an exit or change.
Exactly **ONE** will always be available. Unfortunately that's quite hard to model in TypeScript without complicating all dependent types.
Signature:
export interface SuggestChangeHandlerProps extends SuggestMatchWithReason, EditorViewProps, SuggestIgnoreProps, SuggestMarkProps, Pick<Suggester, 'name' | 'char'>
Extends: SuggestMatchWithReason, EditorViewProps, SuggestIgnoreProps, SuggestMarkProps, Pick<Suggester, 'name' | 'char'>
(Some inherited members may not be shown because they are not represented in the documentation.)
property addIgnored
Add a match target to the ignored matches.
Signature:
addIgnored: (props: AddIgnoredProps) => void;
Remarks:
Until the activation character is deleted the onChange
handler will no longer be triggered for the matched character. It will be like the match doesn't exist.
By ignoring the activation character the plugin ensures that any further matches from the activation character will be ignored.
There are a number of use cases for this. You may chose to ignore a match when:
- The user presses the
escape
key to exit your suggestion dropdown. - The user continues typing without selecting any of the options for the selection drop down. - The user clicks outside of the suggesters dropdown.
const suggester = {
onChange: ({ addIgnored, range: { from }, suggester: { char, name } }: SuggestExitHandlerProps) => {
addIgnored({ from, char, name }); // Ignore this suggester
},
}
property changeReason
The reason for the change. Either this or change reason must have a value..
Signature:
changeReason?: ChangeReason;
property clearIgnored
When the name is provided remove all ignored decorations which match the named suggester. Otherwise remove **all** ignored decorations from the document.
Signature:
clearIgnored: (name?: string) => void;
property exitReason
The reason for the exit. Either this or the change reason must have a value.
Signature:
exitReason?: ExitReason;
property ignoreNextExit
Use this method to skip the next onChange
when the reason is an exit.
Signature:
ignoreNextExit: () => void;
Remarks:
This is useful when you manually call a command which applies the suggestion outside of the onChange
handler. When that happens onChange
will still be triggered since the document has now changed. If you don't have the logic set up properly it may rerun your exit logic. This can lead to mismatched transaction errors since the onChange
handler is provided the last active range and query when the reason is an exit, but these values are probably no longer valid.
This helper method can be applied to make life easier. Call it when running a command in a click handler or key binding and you don't have to worry about your onChange
handler being called again and leading to a mismatched transaction error.
property match
The raw regex match which caused this suggester to be triggered.
rawMatch[0]
is always the full match. -rawMatch[1]
is always the matching character (or regex pattern).
To make use of this you can set the [[Suggester.supportedCharacters
]] property to be a regex which included matching capture group segments.
Signature:
match: RegExpExecArray;
property query
Current query of match which doesn't include the activation character.
Signature:
query: MatchValue;
property range
Range of current match; for example @foo|bar
(where | is the cursor) - from
is the start (= 0) - to
is cursor position (= 4) - end
is the end of the match (= 7)
Signature:
range: RangeWithCursor;
property setMarkRemoved
When managing suggesters with marks it is possible to remove a mark without the change reflecting in the prosemirror state. This method should be used when removing a suggestion if you are using prosemirror Marks
to identify the suggestion.
When this method is called, prosemirror-suggest
will handle the removal of the mark in the next state update (during apply).
Signature:
setMarkRemoved: () => void;
property suggester
The suggester to use for finding matches.
Signature:
suggester: Required<Suggester>;
property text
Full text of match including the activation character
Signature:
text: MatchValue;
Remarks:
For a char
of '@'
and query of 'awesome'
text.full
would be '@awesome'
.
property textAfter
The text after full match, up until the end of the text block.
Signature:
textAfter: string;
property textBefore
The text before the full match, up until the beginning of the node.
Signature:
textBefore: string;
property view
An instance of the ProseMirror editor view
.
Signature:
view: EditorView;
interface Suggester
This [[Suggester
]] interface defines all the options required to create a suggestion within your editor.
Signature:
export interface Suggester
Remarks:
The options are passed to the [[suggest
]] method which uses them.
property appendTransaction
Set this to true so that the onChange
handler is called in the appendTransaction
ProseMirror plugin hook instead of the the view update handler.
This tends to work better with updates that are run multiple times while preserving the redo/undo history stack.
Please note this should only be set to true if updates are expected to be synchronous and immediately available. If you're planning on packaging the update into a command which dispatches the update in response to user interaction, then you're better off leaving this as false.
An example of how it's being used is in the autoLink
functionality for the LinkExtension
in remirror. Since autolinking is purely based on configuration and not on user interaction it's possible to create the links automatically within the appendTransaction
hook.
Signature:
appendTransaction?: boolean;
property captureChar
Whether to capture the `char character as the first capture group.
When this is set to true it will be the first matching group with match[1]
.
Signature:
captureChar?: boolean;
property caseInsensitive
Whether the match should be case insensitive and ignore the case. This adds the i
flag to the regex used.
Signature:
caseInsensitive?: boolean;
property char
The activation character(s) to match against.
Signature:
char: RegExp | string;
Remarks:
For example if building a mention plugin you might want to set this to @
. Multi string characters are theoretically supported (although currently untested).
The character does not have to be unique amongst the suggesters and the eventually matched suggester will depend on the order in which the suggesters are added to the plugin.
Please note that when this is a plain string, it is assumed to be a plain string. Which means that it will be matched as it is and **not** as a string representation of RegExp
.
It can also be regex, but the regex support has a few caveats.
- All flags specified will be ignored. - Avoid using
^
to denote the start of line since that can conflict with the [[Suggester.startOfLine
]] value and cause an invalid regex.
property checkNextValidSelection
This is a utility option that may be necessary for you when building editable mentions using prosemirror-suggest
.
By default prosemirror-suggest
searches backwards from the current cursor position to see if any text matches any of the configured suggesters. For the majority of use cases this is perfectly acceptable behaviour.
However, [#639](https://github.com/remirror/remirror/issues/639) shows that it's possible to delete forward and make mentions invalid. Without adding this option, the only solution to this problem would have required, creating a custom plugin to check each state update and see if the next character is still valid.
This method removes this requirement. It is run on every single update where there is a valid text selection after the current cursor position. It makes use of the appendTransaction
ProseMirror plugin hook and provides you with a transaction (tr
) which should be mutated with updates. These updates are added to the updates for the editor and makes it much easier to build history
friendly functionality.
This is called before all onChange
handlers.
Signature:
checkNextValidSelection?: CheckNextValidSelection | null;
property disableDecorations
When true, decorations are not created when this mention is being edited.
Signature:
disableDecorations?: boolean | ShouldDisableDecorations;
property emptySelectionsOnly
Whether this suggester should only be valid for empty selections.
Signature:
emptySelectionsOnly?: boolean;
property ignoredClassName
Set a class for the ignored suggester decoration.
Signature:
ignoredClassName?: string | null;
property ignoredTag
Set a tag for the ignored suggester decoration.
Signature:
ignoredTag?: string;
property invalidMarks
A list of node names which will be marked as invalid.
Signature:
invalidMarks?: string[];
property invalidNodes
A list of node names which will be marked as invalid.
Signature:
invalidNodes?: string[];
property invalidPrefixCharacters
A regex expression used to invalidate the text directly before the match.
Signature:
invalidPrefixCharacters?: RegExp | string | null;
Remarks:
This has preference over the validPrefixCharacters
option and when it is defined only it will be looked at in determining whether a prefix is valid.
property isValidPosition
This is run after the valid
and invalid
node and mark checks regardless of their outcomes and only when the current suggester has found a match at the current position.
It is a method of doing more advanced checking of the resolved position. Perhaps checking the attributes on the marks resolvedRange.$to.marks
, or the checking the attributes of the direct parent node resolvedRange.$to.parent.attrs
to check if something is missing.
Signature:
isValidPosition?: (resolvedRange: ResolvedRangeWithCursor, match: SuggestMatch) => boolean;
property matchOffset
Sets the characters that need to be present after the initial character match before a match is triggered.
Signature:
matchOffset?: number;
Remarks:
For example with char
= @
the following is true.
matchOffset: 0
matches'@'
immediately -matchOffset: 1
matches'@a'
but not'@'
-matchOffset: 2
matches'@ab'
but not'@a'
or'@'
-matchOffset: 3
matches'@abc'
but not'@ab'
or'@a'
or'@'
- And so on...
property multiline
When true support matches across multiple lines.
Signature:
multiline?: boolean;
property name
A unique identifier for the suggester.
Signature:
name: string;
Remarks:
This should be globally unique amongst all suggesters registered with this plugin. The plugin will throw an error if duplicates names are used.
Typically this value will be appended to classes to uniquely identify them amongst the suggesters and even in your own nodes and mark.
property onChange
Called whenever a suggester becomes active or changes in any way.
Signature:
onChange: SuggestChangeHandler;
Remarks:
It receives a parameters object with the changeReason
or exitReason
to let you know whether the change was an exit and what caused the change.
property priority
The priority for this suggester.
A higher number means that this will be added to the list earlier. If you're using this within the context of remirror
you can also use the ExtensionPriority
from the remirror/core
library.
Signature:
priority?: number;
property startOfLine
When set to true, matches will only be recognised at the start of a new line.
Signature:
startOfLine?: boolean;
property suggestClassName
Class name to use for the decoration while the suggester is active.
Signature:
suggestClassName?: string;
property suggestTag
Tag for the prosemirror decoration which wraps an active match.
Signature:
suggestTag?: string;
property supportedCharacters
A regex containing all supported characters when within an active suggester.
Signature:
supportedCharacters?: RegExp | string;
property unicode
When true support matches using Unicode Regex.
Signature:
unicode?: boolean;
property validMarks
A list of node names which will be marked as invalid. This takes priority over invalidMarks
if both properties are present.
By setting this value to the empty array []
, you are telling this [[Suggester
]] to never match if any marks are found.
Signature:
validMarks?: string[] | null;
property validNodes
A list of node names which will be marked as invalid. This takes priority over invalidNodes
if both properties are present.
Setting this to an empty array would mean that this [[Suggester
]] can never match.
Signature:
validNodes?: string[] | null;
property validPrefixCharacters
A regex expression used to validate the text directly before the match.
Signature:
validPrefixCharacters?: RegExp | string;
Remarks:
This will be used when Suggester.invalidPrefixCharacters is not provided.
interface SuggesterProps
Signature:
export interface SuggesterProps
property suggester
The suggester to use for finding matches.
Signature:
suggester: Required<Suggester>;
interface SuggestIgnoreProps
A parameter builder interface describing the ignore methods available to the [[Suggester
]] handlers.
Signature:
export interface SuggestIgnoreProps
property addIgnored
Add a match target to the ignored matches.
Signature:
addIgnored: (props: AddIgnoredProps) => void;
Remarks:
Until the activation character is deleted the onChange
handler will no longer be triggered for the matched character. It will be like the match doesn't exist.
By ignoring the activation character the plugin ensures that any further matches from the activation character will be ignored.
There are a number of use cases for this. You may chose to ignore a match when:
- The user presses the
escape
key to exit your suggestion dropdown. - The user continues typing without selecting any of the options for the selection drop down. - The user clicks outside of the suggesters dropdown.
const suggester = {
onChange: ({ addIgnored, range: { from }, suggester: { char, name } }: SuggestExitHandlerProps) => {
addIgnored({ from, char, name }); // Ignore this suggester
},
}
property clearIgnored
When the name is provided remove all ignored decorations which match the named suggester. Otherwise remove **all** ignored decorations from the document.
Signature:
clearIgnored: (name?: string) => void;
property ignoreNextExit
Use this method to skip the next onChange
when the reason is an exit.
Signature:
ignoreNextExit: () => void;
Remarks:
This is useful when you manually call a command which applies the suggestion outside of the onChange
handler. When that happens onChange
will still be triggered since the document has now changed. If you don't have the logic set up properly it may rerun your exit logic. This can lead to mismatched transaction errors since the onChange
handler is provided the last active range and query when the reason is an exit, but these values are probably no longer valid.
This helper method can be applied to make life easier. Call it when running a command in a click handler or key binding and you don't have to worry about your onChange
handler being called again and leading to a mismatched transaction error.
interface SuggestMarkProps
A 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
.
Signature:
export interface SuggestMarkProps
property setMarkRemoved
When managing suggesters with marks it is possible to remove a mark without the change reflecting in the prosemirror state. This method should be used when removing a suggestion if you are using prosemirror Marks
to identify the suggestion.
When this method is called, prosemirror-suggest
will handle the removal of the mark in the next state update (during apply).
Signature:
setMarkRemoved: () => void;
interface SuggestMatch
Describes the properties of a match which includes range and the text as well as information of the suggester that created the match.
Signature:
export interface SuggestMatch extends SuggesterProps
Extends: SuggesterProps
property match
The raw regex match which caused this suggester to be triggered.
rawMatch[0]
is always the full match. -rawMatch[1]
is always the matching character (or regex pattern).
To make use of this you can set the [[Suggester.supportedCharacters
]] property to be a regex which included matching capture group segments.
Signature:
match: RegExpExecArray;
property query
Current query of match which doesn't include the activation character.
Signature:
query: MatchValue;
property range
Range of current match; for example @foo|bar
(where | is the cursor) - from
is the start (= 0) - to
is cursor position (= 4) - end
is the end of the match (= 7)
Signature:
range: RangeWithCursor;
property suggester
The suggester to use for finding matches.
Signature:
suggester: Required<Suggester>;
property text
Full text of match including the activation character
Signature:
text: MatchValue;
Remarks:
For a char
of '@'
and query of 'awesome'
text.full
would be '@awesome'
.
property textAfter
The text after full match, up until the end of the text block.
Signature:
textAfter: string;
property textBefore
The text before the full match, up until the beginning of the node.
Signature:
textBefore: string;
interface SuggestMatchWithReason
The matching suggester along with the reason, whether it is a changeReason
or an exitReason
.
Signature:
export interface SuggestMatchWithReason extends SuggestMatch, ReasonProps
Extends: SuggestMatch, ReasonProps
property changeReason
The reason for the change. Either this or change reason must have a value..
Signature:
changeReason?: ChangeReason;
property exitReason
The reason for the exit. Either this or the change reason must have a value.
Signature:
exitReason?: ExitReason;
property match
The raw regex match which caused this suggester to be triggered.
rawMatch[0]
is always the full match. -rawMatch[1]
is always the matching character (or regex pattern).
To make use of this you can set the [[Suggester.supportedCharacters
]] property to be a regex which included matching capture group segments.
Signature:
match: RegExpExecArray;
property query
Current query of match which doesn't include the activation character.
Signature:
query: MatchValue;
property range
Range of current match; for example @foo|bar
(where | is the cursor) - from
is the start (= 0) - to
is cursor position (= 4) - end
is the end of the match (= 7)
Signature:
range: RangeWithCursor;
property suggester
The suggester to use for finding matches.
Signature:
suggester: Required<Suggester>;
property text
Full text of match including the activation character
Signature:
text: MatchValue;
Remarks:
For a char
of '@'
and query of 'awesome'
text.full
would be '@awesome'
.
property textAfter
The text after full match, up until the end of the text block.
Signature:
textAfter: string;
property textBefore
The text before the full match, up until the beginning of the node.
Signature:
textBefore: string;
interface SuggestReasonMap
A mapping of the handler matches with their reasons for occurring within the suggest state.
Signature:
export interface SuggestReasonMap
property change
Change reasons for triggering the change handler.
Signature:
change?: SuggestMatchWithReason;
property exit
Exit reasons for triggering the change handler.
Signature:
exit?: SuggestMatchWithReason;
interface SuggestStateMatchProps
A parameter builder interface describing match found by the suggest plugin.
Signature:
export interface SuggestStateMatchProps
property match
The match that will be triggered.
Signature:
match: SuggestMatch;
interface TextProps
Signature:
export interface TextProps
property text
The text to insert or work with.
Signature:
text: string;
interface TransactionProps
A parameter builder interface containing the tr
property.
Signature:
export interface TransactionProps
property tr
The prosemirror transaction
Signature:
tr: Transaction;
type CheckNextValidSelection
A function for checking whether the next selection is valid.
It is called for all registered suggesters before any of the onChange handlers are fired.
Signature:
export type CheckNextValidSelection = ($pos: ResolvedPos, tr: Transaction, matches: {
change?: string;
exit?: string;
}) => Transaction | null | void;
References: ResolvedPos, Transaction
type EditorSchema
Signature:
export type EditorSchema = PMModel.Schema;
type EditorState
Signature:
export type EditorState = PMState.EditorState;
type EditorView
Signature:
export type EditorView = PMView.EditorView;
type MakeOptional
Makes specified keys of an interface optional while the rest stay the same.
Signature:
export type MakeOptional<Type extends object, Keys extends keyof Type> = Omit<Type, Keys> & {
[Key in Keys]+?: Type[Key];
};
type ProsemirrorNode
Signature:
export type ProsemirrorNode = PMModel.Node;
type ResolvedPos
Signature:
export type ResolvedPos = PMModel.ResolvedPos;
type ShouldDisableDecorations
A function that can be used to determine whether the decoration should be set or not.
Signature:
export type ShouldDisableDecorations = (state: EditorState, match: Readonly<SuggestMatch>) => boolean;
References: EditorState, SuggestMatch
type SuggestChangeHandler
The type signature of the onChange
handler method.
Signature:
export type SuggestChangeHandler = (changeDetails: SuggestChangeHandlerProps, tr: Transaction) => void;
References: SuggestChangeHandlerProps, Transaction
type Transaction
Signature:
export type Transaction = PMState.Transaction;