All files / components/Switch Switch.jsx

100% Statements 12/12
50% Branches 1/2
100% Functions 0/0
100% Lines 12/12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123          120x           120x                       120x                                                                       120x               38x                   52x   52x                                                             31x   31x   31x 31x 31x            
import _ from 'lodash';
import React from 'react';
import { lucidClassNames } from '../../util/style-helpers';
import { createClass, omitProps } from '../../util/component-types';
 
const cx = lucidClassNames.bind('&-Switch');
const {
	bool,
	func,
	object,
	string,
} = React.PropTypes;
 
/**
 * {"categories": ["controls", "toggles"]}
 *
 * This is a toggle -- a component that is in one of two particular states at
 * any given moment in time -- that uses a visualization of a physical on/off
 * switch made popular by smartphone OSes to reflect its current state.
 *
 * It uses a hidden native check box control under the hood but leverages other
 * HTML elements to visualize its state.
 */
const Switch = createClass({
	displayName: 'Switch',
	propTypes: {
		/**
		 * Appended to the component-specific class names set on the root
		 * element.
		 */
		className: string,
 
		/**
		 * Indicates whether the component should appear and act disabled by
		 * having a "greyed out" palette and ignoring user interactions.
		 */
		isDisabled: bool,
 
		/**
		 * Indicates that the component is in the "selected" state when true
		 * and in the "unselected" state when false.
		 */
		isSelected: bool,
 
		/**
		 * Called when the user clicks on the component or when they press the
		 * space key while the component is in focus.
		 *
		 * Signature: `(isSelected, { event, props }) => {}`
		 */
		onSelect: func,
 
		/**
		 * Passed through to the root element.
		 */
		style: object,
	},
 
	getDefaultProps() {
		return {
			isDisabled: false,
			isSelected: false,
			onSelect: _.noop,
		};
	},
 
	componentDidMount() {
		this.nativeElement = this.refs.nativeElement;
	},
 
	render() {
		const {
			className,
			isDisabled,
			isSelected,
			style,
			...passThroughs,
		} = this.props;
 
		return (
			<span
					className={cx('&', {
						'&-is-disabled': isDisabled,
						'&-is-selected': isSelected,
					}, className)}
					onClick={this.handleClicked}
					onTouchEnd={this.handleClicked}
					style={style}
			>
				<input
						onChange={_.noop}
						{...omitProps(passThroughs, Switch, 'children')}
						checked={isSelected}
						className={cx('&-native')}
						disabled={isDisabled}
						ref='nativeElement'
						type='checkbox'
				/>
				<span className={cx('&-visualization-container')} />
				<span className={cx('&-visualization-glow')} />
				<span className={cx('&-visualization-handle')} />
			</span>
		);
	},
 
	handleClicked(event) {
		const {
			isDisabled,
			isSelected,
			onSelect,
		} = this.props;
 
		event.preventDefault();
 
		Eif (!isDisabled) {
			onSelect(!isSelected, { event, props: this.props });
			this.nativeElement.focus();
		}
	},
});
 
export default Switch;