@jeevandev/flow-canvas 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # Flow Canvas
2
+
3
+ A powerful, dual-mode React diagramming library that combines free-form design tools (like Canva) with structured node-based workflows
4
+
5
+ ![Demo](https://i.ibb.co/xSzsMgR0/flow.png) <!-- Replace with actual demo image if available -->
6
+
7
+ ## Features
8
+
9
+ - **Dual-Mode Engine**:
10
+ - **Design Mode**: Free-form resizing, rotating, and snapping for design elements.
11
+ - **Workflow Mode**: Structured nodes with handles and strict connection logic.
12
+ - **Infinite Canvas**: Zoomable, pannable, and virtually infinite workspace.
13
+ - **Performance Optimized**: Viewport culling (virtualization) for thousands of nodes and edges.
14
+ - **Customizable**: Fully stylable nodes and edges using standard CSS/SCSS.
15
+ - **Interactive**: Drag, drop, resize, rotate, and connect interactions built-in.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install flow-canvas
21
+ ```
22
+
23
+ ## Basic Usage
24
+
25
+ Wrap your application in the `Editor` context and render the `Canvas`.
26
+
27
+ ```tsx
28
+ import React from 'react';
29
+ import { Editor, Canvas, NodeLayer } from 'flow-canvas';
30
+ import 'flow-canvas/style.css'; // Import default styles
31
+
32
+ // 1. Define Nodes
33
+ const initialNodes = [
34
+ { id: '1', type: 'default', x: 100, y: 100, data: { label: 'Node A' } },
35
+ { id: '2', type: 'input', x: 400, y: 200, data: { label: 'Node B' } }
36
+ ];
37
+
38
+ // 2. Define Edges
39
+ const initialEdges = [
40
+ { id: 'e1', source: '1', target: '2' }
41
+ ];
42
+
43
+ const App = () => {
44
+ return (
45
+ <div style={{ width: '100vw', height: '100vh' }}>
46
+ <Editor initialNodes={initialNodes} initialEdges={initialEdges}>
47
+ <Canvas>
48
+ <NodeLayer />
49
+ </Canvas>
50
+ </Editor>
51
+ </div>
52
+ );
53
+ };
54
+ ```
55
+
56
+ ## Configuration
57
+
58
+ You can customize the editor behavior via the `config` prop:
59
+
60
+ ```tsx
61
+ <Editor
62
+ config={{
63
+ viewOnly: false,
64
+ pan: true,
65
+ zoom: true,
66
+ snapping: true,
67
+ showGrid: true,
68
+ gridSize: 20,
69
+ gridColor: '#e5e7eb',
70
+ snapGuide: true, // Visual alignment guides
71
+ isLimited: false, // Infinite canvas if false
72
+ }}
73
+ >
74
+ ...
75
+ </Editor>
76
+ ```
77
+
78
+ ## Creating Custom Nodes
79
+
80
+ ### Design Node (Resizable & Rotatable)
81
+ Any node with `resizable: true` or `rotatable: true` automatically gets the Design wrappers.
82
+
83
+ ```tsx
84
+ const nodes = [
85
+ {
86
+ id: 'design-1',
87
+ type: 'custom',
88
+ x: 100, y: 100,
89
+ width: 200, height: 200,
90
+ resizable: true,
91
+ rotatable: true,
92
+ doubleClickToEdit: true, // Prevents interaction until double-click
93
+ data: { ... }
94
+ }
95
+ ];
96
+ ```
97
+
98
+ ### Workflow Node (Logic & Connections)
99
+ Standard nodes usually just need handles.
100
+
101
+ ```tsx
102
+ // Custom Component
103
+ const MyNode = ({ data }) => {
104
+ return (
105
+ <div className="my-node">
106
+ <Handle type="target" position="left" />
107
+ {data.label}
108
+ <Handle type="source" position="right" />
109
+ </div>
110
+ );
111
+ };
112
+ ```
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1 @@
1
+ .ce-editor{position:relative;width:100%;height:100%;overflow:hidden;background-color:#f3f4f6}.ce-editor__canvas{position:absolute;top:0;left:0;width:100%;height:100%;touch-action:none;transform-origin:0 0}.ce-editor__viewport{width:100%;height:100%;overflow:hidden}.ce-editor__viewport--panning{cursor:grab!important}.ce-editor__viewport--panning *{pointer-events:none!important}.ce-editor__grid-layer{position:absolute;top:-50000px;left:-50000px;width:100000px;height:100000px;opacity:.5;pointer-events:none;z-index:0}.ce-editor__content-area{position:absolute;left:0;top:0;background-color:#fff;overflow:hidden;z-index:1;box-shadow:0 0 20px #0000001a}.ce-editor__infinite-area{position:relative;z-index:1}.ce-element{position:absolute;touch-action:none;-webkit-user-select:none;user-select:none;box-sizing:border-box;transition:box-shadow .1s}.ce-element--selected{outline:2px solid #3b82f6;outline-width:calc(2px * var(--ce-inverse-zoom, 1));box-shadow:0 0 0 calc(4px * var(--ce-inverse-zoom, 1)) #3b82f633;z-index:100!important}.ce-element img{pointer-events:none;-webkit-user-drag:none;-webkit-user-select:none;user-select:none}.ce-editor--connecting{cursor:crosshair!important}.ce-editor--connecting .ce-element:hover{outline:2px dashed #3b82f6;outline-width:calc(2px * var(--ce-inverse-zoom, 1));background-color:#3b82f60d;cursor:copy}.ce-editor--connecting .ce-handle:hover{transform:scale(1.5);background-color:#3b82f6!important;border-color:#fff!important;transition:transform .1s}.ce-resize-handle{width:calc(10px * var(--ce-inverse-zoom, 1));height:calc(10px * var(--ce-inverse-zoom, 1));background:#fff;border:calc(1px * var(--ce-inverse-zoom, 1)) solid #3b82f6;position:absolute;z-index:101}.ce-resize-handle--nw{top:calc(-6px * var(--ce-inverse-zoom, 1));left:calc(-6px * var(--ce-inverse-zoom, 1));cursor:nw-resize}.ce-resize-handle--ne{top:calc(-6px * var(--ce-inverse-zoom, 1));right:calc(-6px * var(--ce-inverse-zoom, 1));cursor:ne-resize}.ce-resize-handle--sw{bottom:calc(-6px * var(--ce-inverse-zoom, 1));left:calc(-6px * var(--ce-inverse-zoom, 1));cursor:sw-resize}.ce-resize-handle--se{bottom:calc(-6px * var(--ce-inverse-zoom, 1));right:calc(-6px * var(--ce-inverse-zoom, 1));cursor:se-resize}.ce-resize-handle--n{top:calc(-6px * var(--ce-inverse-zoom, 1));left:50%;transform:translate(-50%);cursor:n-resize}.ce-resize-handle--s{bottom:calc(-6px * var(--ce-inverse-zoom, 1));left:50%;transform:translate(-50%);cursor:s-resize}.ce-resize-handle--e{right:calc(-6px * var(--ce-inverse-zoom, 1));top:50%;transform:translateY(-50%);cursor:e-resize}.ce-resize-handle--w{left:calc(-6px * var(--ce-inverse-zoom, 1));top:50%;transform:translateY(-50%);cursor:w-resize}.ce-rotate-handle{width:calc(24px * var(--ce-inverse-zoom, 1));height:calc(24px * var(--ce-inverse-zoom, 1));background:#fff;border:none;box-shadow:0 2px 4px #0003;border-radius:50%;position:absolute;top:auto;bottom:calc(-35px * var(--ce-inverse-zoom, 1));left:50%;transform:translate(-50%);cursor:grab;z-index:101;display:flex;align-items:center;justify-content:center;color:#555}.ce-rotate-handle:after{display:none}.ce-rotate-handle:active{cursor:grabbing;background:#f3f4f6;color:#000}.ce-drag-handle-minimal{width:calc(24px * var(--ce-inverse-zoom, 1));height:calc(24px * var(--ce-inverse-zoom, 1));position:absolute;top:auto;bottom:calc(-35px * var(--ce-inverse-zoom, 1));left:calc(50% + calc(30px * var(--ce-inverse-zoom, 1)));transform:translate(-50%);background-color:#fff;border-radius:50%;box-shadow:0 2px 4px #0003;cursor:grab;z-index:102;display:flex;align-items:center;justify-content:center;color:#555;background-image:none}.ce-drag-handle-minimal:active{cursor:grabbing;background-color:#f3f4f6;color:#000}.ce-snap-guide{position:absolute;background-color:#f0f;pointer-events:none;z-index:200}.ce-snap-guide--vertical{width:1px;height:100vh}.ce-snap-guide--horizontal{height:1px;width:100vw}.ce-node-default,.ce-node-input,.ce-node-output{background:#fff;border:1px solid #777;border-radius:4px;padding:10px;min-width:180px;text-align:center;font-size:14px;color:#222;box-shadow:0 1px 4px #0000001a;position:relative}.ce-node-input{border-color:#3b82f6}.ce-node-output{border-color:#10b981}.ce-node-content{pointer-events:none}.ce-handle{width:10px;height:10px;background:#fff;border-radius:50%;position:absolute;border:3px solid #777;z-index:10;cursor:crosshair;transition:border-color .2s}.ce-handle--left{left:0;transform:translate(-50%)}.ce-handle--right{right:0;transform:translate(50%)}.ce-handle--top{top:0;transform:translateY(-50%)}.ce-handle--bottom{bottom:0;transform:translateY(50%)}.ce-workflow-node:hover .ce-delete-node-btn{opacity:1;pointer-events:auto}.ce-delete-node-btn{position:absolute;top:-8px;right:-8px;width:18px;height:18px;background:#ff4d4f;color:#fff;border:none;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;line-height:1;padding:0;z-index:20;opacity:0;pointer-events:none;transition:opacity .2s,transform .1s;box-shadow:0 2px 4px #0000001a}.ce-delete-node-btn:hover{transform:scale(1.1);background:#ff7875}.ce-edge-group .ce-edge-delete-fo{opacity:0;pointer-events:none;transition:opacity .2s}.ce-edge-group:hover .ce-edge-delete-fo{opacity:1;pointer-events:auto}.ce-connection-line{animation:dashdraw .5s linear infinite}@keyframes dashdraw{0%{stroke-dashoffset:10}to{stroke-dashoffset:0}}