Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/i-like-robots/react-tags
⚛️ Legacy repo for the fantastically simple tagging component for your React projects (legacy repo)
https://github.com/i-like-robots/react-tags
autocomplete preact preact-components react react-component tagging
Last synced: 3 days ago
JSON representation
⚛️ Legacy repo for the fantastically simple tagging component for your React projects (legacy repo)
- Host: GitHub
- URL: https://github.com/i-like-robots/react-tags
- Owner: i-like-robots
- License: mit
- Created: 2016-02-15T16:48:10.000Z (almost 9 years ago)
- Default Branch: main
- Last Pushed: 2024-06-19T14:57:39.000Z (6 months ago)
- Last Synced: 2024-10-29T17:32:05.626Z (about 2 months ago)
- Topics: autocomplete, preact, preact-components, react, react-component, tagging
- Language: JavaScript
- Homepage: http://i-like-robots.github.io/react-tags
- Size: 5.74 MB
- Stars: 457
- Watchers: 8
- Forks: 170
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome - i-like-robots/react-tags - ⚛️ Legacy repo for the fantastically simple tagging component for your React projects (legacy repo) (JavaScript)
README
# React Tag Autocomplete
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/i-like-robots/react-tags/blob/main/LICENSE) ![build status](https://github.com/i-like-robots/react-tags/actions/workflows/test.yml/badge.svg?branch=main) [![Coverage Status](https://coveralls.io/repos/github/i-like-robots/react-tags/badge.svg?branch=main)](https://coveralls.io/github/i-like-robots/react-tags?branch=main) [![npm version](https://img.shields.io/npm/v/react-tag-autocomplete/legacy.svg?style=flat)](https://www.npmjs.com/package/react-tag-autocomplete)
React Tag Autocomplete is a simple tagging component ready to drop in your React projects. Originally based on the [React Tags project](http://prakhar.me/react-tags/example) by Prakhar Srivastav this version removes the drag-and-drop re-ordering functionality, adds appropriate roles and ARIA states and introduces a resizing text input. [View demo](http://i-like-robots.github.io/react-tags/).
![Screenshot of React Tag Autocomplete](https://cloud.githubusercontent.com/assets/271645/25478773/54aa2bbe-2b3a-11e7-95cf-d419f3c24418.png)
**_Please note:_ This repository is for v6 and older versions of this component. For later releases, compatible with React v18+, please go to [the new repository](https://github.com/i-like-robots/react-tag-autocomplete).**
## Installation
This is a [Node.js] module available through the [npm] registry. Before installing, download and install Node.js.
Installation is done using the [npm install] command:
```
npm install --save react-tag-autocomplete@legacy
```[Node.js]: https://nodejs.org/en/
[npm]: https://www.npmjs.com/
[npm install]: https://docs.npmjs.com/getting-started/installing-npm-packages-locally## Usage
Here's a sample implementation that initializes the component with an empty list of `tags` and a pre-populated list of `suggestions`. For further customization details, see [options](#options).
```js
import React, { useCallback, useRef, useState } from 'react'
import ReactTags from 'react-tag-autocomplete'function App () {
const [tags, setTags] = useState([])const [suggestions, setSuggestions] = useState([
{ id: 1, name: "Apples" },
{ id: 2, name: "Pears" },
{ id: 3, name: "Bananas" },
{ id: 4, name: "Mangos" },
{ id: 5, name: "Lemons" },
{ id: 6, name: "Apricots" }
])const reactTags = useRef()
const onDelete = useCallback((tagIndex) => {
setTags(tags.filter((_, i) => i !== tagIndex))
}, [tags])const onAddition = useCallback((newTag) => {
setTags([...tags, newTag])
}, [tags])return (
)
}
```### Options
- [`id`](#id-optional)
- [`tags`](#tags-optional)
- [`suggestions`](#suggestions-optional)
- [`suggestionsFilter`](#suggestionsfilter-optional)
- [`suggestionsTransform`](#suggestionsTransform-optional)
- [`placeholderText`](#placeholdertext-optional)
- [`ariaLabelText`](#arialabeltext-optional)
- [`removeButtonText`](#removeButtontext-optional)
- [`noSuggestionsText`](#noSuggestionsText-optional)
- [`newTagText`](#newtagtext-optional)
- [`autoresize`](#autoresize-optional)
- [`delimiters`](#delimiters-optional)
- [`minQueryLength`](#minquerylength-optional)
- [`maxSuggestionsLength`](#maxsuggestionslength-optional)
- [`classNames`](#classnames-optional)
- [`onAddition`](#onaddition-required)
- [`onDelete`](#ondelete-required)
- [`onInput`](#oninput-optional)
- [`onFocus`](#onfocus-optional)
- [`onBlur`](#onblur-optional)
- [`onValidate`](#onvalidate-optional)
- [`addOnBlur`](#addonblur-optional)
- [`allowNew`](#allownew-optional)
- [`allowBackspace`](#allowbackspace-optional)
- [`tagComponent`](#tagcomponent-optional)
- [`suggestionComponent`](#suggestioncomponent-optional)
- [`inputAttributes`](#inputAttributes-optional)#### id (optional)
The ID attribute given to the listbox element. Default: `ReactTags`.
#### tags (optional)
An array of selected tags. Each tag is an object which must have an `id` and a `name` property. Defaults to `[]`.
```js
const tags = [
{ id: 1, name: 'Apples' },
{ id: 2, name: 'Pears' }
]
```#### suggestions (optional)
An array of tag suggestions. Each suggestion is an object which must have an `id` and a `name` property and an optional `disabled` property to make the suggestion non-selectable. Defaults to `[]`.
```js
const suggestions = [
{ id: 3, name: 'Bananas' },
{ id: 4, name: 'Mangos' },
{ id: 5, name: 'Lemons' },
{ id: 6, name: 'Apricots', disabled: true }
]
```#### suggestionsFilter (optional)
A callback function to filter suggestion items with. The callback receives two arguments; a `suggestion` and the current `query` and must return a boolean value.
If no function is supplied the default filter is applied. Defaults to `null`.
**Note:** This filter will be ignored if [suggestionsTransform](#suggestionsTransform-optional) is supplied.
#### suggestionsTransform (optional)
A callback function to apply a custom filter to the suggestions. The callback receives two arguments; a `query` and the input [suggestions](#suggestions-optional) and must return a new array of suggestion items. Using this option you can filter and sort suggestions.
**Note:** This will supersede [suggestionsFilter](#suggestionsfilter-optional) in future.
```js
import matchSorter from "match-sorter";function suggestionsFilter(query, suggestions) {
return matchSorter(suggestions, query, { keys: ["name"] });
}
```#### placeholderText (optional)
The placeholder string shown for the input. Defaults to `'Add new tag'`.
#### ariaLabelText (optional)
The aria-label string for the input. Defaults to placeholder string.
#### removeButtonText (optional)
The title text to add to the remove selected tag button. Default `'Click to remove tag'`.
#### noSuggestionsText (optional)
Message shown if there are no matching suggestions. Defaults to `null`.
#### newTagText (optional)
Enables users to show a prompt to add a new tag at the bottom of the suggestions list if `allowNew` is enabled. Defaults to `null`.
#### autoresize (optional)
Boolean parameter to control whether the text-input should be automatically resized to fit its value. Defaults to `true`.
#### delimiters (optional)
Array of keys matching `KeyboardEvent.key` values. When a corresponding key is pressed it will trigger tag selection or creation. Defaults to `['Enter', 'Tab']`.
#### minQueryLength (optional)
Minimum query length required to show the suggestions list. Defaults to `2`.
#### maxSuggestionsLength (optional)
Maximum number of suggestions to display. Defaults to `6`.
#### classNames (optional)
Override the default class names used by the component. Defaults to:
```js
{
root: 'react-tags',
rootFocused: 'is-focused',
selected: 'react-tags__selected',
selectedTag: 'react-tags__selected-tag',
selectedTagName: 'react-tags__selected-tag-name',
search: 'react-tags__search',
searchWrapper: 'react-tags__search-wrapper',
searchInput: 'react-tags__search-input',
suggestions: 'react-tags__suggestions',
suggestionActive: 'is-active',
suggestionDisabled: 'is-disabled',
suggestionPrefix: 'react-tags__suggestion-prefix'
}
```#### onAddition (required)
Function called when the user wants to add a tag. Receives the tag.
```js
const [tags, setTags] = useState([])function onAddition (newTag) {
setTags([...tags, newTag])
}
```#### onDelete (required)
Function called when the user wants to delete a tag. Receives the tag index.
```js
const [tags, setTags] = useState([])function onDelete (tagIndex) {
setTags(tags.filter((_, i) => i !== tagIndex))
}
```#### onInput (optional)
Optional event handler when the input value changes. Receives the current query.
```js
const [isBusy, setIsBusy] = useState(false)function onInput (query) {
if (!isBusy) {
setIsBusy(true)return fetch(`?query=${query}`).then((result) => {
setIsBusy(false)
})
}
}
```#### onFocus (optional)
Optional callback function for when the input receives focus. Receives no arguments.
#### onBlur (optional)
Optional callback function for when focus on the input is lost. Receives no arguments.
#### onValidate (optional)
Optional validation function that determines if tag should be added. Receives the tag object and must return a boolean.
```js
function onValidate (tag) {
return tag.name.length >= 5;
}
```#### addOnBlur (optional)
Creates a tag from the current input value when focus on the input is lost. Defaults to `false`.
#### allowNew (optional)
Enable users to add new (not suggested) tags. Defaults to `false`.
#### allowBackspace (optional)
Enable users to delete selected tags when backspace is pressed while focussed on the text input when empty. Defaults to `true`.
#### tagComponent (optional)
Provide a custom tag component to render. Receives the tag, button text, and delete callback as props. Defaults to `null`.
```jsx
function TagComponent ({ tag, removeButtonText, onDelete }) {
return (
{tag.name}
)
}
```#### suggestionComponent (optional)
Provide a custom suggestion component to render. Receives the suggestion and current query as props. Defaults to `null`.
```jsx
function SuggestionComponent ({ item, query }) {
return (
{item.name}
)
}
```#### inputAttributes (optional)
An object containing additional attributes that will be applied to the text input. _Please note_ that this prop cannot overwrite existing attributes, it can only add new ones. Defaults to `{}`.
### API
By adding a `ref` to any instances of this component you can access its API methods.
#### `addTag(tag)`
Adds a tag to the list of selected tags. This will trigger the validation and addition callbacks.
#### `deleteTag(index)`
Removes a tag from the list of selected tags. This will trigger the delete callback.
#### `clearInput()`
Clears the input, current query and selected suggestion.
#### `clearSelectedIndex()`
Clears the currently selected suggestion.
#### `focusInput()`
Sets cursor focus to the text input element.
### Styling
It is possible to customize the appearance of the component, the included styles found in `/example/styles.css` are only an example.
### Development
The component is written in ES6 and uses [Rollup](https://rollupjs.org/) as its build tool. Tests are written with [Jasmine](https://jasmine.github.io/) using [JSDOM](https://github.com/jsdom/jsdom).
```sh
npm install
npm run dev # will open http://localhost:8080 and watch files for changes
```### Upgrading
To see all changes refer to [the changelog](CHANGELOG.md).
#### Upgrading from 5.x to 6.x
- React 16.5 or above is now required.
- Event handlers and callbacks have been renamed to use `on` prefixes, e.g. the `handleAddition()` callback should now be called `onAddition()`.
- The `delimiters` option is now an array of `KeyboardEvent.key` values and not `KeyboardEvent.keyCode` codes, e.g. `[13, 9]` should now be written as `['Enter', 'Tab']`. See https://keycode.info/ for more information.
- The `placeholder` option has been renamed `placeholderText`
- The `ariaLabel` option has been renamed `ariaLabelText`
- The `delimiterChars` option has been removed, use the `delimiters` option instead.
- The `clearInputOnDelete` option has been removed and is now the default behaviour
- The `autofocus` option has been removed.