mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2025-12-27 00:19:14 -05:00
feat: styling updates
This commit is contained in:
@@ -40,7 +40,7 @@ export const ConnectorControls = ({ id }: Props) => {
|
||||
<ControlsContainer>
|
||||
<Section>
|
||||
<ColorSelector
|
||||
colors={Object.values(theme.customVars.diagramPalette)}
|
||||
colors={Object.values(theme.customVars.customPalette)}
|
||||
onChange={(color) => {
|
||||
return onConnectorUpdated({ color });
|
||||
}}
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { Tabs, Tab, Box } from '@mui/material';
|
||||
import React, { useState, useCallback, useMemo } from 'react';
|
||||
import { Box, Stack, Button } from '@mui/material';
|
||||
import {
|
||||
ChevronRight as ChevronRightIcon,
|
||||
ChevronLeft as ChevronLeftIcon
|
||||
} from '@mui/icons-material';
|
||||
import { Node } from 'src/types';
|
||||
import { useSceneStore } from 'src/stores/sceneStore';
|
||||
import { useNode } from 'src/hooks/useNode';
|
||||
import { useUiStateStore } from 'src/stores/uiStateStore';
|
||||
import { useIconCategories } from 'src/hooks/useIconCategories';
|
||||
import { getItemById } from 'src/utils';
|
||||
import { ControlsContainer } from '../components/ControlsContainer';
|
||||
import { Icons } from '../IconSelectionControls/Icons';
|
||||
import { NodeSettings } from './NodeSettings/NodeSettings';
|
||||
import { Section } from '../components/Section';
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
}
|
||||
|
||||
const ModeEnum = {
|
||||
Settings: 'Settings',
|
||||
ChangeIcon: 'ChangeIcon'
|
||||
} as const;
|
||||
|
||||
export const NodeControls = ({ id }: Props) => {
|
||||
const [tab, setTab] = useState(0);
|
||||
const [mode, setMode] = useState<keyof typeof ModeEnum>('Settings');
|
||||
const { iconCategories } = useIconCategories();
|
||||
const icons = useSceneStore((state) => {
|
||||
return state.icons;
|
||||
});
|
||||
const sceneActions = useSceneStore((state) => {
|
||||
return state.actions;
|
||||
});
|
||||
@@ -24,9 +38,11 @@ export const NodeControls = ({ id }: Props) => {
|
||||
});
|
||||
const node = useNode(id);
|
||||
|
||||
const onTabChanged = (event: React.SyntheticEvent, newValue: number) => {
|
||||
setTab(newValue);
|
||||
};
|
||||
const iconUrl = useMemo(() => {
|
||||
const { item: icon } = getItemById(icons, node.icon);
|
||||
|
||||
return icon.url;
|
||||
}, [node.icon, icons]);
|
||||
|
||||
const onNodeUpdated = useCallback(
|
||||
(updates: Partial<Node>) => {
|
||||
@@ -40,27 +56,61 @@ export const NodeControls = ({ id }: Props) => {
|
||||
sceneActions.deleteNode(id);
|
||||
}, [sceneActions, id, uiStateActions]);
|
||||
|
||||
const onSwitchMode = useCallback((newMode: keyof typeof ModeEnum) => {
|
||||
setMode(newMode);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ControlsContainer
|
||||
header={
|
||||
<Box>
|
||||
<Tabs sx={{ px: 2 }} value={tab} onChange={onTabChanged}>
|
||||
<Tab label="Settings" />
|
||||
<Tab label="Change icon" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
{tab === 0 && (
|
||||
<ControlsContainer>
|
||||
<Box
|
||||
sx={{
|
||||
bgcolor: (theme) => {
|
||||
return theme.customVars.customPalette.diagramBg;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Section sx={{ py: 2 }}>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={2}
|
||||
alignItems="flex-end"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Box component="img" src={iconUrl} sx={{ width: 70, height: 70 }} />
|
||||
{mode === 'Settings' && (
|
||||
<Button
|
||||
endIcon={<ChevronRightIcon />}
|
||||
onClick={() => {
|
||||
onSwitchMode('ChangeIcon');
|
||||
}}
|
||||
variant="text"
|
||||
>
|
||||
Update icon
|
||||
</Button>
|
||||
)}
|
||||
{mode === 'ChangeIcon' && (
|
||||
<Button
|
||||
startIcon={<ChevronLeftIcon />}
|
||||
onClick={() => {
|
||||
onSwitchMode('Settings');
|
||||
}}
|
||||
variant="text"
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
</Section>
|
||||
</Box>
|
||||
{mode === ModeEnum.Settings && (
|
||||
<NodeSettings
|
||||
key={node.id}
|
||||
label={node.label}
|
||||
labelHeight={node.labelHeight}
|
||||
node={node}
|
||||
onUpdate={onNodeUpdated}
|
||||
onDelete={onNodeDeleted}
|
||||
/>
|
||||
)}
|
||||
{tab === 1 && (
|
||||
{mode === ModeEnum.ChangeIcon && (
|
||||
<Icons
|
||||
key={node.id}
|
||||
iconCategories={iconCategories}
|
||||
|
||||
@@ -6,36 +6,30 @@ import { DeleteButton } from '../../components/DeleteButton';
|
||||
import { Section } from '../../components/Section';
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
labelHeight: number;
|
||||
node: Node;
|
||||
onUpdate: (updates: Partial<Node>) => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const NodeSettings = ({
|
||||
label,
|
||||
labelHeight,
|
||||
onUpdate,
|
||||
onDelete
|
||||
}: Props) => {
|
||||
export const NodeSettings = ({ node, onUpdate, onDelete }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<Section title="Label">
|
||||
<MarkdownEditor
|
||||
value={label}
|
||||
value={node.label}
|
||||
onChange={(text) => {
|
||||
if (label !== text) onUpdate({ label: text });
|
||||
if (node.label !== text) onUpdate({ label: text });
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
{label && (
|
||||
{node.label && (
|
||||
<Section title="Label height">
|
||||
<Slider
|
||||
marks
|
||||
step={20}
|
||||
min={60}
|
||||
max={280}
|
||||
value={labelHeight}
|
||||
value={node.labelHeight}
|
||||
onChange={(e, newHeight) => {
|
||||
onUpdate({ labelHeight: newHeight as number });
|
||||
}}
|
||||
|
||||
@@ -40,7 +40,7 @@ export const RectangleControls = ({ id }: Props) => {
|
||||
<ControlsContainer>
|
||||
<Section>
|
||||
<ColorSelector
|
||||
colors={Object.values(theme.customVars.diagramPalette)}
|
||||
colors={Object.values(theme.customVars.customPalette)}
|
||||
onChange={(color) => {
|
||||
return onRectangleUpdated({ color });
|
||||
}}
|
||||
|
||||
@@ -22,7 +22,6 @@ export const Section = ({ children, sx, title }: Props) => {
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
textTransform="uppercase"
|
||||
fontWeight={600}
|
||||
pb={1}
|
||||
>
|
||||
{title}
|
||||
|
||||
@@ -38,10 +38,11 @@ export const MarkdownEditor = ({
|
||||
},
|
||||
'.ql-toolbar.ql-snow + .ql-container.ql-snow': {
|
||||
border: '1px solid',
|
||||
borderColor: 'grey.800',
|
||||
borderColor: 'grey.300',
|
||||
borderTop: 'auto',
|
||||
borderRadius: 1.5,
|
||||
height
|
||||
height,
|
||||
color: 'text.secondary'
|
||||
},
|
||||
'.ql-container.ql-snow': {
|
||||
...(readOnly ? { border: 'none' } : {}),
|
||||
|
||||
@@ -51,7 +51,9 @@ export const Renderer = () => {
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
bgcolor: '#f6faff'
|
||||
bgcolor: (theme) => {
|
||||
return theme.customVars.customPalette.diagramBg;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SceneLayer>
|
||||
|
||||
@@ -7,7 +7,7 @@ export const TILE_PROJECTION_MULTIPLIERS: Size = {
|
||||
width: 1.415,
|
||||
height: 0.819
|
||||
};
|
||||
export const DEFAULT_COLOR = customVars.diagramPalette.blue;
|
||||
export const DEFAULT_COLOR = customVars.customPalette.blue;
|
||||
export const DEFAULT_FONT_FAMILY = 'Roboto, Arial, sans-serif';
|
||||
export const NODE_DEFAULTS = {
|
||||
label: '',
|
||||
|
||||
@@ -8,7 +8,7 @@ interface CustomThemeVars {
|
||||
toolMenu: {
|
||||
height: number;
|
||||
};
|
||||
diagramPalette: {
|
||||
customPalette: {
|
||||
[key in string]: string;
|
||||
};
|
||||
}
|
||||
@@ -31,7 +31,8 @@ export const customVars: CustomThemeVars = {
|
||||
toolMenu: {
|
||||
height: 40
|
||||
},
|
||||
diagramPalette: {
|
||||
customPalette: {
|
||||
diagramBg: '#f6faff',
|
||||
blue: '#a0b9f8',
|
||||
purple: '#bbadfb',
|
||||
yellow: '#f4eb8e',
|
||||
|
||||
Reference in New Issue
Block a user