Skip to content

Commit

Permalink
Public imperative API
Browse files Browse the repository at this point in the history
It's either this or `props.inputRef`, unless we want to wait for
facebook/react#4213
  • Loading branch information
superbuddyy committed Apr 23, 2017
1 parent b4cd638 commit a6e5e7a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
17 changes: 16 additions & 1 deletion lib/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ const { findDOMNode } = require('react-dom')
const scrollIntoView = require('dom-scroll-into-view')

let _debugStates = []
const IMPERATIVE_API = [
'blur',
'checkValidity',
'click',
'focus',
'select',
'setCustomValidity',
'setSelectionRange',
'setRangeText',
]

let Autocomplete = React.createClass({

Expand Down Expand Up @@ -189,6 +199,11 @@ let Autocomplete = React.createClass({
}
},

exposeAPI(el) {
this.refs.input = el
IMPERATIVE_API.forEach(ev => this[ev] = (el && el[ev] && el[ev].bind(el)))
},

maybeScrollItemIntoView() {
if (this.isOpen() && this.state.highlightedIndex !== null) {
const itemNode = this.refs[`item-${this.state.highlightedIndex}`]
Expand Down Expand Up @@ -454,7 +469,7 @@ let Autocomplete = React.createClass({
aria-autocomplete="list"
aria-expanded={open}
autoComplete="off"
ref={e => this.refs.input = e}
ref={this.exposeAPI}
onFocus={this.composeEventHandlers(this.handleInputFocus, inputProps.onFocus)}
onBlur={this.composeEventHandlers(this.handleInputBlur, inputProps.onBlur)}
onChange={this.handleChange}
Expand Down
18 changes: 18 additions & 0 deletions lib/__tests__/Autocomplete-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,21 @@ describe('Autocomplete#renderMenu', () => {
expect(wrapper.find(Item).length).toBe(50)
})
})

describe('Public imperative API', () => {
it('should expose select APIs available on HTMLInputElement', () => {
const tree = mount(AutocompleteComponentJSX({ value: 'foo' }))
const ac = tree.get(0)
expect(typeof ac.focus).toBe('function')
expect(ac.isInputFocused()).toBe(false)
ac.focus()
expect(ac.isInputFocused()).toBe(true)
expect(typeof ac.setSelectionRange).toBe('function')
ac.setSelectionRange(1, 2)
expect(tree.find('input').get(0).selectionStart).toBe(1)
expect(tree.find('input').get(0).selectionEnd).toBe(2)
expect(typeof ac.blur).toBe('function')
ac.blur()
expect(ac.isInputFocused()).toBe(false)
})
})

0 comments on commit a6e5e7a

Please sign in to comment.