Implement symbols - Add, Remove, Select Container - Form - Link with container - Symbol behavior application to container (move to x with xpositionreference) Important changes - Remove SelectedContainer from HistoryState, meaning that it will be slower for each load but will be faster for each operations* (SetHistory, SelectContainer, DeleteContainer, SymbolOperations) - ElementsSidebar now opens with isSidebarOpen meaning that both sidebar will open on toggle - Moved camelize, transformX, restoreX to different modules (stringtools.ts, svg.ts)
134 lines
5 KiB
TypeScript
134 lines
5 KiB
TypeScript
import * as React from 'react';
|
|
import { ElementsSidebar } from '../ElementsSidebar/ElementsSidebar';
|
|
import { Sidebar } from '../Sidebar/Sidebar';
|
|
import { History } from '../History/History';
|
|
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
|
|
import { IContainerModel } from '../../Interfaces/IContainerModel';
|
|
import { IHistoryState } from '../../Interfaces/IHistoryState';
|
|
import { PhotographIcon, UploadIcon } from '@heroicons/react/outline';
|
|
import { FloatingButton } from '../FloatingButton/FloatingButton';
|
|
import { Bar } from '../Bar/Bar';
|
|
import { IAvailableSymbol } from '../../Interfaces/IAvailableSymbol';
|
|
import { Symbols } from '../Symbols/Symbols';
|
|
import { SymbolsSidebar } from '../SymbolsSidebar/SymbolsSidebar';
|
|
|
|
interface IUIProps {
|
|
SelectedContainer: IContainerModel | undefined
|
|
current: IHistoryState
|
|
history: IHistoryState[]
|
|
historyCurrentStep: number
|
|
AvailableContainers: IAvailableContainer[]
|
|
AvailableSymbols: IAvailableSymbol[]
|
|
SelectContainer: (containerId: string) => void
|
|
DeleteContainer: (containerId: string) => void
|
|
OnPropertyChange: (key: string, value: string | number | boolean, isStyle?: boolean) => void
|
|
OnPropertiesSubmit: (event: React.FormEvent<HTMLFormElement>) => void
|
|
AddContainerToSelectedContainer: (type: string) => void
|
|
AddContainer: (index: number, type: string, parentId: string) => void
|
|
AddSymbol: (type: string) => void
|
|
OnSymbolPropertyChange: (key: string, value: string | number | boolean) => void
|
|
SelectSymbol: (symbolId: string) => void
|
|
DeleteSymbol: (symbolId: string) => void
|
|
SaveEditorAsJSON: () => void
|
|
SaveEditorAsSVG: () => void
|
|
LoadState: (move: number) => void
|
|
}
|
|
|
|
function CloseOtherSidebars(
|
|
setIsSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>,
|
|
setIsSymbolsOpen: React.Dispatch<React.SetStateAction<boolean>>
|
|
): void {
|
|
setIsSidebarOpen(false);
|
|
setIsSymbolsOpen(false);
|
|
}
|
|
|
|
export const UI: React.FunctionComponent<IUIProps> = (props: IUIProps) => {
|
|
const [isSidebarOpen, setIsSidebarOpen] = React.useState(true);
|
|
const [isSymbolsOpen, setIsSymbolsOpen] = React.useState(false);
|
|
const [isHistoryOpen, setIsHistoryOpen] = React.useState(false);
|
|
|
|
let buttonRightOffsetClasses = 'right-12';
|
|
if (isSidebarOpen || isHistoryOpen) {
|
|
buttonRightOffsetClasses = 'right-72';
|
|
}
|
|
if (isHistoryOpen && isSidebarOpen) {
|
|
buttonRightOffsetClasses = 'right-[544px]';
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Bar
|
|
isSidebarOpen={isSidebarOpen}
|
|
isSymbolsOpen={isSymbolsOpen}
|
|
isElementsSidebarOpen={isSidebarOpen}
|
|
isHistoryOpen={isHistoryOpen}
|
|
ToggleSidebar={() => {
|
|
CloseOtherSidebars(setIsSidebarOpen, setIsSymbolsOpen);
|
|
setIsSidebarOpen(!isSidebarOpen);
|
|
}}
|
|
ToggleSymbols={() => {
|
|
CloseOtherSidebars(setIsSidebarOpen, setIsSymbolsOpen);
|
|
setIsSymbolsOpen(!isSymbolsOpen);
|
|
}}
|
|
ToggleTimeline={() => setIsHistoryOpen(!isHistoryOpen)}
|
|
/>
|
|
|
|
<Sidebar
|
|
componentOptions={props.AvailableContainers}
|
|
isOpen={isSidebarOpen}
|
|
buttonOnClick={props.AddContainerToSelectedContainer}
|
|
/>
|
|
<Symbols
|
|
componentOptions={props.AvailableSymbols}
|
|
isOpen={isSymbolsOpen}
|
|
buttonOnClick={props.AddSymbol}
|
|
/>
|
|
<ElementsSidebar
|
|
MainContainer={props.current.MainContainer}
|
|
symbols={props.current.Symbols}
|
|
SelectedContainer={props.SelectedContainer}
|
|
isOpen={isSidebarOpen}
|
|
isHistoryOpen={isHistoryOpen}
|
|
OnPropertyChange={props.OnPropertyChange}
|
|
OnPropertiesSubmit={props.OnPropertiesSubmit}
|
|
SelectContainer={props.SelectContainer}
|
|
DeleteContainer={props.DeleteContainer}
|
|
AddContainer={props.AddContainer}
|
|
/>
|
|
<SymbolsSidebar
|
|
SelectedSymbolId={props.current.SelectedSymbolId}
|
|
symbols={props.current.Symbols}
|
|
isOpen={isSymbolsOpen}
|
|
isHistoryOpen={isHistoryOpen}
|
|
OnPropertyChange={props.OnSymbolPropertyChange}
|
|
SelectSymbol={props.SelectSymbol}
|
|
DeleteSymbol={props.DeleteSymbol}
|
|
/>
|
|
<History
|
|
history={props.history}
|
|
historyCurrentStep={props.historyCurrentStep}
|
|
isOpen={isHistoryOpen}
|
|
jumpTo={props.LoadState}
|
|
/>
|
|
|
|
<FloatingButton className={`fixed z-10 flex flex-col gap-2 items-center bottom-40 ${buttonRightOffsetClasses}`}>
|
|
<button
|
|
className={'transition-all w-10 h-10 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'}
|
|
title='Export as JSON'
|
|
onClick={props.SaveEditorAsJSON}
|
|
>
|
|
<UploadIcon className="heroicon text-white" />
|
|
</button>
|
|
<button
|
|
className={'transition-all w-10 h-10 p-2 align-middle items-center justify-center rounded-full bg-blue-500 hover:bg-blue-800'}
|
|
title='Export as SVG'
|
|
onClick={props.SaveEditorAsSVG}
|
|
>
|
|
<PhotographIcon className="heroicon text-white" />
|
|
</button>
|
|
</FloatingButton>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default UI;
|