npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mention-completer

v1.0.8

Published

A UI-platform-independent library for managing mention-like completion

Downloads

9

Readme

mention-completer

js-standard-style Build Status npm version Dependency Status

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.

HTML Screenshot

var MentionCompleter = require('mention-completer')

var completer = new MentionCompleter({
  patterns: { handle: /(@[\w]+)\b/, hashtag: /(#[\w]+)\b/ },
  getSelectionRange: ...,
  setSelectionRange: ...,
  getValue: ...,
  setValue: ...
})
  
completer
  .on('match', function(match) {
    // Trigger a remote API lookup and expose a UI element here, perhaps.
    // Returns, e.g.:
    //     match = { value:'@usern', type:'handle', range:{start: 7, end: 13} }
  })
  .on('nomatch', function() {
    // Hook into this event to close the menu
  })

// Trigger a check when an input is modified:
$('#my-input-field').on('keyup', completer.checkForMatch.bind(completer) )

// 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: /(@[\w]+)\b/,
  hashtag: /(#[\w]+)\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 each replace 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 each replace event.

Properties

  • .mostRecentMatch: the most recent match. If no match is present, equal to null.

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:

$('#input').on('change', completer.checkForMatch.bind(completer) )

.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.on('match', function(match) {
  currentMatch = match
})

// Result of user action:
mention.replaceMatch(currentMatch, '@suggestedname')

.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}} where value is the queried value of the input and range is the queried selection range.

  • match: Triggered when a completable match is detected. data contains {string, value, type, range:{start,end}} where string is the matched string, value is the match captured by the regex, type is the key of the pattern that was matched, and range contains the integer range of value within string.

  • nomatch: Triggered when no completable match is detected. Perhaps a good place to trigger closing of a suggestion menu.

  • replace: Triggered when replaceWith is explicitly called. data contains the computed replacement, {text, selectionRange:{start,end}} where text contains the text with replacement, and selectionRange contains the post-replacement selection range. If provided, setSelectionRange and setValue 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