@hackplan/polaris
Version:
Shopify’s product component library
70 lines (69 loc) • 3.17 kB
JavaScript
import React from 'react';
import { MinusMinor, TickSmallMinor } from '@shopify/polaris-icons';
import { createUniqueIDFactory } from '@shopify/javascript-utilities/other';
import { classNames } from '../../utilities/css';
import { withAppProvider } from '../AppProvider';
import Choice, { helpTextID } from '../Choice';
import Icon from '../Icon';
import { Key } from '../../types';
import styles from './Checkbox.scss';
const getUniqueID = createUniqueIDFactory('Checkbox');
class Checkbox extends React.PureComponent {
constructor() {
super(...arguments);
this.inputNode = React.createRef();
this.handleInput = () => {
const { onChange, id, disabled } = this.props;
if (onChange == null || this.inputNode.current == null || disabled) {
return;
}
onChange(!this.inputNode.current.checked, id);
this.inputNode.current.focus();
};
this.handleKeyUp = (event) => {
const { keyCode } = event;
if (keyCode !== Key.Space)
return;
this.handleInput();
};
}
render() {
const { id = getUniqueID(), label, labelHidden, helpText, checked = false, error, disabled, onFocus, onBlur, name, value, } = this.props;
const describedBy = [];
if (error) {
describedBy.push(`${id}Error`);
}
if (helpText) {
describedBy.push(helpTextID(id));
}
const ariaDescribedBy = describedBy.length
? describedBy.join(' ')
: undefined;
const wrapperClassName = classNames(styles.Checkbox, error && styles.error);
const isIndeterminate = checked === 'indeterminate';
const isChecked = !isIndeterminate && Boolean(checked);
const indeterminateAttributes = isIndeterminate
? { indeterminate: 'true', 'aria-checked': 'mixed' }
: { 'aria-checked': isChecked };
const iconSource = isIndeterminate ? MinusMinor : TickSmallMinor;
const inputClassName = classNames(styles.Input, isIndeterminate && styles['Input-indeterminate']);
return (
/* eslint-disable jsx-a11y/no-redundant-roles */
<Choice id={id} label={label} labelHidden={labelHidden} helpText={helpText} error={error} disabled={disabled} onClick={this.handleInput}>
<span className={wrapperClassName}>
<input onKeyUp={this.handleKeyUp} ref={this.inputNode} id={id} name={name} value={value} type="checkbox" checked={isChecked} disabled={disabled} className={inputClassName} onFocus={onFocus} onBlur={onBlur} onClick={stopPropagation} onChange={noop} aria-invalid={error != null} aria-describedby={ariaDescribedBy} role="checkbox" {...indeterminateAttributes}/>
<span className={styles.Backdrop}/>
<span className={styles.Icon}>
<Icon source={iconSource}/>
</span>
</span>
</Choice>
/* eslint-enable jsx-a11y/no-redundant-roles */
);
}
}
function noop() { }
function stopPropagation(event) {
event.stopPropagation();
}
export default withAppProvider()(Checkbox);