Skip to content

Commit 97d8ae2

Browse files
Merge pull request #109 from i-like-robots/6.0
v6.0
2 parents 18aa300 + 5f25446 commit 97d8ae2

17 files changed

+636
-471
lines changed

.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
.nyc_output
33
node_modules
44
npm-debug.log
5-
dist-es5
6-
dist-es6
5+
dist
76
example/bundle.js
87
example/bundle.js.map
98
coverage

.npmignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
.nyc_output/
44
coverage/
55
example/
6+
lib/
67
spec/
78
.DS_Store
89
.editorconfig
910
.travis.yml
1011
gh-pages.sh
11-
webpack.config.js
12+
rollup.config.js

CHANGELOG.md

+21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

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

526
- Fixed an issue where cursor focus could be lost after removing a selected tag

README.md

+99-74
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

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

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

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

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

1717
```
18-
npm install --save react-tag-autocomplete
18+
npm install --save react-tag-autocomplete@pre-release
1919
```
2020

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

2929
```js
3030
import React from 'react'
31+
import ReactDOM from 'react-dom'
3132
import ReactTags from 'react-tag-autocomplete'
3233

3334
class App extends React.Component {
@@ -46,62 +47,68 @@ class App extends React.Component {
4647
{ id: 6, name: "Apricots" }
4748
]
4849
}
50+
51+
this.reactTags = React.createRef()
4952
}
5053

51-
handleDelete (i) {
54+
onDelete (i) {
5255
const tags = this.state.tags.slice(0)
5356
tags.splice(i, 1)
5457
this.setState({ tags })
5558
}
5659

57-
handleAddition (tag) {
60+
onAddition (tag) {
5861
const tags = [].concat(this.state.tags, tag)
5962
this.setState({ tags })
6063
}
6164

6265
render () {
6366
return (
6467
<ReactTags
68+
ref={this.reactTags}
6569
tags={this.state.tags}
6670
suggestions={this.state.suggestions}
67-
handleDelete={this.handleDelete.bind(this)}
68-
handleAddition={this.handleAddition.bind(this)} />
71+
onDelete={this.onDelete.bind(this)}
72+
onAddition={this.onAddition.bind(this)} />
6973
)
7074
}
7175
}
7276

73-
React.render(<App />, document.getElementById('app'))
77+
ReactDOM.render(<App />, document.getElementById('app'))
7478
```
7579

7680

7781
### Options
7882

83+
- [`id`](#id-optional)
7984
- [`tags`](#tags-optional)
8085
- [`suggestions`](#suggestions-optional)
8186
- [`suggestionsFilter`](#suggestionsfilter-optional)
82-
- [`placeholder`](#placeholder-optional)
83-
- [`ariaLabel`](#ariaLabel-optional)
87+
- [`placeholderText`](#placeholdertext-optional)
88+
- [`ariaLabelText`](#arialabeltext-optional)
89+
- [`removeButtonText`](#removeButtontext-optional)
8490
- [`noSuggestionsText`](#noSuggestionsText-optional)
85-
- [`autofocus`](#autofocus-optional)
8691
- [`autoresize`](#autoresize-optional)
8792
- [`delimiters`](#delimiters-optional)
88-
- [`delimiterChars`](#delimiterschars-optional)
8993
- [`minQueryLength`](#minquerylength-optional)
9094
- [`maxSuggestionsLength`](#maxsuggestionslength-optional)
9195
- [`classNames`](#classnames-optional)
92-
- [`handleAddition`](#handleaddition-optional)
93-
- [`handleDelete`](#handledelete-optional)
94-
- [`handleInputChange`](#handleinputchange-optional)
95-
- [`handleFocus`](#handlefocus-optional)
96-
- [`handleBlur`](#handleblur-optional)
97-
- [`handleValidate`](#handlevalidate-optional)
96+
- [`onAddition`](#onaddition-optional)
97+
- [`onDelete`](#ondelete-optional)
98+
- [`onInput`](#oninput-optional)
99+
- [`onFocus`](#onfocus-optional)
100+
- [`onBlur`](#onblur-optional)
101+
- [`onValidate`](#onvalidate-optional)
98102
- [`addOnBlur`](#addonblur-optional)
99103
- [`allowNew`](#allownew-optional)
100104
- [`allowBackspace`](#allowbackspace-optional)
101-
- [`clearInputOnDelete`](#clearinputondelete-optional)
102105
- [`tagComponent`](#tagcomponent-optional)
103106
- [`inputAttributes`](#inputAttributes-optional)
104107

108+
#### id (optional)
109+
110+
The ID attribute given to the listbox element. Default: `ReactTags`.
111+
105112
#### tags (optional)
106113

107114
An array of selected tags. Each tag is an object which must have an `id` and a `name` property. Defaults to `[]`.
@@ -132,33 +139,29 @@ A callback function to filter suggestion items with. The callback receives two a
132139

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

135-
#### placeholder (optional)
142+
#### placeholderText (optional)
136143

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

139-
#### ariaLabel (optional)
146+
#### ariaLabelText (optional)
140147

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

143-
#### noSuggestionsText (optional)
150+
#### removeButtonText (optional)
144151

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

147-
#### autofocus (optional)
154+
#### noSuggestionsText (optional)
148155

149-
Boolean parameter to control whether the text-input should be autofocused on mount. Defaults to `true`.
156+
Message shown if there are no matching suggestions. Defaults to `null`.
150157

151158
#### autoresize (optional)
152159

153160
Boolean parameter to control whether the text-input should be automatically resized to fit its value. Defaults to `true`.
154161

155162
#### delimiters (optional)
156163

157-
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).
158-
159-
#### delimiterChars (optional)
160-
161-
Array of characters matching `KeyboardEvent.key` values. This is useful when needing to support a specific character irrespective of the keyboard layout. Defaults to `[]`.
164+
Array of keys matching `KeyboardEvent.key` values. When a corresponding key is pressed it will trigger tag selection or creation. Defaults to `['Enter', 'Tab']`.
162165

163166
#### minQueryLength (optional)
164167

@@ -180,42 +183,43 @@ Override the default class names used by the component. Defaults to:
180183
selectedTag: 'react-tags__selected-tag',
181184
selectedTagName: 'react-tags__selected-tag-name',
182185
search: 'react-tags__search',
186+
searchWrapper: 'react-tags__search-wrapper',
183187
searchInput: 'react-tags__search-input',
184188
suggestions: 'react-tags__suggestions',
185189
suggestionActive: 'is-active',
186190
suggestionDisabled: 'is-disabled'
187191
}
188192
```
189193

190-
#### handleAddition (required)
194+
#### onAddition (required)
191195

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

194198
```js
195-
function handleAddition(tag) {
199+
function onAddition(tag) {
196200
const tags = [...this.state.tags, tag]
197201
this.setState({ tags })
198202
}
199203
```
200204

201-
#### handleDelete (required)
205+
#### onDelete (required)
202206

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

205209
```js
206-
function handleDelete(i) {
210+
function onDelete(i) {
207211
const tags = this.state.tags.slice(0)
208212
tags.splice(i, 1)
209213
this.setState({ tags })
210214
}
211215
```
212216

213-
#### handleInputChange (optional)
217+
#### onInput (optional)
214218

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

217221
```js
218-
function handleInputChange(query) {
222+
function onInput(query) {
219223
if (!this.state.busy) {
220224
this.setState({ busy: true })
221225

@@ -226,20 +230,20 @@ function handleInputChange(query) {
226230
}
227231
```
228232

229-
#### handleFocus (optional)
233+
#### onFocus (optional)
230234

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

233-
#### handleBlur (optional)
237+
#### onBlur (optional)
234238

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

237-
#### handleValidate (optional)
241+
#### onValidate (optional)
238242

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

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

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

259-
#### clearInputOnDelete (optional)
263+
#### tagComponent (optional)
260264

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

263-
#### tagComponent (optional)
267+
```jsx
268+
function TagComponent({ tag, removeButtonText, onDelete }) {
269+
return (
270+
<button type='button' title={removeButtonText} onClick={onDelete}>
271+
{tag.name}
272+
</button>
273+
)
274+
}
275+
```
276+
277+
#### suggestionComponent (optional)
264278

265-
Provide a custom tag component to render. Defaults to `null`.
279+
Provide a custom suggestion component to render. Receives the suggestion and current query as props. Defaults to `null`.
280+
281+
```jsx
282+
function SuggestionComponent({ item, query }) {
283+
return (
284+
<span id={item.id} className={item.name === query ? 'match' : 'no-match'}>
285+
{item.name}
286+
</span>
287+
)
288+
}
289+
```
266290

267291
#### inputAttributes (optional)
268292

269293
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 `{}`.
270294

271295

296+
### API
297+
298+
By adding a `ref` to any instances of this component you can access its API methods.
299+
300+
#### `addTag(tag)`
301+
302+
Adds a tag to the list of selected tags. This will trigger the validation and addition callbacks.
303+
304+
#### `deleteTag(index)`
305+
306+
Removes a tag from the list of selected tags. This will trigger the delete callback.
307+
308+
#### `clearInput()`
309+
310+
Clears the input and current query.
311+
312+
272313
### Styling
273314

274315
It is possible to customize the appearance of the component, the included styles found in `/example/styles.css` are only an example.
275316

276317

277318
### Development
278319

279-
The component is written in ES6 and uses [Webpack](http://webpack.github.io/) as its build tool.
320+
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).
280321

281-
```
322+
```sh
282323
npm install
283-
npm run dev # open http://localhost:8080
324+
npm run dev # will open http://localhost:8080 and watch files for changes
284325
```
285326

327+
### Upgrading
286328

287-
### Upgrading from 4.x to 5.x
288-
289-
1. The `delimiters` option has been removed, any references to this will now be ignored.
290-
2. The `classNames` option has been updated:
291-
292-
```udiff
293-
{
294-
- root: 'ReactTags',
295-
- tagInput: 'ReactTags__tagInput',
296-
- selected: 'ReactTags__selected',
297-
- tag: 'ReactTags__tag',
298-
- tagName: 'ReactTags__tagName',
299-
- suggestions: 'ReactTags__suggestions',
300-
- isActive: 'is-active',
301-
- isDisabled: 'is-disabled'
302-
+ root: 'react-tags',
303-
+ rootFocused: 'is-focused',
304-
+ selected: 'react-tags__selected',
305-
+ selectedTag: 'react-tags__selected-tag',
306-
+ selectedTagName: 'react-tags__selected-tag-name',
307-
+ search: 'react-tags__search',
308-
+ searchInput: 'react-tags__search-input',
309-
+ suggestions: 'react-tags__suggestions',
310-
+ suggestionActive: 'is-active',
311-
+ suggestionDisabled: 'is-disabled'
312-
}
313-
```
329+
To see all changes refer to [the changelog](CHANGELOG.md).
330+
331+
#### Upgrading from 5.x to 6.x
314332

315-
For smaller changes refer to [the changelog](CHANGELOG.md).
333+
- React 16.5 or above is now required.
334+
- Event handlers and callbacks have been renamed to use `on` prefixes, e.g. the `handleAddition()` callback should now be called `onAddition()`.
335+
- 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.
336+
- The `placeholder` option has been renamed `placeholderText`
337+
- The `ariaLabel` option has been renamed `ariaLabelText`
338+
- The `delimiterChars` option has been removed, use the `delimiters` option instead.
339+
- The `clearInputOnDelete` option has been removed and is now the default behaviour
340+
- The `autofocus` option has been removed.

example/countries.js

+1-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)