mdc-react
Version:
Material Components for the web implemented in React
121 lines (111 loc) • 4.17 kB
JSX
import { forwardRef } from 'react';
import { CSSTransition } from 'react-transition-group';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { numbers, chipCssClasses as cssClasses } from './constants';
import ChipPrimaryAction from './ChipPrimaryAction';
import ChipTrailingAction from './ChipTrailingAction';
const Chip = forwardRef(({
value,
text,
icon,
avatar,
graphic = avatar,
primaryIcon = icon,
trailingIcon,
selectable = false,
filter = false,
selected = false,
outlined = false,
disabled = false,
touch = false,
withAvatar = Boolean(avatar),
element = 'span',
component: Element = element,
className,
...props
}, ref) => {
const withPrimaryGraphic = selectable || Boolean(graphic) || Boolean(primaryIcon);
const withPrimaryIcon = Boolean(primaryIcon);
const withTrailingAction = Boolean(trailingIcon);
const classNames = classnames(cssClasses.ROOT, {
[cssClasses.SELECTABLE]: selectable,
[cssClasses.FILTER]: filter,
[cssClasses.OUTLINED]: outlined,
[cssClasses.DISABLED]: disabled,
[cssClasses.TOUCH]: touch,
[cssClasses.WITH_PRIMARY_GRAPHIC]: withPrimaryGraphic,
[cssClasses.WITH_PRIMARY_ICON]: withPrimaryIcon,
[cssClasses.WITH_TRAILING_ACTION]: withTrailingAction,
[cssClasses.WITH_AVATAR]: withAvatar
}, className);
const selectingClass = withPrimaryIcon ? cssClasses.SELECTING_WITH_PRIMARY_ICON : cssClasses.SELECTING;
const deselectingClass = withPrimaryIcon ? cssClasses.DESELECTING_WITH_PRIMARY_ICON : cssClasses.DESELECTING;
return (
<CSSTransition
in={selected}
appear
timeout={{
enter: numbers.SELECTING_ANIMATION_MS,
exit: numbers.DESELECTING_ANIMATION_MS
}}
classNames={{
enter: selectingClass,
enterActive: `${cssClasses.SELECTED} ${selectingClass}`,
enterDone: cssClasses.SELECTED,
exit: deselectingClass,
exitActive: deselectingClass
}}
>
<Element
ref={ref}
className={classNames}
data-value={value}
role={selectable ? 'presentation' : 'row'}
{...props}
>
{selectable ?
<ChipPrimaryAction
element="span"
text={text}
graphic={graphic}
icon={primaryIcon}
selectable={selectable}
selected={selected}
disabled={disabled}
/>
:
<>
<span className={`${cssClasses.CELL} ${cssClasses.PRIMARY_CELL}`} role="gridcell">
<ChipPrimaryAction
text={text}
graphic={graphic}
icon={primaryIcon}
disabled={disabled}
/>
</span>
{trailingIcon &&
<span className={`${cssClasses.CELL} ${cssClasses.TRAILING_CELL}`} role="gridcell">
<ChipTrailingAction
icon={trailingIcon}
disabled={disabled}
/>
</span>
}
</>
}
</Element>
</CSSTransition>
);
});
Chip.displayName = 'MDCChip';
Chip.propTypes = {
value: PropTypes.any,
text: PropTypes.node,
leadingIcon: PropTypes.node,
trailingIcon: PropTypes.node,
selected: PropTypes.bool,
outlined: PropTypes.bool,
onClick: PropTypes.func
};
export default Chip;