react-tag-autocomplete
Advanced tools
Comparing version 6.2.0 to 6.3.0
# Changelog | ||
## 6.3.0 | ||
- Added `clearSelectedIndex` method to programmatically clear the currently selected suggestion ([joelposti](https://github.com/joelposti)) | ||
## 6.2.0 | ||
@@ -4,0 +7,0 @@ |
@@ -11,7 +11,9 @@ 'use strict'; | ||
var Tag = (props) => ( | ||
React__default['default'].createElement( 'button', { type: 'button', className: props.classNames.selectedTag, title: props.removeButtonText, onClick: props.onDelete }, | ||
React__default['default'].createElement( 'span', { className: props.classNames.selectedTagName }, props.tag.name) | ||
function Tag (props) { | ||
return ( | ||
React__default['default'].createElement( 'button', { type: 'button', className: props.classNames.selectedTag, title: props.removeButtonText, onClick: props.onDelete }, | ||
React__default['default'].createElement( 'span', { className: props.classNames.selectedTagName }, props.tag.name) | ||
) | ||
) | ||
); | ||
} | ||
@@ -114,55 +116,45 @@ const SIZER_STYLES = { | ||
const DefaultSuggestionComponent = ({ item, query }) => ( | ||
React__default['default'].createElement( 'span', { dangerouslySetInnerHTML: { __html: markIt(item.name, query) } }) | ||
); | ||
function DefaultSuggestionComponent ({ item, query }) { | ||
return ( | ||
React__default['default'].createElement( 'span', { dangerouslySetInnerHTML: { __html: markIt(item.name, query) } }) | ||
) | ||
} | ||
class Suggestions extends React__default['default'].Component { | ||
onMouseDown (item, e) { | ||
// focus is shifted on mouse down but calling preventDefault prevents this | ||
e.preventDefault(); | ||
this.props.addTag(item); | ||
} | ||
function Suggestions (props) { | ||
const SuggestionComponent = props.suggestionComponent || DefaultSuggestionComponent; | ||
render () { | ||
if (!this.props.expanded || !this.props.options.length) { | ||
return null | ||
const options = props.options.map((item, index) => { | ||
const key = `${props.id}-${index}`; | ||
const classNames = []; | ||
if (props.index === index) { | ||
classNames.push(props.classNames.suggestionActive); | ||
} | ||
const SuggestionComponent = this.props.suggestionComponent || DefaultSuggestionComponent; | ||
if (item.disabled) { | ||
classNames.push(props.classNames.suggestionDisabled); | ||
} | ||
const options = this.props.options.map((item, index) => { | ||
const key = `${this.props.id}-${index}`; | ||
const classNames = []; | ||
if (this.props.index === index) { | ||
classNames.push(this.props.classNames.suggestionActive); | ||
} | ||
if (item.disabled) { | ||
classNames.push(this.props.classNames.suggestionDisabled); | ||
} | ||
return ( | ||
React__default['default'].createElement( 'li', { | ||
id: key, key: key, role: 'option', className: classNames.join(' '), 'aria-disabled': item.disabled === true, onMouseDown: this.onMouseDown.bind(this, item) }, | ||
item.prefix | ||
? React__default['default'].createElement( 'span', { className: this.props.classNames.suggestionPrefix }, item.prefix, ' ') | ||
: null, | ||
item.disableMarkIt | ||
? item.name | ||
: React__default['default'].createElement( SuggestionComponent, { item: item, query: this.props.query }) | ||
) | ||
) | ||
}); | ||
return ( | ||
React__default['default'].createElement( 'div', { className: this.props.classNames.suggestions }, | ||
React__default['default'].createElement( 'ul', { role: 'listbox', id: this.props.id }, options) | ||
React__default['default'].createElement( 'li', { | ||
id: key, key: key, role: 'option', className: classNames.join(' '), 'aria-disabled': Boolean(item.disabled), onMouseDown: (e) => e.preventDefault(), onClick: () => props.addTag(item) }, | ||
item.prefix | ||
? React__default['default'].createElement( 'span', { className: props.classNames.suggestionPrefix }, item.prefix, ' ') | ||
: null, | ||
item.disableMarkIt | ||
? item.name | ||
: React__default['default'].createElement( SuggestionComponent, { item: item, query: props.query }) | ||
) | ||
) | ||
} | ||
}); | ||
return ( | ||
React__default['default'].createElement( 'div', { className: props.classNames.suggestions }, | ||
React__default['default'].createElement( 'ul', { role: 'listbox', id: props.id }, options) | ||
) | ||
) | ||
} | ||
function focusNextElement(scope, currentTarget) { | ||
const interactiveEls = scope.querySelectorAll("a,button,input"); | ||
function focusNextElement (scope, currentTarget) { | ||
const interactiveEls = scope.querySelectorAll('a,button,input'); | ||
@@ -264,10 +256,6 @@ const currentEl = Array.prototype.findIndex.call( | ||
if (props.allowNew) { | ||
if (props.newTagText && findMatchIndex(options, state.query) === -1) { | ||
options.push({ id: 0, name: state.query, prefix: props.newTagText, disableMarkIt: true }); | ||
} | ||
} else { | ||
if (props.noSuggestionsText && options.length === 0) { | ||
options.push({ id: 0, name: props.noSuggestionsText, disabled: true, disableMarkIt: true }); | ||
} | ||
if (props.allowNew && props.newTagText && findMatchIndex(options, state.query) === -1) { | ||
options.push({ id: 0, name: state.query, prefix: props.newTagText, disableMarkIt: true }); | ||
} else if (props.noSuggestionsText && options.length === 0) { | ||
options.push({ id: 0, name: props.noSuggestionsText, disabled: true, disableMarkIt: true }); | ||
} | ||
@@ -301,3 +289,2 @@ | ||
this.input = React__default['default'].createRef(); | ||
this.suggestions = React__default['default'].createRef(); | ||
} | ||
@@ -352,3 +339,3 @@ | ||
if (document.activeElement !== e.target) { | ||
this.input.current.input.current.focus(); | ||
this.focusInput(); | ||
} | ||
@@ -412,2 +399,12 @@ } | ||
clearSelectedIndex () { | ||
this.setState({ index: -1 }); | ||
} | ||
focusInput () { | ||
if (this.input.current && this.input.current.input.current) { | ||
this.input.current.input.current.focus(); | ||
} | ||
} | ||
render () { | ||
@@ -434,4 +431,6 @@ const TagComponent = this.props.tagComponent || Tag; | ||
this.state, { id: this.props.id, ref: this.input, classNames: classNames, inputAttributes: this.props.inputAttributes, inputEventHandlers: this.inputEventHandlers, autoresize: this.props.autoresize, expanded: expanded, placeholderText: this.props.placeholderText, ariaLabelText: this.props.ariaLabelText })), | ||
React__default['default'].createElement( Suggestions, Object.assign({}, | ||
this.state, { id: this.props.id, ref: this.suggestions, classNames: classNames, expanded: expanded, addTag: this.addTag.bind(this), suggestionComponent: this.props.suggestionComponent })) | ||
expanded && this.state.options.length | ||
? React__default['default'].createElement( Suggestions, Object.assign({}, | ||
this.state, { id: this.props.id, classNames: classNames, expanded: expanded, addTag: this.addTag.bind(this), suggestionComponent: this.props.suggestionComponent })) | ||
: null | ||
) | ||
@@ -438,0 +437,0 @@ ) |
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
var Tag = (props) => ( | ||
React.createElement( 'button', { type: 'button', className: props.classNames.selectedTag, title: props.removeButtonText, onClick: props.onDelete }, | ||
React.createElement( 'span', { className: props.classNames.selectedTagName }, props.tag.name) | ||
function Tag (props) { | ||
return ( | ||
React.createElement( 'button', { type: 'button', className: props.classNames.selectedTag, title: props.removeButtonText, onClick: props.onDelete }, | ||
React.createElement( 'span', { className: props.classNames.selectedTagName }, props.tag.name) | ||
) | ||
) | ||
); | ||
} | ||
@@ -106,55 +108,45 @@ const SIZER_STYLES = { | ||
const DefaultSuggestionComponent = ({ item, query }) => ( | ||
React.createElement( 'span', { dangerouslySetInnerHTML: { __html: markIt(item.name, query) } }) | ||
); | ||
function DefaultSuggestionComponent ({ item, query }) { | ||
return ( | ||
React.createElement( 'span', { dangerouslySetInnerHTML: { __html: markIt(item.name, query) } }) | ||
) | ||
} | ||
class Suggestions extends React.Component { | ||
onMouseDown (item, e) { | ||
// focus is shifted on mouse down but calling preventDefault prevents this | ||
e.preventDefault(); | ||
this.props.addTag(item); | ||
} | ||
function Suggestions (props) { | ||
const SuggestionComponent = props.suggestionComponent || DefaultSuggestionComponent; | ||
render () { | ||
if (!this.props.expanded || !this.props.options.length) { | ||
return null | ||
const options = props.options.map((item, index) => { | ||
const key = `${props.id}-${index}`; | ||
const classNames = []; | ||
if (props.index === index) { | ||
classNames.push(props.classNames.suggestionActive); | ||
} | ||
const SuggestionComponent = this.props.suggestionComponent || DefaultSuggestionComponent; | ||
if (item.disabled) { | ||
classNames.push(props.classNames.suggestionDisabled); | ||
} | ||
const options = this.props.options.map((item, index) => { | ||
const key = `${this.props.id}-${index}`; | ||
const classNames = []; | ||
if (this.props.index === index) { | ||
classNames.push(this.props.classNames.suggestionActive); | ||
} | ||
if (item.disabled) { | ||
classNames.push(this.props.classNames.suggestionDisabled); | ||
} | ||
return ( | ||
React.createElement( 'li', { | ||
id: key, key: key, role: 'option', className: classNames.join(' '), 'aria-disabled': item.disabled === true, onMouseDown: this.onMouseDown.bind(this, item) }, | ||
item.prefix | ||
? React.createElement( 'span', { className: this.props.classNames.suggestionPrefix }, item.prefix, ' ') | ||
: null, | ||
item.disableMarkIt | ||
? item.name | ||
: React.createElement( SuggestionComponent, { item: item, query: this.props.query }) | ||
) | ||
) | ||
}); | ||
return ( | ||
React.createElement( 'div', { className: this.props.classNames.suggestions }, | ||
React.createElement( 'ul', { role: 'listbox', id: this.props.id }, options) | ||
React.createElement( 'li', { | ||
id: key, key: key, role: 'option', className: classNames.join(' '), 'aria-disabled': Boolean(item.disabled), onMouseDown: (e) => e.preventDefault(), onClick: () => props.addTag(item) }, | ||
item.prefix | ||
? React.createElement( 'span', { className: props.classNames.suggestionPrefix }, item.prefix, ' ') | ||
: null, | ||
item.disableMarkIt | ||
? item.name | ||
: React.createElement( SuggestionComponent, { item: item, query: props.query }) | ||
) | ||
) | ||
} | ||
}); | ||
return ( | ||
React.createElement( 'div', { className: props.classNames.suggestions }, | ||
React.createElement( 'ul', { role: 'listbox', id: props.id }, options) | ||
) | ||
) | ||
} | ||
function focusNextElement(scope, currentTarget) { | ||
const interactiveEls = scope.querySelectorAll("a,button,input"); | ||
function focusNextElement (scope, currentTarget) { | ||
const interactiveEls = scope.querySelectorAll('a,button,input'); | ||
@@ -256,10 +248,6 @@ const currentEl = Array.prototype.findIndex.call( | ||
if (props.allowNew) { | ||
if (props.newTagText && findMatchIndex(options, state.query) === -1) { | ||
options.push({ id: 0, name: state.query, prefix: props.newTagText, disableMarkIt: true }); | ||
} | ||
} else { | ||
if (props.noSuggestionsText && options.length === 0) { | ||
options.push({ id: 0, name: props.noSuggestionsText, disabled: true, disableMarkIt: true }); | ||
} | ||
if (props.allowNew && props.newTagText && findMatchIndex(options, state.query) === -1) { | ||
options.push({ id: 0, name: state.query, prefix: props.newTagText, disableMarkIt: true }); | ||
} else if (props.noSuggestionsText && options.length === 0) { | ||
options.push({ id: 0, name: props.noSuggestionsText, disabled: true, disableMarkIt: true }); | ||
} | ||
@@ -293,3 +281,2 @@ | ||
this.input = React.createRef(); | ||
this.suggestions = React.createRef(); | ||
} | ||
@@ -344,3 +331,3 @@ | ||
if (document.activeElement !== e.target) { | ||
this.input.current.input.current.focus(); | ||
this.focusInput(); | ||
} | ||
@@ -404,2 +391,12 @@ } | ||
clearSelectedIndex () { | ||
this.setState({ index: -1 }); | ||
} | ||
focusInput () { | ||
if (this.input.current && this.input.current.input.current) { | ||
this.input.current.input.current.focus(); | ||
} | ||
} | ||
render () { | ||
@@ -426,4 +423,6 @@ const TagComponent = this.props.tagComponent || Tag; | ||
this.state, { id: this.props.id, ref: this.input, classNames: classNames, inputAttributes: this.props.inputAttributes, inputEventHandlers: this.inputEventHandlers, autoresize: this.props.autoresize, expanded: expanded, placeholderText: this.props.placeholderText, ariaLabelText: this.props.ariaLabelText })), | ||
React.createElement( Suggestions, Object.assign({}, | ||
this.state, { id: this.props.id, ref: this.suggestions, classNames: classNames, expanded: expanded, addTag: this.addTag.bind(this), suggestionComponent: this.props.suggestionComponent })) | ||
expanded && this.state.options.length | ||
? React.createElement( Suggestions, Object.assign({}, | ||
this.state, { id: this.props.id, classNames: classNames, expanded: expanded, addTag: this.addTag.bind(this), suggestionComponent: this.props.suggestionComponent })) | ||
: null | ||
) | ||
@@ -430,0 +429,0 @@ ) |
@@ -12,7 +12,9 @@ (function (global, factory) { | ||
function Tag (props) { return ( | ||
React__default['default'].createElement( 'button', { type: 'button', className: props.classNames.selectedTag, title: props.removeButtonText, onClick: props.onDelete }, | ||
React__default['default'].createElement( 'span', { className: props.classNames.selectedTagName }, props.tag.name) | ||
function Tag (props) { | ||
return ( | ||
React__default['default'].createElement( 'button', { type: 'button', className: props.classNames.selectedTag, title: props.removeButtonText, onClick: props.onDelete }, | ||
React__default['default'].createElement( 'span', { className: props.classNames.selectedTagName }, props.tag.name) | ||
) | ||
) | ||
); } | ||
} | ||
@@ -135,3 +137,3 @@ var SIZER_STYLES = { | ||
var DefaultSuggestionComponent = function (ref) { | ||
function DefaultSuggestionComponent (ref) { | ||
var item = ref.item; | ||
@@ -141,67 +143,43 @@ var query = ref.query; | ||
return ( | ||
React__default['default'].createElement( 'span', { dangerouslySetInnerHTML: { __html: markIt(item.name, query) } }) | ||
); | ||
}; | ||
React__default['default'].createElement( 'span', { dangerouslySetInnerHTML: { __html: markIt(item.name, query) } }) | ||
) | ||
} | ||
var Suggestions = /*@__PURE__*/(function (superclass) { | ||
function Suggestions () { | ||
superclass.apply(this, arguments); | ||
} | ||
function Suggestions (props) { | ||
var SuggestionComponent = props.suggestionComponent || DefaultSuggestionComponent; | ||
if ( superclass ) Suggestions.__proto__ = superclass; | ||
Suggestions.prototype = Object.create( superclass && superclass.prototype ); | ||
Suggestions.prototype.constructor = Suggestions; | ||
var options = props.options.map(function (item, index) { | ||
var key = (props.id) + "-" + index; | ||
var classNames = []; | ||
Suggestions.prototype.onMouseDown = function onMouseDown (item, e) { | ||
// focus is shifted on mouse down but calling preventDefault prevents this | ||
e.preventDefault(); | ||
this.props.addTag(item); | ||
}; | ||
if (props.index === index) { | ||
classNames.push(props.classNames.suggestionActive); | ||
} | ||
Suggestions.prototype.render = function render () { | ||
var this$1$1 = this; | ||
if (!this.props.expanded || !this.props.options.length) { | ||
return null | ||
if (item.disabled) { | ||
classNames.push(props.classNames.suggestionDisabled); | ||
} | ||
var SuggestionComponent = this.props.suggestionComponent || DefaultSuggestionComponent; | ||
var options = this.props.options.map(function (item, index) { | ||
var key = (this$1$1.props.id) + "-" + index; | ||
var classNames = []; | ||
if (this$1$1.props.index === index) { | ||
classNames.push(this$1$1.props.classNames.suggestionActive); | ||
} | ||
if (item.disabled) { | ||
classNames.push(this$1$1.props.classNames.suggestionDisabled); | ||
} | ||
return ( | ||
React__default['default'].createElement( 'li', { | ||
id: key, key: key, role: 'option', className: classNames.join(' '), 'aria-disabled': item.disabled === true, onMouseDown: this$1$1.onMouseDown.bind(this$1$1, item) }, | ||
item.prefix | ||
? React__default['default'].createElement( 'span', { className: this$1$1.props.classNames.suggestionPrefix }, item.prefix, ' ') | ||
: null, | ||
item.disableMarkIt | ||
? item.name | ||
: React__default['default'].createElement( SuggestionComponent, { item: item, query: this$1$1.props.query }) | ||
) | ||
) | ||
}); | ||
return ( | ||
React__default['default'].createElement( 'div', { className: this.props.classNames.suggestions }, | ||
React__default['default'].createElement( 'ul', { role: 'listbox', id: this.props.id }, options) | ||
React__default['default'].createElement( 'li', { | ||
id: key, key: key, role: 'option', className: classNames.join(' '), 'aria-disabled': Boolean(item.disabled), onMouseDown: function (e) { return e.preventDefault(); }, onClick: function () { return props.addTag(item); } }, | ||
item.prefix | ||
? React__default['default'].createElement( 'span', { className: props.classNames.suggestionPrefix }, item.prefix, ' ') | ||
: null, | ||
item.disableMarkIt | ||
? item.name | ||
: React__default['default'].createElement( SuggestionComponent, { item: item, query: props.query }) | ||
) | ||
) | ||
}; | ||
}); | ||
return Suggestions; | ||
}(React__default['default'].Component)); | ||
return ( | ||
React__default['default'].createElement( 'div', { className: props.classNames.suggestions }, | ||
React__default['default'].createElement( 'ul', { role: 'listbox', id: props.id }, options) | ||
) | ||
) | ||
} | ||
function focusNextElement(scope, currentTarget) { | ||
var interactiveEls = scope.querySelectorAll("a,button,input"); | ||
function focusNextElement (scope, currentTarget) { | ||
var interactiveEls = scope.querySelectorAll('a,button,input'); | ||
@@ -303,10 +281,6 @@ var currentEl = Array.prototype.findIndex.call( | ||
if (props.allowNew) { | ||
if (props.newTagText && findMatchIndex(options, state.query) === -1) { | ||
options.push({ id: 0, name: state.query, prefix: props.newTagText, disableMarkIt: true }); | ||
} | ||
} else { | ||
if (props.noSuggestionsText && options.length === 0) { | ||
options.push({ id: 0, name: props.noSuggestionsText, disabled: true, disableMarkIt: true }); | ||
} | ||
if (props.allowNew && props.newTagText && findMatchIndex(options, state.query) === -1) { | ||
options.push({ id: 0, name: state.query, prefix: props.newTagText, disableMarkIt: true }); | ||
} else if (props.noSuggestionsText && options.length === 0) { | ||
options.push({ id: 0, name: props.noSuggestionsText, disabled: true, disableMarkIt: true }); | ||
} | ||
@@ -340,3 +314,2 @@ | ||
this.input = React__default['default'].createRef(); | ||
this.suggestions = React__default['default'].createRef(); | ||
} | ||
@@ -395,3 +368,3 @@ | ||
if (document.activeElement !== e.target) { | ||
this.input.current.input.current.focus(); | ||
this.focusInput(); | ||
} | ||
@@ -455,2 +428,12 @@ }; | ||
ReactTags.prototype.clearSelectedIndex = function clearSelectedIndex () { | ||
this.setState({ index: -1 }); | ||
}; | ||
ReactTags.prototype.focusInput = function focusInput () { | ||
if (this.input.current && this.input.current.input.current) { | ||
this.input.current.input.current.focus(); | ||
} | ||
}; | ||
ReactTags.prototype.render = function render () { | ||
@@ -479,4 +462,6 @@ var this$1$1 = this; | ||
this.state, { id: this.props.id, ref: this.input, classNames: classNames, inputAttributes: this.props.inputAttributes, inputEventHandlers: this.inputEventHandlers, autoresize: this.props.autoresize, expanded: expanded, placeholderText: this.props.placeholderText, ariaLabelText: this.props.ariaLabelText })), | ||
React__default['default'].createElement( Suggestions, Object.assign({}, | ||
this.state, { id: this.props.id, ref: this.suggestions, classNames: classNames, expanded: expanded, addTag: this.addTag.bind(this), suggestionComponent: this.props.suggestionComponent })) | ||
expanded && this.state.options.length | ||
? React__default['default'].createElement( Suggestions, Object.assign({}, | ||
this.state, { id: this.props.id, classNames: classNames, expanded: expanded, addTag: this.addTag.bind(this), suggestionComponent: this.props.suggestionComponent })) | ||
: null | ||
) | ||
@@ -483,0 +468,0 @@ ) |
{ | ||
"name": "react-tag-autocomplete", | ||
"version": "6.2.0", | ||
"version": "6.3.0", | ||
"description": "React Tag Autocomplete is a simple tagging component ready to drop in your React projects.", | ||
@@ -42,3 +42,4 @@ "main": "dist/ReactTags.cjs.js", | ||
"Alexander Nestorov", | ||
"Lars Haßler" | ||
"Lars Haßler", | ||
"Joel Posti" | ||
], | ||
@@ -45,0 +46,0 @@ "license": "MIT", |
# React Tag Autocomplete | ||
[![Build status](https://api.travis-ci.org/i-like-robots/react-tags.svg?branch=master)](https://travis-ci.org/i-like-robots/react-tags) [![Coverage Status](https://coveralls.io/repos/github/i-like-robots/react-tags/badge.svg?branch=master)](https://coveralls.io/github/i-like-robots/react-tags) | ||
[![Build status](https://api.travis-ci.com/i-like-robots/react-tags.svg?branch=main)](https://travis-ci.com/i-like-robots/react-tags) [![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) | ||
@@ -332,5 +332,12 @@ 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/). | ||
Clears the input and current query. | ||
Clears the input, current query and selected suggestion. | ||
#### `clearSelectedIndex()` | ||
Clears the currently selected suggestion. | ||
#### `focusInput()` | ||
Sets cursor focus to the text input element. | ||
### Styling | ||
@@ -337,0 +344,0 @@ |
370
69946
1288