Converts SVG files to one tree-shakable typescript definition model, which can be used by a icon library.
Adaptation of the svg-to-ts project. The main addition which this project provides for, is an svg coloring workflow. With this workflow, it is possible to have one annotated svg which can be used to render a svg using css variables.
- SVG files must be annotated with properties containing the name of a css variable.
- A rc-file must be added to the svg root, containing the configuration.
- Run the tool.
- Implement the definition model in your application.
We use Affinity Designer to manage our Icon Library at Scienta. Each layer which must be thematically colorized is named after the css variable which must be used. When exported, these layer names are preserved by the exporter of Affinity Sesigner.
Input example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
>
<rect serif:id="--secondary-color" x="1.029" y="2" width="16" height="2" style="fill:#aaa;"/>
<rect serif:id="--secondary-color" x="1.029" y="8" width="16" height="2" style="fill:#aaa;"/>
<rect serif:id="--secondary-color" x="1.029" y="14" width="16" height="2" style="fill:#aaa;"/>
<rect serif:id="--main-color" x="13.029" y="1" width="2" height="4" style="fill:#333;"/>
<rect serif:id="--main-color" x="4.029" y="7" width="2" height="4" style="fill:#333;"/>
<rect serif:id="--main-color" x="10.029" y="13" width="2" height="4" style="fill:#333;"/>
</svg>
This will be transformed to:
<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
>
<path style="fill:var(--secondary-color,#aaa)" d="M1.029 2h16v2h-16zm0 6h16v2h-16zm0 6h16v2h-16z"/>
<path style="fill:var(--main-color,#333)" d="M13.029 1h2v4h-2zm-9 6h2v4h-2zm6 6h2v4h-2z"/>
</svg>
The icon is optimized by svgo and the colors are substituted with a css-variable having the original color set as default. The settings of how to parse annotated svgs are configurable.
The output of this tool is a definition model with a constant for each converted svg asset. The typings can be configured in the configuration rc file.
** Example Typescript definition model file:**
// Prefixed with the prefix `scaIcon` and typed `ScaIcon`
export const scaIcon_action_preset: ScaIcon = {
name: `action-preset`,
svg: `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"><path style="fill:none;fill-rule:nonzero" d="M0 0h18v18H0z"/><path style="fill:var(--secondary-color,#aaa)" d="M1.029 2h16v2h-16zm0 6h16v2h-16zm0 6h16v2h-16z"/><path style="fill:var(--main-color,#333)" d="M13.029 1h2v4h-2zm-9 6h2v4h-2zm6 6h2v4h-2z"/></svg>`,
};
// ... All other converted files
// A type of all the asset names
export type scaIcon =
| 'action-preset' // ... And all other converted files
;
// ... Type definitions
export interface ScaIcon {
name: string;
svg: string;
}
It is mandatory to add a rc file to the path you want to create a svg definition model for.
The main config can be configured in a rc yml file. This file must be specified as command parameter when running the tool.
interface ConfigInterface {
inputs: string[]; // One ore more input paths locating the SVGs
parser: {
cssVariableAttribute: string; //Name of the aattribute in which the css variable name is annotated to
cssVariableRegex: string; // Regex to fetch the variable
svgoPlugins?: string[]; // List of svgo plugins to use
js2svg: Record<string, any> // js2svg settings
};
writer: {
constPrefix: string; // Name of the constant prefix to use in the definition model
assetInterfaceName: string; // Name of the Typescript asset interface which will be generated
}
}
Checkout this repository and run it 😃
./svg-assets-to-typescript.sh .svg-assets-to-typescriptrc.yml .
- Edit the .env-file according to the template and your paths
- Spin up the container
docker-compose -f docker-compose.development.yml up -d --build --force-recreate --remove-orphans
docker exec -ti svg-assets-to-typescript sh
And in the container's terminal:
- Install dependencies
- run the tool
--input
: The root input rc file--output
: The root output definition model file
npm install
npm run extract --input=/assets/.svg-assets-to-typescriptrc.yml --output=/output