Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
levithomason committed Jul 12, 2016
1 parent 2a08fbe commit 7f57ef8
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 32 deletions.
6 changes: 1 addition & 5 deletions docs/app/Examples/modules/Checkbox/Types/RadioGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Form, Checkbox } from 'stardust'

export default class CheckboxRadioGroupExample extends Component {
state = {}
handleClick = (e, props) => this.setState({ value: props.value })
// handleClick = (e, props) => this.setState({ value: props.value })

render() {
return (
Expand All @@ -14,8 +14,6 @@ export default class CheckboxRadioGroupExample extends Component {
label='Choose this'
value='this'
name='radioGroup'
onClick={this.handleClick}
checked={this.state.value === 'this'}
/>
</Form.Field>
<Form.Field>
Expand All @@ -24,8 +22,6 @@ export default class CheckboxRadioGroupExample extends Component {
label='Or that'
value='that'
name='radioGroup'
onClick={this.handleClick}
checked={this.state.value === 'that'}
/>
</Form.Field>
</Form>
Expand Down
8 changes: 1 addition & 7 deletions docs/app/Examples/modules/Checkbox/Types/Types.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,7 @@ export default class CheckboxTypesExamples extends Component {
description='A checkbox can be formatted as a radio element. This means it is an exclusive option.'
examplePath='modules/Checkbox/Types/Radio'
/>
<ComponentExample examplePath='modules/Checkbox/Types/RadioGroup'>
<Message>
Radio groups must use
{' '}<a href='http://facebook.github.io/react/docs/forms.html#controlled-components'>controlled</a>
{' '}components.
</Message>
</ComponentExample>
<ComponentExample examplePath='modules/Checkbox/Types/RadioGroup' />
</ExampleSection>
)
}
Expand Down
39 changes: 28 additions & 11 deletions src/modules/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import _ from 'lodash'
import React, { PropTypes } from 'react'
import cx from 'classnames'

Expand Down Expand Up @@ -65,6 +66,10 @@ export default class Checkbox extends AutoControlledComponent {
* You can set `inputType` separately to mix and match appearance and behavior.
*/
type: PropTypes.oneOf(_meta.props.type),

name: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,
}

static defaultProps = {
Expand All @@ -79,23 +84,26 @@ export default class Checkbox extends AutoControlledComponent {

state = {}

// Heads Up!
// the event target here will never be the input, it is hidden
// this will either be the label or the parent div
handleClick = (e) => {
debug('handleClick()')
debug(`checked: ${this.props.checked}`)
const { onClick, name, value, checked } = this.props
if (onClick) onClick(e, { name, value, checked })
this.toggle()
}
const { disabled, onChange, onClick, name, readOnly, value } = this.props
const { checked: isStateChecked } = this.state
// const isInputChecked = _.get(this.refs, 'input.checked')

if (onClick) onClick(e, { name, value, checked: isStateChecked })
if (onChange) onChange(e, { name, value, checked: !isStateChecked })
// TODO onChange, isn't this identical to onClick with a negated checked?

toggle = () => {
debug('toggle()')
const { disabled, readOnly } = this.props
if (disabled || readOnly) return
this.trySetState({ checked: !this.state.checked })
if (!disabled && !readOnly) {
this.trySetState({ checked: !isStateChecked })
}
}

render() {
const { className, label, inputType, type } = this.props
const { className, inputType, label, name, onChange, type, value } = this.props
const { checked } = this.state
const classes = cx(
'ui',
Expand All @@ -113,13 +121,22 @@ export default class Checkbox extends AutoControlledComponent {
<div
className={classes}
onClick={this.handleClick}
onChange={onChange}
{...rest}
>
{/*
Heads Up!
onChange is never called because the user cannot click on the hidden input.
The noop exists only to prevent React warnings about "checked without onChange".
*/}
<input
ref='input'
type={inputType || typeMap[type]}
name={name}
checked={checked}
className='hidden'
tabIndex={0}
value={value}
/>
<label>{label}</label>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/utils/AutoControlledComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default class AutoControlledComponent extends Component {
} else if (prop === 'checked') {
res[prop] = false
} else if (prop === 'value') {
res[prop] = null
res[prop] = ''
}

if (process.env.NODE_ENV !== 'production') {
Expand Down
14 changes: 8 additions & 6 deletions test/specs/modules/Checkbox/Checkbox-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import React from 'react'
import Checkbox from 'src/modules/Checkbox/Checkbox'
import * as common from 'test/specs/commonTests'
import sandbox from 'test/utils/Sandbox-util'
import * as consoleUtil from 'test/utils/consoleUtil'
import * as syntheticEvent from 'test/utils/syntheticEvent'

describe('Checkbox', () => {
common.isConformant(Checkbox)
common.hasUIClassName(Checkbox)

it('can be checked by default', () => {
consoleUtil.disableOnce()
shallow(<Checkbox defaultChecked name='firstName' />)
.find('input')
.should.be.checked()
describe('defaultChecked', () => {
it('sets the initial checked state', () => {
// consoleUtil.disableOnce()
shallow(<Checkbox defaultChecked onChange={_.noop} />)
.find('input')
.should.be.checked()
})
})

it('adds the "fitted" class if no label is given', () => {
Expand Down
4 changes: 2 additions & 2 deletions test/specs/utils/AutoControlledComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ describe('extending AutoControlledComponent', () => {
.should.have.state('checked', false)
})

it('defaults "value" to null if not present', () => {
it('defaults "value" to an empty string if not present', () => {
consoleUtil.disableOnce()
TestClass.autoControlledProps.push('value')

shallow(<TestClass />)
.should.have.state('value', null)
.should.have.state('value', '')
})
})

Expand Down

0 comments on commit 7f57ef8

Please sign in to comment.