UNPKG

sc-react-ions

Version:

An open source set of React components that implement Ambassador's Design and UX patterns.

146 lines (128 loc) 4.06 kB
import React from 'react' import PropTypes from 'prop-types' import style from './style.scss' import classNames from 'classnames/bind' import Icon from '../Icon' class Checkbox extends React.Component { constructor(props) { super(props) } static defaultProps = { disabled: false, iconName: 'md-check', locked: false } state = { value: this.props.value, iconName: this.props.iconName } static propTypes = { /** * Displays a native checkbox, instead of the custom implementation. */ allowNative: PropTypes.bool, /** * Whether the checkbox is disabled. */ disabled: PropTypes.bool, /** * Value of the input. Sets whether the component is checked or not. */ value: PropTypes.bool, /** * Unique string to be passed to the label 'for' attrbute and the native checkbox 'id', * to allow using label to check/uncheck */ forLabelAttr: PropTypes.string, /** * Node displayed with the checkbox (can be a string). */ label: PropTypes.node, /** * Optional styles to add to the checkbox. */ optClass: PropTypes.string, /** * A callback function to be called when the checkbox changes. */ changeCallback: PropTypes.func, /** * Icon to be used in the checkbox. */ iconName: PropTypes.string, /** * Whether the checkbox is locked from change outside of receiving props. */ locked: PropTypes.bool, /** * Optional description that appears below the label. */ description: PropTypes.string } handleChange = event => { event.persist() // Allow user to interact with locked checkboxes only if the value is false (unchecked) if (!this.props.locked || !this.props.value) { this.setState({ value: event.target.checked }, () => { if (typeof this.props.changeCallback === 'function') { this.props.changeCallback(event) } }) } } componentWillReceiveProps = nextProps => { let newState = {} if (nextProps.value !== this.props.value) { newState.value = nextProps.value } if (nextProps.iconName !== this.state.iconName) { newState.iconName = nextProps.iconName } this.setState(newState) } getLabel = () => { if (this.props.label && this.props.description) { return <div className={style['label-wrapper']}> <label htmlFor={this.props.forLabelAttr}> <span className={style['label-title']}>{this.props.label}</span> <span className={style['label-description']}>{this.props.description}</span> </label> </div> } if (this.props.label) { return <label htmlFor={this.props.forLabelAttr}>{this.props.label}</label> } return null } render = () => { const { optClass, changeCallback, value, disabled, name, label, forLabelAttr, ...other } = this.props const cx = classNames.bind(style) const disabledClass = this.props.disabled ? style['checkbox-disabled'] : '' const allowNativeClass = this.props.allowNative ? style['checkbox-native'] : null const descriptionClass = this.props.description ? style['has-description'] : null const checkboxClass = cx(style['checkbox-component'], allowNativeClass, descriptionClass, disabledClass, optClass) const inputFillColor = this.props.disabled ? '#9198A0' : '#3C97D3' const labelWrapperClass = this.props.description ? style['label-group'] : null return ( <div className={checkboxClass}> <input type='checkbox' id={this.props.forLabelAttr} checked={this.state.value} onChange={this.handleChange} value={value} disabled={disabled} name={name} label={label}></input> <div className={labelWrapperClass}> <div className={style['checkbox-input']}> <Icon name={this.state.iconName} fill={inputFillColor} /> </div> {this.getLabel()} </div> </div> ) } } export default Checkbox