A lightweight component to use SVG.js library in React. Custom hooks are provided for automatically re-rendering when the underlying data changes. Check out the demo for some examples.
Install react-svgdotjs
using npm.
npm install react-svgdotjs
Then you can just import the component and its hook:
import { SvgContainer, useSvgContainer } from 'react-svgdotjs';
and use it as below:
const { setHandles, svgContainer } = useSvgContainer();
<SvgContainer setHandles={setHandles} width='500px' height='600px' margin='0 auto' onload={onload}/>
SvgContainer
is rendered as a div
element with specified width, height, and margin. In onload
, you can access the svg
element inserted into the above container.
const onload = (svg, container) => {
// Set svg dimensions
svg.size(500, 600);
// Add a 100x100 red rectangle
svg.rect(100, 100).fill('red');
}
To add, remove, or change SVG elements in React event handlers, import and utilize svgUpdate
hook like so:
const clickHandler = svgUpdate(svgContainer, svg => {
svg.circle(10).fill('red').move(130, 130);
});
<button onClick={clickHandler}>Add a red circle</button>
Alternatively, you can access svg
as below:
const clickHandler = () => {
let svg = svgContainer.svg;
svg.circle(10).fill('red').move(130, 130);
}
The onload
behavior prevents SVG from benefiting from seamless re-rendering when the underlying data changes. Some custom hooks are provided to address this problem.
Consider the state
provided below:
const [color, setColor] = React.useState("red");
Now, you can move the part of your code that contains states from onload
to useSvg
:
import { SvgContainer, useSvgContainer, useSvg } from 'react-svgdotjs';
const onload = (svg, container) => {
// Set svg dimensions
svg.size(500, 600);
}
useSvg(svgContainer, svg => {
// Add a 100x100 rectangle whose color may change!
let rect = svg.rect(100, 100).fill(color);
return [rect];
}, [color]);
Ensure to return an array containing the added elements. Whenever any of the dependencies undergo a change, the hook will remove
them and re-execute the function. Within a component, you are allowed to include multiple useSvg
s, each with its own set of dependencies.
When there is a need for running a function and specifying a cleanup function, you may opt to utilize useSvgWithCleanup
hook. If no cleanup function is returned, it will proceed to execute svg.clear()
by default instead.
import { SvgContainer, useSvgContainer, useSvgWithCleanup } from 'react-svgdotjs';
const imgUrl = 'https://svgjs.dev/docs/3.0/assets/images/logo-svg-js-01d-128.png';
const [img, setImg] = React.useState(imgUrl);
useSvgWithCleanup(svgContainer, svg => {
let _img = svg.image(img, ev => {
svg.size(500, 600);
});
return svg => { svg.clear(); }
}, [img]);
Within a component, you are allowed to include multiple useSvgWithCleanup
s, each with its own set of dependencies.
- Fork the project.
- Make changes.
- Run the project in development mode:
npm run ladle
. - Test your changes using
svg-container.stories.tsx
or your own Stories (*.stories.tsx
). - Update README with appropriate docs.
- Commit and PR
The package is dependent on svgdotjs/svg.js
which is automatically managed by NPM. The following peer dependencies must be specified by your project in order to avoid version conflicts:
react
,
react-dom
.
NPM will not automatically install these for you but it will show you a warning message with instructions on how to install them.