UNPKG

@momentum-ui/react-collaboration

Version:

Cisco Momentum UI Framework for React Collaboration Applications

193 lines (177 loc) 5.39 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-collaboration'; import { getColorValue } from '../utils'; /** * @deprecated - Components in the legacy folder (/src/legacy) are deprecated. Please use a component from the components folder (/src/components) instead. Legacy components may not follow accessibility standards. **/ class Icon extends React.PureComponent { render() { const { append, ariaLabel, buttonClassName, buttonProps, color, className, description, onClick, name, prepend, size, sizeOverride, style, title, type, icon, ...otherProps } = this.props; const consoleHandler = (message, data) => { /* eslint-disable no-console */ switch (message) { case 'color-warn': console.warn( `[@momentum-ui/react-collaboration] 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-collaboration] 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 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 = () => { const styles = { fontSize: getSize(), ...(color && { color: getColor() }), ...style, }; 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} > {icon ? icon : getIcon()} </Button> ) : icon ? ( icon ) : ( 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 Icon node to draw instead of supplying name */ icon: PropTypes.node, /** @prop Legacy icon name */ name: PropTypes.string, /** @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;