Skip to content

Commit 33d0d7b

Browse files
Merge pull request #208 from i-like-robots/focus-input-on-delete
Add custom click handler for the tag component
2 parents be1270e + b882205 commit 33d0d7b

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

lib/ReactTags.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class ReactTags extends React.Component {
4949
onInput: this.handleInput.bind(this),
5050
onKeyDown: this.handleKeyDown.bind(this)
5151
}
52+
53+
this.container = React.createRef()
5254
}
5355

5456
componentWillReceiveProps (newProps) {
@@ -148,6 +150,26 @@ class ReactTags extends React.Component {
148150
}
149151
}
150152

153+
handleDeleteTag (index, event) {
154+
// Because we'll destroy the element with cursor focus we need to ensure
155+
// it does not get lost and move it to the next interactive element
156+
if (this.container.current) {
157+
const interactiveEls = this.container.current.querySelectorAll('a,button,input')
158+
159+
const currentEl = Array.prototype.findIndex.call(interactiveEls, (element) => {
160+
return element === event.currentTarget
161+
})
162+
163+
const nextEl = interactiveEls[currentEl - 1] || interactiveEls[currentEl + 1]
164+
165+
if (nextEl) {
166+
nextEl.focus()
167+
}
168+
}
169+
170+
this.deleteTag(index)
171+
}
172+
151173
addTag (tag) {
152174
if (tag.disabled) {
153175
return
@@ -184,7 +206,7 @@ class ReactTags extends React.Component {
184206
key={i}
185207
tag={tag}
186208
classNames={this.state.classNames}
187-
onDelete={this.deleteTag.bind(this, i)}
209+
onDelete={this.handleDeleteTag.bind(this, i)}
188210
/>
189211
))
190212

@@ -194,7 +216,7 @@ class ReactTags extends React.Component {
194216
this.state.focused && classNames.push(this.state.classNames.rootFocused)
195217

196218
return (
197-
<div className={classNames.join(' ')} onClick={this.handleClick.bind(this)}>
219+
<div ref={this.container} className={classNames.join(' ')} onClick={this.handleClick.bind(this)}>
198220
<div className={this.state.classNames.selected} aria-live='polite' aria-relevant='additions removals'>
199221
{tags}
200222
</div>

spec/ReactTags.spec.js

+5
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ describe('React Tags', () => {
420420
sinon.assert.calledWith(props.handleDelete, sinon.match(0))
421421
})
422422

423+
it('moves focus to the input when a tag is removed', () => {
424+
click($('.react-tags__selected-tag'))
425+
expect(document.activeElement).toEqual($('input'))
426+
})
427+
423428
it('deletes the last selected tag when backspace is pressed and query is empty', () => {
424429
type(''); key('backspace')
425430

0 commit comments

Comments
 (0)