diff --git a/src/components/Icon/CustomSvgIcon.jsx b/src/components/Icon/CustomSvgIcon.jsx index 2b7b35dae7..54ea39c556 100644 --- a/src/components/Icon/CustomSvgIcon.jsx +++ b/src/components/Icon/CustomSvgIcon.jsx @@ -1,23 +1,48 @@ /* eslint-disable react/jsx-props-no-spreading */ -import React from "react"; +import React, { useCallback } from "react"; import PropTypes from "prop-types"; import cx from "classnames"; import SVG from "react-inlinesvg"; import "./CustomSvgIcon.scss"; import useIconScreenReaderAccessProps from "../../hooks/useIconScreenReaderAccessProps"; -const CustomSvgIcon = ({ className, src, onClick, clickable, ariaLabel, ariaHidden, ...props }) => { +function modifySvgCode(svg, color = "currentColor") { + return svg.replace(/fill=".*?"/g, `fill="${color}"`); +} + +const CustomSvgIcon = ({ + className, + src, + onClick, + clickable, + ariaLabel, + ariaHidden, + replaceToCurrentColor, + customColor, + ...props +}) => { const screenReaderAccessProps = useIconScreenReaderAccessProps({ isClickable: clickable, label: ariaLabel, isDecorationOnly: ariaHidden }); + + const svgProcessor = useCallback( + svg => { + if (replaceToCurrentColor) return modifySvgCode(svg, "currentColor"); + if (customColor) return modifySvgCode(svg, customColor); + return svg; + }, + [replaceToCurrentColor, customColor] + ); + return ( ); @@ -27,13 +52,17 @@ CustomSvgIcon.propTypes = { className: PropTypes.string, src: PropTypes.string, ariaLabel: PropTypes.string, - ariaHidden: PropTypes.bool + ariaHidden: PropTypes.bool, + replaceToCurrentColor: PropTypes.bool, + customColor: PropTypes.string }; CustomSvgIcon.defaultProps = { className: "", src: "", ariaLabel: undefined, - ariaHidden: undefined + ariaHidden: undefined, + replaceToCurrentColor: false, + customColor: undefined }; export default CustomSvgIcon; diff --git a/src/components/Icon/Icon.jsx b/src/components/Icon/Icon.jsx index c85d3260a2..c8d7bbad77 100644 --- a/src/components/Icon/Icon.jsx +++ b/src/components/Icon/Icon.jsx @@ -23,7 +23,9 @@ const Icon = forwardRef( ignoreFocusStyle, tabindex: externalTabIndex, ariaHidden, - style + style, + useCurrentColor, + customColor }, ref ) => { @@ -65,6 +67,8 @@ const Icon = forwardRef( className={cx(computedClassName)} onClick={onClickCallback} style={style} + replaceToCurrentColor={useCurrentColor} + customColor={customColor} /> ); } @@ -85,20 +89,43 @@ Icon.type = ICON_TYPES; Icon.propTypes = { onClick: PropTypes.func, + /** + * class name to be added to icon + */ className: PropTypes.string, - /** the type of the component - svg, font or custom svg (using react-inlinesvg) */ + /** + * the type of the component - svg, font or custom svg (using react-inlinesvg) + */ iconType: PropTypes.oneOf([Icon.type.SVG, Icon.type.ICON_FONT, ICON_TYPES.SRC]), - /** we support three types of icons - SVG, FONT and SRC (classname) so this prop is either the name of the icon or the component */ + /** + * we support three types of icons - SVG, FONT and SRC (classname) so this prop is either the name of the icon or the component + */ icon: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), - /** is in used for tabIndex */ + /** + * is in used for tabIndex + */ clickable: PropTypes.bool, - /** icon aria label support */ + /** + * icon aria label support + */ iconLabel: PropTypes.string, - /** size for font icon */ + /** + * size for font icon + */ iconSize: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - /** remove focus style */ + /** + * remove focus style + */ ignoreFocusStyle: PropTypes.bool, - ariaHidden: PropTypes.bool + ariaHidden: PropTypes.bool, + /** + * when using svg from src (Icon.type.SRC) this boolean will transform the "fill" property to "currentColor" + */ + useCurrentColor: PropTypes.bool, + /** + * If you want to override to coloring of currentColor + */ + customColor: PropTypes.string }; Icon.defaultProps = { @@ -110,7 +137,9 @@ Icon.defaultProps = { iconType: ICON_TYPES.SVG, iconSize: 16, ignoreFocusStyle: false, - ariaHidden: undefined + ariaHidden: undefined, + useCurrentColor: false, + customColor: undefined }; export default Icon; diff --git a/src/components/Icon/__stories__/IconStory.scss b/src/components/Icon/__stories__/IconStory.scss index e016c82649..628fa1130b 100644 --- a/src/components/Icon/__stories__/IconStory.scss +++ b/src/components/Icon/__stories__/IconStory.scss @@ -40,12 +40,15 @@ .icon-story-custom-icon { width: 20px; height: 16px; + color: var(--primary-text-color); + border-radius: 4px; } .single-icon-wrapper { display: flex; justify-self: center; align-items: center; + } .icon-story-search-component { width: 50% !important; diff --git a/src/components/Icon/__stories__/icon.stories.js b/src/components/Icon/__stories__/icon.stories.js index 800744da1c..5dbba33a4b 100644 --- a/src/components/Icon/__stories__/icon.stories.js +++ b/src/components/Icon/__stories__/icon.stories.js @@ -30,10 +30,11 @@ export const Icons = () => {