UNPKG

@momentum-ui/react

Version:

Cisco Momentum UI framework for ReactJs applications

185 lines (169 loc) 5.01 kB
/** @component icon */ import React from 'react'; import PropTypes from 'prop-types'; import iconNames from '@momentum-ui/icons/data/momentumUiIconsNames.json'; import { Button } from '@momentum-ui/react'; import getColorValue from '@momentum-ui/utils/lib/getColorValue'; class Icon extends React.PureComponent { render() { const { append, ariaLabel, buttonClassName, buttonProps, color, className, description, onClick, name, prepend, size, sizeOverride, style, title, type, ...otherProps } = this.props; const consoleHandler = (message, data) => { /* eslint-disable no-console */ switch (message) { case 'color-warn': console.warn( `[@momentum-ui/react] Icon: ${data} may not exist in the design system,` + ` please use a color name from https://momentum.design/styles/color/style` ); break; case 'name-error': console.warn( `[@momentum-ui/react] Icon: Icon ${data} does not exist in the design system.` + ` Visit https://momentum.design/styles/icons/library for a list of available icons or to request a new icon.` ); break; } /* eslint-enable no-console */ }; const getSize = () => { const defaultSize = 16; const sizeFromName = Number(name.split('_')[1]); return size || sizeFromName || defaultSize; }; const getColor = () => { if (color.startsWith('#')) { consoleHandler('color-warn', color); return color; } const value = getColorValue(color); return value; }; const getNameClass = () => { let iconName = name.startsWith('icon-') ? name.replace(/^(icon-)/, '') : name; if (sizeOverride) { iconName = name.split('_')[0] + `_${getSize()}`; } return iconNames.includes(iconName) ? `icon-${iconName}` : consoleHandler('name-error', iconName); }; const styles = { fontSize: getSize(), ...color && { color: getColor() }, ...style, }; const getAriaLabel = () => { if ( ariaLabel ) { return ariaLabel; } if (!ariaLabel) { if (title && description) return `${title} ${description}`; if (title) return title; if (description) return description; } return null; }; const getIcon = () => { return ( <i className={ `md-icon icon` + ` ${getNameClass()}` + `${(className && ` ${className}`) || ''}` + `${(prepend && ` md-prepend`) || ''}` + `${(append && ` md-append`) || ''}` } aria-label={!onClick ? getAriaLabel() : null} style={styles} {...(title && !onClick) && { title: title }} {...!onClick && { ...otherProps }} /> ); }; return onClick ? ( <Button className={ 'md-button--icon' + `${(type && ` md-button--icon-${type}`) || ''}` + `${(buttonClassName && ` ${buttonClassName}`) || ''}` } ariaLabel={getAriaLabel()} onClick={onClick} {...buttonProps} {...title && { title: title }} {...otherProps} > {getIcon()} </Button> ) : ( getIcon() ); } } Icon.propTypes = { /** @prop Add margin to the left of Icon | null */ append: PropTypes.bool, /** @prop Text to display for blindness accessibility features | null */ ariaLabel: PropTypes.string, /** @prop Optional Button class name string | '' */ buttonClassName: PropTypes.string, /** @prop Optional props to pass to underlying button component | null */ buttonProps: PropTypes.object, /** @prop Optional color css styling | '' */ color: PropTypes.string, /** @prop Optional class name string | '' */ className: PropTypes.string, /** @prop Icon description text | '' */ description: PropTypes.string, /** @prop Required Icon name */ name: PropTypes.string.isRequired, /** @prop Handler invoked by click of the user | null */ onClick: PropTypes.func, /** @prop Add margin to the right of Icon | null */ prepend: PropTypes.bool, /** @prop Sets Icon size | null */ size: PropTypes.number, // Internal prop to override iconName with size prop */ sizeOverride: PropTypes.bool, /** @prop Additional style properties to be applied | null */ style: PropTypes.object, /** @prop Sets Icon Title prop | '' */ title: PropTypes.string, /** @prop Sets Icon Type | '' */ type: PropTypes.oneOf(['', 'white']), }; Icon.defaultProps = { append: false, ariaLabel: null, buttonClassName: '', buttonProps: null, color: '', className: '', description: '', onClick: null, prepend: false, size: null, sizeOverride: false, style: null, title: '', type: '', }; Icon.displayName = 'Icon'; export default Icon;