mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2025-12-25 15:39:35 -05:00
feat: adds documentation
This commit is contained in:
80
README.md
80
README.md
@@ -7,7 +7,7 @@
|
||||
</h4>
|
||||
|
||||
<div align="center">
|
||||
<h1>An open-source network diagram editor for React.</h2>
|
||||
<h1>An open-source React component for drawing network diagrams.</h2>
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
@@ -20,46 +20,43 @@
|
||||
## Key Features
|
||||
|
||||
- **Annotation tools:** Annotate your architecture with isometric icons, labels, regions and connectors.
|
||||
- **Customizable:** Use your own isometric icon packs, or the standard free set of networking icons (also under MIT).
|
||||
- **Customizable:** Use the standard free set of networking icons (also included under the MIT licence), or create your own.
|
||||
- **Export options:** Export diagrams as images, JSON or YAML.
|
||||
|
||||
## Roadmap
|
||||
|
||||
Beta release progress: ███████░░
|
||||
Beta release progress: ████████░
|
||||
|
||||
- [x] Basic view controls (pan & zoom)
|
||||
- [x] Create / delete nodes
|
||||
- [x] Create / delete rectangle areas
|
||||
- [x] Create / delete connectors
|
||||
- [x] Create / delete rectangle areas
|
||||
- [x] onSceneUpdate callback
|
||||
- [x] Drag items
|
||||
- [x] Iconpacks
|
||||
- [x] Documentation
|
||||
- [ ] Export options
|
||||
|
||||
|
||||
## Quick start
|
||||
|
||||
Install the [Isoflow npm package](https://www.npmjs.com/package/isoflow):
|
||||
```
|
||||
Install the Isoflow [npm package](https://www.npmjs.com/package/isoflow):
|
||||
```bash
|
||||
npm install isoflow
|
||||
```
|
||||
|
||||
Render a diagram:
|
||||
Basic usage is as follows:
|
||||
|
||||
```
|
||||
```jsx
|
||||
import Isoflow from 'isoflow';
|
||||
import { networkingIsopack } from 'isoflow/dist/iconpacks';
|
||||
|
||||
const initialData = {
|
||||
icons: [
|
||||
{
|
||||
id: "block",
|
||||
name: "Block",
|
||||
url: "https://isoflow.io/static/assets/icons/networking/primitive.svg"
|
||||
},
|
||||
],
|
||||
icons: networkingIsopack,
|
||||
nodes: [
|
||||
{
|
||||
id: "node1",
|
||||
icon: "block",
|
||||
iconId: "server",
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -68,56 +65,29 @@ const initialData = {
|
||||
],
|
||||
connectors: [],
|
||||
rectangles: []
|
||||
}
|
||||
};
|
||||
|
||||
const App = () => (
|
||||
<Isoflow
|
||||
height={500}
|
||||
initialData={initialData}
|
||||
>
|
||||
)
|
||||
<Isoflow initialData={initialData}>
|
||||
);
|
||||
```
|
||||
|
||||
If using Next.js, make sure you only import Isoflow in the browser:
|
||||
**Note:** Isoflow cannot be server-side rendered. If using Next.js, make sure you only import Isoflow in the browser:
|
||||
|
||||
```
|
||||
```jsx
|
||||
const Isoflow = dynamic(() => import("isoflow"), {
|
||||
ssr: false,
|
||||
});
|
||||
```
|
||||
|
||||
## Codesandbox
|
||||
## Developer documentation
|
||||
For more detailed API documentation, examples and more, see the [developer documentation](https://v2.isoflow.io/docs).
|
||||
|
||||
You can preview the latest version of Isoflow on Codesandbox [here](https://codesandbox.io/p/sandbox/github/markmanx/isoflow/tree).
|
||||
## CodeSandbox
|
||||
|
||||
Demo the latest version of Isoflow on Codesandbox [here](https://codesandbox.io/p/sandbox/github/markmanx/isoflow/tree).
|
||||
The sandbox is always synced with the Github repo.
|
||||
|
||||
## Contributing
|
||||
- Missing something or found a bug? Report it [here](https://github.com/markmanx/isoflow/issues).
|
||||
- Want to contribute? See [good first issues](https://github.com/markmanx/isoflow/contribute).
|
||||
|
||||
# For contributors
|
||||
|
||||
## Deploying to NPM
|
||||
|
||||
CI is sensitive to any tag pushed to `main` branch. It will build and deploy the app to NPM.
|
||||
To deploy:
|
||||
|
||||
1. Bump the version using `npm version patch` or similar
|
||||
2. `git push && git push --tags`
|
||||
|
||||
### Branching Strategy:
|
||||
|
||||
Branches are named using the following convention:
|
||||
|
||||
- `feature/` for new feature implementations
|
||||
- `fix/` for broken code / build / bug fixes
|
||||
- `chore/` non-breaking & non-fixing code changes such as linting, formatting, etc.
|
||||
|
||||
#### Commit / PR Strategy:
|
||||
|
||||
- Commits are to be squashed prior to merge
|
||||
- PRs are to target a singular issue in order to keep the commit history clean and easy to follow
|
||||
|
||||
## License
|
||||
|
||||
Isoflow is MIT licensed (see ./LICENSE).
|
||||
- Missing something or found a bug? Report it [here](https://github.com/markmanx/isoflow/issues) or join our [Discord server](https://discord.gg/efXxbsha).
|
||||
- Want to contribute? See [good first issues](https://github.com/markmanx/isoflow/contribute).
|
||||
2
docs/.gitignore
vendored
Normal file
2
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
.next
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"index": "Installation"
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
# Installation
|
||||
|
||||
**Isoflow** is published to npm as a React component you can directly embed in your projects.
|
||||
|
||||
Using `npm`:
|
||||
|
||||
```bash
|
||||
npm install isoflow
|
||||
```
|
||||
|
||||
or `yarn`:
|
||||
|
||||
```bash
|
||||
yarn add isoflow
|
||||
```
|
||||
|
||||
### Static assets
|
||||
|
||||
Isoflow depends on static assets for displaying icons. These iconsets are included as part of the npm package and can be imported into Isoflow directly, but you will get better performance if you host these yourself so each icon is accessible via it's own url (for example, storing them on a service like S3 or CDN). See below for more details on the benefits of lazy-loading vs importing:
|
||||
|
||||
- **Importing** assets adds to the bundle size, so your users will have to download **all** assets before your app loads. This can be a problem if there are a lot of icons.
|
||||
|
||||
- **Lazy-loading** assets allow the icons to be downloaded on-demand. Also, lazy-loading assets allows the browser to activate its cache, so they icons only need to be downloaded once.
|
||||
|
||||
### Dimensions of Isoflow
|
||||
|
||||
isoflow takes _100%_ of `width` and `height` of the containing block so make sure the container in which you render Isoflow has non zero dimensions.
|
||||
|
||||
### Demo
|
||||
|
||||
[Try here](https://codesandbox.io/p/sandbox/github/markmanx/isoflow).
|
||||
5
docs/next-env.d.ts
vendored
Normal file
5
docs/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
7
docs/next.config.js
Normal file
7
docs/next.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const withNextra = require('nextra')({
|
||||
theme: 'nextra-theme-docs',
|
||||
themeConfig: './theme.config.tsx',
|
||||
basePath: '/docs',
|
||||
});
|
||||
|
||||
module.exports = withNextra();
|
||||
4457
docs/package-lock.json
generated
Normal file
4457
docs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
docs/package.json
Normal file
18
docs/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "isoflow-docs",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3002"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"next": "^13.4.19",
|
||||
"nextra": "^2.12.1",
|
||||
"nextra-theme-docs": "^2.12.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
}
|
||||
3
docs/pages/_meta.json
Normal file
3
docs/pages/_meta.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"docs": "Isoflow"
|
||||
}
|
||||
7
docs/pages/docs/_meta.json
Normal file
7
docs/pages/docs/_meta.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"index": "Installation",
|
||||
"quickstart": "Quick start",
|
||||
"isopacks": "Loading Isopacks",
|
||||
"api": "API",
|
||||
"contributing": "Contributing"
|
||||
}
|
||||
4
docs/pages/docs/api/_meta.json
Normal file
4
docs/pages/docs/api/_meta.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"index": "Props",
|
||||
"initialData": "initialData"
|
||||
}
|
||||
10
docs/pages/docs/api/index.mdx
Normal file
10
docs/pages/docs/api/index.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
# Props
|
||||
|
||||
| Name | Type | Description | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| `initialData` | [`object`](docs/api/initialData) | The initial scene that Isoflow should render. If `undefined`, isoflow loads a blank scene. | `undefined` |
|
||||
| `width` | `number` \| `string` | Width of the Isoflow renderer as a CSS value. | `100%` |
|
||||
| `height` | `number` \| `string` | Height of the Isoflow renderer as a CSS value. | `100%` |
|
||||
| `onSceneUpdate` | `function` | A callback that is triggered whenever an item is added, updated or removed from the scene. The callback is called with the updated scene as the first argument. | `undefined` |
|
||||
| `disableInteractions` | `boolean` | Removes the ability to interact with the diagram (e.g. to pan, zoom or select elements), as well as hides the toolbar. | `false` |
|
||||
| `debugMode` | `boolean` | Enables extra tools for debugging purposes. | `false` |
|
||||
170
docs/pages/docs/api/initialData.mdx
Normal file
170
docs/pages/docs/api/initialData.mdx
Normal file
@@ -0,0 +1,170 @@
|
||||
# `initialData`
|
||||
|
||||
The `initialData` object contains the following properties:
|
||||
|
||||
| Name | Type | Required |
|
||||
| --- | --- | :---: |
|
||||
| `icons` | [`Icon[]`](#icon) | ✓ |
|
||||
| `nodes` | [`Node[]`](#node) | ✓ |
|
||||
| `connectors` | [`Connector[]`](#connector) | ✓ |
|
||||
| `rectangles` | [`Rectangle[]`](#rectangle) | ✓ |
|
||||
| `zoom` | `number` | |
|
||||
|
||||
## `Icon`
|
||||
|
||||
```js
|
||||
{
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
category?: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Notes on icons:**
|
||||
- `category` is an optional property that can be used to group icons together in the icon picker. All icons with the same `category` will be grouped together.
|
||||
- For a list of standard icon `id`s, see [Isopacks](isopacks#icon-ids).
|
||||
|
||||
## `Node`
|
||||
|
||||
```js
|
||||
{
|
||||
id: string;
|
||||
iconId: string;
|
||||
label?: string;
|
||||
labelHeight?: number;
|
||||
position: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `Connector`
|
||||
|
||||
```js
|
||||
{
|
||||
id: string;
|
||||
color?: string;
|
||||
style?: 'SOLID' | 'DOTTED' | 'DASHED';
|
||||
width?: number;
|
||||
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.
|
||||
|
||||
## `ConnectorAnchor`
|
||||
|
||||
```js
|
||||
{
|
||||
nodeId: string
|
||||
} |
|
||||
{
|
||||
tile: {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## `Rectangle`
|
||||
|
||||
```js
|
||||
{
|
||||
id: string;
|
||||
color?: string;
|
||||
from: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
to: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `initialData` 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](isopacks).
|
||||
|
||||
```js
|
||||
{
|
||||
icons: networkingIsopack,
|
||||
nodes: [
|
||||
{
|
||||
id: 'database',
|
||||
iconId: 'storage',
|
||||
label: 'Database',
|
||||
position: {
|
||||
x: 2,
|
||||
y: -2
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'server',
|
||||
iconId: 'server',
|
||||
label: 'Server',
|
||||
labelHeight: 100,
|
||||
position: {
|
||||
x: 2,
|
||||
y: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'client',
|
||||
iconId: 'laptop',
|
||||
label: 'Client',
|
||||
labelHeight: 100,
|
||||
position: {
|
||||
x: -1,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
],
|
||||
connectors: [
|
||||
{
|
||||
id: 'connector1',
|
||||
anchors: [{ nodeId: 'server' }, { nodeId: 'database' }]
|
||||
},
|
||||
{
|
||||
id: 'connector2',
|
||||
style: ConnectorStyleEnum.DOTTED,
|
||||
width: 10,
|
||||
anchors: [
|
||||
{ nodeId: 'server' },
|
||||
{ tile: { x: -1, y: 2 } },
|
||||
{ nodeId: 'client' }
|
||||
]
|
||||
}
|
||||
],
|
||||
rectangles: [
|
||||
{
|
||||
id: 'rect1',
|
||||
from: {
|
||||
x: 3,
|
||||
y: 3
|
||||
},
|
||||
to: {
|
||||
x: 1,
|
||||
y: -3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Validation
|
||||
`initialData` 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 `iconId` 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.
|
||||
26
docs/pages/docs/contributing.mdx
Normal file
26
docs/pages/docs/contributing.mdx
Normal file
@@ -0,0 +1,26 @@
|
||||
# Contributing
|
||||
|
||||
### Branching Strategy:
|
||||
|
||||
Branches are named using the following convention:
|
||||
|
||||
- `feature/` for new feature implementations
|
||||
- `fix/` for broken code / build / bug fixes
|
||||
- `chore/` non-breaking & non-fixing code changes such as linting, formatting, etc.
|
||||
|
||||
### Commit / PR Strategy:
|
||||
|
||||
- Commits are to be squashed prior to merge
|
||||
- PRs are to target a singular issue in order to keep the commit history clean and easy to follow
|
||||
|
||||
### Deploying to NPM
|
||||
|
||||
CI is sensitive to any tag pushed to `main` branch. It will build and deploy the app to NPM.
|
||||
To deploy:
|
||||
|
||||
1. Bump the version using `npm version patch` or similar
|
||||
2. `git push && git push --tags`
|
||||
|
||||
## License
|
||||
|
||||
Isoflow is MIT licensed (see [./LICENSE](https://github.com/markmanx/isoflow/blob/main/LICENSE)).
|
||||
19
docs/pages/docs/index.mdx
Normal file
19
docs/pages/docs/index.mdx
Normal file
@@ -0,0 +1,19 @@
|
||||
# Installation
|
||||
|
||||
**Isoflow** is published to npm as a React component you can directly embed in your projects.
|
||||
|
||||
Install using `npm`:
|
||||
|
||||
```bash
|
||||
npm install isoflow
|
||||
```
|
||||
|
||||
or `yarn`:
|
||||
|
||||
```bash
|
||||
yarn add isoflow
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
Try it out on [CodeSandbox](https://codesandbox.io/p/sandbox/github/markmanx/isoflow).
|
||||
89
docs/pages/docs/isopacks.mdx
Normal file
89
docs/pages/docs/isopacks.mdx
Normal file
@@ -0,0 +1,89 @@
|
||||
# Isopacks
|
||||
|
||||
**Isopacks** are add-on modules for Isoflow that contain icons and other assets that can be loaded with the Isoflow editor. You can easily extend Isopacks or build your own from scratch.
|
||||
|
||||
### Standard Isopacks
|
||||
|
||||
Two Isopacks are included as part of the npm package. Both sets of icons are available under the MIT license:
|
||||
1. **[The Basic Isopack](https://github.com/markmanx/isoflow/tree/main/src/isopacks/basic/icons)** includes a set of generic isometric icons (for example, cube, pyramid and block).
|
||||
<div style={{ display: 'flex' }}>
|
||||
<img src="https://raw.githubusercontent.com/markmanx/isoflow/main/src/isopacks/basic/icons/cube.svg" alt="drawing" width="100"/>
|
||||
<img src="https://raw.githubusercontent.com/markmanx/isoflow/main/src/isopacks/basic/icons/pyramid.svg" alt="drawing" width="100"/>
|
||||
<img src="https://raw.githubusercontent.com/markmanx/isoflow/main/src/isopacks/basic/icons/block.svg" alt="drawing" width="100"/>
|
||||
</div>
|
||||
2. **[The Networking Isopack](https://github.com/markmanx/isoflow/tree/main/src/isopacks/networking/icons)** includes a set of isometric networking icons (for example, server, storage and switch).
|
||||
<div style={{ display: 'flex' }}>
|
||||
<img src="https://raw.githubusercontent.com/markmanx/isoflow/main/src/isopacks/networking/icons/server.svg" alt="drawing" width="100"/>
|
||||
<img src="https://raw.githubusercontent.com/markmanx/isoflow/main/src/isopacks/networking/icons/storage.svg" alt="drawing" width="100"/>
|
||||
<img src="https://raw.githubusercontent.com/markmanx/isoflow/main/src/isopacks/networking/icons/switch.svg" alt="drawing" width="100"/>
|
||||
</div>
|
||||
|
||||
## Loading the Networking Isopack
|
||||
This will enable the standard set of networking icons within the Isoflow editor.
|
||||
|
||||
```jsx showLineNumbers
|
||||
import Isoflow from 'isoflow';
|
||||
import { networkingIsopack } from 'isoflow/dist/isopacks';
|
||||
|
||||
const initialData = {
|
||||
icons: networkingIsopack,
|
||||
nodes: [],
|
||||
connectors: [],
|
||||
rectangles: [],
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<div style={{ width: '100%', height: '100%' }}>
|
||||
<Isoflow initialData={initialData} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
### Combining Isopacks
|
||||
|
||||
You can combine multiple Isopacks together using the `mergeIsopacks` method.
|
||||
|
||||
```js
|
||||
import { networkingIsopack, basicIsopack, mergeIsopacks } from 'isoflow/dist/isopacks';
|
||||
|
||||
const mergedIsopacks = mergeIsopacks(basicIsopack, networkingIsopack);
|
||||
|
||||
const initialData = {
|
||||
icons: mergedIsopacks,
|
||||
nodes: [],
|
||||
connectors: [],
|
||||
rectangles: [],
|
||||
}
|
||||
```
|
||||
|
||||
### Icon IDs
|
||||
|
||||
As a convention, the `id` of an Isopack icon should be the same as the icon's SVG filename (without the `.svg` extension).
|
||||
This makes it easy to derive `id`s from the file structure (see the links to the Isopacks [above](#standard-isopacks)).
|
||||
|
||||
## Static assets
|
||||
|
||||
While you can import all icon images directly from the npm package (as shown above), it is recommended that you host the icon images yourself so that they can be lazy-loaded (referencing them via URL from a service like S3 or a CDN).
|
||||
|
||||
```js {6}
|
||||
{
|
||||
icons: [
|
||||
{
|
||||
id: 'server',
|
||||
name: 'Server',
|
||||
url: 'https://isoflow.io/static/assets/icons/networking/server.svg',
|
||||
category: 'Networking'
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Benefits of lazy-loading vs importing icons
|
||||
|
||||
- **Importing icons** directly from the npm package adds to the final bundle size. Users will have to download *all* assets in the Isopack before your app loads (which can be a problem if there are a lot of icons).
|
||||
|
||||
- **Referencing icons via URL** enables the icons to be downloaded later on, after the app loads. This also activates the browser's cache for individual icons so that they can be loaded instantly later on.
|
||||
60
docs/pages/docs/quickstart.mdx
Normal file
60
docs/pages/docs/quickstart.mdx
Normal file
@@ -0,0 +1,60 @@
|
||||
# Quick Start
|
||||
|
||||
Isoflow can be imported as an ES6 module:
|
||||
|
||||
```jsx
|
||||
import Isoflow from "isoflow";
|
||||
```
|
||||
|
||||
### Basic usage
|
||||
|
||||
```jsx showLineNumbers
|
||||
import React from 'react';
|
||||
import Isoflow from 'isoflow';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<div style={{ width: '100%', height: '100%' }}>
|
||||
<Isoflow />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
**Note**: this will display a blank Isoflow editor, without icons (which is not very useful!). To initialise the editor with an iconset, see [Loading Isopacks](./isopacks).
|
||||
|
||||
### Dimensions of Isoflow
|
||||
|
||||
Isoflow takes _100%_ of `width` and `height` of the containing block so make sure the container in which you render Isoflow in has non-zero dimensions.
|
||||
|
||||
### Integration with NextJS
|
||||
|
||||
Isoflow cannot be server-side renderered and has to be imported slightly differently when using SSR frameworks like NextJS.
|
||||
|
||||
```jsx showLineNumbers filename="IsoflowDynamic.jsx"
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
export const IsoflowDynamic = dynamic(() => {
|
||||
return import('isoflow');
|
||||
},
|
||||
{
|
||||
ssr: false
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
```jsx showLineNumbers filename="App.jsx"
|
||||
import { IsoflowDynamic } from './IsoflowDynamic';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<div style={{ width: '100%', height: '100%' }}>
|
||||
<IsoflowDynamic />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
12
docs/pages/index.tsx
Normal file
12
docs/pages/index.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
export default function Home() {
|
||||
const { push } = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
push('/docs');
|
||||
}, [push]);
|
||||
|
||||
return null;
|
||||
}
|
||||
36
docs/theme.config.tsx
Normal file
36
docs/theme.config.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
|
||||
export default {
|
||||
darkMode: false,
|
||||
logo: () => {
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
letterSpacing: '-0.02em',
|
||||
fontWeight: 'bold',
|
||||
fontSize: '1.2em'
|
||||
}}
|
||||
>
|
||||
Isoflow Developer Documentation
|
||||
</span>
|
||||
);
|
||||
},
|
||||
nextThemes: {
|
||||
defaultTheme: 'light'
|
||||
},
|
||||
project: {
|
||||
link: 'https://github.com/markmanx/isoflow'
|
||||
},
|
||||
feedback: {
|
||||
content: null
|
||||
},
|
||||
editLink: {
|
||||
component: () => {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
footer: {
|
||||
component: null
|
||||
}
|
||||
};
|
||||
28
docs/tsconfig.json
Normal file
28
docs/tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"noEmit": true,
|
||||
"incremental": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
@@ -16,7 +16,8 @@
|
||||
"build": "webpack --config ./webpack/prod.config.js && tsc --declaration --emitDeclarationOnly && tsc-alias",
|
||||
"test": "jest",
|
||||
"lint": "eslint ./src/**/*.{ts,tsx}",
|
||||
"lint:fix": "eslint --fix ./src/**/*.{ts,tsx}"
|
||||
"lint:fix": "eslint --fix ./src/**/*.{ts,tsx}",
|
||||
"start:docs": "cd ./docs && npm run dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
|
||||
@@ -10,7 +10,9 @@ import {
|
||||
NodeInput,
|
||||
ConnectorInput,
|
||||
RectangleInput,
|
||||
Scene
|
||||
Scene,
|
||||
ConnectorStyleEnum,
|
||||
InitialData
|
||||
} from 'src/types';
|
||||
import { sceneToSceneInput } from 'src/utils';
|
||||
import { useSceneStore, SceneProvider } from 'src/stores/sceneStore';
|
||||
@@ -26,9 +28,7 @@ import { SceneLayer } from './components/SceneLayer/SceneLayer';
|
||||
import { DragAndDrop } from './components/DragAndDrop/DragAndDrop';
|
||||
|
||||
interface Props {
|
||||
initialData?: SceneInput & {
|
||||
zoom?: number;
|
||||
};
|
||||
initialData?: InitialData;
|
||||
disableInteractions?: boolean;
|
||||
onSceneUpdated?: (scene: SceneInput) => void;
|
||||
width?: number | string;
|
||||
@@ -139,6 +139,7 @@ const useIsoflow = () => {
|
||||
export default Isoflow;
|
||||
|
||||
export {
|
||||
InitialData,
|
||||
Scene,
|
||||
SceneInput,
|
||||
IconInput,
|
||||
@@ -147,5 +148,6 @@ export {
|
||||
ConnectorInput,
|
||||
useIsoflow,
|
||||
LabelContainer,
|
||||
sceneValidationSchema
|
||||
sceneValidationSchema,
|
||||
ConnectorStyleEnum
|
||||
};
|
||||
|
||||
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -1,17 +1,71 @@
|
||||
import React from 'react';
|
||||
import Isoflow from 'src/Isoflow';
|
||||
import icons from '../icons';
|
||||
import Isoflow, { ConnectorStyleEnum, InitialData } from 'src/Isoflow';
|
||||
import { networkingIsopack } from 'src/isopacks';
|
||||
|
||||
const initialData: InitialData = {
|
||||
icons: networkingIsopack,
|
||||
nodes: [
|
||||
{
|
||||
id: 'database',
|
||||
iconId: 'storage',
|
||||
label: 'Database',
|
||||
position: {
|
||||
x: 2,
|
||||
y: -2
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'server',
|
||||
iconId: 'server',
|
||||
label: 'Server',
|
||||
labelHeight: 100,
|
||||
position: {
|
||||
x: 2,
|
||||
y: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'client',
|
||||
iconId: 'laptop',
|
||||
label: 'Client',
|
||||
labelHeight: 100,
|
||||
position: {
|
||||
x: -1,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
],
|
||||
connectors: [
|
||||
{
|
||||
id: 'connector1',
|
||||
anchors: [{ nodeId: 'server' }, { nodeId: 'database' }]
|
||||
},
|
||||
{
|
||||
id: 'connector2',
|
||||
style: ConnectorStyleEnum.DOTTED,
|
||||
width: 10,
|
||||
anchors: [
|
||||
{ nodeId: 'server' },
|
||||
{ tile: { x: -1, y: 2 } },
|
||||
{ nodeId: 'client' }
|
||||
]
|
||||
}
|
||||
],
|
||||
rectangles: [
|
||||
{
|
||||
id: 'rect1',
|
||||
from: {
|
||||
x: 3,
|
||||
y: 3
|
||||
},
|
||||
to: {
|
||||
x: 1,
|
||||
y: -3
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const BasicEditor = () => {
|
||||
return (
|
||||
<Isoflow
|
||||
initialData={{
|
||||
icons,
|
||||
nodes: [],
|
||||
connectors: [],
|
||||
rectangles: []
|
||||
}}
|
||||
height="100%"
|
||||
/>
|
||||
);
|
||||
return <Isoflow initialData={initialData} />;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import basicIcons from 'src/isopacks/basic/manifest';
|
||||
import networkingIcons from 'src/isopacks/networking/manifest';
|
||||
import { mergeManifests } from 'src/isopacks/utils';
|
||||
import { basicIsopack, networkingIsopack, mergeIsopacks } from 'src/isopacks';
|
||||
|
||||
export default mergeManifests([basicIcons, networkingIcons]);
|
||||
export default mergeIsopacks([basicIsopack, networkingIsopack]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { IconInput } from 'src/types';
|
||||
import type { SceneInput } from 'src/types';
|
||||
import { createCategoryIcon } from '../utils';
|
||||
import Block from './icons/block.svg';
|
||||
import Cube from './icons/cube.svg';
|
||||
@@ -8,7 +8,7 @@ import Sphere from './icons/sphere.svg';
|
||||
|
||||
const createIcon = createCategoryIcon('Basic shapes');
|
||||
|
||||
const manifest: IconInput[] = [
|
||||
export const basicIsopack: SceneInput['icons'] = [
|
||||
createIcon({
|
||||
id: 'block',
|
||||
name: 'Block',
|
||||
@@ -35,5 +35,3 @@ const manifest: IconInput[] = [
|
||||
url: Sphere
|
||||
})
|
||||
];
|
||||
|
||||
export default manifest;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * as BasicIsopack from './basic/manifest';
|
||||
export * as NetworkingIsopack from './networking/manifest';
|
||||
export { basicIsopack } from './basic/manifest';
|
||||
export { networkingIsopack } from './networking/manifest';
|
||||
|
||||
export { mergeManifests } from './utils';
|
||||
export { mergeIsopacks } from './utils';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { IconInput } from 'src/types';
|
||||
import type { SceneInput } from 'src/types';
|
||||
import { createCategoryIcon } from '../utils';
|
||||
import Cache from './icons/cache.svg';
|
||||
import CardTerminal from './icons/cardterminal.svg';
|
||||
@@ -29,14 +29,14 @@ import VM from './icons/vm.svg';
|
||||
|
||||
const createIcon = createCategoryIcon('Networking');
|
||||
|
||||
const manifest: IconInput[] = [
|
||||
export const networkingIsopack: SceneInput['icons'] = [
|
||||
createIcon({
|
||||
id: 'cache',
|
||||
name: 'Cache',
|
||||
url: Cache
|
||||
}),
|
||||
createIcon({
|
||||
id: 'card-terminal',
|
||||
id: 'cardterminal',
|
||||
name: 'Card Terminal',
|
||||
url: CardTerminal
|
||||
}),
|
||||
@@ -66,9 +66,9 @@ const manifest: IconInput[] = [
|
||||
url: Firewall
|
||||
}),
|
||||
createIcon({
|
||||
url: Function,
|
||||
id: 'function',
|
||||
name: 'Function'
|
||||
name: 'Function',
|
||||
url: Function
|
||||
}),
|
||||
createIcon({
|
||||
id: 'laptop',
|
||||
@@ -76,7 +76,7 @@ const manifest: IconInput[] = [
|
||||
url: Laptop
|
||||
}),
|
||||
createIcon({
|
||||
id: 'load-balancer',
|
||||
id: 'loadbalancer',
|
||||
name: 'Load balancer',
|
||||
url: LoadBalancer
|
||||
}),
|
||||
@@ -91,12 +91,12 @@ const manifest: IconInput[] = [
|
||||
url: Mail
|
||||
}),
|
||||
createIcon({
|
||||
id: 'mail-multiple',
|
||||
id: 'mailmultiple',
|
||||
name: 'Mail multiple',
|
||||
url: MailMultiple
|
||||
}),
|
||||
createIcon({
|
||||
id: 'mobile-device',
|
||||
id: 'mobiledevice',
|
||||
name: 'Mobile device',
|
||||
url: MobileDevice
|
||||
}),
|
||||
@@ -111,7 +111,7 @@ const manifest: IconInput[] = [
|
||||
url: Package
|
||||
}),
|
||||
createIcon({
|
||||
id: 'payment-card',
|
||||
id: 'paymentcard',
|
||||
name: 'Payment card',
|
||||
url: PaymentCard
|
||||
}),
|
||||
@@ -156,15 +156,8 @@ const manifest: IconInput[] = [
|
||||
url: User
|
||||
}),
|
||||
createIcon({
|
||||
id: 'virtual-machine',
|
||||
id: 'vm',
|
||||
name: 'Virtual machine',
|
||||
url: VM
|
||||
}),
|
||||
createIcon({
|
||||
url: Function,
|
||||
id: 'function',
|
||||
name: 'Function'
|
||||
})
|
||||
];
|
||||
|
||||
export default manifest;
|
||||
|
||||
@@ -17,7 +17,7 @@ export const createCategoryIcon = (category: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const mergeManifests = (manifests: IconInput[][]) => {
|
||||
export const mergeIsopacks = (manifests: IconInput[][]) => {
|
||||
return manifests.reduce((acc, manifest) => {
|
||||
return [...acc, ...manifest];
|
||||
}, []);
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import type { SceneInput } from './inputs';
|
||||
|
||||
export type InitialData = SceneInput & {
|
||||
zoom?: number;
|
||||
};
|
||||
|
||||
export interface Coords {
|
||||
x: number;
|
||||
y: number;
|
||||
|
||||
@@ -10,7 +10,8 @@ import {
|
||||
Rectangle,
|
||||
ConnectorAnchorInput,
|
||||
ConnectorAnchor,
|
||||
Coords
|
||||
Coords,
|
||||
ConnectorStyleEnum
|
||||
} from 'src/types';
|
||||
import { NODE_DEFAULTS, DEFAULT_COLOR, CONNECTOR_DEFAULTS } from 'src/config';
|
||||
import { getConnectorPath } from './renderer';
|
||||
|
||||
@@ -22,6 +22,7 @@ export const nodeInput = z.object({
|
||||
});
|
||||
|
||||
export const connectorAnchorInput = z
|
||||
// TODO: See if we can use `z.discriminatedUnion` here. See https://github.com/colinhacks/zod#unions
|
||||
.object({
|
||||
nodeId: z.string(),
|
||||
tile: coords
|
||||
|
||||
Reference in New Issue
Block a user