React — build SVG components with styled components
I worked with a project and we used SVG for icons. SVG is called Scalable Vector Graphics and it provides a lot of benefits as an image type/extension, it is scalable and the size is very small comparing to png and other image type.
There are a few ways to use the SVG in react:
- Use it as a regular image (
<img src="/images/logo.svg" />)
- Import it as a component via bundler magic (SVGR)
- Include it directly as JSX
The project chose the third approach and I will share my learning in here.
Icon based component
import styled from 'styled-components';export interface IconProps {
className?: string;
}export default styled.svg.attrs({
version: '1.1',
xmlns: 'http://www.w3.org/2000/svg',
xmlnsXlink: 'http://www.w3.org/1999/xlink',
})`
width: 52px;
height: 52px;
`;
- created based component with the svg attributes and default css style (width and height) which is optional
- this is also an optional step
Twitter Icon component
import Svg, { IconProps } from './Icon';const TwitterIcon = (props: IconProps) => {
const { className } = props; return (
<Svg viewBox="0 0 52 52" className={className}>
<path fill="currentColor" d="M42 xxxxxx 16.0777Z" />
</Svg>
);
};export default TwitterIcon;
- created the TwitterIcon component to return the SVG content
- import the base
Icon
component asSvg
(can name anything), and replaced the svg content<svg></svg>
tag with our own versionSvg
. This allowed the icon component to inherit all svg attributes and the css styles from the basedIcon
component. (this is optional but it allows us to set the default css styles) className={className}
this is mandatory if we want to styled the component with width and height, it passed down theclassName
from current props to the baseIcon
componentfill="currentColor"
this is mandatory if we want to style the component with colors, (if you haven’t heard about it, check it out here, with a browser support breakdown here) as the value of the fill prop. (from the reference)
Then we can override the component style in this way
const StyledTwitterIcon = styled(TwitterIcon)`
width: 35px;
height: 35px;
`;