mdc-react
Version:
Material Components for the web implemented in React
71 lines (60 loc) • 2.27 kB
JSX
import { Children, forwardRef, useCallback } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { isUndefined, isArray } from '../types';
import { clone, create } from '../component';
import { chipSetCssClasses as cssClasses } from './constants';
import Chip from './Chip';
const ChipSet = forwardRef(({
value,
chips,
input = false,
choice = (!input && !isUndefined(value) && !isArray(value)),
filter = (!input && !isUndefined(value) && isArray(value)),
overflow = false,
onChange = Function.prototype,
element = 'div',
component: Element = element,
className,
children = chips?.map(chip => create(Chip, chip)),
...props
}, ref) => {
const handleClick = useCallback(event => {
const chipValue = event.currentTarget.dataset.value;
const newValue = choice ? chipValue :
(value.includes(chipValue) ?
value.filter(v => v !== chipValue) :
value.concat(chipValue)
);
onChange(newValue);
}, [value, choice, onChange]);
const classNames = classnames(cssClasses.ROOT, {
[cssClasses.OVERFLOW]: overflow
}, className);
return (
<Element ref={ref} className={classNames} role={filter ? 'listbox' : 'grid'} {...props}>
<div className={cssClasses.CHIPS} role="presentation">
{isUndefined(value) ? children :
Children.map(children, chip => {
const chipValue = chip.props.value;
return clone(chip, {
selectable: true,
selected: choice ? value === chipValue : value.includes(chipValue),
onClickCapture: (choice || filter) ? handleClick : undefined,
});
})
}
</div>
</Element>
);
});
ChipSet.displayName = 'MDCChipSet';
ChipSet.propTypes = {
value: PropTypes.any,
input: PropTypes.bool,
choice: PropTypes.bool,
filter: PropTypes.bool,
overflow: PropTypes.bool,
onChange: PropTypes.func
};
export default ChipSet;