From d2492520b41902869d8b2aec3fff234e9d8ddc6c Mon Sep 17 00:00:00 2001 From: Siklos Date: Mon, 1 Aug 2022 16:16:31 +0200 Subject: [PATCH] Big refactoring with properties + Implement Property --- src/App.tsx | 71 +++++++++++++++---- .../ElementsSidebar/ElementsSidebar.tsx | 9 ++- src/Components/Properties/Properties.tsx | 48 +++++++++++++ src/Components/SVG/Elements/Container.tsx | 26 ++++--- src/Interfaces/Properties.ts | 7 ++ 5 files changed, 133 insertions(+), 28 deletions(-) create mode 100644 src/Components/Properties/Properties.tsx create mode 100644 src/Interfaces/Properties.ts diff --git a/src/App.tsx b/src/App.tsx index 20a44da..9e78592 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -43,16 +43,16 @@ class App extends React.Component { const MainContainer = new Container( { parent: null, - id: 'main', - x: 0, - y: 0, - width: configuration.MainContainer.Width, - height: configuration.MainContainer.Height, - children: [], - style: { + properties: { + id: 'main', + x: 0, + y: 0, + width: configuration.MainContainer.Width, + height: configuration.MainContainer.Height, fillOpacity: 0, stroke: 'black' - } as React.CSSProperties + }, + children: [] } ); this.setState(prevState => ({ @@ -82,6 +82,46 @@ class App extends React.Component { } as IAppProps); } + public OnPropertyChange(key: string, value: string) { + if (this.state.SelectedContainer === null || + this.state.SelectedContainer === undefined) { + throw new Error('Property was changed before selecting a Container'); + } + + if (this.state.MainContainer === null || + this.state.MainContainer === undefined) { + throw new Error('Property was changed before the main container was added'); + } + + const pair = {} as Record; + pair[key] = value; + const properties = Object.assign(this.state.SelectedContainer.props.properties, pair); + const props = { + ...this.state.SelectedContainer.props, + properties + }; + + const newSelectedContainer = new Container(props); + + const parent = this.state.SelectedContainer.props.parent; + if (parent === null) { + this.setState({ + SelectedContainer: newSelectedContainer, + MainContainer: newSelectedContainer + }); + return; + } + + const index = parent.props.children.indexOf(this.state.SelectedContainer); + parent.props.children[index] = newSelectedContainer; + + const newMainContainer = new Container(Object.assign({}, this.state.MainContainer.props)); + this.setState({ + SelectedContainer: newSelectedContainer, + MainContainer: newMainContainer + }); + } + public AddContainer(type: string): void { if (this.state.SelectedContainer === null || this.state.SelectedContainer === undefined) { @@ -111,13 +151,15 @@ class App extends React.Component { const count = newCounters[type]; const container = new Container({ parent, - id: `${type}-${count}`, - x: 0, - y: 0, - width: properties?.Width, - height: parent.props.height, + properties: { + id: `${type}-${count}`, + x: 0, + y: 0, + width: properties?.Width, + height: parent.props.properties.height, + ...properties.Style + }, children: [], - style: properties.Style, userData: { type } @@ -148,6 +190,7 @@ class App extends React.Component { SelectedContainer={this.state.SelectedContainer} isOpen={this.state.isSVGSidebarOpen} onClick={() => this.ToggleSVGSidebar()} + onPropertyChange={(key: string, value: string) => this.OnPropertyChange(key, value)} selectContainer={(container: Container) => this.SelectContainer(container)} /> diff --git a/src/Components/ElementsSidebar/ElementsSidebar.tsx b/src/Components/ElementsSidebar/ElementsSidebar.tsx index 46b6120..b184df5 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Properties } from '../Properties/Properties'; import { Container } from '../SVG/Elements/Container'; interface IElementsSidebarProps { @@ -6,6 +7,7 @@ interface IElementsSidebarProps { isOpen: boolean, SelectedContainer: Container | null, onClick: () => void, + onPropertyChange: (key: string, value: string) => void, selectContainer: (container: Container) => void } @@ -39,10 +41,10 @@ export class ElementsSidebar extends React.Component { const containerRows: React.ReactNode[] = []; this.iterateChilds((container: Container) => { const depth: number = Container.getDepth(container); - const key = container.props.id.toString(); + const key = container.props.properties.id.toString(); const text = '|\t'.repeat(depth) + key; const selectedClass: string = this.props.SelectedContainer !== null && - this.props.SelectedContainer.props.id === container.props.id + 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( @@ -53,7 +55,7 @@ export class ElementsSidebar extends React.Component { }); return ( -
+
@@ -63,6 +65,7 @@ export class ElementsSidebar extends React.Component {
{ containerRows }
+
); } diff --git a/src/Components/Properties/Properties.tsx b/src/Components/Properties/Properties.tsx new file mode 100644 index 0000000..155a686 --- /dev/null +++ b/src/Components/Properties/Properties.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +import ContainerProperties from '../../Interfaces/Properties'; + +interface IPropertiesProps { + properties?: ContainerProperties, + onChange: (key: string, value: string) => void +} + +interface IPropertiesState { + hasUpdate: boolean +} + +export class Properties extends React.Component { + public state: IPropertiesState; + + constructor(props: IPropertiesProps) { + super(props); + this.state = { + hasUpdate: false + }; + } + + public render() { + if (this.props.properties === undefined) { + return
; + } + + const groupInput: React.ReactNode[] = []; + Object.entries(this.props.properties).forEach((pair) => this.handleProperties(pair, groupInput)); + + return ( +
+ { groupInput } +
+ ); + } + + public handleProperties = ([key, value]: [string, string | number], groupInput: React.ReactNode[]) => { + const id = `property-${key}`; + const type = typeof value === 'number' ? 'number' : 'text'; + groupInput.push( +
+ + this.props.onChange(key, event.target.value)} /> +
+ ); + }; +} diff --git a/src/Components/SVG/Elements/Container.tsx b/src/Components/SVG/Elements/Container.tsx index 728a954..d1bf336 100644 --- a/src/Components/SVG/Elements/Container.tsx +++ b/src/Components/SVG/Elements/Container.tsx @@ -1,16 +1,12 @@ import * as React from 'react'; +import Properties from '../../../Interfaces/Properties'; interface IContainerProps { // eslint-disable-next-line no-use-before-define parent: Container | null, - id: string, // eslint-disable-next-line no-use-before-define children: Container[], - x: number, - y: number, - width: number, - height: number, - style?: React.CSSProperties, + properties: Properties, userData?: Record } @@ -18,17 +14,25 @@ export class Container extends React.Component { componentWillUnMount() { } + public GetProperties(): Properties { + const properties : Properties = { + ...this.props.properties + }; + return properties; + } + public render(): React.ReactNode { const containersElements = this.props.children.map(child => child.render()); + const style = Object.assign({}, this.props.properties); + style.x = 0; + style.y = 0; return ( { containersElements } diff --git a/src/Interfaces/Properties.ts b/src/Interfaces/Properties.ts new file mode 100644 index 0000000..ce386aa --- /dev/null +++ b/src/Interfaces/Properties.ts @@ -0,0 +1,7 @@ +import * as React from 'react'; + +export default interface Properties extends React.CSSProperties { + id: string, + x: number, + y: number, +}