86 lines
2.9 KiB
TypeScript
86 lines
2.9 KiB
TypeScript
import * as React from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import { Properties } from '../Properties/Properties';
|
|
import { Container } from '../SVG/Elements/Container';
|
|
|
|
interface IElementsSidebarProps {
|
|
MainContainer: Container | null,
|
|
isOpen: boolean,
|
|
SelectedContainer: Container | null,
|
|
onClick: () => void,
|
|
onPropertyChange: (key: string, value: string) => void,
|
|
selectContainer: (container: Container) => void
|
|
}
|
|
|
|
export class ElementsSidebar extends React.Component<IElementsSidebarProps> {
|
|
public iterateChilds(handleContainer: (container: Container) => void): React.ReactNode {
|
|
const root = this.props.MainContainer;
|
|
if (!root) {
|
|
return null;
|
|
}
|
|
|
|
const queue = [root];
|
|
const visited = new Set([root]);
|
|
while (queue.length > 0) {
|
|
const container = queue.pop() as Container;
|
|
|
|
handleContainer(container);
|
|
|
|
container.props.children.forEach((child) => {
|
|
if (visited.has(child)) {
|
|
return;
|
|
}
|
|
visited.add(child);
|
|
queue.push(child);
|
|
});
|
|
}
|
|
}
|
|
|
|
public render() {
|
|
const isOpenClasses = this.props.isOpen ? 'right-0' : '-right-64';
|
|
|
|
const containerRows: React.ReactNode[] = [];
|
|
this.iterateChilds((container: Container) => {
|
|
const depth: number = Container.getDepth(container);
|
|
const key = container.props.properties.id.toString();
|
|
const text = '|\t'.repeat(depth) + key;
|
|
const selectedClass: string = this.props.SelectedContainer !== null &&
|
|
this.props.SelectedContainer.props.properties.id === container.props.properties.id
|
|
? 'bg-blue-500 hover:bg-blue-600'
|
|
: 'bg-slate-400 hover:bg-slate-600';
|
|
containerRows.push(
|
|
<motion.button
|
|
whileHover={{ scale: 1.05 }}
|
|
whileTap={{ scale: 1.2 }}
|
|
initial={{ opacity: 0, scale: 0 }}
|
|
animate={{ opacity: 1, scale: 1 }}
|
|
transition={{
|
|
duration: 0.150
|
|
}}
|
|
className={
|
|
`w-full elements-sidebar-row whitespace-pre
|
|
text-left text-sm font-medium transition-all ${selectedClass}`
|
|
}
|
|
key={key}
|
|
onClick={() => this.props.selectContainer(container)}>
|
|
{ text }
|
|
</motion.button>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<div className={`fixed flex flex-col bg-slate-300 text-white transition-all h-screen w-64 overflow-y-auto z-20 ${isOpenClasses}`}>
|
|
<button className='close-button bg-slate-400 hover:bg-slate-600 justify-start' onClick={this.props.onClick}>
|
|
× Close
|
|
</button>
|
|
<div className='bg-slate-500 sidebar-row'>
|
|
Elements
|
|
</div>
|
|
<div className='overflow-y-auto overflow-x-hidden text-slate-200 flex-grow divide-y divide-solid divide-slate-500'>
|
|
{ containerRows }
|
|
</div>
|
|
<Properties properties={this.props.SelectedContainer?.GetProperties()} onChange={this.props.onPropertyChange}></Properties>
|
|
</div>
|
|
);
|
|
}
|
|
}
|