Last active
February 16, 2022 20:42
-
-
Save ryanoglesby08/603966db3884178e4bade6b5d878c437 to your computer and use it in GitHub Desktop.
Generate React icon components from SVG files using SVGR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { transform } from '@svgr/core' | |
import fs from 'fs' | |
import template from "./template" | |
const ICON_DEFAULT_COLOR = 'black' | |
const fileName = "svgs/myIcon.svg" | |
const svgData = fs.readFileSync(fileName) | |
const componentData = transform.sync( | |
svgData, | |
{ | |
icon: true, | |
plugins: ['@svgr/plugin-jsx', '@svgr/plugin-prettier'], | |
prettier: true, | |
prettierConfig: { | |
parser: 'typescript', | |
semi: false, | |
useTabs: false, | |
}, | |
svgProps: { | |
// Aids in unit testing by consumers, such as asserting an icon is on the page or not | |
'data-testid': `svg_${fileName}`, | |
}, | |
// Removing fill or stroke values set to our default color allow any color to be passed in | |
replaceAttrValues: { | |
[ICON_DEFAULT_COLOR]: 'inherit', | |
}, | |
template: template, | |
typescript: true, | |
}, | |
{ | |
componentName: fileName, | |
} | |
) | |
fs.writeFileSync( | |
`src/icons/${fileName}.tsx`, | |
componentData, | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const GENERATED_MESSAGE = `/** | |
* @generated | |
* This file was automatically generated and should not be edited. | |
*/` | |
// See docs for SVGR custom templates: https://react-svgr.com/docs/custom-templates/ | |
const iconTemplate = ({ template }, opts, { componentName, jsx }) => { | |
const plugins = ['jsx', 'typescript'] | |
const typeScriptTpl = template.smart({ plugins }) | |
return typeScriptTpl.ast` | |
${GENERATED_MESSAGE} | |
import React from 'react' | |
import { system, Config } from 'styled-system' | |
import { Box, BoxProps, useTheme } from 'design-system' | |
type Props = BoxProps & React.SVGProps<SVGSVGElement> | |
const config: Config = { | |
fill: { | |
property: 'fill', | |
scale: 'colors', | |
}, | |
stroke: { | |
property: 'stroke', | |
scale: 'colors', | |
}, | |
} | |
const styleFn = system(config) | |
const Svg = (props: React.SVGProps<SVGSVGElement>) => (${jsx}) | |
const ${componentName} = (props: Props) => { | |
const theme = useTheme() | |
const styledProps = styleFn({ ...props, theme }) | |
return <Box as={Svg} {...props} {...styledProps} /> | |
} | |
export default ${componentName} | |
` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment