wix-style-react
Version:
126 lines (116 loc) • 3.57 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { withFocusable } from 'wix-ui-core/dist/src/hocs/Focusable';
import { generateDataAttr } from '../utils/generateDataAttr';
import { SKIN, TYPE, SIZE } from './constants';
import { st, classes } from './Badge.st.css';
import Caption from '../Text/Caption';
class Badge extends React.PureComponent {
static propTypes = {
/** Applied as data-hook HTML attribute that can be used to create driver in testing */
dataHook: PropTypes.string,
/** A css class to be applied to the component's root element */
className: PropTypes.string,
/** variation of the component structure */
type: PropTypes.oneOf(['solid', 'outlined', 'transparent']),
/** color indication of the component */
skin: PropTypes.oneOf([
'general',
'standard',
'danger',
'success',
'neutral',
'warning',
'urgent',
'neutralLight',
'neutralStandard',
'neutralSuccess',
'neutralDanger',
'premium',
'warningLight',
]),
/** component size */
size: PropTypes.oneOf(['medium', 'small', 'tiny']),
/** usually an icon to appear at the beginning of the text */
prefixIcon: PropTypes.node,
/** usually an icon to appear at the end of the text */
suffixIcon: PropTypes.node,
/** callback function called when badge is clicked */
onClick: PropTypes.func,
/** forces an uppercase letters */
uppercase: PropTypes.bool,
focusableOnFocus: PropTypes.func,
focusableOnBlur: PropTypes.func,
/** the text to display in the badge */
children: PropTypes.node,
};
static displayName = 'Badge';
static defaultProps = {
type: TYPE.solid,
skin: SKIN.general,
size: SIZE.medium,
uppercase: true,
};
getProps = () => {
// that's what you pay for using HOCs...
const { focusableOnFocus, focusableOnBlur, ...rest } = this.props;
return rest;
};
_getFocusableProps = () => {
// add focusable hooks only when badge is clickable
const { onClick, focusableOnFocus, focusableOnBlur } = this.props;
return onClick
? {
onFocus: focusableOnFocus,
onBlur: focusableOnBlur,
tabIndex: 0,
}
: {};
};
render() {
const {
children,
prefixIcon,
suffixIcon,
onClick,
dataHook,
className,
...rest
} = this.getProps();
return (
<div
data-hook={dataHook}
onClick={onClick}
{...this._getFocusableProps()}
className={st(
classes.root,
{ clickable: !!onClick, ...rest },
className,
)}
{...generateDataAttr(this.props, ['type', 'skin', 'size', 'uppercase'])}
data-clickable={!!onClick}
/* TODO: this prop used to come from stylable v1 spread and is used for testing. Update component testkit to use stylable testkit instead */
data-is-inverted={rest['data-is-inverted']}
>
{prefixIcon &&
React.cloneElement(prefixIcon, {
className: classes.prefix,
'data-prefix-icon': true,
})}
<Caption
className={classes.text}
caption={this.getProps().size === 'tiny' ? 'c2' : 'c1'}
ellipsis
>
{children}
</Caption>
{suffixIcon &&
React.cloneElement(suffixIcon, {
className: classes.suffix,
'data-suffix-icon': true,
})}
</div>
);
}
}
export default withFocusable(Badge);