diff --git a/docs/pages/docs/api/initialScene.mdx b/docs/pages/docs/api/initialScene.mdx index 992e08f..43278f3 100644 --- a/docs/pages/docs/api/initialScene.mdx +++ b/docs/pages/docs/api/initialScene.mdx @@ -2,13 +2,14 @@ The `initialScene` object contains the following properties: -| Name | Type | Required | +| Name | Type | | --- | --- | :---: | -| `icons` | [`Icon[]`](#icon) | ✓ | -| `nodes` | [`Node[]`](#node) | ✓ | -| `connectors` | [`Connector[]`](#connector) | ✓ | -| `rectangles` | [`Rectangle[]`](#rectangle) | ✓ | -| `zoom` | `number` | | +| `icons` | [`Icon[]`](#icon) | +| `nodes` | [`Node[]`](#node) | +| `connectors` | [`Connector[]`](#connector) | +| `rectangles` | [`Rectangle[]`](#rectangle) | +| `textBoxes` | [`TextBox[]`](#textbox) | +| `zoom` | `number` | ## `Icon` @@ -24,6 +25,7 @@ The `initialScene` object contains the following properties: **Notes on icons:** - `collection` is an optional property that can be used to group icons together in the icon picker. All icons with the same `collection` will be grouped together under a heading. +- `isIsometric` is used to hint to Isoflow how to render an icon. if `isIsometric = false`, an isometric perpective will be forced on it (good for logos). ## `Node` @@ -46,32 +48,37 @@ The `initialScene` object contains the following properties: { id: string; color?: string; - style?: 'SOLID' | 'DOTTED' | 'DASHED'; width?: number; + style?: 'SOLID' | 'DOTTED' | 'DASHED'; anchors: ConnectorAnchor[] } ``` **Notes on connectors:** -- A connector needs a minimum of 2 anchors to determine where it starts and ends. -If you want more control over the connector's path you can specify additional anchors that the connector will pass through. -- Connector anchors can either be a reference to a `tile` coordinate on the grid, or a reference to another `node`. -If the reference is another `node`, the anchor's position is dynamic and will be tied to the node's position. +- A connector needs a minimum of 2 anchors to determine where it starts and ends. If you want more control over the connector's path you can specify additional anchors that the connector will pass through. ## `ConnectorAnchor` ```js +id?: string; { - nodeId: string + node: string } | { tile: { x: number; y: number; } +} | +{ + anchor: string; } ``` +**Notes on anchors** +- Connector anchors can reference either one of a `tile`, a `node` or another `connectorAnchor`. If the reference is to a `node` or another `anchor`, the anchor is dynamic and will be tied to the reference's position. +- When using either a `node` or an `anchor` as a reference, you must specify the `id` of the of the item being referred to. + ## `Rectangle` ```js @@ -89,14 +96,46 @@ If the reference is another `node`, the anchor's position is dynamic and will be } ``` -## `initialScene` example -Open this example in [CodeSandbox](https://codesandbox.io/p/sandbox/github/markmanx/isoflow/tree/main). - -**Note:** This example assumes the `networkingIsopack` is imported from `isoflow/dist/isopacks`. See [Loading Isopacks](/docs/isopacks). +## `TextBox` ```js { - icons: networkingIsopack, + id: string; + tile: { + x: number; + y: number; + }; + text: string; + fontSize?: number; + orientation?: 'X' | 'Y'; +} +``` + +## `initialScene` example +Open this example in [CodeSandbox](https://codesandbox.io/p/sandbox/github/markmanx/isoflow/tree/main). + +```js +{ + icons: [ + { + id: 'server', + name: 'Server', + url: 'https://isoflow-public.s3.eu-west-2.amazonaws.com/isopacks/isoflow/server.svg', + isIsometric: true + }, + { + id: 'storage', + name: 'Storage', + url: 'https://isoflow-public.s3.eu-west-2.amazonaws.com/isopacks/isoflow/storage.svg', + isIsometric: true + }, + { + id: 'laptop', + name: 'Laptop', + url: 'https://isoflow-public.s3.eu-west-2.amazonaws.com/isopacks/isoflow/laptop.svg', + isIsometric: true + } + ], nodes: [ { id: 'database', @@ -156,6 +195,16 @@ Open this example in [CodeSandbox](https://codesandbox.io/p/sandbox/github/markm y: -3 } } + ], + textBoxes: [ + { + id: 'text1', + tile: { + x: 1, + y: -4 + }, + text: 'Backend' + } ] } ``` @@ -164,7 +213,7 @@ Open this example in [CodeSandbox](https://codesandbox.io/p/sandbox/github/markm `initialScene` is validated before Isoflow renders the scene, and an error is thrown if the data is invalid. Examples of common errors are as follows: -- A `connector` references a `nodeId` that does not exist in the `nodes` array. -- A `node` references an `icon` that does not exist in the `icons` array. -- A `rectangle` has a `from` but not a `to` property. -- A `connector` has less than 2 anchors. \ No newline at end of file +- A `ConnectorAnchor` references a `Node` that does not exist. +- A `Node` references an `Icon` that does not exist. +- A `Rectangle` has a `from` but not a `to` property. +- A `Connector` has less than 2 anchors. \ No newline at end of file diff --git a/src/examples/initialScene.ts b/src/examples/initialScene.ts index 89f0b0b..cde0845 100644 --- a/src/examples/initialScene.ts +++ b/src/examples/initialScene.ts @@ -64,7 +64,6 @@ export const initialScene: InitialScene = { ] } ], - textBoxes: [], rectangles: [ { id: 'rect1', @@ -77,5 +76,15 @@ export const initialScene: InitialScene = { y: -3 } } + ], + textBoxes: [ + { + id: 'text1', + tile: { + x: 1, + y: -4 + }, + text: 'Backend' + } ] }; diff --git a/src/tests/fixtures/scene.ts b/src/tests/fixtures/scene.ts index 412b5a4..81ad9a9 100644 --- a/src/tests/fixtures/scene.ts +++ b/src/tests/fixtures/scene.ts @@ -49,7 +49,10 @@ export const scene: SceneInput = { }, { id: 'connector2', - anchors: [{ ref: { node: 'node2' } }, { ref: { node: 'node3' } }] + anchors: [ + { id: 'anchor1', ref: { node: 'node2' } }, + { ref: { node: 'node3' } } + ] } ], textBoxes: [], diff --git a/src/utils/inputs.ts b/src/utils/inputs.ts index 56761bf..324d75e 100644 --- a/src/utils/inputs.ts +++ b/src/utils/inputs.ts @@ -174,6 +174,10 @@ export const sceneInputToScene = (sceneInput: SceneInput): Scene => { return rectangleInputToRectangle(rectangleInput); }); + const textBoxes = sceneInput.textBoxes.map((textBoxInput) => { + return textBoxInputToTextBox(textBoxInput); + }); + const allAnchors = getAllAnchorsFromInput(sceneInput.connectors); const connectors = sceneInput.connectors.map((connectorInput) => { @@ -184,7 +188,8 @@ export const sceneInputToScene = (sceneInput: SceneInput): Scene => { icons, nodes, rectangles, - connectors + connectors, + textBoxes } as Scene; }; diff --git a/src/validation/tests/Scene.test.ts b/src/validation/tests/Scene.test.ts index 92220d6..704bd27 100644 --- a/src/validation/tests/Scene.test.ts +++ b/src/validation/tests/Scene.test.ts @@ -48,7 +48,7 @@ describe('scene validation works correctly', () => { } }); - test('connector with anchor that references an invalid anchor fails validation', () => { + test('connector with less than two anchors fails validation', () => { const invalidConnector = { id: 'invalidConnector', anchors: [{ ref: { anchor: 'invalidAnchor' } }] @@ -59,6 +59,28 @@ describe('scene validation works correctly', () => { const result = sceneInput.safeParse(scene); + expect(result.success).toBe(false); + if (result.success === false) { + expect(result.error.errors[0].message).toContain( + 'must have at least 2 anchors' + ); + } + }); + + test('connector with anchor that references an invalid anchor fails validation', () => { + const invalidConnector = { + id: 'invalidConnector', + anchors: [ + { ref: { anchor: 'invalidAnchor' } }, + { ref: { anchor: 'anchor1' } } + ] + }; + const scene = produce(sceneFixture, (draft) => { + draft.connectors.push(invalidConnector); + }); + + const result = sceneInput.safeParse(scene); + expect(result.success).toBe(false); if (result.success === false) { expect(result.error.errors[0].message).toContain('anchor does not exist');