Merged PR 320: #7697 - Remplacer par

Il faut juste que je confirme avec Eric le fonctionnement de l'index (pour l'insertion de l'element dupliqué) au même endroit

+ Peut être ajouté un guard si le nombre d'element autorisé dans un type n'est pas le même que l'element remplaçant

Related work items: #7687
This commit is contained in:
Carl Fuchs 2023-02-17 09:04:46 +00:00 committed by Eric Nguyen
commit 09654a6d50
10 changed files with 246 additions and 95 deletions

View file

@ -17,6 +17,7 @@ import { BarIcon } from './BarIcon';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';
interface IBarProps { interface IBarProps {
className: string
isComponentsOpen: boolean isComponentsOpen: boolean
isSymbolsOpen: boolean isSymbolsOpen: boolean
isHistoryOpen: boolean isHistoryOpen: boolean
@ -33,7 +34,7 @@ export const BAR_WIDTH = 64; // 4rem
export function Bar(props: IBarProps): JSX.Element { export function Bar(props: IBarProps): JSX.Element {
return ( return (
<div className='bar'> <div className={`bar ${props.className}`}>
<BarIcon <BarIcon
isActive={props.isComponentsOpen} isActive={props.isComponentsOpen}
title={Text({ textId: '@Components' })} title={Text({ textId: '@Components' })}

View file

@ -1,4 +1,4 @@
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'; import { EyeIcon, EyeSlashIcon, XCircleIcon } from '@heroicons/react/24/outline';
import * as React from 'react'; import * as React from 'react';
import { IAvailableContainer } from '../../Interfaces/IAvailableContainer'; import { IAvailableContainer } from '../../Interfaces/IAvailableContainer';
import { ICategory } from '../../Interfaces/ICategory'; import { ICategory } from '../../Interfaces/ICategory';
@ -6,11 +6,15 @@ import { IContainerModel } from '../../Interfaces/IContainerModel';
import { TruncateString } from '../../utils/stringtools'; import { TruncateString } from '../../utils/stringtools';
import { Category } from '../Category/Category'; import { Category } from '../Category/Category';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';
import { IReplaceContainer } from '../../Interfaces/IReplaceContainer';
import { Dispatch } from 'react';
interface IComponentsProps { interface IComponentsProps {
selectedContainer: IContainerModel | undefined selectedContainer: IContainerModel | undefined
componentOptions: IAvailableContainer[] componentOptions: IAvailableContainer[]
categories: ICategory[] categories: ICategory[]
replaceContainer: IReplaceContainer
setReplaceContainer: Dispatch<React.SetStateAction<IReplaceContainer>>
buttonOnClick: (type: string) => void buttonOnClick: (type: string) => void
} }
@ -62,6 +66,10 @@ export function Components(props: IComponentsProps): JSX.Element {
disabled = config.Blacklist?.find(type => type === componentOption.Type) !== undefined ?? false; disabled = config.Blacklist?.find(type => type === componentOption.Type) !== undefined ?? false;
} }
if (props.replaceContainer.isReplacing && componentOption.Category !== props.replaceContainer.category) {
disabled = true;
}
if (disabled && hideDisabled) { if (disabled && hideDisabled) {
return; return;
} }
@ -96,6 +104,15 @@ export function Components(props: IComponentsProps): JSX.Element {
return ( return (
<div className='h-full'> <div className='h-full'>
<div className='hover:bg-slate-300 h-7 text-right pr-1 pl-1'> <div className='hover:bg-slate-300 h-7 text-right pr-1 pl-1'>
{props.replaceContainer.isReplacing && <button
onClick={() => {
props.setReplaceContainer({ isReplacing: false, id: undefined, category: undefined });
}}
className='h-full hover:bg-slate-400 rounded-lg p-1'
>
<XCircleIcon className='heroicon'></XCircleIcon>
</button>
}
<button <button
onClick={() => { setHideDisabled(!hideDisabled); }} onClick={() => { setHideDisabled(!hideDisabled); }}
className='h-full hover:bg-slate-400 rounded-lg p-1' className='h-full hover:bg-slate-400 rounded-lg p-1'
@ -117,4 +134,4 @@ export function Components(props: IComponentsProps): JSX.Element {
</div> </div>
</div> </div>
); );
}; }

View file

@ -8,6 +8,8 @@ import Swal from 'sweetalert2';
import { PropertyType } from '../../../Enums/PropertyType'; import { PropertyType } from '../../../Enums/PropertyType';
import { TransformX, TransformY } from '../../../utils/svg'; import { TransformX, TransformY } from '../../../utils/svg';
import { Orientation } from '../../../Enums/Orientation'; import { Orientation } from '../../../Enums/Orientation';
import { AddContainers } from './AddContainer';
import { IConfiguration } from '../../../Interfaces/IConfiguration';
/** /**
* Select a container * Select a container
@ -133,6 +135,58 @@ export function DeleteContainer(
return history; return history;
} }
/**
* Replace a container
* @param containerId containerId of the container to delete
* @param newContainerId
* @param configuration
* @param fullHistory History of the editor
* @param historyCurrentStep Current step
* @returns New history
*/
export function ReplaceByContainer(
containerId: string,
newContainerId: string,
configuration: IConfiguration,
fullHistory: IHistoryState[],
historyCurrentStep: number
): IHistoryState[] {
const history = GetCurrentHistory(fullHistory, historyCurrentStep);
const current = history[history.length - 1];
const containerToReplace = FindContainerById(current.containers, containerId);
if (containerToReplace === undefined) {
return history;
}
const containerParent = FindContainerById(current.containers, containerToReplace.properties.parentId);
if (containerParent === undefined) {
return history;
}
const historyAdd = AddContainers(
containerParent.children.indexOf(containerId),
[{ Type: newContainerId }],
containerParent.properties.id,
configuration, fullHistory, historyCurrentStep
);
const historyDelete = DeleteContainer(containerId, historyAdd.history, historyCurrentStep + 1);
const currentDelete = historyDelete[historyDelete.length - 1];
fullHistory.push({
lastAction: `Replace ${containerId} by ${newContainerId}`,
mainContainer: currentDelete.mainContainer,
containers: currentDelete.containers,
selectedContainerId: currentDelete.selectedContainerId,
typeCounters: Object.assign({}, currentDelete.typeCounters),
symbols: current.symbols,
selectedSymbolId: current.selectedSymbolId
});
return fullHistory;
}
/** /**
* Returns the next container that will be selected * Returns the next container that will be selected
* after the selectedContainer is removed. * after the selectedContainer is removed.

View file

@ -16,6 +16,7 @@ import { AddContainers } from './AddContainer';
import { DeleteContainer } from './ContainerOperations'; import { DeleteContainer } from './ContainerOperations';
import { DeleteSymbol } from './SymbolOperations'; import { DeleteSymbol } from './SymbolOperations';
import { Text } from '../../Text/Text'; import { Text } from '../../Text/Text';
import { IReplaceContainer } from '../../../Interfaces/IReplaceContainer';
export function InitActions( export function InitActions(
menuActions: Map<string, IMenuAction[]>, menuActions: Map<string, IMenuAction[]>,
@ -23,7 +24,8 @@ export function InitActions(
history: IHistoryState[], history: IHistoryState[],
historyCurrentStep: number, historyCurrentStep: number,
setNewHistory: (newHistory: IHistoryState[]) => void, setNewHistory: (newHistory: IHistoryState[]) => void,
setHistoryCurrentStep: Dispatch<SetStateAction<number>> setHistoryCurrentStep: Dispatch<SetStateAction<number>>,
setIsReplacingContainer: Dispatch<SetStateAction<IReplaceContainer>>
): void { ): void {
menuActions.set( menuActions.set(
'', '',
@ -56,9 +58,24 @@ export function InitActions(
menuActions.set( menuActions.set(
'elements-sidebar-row', 'elements-sidebar-row',
[{ [{
text: Text({ textId: '@ReplaceByContainer' }),
title: Text({ textId: '@ReplaceByContainerTitle' }),
shortcut: '<kbd>R</kbd>',
action: (target: HTMLElement) => {
const targetContainer = FindContainerById(history[historyCurrentStep].containers, target.id);
const targetAvailableContainer = configuration.AvailableContainers.find((availableContainer) => availableContainer.Type === targetContainer?.properties.type);
if (targetAvailableContainer === undefined) {
return;
}
setIsReplacingContainer({ isReplacing: true, id: target.id, category: targetAvailableContainer.Category });
}
}, {
text: Text({ textId: '@DeleteContainer' }), text: Text({ textId: '@DeleteContainer' }),
title: Text({ textId: '@DeleteContainerTitle' }), title: Text({ textId: '@DeleteContainerTitle' }),
shortcut: '<kbd>Suppr</kbd>', shortcut: '<kbd>Suppr</kbd>',
action: (target: HTMLElement) => { action: (target: HTMLElement) => {
const id = target.id; const id = target.id;
const newHistory = DeleteContainer( const newHistory = DeleteContainer(

View file

@ -7,7 +7,8 @@ export function OnKey(
history: IHistoryState[], history: IHistoryState[],
historyCurrentStep: number, historyCurrentStep: number,
setHistoryCurrentStep: Dispatch<SetStateAction<number>>, setHistoryCurrentStep: Dispatch<SetStateAction<number>>,
deleteAction: () => void deleteAction: () => void,
resetState: () => void
): void { ): void {
if (!ENABLE_SHORTCUTS) { if (!ENABLE_SHORTCUTS) {
return; return;
@ -27,5 +28,7 @@ export function OnKey(
setHistoryCurrentStep(historyCurrentStep + 1); setHistoryCurrentStep(historyCurrentStep + 1);
} else if (event.key === 'Delete') { } else if (event.key === 'Delete') {
deleteAction(); deleteAction();
} else if (event.key === 'Escape') {
resetState();
} }
} }

View file

@ -1,9 +1,9 @@
import React, { Dispatch, SetStateAction, useEffect, useRef } from 'react'; import React, { type Dispatch, type SetStateAction, useEffect, useRef } from 'react';
import './Editor.scss'; import './Editor.scss';
import { IConfiguration } from '../../Interfaces/IConfiguration'; import { type IConfiguration } from '../../Interfaces/IConfiguration';
import { IHistoryState } from '../../Interfaces/IHistoryState'; import { type IHistoryState } from '../../Interfaces/IHistoryState';
import { UI } from '../UI/UI'; import { UI } from '../UI/UI';
import { SelectContainer, DeleteContainer, OnPropertyChange } from './Actions/ContainerOperations'; import { SelectContainer, DeleteContainer, OnPropertyChange, ReplaceByContainer } from './Actions/ContainerOperations';
import { SaveEditorAsJSON, SaveEditorAsSVG } from './Actions/Save'; import { SaveEditorAsJSON, SaveEditorAsSVG } from './Actions/Save';
import { OnKey } from './Actions/Shortcuts'; import { OnKey } from './Actions/Shortcuts';
import { UseCustomEvents, UseEditorListener } from '../../Events/EditorEvents'; import { UseCustomEvents, UseEditorListener } from '../../Events/EditorEvents';
@ -13,6 +13,7 @@ import { FindContainerById } from '../../utils/itertools';
import { Menu } from '../Menu/Menu'; import { Menu } from '../Menu/Menu';
import { InitActions } from './Actions/ContextMenuActions'; import { InitActions } from './Actions/ContextMenuActions';
import { AddContainerToSelectedContainer, AddContainer } from './Actions/AddContainer'; import { AddContainerToSelectedContainer, AddContainer } from './Actions/AddContainer';
import { type IReplaceContainer } from '../../Interfaces/IReplaceContainer';
interface IEditorProps { interface IEditorProps {
root: Element | Document root: Element | Document
@ -25,16 +26,18 @@ function UseShortcuts(
history: IHistoryState[], history: IHistoryState[],
historyCurrentStep: number, historyCurrentStep: number,
setHistoryCurrentStep: Dispatch<SetStateAction<number>>, setHistoryCurrentStep: Dispatch<SetStateAction<number>>,
deleteAction: () => void deleteAction: () => void,
resetState: () => void
): void { ): void {
useEffect(() => { useEffect(() => {
function OnKeyUp(event: KeyboardEvent): void { function OnKeyUp(event: KeyboardEvent): void {
return OnKey( OnKey(
event, event,
history, history,
historyCurrentStep, historyCurrentStep,
setHistoryCurrentStep, setHistoryCurrentStep,
deleteAction deleteAction,
resetState
); );
} }
@ -62,13 +65,20 @@ function UseNewHistoryState(
}; };
} }
export function Editor(props: IEditorProps): JSX.Element { export function Editor(props: IEditorProps): JSX.Element {
// States // States
const [history, setHistory] = React.useState<IHistoryState[]>(structuredClone(props.history)); const [history, setHistory] = React.useState<IHistoryState[]>(structuredClone(props.history));
const [historyCurrentStep, setHistoryCurrentStep] = React.useState<number>(props.historyCurrentStep); const [historyCurrentStep, setHistoryCurrentStep] = React.useState<number>(props.historyCurrentStep);
const [replaceContainer, setReplaceContainer] = React.useState<IReplaceContainer>({ isReplacing: false, id: undefined, category: undefined });
const editorRef = useRef<HTMLDivElement>(null); const editorRef = useRef<HTMLDivElement>(null);
const setNewHistory = UseNewHistoryState(setHistory, setHistoryCurrentStep); const setNewHistory = UseNewHistoryState(setHistory, setHistoryCurrentStep);
function ResetState(): void {
setReplaceContainer({ isReplacing: false, id: undefined, category: undefined });
}
// Events // Events
UseShortcuts( UseShortcuts(
history, history,
@ -79,7 +89,8 @@ export function Editor(props: IEditorProps): JSX.Element {
setNewHistory( setNewHistory(
DeleteContainer(current.selectedContainerId, history, historyCurrentStep) DeleteContainer(current.selectedContainerId, history, historyCurrentStep)
); );
} },
ResetState
); );
UseCustomEvents( UseCustomEvents(
props.root, props.root,
@ -104,7 +115,8 @@ export function Editor(props: IEditorProps): JSX.Element {
history, history,
historyCurrentStep, historyCurrentStep,
setNewHistory, setNewHistory,
setHistoryCurrentStep setHistoryCurrentStep,
setReplaceContainer
); );
// Render // Render
@ -113,37 +125,54 @@ export function Editor(props: IEditorProps): JSX.Element {
const selected = FindContainerById(current.containers, current.selectedContainerId); const selected = FindContainerById(current.containers, current.selectedContainerId);
return ( return (
<div ref={editorRef} className="Editor font-sans h-full"> <div ref={editorRef} className="Editor font-sans h-full ">
<UI <UI
editorState={{ editorState={{
configuration: props.configuration, configuration: props.configuration,
history, history,
historyCurrentStep historyCurrentStep
}} }}
selectContainer={(container) => setNewHistory( replaceContainer={replaceContainer}
selectContainer={(container) => {
setNewHistory(
SelectContainer( SelectContainer(
container, container,
history, history,
historyCurrentStep historyCurrentStep
))} ));
deleteContainer={(containerId: string) => setNewHistory( }}
deleteContainer={(containerId: string) => {
setNewHistory(
DeleteContainer( DeleteContainer(
containerId, containerId,
history, history,
historyCurrentStep historyCurrentStep
))} ));
onPropertyChange={(key, value, type) => setNewHistory( }}
onPropertyChange={(key, value, type) => {
setNewHistory(
OnPropertyChange( OnPropertyChange(
key, value, type, key, value, type,
selected, selected,
history, history,
historyCurrentStep historyCurrentStep
))} ));
addContainer={(type) => { }}
addOrReplaceContainer={(type) => {
if (selected === null || selected === undefined) { if (selected === null || selected === undefined) {
return; return;
} }
if (replaceContainer.isReplacing && replaceContainer.id !== undefined) {
const newHistory = ReplaceByContainer(
replaceContainer.id,
type,
configuration,
history,
historyCurrentStep
);
setReplaceContainer({ isReplacing: false, id: undefined, category: undefined });
setNewHistory(newHistory);
} else {
setNewHistory(AddContainerToSelectedContainer( setNewHistory(AddContainerToSelectedContainer(
type, type,
selected, selected,
@ -151,8 +180,10 @@ export function Editor(props: IEditorProps): JSX.Element {
history, history,
historyCurrentStep historyCurrentStep
)); ));
}
}} }}
addContainerAt={(index, type, parent) => setNewHistory( addContainerAt={(index, type, parent) => {
setNewHistory(
AddContainer( AddContainer(
index, index,
type, type,
@ -161,39 +192,51 @@ export function Editor(props: IEditorProps): JSX.Element {
history, history,
historyCurrentStep historyCurrentStep
) )
)} );
addSymbol={(type) => setNewHistory( }}
addSymbol={(type) => {
setNewHistory(
AddSymbol( AddSymbol(
type, type,
configuration, configuration,
history, history,
historyCurrentStep historyCurrentStep
))} ));
onSymbolPropertyChange={(key, value) => setNewHistory( }}
onSymbolPropertyChange={(key, value) => {
setNewHistory(
OnSymbolPropertyChange( OnSymbolPropertyChange(
key, value, key, value,
history, history,
historyCurrentStep historyCurrentStep
))} ));
selectSymbol={(symbolId) => setNewHistory( }}
selectSymbol={(symbolId) => {
setNewHistory(
SelectSymbol( SelectSymbol(
symbolId, symbolId,
history, history,
historyCurrentStep historyCurrentStep
))} ));
deleteSymbol={(symbolId) => setNewHistory( }}
deleteSymbol={(symbolId) => {
setNewHistory(
DeleteSymbol( DeleteSymbol(
symbolId, symbolId,
history, history,
historyCurrentStep historyCurrentStep
))} ));
saveEditorAsJSON={() => SaveEditorAsJSON( }}
saveEditorAsJSON={() => {
SaveEditorAsJSON(
history, history,
historyCurrentStep, historyCurrentStep,
configuration configuration
)} );
saveEditorAsSVG={() => SaveEditorAsSVG()} }}
loadState={(move) => setHistoryCurrentStep(move)} saveEditorAsSVG={() => { SaveEditorAsSVG(); }}
loadState={(move) => { setHistoryCurrentStep(move); }}
setReplaceContainer={setReplaceContainer}
/> />
<Menu <Menu
getListener={() => editorRef.current} getListener={() => editorRef.current}

View file

@ -21,6 +21,7 @@ export interface IMenuAction {
/** function to be called on button click */ /** function to be called on button click */
action: (target: HTMLElement) => void action: (target: HTMLElement) => void
} }
function UseMouseEvents( function UseMouseEvents(
@ -139,7 +140,7 @@ function AddClassSpecificActions(
onClick={() => action.action(target)} />); onClick={() => action.action(target)} />);
}); });
children.push(<hr key={`contextmenu-hr-${count}`} className='border-slate-400' />); children.push(<hr key={`contextmenu-hr-${count}`} className='border-slate-400' />);
}; }
return count; return count;
} }

View file

@ -17,13 +17,16 @@ import { FindContainerById } from '../../utils/itertools';
import { type IEditorState } from '../../Interfaces/IEditorState'; import { type IEditorState } from '../../Interfaces/IEditorState';
import { GetCurrentHistoryState } from '../Editor/Editor'; import { GetCurrentHistoryState } from '../Editor/Editor';
import { Text } from '../Text/Text'; import { Text } from '../Text/Text';
import { IReplaceContainer } from '../../Interfaces/IReplaceContainer';
import { Dispatch } from 'react';
export interface IUIProps { export interface IUIProps {
editorState: IEditorState editorState: IEditorState
replaceContainer: IReplaceContainer
selectContainer: (containerId: string) => void selectContainer: (containerId: string) => void
deleteContainer: (containerId: string) => void deleteContainer: (containerId: string) => void
onPropertyChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void onPropertyChange: (key: string, value: string | number | boolean | number[], type?: PropertyType) => void
addContainer: (type: string) => void addOrReplaceContainer: (type: string) => void
addContainerAt: (index: number, type: string, parent: string) => void addContainerAt: (index: number, type: string, parent: string) => void
addSymbol: (type: string) => void addSymbol: (type: string) => void
onSymbolPropertyChange: (key: string, value: string | number | boolean) => void onSymbolPropertyChange: (key: string, value: string | number | boolean) => void
@ -32,6 +35,8 @@ export interface IUIProps {
saveEditorAsJSON: () => void saveEditorAsJSON: () => void
saveEditorAsSVG: () => void saveEditorAsSVG: () => void
loadState: (move: number) => void loadState: (move: number) => void
setReplaceContainer: Dispatch<React.SetStateAction<IReplaceContainer>>
} }
export enum SidebarType { export enum SidebarType {
@ -59,7 +64,7 @@ function UseSetOrToggleSidebar(
}; };
} }
export function UI({ editorState, ...methods }: IUIProps): JSX.Element { export function UI({ editorState, replaceContainer, setReplaceContainer, ...methods }: IUIProps): JSX.Element {
const [selectedSidebar, setSelectedSidebar] = React.useState<SidebarType>(SidebarType.Components); const [selectedSidebar, setSelectedSidebar] = React.useState<SidebarType>(SidebarType.Components);
const [messages, setMessages] = React.useState<IMessage[]>([]); const [messages, setMessages] = React.useState<IMessage[]>([]);
@ -101,12 +106,14 @@ export function UI({ editorState, ...methods }: IUIProps): JSX.Element {
switch (selectedSidebar) { switch (selectedSidebar) {
case SidebarType.Components: case SidebarType.Components:
leftSidebarTitle = Text({ textId: '@Components' }); leftSidebarTitle = Text({ textId: '@Components' });
leftChildren = <Components leftChildren = <Components
selectedContainer={selectedContainer} selectedContainer={selectedContainer}
componentOptions={configuration.AvailableContainers} componentOptions={configuration.AvailableContainers}
categories={configuration.Categories} categories={configuration.Categories}
buttonOnClick={methods.addContainer} buttonOnClick={methods.addOrReplaceContainer}
/>; replaceContainer={replaceContainer}
setReplaceContainer={setReplaceContainer}/>;
rightSidebarTitle = Text({ textId: '@Elements' }); rightSidebarTitle = Text({ textId: '@Elements' });
rightChildren = <ElementsSideBar rightChildren = <ElementsSideBar
containers={current.containers} containers={current.containers}
@ -126,8 +133,9 @@ export function UI({ editorState, ...methods }: IUIProps): JSX.Element {
selectedContainer={selectedContainer} selectedContainer={selectedContainer}
componentOptions={configuration.AvailableContainers} componentOptions={configuration.AvailableContainers}
categories={configuration.Categories} categories={configuration.Categories}
buttonOnClick={methods.addContainer} buttonOnClick={methods.addOrReplaceContainer}
/>; replaceContainer={replaceContainer}
setReplaceContainer={setReplaceContainer}/>;
rightSidebarTitle = Text({ textId: '@Elements' }); rightSidebarTitle = Text({ textId: '@Elements' });
rightChildren = <ElementsSideBar rightChildren = <ElementsSideBar
containers={current.containers} containers={current.containers}
@ -243,12 +251,14 @@ export function UI({ editorState, ...methods }: IUIProps): JSX.Element {
isLeftSidebarOpenClasses.add('left-sidebar-single'); isLeftSidebarOpenClasses.add('left-sidebar-single');
} }
const clickRestrictionsClasses = replaceContainer.isReplacing ? 'pointer-events-none opacity-50' : '';
const isComponentsOpen = selectedSidebar === SidebarType.Components || selectedSidebar === SidebarType.ComponentsExpanded; const isComponentsOpen = selectedSidebar === SidebarType.Components || selectedSidebar === SidebarType.ComponentsExpanded;
const isSymbolsOpen = selectedSidebar === SidebarType.Symbols || selectedSidebar === SidebarType.SymbolsExpanded; const isSymbolsOpen = selectedSidebar === SidebarType.Symbols || selectedSidebar === SidebarType.SymbolsExpanded;
return ( return (
<> <>
<Bar <Bar
className={clickRestrictionsClasses}
isComponentsOpen={isComponentsOpen} isComponentsOpen={isComponentsOpen}
isSymbolsOpen={isSymbolsOpen} isSymbolsOpen={isSymbolsOpen}
isHistoryOpen={selectedSidebar === SidebarType.History} isHistoryOpen={selectedSidebar === SidebarType.History}
@ -285,7 +295,7 @@ export function UI({ editorState, ...methods }: IUIProps): JSX.Element {
{ leftChildren } { leftChildren }
</Sidebar> </Sidebar>
<Viewer <Viewer
className={`${[...viewerMarginClasses.values()].join(' ')} w-full h-full`} className={`${clickRestrictionsClasses} ${[...viewerMarginClasses.values()].join(' ')} w-full h-full`}
current={current} current={current}
isComponentsOpen={isComponentsOpen} isComponentsOpen={isComponentsOpen}
isSymbolsOpen={isSymbolsOpen} isSymbolsOpen={isSymbolsOpen}
@ -295,7 +305,7 @@ export function UI({ editorState, ...methods }: IUIProps): JSX.Element {
margin={marginSidebar} margin={marginSidebar}
/> />
<Sidebar <Sidebar
className={`right-sidebar ${isRightSidebarOpenClasses}`} className={`right-sidebar ${isRightSidebarOpenClasses} ${clickRestrictionsClasses}`}
title={rightSidebarTitle} title={rightSidebarTitle}
> >
{ rightChildren } { rightChildren }

View file

@ -14,7 +14,7 @@ import { useState } from 'react';
import { type ISymbolModel } from '../../Interfaces/ISymbolModel'; import { type ISymbolModel } from '../../Interfaces/ISymbolModel';
interface IViewerProps { interface IViewerProps {
className?: string className: string
current: IHistoryState current: IHistoryState
selectedContainer: IContainerModel | undefined selectedContainer: IContainerModel | undefined
selectContainer: (containerId: string) => void selectContainer: (containerId: string) => void
@ -133,7 +133,7 @@ export function Viewer({
return ( return (
<Canvas <Canvas
draw={Draw} draw={Draw}
className='ml-16' className={`ml-16 ${className}`}
width={window.innerWidth - BAR_WIDTH} width={window.innerWidth - BAR_WIDTH}
height={window.innerHeight} height={window.innerHeight}
/> />

View file

@ -0,0 +1,5 @@
export interface IReplaceContainer {
id: string | undefined
isReplacing: boolean
category: string | undefined
}