diff --git a/src/Components/App/MenuActions.ts b/src/Components/App/MenuActions.ts index b9a455e..8dec2a1 100644 --- a/src/Components/App/MenuActions.ts +++ b/src/Components/App/MenuActions.ts @@ -24,10 +24,8 @@ export function NewEditor( height: Number(configuration.MainContainer.Height), isRigidBody: false, isAnchor: false, - style: { - fillOpacity: 0, - stroke: 'black' - } + fillOpacity: 0, + stroke: 'black' } ); diff --git a/src/Components/Editor/ContainerOperations.ts b/src/Components/Editor/ContainerOperations.ts index d778d82..0ab670d 100644 --- a/src/Components/Editor/ContainerOperations.ts +++ b/src/Components/Editor/ContainerOperations.ts @@ -209,6 +209,7 @@ export function AddContainer( x = ApplyAddMethod(index, containerConfig, parentClone, x); const defaultProperties: IProperties = { + ...containerConfig.Style, id: `${type}-${count}`, parentId: parentClone.properties.id, x, @@ -217,8 +218,7 @@ export function AddContainer( height, isRigidBody: false, isAnchor: false, - xPositionReference: containerConfig.XPositionReference, - style: containerConfig.Style + XPositionReference: containerConfig.XPositionReference }; // Create the container @@ -270,7 +270,7 @@ function ApplyAddMethod(index: number, containerConfig: IAvailableContainer, par lastChild.properties.x, lastChild.properties.y, lastChild.properties.width, - lastChild.properties.xPositionReference + lastChild.properties.XPositionReference ); x += transformedX + lastChild.properties.width; diff --git a/src/Components/Editor/Editor.tsx b/src/Components/Editor/Editor.tsx index 75bf90c..fcd62f9 100644 --- a/src/Components/Editor/Editor.tsx +++ b/src/Components/Editor/Editor.tsx @@ -91,15 +91,16 @@ const Editor: React.FunctionComponent = (props) => { setHistory, setHistoryCurrentStep )} - OnPropertyChange={(key, value, isStyle) => OnPropertyChange( - key, value, isStyle, + OnPropertyChange={(key, value) => OnPropertyChange( + key, value, history, historyCurrentStep, setHistory, setHistoryCurrentStep )} - OnPropertiesSubmit={(event) => OnPropertiesSubmit( + OnPropertiesSubmit={(event, properties) => OnPropertiesSubmit( event, + properties, history, historyCurrentStep, setHistory, diff --git a/src/Components/Editor/PropertiesOperations.ts b/src/Components/Editor/PropertiesOperations.ts index cccc363..4bd4c2d 100644 --- a/src/Components/Editor/PropertiesOperations.ts +++ b/src/Components/Editor/PropertiesOperations.ts @@ -1,6 +1,7 @@ import { Dispatch, SetStateAction } from 'react'; import { IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel'; import { IHistoryState } from '../../Interfaces/IHistoryState'; +import IProperties from '../../Interfaces/IProperties'; import { findContainerById } from '../../utils/itertools'; import { getCurrentHistory } from './Editor'; import { RecalculatePhysics } from './Behaviors/RigidBodyBehaviors'; @@ -16,7 +17,6 @@ import { ImposePosition } from './Behaviors/AnchorBehaviors'; export function OnPropertyChange( key: string, value: string | number | boolean, - isStyle: boolean = false, fullHistory: IHistoryState[], historyCurrentStep: number, setHistory: Dispatch>, @@ -37,14 +37,10 @@ export function OnPropertyChange( throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); } - if (isStyle) { - (container.properties.style as any)[key] = value; + if (INPUT_TYPES[key] === 'number') { + (container.properties as any)[key] = Number(value); } else { - if (INPUT_TYPES[key] === 'number') { - (container.properties as any)[key] = Number(value); - } else { - (container.properties as any)[key] = value; - } + (container.properties as any)[key] = value; } if (container.properties.isAnchor) { @@ -74,6 +70,7 @@ export function OnPropertyChange( */ export function OnPropertiesSubmit( event: React.SyntheticEvent, + properties: IProperties, fullHistory: IHistoryState[], historyCurrentStep: number, setHistory: Dispatch>, @@ -95,33 +92,15 @@ export function OnPropertiesSubmit( throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); } - // Assign container properties - for (const property in container.properties) { + for (const property in properties) { const input = (event.target as HTMLFormElement).querySelector(`#${property}`); if (input instanceof HTMLInputElement) { (container.properties as any)[property] = input.value; - if (INPUT_TYPES[property] === 'number') { (container.properties as any)[property] = Number(input.value); - continue; + } else { + (container.properties as any)[property] = input.value; } - - (container.properties as any)[property] = input.value; - } - } - - // Assign cssproperties - for (const styleProperty in container.properties.style) { - const input = (event.target as HTMLFormElement).querySelector(`#${styleProperty}`); - if (input instanceof HTMLInputElement) { - (container.properties.style as any)[styleProperty] = input.value; - - if (INPUT_TYPES[styleProperty] === 'number') { - (container.properties.style as any)[styleProperty] = Number(input.value); - continue; - } - - (container.properties.style as any)[styleProperty] = input.value; } } diff --git a/src/Components/ElementsSidebar/ElementsSidebar.tsx b/src/Components/ElementsSidebar/ElementsSidebar.tsx index 21eb6b2..ab3efdd 100644 --- a/src/Components/ElementsSidebar/ElementsSidebar.tsx +++ b/src/Components/ElementsSidebar/ElementsSidebar.tsx @@ -14,8 +14,8 @@ interface IElementsSidebarProps { isOpen: boolean isHistoryOpen: boolean SelectedContainer: IContainerModel | null - OnPropertyChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void - OnPropertiesSubmit: (event: React.FormEvent) => void + OnPropertyChange: (key: string, value: string | number | boolean) => void + OnPropertiesSubmit: (event: React.FormEvent, properties: ContainerProperties) => void SelectContainer: (container: IContainerModel) => void DeleteContainer: (containerid: string) => void AddContainer: (index: number, type: string, parent: string) => void diff --git a/src/Components/InputGroup/InputGroup.tsx b/src/Components/InputGroup/InputGroup.tsx deleted file mode 100644 index bc794d3..0000000 --- a/src/Components/InputGroup/InputGroup.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import * as React from 'react'; - -interface IInputGroupProps { - labelKey?: string - labelText: string - inputKey: string - labelClassName: string - inputClassName: string - type: string - value?: string - checked?: boolean - defaultValue?: string - defaultChecked?: boolean - isDisabled?: boolean - onChange?: (event: React.ChangeEvent) => void -} - -const className = ` - w-full - text-xs font-medium transition-all text-gray-800 mt-1 px-3 py-2 - bg-white border-2 border-white rounded-lg placeholder-gray-800 - focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 - disabled:bg-slate-300 disabled:text-gray-500 disabled:border-slate-300 disabled:shadow-none`; - -export const InputGroup: React.FunctionComponent = (props) => { - return <> - - - ; -}; diff --git a/src/Components/Properties/DynamicForm.tsx b/src/Components/Properties/DynamicForm.tsx deleted file mode 100644 index 7ef1031..0000000 --- a/src/Components/Properties/DynamicForm.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import * as React from 'react'; -import IProperties from '../../Interfaces/IProperties'; -import { InputGroup } from '../InputGroup/InputGroup'; - -interface IDynamicFormProps { - properties: IProperties - onChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void -} - -const getCSSInputs = ( - properties: IProperties, - onChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void -): JSX.Element[] => { - const groupInput: JSX.Element[] = []; - for (const key in properties.style) { - groupInput.push( onChange(key, event.target.value, true)} - />); - } - return groupInput; -}; - -const DynamicForm: React.FunctionComponent = (props) => { - return ( -
- - - props.onChange('x', event.target.value)} - /> - props.onChange('y', event.target.value)} - /> - props.onChange('width', event.target.value)} - /> - props.onChange('height', event.target.value)} - /> - props.onChange('isRigidBody', event.target.checked)} - /> - props.onChange('isAnchor', event.target.checked)} - /> - props.onChange('xPositionReference', event.target.value)} - /> - { getCSSInputs(props.properties, props.onChange) } -
- ); -}; - -export default DynamicForm; diff --git a/src/Components/Properties/Form.tsx b/src/Components/Properties/Form.tsx deleted file mode 100644 index bc0f508..0000000 --- a/src/Components/Properties/Form.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import * as React from 'react'; -import IProperties from '../../Interfaces/IProperties'; -import DynamicForm from './DynamicForm'; -import StaticForm from './StaticForm'; - -interface IFormProps { - properties: IProperties - isDynamicInput: boolean - onChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void - onSubmit: (event: React.FormEvent) => void -} - -export const Form: React.FunctionComponent = (props) => { - if (props.isDynamicInput) { - return ; - } - return ; -}; diff --git a/src/Components/Properties/Properties.tsx b/src/Components/Properties/Properties.tsx index b72eead..516f23d 100644 --- a/src/Components/Properties/Properties.tsx +++ b/src/Components/Properties/Properties.tsx @@ -1,12 +1,12 @@ import React, { useState } from 'react'; -import IProperties from '../../Interfaces/IProperties'; +import ContainerProperties from '../../Interfaces/IProperties'; import { ToggleButton } from '../ToggleButton/ToggleButton'; -import { Form } from './Form'; +import { INPUT_TYPES } from './PropertiesInputTypes'; interface IPropertiesProps { - properties?: IProperties - onChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void - onSubmit: (event: React.FormEvent) => void + properties?: ContainerProperties + onChange: (key: string, value: string | number | boolean) => void + onSubmit: (event: React.FormEvent, properties: ContainerProperties) => void } export const Properties: React.FC = (props: IPropertiesProps) => { @@ -16,6 +16,26 @@ export const Properties: React.FC = (props: IPropertiesProps) return
; } + const groupInput: React.ReactNode[] = []; + Object + .entries(props.properties) + .forEach((pair) => handleProperties(pair, groupInput, isDynamicInput, props.onChange)); + + const form = isDynamicInput + ?
+ { groupInput } +
+ :
props.onSubmit(event, props.properties as ContainerProperties)} + > + +
+ { groupInput } +
+
+ ; + return (
= (props: IPropertiesProps) checked={isDynamicInput} onChange={() => setIsDynamicInput(!isDynamicInput)} /> -
+ { form }
); -}; \ No newline at end of file +}; + +const handleProperties = ( + [key, value]: [string, string | number], + groupInput: React.ReactNode[], + isDynamicInput: boolean, + onChange: (key: string, value: string | number | boolean) => void +): void => { + const id = `property-${key}`; + let type = 'text'; + let checked; + + /// hardcoded stuff for ergonomy /// + if (typeof value === 'boolean') { + checked = value; + } + + if (key in INPUT_TYPES) { + type = INPUT_TYPES[key]; + } + + const className = ` + w-full + text-xs font-medium transition-all text-gray-800 mt-1 px-3 py-2 + bg-white border-2 border-white rounded-lg placeholder-gray-800 + focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 + disabled:bg-slate-300 disabled:text-gray-500 disabled:border-slate-300 disabled:shadow-none`; + const isDisabled = ['id', 'parentId'].includes(key); + const input = isDynamicInput + ? { + if (type === 'checkbox') { + onChange(key, event.target.checked); + return; + } + onChange(key, event.target.value); + }} + disabled={isDisabled} + /> + : ; + + groupInput.push( + + ); + groupInput.push(input); +}; diff --git a/src/Components/Properties/StaticForm.tsx b/src/Components/Properties/StaticForm.tsx deleted file mode 100644 index 06a186e..0000000 --- a/src/Components/Properties/StaticForm.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import * as React from 'react'; -import IProperties from '../../Interfaces/IProperties'; -import { InputGroup } from '../InputGroup/InputGroup'; - -interface IStaticFormProps { - properties: IProperties - onSubmit: (event: React.FormEvent) => void -} - -const getCSSInputs = (properties: IProperties): JSX.Element[] => { - const groupInput: JSX.Element[] = []; - for (const key in properties.style) { - groupInput.push(); - } - return groupInput; -}; - -const StaticForm: React.FunctionComponent = (props) => { - return ( props.onSubmit(event)} - > - -
- - - - - - - - - - { getCSSInputs(props.properties) } -
- ); -}; - -export default StaticForm; diff --git a/src/Components/SVG/Elements/Container.tsx b/src/Components/SVG/Elements/Container.tsx index 11ec38d..56d4797 100644 --- a/src/Components/SVG/Elements/Container.tsx +++ b/src/Components/SVG/Elements/Container.tsx @@ -22,7 +22,7 @@ export const Container: React.FC = (props: IContainerProps) => props.model.properties.x, props.model.properties.y, props.model.properties.width, - props.model.properties.xPositionReference + props.model.properties.XPositionReference ); const transform = `translate(${transformedX}, ${transformedY})`; @@ -36,8 +36,12 @@ export const Container: React.FC = (props: IContainerProps) => // Rect style const style = Object.assign( JSON.parse(JSON.stringify(defaultStyle)), - props.model.properties.style + props.model.properties ); + style.x = 0; + style.y = 0; + delete style.height; + delete style.width; // Dimension props const depth = getDepth(props.model); diff --git a/src/Components/SVG/Elements/Selector.tsx b/src/Components/SVG/Elements/Selector.tsx index 5a0bb96..101f19a 100644 --- a/src/Components/SVG/Elements/Selector.tsx +++ b/src/Components/SVG/Elements/Selector.tsx @@ -20,7 +20,7 @@ export const Selector: React.FC = (props) => { x, y, props.selected.properties.width, - props.selected.properties.xPositionReference + props.selected.properties.XPositionReference ); const [width, height] = [ props.selected.properties.width, diff --git a/src/Components/UI/UI.tsx b/src/Components/UI/UI.tsx index c57daee..4fa36e6 100644 --- a/src/Components/UI/UI.tsx +++ b/src/Components/UI/UI.tsx @@ -8,6 +8,7 @@ import { IHistoryState } from '../../Interfaces/IHistoryState'; import { PhotographIcon, UploadIcon } from '@heroicons/react/outline'; import { FloatingButton } from '../FloatingButton/FloatingButton'; import { Bar } from '../Bar/Bar'; +import IProperties from '../../Interfaces/IProperties'; interface IUIProps { current: IHistoryState @@ -16,8 +17,8 @@ interface IUIProps { AvailableContainers: IAvailableContainer[] SelectContainer: (container: ContainerModel) => void DeleteContainer: (containerId: string) => void - OnPropertyChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void - OnPropertiesSubmit: (event: React.FormEvent) => void + OnPropertyChange: (key: string, value: string | number | boolean) => void + OnPropertiesSubmit: (event: React.FormEvent, properties: IProperties) => void AddContainerToSelectedContainer: (type: string) => void AddContainer: (index: number, type: string, parentId: string) => void SaveEditorAsJSON: () => void diff --git a/src/Interfaces/IProperties.ts b/src/Interfaces/IProperties.ts index c04584f..ad23442 100644 --- a/src/Interfaces/IProperties.ts +++ b/src/Interfaces/IProperties.ts @@ -10,7 +10,7 @@ import { XPositionReference } from '../Enums/XPositionReference'; * @property isRigidBody if true apply rigid body behaviors * @property isAnchor if true apply anchor behaviors */ -export default interface IProperties { +export default interface IProperties extends Omit { id: string parentId: string | null x: number @@ -19,6 +19,5 @@ export default interface IProperties { height: number isRigidBody: boolean isAnchor: boolean - xPositionReference?: XPositionReference - style?: React.CSSProperties + XPositionReference?: XPositionReference } diff --git a/src/utils/default.ts b/src/utils/default.ts index ae952bd..b16e528 100644 --- a/src/utils/default.ts +++ b/src/utils/default.ts @@ -34,10 +34,8 @@ export const DEFAULT_MAINCONTAINER_PROPS: IProperties = { height: Number(DEFAULT_CONFIG.MainContainer.Height), isRigidBody: false, isAnchor: false, - style: { - stroke: 'black', - fillOpacity: 0 - } + fillOpacity: 0, + stroke: 'black' }; export const DIMENSION_MARGIN = 50;