mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2025-12-24 06:58:48 -05:00
feat: stores colors as part of model
This commit is contained in:
@@ -10,15 +10,17 @@ import {
|
||||
Connector,
|
||||
Rectangle,
|
||||
IsoflowProps,
|
||||
InitialData
|
||||
InitialData,
|
||||
EditorConfig,
|
||||
Colors,
|
||||
Icons
|
||||
} from 'src/types';
|
||||
import { setWindowCursor, generateId } from 'src/utils';
|
||||
import { modelSchema } from 'src/validation/model';
|
||||
import { modelSchema } from 'src/schemas/model';
|
||||
import { useModelStore, ModelProvider } from 'src/stores/modelStore';
|
||||
import { SceneProvider } from 'src/stores/sceneStore';
|
||||
import { GlobalStyles } from 'src/styles/GlobalStyles';
|
||||
import { Renderer } from 'src/components/Renderer/Renderer';
|
||||
import { useWindowUtils } from 'src/hooks/useWindowUtils';
|
||||
import { UiOverlay } from 'src/components/UiOverlay/UiOverlay';
|
||||
import { UiStateProvider, useUiStateStore } from 'src/stores/uiStateStore';
|
||||
import {
|
||||
@@ -174,10 +176,13 @@ const useIsoflow = () => {
|
||||
export {
|
||||
useIsoflow,
|
||||
InitialData,
|
||||
EditorConfig,
|
||||
Model,
|
||||
Icon,
|
||||
ModelItem,
|
||||
Rectangle,
|
||||
Colors,
|
||||
Icons,
|
||||
Connector,
|
||||
modelSchema,
|
||||
IsoflowProps
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
import React from 'react';
|
||||
import { Box } from '@mui/material';
|
||||
import { useScene } from 'src/hooks/useScene';
|
||||
import { ColorSwatch } from './ColorSwatch';
|
||||
|
||||
interface Props {
|
||||
colors: string[];
|
||||
onChange: (color: string) => void;
|
||||
activeColor: string;
|
||||
}
|
||||
|
||||
export const ColorSelector = ({ colors, onChange, activeColor }: Props) => {
|
||||
export const ColorSelector = ({ onChange, activeColor }: Props) => {
|
||||
const { colors } = useScene();
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{colors.map((color) => {
|
||||
return (
|
||||
<ColorSwatch
|
||||
key={color}
|
||||
hex={color}
|
||||
key={color.id}
|
||||
hex={color.value}
|
||||
onClick={() => {
|
||||
return onChange(color);
|
||||
return onChange(color.id);
|
||||
}}
|
||||
isActive={activeColor === color}
|
||||
isActive={activeColor === color.id}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Connector, connectorStyleOptions } from 'src/types';
|
||||
import {
|
||||
useTheme,
|
||||
Box,
|
||||
Slider,
|
||||
Select,
|
||||
MenuItem,
|
||||
TextField
|
||||
} from '@mui/material';
|
||||
import { Box, Slider, Select, MenuItem, TextField } from '@mui/material';
|
||||
import { useConnector } from 'src/hooks/useConnector';
|
||||
import { ColorSelector } from 'src/components/ColorSelector/ColorSelector';
|
||||
import { useUiStateStore } from 'src/stores/uiStateStore';
|
||||
@@ -21,7 +14,6 @@ interface Props {
|
||||
}
|
||||
|
||||
export const ConnectorControls = ({ id }: Props) => {
|
||||
const theme = useTheme();
|
||||
const uiStateActions = useUiStateStore((state) => {
|
||||
return state.actions;
|
||||
});
|
||||
@@ -43,7 +35,6 @@ export const ConnectorControls = ({ id }: Props) => {
|
||||
</Section>
|
||||
<Section>
|
||||
<ColorSelector
|
||||
colors={Object.values(theme.customVars.customPalette)}
|
||||
onChange={(color) => {
|
||||
return updateConnector(connector.id, { color });
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useTheme, Box } from '@mui/material';
|
||||
import { Box } from '@mui/material';
|
||||
import { useRectangle } from 'src/hooks/useRectangle';
|
||||
import { ColorSelector } from 'src/components/ColorSelector/ColorSelector';
|
||||
import { useUiStateStore } from 'src/stores/uiStateStore';
|
||||
@@ -13,7 +13,6 @@ interface Props {
|
||||
}
|
||||
|
||||
export const RectangleControls = ({ id }: Props) => {
|
||||
const theme = useTheme();
|
||||
const uiStateActions = useUiStateStore((state) => {
|
||||
return state.actions;
|
||||
});
|
||||
@@ -24,7 +23,6 @@ export const RectangleControls = ({ id }: Props) => {
|
||||
<ControlsContainer>
|
||||
<Section>
|
||||
<ColorSelector
|
||||
colors={Object.values(theme.customVars.customPalette)}
|
||||
onChange={(color) => {
|
||||
updateRectangle(rectangle.id, { color });
|
||||
}}
|
||||
|
||||
@@ -78,6 +78,7 @@ export const MainMenu = () => {
|
||||
const onExportAsJSON = useCallback(async () => {
|
||||
const payload: Model = {
|
||||
icons: model.icons,
|
||||
colors: model.colors,
|
||||
items: model.items,
|
||||
title: model.title,
|
||||
version: model.version,
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Svg } from 'src/components/Svg/Svg';
|
||||
import { useIsoProjection } from 'src/hooks/useIsoProjection';
|
||||
import { useConnector } from 'src/hooks/useConnector';
|
||||
import { useScene } from 'src/hooks/useScene';
|
||||
import { useColor } from 'src/hooks/useColor';
|
||||
|
||||
interface Props {
|
||||
connector: ReturnType<typeof useScene>['connectors'][0];
|
||||
@@ -14,6 +15,7 @@ interface Props {
|
||||
|
||||
export const Connector = ({ connector: _connector }: Props) => {
|
||||
const theme = useTheme();
|
||||
const color = useColor(_connector.color);
|
||||
const { currentView } = useScene();
|
||||
const connector = useConnector(_connector.id);
|
||||
const { css, pxSize } = useIsoProjection({
|
||||
@@ -89,7 +91,7 @@ export const Connector = ({ connector: _connector }: Props) => {
|
||||
/>
|
||||
<polyline
|
||||
points={pathString}
|
||||
stroke={getColorVariant(connector.color, 'dark', { grade: 1 })}
|
||||
stroke={getColorVariant(color.value, 'dark', { grade: 1 })}
|
||||
strokeWidth={connectorWidthPx}
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Rectangle as RectangleI } from 'src/types';
|
||||
import { useScene } from 'src/hooks/useScene';
|
||||
import { IsoTileArea } from 'src/components/IsoTileArea/IsoTileArea';
|
||||
import { getColorVariant } from 'src/utils';
|
||||
import { DEFAULT_COLOR } from 'src/config';
|
||||
import { useColor } from 'src/hooks/useColor';
|
||||
|
||||
type Props = RectangleI;
|
||||
type Props = ReturnType<typeof useScene>['rectangles'][0];
|
||||
|
||||
export const Rectangle = ({ from, to, color: colorId }: Props) => {
|
||||
const color = useColor(colorId);
|
||||
|
||||
export const Rectangle = ({ from, to, color = DEFAULT_COLOR }: Props) => {
|
||||
return (
|
||||
<IsoTileArea
|
||||
from={from}
|
||||
to={to}
|
||||
fill={color}
|
||||
fill={color.value}
|
||||
cornerRadius={22}
|
||||
stroke={{
|
||||
color: getColorVariant(color, 'dark', { grade: 2 }),
|
||||
color: getColorVariant(color.value, 'dark', { grade: 2 }),
|
||||
width: 1
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { Rectangle as RectangleI } from 'src/types';
|
||||
import { useScene } from 'src/hooks/useScene';
|
||||
import { Rectangle } from './Rectangle';
|
||||
|
||||
interface Props {
|
||||
rectangles: RectangleI[];
|
||||
rectangles: ReturnType<typeof useScene>['rectangles'];
|
||||
}
|
||||
|
||||
export const Rectangles = ({ rectangles }: Props) => {
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
TextBox,
|
||||
ViewItem,
|
||||
View,
|
||||
Rectangle
|
||||
Rectangle,
|
||||
Colors
|
||||
} from 'src/types';
|
||||
import { customVars } from './styles/theme';
|
||||
import { CoordsUtils } from './utils';
|
||||
@@ -23,7 +24,11 @@ export const PROJECTED_TILE_SIZE = {
|
||||
height: UNPROJECTED_TILE_SIZE * TILE_PROJECTION_MULTIPLIERS.height
|
||||
};
|
||||
|
||||
export const DEFAULT_COLOR = customVars.customPalette.blue;
|
||||
export const DEFAULT_COLOR: Colors[0] = {
|
||||
id: '__DEFAULT__',
|
||||
value: customVars.customPalette.defaultColor
|
||||
};
|
||||
|
||||
export const DEFAULT_FONT_FAMILY = 'Roboto, Arial, sans-serif';
|
||||
|
||||
export const VIEW_DEFAULTS: Required<Omit<View, 'id' | 'description'>> = {
|
||||
@@ -41,7 +46,7 @@ export const VIEW_ITEM_DEFAULTS: Required<Omit<ViewItem, 'id' | 'tile'>> = {
|
||||
export const CONNECTOR_DEFAULTS: Required<Omit<Connector, 'id'>> = {
|
||||
width: 10,
|
||||
description: '',
|
||||
color: DEFAULT_COLOR,
|
||||
color: DEFAULT_COLOR.id,
|
||||
anchors: [],
|
||||
style: 'SOLID'
|
||||
};
|
||||
@@ -62,7 +67,7 @@ export const TEXTBOX_FONT_WEIGHT = 'bold';
|
||||
export const RECTANGLE_DEFAULTS: Required<
|
||||
Omit<Rectangle, 'id' | 'from' | 'to'>
|
||||
> = {
|
||||
color: DEFAULT_COLOR
|
||||
color: DEFAULT_COLOR.id
|
||||
};
|
||||
|
||||
export const ZOOM_INCREMENT = 0.2;
|
||||
@@ -74,6 +79,7 @@ export const INITIAL_DATA: Model = {
|
||||
title: 'Untitled',
|
||||
version: '',
|
||||
icons: [],
|
||||
colors: [],
|
||||
items: [],
|
||||
views: []
|
||||
};
|
||||
@@ -102,3 +108,5 @@ export const DEFAULT_ICON: Icon = {
|
||||
};
|
||||
|
||||
export const DEFAULT_LABEL_HEIGHT = 20;
|
||||
|
||||
export const EDITOR_CONFIG = {};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { InitialData } from 'src/Isoflow';
|
||||
import { InitialData, Colors, Icons } from 'src/Isoflow';
|
||||
import { flattenCollections } from '@isoflow/isopacks/dist/utils';
|
||||
import isoflowIsopack from '@isoflow/isopacks/dist/isoflow';
|
||||
import awsIsopack from '@isoflow/isopacks/dist/aws';
|
||||
@@ -15,10 +15,38 @@ const isopacks = flattenCollections([
|
||||
kubernetesIsopack
|
||||
]);
|
||||
|
||||
// The data used in this visualisation example has been derived from the following blog post
|
||||
// https://www.altexsoft.com/blog/travel/airport-technology-management-operations-software-solutions-and-vendors/
|
||||
export const colors: Colors = [
|
||||
{
|
||||
id: 'color2',
|
||||
value: '#bbadfb'
|
||||
},
|
||||
{
|
||||
id: 'color3',
|
||||
value: '#f4eb8e'
|
||||
},
|
||||
{
|
||||
id: 'color4',
|
||||
value: '#f0aca9'
|
||||
},
|
||||
{
|
||||
id: 'color5',
|
||||
value: '#fad6ac'
|
||||
},
|
||||
{
|
||||
id: 'color6',
|
||||
value: '#a8dc9d'
|
||||
},
|
||||
{
|
||||
id: 'color7',
|
||||
value: '#b3e5e3'
|
||||
}
|
||||
];
|
||||
|
||||
export const icons: Icons = isopacks;
|
||||
|
||||
export const initialData: InitialData = {
|
||||
icons: isopacks,
|
||||
icons,
|
||||
colors,
|
||||
items: [
|
||||
{
|
||||
id: 'item1',
|
||||
@@ -40,6 +68,7 @@ export const initialData: InitialData = {
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// export const initialData: InitialData = {
|
||||
// title: 'Airport Management Software',
|
||||
// icons: isopacks,
|
||||
|
||||
12
src/fixtures/colors.ts
Normal file
12
src/fixtures/colors.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Colors } from 'src/types';
|
||||
|
||||
export const colors: Colors = [
|
||||
{
|
||||
id: 'color1',
|
||||
value: '#000000'
|
||||
},
|
||||
{
|
||||
id: 'color2',
|
||||
value: '#ffffff'
|
||||
}
|
||||
];
|
||||
@@ -2,11 +2,13 @@ import { Model } from 'src/types';
|
||||
import { icons } from './icons';
|
||||
import { modelItems } from './modelItems';
|
||||
import { views } from './views';
|
||||
import { colors } from './colors';
|
||||
|
||||
export const model: Model = {
|
||||
version: '1.0.0',
|
||||
title: 'TestModel',
|
||||
description: 'TestModelDescription',
|
||||
version: '1.0.0',
|
||||
colors,
|
||||
icons,
|
||||
items: modelItems,
|
||||
views
|
||||
|
||||
@@ -29,7 +29,11 @@ export const views: Model['views'] = [
|
||||
}
|
||||
],
|
||||
rectangles: [
|
||||
{ id: 'rectangle1', from: { x: 0, y: 0 }, to: { x: 2, y: 2 } }
|
||||
{
|
||||
id: 'rectangle1',
|
||||
from: { x: 0, y: 0 },
|
||||
to: { x: 2, y: 2 }
|
||||
}
|
||||
],
|
||||
connectors: [
|
||||
{
|
||||
|
||||
13
src/hooks/useColor.ts
Normal file
13
src/hooks/useColor.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { useMemo } from 'react';
|
||||
import { getItemByIdOrThrow } from 'src/utils';
|
||||
import { useScene } from 'src/hooks/useScene';
|
||||
|
||||
export const useColor = (colorId: string) => {
|
||||
const { colors } = useScene();
|
||||
|
||||
const color = useMemo(() => {
|
||||
return getItemByIdOrThrow(colors, colorId).value;
|
||||
}, [colorId, colors]);
|
||||
|
||||
return color;
|
||||
};
|
||||
@@ -16,6 +16,7 @@ import type { State } from 'src/stores/reducers/types';
|
||||
import { getItemByIdOrThrow } from 'src/utils';
|
||||
import {
|
||||
CONNECTOR_DEFAULTS,
|
||||
DEFAULT_COLOR,
|
||||
RECTANGLE_DEFAULTS,
|
||||
TEXTBOX_DEFAULTS
|
||||
} from 'src/config';
|
||||
@@ -41,6 +42,10 @@ export const useScene = () => {
|
||||
return currentView.items ?? [];
|
||||
}, [currentView.items]);
|
||||
|
||||
const colors = useMemo(() => {
|
||||
return [DEFAULT_COLOR, ...model.colors];
|
||||
}, [model.colors]);
|
||||
|
||||
const connectors = useMemo(() => {
|
||||
return (currentView.connectors ?? []).map((connector) => {
|
||||
const sceneConnector = scene.connectors[connector.id];
|
||||
@@ -262,6 +267,7 @@ export const useScene = () => {
|
||||
return {
|
||||
items,
|
||||
connectors,
|
||||
colors,
|
||||
rectangles,
|
||||
textBoxes,
|
||||
currentView,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ModeActions } from 'src/types';
|
||||
import { produce } from 'immer';
|
||||
import { generateId, hasMovedTile, setWindowCursor } from 'src/utils';
|
||||
import { DEFAULT_COLOR } from 'src/config';
|
||||
import { generateId, hasMovedTile, setWindowCursor } from 'src/utils';
|
||||
|
||||
export const DrawRectangle: ModeActions = {
|
||||
entry: () => {
|
||||
@@ -31,7 +31,7 @@ export const DrawRectangle: ModeActions = {
|
||||
|
||||
scene.createRectangle({
|
||||
id: newRectangleId,
|
||||
color: DEFAULT_COLOR,
|
||||
color: DEFAULT_COLOR.id,
|
||||
from: uiState.mouse.position.tile,
|
||||
to: uiState.mouse.position.tile
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file will be exported as it's own bundle (separate to the main bundle). This is because the main
|
||||
// bundle requires `window` to be present and so can't be imported into a Node environment.
|
||||
export { INITIAL_DATA } from 'src/config';
|
||||
export { modelSchema } from 'src/validation/model';
|
||||
export { modelSchema } from 'src/schemas/model';
|
||||
export const version = PACKAGE_VERSION;
|
||||
|
||||
@@ -13,6 +13,7 @@ describe('Model validation works correctly', () => {
|
||||
test('Connector with anchor that references an invalid item fails validation', () => {
|
||||
const invalidConnector: Connector = {
|
||||
id: 'invalidConnector',
|
||||
color: 'color1',
|
||||
anchors: [
|
||||
{ id: 'testAnch', ref: { item: 'node1' } },
|
||||
{ id: 'testAnch2', ref: { item: 'invalidItem' } }
|
||||
@@ -31,6 +32,7 @@ describe('Model validation works correctly', () => {
|
||||
test('Connector with less than two anchors fails validation', () => {
|
||||
const invalidConnector: Connector = {
|
||||
id: 'invalidConnector',
|
||||
color: 'color1',
|
||||
anchors: []
|
||||
};
|
||||
|
||||
@@ -46,6 +48,7 @@ describe('Model validation works correctly', () => {
|
||||
test('Connector with anchor that references an invalid anchor fails validation', () => {
|
||||
const invalidConnector: Connector = {
|
||||
id: 'invalidConnector',
|
||||
color: 'color1',
|
||||
anchors: [
|
||||
{ id: 'testAnch1', ref: { anchor: 'invalidAnchor' } },
|
||||
{ id: 'testAnch2', ref: { anchor: 'anchor1' } }
|
||||
9
src/schemas/colors.ts
Normal file
9
src/schemas/colors.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { z } from 'zod';
|
||||
import { id } from './common';
|
||||
|
||||
export const colorSchema = z.object({
|
||||
id,
|
||||
value: z.string().max(7)
|
||||
});
|
||||
|
||||
export const colorsSchema = z.array(colorSchema);
|
||||
@@ -1,5 +1,5 @@
|
||||
import { z } from 'zod';
|
||||
import { coords, id, constrainedStrings, color } from '../common';
|
||||
import { coords, id, constrainedStrings } from './common';
|
||||
|
||||
export const connectorStyleOptions = ['SOLID', 'DOTTED', 'DASHED'] as const;
|
||||
|
||||
@@ -17,7 +17,7 @@ export const anchorSchema = z.object({
|
||||
export const connectorSchema = z.object({
|
||||
id,
|
||||
description: constrainedStrings.description.optional(),
|
||||
color: color.optional(),
|
||||
color: id.optional(),
|
||||
width: z.number().optional(),
|
||||
style: z.enum(connectorStyleOptions).optional(),
|
||||
anchors: z.array(anchorSchema)
|
||||
8
src/schemas/index.ts
Normal file
8
src/schemas/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from './model';
|
||||
export * from './colors';
|
||||
export * from './icons';
|
||||
export * from './modelItems';
|
||||
export * from './views';
|
||||
export * from './connector';
|
||||
export * from './rectangle';
|
||||
export * from './textBox'
|
||||
@@ -3,20 +3,22 @@ import { INITIAL_DATA } from '../config';
|
||||
import { constrainedStrings } from './common';
|
||||
import { modelItemsSchema } from './modelItems';
|
||||
import { viewsSchema } from './views';
|
||||
import { iconsSchema } from './icons';
|
||||
import { validateModel } from './utils';
|
||||
import { iconsSchema } from './icons';
|
||||
import { colorsSchema } from './colors';
|
||||
|
||||
export const modelSchema = z
|
||||
.object({
|
||||
version: z.string().max(10),
|
||||
title: constrainedStrings.name,
|
||||
description: constrainedStrings.description.optional(),
|
||||
icons: iconsSchema,
|
||||
items: modelItemsSchema,
|
||||
views: viewsSchema
|
||||
views: viewsSchema,
|
||||
icons: iconsSchema,
|
||||
colors: colorsSchema
|
||||
})
|
||||
.superRefine((_Model, ctx) => {
|
||||
const issues = validateModel({ ...INITIAL_DATA, ..._Model });
|
||||
.superRefine((model, ctx) => {
|
||||
const issues = validateModel({ ...INITIAL_DATA, ...model });
|
||||
|
||||
issues.forEach((issue) => {
|
||||
ctx.addIssue({
|
||||
@@ -1,9 +1,9 @@
|
||||
import { z } from 'zod';
|
||||
import { id, color, coords } from '../common';
|
||||
import { id, coords } from './common';
|
||||
|
||||
export const rectangleSchema = z.object({
|
||||
id,
|
||||
color: color.optional(),
|
||||
color: id.optional(),
|
||||
from: coords,
|
||||
to: coords
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { z } from 'zod';
|
||||
import { ProjectionOrientationEnum } from 'src/types/common';
|
||||
import { id, coords, constrainedStrings } from '../common';
|
||||
import { id, coords, constrainedStrings } from './common';
|
||||
|
||||
export const textBoxSchema = z.object({
|
||||
id,
|
||||
@@ -1,8 +1,8 @@
|
||||
import { z } from 'zod';
|
||||
import { id, constrainedStrings, coords } from './common';
|
||||
import { rectangleSchema } from './annotations/rectangle';
|
||||
import { connectorSchema } from './annotations/connector';
|
||||
import { textBoxSchema } from './annotations/textBox';
|
||||
import { rectangleSchema } from './rectangle';
|
||||
import { connectorSchema } from './connector';
|
||||
import { textBoxSchema } from './textBox';
|
||||
|
||||
export const viewItemSchema = z.object({
|
||||
id,
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Connector } from 'src/types';
|
||||
import { produce } from 'immer';
|
||||
import { getItemByIdOrThrow, getConnectorPath, getAllAnchors } from 'src/utils';
|
||||
import { validateConnector } from 'src/validation/utils';
|
||||
import { validateConnector } from 'src/schemas/utils';
|
||||
import { State } from './types';
|
||||
|
||||
export const deleteConnector = (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { produce } from 'immer';
|
||||
import { ViewItem } from 'src/types';
|
||||
import { getItemByIdOrThrow, getConnectorsByViewItem } from 'src/utils';
|
||||
import { validateView } from 'src/validation/utils';
|
||||
import { validateView } from 'src/schemas/utils';
|
||||
import { State } from './types';
|
||||
import { updateConnector, syncConnector } from './connector';
|
||||
|
||||
|
||||
@@ -33,13 +33,7 @@ export const customVars: CustomThemeVars = {
|
||||
},
|
||||
customPalette: {
|
||||
diagramBg: '#f6faff',
|
||||
blue: '#a0b9f8',
|
||||
purple: '#bbadfb',
|
||||
yellow: '#f4eb8e',
|
||||
red: '#f0aca9',
|
||||
orange: '#fad6ac',
|
||||
green: '#a8dc9d',
|
||||
torquise: '#b3e5e3'
|
||||
defaultColor: '#a5b8f3'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@ export * from './model';
|
||||
export * from './scene';
|
||||
export * from './ui';
|
||||
export * from './interactions';
|
||||
export * from './isoflowProps';
|
||||
|
||||
26
src/types/isoflowProps.ts
Normal file
26
src/types/isoflowProps.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Coords } from 'src/types';
|
||||
import { StoreApi } from 'zustand';
|
||||
import type { EditorModeEnum, MainMenuOptions } from './common';
|
||||
import type { Model } from './model';
|
||||
|
||||
export type InitialData = Partial<Model> & {
|
||||
zoom?: number;
|
||||
scroll?: Coords;
|
||||
};
|
||||
|
||||
export interface IsoflowProps {
|
||||
initialData?: InitialData;
|
||||
mainMenuOptions?: MainMenuOptions;
|
||||
onModelUpdated?: (Model: Model) => void;
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
enableDebugTools?: boolean;
|
||||
editorMode?: keyof typeof EditorModeEnum;
|
||||
}
|
||||
|
||||
export type ModelStore = Model & {
|
||||
actions: {
|
||||
get: StoreApi<ModelStore>['getState'];
|
||||
set: StoreApi<ModelStore>['setState'];
|
||||
};
|
||||
};
|
||||
@@ -1,26 +1,31 @@
|
||||
import z from 'zod';
|
||||
import { iconSchema } from 'src/validation/icons';
|
||||
import { modelSchema } from 'src/validation/model';
|
||||
import { modelItemSchema } from 'src/validation/modelItems';
|
||||
import { viewSchema, viewItemSchema } from 'src/validation/views';
|
||||
import {
|
||||
iconSchema,
|
||||
modelSchema,
|
||||
modelItemSchema,
|
||||
viewSchema,
|
||||
viewItemSchema,
|
||||
connectorSchema,
|
||||
iconsSchema,
|
||||
colorsSchema,
|
||||
anchorSchema,
|
||||
textBoxSchema,
|
||||
rectangleSchema,
|
||||
connectorStyleOptions
|
||||
} from 'src/validation/annotations/connector';
|
||||
import { textBoxSchema } from 'src/validation/annotations/textBox';
|
||||
import { rectangleSchema } from 'src/validation/annotations/rectangle';
|
||||
import { Coords } from 'src/types';
|
||||
import { StoreApi } from 'zustand';
|
||||
import type { EditorModeEnum, MainMenuOptions } from './common';
|
||||
} from 'src/schemas';
|
||||
|
||||
export { connectorStyleOptions } from 'src/validation/annotations/connector';
|
||||
export interface EditorConfig {
|
||||
icons: Icons;
|
||||
colors: Colors;
|
||||
}
|
||||
|
||||
export { connectorStyleOptions } from 'src/schemas';
|
||||
export type Model = z.infer<typeof modelSchema>;
|
||||
export type ModelItems = Model['items'];
|
||||
export type Views = Model['views'];
|
||||
export type Icons = Model['icons'];
|
||||
export type Icon = z.infer<typeof iconSchema>;
|
||||
export type Icons = z.infer<typeof iconsSchema>;
|
||||
export type Colors = z.infer<typeof colorsSchema>;
|
||||
export type ModelItem = z.infer<typeof modelItemSchema>;
|
||||
export type View = z.infer<typeof viewSchema>;
|
||||
export type ViewItem = z.infer<typeof viewItemSchema>;
|
||||
@@ -29,25 +34,3 @@ export type ConnectorAnchor = z.infer<typeof anchorSchema>;
|
||||
export type Connector = z.infer<typeof connectorSchema>;
|
||||
export type TextBox = z.infer<typeof textBoxSchema>;
|
||||
export type Rectangle = z.infer<typeof rectangleSchema>;
|
||||
|
||||
export type InitialData = Partial<Model> & {
|
||||
zoom?: number;
|
||||
scroll?: Coords;
|
||||
};
|
||||
|
||||
export interface IsoflowProps {
|
||||
initialData?: InitialData;
|
||||
mainMenuOptions?: MainMenuOptions;
|
||||
onModelUpdated?: (Model: Model) => void;
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
enableDebugTools?: boolean;
|
||||
editorMode?: keyof typeof EditorModeEnum;
|
||||
}
|
||||
|
||||
export type ModelStore = Model & {
|
||||
actions: {
|
||||
get: StoreApi<ModelStore>['getState'];
|
||||
set: StoreApi<ModelStore>['setState'];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { produce } from 'immer';
|
||||
import { Model } from 'src/types';
|
||||
import { validateModel } from 'src/validation/utils';
|
||||
import { validateModel } from 'src/schemas/utils';
|
||||
import { getItemByIdOrThrow } from './common';
|
||||
|
||||
export const fixModel = (model: Model): Model => {
|
||||
|
||||
Reference in New Issue
Block a user