You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to propose adding support for foreignObject SVG node to this project.
the foreignObject node can handle any html elements not currently supported by this project and is still valid SVG. A use case would be a component in Vue, React, etc that renders as an SVG, but has the capability of providing forms and other interactive elements within the generated SVG. The only drawback is that react-dom and @types/react-dom would need to be added to the project to render the children of foreignobject react node to html and inseret that html into the constructed SVG foreignObject node.
The target for generating foreignObject node could be an html attribute foreignobject="true" that gets picked up similar to how the image and svg in the layout.ts code and look something like:
layout.ts
// Render different types of elementsif(type==='img'){constsrc=computedStyle.__srcasstring;baseRenderResult=awaitrect({
id,
left,
top,
width,
height,
src,
isInheritingTransform,
debug,},computedStyle,newInheritableStyle,);}elseif(type==='svg'){constcurrentColor=computedStyle.color;constsrc=awaitSVGNodeToImage(element,currentColor);baseRenderResult=awaitrect({
id,
left,
top,
width,
height,
src,
isInheritingTransform,
debug,},computedStyle,newInheritableStyle,);}elseif(// get element with attribute foreignobject children&&typeofchildren!=='string'&&restProps?.foreignobject&&style?.display=='flex'&&style?.display!=='none'){constpos={left: left,top: top};constshape={width: width??'100%',height: height??'100%'};baseRenderResult=awaitSVGNodeToForeignObject(element,pos,shape);console.log('baseRenderResult: ',baseRenderResult);}else{constdisplay=style?.display;if(type==='div'&&children&&typeofchildren!=='string'&&display!=='flex'&&display!=='none'){thrownewError(`Expected <div> to have explicit "display: flex" or "display: none" if it has more than one child node.`,);}baseRenderResult=awaitrect({ id, left, top, width, height, isInheritingTransform, debug },computedStyle,newInheritableStyle,);}// Render children that are not children of react node that has attribute foreignobjectif(!restProps?.foreignobject){for(constiterofiterators){childrenRenderResult+=(awaititer.next([left,top])).value;}}
which would catch the react node that has foreignobject attribute and then uses a preprocess function to construct the foreignObject node: and prevent the children from being rendered in the iteration.
preprocess.ts
import{createRoot}from'react-dom/client';import{flushSync}from'react-dom';
...
/** * Interface representing the position of an element. */interfacePosition{left: number;top: number;}/** * Interface representing the shape of an element. */interfaceShape{width: string|number;height: string|number;}/** * Converts a React element to an SVG foreignObject element. * * @param node - The React element to be converted. * @param pos - The position where the foreignObject should be placed. * @param shape - The shape (width and height) of the foreignObject. * @returns A promise that resolves to a string representing the foreignObject element. * @throws Will throw an error if the rendering process fails. */exportasyncfunctionSVGNodeToForeignObject(node: ReactElement,pos: Position,shape: Shape): Promise<string>{try{// Create a div element to render the React element intoconstdiv=document.createElement('div');constroot=createRoot(div);// Render the React element into the divflushSync(()=>{root.render(node);});// Get the inner HTML of the div and remove any foreignObject attributesconstnodeChildren=div.innerHTML.replace(/ foreignobject="true"/g,'');// Build and return the XML string for the foreignObject elementreturnbuildXMLString('foreignObject',{xmlns: 'http://www.w3.org/1999/xhtml',x: pos.left,y: pos.top,width: shape.width,height: shape.height,},nodeChildren,);}catch(error){// Log and rethrow any errors that occur during the rendering processconsole.error('Error rendering SVG node to foreignObject:',error);throwerror;}}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I would like to propose adding support for foreignObject SVG node to this project.
the foreignObject node can handle any html elements not currently supported by this project and is still valid SVG. A use case would be a component in Vue, React, etc that renders as an SVG, but has the capability of providing forms and other interactive elements within the generated SVG. The only drawback is that react-dom and @types/react-dom would need to be added to the project to render the children of foreignobject react node to html and inseret that html into the constructed SVG foreignObject node.
The target for generating foreignObject node could be an html attribute foreignobject="true" that gets picked up similar to how the image and svg in the layout.ts code and look something like:
layout.ts
which would catch the react node that has foreignobject attribute and then uses a preprocess function to construct the foreignObject node: and prevent the children from being rendered in the iteration.
preprocess.ts
Thoughts?
Beta Was this translation helpful? Give feedback.
All reactions