Socket
Socket
Sign inDemoInstall

react-tagsinput

Package Overview
Dependencies
3
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.19.0 to 3.20.0

57

package.json
{
"name": "react-tagsinput",
"version": "3.19.0",
"version": "3.20.0",
"description": "Highly customizable React component for inputing tags",
"main": "react-tagsinput.js",
"peerDependencies": {
"react": "^16.0.0 || ^15.0.0 || ^0.14.0"
"react": "^18.0.0 || ^17.0.0 || ^16.0.0 || ^15.0.0"
},
"devDependencies": {
"babel-cli": "^6.8.0",
"babel-core": "^6.8.0",
"babel-eslint": "^6.0.4",
"babel-plugin-add-module-exports": "^0.2.0",
"babel-plugin-transform-es2015-modules-umd": "^6.8.0",
"babel-plugin-transform-react-remove-prop-types": "^0.3.3",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-plugin-transform-es2015-modules-umd": "^6.24.1",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.8.0",
"istanbul": "^1.1.0-alpha.1",
"jsdom": "^7.0.2",
"mocha": "^2.3.3",
"prop-types": "^15.6.0",
"react": "^16.0.0",
"react-addons-test-utils": "^15.0.0",
"react-autosuggest": "^8.0.0",
"react-dom": "^16.0.0",
"react-input-autosize": "^1.0.0",
"reactpack": "^0.9.0",
"sinon": "^2.1.0",
"standard": "^8.6.0"
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"jsdom": "^20.0.1",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sinon": "^14.0.1",
"standard": "^17.0.0"
},
"scripts": {
"test": "standard src/index.js && mocha --compilers js:babel-register",
"test": "standard src/index.js && mocha --require babel-register",
"lint": "standard src/index.js",
"fix": "standard src/index.js --fix",
"build": "babel --module-id ReactTagsInput -m umd src/index.js > react-tagsinput.js",
"build-example": "reactpack --no-extract --no-source-map --no-html example/index.js example/",
"build-example-watch": "reactpack -w --no-extract --no-source-map --no-html example/index.js example/",
"coverage": "istanbul cover --report text --report html _mocha -- --compilers js:babel-register",
"coverage": "npx nyc --reporter=lcov --reporter=text-summary npm test",
"prepublish": "npm run build"

@@ -58,6 +53,6 @@ },

},
"standard": {
"parser": "babel-eslint"
},
"homepage": "https://github.com/olahol/react-tagsinput"
"homepage": "https://github.com/olahol/react-tagsinput",
"files": [
"react-tagsinput.css"
]
}
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define('ReactTagsInput', ['module', 'exports', 'react', 'prop-types'], factory);
define('ReactTagsInput', ['exports', 'react', 'prop-types'], factory);
} else if (typeof exports !== "undefined") {
factory(module, exports, require('react'), require('prop-types'));
factory(exports, require('react'), require('prop-types'));
} else {

@@ -10,6 +10,6 @@ var mod = {

};
factory(mod, mod.exports, global.React, global.propTypes);
factory(mod.exports, global.React, global.propTypes);
global.ReactTagsInput = mod.exports;
}
})(this, function (module, exports, _react, _propTypes) {
})(this, function (exports, _react, _propTypes) {
'use strict';

@@ -207,2 +207,3 @@

_this.blur = _this.blur.bind(_this);
_this.accept = _this.accept.bind(_this);
return _this;

@@ -268,3 +269,2 @@ }

var _props = this.props,
validationRegex = _props.validationRegex,
onChange = _props.onChange,

@@ -287,6 +287,6 @@ onValidationReject = _props.onValidationReject,

var rejectedTags = tags.filter(function (tag) {
return !validationRegex.test(_this2._getTagDisplayValue(tag));
return !_this2._validate(_this2._getTagDisplayValue(tag));
});
tags = tags.filter(function (tag) {
return validationRegex.test(_this2._getTagDisplayValue(tag));
return _this2._validate(_this2._getTagDisplayValue(tag));
});

@@ -296,3 +296,3 @@ tags = tags.filter(function (tag) {

if (typeof tagDisplayValue.trim === 'function') {
return tagDisplayValue.trim().length > 0;
return tagDisplayValue.trim().length >= 0;
} else {

@@ -331,4 +331,14 @@ return tagDisplayValue;

}, {
key: '_validate',
value: function _validate(tag) {
var _props2 = this.props,
validate = _props2.validate,
validationRegex = _props2.validationRegex;
return validate(tag) && validationRegex.test(tag);
}
}, {
key: '_shouldPreventDefaultEventOnAdd',
value: function _shouldPreventDefaultEventOnAdd(added, empty, keyCode) {
value: function _shouldPreventDefaultEventOnAdd(added, empty, key) {
if (added) {

@@ -338,3 +348,3 @@ return true;

if (keyCode === 13) {
if (key === 'Enter') {
return this.props.preventSubmit || !this.props.preventSubmit && !empty;

@@ -366,5 +376,6 @@ }

value: function accept() {
var preventSubmit = this.props.preventSubmit;
var tag = this._tag();
if (tag !== '') {
if (tag !== '' || !preventSubmit) {
tag = this._makeTag(tag);

@@ -391,5 +402,5 @@ return this._addTags([tag]);

var _props2 = this.props,
addOnPaste = _props2.addOnPaste,
pasteSplit = _props2.pasteSplit;
var _props3 = this.props,
addOnPaste = _props3.addOnPaste,
pasteSplit = _props3.pasteSplit;

@@ -417,6 +428,6 @@

var _props3 = this.props,
value = _props3.value,
removeKeys = _props3.removeKeys,
addKeys = _props3.addKeys;
var _props4 = this.props,
value = _props4.value,
removeKeys = _props4.removeKeys,
addKeys = _props4.addKeys;

@@ -432,3 +443,3 @@ var tag = this._tag();

var added = this.accept();
if (this._shouldPreventDefaultEventOnAdd(added, empty, keyCode)) {
if (this._shouldPreventDefaultEventOnAdd(added, empty, key)) {
e.preventDefault();

@@ -446,3 +457,6 @@ }

value: function handleClick(e) {
if (e.target === this.div) {
var clickedElement = e.target;
var parentElement = e.target && e.target.parentElement;
if (clickedElement === this.div || parentElement === this.div) {
this.focus();

@@ -532,5 +546,5 @@ }

value: function hasControlledInput() {
var _props4 = this.props,
inputValue = _props4.inputValue,
onChangeInput = _props4.onChangeInput;
var _props5 = this.props,
inputValue = _props5.inputValue,
onChangeInput = _props5.onChangeInput;

@@ -552,4 +566,4 @@

}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
/* istanbul ignore next */

@@ -560,9 +574,11 @@ if (this.hasControlledInput()) {

if (!this.inputValue(nextProps)) {
if (!this.inputValue(this.props)) {
return;
}
this.setState({
tag: this.inputValue(nextProps)
});
if (this.inputValue(prevProps) !== this.inputValue(this.props)) {
this.setState({
tag: this.inputValue(this.props)
});
}
}

@@ -574,33 +590,14 @@ }, {

var _props5 = this.props,
value = _props5.value,
onChange = _props5.onChange,
tagProps = _props5.tagProps,
renderLayout = _props5.renderLayout,
renderTag = _props5.renderTag,
renderInput = _props5.renderInput,
addKeys = _props5.addKeys,
removeKeys = _props5.removeKeys,
className = _props5.className,
focusedClassName = _props5.focusedClassName,
addOnBlur = _props5.addOnBlur,
addOnPaste = _props5.addOnPaste,
inputProps = _props5.inputProps,
pasteSplit = _props5.pasteSplit,
onlyUnique = _props5.onlyUnique,
maxTags = _props5.maxTags,
validationRegex = _props5.validationRegex,
disabled = _props5.disabled,
tagDisplayProp = _props5.tagDisplayProp,
inputValue = _props5.inputValue,
onChangeInput = _props5.onChangeInput,
other = _objectWithoutProperties(_props5, ['value', 'onChange', 'tagProps', 'renderLayout', 'renderTag', 'renderInput', 'addKeys', 'removeKeys', 'className', 'focusedClassName', 'addOnBlur', 'addOnPaste', 'inputProps', 'pasteSplit', 'onlyUnique', 'maxTags', 'validationRegex', 'disabled', 'tagDisplayProp', 'inputValue', 'onChangeInput']);
var _props6 = this.props,
value = _props6.value,
tagProps = _props6.tagProps,
renderLayout = _props6.renderLayout,
renderTag = _props6.renderTag,
renderInput = _props6.renderInput,
className = _props6.className,
focusedClassName = _props6.focusedClassName,
disabled = _props6.disabled;
var isFocused = this.state.isFocused;
if (isFocused) {
className += ' ' + focusedClassName;
}
var tagComponents = value.map(function (tag, index) {

@@ -633,3 +630,3 @@ return renderTag(_extends({

_this4.div = r;
}, onClick: this.handleClick.bind(this), className: className },
}, onClick: this.handleClick.bind(this), className: className + (isFocused ? ' ' + focusedClassName : '') },
renderLayout(tagComponents, inputComponent)

@@ -646,7 +643,7 @@ );

focusedClassName: 'react-tagsinput--focused',
addKeys: [9, 13],
addKeys: ['Tab', 'Enter'],
addOnBlur: false,
addOnPaste: false,
inputProps: {},
removeKeys: [8],
removeKeys: ['Backspace'],
renderInput: defaultRenderInput,

@@ -659,2 +656,5 @@ renderTag: defaultRenderTag,

maxTags: -1,
validate: function validate() {
return true;
},
validationRegex: /.*/,

@@ -666,4 +666,4 @@ disabled: false,

exports.default = TagsInput;
module.exports = exports['default'];
module.exports = exports.default;
});
# react-tagsinput
[![NPM version][npm-image]][npm-url]
[![Build Status][travis-image]][travis-url]
[![Coverage Status][coverage-image]][coverage-url]
[![Dependency Status][dep-image]][dep-url]
[![Size][size-image]][size-url]
[![Download Count][downloads-image]][downloads-url]
[![Code coverage][codecov-image]][codecov-url]
[![Download count][downloads-image]][downloads-url]
[![js-standard-style][standard-image]][standard-url]

@@ -13,70 +11,11 @@

## Table of Contents
![Demo](./example/demo.gif)
* [react-tagsinput](#react-tagsinput)
* [Demo](#demo)
* [Install](#install)
* [Example](#example)
* [FAQ](#faq)
* [How do I make the input dynamically grow in size?](#how-do-i-make-the-input-dynamically-grow-in-size)
* [How do I add auto suggestion?](#how-do-i-add-auto-suggestion)
* [How do I control the value of the input box?](#how-do-i-control-the-value-of-the-input-box)
* [How do I fix warning "unknown prop `addTag`"?](#how-do-i-fix-warning-unknown-prop-addtag)
* [How do I copy paste from Excel?](#how-do-i-copy-paste-from-excel)
* [Component Interface](#component-interface)
* [Props](#props)
* [value (required)](#value-required)
* [onChange (required)](#onchange-required)
* [onChangeInput](#onchangeinput)
* [addKeys](#addkeys)
* [currentValue](#currentvalue)
* [inputValue](#inputvalue)
* [onlyUnique](#onlyunique)
* [validationRegex](#validationregex)
* [onValidationReject](#onvalidationreject)
* [disabled](#disabled)
* [maxTags](#maxtags)
* [addOnBlur](#addonblur)
* [addOnPaste](#addonpaste)
* [pasteSplit](#pastesplit)
* [removeKeys](#removekeys)
* [tagProps](#tagprops)
* [inputProps](#inputprops)
* [renderTag](#rendertag)
* [renderInput](#renderinput)
* [renderLayout](#renderlayout)
* [preventSubmit](#preventSubmit)
* [Methods](#methods)
* [focus()](#focus)
* [blur()](#blur)
* [accept()](#accept)
* [addTag()](#addTag)
* [clearInput()](#clearInput)
* [Styling](#styling)
* [Contributors](#contributors)
* [Changelog](#changelog)
* [License](#license)
## Demo
[![Demo](./example/demo.gif)][demo-url]
### [Interactive Demo](https://olahol.github.io/react-tagsinput)
## Install
```bash
npm install react-tagsinput --save
```
```bash
bower install react-tagsinput --save
```
## Example
```javascript
import React from 'react'
import TagsInput from 'react-tagsinput'
import 'react-tagsinput/react-tagsinput.css' // If using WebPack and style-loader.
import 'react-tagsinput/react-tagsinput.css'

@@ -89,3 +28,3 @@ class Example extends React.Component {

handleChange(tags) {
handleChange = (tags) => {
this.setState({tags})

@@ -95,127 +34,49 @@ }

render() {
return <TagsInput value={this.state.tags} onChange={::this.handleChange} />
return <TagsInput value={this.state.tags} onChange={this.handleChange} />
}
}
```
## FAQ
##### How do I make the input dynamically grow in size?
## Table of Contents
Install [`react-input-autosize`](https://github.com/JedWatson/react-input-autosize) and change the `renderInput` prop to:
* [Example](#example)
* [Styling](#styling)
* [Component Interface](#component-interface)
* [Props](#props)
* [value (required)](#value-required)
* [onChange (required)](#onchange-required)
* [onChangeInput](#onchangeinput)
* [addKeys](#addkeys)
* [currentValue](#currentvalue)
* [inputValue](#inputvalue)
* [onlyUnique](#onlyunique)
* [validate](#validate)
* [validationRegex](#validationregex)
* [onValidationReject](#onvalidationreject)
* [disabled](#disabled)
* [maxTags](#maxtags)
* [addOnBlur](#addonblur)
* [addOnPaste](#addonpaste)
* [pasteSplit](#pastesplit)
* [removeKeys](#removekeys)
* [tagProps](#tagprops)
* [inputProps](#inputprops)
* [renderTag](#rendertag)
* [renderInput](#renderinput)
* [renderLayout](#renderlayout)
* [preventSubmit](#preventSubmit)
* [Methods](#methods)
* [focus()](#focus)
* [blur()](#blur)
* [accept()](#accept)
* [addTag()](#addTag)
* [clearInput()](#clearInput)
* [Contributors](#contributors)
* [Changelog](#changelog)
* [License](#license)
```js
function autosizingRenderInput ({addTag, ...props}) {
let {onChange, value, ...other} = props
return (
<AutosizeInput type='text' onChange={onChange} value={value} {...other} />
)
}
```
## Styling
##### How do I add auto suggestion?
Look at [react-tagsinput.css](./react-tagsinput.css) for a basic style.
Use [`react-autosuggest`](https://github.com/moroshko/react-autosuggest) and change the `renderInput` prop to
something like:
```js
function autosuggestRenderInput ({addTag, ...props}) {
const handleOnChange = (e, {newValue, method}) => {
if (method === 'enter') {
e.preventDefault()
} else {
props.onChange(e)
}
}
const inputValue = (props.value && props.value.trim().toLowerCase()) || ''
const inputLength = inputValue.length
let suggestions = states().filter((state) => {
return state.name.toLowerCase().slice(0, inputLength) === inputValue
})
return (
<Autosuggest
ref={props.ref}
suggestions={suggestions}
shouldRenderSuggestions={(value) => value && value.trim().length > 0}
getSuggestionValue={(suggestion) => suggestion.name}
renderSuggestion={(suggestion) => <span>{suggestion.name}</span>}
inputProps={{...props, onChange: handleOnChange}}
onSuggestionSelected={(e, {suggestion}) => {
addTag(suggestion.name)
}}
onSuggestionsClearRequested={() => {}}
onSuggestionsFetchRequested={() => {}}
/>
)
}
```
A working example can be found in
[`example/components/autocomplete.js`](https://github.com/olahol/react-tagsinput/blob/master/example/components/autocomplete.js).
##### How do I control the value of the input box?
Use `inputValue` and `onChangeInput`:
```js
class Example extends React.Component {
constructor() {
super()
this.state = {tags: [], tag: ''}
}
handleChange(tags) {
this.setState({tags})
}
handleChangeInput(tag) {
this.setState({tag})
}
render() {
return (
<TagsInput
value={this.state.tags}
onChange={::this.handleChange}
inputValue={this.state.tag}
onChangeInput={::this.handleChangeInput}
/>
)
}
}
```
##### How do I fix warning "unknown prop `addTag`"?
For ease of integration with auto complete components `react-tagsinput`
passes the `addTag` method to `renderInput` props, if you are writing your
own `renderInput` you need to filter `addTag` to not get an error about
`unknown prop addTag` from React. Here is how it's done in the default
`renderInput` function.
```js
function defaultRenderInput ({addTag, ...props}) {
let {onChange, value, ...other} = props
return (
<input type='text' onChange={onChange} value={value} {...other} />
)
}
```
##### How do I copy paste from Excel?
>All you need is to add a CR, carriage return, symbol (it is the default line break style in MS Office documents).
See [answer on Stack Overflow](http://stackoverflow.com/a/42008826/3276759).
Set the `pasteSplit` prop to this function:
```js
pasteSplit(data) {
const separators = [',', ';', '\\(', '\\)', '\\*', '/', ':', '\\?', '\n', '\r'];
return data.split(new RegExp(separators.join('|'))).map(d => d.trim());
}
```
## Component Interface

@@ -242,3 +103,3 @@

An array of key codes that add a tag, default is `[9, 13]` (Tab and Enter).
An array of [keys](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) or [key codes](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which) that add a tag, default is `[9, 13]` (Tab and Enter).

@@ -257,2 +118,6 @@ ##### currentValue

##### validate
Allow only tags that pass this validation function. Gets one argument `tag` which is the tag to validate. Default is `() => true`.
##### validationRegex

@@ -310,6 +175,6 @@

Props passed down to every tag component. Default is:
Props passed down to every tag component. Default is:
```javascript
{
className: 'react-tagsinput-tag',
className: 'react-tagsinput-tag',
classNameRemove: 'react-tagsinput-remove'

@@ -369,10 +234,10 @@ }

Renders the layout of the component. Takes `tagComponents` and `inputComponent` as args. Default is:
Renders the layout of the component. Takes `tagElements` and `inputElement` as args. Default is:
```javascript
function defaultRenderLayout (tagComponents, inputComponent) {
function defaultRenderLayout (tagElements, inputElement) {
return (
<span>
{tagComponents}
{inputComponent}
{tagElements}
{inputElement}
</span>

@@ -412,7 +277,8 @@ )

## Styling
## Contributors
Look at [react-tagsinput.css](./react-tagsinput.css) for a basic style.
<a href="https://github.com/olahol/react-tagsinput/graphs/contributors">
<img src="https://contrib.rocks/image?repo=olahol/react-tagsinput" />
</a>
## [Contributors](./CONTRIBUTORS.md)

@@ -432,12 +298,7 @@ ## [Changelog](./CHANGELOG.md)

[downloads-url]: https://npmjs.org/package/react-tagsinput
[travis-image]: https://img.shields.io/travis/olahol/react-tagsinput/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/olahol/react-tagsinput
[coverage-image]: https://img.shields.io/coveralls/olahol/react-tagsinput.svg?style=flat-square
[coverage-url]: https://coveralls.io/r/olahol/react-tagsinput
[demo-url]: https://github.com/olahol/react-tagsinput/blob/master/example/index.html
[dep-image]: https://david-dm.org/olahol/react-tagsinput/peer-status.svg?style=flat-square
[dep-url]: https://david-dm.org/olahol/react-tagsinput
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
[standard-url]: https://github.com/feross/standard
[size-image]: https://badge-size.herokuapp.com/olahol/react-tagsinput/master/src/index.js?style=flat-square
[size-url]: https://github.com/olahol/react-tagsinput/blob/master/src/index.js
[size-image]: https://badge-size.herokuapp.com/olahol/react-tagsinput/master/react-tagsinput.js?style=flat-square
[size-url]: https://github.com/olahol/react-tagsinput/blob/master/react-tagsinput.js
[codecov-image]: https://img.shields.io/codecov/c/github/olahol/react-tagsinput?style=flat-square
[codecov-url]: https://app.codecov.io/github/olahol/react-tagsinput
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc