|
|
@@ -1,7 +1,6 @@
|
|
|
+# Creating a Fixed Layout Canvas
|
|
|
|
|
|
-# Create a Fixed Layout Canvas
|
|
|
-
|
|
|
-This case can be installed by `npx @flowgram.ai/create-app@latest fixed-layout-simple`, the complete code and effect are as follows:
|
|
|
+This example can be installed using `npx @flowgram.ai/create-app@latest fixed-layout-simple`. For complete code and demo, see:
|
|
|
|
|
|
<div className="rs-tip">
|
|
|
<a className="rs-link" href="/en/examples/fixed-layout/fixed-layout-simple.html">
|
|
|
@@ -9,21 +8,34 @@ This case can be installed by `npx @flowgram.ai/create-app@latest fixed-layout-s
|
|
|
</a>
|
|
|
</div>
|
|
|
|
|
|
+File structure:
|
|
|
+
|
|
|
+```
|
|
|
+- hooks
|
|
|
+ - use-editor-props.ts # Canvas configuration
|
|
|
+- components
|
|
|
+ - base-node.tsx # Node rendering
|
|
|
+ - tools.tsx # Canvas toolbar
|
|
|
+- initial-data.ts # Initialization data
|
|
|
+- node-registries.ts # Node configuration
|
|
|
+- app.tsx # Canvas entry
|
|
|
+```
|
|
|
|
|
|
### 1. Canvas Entry
|
|
|
|
|
|
-- `FixedLayoutEditorProvider`: Canvas configurator, internally generates a react-context for consumption by child components
|
|
|
-- `EditorRenderer`: The final rendered canvas, can be wrapped in other components to customize the canvas position
|
|
|
+- `FixedLayoutEditorProvider`: Canvas configurator that generates react-context internally for child components to consume
|
|
|
+- `EditorRenderer`: The final rendered canvas that can be wrapped under other components for customizing canvas position
|
|
|
|
|
|
```tsx pure title="app.tsx"
|
|
|
-
|
|
|
import {
|
|
|
FixedLayoutEditorProvider,
|
|
|
EditorRenderer,
|
|
|
} from '@flowgram.ai/fixed-layout-editor';
|
|
|
|
|
|
-import { useEditorProps } from './use-editor-props' // Canvas detailed props configuration
|
|
|
-import { Tools } from './tools' // Canvas tools
|
|
|
+import '@flowgram.ai/fixed-layout-editor/index.css'; // Load styles
|
|
|
+
|
|
|
+import { useEditorProps } from './hooks/use-editor-props' // Detailed canvas props configuration
|
|
|
+import { Tools } from './components/tools' // Canvas tools
|
|
|
|
|
|
function App() {
|
|
|
const editorProps = useEditorProps()
|
|
|
@@ -38,15 +50,15 @@ function App() {
|
|
|
|
|
|
### 2. Configure Canvas
|
|
|
|
|
|
-Canvas configuration uses declarative, providing data, rendering, event, plugin related configurations
|
|
|
+Canvas configuration is declarative, providing configurations for data, rendering, events, and plugins.
|
|
|
|
|
|
-```tsx pure title="use-editor-props.tsx"
|
|
|
+```tsx pure title="hooks/use-editor-props.tsx"
|
|
|
import { useMemo } from 'react';
|
|
|
import { type FixedLayoutProps } from '@flowgram.ai/fixed-layout-editor';
|
|
|
import { defaultFixedSemiMaterials } from '@flowgram.ai/fixed-semi-materials';
|
|
|
import { createMinimapPlugin } from '@flowgram.ai/minimap-plugin';
|
|
|
|
|
|
-import { intialData } from './initial-data' // Initial data
|
|
|
+import { initialData } from './initial-data' // Initialization data
|
|
|
import { nodeRegistries } from './node-registries' // Node declaration configuration
|
|
|
import { BaseNode } from './base-node' // Node rendering
|
|
|
|
|
|
@@ -55,15 +67,16 @@ export function useEditorProps(
|
|
|
return useMemo<FixedLayoutProps>(
|
|
|
() => ({
|
|
|
/**
|
|
|
- * Initial data
|
|
|
+ * Initialization data
|
|
|
*/
|
|
|
initialData,
|
|
|
/**
|
|
|
- * Canvas node definition
|
|
|
+ * Canvas node definitions
|
|
|
*/
|
|
|
nodeRegistries,
|
|
|
/**
|
|
|
- * Custom UI components can be defined by key, for example, add a button, here is a semi-component set for quick verification, if you need deep customization, refer to:
|
|
|
+ * UI components can be customized through keys. Here, a set of semi components is provided for quick validation.
|
|
|
+ * For deep customization, refer to:
|
|
|
* https://github.com/bytedance/flowgram.ai/blob/main/packages/materials/fixed-semi-materials/src/components/index.tsx
|
|
|
*/
|
|
|
materials: {
|
|
|
@@ -75,31 +88,31 @@ export function useEditorProps(
|
|
|
renderDefaultNode: BaseNode, // Node rendering component
|
|
|
},
|
|
|
/**
|
|
|
- * Node engine, used to render node form
|
|
|
+ * Node engine for rendering node forms
|
|
|
*/
|
|
|
nodeEngine: {
|
|
|
enable: true,
|
|
|
},
|
|
|
/**
|
|
|
- * Canvas history, used to control redo/undo
|
|
|
+ * Canvas history record for controlling redo/undo
|
|
|
*/
|
|
|
history: {
|
|
|
enable: true,
|
|
|
- enableChangeNode: true, // Used to listen to node form data changes
|
|
|
+ enableChangeNode: true, // Monitor node form data changes
|
|
|
},
|
|
|
/**
|
|
|
* Canvas initialization callback
|
|
|
*/
|
|
|
onInit: ctx => {
|
|
|
- // If you want to dynamically load data, you can execute it asynchronously by the following method
|
|
|
+ // For dynamic data loading, use the following method asynchronously
|
|
|
// ctx.docuemnt.fromJSON(initialData)
|
|
|
},
|
|
|
/**
|
|
|
- * Canvas first rendering completed callback
|
|
|
+ * Callback when canvas first render completes
|
|
|
*/
|
|
|
onAllLayersRendered: (ctx) => {},
|
|
|
/**
|
|
|
- * Canvas destruction callback
|
|
|
+ * Canvas disposal callback
|
|
|
*/
|
|
|
onDispose: () => { },
|
|
|
plugins: () => [
|
|
|
@@ -112,28 +125,25 @@ export function useEditorProps(
|
|
|
[],
|
|
|
);
|
|
|
}
|
|
|
-
|
|
|
```
|
|
|
|
|
|
-
|
|
|
### 3. Configure Data
|
|
|
|
|
|
-Canvas document data uses a tree structure, supports nesting
|
|
|
+Canvas document data uses a tree structure that supports nesting.
|
|
|
|
|
|
-:::note Document data basic structure:
|
|
|
+:::note Document Data Basic Structure:
|
|
|
|
|
|
- nodes `array` Node list, supports nesting
|
|
|
|
|
|
:::
|
|
|
|
|
|
-:::note Node data basic structure:
|
|
|
+:::note Node Data Basic Structure:
|
|
|
|
|
|
-
|
|
|
-- id: `string` Node unique identifier, must be unique
|
|
|
-- meta: `object` Node ui configuration information, such as free layout `position` information
|
|
|
-- type: `string | number` Node type, will correspond to `type` in `nodeRegistries`
|
|
|
+- id: `string` Unique node identifier, must be unique
|
|
|
+- meta: `object` Node UI configuration information, such as position information for free layout
|
|
|
+- type: `string | number` Node type, corresponds to `type` in `nodeRegistries`
|
|
|
- data: `object` Node form data
|
|
|
-- blocks: `array` Node branch, using `block` is more in line with `Gramming`
|
|
|
+- blocks: `array` Node branches, using `block` is closer to `Gramming`
|
|
|
|
|
|
:::
|
|
|
|
|
|
@@ -141,7 +151,7 @@ Canvas document data uses a tree structure, supports nesting
|
|
|
import { FlowDocumentJSON } from '@flowgram.ai/fixed-layout-editor';
|
|
|
|
|
|
/**
|
|
|
- * Configure workflow data, data is in the format of nested blocks
|
|
|
+ * Configure flow data, data is in blocks nested format
|
|
|
*/
|
|
|
export const initialData: FlowDocumentJSON = {
|
|
|
nodes: [
|
|
|
@@ -155,7 +165,7 @@ export const initialData: FlowDocumentJSON = {
|
|
|
},
|
|
|
blocks: [],
|
|
|
},
|
|
|
- // Branch node
|
|
|
+ // Condition node
|
|
|
{
|
|
|
id: 'condition_0',
|
|
|
type: 'condition',
|
|
|
@@ -176,7 +186,7 @@ export const initialData: FlowDocumentJSON = {
|
|
|
type: 'custom',
|
|
|
data: {
|
|
|
title: 'Custom',
|
|
|
- content: 'custrom content'
|
|
|
+ content: 'custom content'
|
|
|
},
|
|
|
},
|
|
|
],
|
|
|
@@ -203,12 +213,11 @@ export const initialData: FlowDocumentJSON = {
|
|
|
},
|
|
|
],
|
|
|
};
|
|
|
-
|
|
|
```
|
|
|
|
|
|
-### 4. Declare Node
|
|
|
+### 4. Declare Nodes
|
|
|
|
|
|
-Declare node can be used to determine the type and rendering method of the node
|
|
|
+Node declaration can be used to determine node types and rendering methods.
|
|
|
|
|
|
```tsx pure title="node-registries.tsx"
|
|
|
import { FlowNodeRegistry, ValidateTrigger } from '@flowgram.ai/fixed-layout-editor';
|
|
|
@@ -223,30 +232,30 @@ export const nodeRegistries: FlowNodeRegistry[] = [
|
|
|
*/
|
|
|
type: 'condition',
|
|
|
/**
|
|
|
- * Custom node extension:
|
|
|
- * - loop: Extended to loop node
|
|
|
- * - start: Extended to start node
|
|
|
- * - dynamicSplit: Extended to branch node
|
|
|
- * - end: Extended to end node
|
|
|
- * - tryCatch: Extended to tryCatch node
|
|
|
- * - default: Extended to normal node (default)
|
|
|
+ * Custom node extensions:
|
|
|
+ * - loop: Extend as loop node
|
|
|
+ * - start: Extend as start node
|
|
|
+ * - dynamicSplit: Extend as branch node
|
|
|
+ * - end: Extend as end node
|
|
|
+ * - tryCatch: Extend as tryCatch node
|
|
|
+ * - default: Extend as normal node (default)
|
|
|
*/
|
|
|
extend: 'dynamicSplit',
|
|
|
/**
|
|
|
* Node configuration information
|
|
|
*/
|
|
|
meta: {
|
|
|
- // isStart: false, // Whether it is a start node
|
|
|
- // isNodeEnd: false, // Whether it is an end node, the node after the end node cannot be added
|
|
|
- // draggable: false, // Whether it can be dragged, such as the start node and the end node cannot be dragged
|
|
|
- // selectable: false, // The trigger start node cannot be selected
|
|
|
+ // isStart: false, // Whether it's a start node
|
|
|
+ // isNodeEnd: false, // Whether it's an end node, no nodes can be added after end node
|
|
|
+ // draggable: false, // Whether draggable, start and end nodes cannot be dragged
|
|
|
+ // selectable: false, // Triggers and start nodes cannot be box-selected
|
|
|
// deleteDisable: true, // Disable deletion
|
|
|
- // copyDisable: true, // Disable copy
|
|
|
- // addDisable: true, // Disable addition
|
|
|
+ // copyDisable: true, // Disable copying
|
|
|
+ // addDisable: true, // Disable adding
|
|
|
},
|
|
|
/**
|
|
|
- * Configure node form validation and rendering,
|
|
|
- * Note: validate uses data and rendering separation, ensuring that even if the node is not rendered, the data can be validated
|
|
|
+ * Configure node form validation and rendering
|
|
|
+ * Note: validate uses data and rendering separation to ensure node validation even without rendering
|
|
|
*/
|
|
|
formMeta: {
|
|
|
validateTrigger: ValidateTrigger.onChange,
|
|
|
@@ -269,22 +278,22 @@ export const nodeRegistries: FlowNodeRegistry[] = [
|
|
|
},
|
|
|
},
|
|
|
];
|
|
|
-
|
|
|
```
|
|
|
-### 5. Render Node
|
|
|
|
|
|
-The rendering node is used to add styles, events, and form rendering positions
|
|
|
+### 5. Render Nodes
|
|
|
+
|
|
|
+Node rendering is used to add styles, events, and form rendering positions.
|
|
|
|
|
|
-```tsx pure title="base-node.tsx"
|
|
|
+```tsx pure title="components/base-node.tsx"
|
|
|
import { useNodeRender } from '@flowgram.ai/fixed-layout-editor';
|
|
|
|
|
|
export const BaseNode = () => {
|
|
|
/**
|
|
|
- * Provides methods related to node rendering
|
|
|
+ * Provides node rendering related methods
|
|
|
*/
|
|
|
const nodeRender = useNodeRender();
|
|
|
/**
|
|
|
- * Forms can only be used when the node engine is enabled
|
|
|
+ * Form can only be used when node engine is enabled
|
|
|
*/
|
|
|
const form = nodeRender.form;
|
|
|
|
|
|
@@ -305,21 +314,19 @@ export const BaseNode = () => {
|
|
|
}}
|
|
|
>
|
|
|
{
|
|
|
- // Form rendering is generated through formMeta
|
|
|
+ // Form rendering generated through formMeta
|
|
|
form?.render()
|
|
|
}
|
|
|
</div>
|
|
|
);
|
|
|
};
|
|
|
-
|
|
|
```
|
|
|
|
|
|
-
|
|
|
### 6. Add Tools
|
|
|
|
|
|
-Tools are mainly used to control canvas zooming and other operations. Tools are consolidated in `usePlaygroundTools`, while `useClientContext` is used to get the canvas context, which contains core modules such as `history`
|
|
|
+Tools are mainly used to control canvas zooming and other operations. Tools are collected in `usePlaygroundTools`, while `useClientContext` is used to get canvas context, which contains core modules like `history`.
|
|
|
|
|
|
-```tsx pure title="tools.tsx"
|
|
|
+```tsx pure title="components/tools.tsx"
|
|
|
import { useEffect, useState } from 'react'
|
|
|
import { usePlaygroundTools, useClientContext } from '@flowgram.ai/fixed-layout-editor';
|
|
|
|
|
|
@@ -347,9 +354,9 @@ export function Tools() {
|
|
|
<span>{Math.floor(tools.zoom * 100)}%</span>
|
|
|
</div>
|
|
|
}
|
|
|
-
|
|
|
```
|
|
|
-### 7. Effect
|
|
|
+
|
|
|
+### 7. Result
|
|
|
|
|
|
import { FixedLayoutSimple } from '../../../../components';
|
|
|
|