saagie-ui
Version:
Saagie UI from Saagie Design System
91 lines (77 loc) • 2.08 kB
JavaScript
import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import SVGInline from 'react-svg-inline';
import classnames from 'classnames';
import icons from '../../../../assets/icons/icons.map.json';
const propTypes = {
defaultClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
className: PropTypes.string,
name: PropTypes.string.isRequired,
position: PropTypes.oneOf(['', 'start', 'between', 'end']),
size: PropTypes.oneOf(['', 'sm', 'lg', 'xl']),
isSvgColor: PropTypes.bool,
description: PropTypes.string,
};
const defaultProps = {
defaultClassName: 'sui-a-icon',
className: '',
position: '',
size: '',
isSvgColor: false,
description: '',
};
export const Icon = forwardRef((props, ref) => {
const {
defaultClassName,
className,
name,
position,
size,
isSvgColor,
description,
...attributes
} = props;
const randomId = () => Math.random().toString(36).substring(2, 8);
const classes = classnames(
defaultClassName,
name ? `as--${name}` : '',
position ? `as--${position}` : '',
size ? `as--${size}` : '',
isSvgColor ? 'as--svg-color' : '',
className
);
if (!name) {
return '';
}
// Font Awesome
if (name.startsWith('fa-')) {
return (
<i {...attributes} className={classes} aria-hidden ref={ref}>
<span hidden>{description}</span>
</i>
);
}
if (!icons[name]) {
return '';
}
let iconSvg = icons[name];
const matches = [...iconSvg.matchAll(/id="([^"]+)"/g)];
if (matches.length >= 1) {
matches.forEach((match) => {
iconSvg = iconSvg.replace(new RegExp(match[1],'g'), `${match[1]}-${randomId()}`);
});
}
return (
<i {...attributes} className={classes} aria-hidden ref={ref}>
<SVGInline
svg={iconSvg}
stringrole="img"
accessibilityLabel={name}
accessibilityDesc={description}
/>
<span hidden>{description}</span>
</i>
);
});
Icon.propTypes = propTypes;
Icon.defaultProps = defaultProps;