This improve greatly the performance and the code cleaning. It allows us to separate the inseparable class methods into modules functions
80 lines
2.2 KiB
TypeScript
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>
|
|
);
|
|
};
|