import * as React from 'react'; import { ElementsSideBar } from '../ElementsList/ElementsSideBar'; import { History } from '../History/History'; import { Bar, BAR_WIDTH } from '../Bar/Bar'; import { Symbols } from '../Symbols/Symbols'; import { SymbolsSidebar } from '../SymbolsList/SymbolsSidebar'; import { PropertyType } from '../../Enums/PropertyType'; import { Messages } from '../Messages/Messages'; import { Sidebar } from '../Sidebar/Sidebar'; import { Components } from '../Components/Components'; import { Viewer } from '../Viewer/Viewer'; import { Settings } from '../Settings/Settings'; import { IMessage } from '../../Interfaces/IMessage'; import { DISABLE_API } from '../../utils/default'; import { UseWorker, UseAsync } from './UseWorker'; import { FindContainerById } from '../../utils/itertools'; import { IEditorState } from '../../Interfaces/IEditorState'; import { GetCurrentHistoryState } from '../Editor/Editor'; import { Text } from '../Text/Text'; export interface IUIProps { editorState: IEditorState selectContainer: (containerId: string) => void deleteContainer: (containerId: string) => void onPropertyChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void addContainer: (type: string) => void addContainerAt: (index: number, type: string, parent: 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 } export enum SidebarType { None, Components, ComponentsExpanded, Symbols, SymbolsExpanded, History, Messages, Settings } function UseSetOrToggleSidebar( selectedSidebar: SidebarType, setSelectedSidebar: React.Dispatch> ): (newSidebarType: SidebarType) => void { return (newSidebarType) => { if (newSidebarType === selectedSidebar) { setSelectedSidebar(SidebarType.None); return; } setSelectedSidebar(newSidebarType); }; } export function UI({ editorState, ...methods }: IUIProps): JSX.Element { const [selectedSidebar, setSelectedSidebar] = React.useState(SidebarType.Components); const [messages, setMessages] = React.useState([]); const current = GetCurrentHistoryState(editorState.history, editorState.historyCurrentStep); const configuration = editorState.configuration; // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (window.Worker && !DISABLE_API) { UseWorker( current, configuration.APIConfiguration?.apiGetFeedbackUrl, setMessages ); } else if (!DISABLE_API) { UseAsync( current, configuration.APIConfiguration?.apiGetFeedbackUrl, setMessages ); } // Please use setOrToggleSidebar rather than setSelectedSidebar, so we can close the sidebar const setOrToggleSidebar = UseSetOrToggleSidebar(selectedSidebar, setSelectedSidebar); let leftSidebarTitle = ''; let rightSidebarTitle = ''; let leftChildren: JSX.Element = (<>); let rightChildren: JSX.Element = (<>); const mainContainer = FindContainerById(current.containers, current.mainContainer); if (mainContainer === undefined) { throw new Error('Tried to initialized UI but there is no main container!'); } const selectedContainer = FindContainerById(current.containers, current.selectedContainerId); switch (selectedSidebar) { case SidebarType.Components: leftSidebarTitle = Text({ textId: '@Components' }); leftChildren = ; rightSidebarTitle = Text({ textId: '@Elements' }); rightChildren = setOrToggleSidebar(SidebarType.ComponentsExpanded) } />; break; case SidebarType.ComponentsExpanded: leftSidebarTitle = Text({ textId: '@Components' }); leftChildren = ; rightSidebarTitle = Text({ textId: '@Elements' }); rightChildren = setOrToggleSidebar(SidebarType.Components) } />; break; case SidebarType.Symbols: leftSidebarTitle = Text({ textId: '@SymbolsLeft' }); leftChildren = ; rightSidebarTitle = Text({ textId: '@SymbolsRight' }); rightChildren = setOrToggleSidebar(SidebarType.SymbolsExpanded) } />; break; case SidebarType.SymbolsExpanded: leftSidebarTitle = Text({ textId: '@SymbolsLeft' }); leftChildren = ; rightSidebarTitle = Text({ textId: '@SymbolsRight' }); rightChildren = setOrToggleSidebar(SidebarType.Symbols)} />; break; case SidebarType.History: leftSidebarTitle = Text({ textId: '@Timeline' }); leftChildren = ; break; case SidebarType.Messages: leftSidebarTitle = Text({ textId: '@Messages' }); leftChildren = setMessages([])} />; break; case SidebarType.Settings: leftSidebarTitle = Text({ textId: '@Settings' }); leftChildren = ; break; } const isLeftSidebarOpen = selectedSidebar !== SidebarType.None; const isRightSidebarOpen = selectedSidebar === SidebarType.Components || selectedSidebar === SidebarType.Symbols; const isRightSidebarOpenExpanded = selectedSidebar === SidebarType.ComponentsExpanded || selectedSidebar === SidebarType.SymbolsExpanded; const isLeftSidebarOpenClasses = new Set([ 'left-sidebar', 'left-16', '-bottom-full', 'md:-left-64', 'md:bottom-0' ]); let isRightSidebarOpenClasses = 'right-0 -bottom-full md:-right-80 md:bottom-0'; let marginSidebar = BAR_WIDTH; const viewerMarginClasses = new Set([ 'ml-16' ]); if (isLeftSidebarOpen) { isLeftSidebarOpenClasses.delete('-bottom-full'); isLeftSidebarOpenClasses.delete('md:-left-64'); isLeftSidebarOpenClasses.delete('md:bottom-0'); marginSidebar += 256; viewerMarginClasses.add(' md:ml-80'); } if (isRightSidebarOpen || isRightSidebarOpenExpanded) { isRightSidebarOpenClasses = 'right-0'; if (isRightSidebarOpenExpanded) { viewerMarginClasses.add(' md:mr-[32rem]'); marginSidebar += 512; } else { viewerMarginClasses.add(' md:mr-64'); marginSidebar += 256; } } else { isLeftSidebarOpenClasses.delete('left-sidebar'); isLeftSidebarOpenClasses.add('left-sidebar-single'); } return ( <> { if (selectedSidebar === SidebarType.ComponentsExpanded) { setOrToggleSidebar(SidebarType.ComponentsExpanded); } else { setOrToggleSidebar(SidebarType.Components); } } } toggleSymbols={() => { if (selectedSidebar === SidebarType.SymbolsExpanded) { setOrToggleSidebar(SidebarType.SymbolsExpanded); } else { setOrToggleSidebar(SidebarType.Symbols); } } } toggleTimeline={() => { setOrToggleSidebar(SidebarType.History); } } toggleMessages={() => { setOrToggleSidebar(SidebarType.Messages); } } toggleSettings={() => { setOrToggleSidebar(SidebarType.Settings); } } /> { leftChildren } { rightChildren } ); }