@momentum-ui/react
Version:
Cisco Momentum UI framework for ReactJs applications
185 lines (169 loc) • 5.01 kB
JavaScript
/** @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;