Skip to content

Commit a6e5e7a

Browse files
committed
Public imperative API
It's either this or `props.inputRef`, unless we want to wait for facebook/react#4213
1 parent b4cd638 commit a6e5e7a

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

lib/Autocomplete.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ const { findDOMNode } = require('react-dom')
44
const scrollIntoView = require('dom-scroll-into-view')
55

66
let _debugStates = []
7+
const IMPERATIVE_API = [
8+
'blur',
9+
'checkValidity',
10+
'click',
11+
'focus',
12+
'select',
13+
'setCustomValidity',
14+
'setSelectionRange',
15+
'setRangeText',
16+
]
717

818
let Autocomplete = React.createClass({
919

@@ -189,6 +199,11 @@ let Autocomplete = React.createClass({
189199
}
190200
},
191201

202+
exposeAPI(el) {
203+
this.refs.input = el
204+
IMPERATIVE_API.forEach(ev => this[ev] = (el && el[ev] && el[ev].bind(el)))
205+
},
206+
192207
maybeScrollItemIntoView() {
193208
if (this.isOpen() && this.state.highlightedIndex !== null) {
194209
const itemNode = this.refs[`item-${this.state.highlightedIndex}`]
@@ -454,7 +469,7 @@ let Autocomplete = React.createClass({
454469
aria-autocomplete="list"
455470
aria-expanded={open}
456471
autoComplete="off"
457-
ref={e => this.refs.input = e}
472+
ref={this.exposeAPI}
458473
onFocus={this.composeEventHandlers(this.handleInputFocus, inputProps.onFocus)}
459474
onBlur={this.composeEventHandlers(this.handleInputBlur, inputProps.onBlur)}
460475
onChange={this.handleChange}

lib/__tests__/Autocomplete-test.js

+18
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,21 @@ describe('Autocomplete#renderMenu', () => {
427427
expect(wrapper.find(Item).length).toBe(50)
428428
})
429429
})
430+
431+
describe('Public imperative API', () => {
432+
it('should expose select APIs available on HTMLInputElement', () => {
433+
const tree = mount(AutocompleteComponentJSX({ value: 'foo' }))
434+
const ac = tree.get(0)
435+
expect(typeof ac.focus).toBe('function')
436+
expect(ac.isInputFocused()).toBe(false)
437+
ac.focus()
438+
expect(ac.isInputFocused()).toBe(true)
439+
expect(typeof ac.setSelectionRange).toBe('function')
440+
ac.setSelectionRange(1, 2)
441+
expect(tree.find('input').get(0).selectionStart).toBe(1)
442+
expect(tree.find('input').get(0).selectionEnd).toBe(2)
443+
expect(typeof ac.blur).toBe('function')
444+
ac.blur()
445+
expect(ac.isInputFocused()).toBe(false)
446+
})
447+
})

0 commit comments

Comments
 (0)