diff --git a/src/elements/Input/Input.js b/src/elements/Input/Input.js index 3abb1619fd..4c23b84c67 100644 --- a/src/elements/Input/Input.js +++ b/src/elements/Input/Input.js @@ -1,6 +1,6 @@ +import cx from 'classnames' import _ from 'lodash' import React, { Children, cloneElement, Component, PropTypes } from 'react' -import cx from 'classnames' import { createHTMLInput, @@ -114,6 +114,8 @@ class Input extends Component { type: META.TYPES.ELEMENT, } + focus = () => (this.inputRef.focus()) + handleChange = (e) => { const { onChange } = this.props const value = _.get(e, 'target.value') @@ -121,9 +123,14 @@ class Input extends Component { onChange(e, { ...this.props, value }) } - focus = () => { - this.inputRef.focus() - } + handleChildOverrides = (child, defaultProps) => ({ + ...defaultProps, + ...child.props, + ref: c => { + _.invoke(child, 'ref', c) + this.handleInputRef(c) + }, + }) handleInputRef = c => (this.inputRef = c) @@ -187,7 +194,7 @@ class Input extends Component { const childElements = _.map(Children.toArray(children), (child) => { if (child.type !== 'input') return child - return cloneElement(child, { ...htmlInputProps, ...child.props }) + return cloneElement(child, this.handleChildOverrides(child, htmlInputProps)) }) return {childElements} diff --git a/test/specs/elements/Input/Input-test.js b/test/specs/elements/Input/Input-test.js index f5648fbad1..dd2f46d8c4 100644 --- a/test/specs/elements/Input/Input-test.js +++ b/test/specs/elements/Input/Input-test.js @@ -53,14 +53,14 @@ describe('Input', () => { common.hasUIClassName(Input) common.rendersChildren(Input) - common.implementsLabelProp(Input, { - shorthandDefaultProps: { className: 'label' }, - }) common.implementsButtonProp(Input, { propKey: 'action', shorthandDefaultProps: { className: 'button' }, }) common.implementsCreateMethod(Input) + common.implementsLabelProp(Input, { + shorthandDefaultProps: { className: 'label' }, + }) common.implementsHTMLInputProp(Input, { alwaysPresent: true, shorthandDefaultProps: { type: 'text' }, @@ -138,6 +138,22 @@ describe('Input', () => { }) }) + describe('focus', () => { + it('can be set via a ref', () => { + const mountNode = document.createElement('div') + document.body.appendChild(mountNode) + + const wrapper = mount(, { attachTo: mountNode }) + wrapper.instance().focus() + + const input = document.querySelector('.ui.input input') + document.activeElement.should.equal(input) + + wrapper.detach() + document.body.removeChild(mountNode) + }) + }) + describe('onChange', () => { it('is called with (e, data) on change', () => { const spy = sandbox.spy() @@ -170,42 +186,47 @@ describe('Input', () => { }) }) + describe('ref', () => { + it('maintains ref on child node', () => { + const ref = sandbox.spy() + const mountNode = document.createElement('div') + document.body.appendChild(mountNode) + + const wrapper = mount(, { attachTo: mountNode }) + const input = document.querySelector('.ui.input input') + + ref.should.have.been.calledOnce() + ref.should.have.been.calledWithMatch(input) + wrapper.instance().inputRef.should.equal(input) + + wrapper.detach() + document.body.removeChild(mountNode) + }) + }) + describe('tabIndex', () => { it('is not set by default', () => { shallow() .find('input') .should.not.have.prop('tabIndex') }) + it('defaults to -1 when disabled', () => { shallow() .find('input') .should.have.prop('tabIndex', -1) }) + it('can be set explicitly', () => { shallow() .find('input') .should.have.prop('tabIndex', 123) }) + it('can be set explicitly when disabled', () => { shallow() .find('input') .should.have.prop('tabIndex', 123) }) }) - - describe('focus', () => { - it('can be set via a ref', () => { - const mountNode = document.createElement('div') - document.body.appendChild(mountNode) - - const wrapper = mount(, { attachTo: mountNode }) - wrapper.instance().focus() - - const input = document.querySelector('.ui.input input') - document.activeElement.should.equal(input) - - wrapper.detach() - document.body.removeChild(mountNode) - }) - }) })