mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2025-12-24 06:58:48 -05:00
refactor: moves Ui layer styling to parent component
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -76,7 +76,7 @@ export const Renderer = () => {
|
||||
<DebugUtils />
|
||||
</SceneLayer>
|
||||
)}
|
||||
{/* Interaction layer */}
|
||||
{/* Interaction layer: this is where events are detected */}
|
||||
<SceneLayer ref={containerRef} />
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
}}
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
6
src/components/ZoomControls/ZoomControls.tsx
Normal file
6
src/components/ZoomControls/ZoomControls.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
import { UiElement } from '../UiElement/UiElement';
|
||||
|
||||
export const ZoomControls = () => {
|
||||
return <UiElement>Hello</UiElement>;
|
||||
};
|
||||
Reference in New Issue
Block a user