Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/bytedance/flow-builder

A highly customizable streaming flow builder.
https://github.com/bytedance/flow-builder

builder flow process react

Last synced: 26 days ago
JSON representation

A highly customizable streaming flow builder.

Lists

README

        

# Introduction

English | [简体中文](https://github.com/bytedance/flow-builder/blob/main/README.zh-CN.md)

A highly customizable streaming flow builder. The registration ability can flexibly customize your nodes, different types of node display and form, etc.

| ![demo1](./public/demo1-en.png) | ![demo2](./public/demo2-en.png) |
| ------------------------------- | ------------------------------- |

## Try it out

https://bytedance.github.io/flow-builder

## Github

https://github.com/bytedance/flow-builder

## Installation

```
yarn add react-flow-builder

or

npm install react-flow-builder
```

## Usage

```tsx
// index.tsx
import React, { useState, useContext } from 'react';
import FlowBuilder, {
NodeContext,
INode,
IRegisterNode,
} from 'react-flow-builder';

import './index.css';

const StartNodeDisplay: React.FC = () => {
const node = useContext(NodeContext);
return

{node.name}
;
};

const EndNodeDisplay: React.FC = () => {
const node = useContext(NodeContext);
return

{node.name}
;
};

const OtherNodeDisplay: React.FC = () => {
const node = useContext(NodeContext);
return

{node.name}
;
};

const ConditionNodeDisplay: React.FC = () => {
const node = useContext(NodeContext);
return

{node.name}
;
};

const registerNodes: IRegisterNode[] = [
{
type: 'start',
name: 'start node',
displayComponent: StartNodeDisplay,
isStart: true,
},
{
type: 'end',
name: 'end node',
displayComponent: EndNodeDisplay,
isEnd: true,
},
{
type: 'node',
name: 'other node',
displayComponent: OtherNodeDisplay,
},
{
type: 'condition',
name: 'condition node',
displayComponent: ConditionNodeDisplay,
},
{
type: 'branch',
name: 'branch node',
conditionNodeType: 'condition',
},
];

const Demo = () => {
const [nodes, setNodes] = useState([]);

const handleChange = (nodes: INode[]) => {
console.log('nodes change', nodes);
setNodes(nodes);
};

return (

);
};

export default Demo;

// index.css
.start-node, .end-node {
height: 64px;
width: 64px;
border-radius: 50%;
line-height: 64px;
color: #fff;
text-align: center;
}

.start-node {
background-color: #338aff;
}

.end-node {
background-color: #666;
}

.other-node, .condition-node {
width: 224px;
border-radius: 4px;
color: #666;
background: #fff;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.08);
}

.other-node {
height: 118px;
padding: 16px;
display: flex;
flex-direction: column;
}

.condition-node {
height: 44px;
padding: 12px 16px;
}
```

## API

### FlowBuilder

| Property | Description | Type | Required | Default | Version |
| :------------------------ | :-------------------------------------------------- | :--------------------------------------------------------------------------- | :------- | :--------- | :------ |
| backgroundColor | The color of background | `string` | | #F7F7F7 | |
| className | The class name of the container | `string` | | - |
| draggable | drag and drop | `boolean` | | false | 1.0.0 |
| DragComponent | custom drag component | `React.FC`\<[DragComponent](#dragcomponent)\> | | - | 1.0.0 |
| DropComponent | custom drop component | `React.FC`\<[DropComponent](#dropcomponent)\> | | - | 1.0.0 |
| createUuid | custom node uuid | `(type?: string) => string` | | - | 2.0.0 |
| DrawerComponent | Drawer component | `React.FC`\<[DrawerComponent](#drawercomponent)\> | | - | 2.0.0 |
| PopoverComponent | Popover component | `React.FC`\<[PopoverComponent](#popovercomponent)\> | | - | 2.0.0 |
| PopconfirmComponent | Popconfirm component | `React.FC`\<[PopconfirmComponent](#popconfirmcomponent)\> | | - | 2.0.0 |
| drawerProps | Extra props of DrawerComponent | `any` | | - | |
| drawerVisibleWhenAddNode | Drawer visible when add node | `boolean` | | false | |
| historyTool | undo and redo | `boolean` \| [HistoryToolConfig](#historytoolconfig) | | false |
| layout | Use vertical or horizontal layout | `vertical` \| `horizontal` | | `vertical` | |
| lineColor | The color of line | `string` | | #999999 | |
| nodes | The nodes of FlowBuilder | [Node](#node)[] | ✓ | - | |
| readonly | Readonly mode, cannot add, remove, configure. | `boolean` | | false | |
| registerNodes | The registered nodes | [RegisterNode](#registernode)[] | ✓ | - | |
| registerRemoteNodes | The registered remote nodes | [RegisterRemoteNode](#registerremotenode)[] | | - | 1.3.0 |
| showPracticalBranchNode | - | `boolean` | | false | 1.1.0 |
| showPracticalBranchRemove | - | `boolean` | | false | 1.1.0 |
| sortable | Condition nodes can be dragged and sorted in branch | `boolean` | | false | 1.4.0 |
| sortableAnchor | Anchor for start dragging 序 | `ReactNode` | | - | 1.4.0 |
| spaceX | Horizontal spacing between nodes | `number` | | `16` | |
| spaceY | Vertical spacing between nodes | `number` | | `16` |
| zoomTool | zoom | `boolean` \| [ZoomToolConfig](#zoomtoolconfig) | | false | |
| onChange | Callback function for when the data change | (nodes: [Node](#node)[], changeEvent: `string`, nodeChanged?: INode) => void | ✓ | - | |
| onHistoryChange | | `(undoDisabled: boolean, redoDisabled: boolean) => void` | | - | |
| onZoomChange | | `(outDisabled: boolean, value: number, inDisabled: boolean) => void` | | - | |
| showArrow | Show arrow | `boolean` | | false | 1.4.5 |
| arrowIcon | The icon of the arrow | `ReactNode` | | - | 1.4.5 |
| onAddNodeSuccess | Called when add node success | `(type: string, node: INode) => void` | | - | 1.4.9 |
| onDropNodeSuccess | Called when drop node success | `(type: string, node: INode) => void` | | - | 1.4.9 |
| onRemoveNodeSuccess | Called when remove node success | `(node: INode) => void` | | - | 2.2.0 |
| allowStartConfig | Allow start node config | `boolean` | | - | 2.1.0 |
| allowEndConfig | Allow end node config | `boolean` | | - | 2.1.0 |
| scrollByDrag | Scroll by mouse dragging | `boolean` | | - | 2.6.0 |

#### HistoryToolConfig

| Property | Description | Type | Default |
| :------- | :---------- | :-------- | :------ |
| hidden | | `boolean` | false |
| max | | `number` | 10 |

#### ZoomToolConfig

| Property | Description | Type | Default |
| :----------- | :---------- | :-------- | :------ |
| hidden | | `boolean` | false |
| initialValue | | `number` | 100 |
| min | | `number` | 10 |
| max | | `number` | 200 |
| step | | `number` | 10 |

#### DragComponent

| Property | Description | Type | Version |
| :---------- | :--------------------------------------------------------------------------------------------------------------------------------- | :--------------------------- | :------ |
| onDragStart | The dragStart event of the custom drag component needs to call this method to set the dragged type( dragType in BuilderContext ) | `(nodeType: string) => void` | 1.0.0 |
| onDragEnd | The dragEnd event of the custom drag component needs to call this method to clear the dragged type( dragType in BuilderContext ) | `() => void` | 1.0.0 |

#### DropComponent

| Property | Description | Type | Version |
| :------- | :--------------------------------------------------------------------------------------------- | :----------- | :------ |
| onDrop | The drop event of the custom drop component needs to call this method to add the new node type | `() => void` | 1.0.0 |

#### DrawerComponent

| Property | Description | Type | Version |
| :----------------- | :--------------------------------------------------------------- | :------------------------------ | :------ |
| visible | You can judge the boolean value of **selectedNode** by yourself. | `any` | 2.0.0 |
| onClose | You can also call **closeDrawer** by yourself. | `any` | 2.0.0 |
| children | | `any` | 2.0.0 |
| title | | `any` | 2.0.0 |
| width | | `any` | 2.0.0 |
| destroyOnClose | | `any` | 2.0.0 |
| maskClosable | | `any` | 2.0.0 |
| configComponentRef | | `React.MutableRefObject`\ | 2.5.0 |

#### PopoverComponent

| Property | Description | Type | Version |
| :---------------- | :---------- | :---- | :------ |
| visible | | `any` | 2.0.0 |
| onVisibleChange | | `any` | 2.0.0 |
| children | | `any` | 2.0.0 |
| overlayClassName | | `any` | 2.0.0 |
| placement | | `any` | 2.0.0 |
| trigger | | `any` | 2.0.0 |
| content | | `any` | 2.0.0 |
| getPopupContainer | | `any` | 2.0.0 |

#### PopconfirmComponent

| Property | Description | Type | Version |
| :---------------- | :----------------------------------------- | :---- | :------ |
| title | | `any` | 2.0.0 |
| onConfirm | You can also call **removeNode** yourself. | `any` | 2.0.0 |
| children | | `any` | 2.0.0 |
| getPopupContainer | | `any` | 2.0.0 |

### FlowBuilderInstance

| Name | Description | Type | Version |
| :---------- | :------------- | :------------------------------------------------------------------------------ | :------ |
| add | add node | `(node: INode, newNodeType: string) => void` \| `(newNodeType: string) => void` |
| history | undo, redo | `(type: 'undo' \| 'redo') => void` |
| remove | remove noded | `(nodes: INode \| INode[] = useContext(NodeContext)) => void` |
| zoom | zoom | `(type: 'out' \| 'in' \| number) => void` |
| closeDrawer | close drawer | `() => void` |
| context | BuilderContext | [BuilderContext](#buildercontext) | 1.3.5 |

### Formatter

| Name | Description | Type |
| :------------- | :---------------------- | :---------------------------------------------------------------------- |
| buildFlatNodes | Translate to flat nodes | `(params: {registerNodes: IRegisterNode[], nodes: INode[]}) => INode[]` |
| buildTreeNodes | Translate to tree nodes | `(params: {nodes: INode[]}) => INode[]` |
| createUuid | Create uuid | `(prefix?: string) => string` |

### RegisterNode

| Property | Description | Type | Required | Default | Version |
| :------------------------ | :------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :-------------------------------- | :------ |
| addableComponent | | `React.FC`\<[AddableComponent](#addablecomponent)\> | | - |
| addableNodeTypes | The list of nodes that can be added below the node | `string[]` | | - |
| addIcon | The icon in addable node list (There are already some default icons) | `ReactNode` | | - |
| addConditionIcon | The icon of the branch node when adding a condition (The default icon already exists) | `ReactNode` | | - | 1.3.3 |
| className | The class name of node | `string` | | - | 1.3.4 |
| conditionMaxNum | The max number of condition node | `number` | | - |
| conditionNodeType | The type of condition node | `string` | | - |
| configComponent | The Component of configuring node form | `React.FC`\<[ConfigComponent](#configcomponent)\> \| `React.ForwardRefExoticComponent`\<[ConfigComponent](#configcomponent) & `React.RefAttributes`\\> | | - |
| configTitle | The drawer title of configuring node | `string \| ((node: INode, nodes: INode[]) => string)` | | - |
| customRemove | Custom remove button | `boolean` | | false |
| displayComponent | The Component of displaying node | `React.FC`\<[DisplayComponent](#displaycomponent)\> | | - |
| initialNodeData | the initial data when add new node | `Record` | | - |
| isStart | Is start node | `boolean` | | false |
| isEnd | Is end node | `boolean` | | false |
| isLoop | Is loop node | `boolean` | | false | 1.4.6 |
| name | The name of node | `string` | ✓ | - |
| removeConfirmTitle | The confirmation information before deleting the node. The [title](https://ant.design/components/popconfirm/#API) of Popconfirm | `string` \| `ReactNode` | | Are you sure to remove this node? |
| showPracticalBranchNode | - | `boolean` | | false | 1.1.0 |
| showPracticalBranchRemove | - | `boolean` | | false | 1.1.0 |
| type | The type of node, promise `start` is start node type and `end` is end node type | `string` | ✓ | - |

### RegisterRemoteNode

| Property | Description | Type | Required | Default | Version |
| :------- | :------------- | :------- | :------- | :------ | :------ |
| url | remote url | `string` | ✓ | - | 1.3.0 |
| cssUrl | remote css url | `string` | | - | 1.3.0 |

#### DisplayComponent

| Property | Description | Type |
| :------- | :---------------------------------------------------------------- | :----------------------------------- |
| node | The all information of node (NodeContext is recommended since V1) | [Node](#node) |
| nodes | (BuilderContext is recommended since V1) | [Node](#node)[] |
| readonly | (BuilderContext is recommended since V1) | `boolean` |
| remove | Remove node (useAction is recommended since V1) | `(nodes?: INode \| INode[]) => void` |

#### ConfigComponent

| Property | Description | Type |
| :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------- |
| cancel | Called on cancel, used to close the drawer (useDrawer is recommended since V1) | `() => void` |
| node | The all information of node (NodeContext is recommended since V1) | [Node](#node) |
| nodes | (BuilderContext is recommended since V1) | [Node](#node)[] |
| save | Called on save node data (automatically close the drawer, no need to call cancel). FlowBuilder will set the `validateStatusError` property according to the second param (useDrawer is recommended since V1) | `(values: any, validateStatusError?: boolean) => void` |

#### AddableComponent

| Property | Description | Type |
| :------- | :---------------------------------------------------------------- | :----------------------- |
| add | | `(type: string) => void` |
| node | The all information of node (NodeContext is recommended since V1) | [Node](#node) |
| nodes | (BuilderContext is recommended since V1) | [Node](#node)[] |

### Node

| Property | Description | Type |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------ | :-------------- |
| children | The condition nodes array of branch node, or the next flow of condition node | [Node](#node)[] |
| configuring | Whether configuring of node. The display Component can highlight the node according to this property | `boolean` |
| data | The data of node | `any` |
| id | The unique id of node | `string` |
| name | The name of node. Same as the `name` of the registered node | `string` |
| path | The full path in FlowBuilder | `string[]` |
| type | The type of node. Same as the `type` of the registered node | `string` |
| validateStatusError | The Component of configuring node form validate failed. The display Component can highlight the node according to this property | `boolean` |

### Context

**Added since V1**

In the context of FlowBuilder the following contexts can be used

#### BuilderContext

Contains [props](#flowbuilder) and state. The following is the state:

| Property | Description | Type |
| :-------------------------- | :------------------------------------- | :----------------------------------- |
| zoomValue | current zoom value | `number` |
| setZoomValue | set zoomValue | `(zoomValue: number) => void` |
| historyRecords | history nodes records | `INode[][]` |
| setHistoryRecords | set historyRecords | `(records: INode[][]) => void` |
| activeHistoryRecordIndex | current index in history nodes records | `number` |
| setActiveHistoryRecordIndex | set activeHistoryRecordIndex | `(index: number) => void` |
| selectedNode | current selecred node | `INode \| undefined` |
| setSelectedNode | set selectedNode | `(node: INode \| undefined) => void` |
| drawerTitle | the title of Drawer | `string` |
| setDrawerTitle | set drawerTitle | `(title: string) => void` |
| dragType | dragged node type | `string` |
| setDragType | set dragType | `(type: string) => void` |

#### NodeContext

Get the data of the node where it is used. For details [Node](#node)

### Hooks

**Added since V1**

In the context of FlowBuilder the following hooks can be used

#### useAction

| Property | Description | Type | Version |
| :------------ | :-------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------ | :------ |
| clickNode | click node | `(node: INode = useContext(NodeContext)) => void` |
| addNode | add one node. (Get the current node through NodeContext when there is no node property) | `(node: INode, newNodeType: string) => void` \| `(newNodeType: string) => void` |
| addNodeInLoop | add one node in loop node. | `(newNodeType: string) => void` | 1.4.6 |
| removeNode | remove one node or more nodes. | `(targetNode: INode \| INode[] = useContext(NodeContext)) => void` |

#### useDrawer

| Property | Description | Type |
| :---------- | :------------------------------------------------------------------------------------------ | :----------------------------------------------------- |
| closeDrawer | close Drawer and clear selectedNode | `() => void` |
| saveDrawer | save the content in Drawer (same as the save method in [ConfigComponent](#configcomponent)) | `(values: any, validateStatusError?: boolean) => void` |

#### useZoom

| Property | Description | Type |
| :------- | :----------------------------------------------------------------------------------------- | :---------------------------------------- |
| minZoom | minimum zoom value | `number` |
| maxZoom | maximum zoom value | `number` |
| zoom | change zoom value (same as the zoom method in [FlowBuilderInstance](#flowbuilderinstance)) | `(type: 'out' \| 'in' \| number) => void` |

#### useHistory

| Property | Description | Type |
| :---------- | :------------------------------------------------------------------------------------- | :-------------------------------------------------------------- |
| maxLength | Maximum length of history nodes records | `number` |
| pushHistory | add history nodes record | `(record?: INode[] = useContext(BuilderContext).nodes) => void` |
| history | undo, redo (same as the history method in [FlowBuilderInstance](#flowbuilderinstance)) | `(type: 'undo' \| 'redo') => void` |

#### useSort

| Property | Description | Type | Version |
| :------- | :--------------- | :------------------------------------------------ | :------ |
| backward | sort to backward | `(node: INode = useContext(NodeContext)) => void` | 1.4.3 |
| forward | sort to forward | `(node: INode = useContext(NodeContext)) => void` | 1.4.3 |
| end | sort to end | `(node: INode = useContext(NodeContext)) => void` | 1.4.3 |
| start | sort to start | `(node: INode = useContext(NodeContext)) => void` | 1.4.3 |