mention-completer
A UI-platform-independent module for managing mention-like completion
Introduction
This module implements an EventEmitter
object which uses provided regexes to detect and replace @username- or #hashtag-like patterns in a (platform-independent) input field. The entity it interacts with must only have a value, a selection range, and presumably its own UI with which the user may select a completion.
It exists because I found myself working with React Native, implementing the gory details of mention detection and replacement. There's no shortage of HTML-based UI widgets that implement mention detection and completion, but all I needed was a platform-independent utility that would handle the dirty work, leaving me free to hook up the rest trivially.
Installation
$ npm install mention-completer
Example
For a live HTML-based example, see here. Note that the code consists almost entirely of connecting the text field.
var MentionCompleter = var completer = patterns: handle: /\b/ hashtag: /\b/ getSelectionRange: ... setSelectionRange: ... getValue: ... setValue: ... completer // Trigger a check when an input is modified: // 1) User types "hello, @usern"//// 2) Your code exposes a UI completion selector and calls 'replaceMatch'// based on user input, e.g.://// completer.replaceMatch( match, '@username' )//// 3) If setValue and setSelectionRange are provided, they are triggered// automatically with the inserted match. Otherwise you may use the// 'replace' event to trigger them manually.
API
Constructor
MentionCompleter(options)
Constructor for a new mention completer. Note that all get/set callbacks function in receive a callback with which they must return their result using the format callback(err, result)
. Option parameters are:
patterns
: An associative array of pattern names and regexes. Recommended patterns are:
patterns: handle: /\b/ hashtag: /\b/
-
getValue
:function( callback(err,value) )
: A callback that queries the current text field value. It may execute the callback either synchronously or asynchronously with its resulting value. -
setValue
:function( value )
(optional): A callback that inserts the result after replacement. If provided, is triggered automatically on eachreplace
event. -
getSelectionRange
:function( callback(err, {start, end}) )
: A callback that queries the selection range and returns a range with format{start, end}
. -
setSelectionRange
:function( {start, end} )
(optional): A callback that sets the selection range. If provided, is automatically called on eachreplace
event.
Properties
.mostRecentMatch
: the most recent match. If no match is present, equal tonull
.
Methods
.checkForMatch()
Check for a completable match. Uses getSelectionRange
and getValue
to query the range and value. Emits a match
event if a match is present and nomatch
otherwise. You must hook this up automatically. A simple case is:
.replaceMatch( {string, range: {start,end}}, text )
Replaces a match with text
. The format of the first argument matches the value provided with the match
event. Note that for consistency, if replaceMatch
is triggered before a check resulting from new input completes, the value of the text field at the time of the check will be used. In reality, the delay to get the value and selection range is expected to be extremely short (synchronous or very nearly so) compared to the time between input events (100ms?). A simple use-case would be:
var currentMatch mention // Result of user action:mention
.on(eventName, callback(data))
Along with all other EventEmitter
methods, on
may be used to hook into any event. Note that these events are used internally so that .off
may break functionality unless only a specific callback is detached.
Events
-
check
: Triggered just before the field is checked for a match.data
contains{value, range:{start,end}}
wherevalue
is the queried value of the input andrange
is the queried selection range. -
match
: Triggered when a completable match is detected.data
contains{string, value, type, range:{start,end}}
wherestring
is the matched string,value
is the match captured by the regex, type is the key of the pattern that was matched, andrange
contains the integer range ofvalue
withinstring
. -
nomatch
: Triggered when no completable match is detected. Perhaps a good place to trigger closing of a suggestion menu. -
replace
: Triggered whenreplaceWith
is explicitly called.data
contains the computed replacement,{text, selectionRange:{start,end}}
wheretext
contains the text with replacement, andselectionRange
contains the post-replacement selection range. If provided,setSelectionRange
andsetValue
will update the input value. -
error
: Triggered when something goes wrong.data
contains a string message.
Testing
This module uses Standard JS style. To test, run
$ npm run test
Building
To bundle a browserified (output in dist/bundle.js
), run
$ npm install -g browserify$ npm run bundle
License
ISC License, (c) 2015 Ricky Reusser