svg-layout-designer-react/src/Components/SVG/SVG.tsx
Eric Nguyen d9e06537e8
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Merged PR 16: Transform every single class components into functional component
This improve greatly the performance and the code cleaning.
It allows us to separate the inseparable class methods into modules functions
2022-08-09 15:15:56 +00:00

80 lines
2.2 KiB
TypeScript

import * as React from 'react';
import { UncontrolledReactSVGPanZoom } from 'react-svg-pan-zoom';
import { Container } from './Elements/Container';
import { ContainerModel } from '../../Interfaces/ContainerModel';
import { Selector } from './Elements/Selector';
import { BAR_WIDTH } from '../Bar/Bar';
interface ISVGProps {
width: number
height: number
children: ContainerModel | ContainerModel[] | null
selected: ContainerModel | null
}
interface Viewer {
viewerWidth: number
viewerHeight: number
}
export const ID = 'svg';
function resizeViewBox(
setViewer: React.Dispatch<React.SetStateAction<Viewer>>
): void {
setViewer({
viewerWidth: window.innerWidth - BAR_WIDTH,
viewerHeight: window.innerHeight
});
}
export const SVG: React.FC<ISVGProps> = (props: ISVGProps) => {
const [viewer, setViewer] = React.useState<Viewer>({
viewerWidth: window.innerWidth,
viewerHeight: window.innerHeight
});
React.useEffect(() => {
window.addEventListener('resize', () => resizeViewBox(setViewer));
return () => {
window.addEventListener('resize', () => resizeViewBox(setViewer));
};
});
const xmlns = '<http://www.w3.org/2000/svg>';
const properties = {
width: props.width,
height: props.height,
xmlns
};
let children: React.ReactNode | React.ReactNode[] = [];
if (Array.isArray(props.children)) {
children = props.children.map(child => <Container key={`container-${child.properties.id}`} model={child}/>);
} else if (props.children !== null) {
children = <Container key={`container-${props.children.properties.id}`} model={props.children}/>;
}
return (
<div id={ID} className='ml-16'>
<UncontrolledReactSVGPanZoom
width={viewer.viewerWidth}
height={viewer.viewerHeight}
background={'#ffffff'}
defaultTool='pan'
miniatureProps={{
position: 'left',
background: '#616264',
width: window.innerWidth - 12 - BAR_WIDTH,
height: 120
}}
>
<svg {...properties}>
{ children }
<Selector selected={props.selected} />
</svg>
</UncontrolledReactSVGPanZoom>
</div>
);
};