-
Notifications
You must be signed in to change notification settings - Fork 177
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Canvas component and CanvasControls component
- Loading branch information
Antonio Russo
committed
Nov 25, 2020
1 parent
5d66b0f
commit cb64972
Showing
71 changed files
with
965 additions
and
1,092 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"presets": [ | ||
"@babel/preset-env", | ||
"@babel/preset-react" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { memo, ReactElement } from 'react'; | ||
|
||
export type PanState = { x: number, y: number }; | ||
|
||
export type CanvasProps = { | ||
/** | ||
* Since Canvas is a controlled component, the 'pan' prop defines the canvas panning | ||
*/ | ||
pan?: PanState, | ||
/** | ||
* Since Canvas is a controlled component, the 'onPanChange' prop is the change handler of the 'pan' prop | ||
*/ | ||
onPanChange?: (panState: PanState) => unknown, | ||
/** | ||
* Since Canvas is a controlled component, the 'zoom' prop defines its zoom level, aka: how much the canvas is scaling | ||
*/ | ||
zoom?: number, | ||
/** | ||
* Since Canvas is a controlled component, the 'onZoomChange' prop is the change handler of the 'zoom' prop | ||
*/ | ||
onZoomChange?: (zoom: number) => unknown, | ||
/** | ||
* Allow to zoom in/out on mouse wheel | ||
*/ | ||
zoomOnWheel?: boolean, | ||
/** | ||
* The maximum allowed zoom | ||
*/ | ||
maxZoom?: number, | ||
/** | ||
* The minimum allowed zoom | ||
*/ | ||
minZoom?: number, | ||
/** | ||
* Defines whether the zoom should be reset on double click | ||
*/ | ||
zoomResetOnDblClick?: boolean, | ||
/** | ||
* Defines whether the canvas should apply inertia when the drag is over | ||
*/ | ||
inertia?: boolean, | ||
/** | ||
* Displays debug info | ||
*/ | ||
debug?: boolean, | ||
GridRenderer?: ReactElement, | ||
ElementRenderer?: ReactElement, | ||
} | ||
|
||
|
||
declare const Canvas: (props: CanvasProps) => JSX.Element; | ||
|
||
export default memo(Canvas); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { memo, ElementType } from 'react'; | ||
import { PanState } from './Canvas'; | ||
|
||
|
||
export type CanvasControlsProps = { | ||
placement?: 'top-left' | 'top-right' | 'top-center' | 'bottom-right' | 'bottom-center' | 'bottom-left' | 'left' | 'right', | ||
alignment?: 'vertical' | 'horizontal', | ||
onPanChange?: (panState: PanState) => unknown, | ||
onZoomChange?: (zoom: PanState) => unknown, | ||
ButtonRender?: ElementType, | ||
ZoomInBtnRender?: ElementType, | ||
CenterBtnRender?: ElementType, | ||
ZoomOutBtnRender?: ElementType, | ||
ElementRender?: ElementType, | ||
} | ||
|
||
|
||
declare const CanvasControls: (props: CanvasControlsProps) => JSX.Element; | ||
|
||
export default memo(CanvasControls); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { PanState } from './Canvas'; | ||
|
||
|
||
export type CanvasMethods = { | ||
onPanChange: (panState: PanState) => unknown, | ||
onZoomChange: (zoom: number) => unknown, | ||
} | ||
|
||
export type CanvasStates = { | ||
pan: PanState, | ||
zoom: number, | ||
} | ||
|
||
declare const useCanvasState: (initialStates?: CanvasStates) => [CanvasStates, CanvasMethods]; | ||
|
||
export default useCanvasState; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
To start using the library import a `Canvas` and a `Diagram` component, both are [controlled components](https://reactjs.org/docs/forms.html#controlled-components) | ||
so you'll need to provide a [state](https://reactjs.org/docs/faq-state.html) and a [state handler](https://reactjs.org/docs/faq-state.html#how-do-i-update-state-with-values-that-depend-on-the-current-state) | ||
(*beautiful-react-diagrams* exports mainly controlled components). | ||
|
||
A *Diagram* component needs to be wrapped into a *Canvas* which allows panning/zooming functionality.<br /> | ||
|
||
A *Diagram* can easily be represented by a "*schema*" (the library provides a set of pre-made utilities to define and validate schemas). | ||
A "*schema*" is a plain object having, at least, a "*nodes*" property defined.<br /> | ||
|
||
The "*nodes*" property must be an array of tuples (objects) described by a unique "*id*" (if not provided the library will create a unique id for the node), | ||
a "*content*" property (can be a React component) and a "*coordinates*" property describing the node position. | ||
|
||
Optionally a "*links*" property can be defined to define links between the nodes, similar to the "*nodes*" property it must | ||
be an array of valid link describing tuples, a valid link must have an "*input*" and an "*output*" property. | ||
|
||
In order to avoid unnecessary complexity the `useSchema`, `useCanvasState` hooks have been provided together with the | ||
`createSchema` utility. | ||
|
||
```js | ||
import Diagram, { Canvas, createSchema, useSchema, useCanvasState, CanvasControls } from 'beautiful-react-diagrams'; | ||
|
||
// the diagram model | ||
const initialSchema = createSchema({ | ||
nodes: [ | ||
{ id: 'node-1', content: 'Hey Jude', coordinates: [312, 27], }, | ||
{ id: 'node-2', content: 'Don\'t', coordinates: [330, 90], }, | ||
{ id: 'node-3', content: 'be afraid', coordinates: [100, 320], }, | ||
{ id: 'node-4', content: 'let me down', coordinates: [306, 332], }, | ||
{ id: 'node-5', content: 'make it bad', coordinates: [515, 330], }, | ||
], | ||
links: [ | ||
{ input: 'node-1', output: 'node-2' }, | ||
{ input: 'node-2', output: 'node-3' }, | ||
{ input: 'node-2', output: 'node-4' }, | ||
{ input: 'node-2', output: 'node-5' }, | ||
] | ||
}); | ||
|
||
const DiagramExample = () => { | ||
const [canvasState, handlers] = useCanvasState(); // creates canvas state | ||
const [schema, { onChange }] = useSchema(initialSchema); // creates diagrams schema | ||
|
||
return ( | ||
<div style={{ height: '30rem' }}> | ||
<Canvas {...canvasState} {...handlers}> | ||
<Diagram schema={schema} onChange={onChange} /> | ||
<CanvasControls /> | ||
</Canvas> | ||
</div> | ||
); | ||
}; | ||
|
||
<DiagramExample /> | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
```js | ||
import Diagram, { Canvas, createSchema, useSchema, useCanvasState, CanvasControls } from 'beautiful-react-diagrams'; | ||
|
||
// the diagram model | ||
const initialSchema = createSchema({ | ||
nodes: [ | ||
{ id: 'node-1', content: 'Hey Jude', coordinates: [312, 27], }, | ||
{ id: 'node-2', content: 'Don\'t', coordinates: [330, 90], }, | ||
{ id: 'node-3', content: 'be afraid', coordinates: [100, 320], }, | ||
{ id: 'node-4', content: 'let me down', coordinates: [306, 332], }, | ||
{ id: 'node-5', content: 'make it bad', coordinates: [515, 330], }, | ||
], | ||
links: [ | ||
{ input: 'node-1', output: 'node-2' }, | ||
{ input: 'node-2', output: 'node-3' }, | ||
{ input: 'node-2', output: 'node-4' }, | ||
{ input: 'node-2', output: 'node-5' }, | ||
] | ||
}); | ||
|
||
const DiagramExample = () => { | ||
const [canvasState, handlers] = useCanvasState(); // creates canvas state | ||
const [schema, { onChange }] = useSchema(initialSchema); // creates diagrams schema | ||
|
||
return ( | ||
<div style={{ height: '30rem' }}> | ||
<Canvas {...canvasState} {...handlers}> | ||
<Diagram schema={schema} onChange={onChange} /> | ||
<CanvasControls alignment="horizontal" placement="bottom-center" /> | ||
</Canvas> | ||
</div> | ||
); | ||
}; | ||
|
||
<DiagramExample /> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
### Ports | ||
|
||
```js | ||
import Diagram, { Canvas, createSchema, useSchema, useCanvasState, CanvasControls } from 'beautiful-react-diagrams'; | ||
|
||
const initialSchema = createSchema({ | ||
nodes: [ | ||
{ | ||
id: 'node-1', | ||
content: 'Start', | ||
coordinates: [100, 150], | ||
outputs: [ | ||
{ id: 'port-1', alignment: 'right' }, | ||
{ id: 'port-2', alignment: 'right' }, | ||
], | ||
disableDrag: true, | ||
data: { | ||
foo: 'bar', | ||
count: 0, | ||
} | ||
}, | ||
{ | ||
id: 'node-2', | ||
content: 'Middle', | ||
coordinates: [300, 150], | ||
inputs: [ | ||
{ id: 'port-3', alignment: 'left' }, | ||
{ id: 'port-4', alignment: 'left' }, | ||
], | ||
outputs: [ | ||
{ id: 'port-5', alignment: 'right' }, | ||
{ id: 'port-6', alignment: 'right' }, | ||
], | ||
data: { | ||
bar: 'foo', | ||
} | ||
}, | ||
{ | ||
id: 'node-3', | ||
content: 'End', | ||
coordinates: [600, 150], | ||
inputs: [ | ||
{ id: 'port-7', alignment: 'left' }, | ||
{ id: 'port-8', alignment: 'left' }, | ||
], | ||
data: { | ||
foo: true, | ||
bar: false, | ||
some: { | ||
deep: { | ||
object: true, | ||
} | ||
}, | ||
} | ||
}, | ||
], | ||
links: [ | ||
{ input: 'port-1', output: 'port-4' }, | ||
] | ||
}); | ||
|
||
const UncontrolledDiagram = () => { | ||
const [canvasState, handlers] = useCanvasState(); // creates canvas state | ||
const [schema, { onChange }] = useSchema(initialSchema); // creates diagrams schema | ||
|
||
return ( | ||
<div style={{ height: '30rem' }}> | ||
<Canvas {...canvasState} {...handlers}> | ||
<Diagram schema={schema} onChange={onChange} /> | ||
<CanvasControls /> | ||
</Canvas> | ||
</div> | ||
); | ||
}; | ||
|
||
<UncontrolledDiagram /> | ||
``` | ||
|
||
### Readonly Links | ||
|
||
```js static | ||
import Diagram, { Canvas, createSchema, useSchema, useCanvasState, CanvasControls } from 'beautiful-react-diagrams'; | ||
|
||
// the diagram model | ||
const initialSchema = createSchema({ | ||
nodes: [ | ||
{ id: 'node-1', content: 'Hey Jude', coordinates: [312, 27], }, | ||
{ id: 'node-2', content: 'Don\'t', coordinates: [330, 90], }, | ||
{ id: 'node-3', content: 'be afraid', coordinates: [100, 320], }, | ||
{ id: 'node-4', content: 'let me down', coordinates: [306, 332], }, | ||
{ id: 'node-5', content: 'make it bad', coordinates: [515, 330], }, | ||
{ id: 'node-6', content: 'Take a sad song', coordinates: [295, 460], }, | ||
], | ||
links: [ | ||
{ input: 'node-1', output: 'node-2', readonly: true, className: 'my-custom-link-class' }, | ||
{ input: 'node-2', output: 'node-3', readonly: true }, | ||
{ input: 'node-2', output: 'node-4', readonly: true }, | ||
{ input: 'node-2', output: 'node-5', readonly: true }, | ||
{ input: 'node-3', output: 'node-6', readonly: true }, | ||
{ input: 'node-4', output: 'node-6', readonly: true }, | ||
{ input: 'node-5', output: 'node-6', readonly: true }, | ||
] | ||
}); | ||
|
||
const DiagramExample = () => { | ||
const [canvasState, handlers] = useCanvasState(); // creates canvas state | ||
const [schema, { onChange }] = useSchema(initialSchema); // creates diagrams schema | ||
|
||
return ( | ||
<div style={{ height: '35rem' }}> | ||
<Canvas {...canvasState} {...handlers}> | ||
<Diagram schema={schema} onChange={onChange} /> | ||
<CanvasControls /> | ||
</Canvas> | ||
</div> | ||
); | ||
}; | ||
|
||
<DiagramExample /> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.