UNPKG

wix-style-react

Version:
191 lines (166 loc) • 4.86 kB
import React from 'react'; import PropTypes from 'prop-types'; import { st, classes } from './Tag.st.css'; import CloseButton from '../CloseButton'; import Text from '../Text'; import { dataHooks } from './Tag.helpers'; import { FontUpgradeContext } from '../FontUpgrade/context'; import { generateDataAttr } from '../utils/generateDataAttr'; const tagToTextSize = { tiny: 'tiny', small: 'small', medium: 'small', large: 'medium', }; const noop = () => ({}); /** * A Tag component */ class Tag extends React.PureComponent { static displayName = 'Tag'; _renderThumb() { const { thumb } = this.props; return thumb ? ( <span data-hook={dataHooks.thumb} className={classes.thumb}> {thumb} </span> ) : null; } _renderText({ isMadefor }) { const { size, children, disabled, theme } = this.props; return ( <Text skin={disabled ? 'disabled' : 'standard'} light={theme === 'dark'} secondary={theme !== 'dark'} ellipsis size={tagToTextSize[size]} weight={isMadefor || size === 'tiny' ? 'thin' : 'normal'} className={classes.text} dataHook={dataHooks.text} > {children} </Text> ); } _renderRemoveButton() { const { removable, disabled, size, theme } = this.props; if (removable) { return ( <CloseButton size={size === 'large' ? 'medium' : 'small'} skin={theme === 'dark' ? 'light' : 'dark'} disabled={disabled} dataHook={dataHooks.removeButton} className={classes.removeButton} onClick={this._handleRemoveClick} /> ); } else { return null; } } _handleRemoveClick = event => { const { onRemove, id } = this.props; event.stopPropagation(); onRemove(id); }; _handleOnClick = event => { const { id, onClick } = this.props; return onClick && onClick(id, event); }; render() { const { id, onClick, maxWidth, dataHook, size, disabled, theme, thumb, removable, className, } = this.props; const clickable = !!onClick; const hoverable = !disabled && !!onClick; return ( <FontUpgradeContext.Consumer> {({ active: isMadefor }) => ( <span className={st( classes.root, { withRemoveButton: removable, withThumb: !!thumb, disabled, clickable, hoverable, size, theme, }, className, )} {...generateDataAttr({ ...this.props, hoverable, clickable }, [ 'size', 'disabled', 'theme', 'hoverable', 'clickable', ])} data-hook={dataHook} id={id} onClick={this._handleOnClick} style={{ maxWidth: `${maxWidth}px` }} > {this._renderThumb()} {this._renderText({ isMadefor })} {this._renderRemoveButton()} </span> )} </FontUpgradeContext.Consumer> ); } } Tag.propTypes = { /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: PropTypes.string, /** Sets the text of the tag */ children: PropTypes.node.isRequired, /** Specifies whether the tag should be disabled */ disabled: PropTypes.bool, /** Assigns an unique identifier for the tag */ id: PropTypes.string.isRequired, /** Defines a callback function which is called whenever a tag component is clicked. * It passes the id property as the first parameter and a mouse event as second parameter. */ onClick: PropTypes.func, /** Defines a callback function which is called when removing the tag. It passes the id property as a parameter. */ onRemove: PropTypes.func, /** Specifies whether the tag is removable or not. If enabled, a small clickable X icon is displayed on the right side of a component. */ removable: PropTypes.bool, /** Controls the size of the component */ size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large']), /** Sets the theme of the component */ theme: PropTypes.oneOf([ 'standard', 'error', 'warning', 'dark', 'neutral', 'success', 'light', 'lightOutlined', ]), /** Displays a thumbnail at the front of a tag label. Usually contain icons or `<Avatar/>`. */ thumb: PropTypes.element, /** Sets a maximum tag width in pixels */ maxWidth: PropTypes.number, /** Specifies a CSS class name to be appended to the component’s root element */ className: PropTypes.string, }; Tag.defaultProps = { size: 'small', removable: true, theme: 'standard', }; export default Tag;