Add option for the properties form to only update on submit (#23)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: https://git.siklos-chaneru.duckdns.org/Siklos/svg-layout-designer-react/pulls/23
This commit is contained in:
parent
7c16d6c97d
commit
ac56f84196
12 changed files with 256 additions and 53 deletions
|
@ -1,4 +1,4 @@
|
|||
import { Dispatch, SetStateAction } from 'react';
|
||||
import React, { Dispatch, SetStateAction } from 'react';
|
||||
import { HistoryState } from '../../Interfaces/HistoryState';
|
||||
import { Configuration } from '../../Interfaces/Configuration';
|
||||
import { ContainerModel, IContainerModel } from '../../Interfaces/ContainerModel';
|
||||
|
@ -60,7 +60,7 @@ export function DeleteContainer(
|
|||
}
|
||||
|
||||
if (container === null || container === undefined) {
|
||||
throw new Error('[OnPropertyChange] Container model was not found among children of the main container!');
|
||||
throw new Error('[DeleteContainer] Container model was not found among children of the main container!');
|
||||
}
|
||||
|
||||
if (container.parent != null) {
|
||||
|
@ -266,6 +266,76 @@ export function OnPropertyChange(
|
|||
setHistoryCurrentStep(history.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handled the property change event in the properties form
|
||||
* @param key Property name
|
||||
* @param value New value of the property
|
||||
* @returns void
|
||||
*/
|
||||
export function OnPropertiesSubmit(
|
||||
event: React.SyntheticEvent<HTMLFormElement>,
|
||||
refs: Array<React.RefObject<HTMLInputElement>>,
|
||||
fullHistory: HistoryState[],
|
||||
historyCurrentStep: number,
|
||||
setHistory: Dispatch<SetStateAction<HistoryState[]>>,
|
||||
setHistoryCurrentStep: Dispatch<SetStateAction<number>>
|
||||
): void {
|
||||
event.preventDefault();
|
||||
const history = getCurrentHistory(fullHistory, historyCurrentStep);
|
||||
const current = history[history.length - 1];
|
||||
|
||||
if (current.SelectedContainer === null ||
|
||||
current.SelectedContainer === undefined) {
|
||||
throw new Error('[OnPropertyChange] Property was changed before selecting a Container');
|
||||
}
|
||||
|
||||
if (parent === null) {
|
||||
const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer);
|
||||
for (const ref of refs) {
|
||||
const input = ref.current;
|
||||
if (input instanceof HTMLInputElement) {
|
||||
(selectedContainerClone.properties as any)[input.id] = input.value;
|
||||
}
|
||||
}
|
||||
setHistory(history.concat([{
|
||||
LastAction: 'Change property of main',
|
||||
MainContainer: selectedContainerClone,
|
||||
SelectedContainer: selectedContainerClone,
|
||||
SelectedContainerId: selectedContainerClone.properties.id,
|
||||
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
return;
|
||||
}
|
||||
|
||||
const mainContainerClone: IContainerModel = structuredClone(current.MainContainer);
|
||||
const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id);
|
||||
|
||||
if (container === null || container === undefined) {
|
||||
throw new Error('[OnPropertyChange] Container model was not found among children of the main container!');
|
||||
}
|
||||
|
||||
for (const ref of refs) {
|
||||
const input = ref.current;
|
||||
if (input instanceof HTMLInputElement) {
|
||||
(container.properties as any)[input.id] = input.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (container.properties.isRigidBody) {
|
||||
RecalculatePhysics(container);
|
||||
}
|
||||
|
||||
setHistory(history.concat([{
|
||||
LastAction: `Change property of container ${container.properties.id}`,
|
||||
MainContainer: mainContainerClone,
|
||||
SelectedContainer: container,
|
||||
SelectedContainerId: container.properties.id,
|
||||
TypeCounters: Object.assign({}, current.TypeCounters)
|
||||
}]));
|
||||
setHistoryCurrentStep(history.length);
|
||||
}
|
||||
|
||||
// TODO put this in a different file
|
||||
|
||||
export function RecalculatePhysics(container: IContainerModel): IContainerModel {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Configuration } from '../../Interfaces/Configuration';
|
|||
import { SVG } from '../SVG/SVG';
|
||||
import { HistoryState } from '../../Interfaces/HistoryState';
|
||||
import { UI } from '../UI/UI';
|
||||
import { SelectContainer, DeleteContainer, OnPropertyChange, AddContainerToSelectedContainer, AddContainer } from './ContainerOperations';
|
||||
import { SelectContainer, DeleteContainer, OnPropertyChange, AddContainerToSelectedContainer, AddContainer, OnPropertiesSubmit } from './ContainerOperations';
|
||||
import { SaveEditorAsJSON, SaveEditorAsSVG } from './Save';
|
||||
import { onKeyDown } from './Shortcuts';
|
||||
|
||||
|
@ -72,6 +72,14 @@ const Editor: React.FunctionComponent<IEditorProps> = (props) => {
|
|||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
OnPropertiesSubmit={(event, refs) => OnPropertiesSubmit(
|
||||
event,
|
||||
refs,
|
||||
history,
|
||||
historyCurrentStep,
|
||||
setHistory,
|
||||
setHistoryCurrentStep
|
||||
)}
|
||||
AddContainerToSelectedContainer={(type) => AddContainerToSelectedContainer(
|
||||
type,
|
||||
configuration,
|
||||
|
|
|
@ -25,6 +25,7 @@ describe.concurrent('Elements sidebar', () => {
|
|||
isHistoryOpen={false}
|
||||
SelectedContainer={null}
|
||||
OnPropertyChange={() => {}}
|
||||
OnPropertiesSubmit={() => {}}
|
||||
SelectContainer={() => {}}
|
||||
DeleteContainer={() => {}}
|
||||
AddContainer={() => {}}
|
||||
|
@ -57,6 +58,7 @@ describe.concurrent('Elements sidebar', () => {
|
|||
isHistoryOpen={false}
|
||||
SelectedContainer={MainContainer}
|
||||
OnPropertyChange={() => {}}
|
||||
OnPropertiesSubmit={() => {}}
|
||||
SelectContainer={() => {}}
|
||||
DeleteContainer={() => {}}
|
||||
AddContainer={() => {}}
|
||||
|
@ -70,12 +72,12 @@ describe.concurrent('Elements sidebar', () => {
|
|||
expect(screen.queryByText('y')).toBeDefined();
|
||||
expect(screen.queryByText('width')).toBeDefined();
|
||||
expect(screen.queryByText('height')).toBeDefined();
|
||||
const propertyId = container.querySelector('#property-id');
|
||||
const propertyParentId = container.querySelector('#property-parentId');
|
||||
const propertyX = container.querySelector('#property-x');
|
||||
const propertyY = container.querySelector('#property-y');
|
||||
const propertyWidth = container.querySelector('#property-width');
|
||||
const propertyHeight = container.querySelector('#property-height');
|
||||
const propertyId = container.querySelector('#id');
|
||||
const propertyParentId = container.querySelector('#parentId');
|
||||
const propertyX = container.querySelector('#x');
|
||||
const propertyY = container.querySelector('#y');
|
||||
const propertyWidth = container.querySelector('#width');
|
||||
const propertyHeight = container.querySelector('#height');
|
||||
expect((propertyId as HTMLInputElement).value).toBe(MainContainer.properties.id.toString());
|
||||
expect(propertyParentId).toBeDefined();
|
||||
expect((propertyParentId as HTMLInputElement).value).toBe('');
|
||||
|
@ -146,6 +148,7 @@ describe.concurrent('Elements sidebar', () => {
|
|||
isHistoryOpen={false}
|
||||
SelectedContainer={MainContainer}
|
||||
OnPropertyChange={() => {}}
|
||||
OnPropertiesSubmit={() => {}}
|
||||
SelectContainer={() => {}}
|
||||
DeleteContainer={() => {}}
|
||||
AddContainer={() => {}}
|
||||
|
@ -202,6 +205,7 @@ describe.concurrent('Elements sidebar', () => {
|
|||
isHistoryOpen={false}
|
||||
SelectedContainer={SelectedContainer}
|
||||
OnPropertyChange={() => {}}
|
||||
OnPropertiesSubmit={() => {}}
|
||||
SelectContainer={selectContainer}
|
||||
DeleteContainer={() => {}}
|
||||
AddContainer={() => {}}
|
||||
|
@ -212,8 +216,8 @@ describe.concurrent('Elements sidebar', () => {
|
|||
expect(screen.getByText(/main/i));
|
||||
const child1 = screen.getByText(/child-1/i);
|
||||
expect(child1);
|
||||
const propertyId = container.querySelector('#property-id');
|
||||
const propertyParentId = container.querySelector('#property-parentId');
|
||||
const propertyId = container.querySelector('#id');
|
||||
const propertyParentId = container.querySelector('#parentId');
|
||||
expect((propertyId as HTMLInputElement).value).toBe(MainContainer.properties.id.toString());
|
||||
expect((propertyParentId as HTMLInputElement).value).toBe('');
|
||||
|
||||
|
@ -225,6 +229,7 @@ describe.concurrent('Elements sidebar', () => {
|
|||
isHistoryOpen={false}
|
||||
SelectedContainer={SelectedContainer}
|
||||
OnPropertyChange={() => {}}
|
||||
OnPropertiesSubmit={() => {}}
|
||||
SelectContainer={selectContainer}
|
||||
DeleteContainer={() => {}}
|
||||
AddContainer={() => {}}
|
||||
|
|
|
@ -14,6 +14,7 @@ interface IElementsSidebarProps {
|
|||
isHistoryOpen: boolean
|
||||
SelectedContainer: IContainerModel | null
|
||||
OnPropertyChange: (key: string, value: string | number | boolean) => void
|
||||
OnPropertiesSubmit: (event: React.FormEvent<HTMLFormElement>, refs: Array<React.RefObject<HTMLInputElement>>) => void
|
||||
SelectContainer: (container: IContainerModel) => void
|
||||
DeleteContainer: (containerid: string) => void
|
||||
AddContainer: (index: number, type: string, parent: string) => void
|
||||
|
@ -145,7 +146,11 @@ export const ElementsSidebar: React.FC<IElementsSidebarProps> = (props: IElement
|
|||
props.DeleteContainer(onClickContainerId);
|
||||
}} />
|
||||
</Menu>
|
||||
<Properties properties={props.SelectedContainer?.properties} onChange={props.OnPropertyChange}></Properties>
|
||||
<Properties
|
||||
properties={props.SelectedContainer?.properties}
|
||||
onChange={props.OnPropertyChange}
|
||||
onSubmit={props.OnPropertiesSubmit}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -38,13 +38,8 @@ export const MainMenu: React.FC<IMainMenuProps> = (props) => {
|
|||
</form>
|
||||
<button
|
||||
onClick={() => setWindowState(WindowState.MAIN)}
|
||||
className='block text-sm
|
||||
mt-8 py-2 px-4
|
||||
rounded-full border-0
|
||||
font-semibold
|
||||
transition-all
|
||||
bg-blue-100 text-blue-700
|
||||
hover:bg-blue-200'
|
||||
className='normal-btn block
|
||||
mt-8 '
|
||||
>
|
||||
Go back
|
||||
</button>
|
||||
|
|
|
@ -8,6 +8,7 @@ describe.concurrent('Properties', () => {
|
|||
render(<Properties
|
||||
properties={undefined}
|
||||
onChange={() => {}}
|
||||
onSubmit={() => {}}
|
||||
/>);
|
||||
|
||||
expect(screen.queryByText('id')).toBeNull();
|
||||
|
@ -16,7 +17,7 @@ describe.concurrent('Properties', () => {
|
|||
expect(screen.queryByText('y')).toBeNull();
|
||||
});
|
||||
|
||||
it('Some properties', () => {
|
||||
it('Some properties, change values with dynamic input', () => {
|
||||
const prop = {
|
||||
id: 'stuff',
|
||||
parentId: 'parentId',
|
||||
|
@ -32,6 +33,7 @@ describe.concurrent('Properties', () => {
|
|||
const { container, rerender } = render(<Properties
|
||||
properties={prop}
|
||||
onChange={handleChange}
|
||||
onSubmit={() => {}}
|
||||
/>);
|
||||
|
||||
expect(screen.queryByText('id')).toBeDefined();
|
||||
|
@ -39,10 +41,10 @@ describe.concurrent('Properties', () => {
|
|||
expect(screen.queryByText('x')).toBeDefined();
|
||||
expect(screen.queryByText('y')).toBeDefined();
|
||||
|
||||
let propertyId = container.querySelector('#property-id');
|
||||
let propertyParentId = container.querySelector('#property-parentId');
|
||||
let propertyX = container.querySelector('#property-x');
|
||||
let propertyY = container.querySelector('#property-y');
|
||||
let propertyId = container.querySelector('#id');
|
||||
let propertyParentId = container.querySelector('#parentId');
|
||||
let propertyX = container.querySelector('#x');
|
||||
let propertyY = container.querySelector('#y');
|
||||
expect(propertyId).toBeDefined();
|
||||
expect((propertyId as HTMLInputElement).value).toBe('stuff');
|
||||
expect(propertyParentId).toBeDefined();
|
||||
|
@ -65,12 +67,13 @@ describe.concurrent('Properties', () => {
|
|||
rerender(<Properties
|
||||
properties={Object.assign({}, prop)}
|
||||
onChange={handleChange}
|
||||
onSubmit={() => {}}
|
||||
/>);
|
||||
|
||||
propertyId = container.querySelector('#property-id');
|
||||
propertyParentId = container.querySelector('#property-parentId');
|
||||
propertyX = container.querySelector('#property-x');
|
||||
propertyY = container.querySelector('#property-y');
|
||||
propertyId = container.querySelector('#id');
|
||||
propertyParentId = container.querySelector('#parentId');
|
||||
propertyX = container.querySelector('#x');
|
||||
propertyY = container.querySelector('#y');
|
||||
expect(propertyId).toBeDefined();
|
||||
expect((propertyId as HTMLInputElement).value).toBe('stuffed');
|
||||
expect(propertyParentId).toBeDefined();
|
||||
|
|
|
@ -1,25 +1,50 @@
|
|||
import * as React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import ContainerProperties from '../../Interfaces/Properties';
|
||||
import { ToggleButton } from '../ToggleButton/ToggleButton';
|
||||
import { INPUT_TYPES } from './PropertiesInputTypes';
|
||||
|
||||
interface IPropertiesProps {
|
||||
properties?: ContainerProperties
|
||||
onChange: (key: string, value: string | number | boolean) => void
|
||||
onSubmit: (event: React.FormEvent<HTMLFormElement>, refs: Array<React.RefObject<HTMLInputElement>>) => void
|
||||
}
|
||||
|
||||
export const Properties: React.FC<IPropertiesProps> = (props: IPropertiesProps) => {
|
||||
const [isDynamicInput, setIsDynamicInput] = useState<boolean>(true);
|
||||
|
||||
if (props.properties === undefined) {
|
||||
return <div></div>;
|
||||
}
|
||||
|
||||
const groupInput: React.ReactNode[] = [];
|
||||
const refs: Array<React.RefObject<HTMLInputElement>> = [];
|
||||
Object
|
||||
.entries(props.properties)
|
||||
.forEach((pair) => handleProperties(pair, groupInput, props.onChange));
|
||||
.forEach((pair) => handleProperties(pair, groupInput, refs, isDynamicInput, props.onChange));
|
||||
|
||||
const form = isDynamicInput
|
||||
? <div>
|
||||
{ groupInput }
|
||||
</div>
|
||||
: <form
|
||||
key={props.properties.id}
|
||||
onSubmit={(event) => props.onSubmit(event, refs)}
|
||||
>
|
||||
<input type='submit' className='normal-btn block mx-auto' value='Submit'/>
|
||||
{ groupInput }
|
||||
</form>
|
||||
;
|
||||
|
||||
return (
|
||||
<div className='p-3 bg-slate-200 h-3/5 overflow-y-auto'>
|
||||
{ groupInput }
|
||||
<div className='h-3/5 p-3 bg-slate-200 overflow-y-auto'>
|
||||
<ToggleButton
|
||||
id='isDynamic'
|
||||
text='Dynamic update'
|
||||
title='Enable dynamic svg update'
|
||||
checked={isDynamicInput}
|
||||
onChange={() => setIsDynamicInput(!isDynamicInput)}
|
||||
/>
|
||||
{ form }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -27,6 +52,8 @@ export const Properties: React.FC<IPropertiesProps> = (props: IPropertiesProps)
|
|||
const handleProperties = (
|
||||
[key, value]: [string, string | number],
|
||||
groupInput: React.ReactNode[],
|
||||
refs: Array<React.RefObject<HTMLInputElement>>,
|
||||
isDynamicInput: boolean,
|
||||
onChange: (key: string, value: string | number | boolean) => void
|
||||
): void => {
|
||||
const id = `property-${key}`;
|
||||
|
@ -42,31 +69,49 @@ const handleProperties = (
|
|||
type = INPUT_TYPES[key];
|
||||
}
|
||||
|
||||
const isDisabled = ['id', 'parentId'].includes(key);
|
||||
///
|
||||
const ref: React.RefObject<HTMLInputElement> = React.useRef<HTMLInputElement>(null);
|
||||
refs.push(ref);
|
||||
|
||||
groupInput.push(
|
||||
<div key={id} className='mt-4'>
|
||||
<label className='text-sm font-medium text-gray-800' htmlFor={id}>{key}</label>
|
||||
<input
|
||||
className='text-base font-medium transition-all text-gray-800 mt-1 block w-full px-3 py-2
|
||||
const isDisabled = ['id', 'parentId'].includes(key);
|
||||
const input = isDynamicInput
|
||||
? <input
|
||||
className='text-base font-medium transition-all text-gray-800 mt-1 block w-full 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
|
||||
'
|
||||
type={type}
|
||||
id={id}
|
||||
value={value}
|
||||
checked={checked}
|
||||
onChange={(event) => {
|
||||
if (type === 'checkbox') {
|
||||
onChange(key, event.target.checked);
|
||||
return;
|
||||
}
|
||||
onChange(key, event.target.value);
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
type={type}
|
||||
id={key}
|
||||
ref={ref}
|
||||
value={value}
|
||||
checked={checked}
|
||||
onChange={(event) => {
|
||||
if (type === 'checkbox') {
|
||||
onChange(key, event.target.checked);
|
||||
return;
|
||||
}
|
||||
onChange(key, event.target.value);
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
: <input
|
||||
className='text-base font-medium transition-all text-gray-800 mt-1 block w-full 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
|
||||
'
|
||||
type={type}
|
||||
id={key}
|
||||
ref={ref}
|
||||
defaultValue={value}
|
||||
defaultChecked={checked}
|
||||
disabled={isDisabled}
|
||||
/>;
|
||||
|
||||
groupInput.push(
|
||||
<div key={id} className='mt-4'>
|
||||
<label className='text-sm font-medium text-gray-800' htmlFor={key}>{key}</label>
|
||||
{input}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
8
src/Components/ToggleButton/ToggleButton.scss
Normal file
8
src/Components/ToggleButton/ToggleButton.scss
Normal file
|
@ -0,0 +1,8 @@
|
|||
input:checked ~ .dot {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
input:checked ~ .line {
|
||||
background-color: #3B82F6;
|
||||
}
|
||||
|
||||
|
52
src/Components/ToggleButton/ToggleButton.tsx
Normal file
52
src/Components/ToggleButton/ToggleButton.tsx
Normal file
|
@ -0,0 +1,52 @@
|
|||
import React, { FC } from 'react';
|
||||
import './ToggleButton.scss';
|
||||
|
||||
interface IToggleButtonProps {
|
||||
id: string
|
||||
text: string
|
||||
type?: TOGGLE_TYPE
|
||||
title: string
|
||||
checked: boolean
|
||||
onChange: React.ChangeEventHandler<HTMLInputElement>
|
||||
}
|
||||
|
||||
export enum TOGGLE_TYPE {
|
||||
MATERIAL,
|
||||
IOS
|
||||
}
|
||||
|
||||
export const ToggleButton: FC<IToggleButtonProps> = (props) => {
|
||||
const id = `toggle-${props.id}`;
|
||||
const type = props.type ?? TOGGLE_TYPE.MATERIAL;
|
||||
let classLine = 'line w-10 h-4 bg-gray-400 rounded-full shadow-inner';
|
||||
let classDot = 'dot absolute w-6 h-6 bg-white rounded-full shadow -left-1 -top-1 transition';
|
||||
if (type === TOGGLE_TYPE.IOS) {
|
||||
classLine = 'line block bg-gray-600 w-14 h-8 rounded-full';
|
||||
classDot = 'dot absolute left-1 top-1 bg-white w-6 h-6 rounded-full transition';
|
||||
}
|
||||
|
||||
return (
|
||||
<div title={props.title}>
|
||||
<div className="flex items-center justify-center w-full mb-12">
|
||||
<label
|
||||
htmlFor={id}
|
||||
className="flex items-center cursor-pointer"
|
||||
>
|
||||
<div className="relative">
|
||||
<input
|
||||
id={id}
|
||||
type="checkbox"
|
||||
onChange={props.onChange}
|
||||
checked={props.checked}
|
||||
className="sr-only" />
|
||||
<div className={classLine}></div>
|
||||
<div className={classDot}></div>
|
||||
</div>
|
||||
<div className="ml-3 text-gray-700 font-medium">
|
||||
{ props.text }
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -17,6 +17,7 @@ interface IUIProps {
|
|||
SelectContainer: (container: ContainerModel) => void
|
||||
DeleteContainer: (containerId: string) => void
|
||||
OnPropertyChange: (key: string, value: string | number | boolean) => void
|
||||
OnPropertiesSubmit: (event: React.FormEvent<HTMLFormElement>, refs: Array<React.RefObject<HTMLInputElement>>) => void
|
||||
AddContainerToSelectedContainer: (type: string) => void
|
||||
AddContainer: (index: number, type: string, parentId: string) => void
|
||||
SaveEditorAsJSON: () => void
|
||||
|
@ -59,6 +60,7 @@ export const UI: React.FunctionComponent<IUIProps> = (props: IUIProps) => {
|
|||
isOpen={isElementsSidebarOpen}
|
||||
isHistoryOpen={isHistoryOpen}
|
||||
OnPropertyChange={props.OnPropertyChange}
|
||||
OnPropertiesSubmit={props.OnPropertiesSubmit}
|
||||
SelectContainer={props.SelectContainer}
|
||||
DeleteContainer={props.DeleteContainer}
|
||||
AddContainer={props.AddContainer}
|
||||
|
|
|
@ -23,6 +23,16 @@
|
|||
@apply transition-all bg-blue-100 hover:bg-blue-200 text-blue-700 text-lg font-semibold p-8 rounded-lg
|
||||
}
|
||||
|
||||
.normal-btn {
|
||||
@apply text-sm
|
||||
py-2 px-4
|
||||
rounded-full border-0
|
||||
font-semibold
|
||||
transition-all
|
||||
bg-blue-100 text-blue-700
|
||||
hover:bg-blue-200
|
||||
}
|
||||
|
||||
.floating-btn {
|
||||
@apply h-full w-full text-white align-middle items-center justify-center
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ export const DEFAULT_MAINCONTAINER_PROPS: Properties = {
|
|||
parentId: 'null',
|
||||
x: 0,
|
||||
y: 0,
|
||||
isRigidBody: false,
|
||||
width: DEFAULT_CONFIG.MainContainer.Width,
|
||||
height: DEFAULT_CONFIG.MainContainer.Height,
|
||||
isRigidBody: false,
|
||||
fillOpacity: 0,
|
||||
stroke: 'black'
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue