refactor: moves Ui layer styling to parent component

This commit is contained in:
Mark Mankarious
2023-08-31 12:51:19 +01:00
parent c240def317
commit d581f28d01
7 changed files with 164 additions and 122 deletions

View File

@@ -1,8 +1,7 @@
import React, { useMemo } from 'react';
import { useTheme } from '@mui/material';
import { Box } from '@mui/material';
import { useUiStateStore } from 'src/stores/uiStateStore';
import { IconSelection } from 'src/components/ItemControls/IconSelection/IconSelection';
import { UiElement } from 'components/UiElement/UiElement';
import { NodeControls } from './NodeControls/NodeControls';
import { ConnectorControls } from './ConnectorControls/ConnectorControls';
import { TextBoxControls } from './TextBoxControls/TextBoxControls';
@@ -12,7 +11,6 @@ export const ItemControlsManager = () => {
const itemControls = useUiStateStore((state) => {
return state.itemControls;
});
const theme = useTheme();
const Controls = useMemo(() => {
switch (itemControls?.type) {
@@ -31,25 +29,13 @@ export const ItemControlsManager = () => {
}
}, [itemControls]);
const topOffset = useMemo(() => {
return theme.customVars.appPadding.y * 2 + parseInt(theme.spacing(2), 10);
}, [theme]);
return (
<UiElement
<Box
sx={{
top: topOffset,
maxHeight: `calc(100% - ${
topOffset + theme.customVars.appPadding.y
}px)`,
overflowY: 'scroll',
'&::-webkit-scrollbar': {
display: 'none'
},
width: '345px'
width: '100%'
}}
>
{Controls}
</UiElement>
</Box>
);
};

View File

@@ -76,7 +76,7 @@ export const Renderer = () => {
<DebugUtils />
</SceneLayer>
)}
{/* Interaction layer */}
{/* Interaction layer: this is where events are detected */}
<SceneLayer ref={containerRef} />
</Box>
);

View File

@@ -8,7 +8,6 @@ import { useUiStateStore } from 'src/stores/uiStateStore';
import { useSceneStore } from 'src/stores/sceneStore';
import { Svg } from 'src/components/Svg/Svg';
import { useIsoProjection } from 'src/hooks/useIsoProjection';
import { IsoTileArea } from 'src/components/IsoTileArea/IsoTileArea';
interface Props {
connector: ConnectorI;
@@ -102,7 +101,7 @@ export const Connector = ({ connector }: Props) => {
fill="none"
/>
{anchorPositions.map((anchor, i) => {
{anchorPositions.map((anchor) => {
return (
<>
<Circle
@@ -115,7 +114,7 @@ export const Connector = ({ connector }: Props) => {
position={CoordsUtils.add(anchor, drawOffset)}
radius={12 * zoom}
stroke={theme.palette.common.black}
fill={i === 0 ? 'red' : theme.palette.common.white}
fill={theme.palette.common.white}
strokeWidth={6 * zoom}
/>
</>

View File

@@ -1,4 +1,5 @@
import React from 'react';
import { Stack } from '@mui/material';
import {
PanToolOutlined as PanToolIcon,
ZoomInOutlined as ZoomInIcon,
@@ -10,7 +11,7 @@ import {
Title as TitleIcon
} from '@mui/icons-material';
import { useUiStateStore } from 'src/stores/uiStateStore';
import { MAX_ZOOM, MIN_ZOOM, TEXTBOX_DEFAULTS } from 'src/config';
import { MAX_ZOOM, MIN_ZOOM } from 'src/config';
import { IconButton } from 'src/components/IconButton/IconButton';
import { UiElement } from 'src/components/UiElement/UiElement';
@@ -26,92 +27,94 @@ export const ToolMenu = () => {
});
return (
<UiElement orientation="TOPRIGHT">
<IconButton
name="Select"
Icon={<NearMeIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'CURSOR',
showCursor: true,
mousedownItem: null
});
}}
isActive={mode.type === 'CURSOR' || mode.type === 'DRAG_ITEMS'}
/>
<IconButton
name="Pan"
Icon={<PanToolIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'PAN',
showCursor: false
});
}}
isActive={mode.type === 'PAN'}
/>
<IconButton
name="Add element"
Icon={<AddIcon />}
onClick={() => {
uiStateStoreActions.setItemControls({
type: 'ADD_ITEM'
});
uiStateStoreActions.setMode({
type: 'PLACE_ELEMENT',
showCursor: true,
icon: null
});
}}
isActive={mode.type === 'PLACE_ELEMENT'}
/>
<IconButton
name="Rectangle"
Icon={<CropSquareIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'RECTANGLE.DRAW',
showCursor: true,
area: null
});
}}
isActive={mode.type === 'RECTANGLE.DRAW'}
/>
<IconButton
name="Connector"
Icon={<ConnectorIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'CONNECTOR',
connector: null,
showCursor: true
});
}}
isActive={mode.type === 'CONNECTOR'}
/>
<IconButton
name="Text"
Icon={<TitleIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'TEXTBOX',
showCursor: false
});
}}
isActive={mode.type === 'TEXTBOX'}
/>
<IconButton
name="Zoom in"
Icon={<ZoomInIcon />}
onClick={uiStateStoreActions.incrementZoom}
disabled={zoom === MAX_ZOOM}
/>
<IconButton
name="Zoom out"
Icon={<ZoomOutIcon />}
onClick={uiStateStoreActions.decrementZoom}
disabled={zoom === MIN_ZOOM}
/>
<UiElement>
<Stack direction="row">
<IconButton
name="Select"
Icon={<NearMeIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'CURSOR',
showCursor: true,
mousedownItem: null
});
}}
isActive={mode.type === 'CURSOR' || mode.type === 'DRAG_ITEMS'}
/>
<IconButton
name="Pan"
Icon={<PanToolIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'PAN',
showCursor: false
});
}}
isActive={mode.type === 'PAN'}
/>
<IconButton
name="Add element"
Icon={<AddIcon />}
onClick={() => {
uiStateStoreActions.setItemControls({
type: 'ADD_ITEM'
});
uiStateStoreActions.setMode({
type: 'PLACE_ELEMENT',
showCursor: true,
icon: null
});
}}
isActive={mode.type === 'PLACE_ELEMENT'}
/>
<IconButton
name="Rectangle"
Icon={<CropSquareIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'RECTANGLE.DRAW',
showCursor: true,
area: null
});
}}
isActive={mode.type === 'RECTANGLE.DRAW'}
/>
<IconButton
name="Connector"
Icon={<ConnectorIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'CONNECTOR',
connector: null,
showCursor: true
});
}}
isActive={mode.type === 'CONNECTOR'}
/>
<IconButton
name="Text"
Icon={<TitleIcon />}
onClick={() => {
uiStateStoreActions.setMode({
type: 'TEXTBOX',
showCursor: false
});
}}
isActive={mode.type === 'TEXTBOX'}
/>
<IconButton
name="Zoom in"
Icon={<ZoomInIcon />}
onClick={uiStateStoreActions.incrementZoom}
disabled={zoom === MAX_ZOOM}
/>
<IconButton
name="Zoom out"
Icon={<ZoomOutIcon />}
onClick={uiStateStoreActions.decrementZoom}
disabled={zoom === MIN_ZOOM}
/>
</Stack>
</UiElement>
);
};

View File

@@ -1,22 +1,15 @@
import React from 'react';
import { Card, useTheme, SxProps } from '@mui/material';
import { Card, SxProps } from '@mui/material';
interface Props {
children: React.ReactNode;
orientation?: 'TOPLEFT' | 'TOPRIGHT';
sx?: SxProps;
}
export const UiElement = ({ children, sx, orientation = 'TOPLEFT' }: Props) => {
const theme = useTheme();
export const UiElement = ({ children, sx }: Props) => {
return (
<Card
sx={{
position: 'absolute',
top: theme.customVars.appPadding.y,
[orientation === 'TOPLEFT' ? 'left' : 'right']:
theme.customVars.appPadding.x,
borderRadius: 2,
...sx
}}

View File

@@ -1,12 +1,24 @@
import React from 'react';
import React, { useCallback } from 'react';
import { Box, useTheme } from '@mui/material';
import { UiElement } from 'components/UiElement/UiElement';
import { toPx } from 'src/utils';
import { SceneLayer } from 'src/components/SceneLayer/SceneLayer';
import { DragAndDrop } from 'src/components/DragAndDrop/DragAndDrop';
import { ItemControlsManager } from 'src/components/ItemControls/ItemControlsManager';
import { ToolMenu } from 'src/components/ToolMenu/ToolMenu';
import { useUiStateStore } from 'src/stores/uiStateStore';
import { MainMenu } from 'src/components/MainMenu/MainMenu';
import { ZoomControls } from 'src/components/ZoomControls/ZoomControls';
export const UiOverlay = () => {
const theme = useTheme();
const { appPadding } = theme.customVars;
const spacing = useCallback(
(multiplier: number) => {
return parseInt(theme.spacing(multiplier), 10);
},
[theme]
);
const disableInteractions = useUiStateStore((state) => {
return state.disableInteractions;
});
@@ -21,14 +33,57 @@ export const UiOverlay = () => {
return (
<>
<ItemControlsManager />
<ToolMenu />
<UiElement
sx={{
position: 'absolute',
top: toPx(appPadding.y * 2 + spacing(2)),
left: appPadding.x,
width: '345px',
maxHeight: `calc(100% - ${toPx(appPadding.y * 6)})`,
overflowY: 'scroll',
'&::-webkit-scrollbar': {
display: 'none'
}
}}
>
<ItemControlsManager />
</UiElement>
<Box
sx={{
position: 'absolute',
right: toPx(appPadding.x),
top: toPx(appPadding.y)
}}
>
<ToolMenu />
</Box>
{mode.type === 'PLACE_ELEMENT' && mode.icon && (
<SceneLayer>
<DragAndDrop icon={mode.icon} tile={mouse.position.tile} />
</SceneLayer>
)}
<MainMenu />
<Box
sx={{
position: 'absolute',
left: appPadding.x,
bottom: appPadding.y
}}
>
<ZoomControls />
</Box>
<Box
sx={{
position: 'absolute',
top: toPx(appPadding.y),
left: toPx(appPadding.x)
}}
>
<MainMenu />
</Box>
</>
);
};

View File

@@ -0,0 +1,6 @@
import React from 'react';
import { UiElement } from '../UiElement/UiElement';
export const ZoomControls = () => {
return <UiElement>Hello</UiElement>;
};