From 81cccc73c9a885b345abe622e3a6e077cd31d183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Tegn=C3=A9r?= Date: Sat, 3 Sep 2016 19:57:39 +0300 Subject: [PATCH] Public imperative API It's either this or `props.inputRef`, unless we want to wait for https://github.com/facebook/react/issues/4213 --- lib/Autocomplete.js | 17 ++++++++++++++++- lib/__tests__/Autocomplete-test.js | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js index 05b7ea12..97123ba7 100644 --- a/lib/Autocomplete.js +++ b/lib/Autocomplete.js @@ -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({ @@ -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}`] @@ -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} diff --git a/lib/__tests__/Autocomplete-test.js b/lib/__tests__/Autocomplete-test.js index c4805f53..9b67cf42 100644 --- a/lib/__tests__/Autocomplete-test.js +++ b/lib/__tests__/Autocomplete-test.js @@ -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) + }) +})