Skip to content

Commit

Permalink
fix(Input): spread input props on the input child (#916)
Browse files Browse the repository at this point in the history
* docs(Input): update children usage

* fix(Input): spread input props on the input child
  • Loading branch information
levithomason committed Nov 22, 2016
1 parent 0551527 commit ac08746
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const options = [
]

const InputExampleActions = () => (
<Input action>
<input type='text' placeholder='Search...' />
<Input type='text' placeholder='Search...' action>
<input />
<Select compact options={options} defaultValue='articles' />
<Button type='submit'>Search</Button>
</Input>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { Icon, Input } from 'semantic-ui-react'

const InputExampleIconChild = () => (
<div>
<Input icon>
<input placeholder='Search...' />
<Input icon placeholder='Search...'>
<input />
<Icon name='search' />
</Input>
<br />
<br />
<Input iconPosition='left'>
<Input iconPosition='left' placeholder='Email'>
<Icon name='at' />
<input placeholder='Email' />
<input />
</Input>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react'
import { Input, Label } from 'semantic-ui-react'

const InputExampleRightLeftLabeled = () => (
<Input labelPosition='right' placeholder='mysite.com'>
<Input labelPosition='right' type='text' placeholder='Amount'>
<Label basic>$</Label>
<input type='text' placeholder='Amount' />
<input />
<Label>.00</Label>
</Input>
)
Expand Down
6 changes: 3 additions & 3 deletions docs/app/Examples/elements/Input/Variations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const InputVariationsExamples = () => (
examplePath='elements/Input/Variations/InputExampleIconChild'
>
<Message warning>
When using <code>children</code>, you must add your own <code>{'<input />'}</code>.
When using <code>children</code>, you must add a placeholder <code>{'<input />'}</code>.
</Message>
</ComponentExample>
<ComponentExample
Expand All @@ -49,7 +49,7 @@ const InputVariationsExamples = () => (
>
<Message warning>
Multiple Labels require <code>children</code>.
When using <code>children</code>, you must add your own <code>{'<input />'}</code>.
When using <code>children</code>, you must add a placeholder <code>{'<input />'}</code>.
</Message>
</ComponentExample>
<ComponentExample examplePath='elements/Input/Variations/InputExampleRightLabeledTag' />
Expand All @@ -71,7 +71,7 @@ const InputVariationsExamples = () => (
<ComponentExample examplePath='elements/Input/Variations/InputExampleActions'>
<Message warning>
Multiple Actions require <code>children</code>.
When using <code>children</code>, you must add your own <code>{'<input />'}</code>.
When using <code>children</code>, you must add a placeholder <code>{'<input />'}</code>.
</Message>
</ComponentExample>
<ComponentExample examplePath='elements/Input/Variations/InputExampleActionLabeledButton' />
Expand Down
11 changes: 9 additions & 2 deletions src/elements/Input/Input.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from 'lodash'
import React, { Component, PropTypes } from 'react'
import React, { Children, cloneElement, Component, PropTypes } from 'react'
import cx from 'classnames'

import {
Expand Down Expand Up @@ -202,7 +202,14 @@ class Input extends Component {
const ElementType = getElementType(Input, this.props)

if (children) {
return <ElementType {...rest} className={classes}>{children}</ElementType>
// add htmlInputProps to the `<input />` child
const childElements = Children.map(children, (child) => {
if (child.type !== 'input') return child

return cloneElement(child, { ...htmlInputProps, ...child.props })
})

return <ElementType {...rest} className={classes}>{childElements}</ElementType>
}

const actionElement = Button.create(action, elProps => ({
Expand Down
35 changes: 35 additions & 0 deletions test/specs/elements/Input/Input-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,24 @@ describe('Input', () => {
.find('input')
.should.have.prop(propName, expectedValue)
})

it(`passes \`${propName}\` to the <input> when using children`, () => {
const propValue = propName === 'onChange' ? () => null : 'foo'
const wrapper = shallow(
<Input {...{ [propName]: propValue }}>
<input />
</Input>
)

// account for overloading the onChange prop
const expectedValue = propName === 'onChange'
? wrapper.instance().handleChange
: propValue

wrapper
.find('input')
.should.have.prop(propName, expectedValue)
})
})
})

Expand All @@ -128,5 +146,22 @@ describe('Input', () => {
spy.should.have.been.calledOnce()
spy.should.have.been.calledWithMatch(e, { ...props, value: e.target.value })
})

it('is called with (e, data) on change when using children', () => {
const spy = sandbox.spy()
const e = { target: { value: 'name' } }
const props = { 'data-foo': 'bar', onChange: spy }

const wrapper = shallow(
<Input {...props}>
<input />
</Input>
)

wrapper.find('input').simulate('change', e)

spy.should.have.been.calledOnce()
spy.should.have.been.calledWithMatch(e, { ...props, value: e.target.value })
})
})
})

0 comments on commit ac08746

Please sign in to comment.