I'd like to use svg-to-pdfkit to render an SVG into a PDF I'm building. It requires a handle to the PDFKit document, which I don't see an obvious way to get. The closest we get is the Canvas element's paint callback, which receives the painter object. However, this isn't sufficiently powerful for svg-to-pdfkit's purposes.
I'd like to either have the paint callback pass the root object as an available parameter:
paint(painter, width, height, root)
Or I'd like a new element, like render callback to which the this.root.instance handle would be passed, and it would hand off the rendering work to the implementor (in this case, svg-to-pdfkit).
Or, just taking the shortcut even further, an <SVGToPDFKit svg={...} width={...} height={...} /> element which wraps up the whole kit and kaboodle. If we went that route, we could make svg-to-pdfkit a peer dependency, so it's not shipped by default.
If any of these are appropriate paths forward, I'd be happy to submit a PR implementing the desired solution.
https://github.com/cheald/react-pdf/commit/453e8a57bcbf8080559fb270d9c1b258ec7900c8
This is the simplest change necessary to enable this workflow. svg-to-pdfkit works like a champ. I now just have an
type AspectRatioPosition =
| "xMaxYMax"
| "xMaxYMid"
| "xMaxYMin"
| "xMidYMax"
| "xMidYMid"
| "xMidYMin"
| "xMinYMax"
| "xMinYMid"
| "xMinYMin";
type AspectRatioBehavior = "meet" | "slice";
type SVGIsh = string | React.ReactNode | SVGImageElement;
function svgishToString(svg: SVGIsh) {
if (React.isValidElement(svg)) {
return ReactDOMServer.renderToStaticMarkup(svg);
} else if (typeof svg === "string") {
return svg;
} else {
return (svg as SVGImageElement).innerHTML;
}
}
function Svg({
svg,
children,
width,
height,
assumePt = true,
aspectRatio = ["xMidYMid", "meet"],
...props
}: Omit<ReactPDF.CanvasProps, "paint"> & {
children?: SVGIsh;
svg?: SVGIsh;
width?: number | string;
height?: number | string;
assumePt?: boolean;
aspectRatio: [AspectRatioPosition, AspectRatioBehavior];
}) {
const source = React.useMemo(() => svgishToString(children || svg), [
children,
svg,
]);
return (
<Canvas
style={{ height, width }}
{...props}
paint={(_, width, height, root) => {
SVGToPDFKit(root, source, 0, 0, {
width,
height,
assumePt,
preserveAspectRatio: aspectRatio.join(" "),
});
}}
/>
);
}
I have to have the SVG already available (either as source, as a React component building the SVG, or as an SVG element DOM node). Pulling remote SVGs will need a new react-pdf element which can do the async/await stuff that React doesn't like to do, as it appears that react-pdf doesn't like to re-render the PDF on a React tree change.
I would really like this feature added as well, I think a separate SvgRef element or property on the Svg element would be the nicest approach, but would be happy to just have a raw doc object too.
2nd up this feature.
Most helpful comment
https://github.com/cheald/react-pdf/commit/453e8a57bcbf8080559fb270d9c1b258ec7900c8
This is the simplest change necessary to enable this workflow. svg-to-pdfkit works like a champ. I now just have an
I have to have the SVG already available (either as source, as a React component building the SVG, or as an SVG element DOM node). Pulling remote SVGs will need a new react-pdf element which can do the async/await stuff that React doesn't like to do, as it appears that react-pdf doesn't like to re-render the PDF on a React tree change.