Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v6.0 #109

Merged
merged 101 commits into from
Jun 28, 2020
Merged

v6.0 #109

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
508db72
React 16
i-like-robots Nov 30, 2017
da6f2ec
Remove autofocus option
i-like-robots Nov 30, 2017
770bef7
Use KeyboardEvent.key rather than non-standard KeyboardEvent.keyCode,…
i-like-robots Nov 30, 2017
37265fd
Unite delimiters and delimiterChars options using KeyboardEvent.key
i-like-robots Nov 30, 2017
a3e202b
Fix prop types dependency
i-like-robots Nov 30, 2017
61f524f
Re-name handleInputChange option to handleInput
i-like-robots Nov 30, 2017
2f5c387
Prefix all event handlers with "on" rather than "handle", fixes #91
i-like-robots Nov 30, 2017
2e03699
Refactor internal state, expandable => expanded
i-like-robots Nov 30, 2017
b54c431
Refactor internal state, selectedIndex => selected
i-like-robots Nov 30, 2017
a2df5d8
Use ES6 module syntax, add pkg.module to manifest, bump Buble
i-like-robots Jan 18, 2018
db1a80a
Setup rollup for compiling single distributable files
i-like-robots Jan 18, 2018
4b779cd
Add missing option anchors to readme
i-like-robots Jan 20, 2018
776174a
Update readme example to use react-dom
i-like-robots Jan 20, 2018
f2466ad
Refactor key handlers into separate functions
i-like-robots Jan 21, 2018
3433fa1
Refactor filtered suggestions into top-level component
i-like-robots Jan 21, 2018
f511a8c
Refactor regexp generators into shared module
i-like-robots Jan 21, 2018
02897b5
Re-name 'selected' state 'index'
i-like-robots Jan 22, 2018
cb258d1
Refactor up/down key handlers with simple ternary
i-like-robots Jan 22, 2018
73a161f
Make listbox ID configurable via top-level prop
i-like-robots Jan 22, 2018
0ec0212
Use capturing event listeners
i-like-robots Apr 23, 2018
addf0af
Allow for custom suggestions component
tjphopkins Apr 26, 2018
c9ca86b
Update dev dependencies
i-like-robots May 1, 2018
4e14933
Add class name to text input, fixes #126
i-like-robots Jul 3, 2018
6c6e04a
Bump rollup and Sinon
i-like-robots Jul 3, 2018
05051cb
Remove redundant webpack options
i-like-robots Jul 3, 2018
24c9a74
Update changelog
i-like-robots Jul 3, 2018
1738b78
Add clearInput method so that input may be cleared programmatically
i-like-robots Jul 6, 2018
f81bcb9
Document API methods in replay
i-like-robots Jul 6, 2018
6d5ee46
Update changelog
i-like-robots Jul 7, 2018
1a6e873
Add 6.x upgrade guide to readme
i-like-robots Jul 7, 2018
fe0085a
Merge branch 'master' into 6.0
i-like-robots Aug 13, 2018
f323a03
Merge branch 'master' into 6.0
i-like-robots Oct 26, 2018
ac76479
Fix merge conflict in package.json
i-like-robots Oct 30, 2018
42b8615
Merge branch 'master' into 6.0
i-like-robots Oct 30, 2018
5972a51
Fix npm build script hooks, complete changelog
i-like-robots Oct 30, 2018
fa0be91
Merge branch 'master' into 6.0
i-like-robots Nov 11, 2018
957354e
Remove unneeded lifecycle method from input component
i-like-robots Nov 11, 2018
3ae0444
Use createRef() and raise minimum React version to 16.3
i-like-robots Nov 11, 2018
4447633
Switch to using Rollup for building example page
i-like-robots Nov 30, 2017
04de4fa
Merge branch 'master' into 6.0
i-like-robots Dec 4, 2018
8f90bb4
Update 5 to 6 migration guide in readme
i-like-robots Dec 4, 2018
92ca942
Add rollup-plugin-serve to host the example in development mode
i-like-robots Dec 29, 2018
fa88763
Add note about testing tools to readme
i-like-robots Dec 29, 2018
f979870
Update Rollup and its plugins
i-like-robots Dec 29, 2018
5b386e4
Merge pull request #128 from i-like-robots/no-webpack
i-like-robots Dec 29, 2018
205ce74
Refactor classNames prop out of state to avoid merging objects on top…
i-like-robots Feb 20, 2019
aaf5469
Update changelog
i-like-robots Feb 20, 2019
4aeae07
Merge pull request #147 from i-like-robots/matth/remove-classnames-fr…
i-like-robots Feb 20, 2019
2413ec7
Set minimum Node version to v8 LTS
i-like-robots Mar 9, 2019
b8c02af
Add .npmignore file
i-like-robots Mar 9, 2019
8b26223
Merge branch 'master' into 6.0
i-like-robots Mar 27, 2019
32fa604
Update dev dependencies
i-like-robots Mar 27, 2019
2064e65
Support legacy (IE9-11) up and down arrow key values
i-like-robots Mar 27, 2019
f71931f
Merge branch 'master' into 6.0
i-like-robots Apr 1, 2019
a3a5a4a
Merge branch 'master' into 6.0
i-like-robots Apr 1, 2019
b53f524
Add ES5/UMD package and pkg.browser field
i-like-robots Apr 1, 2019
04d200a
Merge branch 'master' into 6.0
i-like-robots Apr 14, 2019
a6fcb94
Add removeButtonText prop to enable the configuration of selected tag…
i-like-robots Apr 24, 2019
31a0ad9
Re-name placeholder prop to placeholderText to match other display te…
i-like-robots Apr 24, 2019
e1a210b
Update changelog
i-like-robots Apr 24, 2019
fbf8bdc
Update options anchor links in readme
i-like-robots Apr 24, 2019
254a72a
Merge pull request #154 from i-like-robots/add-remove-button-text-option
i-like-robots Apr 26, 2019
319aee2
Refactor .deleteTag() method so it no longer clears input text when a…
i-like-robots May 1, 2019
4c704cb
Remove clearInputOnDelete option as it is no longer needed.
i-like-robots May 1, 2019
3197851
Merge pull request #155 from i-like-robots/remove-clear-on-delete
i-like-robots May 1, 2019
f6418fa
6.0.0-beta.0
i-like-robots May 1, 2019
e833ddf
Add pre-release installation notes to readme
i-like-robots May 1, 2019
fe94b70
Merge branch 'master' into 6.0
i-like-robots May 18, 2019
6519e7b
6.0.0-beta.1
i-like-robots May 18, 2019
6d6c55f
Update v5 to v6 migration guide in readme
i-like-robots May 18, 2019
ccc52ce
Merge branch 'master' into 6.0
i-like-robots May 18, 2019
ada78b0
Update dev dependencies
i-like-robots Oct 12, 2019
71a11a3
Merge branch 'master' into 6.0
i-like-robots Oct 12, 2019
598b642
Point the example at the component source code so that it can be watc…
i-like-robots Oct 12, 2019
6a8515a
Set the default options state to use suggestions rather than a blank …
i-like-robots Oct 12, 2019
a4ef7ad
Refactor .clearInput() method to reset options state so that the sugg…
i-like-robots Oct 13, 2019
c5457ff
Refactor default suggestions filter to enable use of defaultProps and…
i-like-robots Oct 13, 2019
c4ed884
Add spec for suggestions list behaviour when minQueryLength is set to 0
i-like-robots Oct 13, 2019
13ae8f0
Merge pull request #177 from i-like-robots/fix-default-options-state
i-like-robots Oct 13, 2019
6cc4c6d
6.0.0-beta.2
i-like-robots Oct 13, 2019
585186e
Fix incorrect IE/Edge KeyboardEvent.key up arrow key value
i-like-robots Oct 13, 2019
3bae625
Re-implement delimiterChars in onInput callback
i-like-robots Oct 26, 2019
3f763b3
Add delimiterChars option to readme and amend upgrade instructions
i-like-robots Oct 27, 2019
c07922a
Refactor soft keyboard support to use existing delimiters option
i-like-robots Oct 29, 2019
f9b60ae
Merge pull request #181 from i-like-robots/delimiters-for-soft-keyboards
i-like-robots Nov 1, 2019
0824149
6.0.0-beta.3
i-like-robots Nov 1, 2019
f4df932
Update CHANGELOG.md
i-like-robots Nov 1, 2019
360728a
Merge branch 'master' into 6.0
i-like-robots Feb 3, 2020
5efdab6
6.0.0-beta.4
i-like-robots Feb 3, 2020
dae0dd4
Bump all dev dependencies
i-like-robots Feb 3, 2020
0925ec7
Fix all code formatting issues
i-like-robots Feb 3, 2020
adac2ef
Set minimum Node version to v10
i-like-robots Feb 8, 2020
fc17cd0
Update all Rollup dependencies to latest versions
i-like-robots Feb 9, 2020
cf4abfd
Merge branch 'master' into 6.0
i-like-robots Apr 29, 2020
209f80c
6.0.0-beta.5
i-like-robots Apr 29, 2020
9b9d906
Refactor filtered suggestions to ensure options list updates on top-l…
i-like-robots May 13, 2020
2ac0c3f
Merge pull request #210 from i-like-robots/fix-top-level-suggestions-…
i-like-robots May 13, 2020
7439a45
6.0.0-beta.6
i-like-robots May 13, 2020
9a5992f
Fix coverage script scope
i-like-robots May 17, 2020
f248a14
Add descriptions to API documentation and examples to custom componen…
i-like-robots May 17, 2020
5f25446
Merge branch 'master' into 6.0
i-like-robots May 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
.nyc_output
node_modules
npm-debug.log
dist-es5
dist-es6
dist
example/bundle.js
example/bundle.js.map
coverage
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
.nyc_output/
coverage/
example/
lib/
spec/
.DS_Store
.editorconfig
.travis.yml
gh-pages.sh
webpack.config.js
rollup.config.js
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## 6.0.0

- Added `clearInput` method to programmatically clear input text
- Added `suggestionComponent` option to allow the rendering of a custom suggestion component ([tjphopkins](https://github.com/tjphopkins))
- Added `searchWrapper` to `classNames` option
- Added ES6 package and `"module"` entry point
- Added `id` option to configure the component ID
- Added `removeButtonText` option to configure the selected tag remove button title attribute
- Refactored `ariaLabel` option to `ariaLabelText` to match other text options
- Refactored `placeholder` option to `placeholderText` to match other text options
- Refactored keyboard event handlers to use `KeyboardEvent.key`
- Refactored event handlers and callbacks to use `on` prefixes
- Refactored `classNames` option to avoid creating new and merging objects for each top-level props change
- Refactored `deleteTag` method so it no longer clears the input text when a tag is removed
- Refactored `delimiters` option to be an array of `KeyboardEvent.key` values
- Refactored `onInput` callback to provide basic support for `delimiters` entered on soft keyboards
- Removed `clearInputOnDelete` option
- Removed `autofocus` option
- Removed `delimiterChars` option
- Updated React dependency to 16.5+

## 5.13.1

- Fixed an issue where cursor focus could be lost after removing a selected tag
Expand Down
173 changes: 99 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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/).

**Version 6 of this component is in beta! Please [take a look here](https://github.com/i-like-robots/react-tags/tree/6.0)**
**Please note, this version is in beta, you can check out the [latest stable version here](https://github.com/i-like-robots/react-tags)** 📢

![Screenshot of React Tag Autocomplete](https://cloud.githubusercontent.com/assets/271645/25478773/54aa2bbe-2b3a-11e7-95cf-d419f3c24418.png)

Expand All @@ -15,7 +15,7 @@ This is a [Node.js] module available through the [npm] registry. Before installi
Installation is done using the [npm install] command:

```
npm install --save react-tag-autocomplete
npm install --save react-tag-autocomplete@pre-release
```

[Node.js]: https://nodejs.org/en/
Expand All @@ -28,6 +28,7 @@ Here's a sample implementation that initializes the component with a list of pre

```js
import React from 'react'
import ReactDOM from 'react-dom'
import ReactTags from 'react-tag-autocomplete'

class App extends React.Component {
Expand All @@ -46,62 +47,68 @@ class App extends React.Component {
{ id: 6, name: "Apricots" }
]
}

this.reactTags = React.createRef()
}

handleDelete (i) {
onDelete (i) {
const tags = this.state.tags.slice(0)
tags.splice(i, 1)
this.setState({ tags })
}

handleAddition (tag) {
onAddition (tag) {
const tags = [].concat(this.state.tags, tag)
this.setState({ tags })
}

render () {
return (
<ReactTags
ref={this.reactTags}
tags={this.state.tags}
suggestions={this.state.suggestions}
handleDelete={this.handleDelete.bind(this)}
handleAddition={this.handleAddition.bind(this)} />
onDelete={this.onDelete.bind(this)}
onAddition={this.onAddition.bind(this)} />
)
}
}

React.render(<App />, document.getElementById('app'))
ReactDOM.render(<App />, document.getElementById('app'))
```


### Options

- [`id`](#id-optional)
- [`tags`](#tags-optional)
- [`suggestions`](#suggestions-optional)
- [`suggestionsFilter`](#suggestionsfilter-optional)
- [`placeholder`](#placeholder-optional)
- [`ariaLabel`](#ariaLabel-optional)
- [`placeholderText`](#placeholdertext-optional)
- [`ariaLabelText`](#arialabeltext-optional)
- [`removeButtonText`](#removeButtontext-optional)
- [`noSuggestionsText`](#noSuggestionsText-optional)
- [`autofocus`](#autofocus-optional)
- [`autoresize`](#autoresize-optional)
- [`delimiters`](#delimiters-optional)
- [`delimiterChars`](#delimiterschars-optional)
- [`minQueryLength`](#minquerylength-optional)
- [`maxSuggestionsLength`](#maxsuggestionslength-optional)
- [`classNames`](#classnames-optional)
- [`handleAddition`](#handleaddition-optional)
- [`handleDelete`](#handledelete-optional)
- [`handleInputChange`](#handleinputchange-optional)
- [`handleFocus`](#handlefocus-optional)
- [`handleBlur`](#handleblur-optional)
- [`handleValidate`](#handlevalidate-optional)
- [`onAddition`](#onaddition-optional)
- [`onDelete`](#ondelete-optional)
- [`onInput`](#oninput-optional)
- [`onFocus`](#onfocus-optional)
- [`onBlur`](#onblur-optional)
- [`onValidate`](#onvalidate-optional)
- [`addOnBlur`](#addonblur-optional)
- [`allowNew`](#allownew-optional)
- [`allowBackspace`](#allowbackspace-optional)
- [`clearInputOnDelete`](#clearinputondelete-optional)
- [`tagComponent`](#tagcomponent-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 `[]`.
Expand Down Expand Up @@ -132,33 +139,29 @@ A callback function to filter suggestion items with. The callback receives two a

If no function is supplied the default filter is applied. Defaults to `null`.

#### placeholder (optional)
#### placeholderText (optional)

The placeholder string shown for the input. Defaults to `'Add new tag'`.

#### ariaLabel (optional)
#### ariaLabelText (optional)

The aria-label string for the input. Defaults to placeholder string.

#### noSuggestionsText (optional)
#### removeButtonText (optional)

Message shown if there are no matching suggestions. Defaults to `null`.
The title text to add to the remove selected tag button. Default `'Click to remove tag'`.

#### autofocus (optional)
#### noSuggestionsText (optional)

Boolean parameter to control whether the text-input should be autofocused on mount. Defaults to `true`.
Message shown if there are no matching suggestions. 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)

An array of numbers matching `KeyboardEvent.keyCode` values. When a corresponding key is pressed it will trigger tag selection or creation. Defaults to `[9, 13]` (Tab and return keys).

#### delimiterChars (optional)

Array of characters matching `KeyboardEvent.key` values. This is useful when needing to support a specific character irrespective of the keyboard layout. Defaults to `[]`.
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)

Expand All @@ -180,42 +183,43 @@ Override the default class names used by the component. Defaults to:
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'
}
```

#### handleAddition (required)
#### onAddition (required)

Function called when the user wants to add a tag. Receives the tag.

```js
function handleAddition(tag) {
function onAddition(tag) {
const tags = [...this.state.tags, tag]
this.setState({ tags })
}
```

#### handleDelete (required)
#### onDelete (required)

Function called when the user wants to delete a tag. Receives the tag index.

```js
function handleDelete(i) {
function onDelete(i) {
const tags = this.state.tags.slice(0)
tags.splice(i, 1)
this.setState({ tags })
}
```

#### handleInputChange (optional)
#### onInput (optional)

Optional event handler when the input value changes. Receives the current query.

```js
function handleInputChange(query) {
function onInput(query) {
if (!this.state.busy) {
this.setState({ busy: true })

Expand All @@ -226,20 +230,20 @@ function handleInputChange(query) {
}
```

#### handleFocus (optional)
#### onFocus (optional)

Optional callback function for when the input receives focus. Receives no arguments.

#### handleBlur (optional)
#### onBlur (optional)

Optional callback function for when focus on the input is lost. Receives no arguments.

#### handleValidate (optional)
#### onValidate (optional)

Optional validation function that determines if tag should be added. Receives the tag object and must return a boolean.

```js
function handleValidate(tag) {
function onValidate(tag) {
return tag.name.length >= 5;
}
```
Expand All @@ -256,60 +260,81 @@ Enable users to add new (not suggested) tags. Defaults to `false`.

Enable users to delete selected tags when backspace is pressed while focussed on the text input when empty. Defaults to `true`.

#### clearInputOnDelete (optional)
#### tagComponent (optional)

Clear the text input when a tag is deleted. Defaults to `true`.
Provide a custom tag component to render. Receives the tag, button text, and delete callback as props. Defaults to `null`.

#### tagComponent (optional)
```jsx
function TagComponent({ tag, removeButtonText, onDelete }) {
return (
<button type='button' title={removeButtonText} onClick={onDelete}>
{tag.name}
</button>
)
}
```

#### suggestionComponent (optional)

Provide a custom tag component to render. Defaults to `null`.
Provide a custom suggestion component to render. Receives the suggestion and current query as props. Defaults to `null`.

```jsx
function SuggestionComponent({ item, query }) {
return (
<span id={item.id} className={item.name === query ? 'match' : 'no-match'}>
{item.name}
</span>
)
}
```

#### 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 and current query.


### 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 [Webpack](http://webpack.github.io/) as its build tool.
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 # open http://localhost:8080
npm run dev # will open http://localhost:8080 and watch files for changes
```

### Upgrading

### Upgrading from 4.x to 5.x

1. The `delimiters` option has been removed, any references to this will now be ignored.
2. The `classNames` option has been updated:

```udiff
{
- root: 'ReactTags',
- tagInput: 'ReactTags__tagInput',
- selected: 'ReactTags__selected',
- tag: 'ReactTags__tag',
- tagName: 'ReactTags__tagName',
- suggestions: 'ReactTags__suggestions',
- isActive: 'is-active',
- isDisabled: 'is-disabled'
+ 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',
+ searchInput: 'react-tags__search-input',
+ suggestions: 'react-tags__suggestions',
+ suggestionActive: 'is-active',
+ suggestionDisabled: 'is-disabled'
}
```
To see all changes refer to [the changelog](CHANGELOG.md).

#### Upgrading from 5.x to 6.x

For smaller changes refer to [the changelog](CHANGELOG.md).
- 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.
4 changes: 1 addition & 3 deletions example/countries.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.