f1ow 0.1.0 → 0.1.2
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 +76 -45
- package/dist/components/StylePanel/ui.d.ts +82 -0
- package/dist/components/Toolbar/Toolbar.d.ts +1 -0
- package/dist/f1ow.js +9798 -0
- package/dist/f1ow.umd.cjs +66 -0
- package/dist/lib/FlowCanvasProps.d.ts +46 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/utils/elbowWorkerManager.d.ts +6 -1
- package/dist/utils/exportWorkerManager.d.ts +9 -2
- package/dist/utils/workerFactory.d.ts +38 -0
- package/package.json +15 -7
- package/dist/assets/elbowWorker-CUBh1uET.js +0 -1
- package/dist/assets/exportWorker-hU9uNZXJ.js +0 -8
- package/dist/assets/syncWorker.worker-CnlpNZ3k.js +0 -6
- package/dist/f1ow-canvas.js +0 -37725
- package/dist/f1ow-canvas.umd.cjs +0 -371
package/README.md
CHANGED
|
@@ -1,61 +1,90 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<h1 align="center">f1ow
|
|
2
|
+
<h1 align="center">f1ow</h1>
|
|
3
3
|
<p align="center">
|
|
4
4
|
Interactive canvas drawing toolkit built on <strong>KonvaJS</strong> — drop-in React component for any project.
|
|
5
5
|
</p>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
|
-
<a href="https://www.npmjs.com/package/f1ow
|
|
10
|
-
<a href="https://www.npmjs.com/package/f1ow
|
|
11
|
-
<a href="https://github.com/nuumz/f1ow-canvas/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/f1ow
|
|
9
|
+
<a href="https://www.npmjs.com/package/f1ow"><img src="https://img.shields.io/npm/v/f1ow.svg" alt="npm version"></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/f1ow"><img src="https://img.shields.io/npm/dm/f1ow.svg" alt="npm downloads"></a>
|
|
11
|
+
<a href="https://github.com/nuumz/f1ow-canvas/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/f1ow.svg" alt="license"></a>
|
|
12
12
|
<a href="https://github.com/nuumz/f1ow-canvas"><img src="https://img.shields.io/badge/TypeScript-strict-blue.svg" alt="TypeScript"></a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="assets/preview.png" alt="f1ow preview" width="800" />
|
|
17
|
+
</p>
|
|
18
|
+
|
|
15
19
|
---
|
|
16
20
|
|
|
17
|
-
## Features
|
|
18
|
-
|
|
19
|
-
- **10 Drawing Tools** — Rectangle, Ellipse, Diamond, Line, Arrow, Free Draw, Text, Image, Eraser
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **Pan & Zoom** — Hand tool, scroll-wheel, trackpad pinch, zoom-to-fit
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
## Installation
|
|
21
|
+
## ✨ Features
|
|
22
|
+
|
|
23
|
+
- **10 Drawing Tools** — Rectangle, Ellipse, Diamond, Line, Arrow, Free Draw, Text, Image, Eraser.
|
|
24
|
+
- **Smart Connectors** — Arrows and lines snap to shapes with auto-routing (sharp, curved, elbow).
|
|
25
|
+
- **11 Arrowhead Variants** — Triangle, circle, diamond, bar, crow's foot (ERD), and more.
|
|
26
|
+
- **Selection & Transform** — Click, drag, resize, rotate, multi-select, group/ungroup, lock/unlock.
|
|
27
|
+
- **Pan & Zoom** — Hand tool, scroll-wheel, trackpad pinch, zoom-to-fit, zoom-to-selection.
|
|
28
|
+
- **Rich Styling** — Stroke, fill, width, dash, opacity, roughness, fonts.
|
|
29
|
+
- **Customizable UI** — Floating toolbar (top/bottom/hidden), style panel, context menu.
|
|
30
|
+
- **Undo / Redo** — 100-step history snapshot system.
|
|
31
|
+
- **Export** — Export canvas to PNG, SVG, or JSON.
|
|
32
|
+
- **Real-Time Collaboration** — Optional CRDT via Yjs (experimental) with cursor presence.
|
|
33
|
+
- **Fully Themeable** — Dark mode, custom colors, all via props.
|
|
34
|
+
- **Zero CSS Dependencies** — No external stylesheets required. Inline styled.
|
|
35
|
+
- **TypeScript** — Full type safety with strict mode.
|
|
36
|
+
|
|
37
|
+
## 📦 Installation
|
|
35
38
|
|
|
36
39
|
```bash
|
|
37
|
-
npm install f1ow
|
|
40
|
+
npm install f1ow
|
|
41
|
+
# or
|
|
42
|
+
pnpm add f1ow
|
|
43
|
+
# or
|
|
44
|
+
yarn add f1ow
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> **Peer dependencies:** `react` (≥17), `react-dom` (≥17), `konva` (≥9), `react-konva` (≥18), `zustand` (≥5)
|
|
48
|
+
|
|
49
|
+
### Next.js / Non-Vite Bundlers
|
|
50
|
+
|
|
51
|
+
f1ow-canvas uses Web Workers for performance-intensive operations. When using Next.js, Webpack, or other non-Vite bundlers, workers auto-fallback to synchronous mode. For optimal performance on large canvases, see the [Next.js Integration Guide](docs/NEXTJS_INTEGRATION.md).
|
|
52
|
+
|
|
53
|
+
**TL;DR:**
|
|
54
|
+
- **No config needed** — auto-fallback works out of the box.
|
|
55
|
+
- **For better performance** — copy worker files to `public/` and pass `workerConfig` prop.
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
<FlowCanvas
|
|
59
|
+
workerConfig={{
|
|
60
|
+
elbowWorkerUrl: '/workers/elbowWorker.js',
|
|
61
|
+
exportWorkerUrl: '/workers/exportWorker.js',
|
|
62
|
+
}}
|
|
63
|
+
/>
|
|
38
64
|
```
|
|
39
65
|
|
|
40
|
-
|
|
66
|
+
See the [integration guide](docs/NEXTJS_INTEGRATION.md) for detailed setup instructions.
|
|
41
67
|
|
|
42
|
-
## Quick Start
|
|
68
|
+
## 🚀 Quick Start
|
|
43
69
|
|
|
44
70
|
```tsx
|
|
45
|
-
import { FlowCanvas } from "f1ow
|
|
71
|
+
import { FlowCanvas } from "f1ow";
|
|
46
72
|
|
|
47
73
|
function App() {
|
|
48
74
|
return (
|
|
49
75
|
<div style={{ width: "100vw", height: "100vh" }}>
|
|
50
|
-
<FlowCanvas
|
|
76
|
+
<FlowCanvas
|
|
77
|
+
onChange={(elements) => console.log('Canvas updated:', elements)}
|
|
78
|
+
toolbarPosition="bottom"
|
|
79
|
+
/>
|
|
51
80
|
</div>
|
|
52
81
|
);
|
|
53
82
|
}
|
|
54
83
|
```
|
|
55
84
|
|
|
56
|
-
That's it — you get a full-featured canvas editor with toolbar, style panel, keyboard shortcuts, and grid out of the box.
|
|
85
|
+
That's it — you get a full-featured canvas editor with a toolbar, style panel, keyboard shortcuts, and grid out of the box.
|
|
57
86
|
|
|
58
|
-
## Props
|
|
87
|
+
## ⚙️ Props
|
|
59
88
|
|
|
60
89
|
| Prop | Type | Default | Description |
|
|
61
90
|
| --- | --- | --- | --- |
|
|
@@ -68,8 +97,9 @@ That's it — you get a full-featured canvas editor with toolbar, style panel, k
|
|
|
68
97
|
| `onElementDoubleClick` | `(id, element) => boolean` | — | Return `true` to prevent default |
|
|
69
98
|
| `width` / `height` | `number \| string` | `'100%'` | Canvas dimensions |
|
|
70
99
|
| `tools` | `ToolType[]` | all | Visible tools in toolbar |
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
100
|
+
| `defaultTool` | `ToolType` | `'select'` | Default active tool on mount |
|
|
101
|
+
| `toolbarPosition` | `'top' \| 'bottom' \| 'hidden'` | `'bottom'` | Position of the main toolbar |
|
|
102
|
+
| `showToolbar` | `boolean` | `true` | Show toolbar (legacy, use `toolbarPosition`) |
|
|
73
103
|
| `showStylePanel` | `boolean` | `true` | Show style panel |
|
|
74
104
|
| `showStatusBar` | `boolean` | `true` | Show status bar |
|
|
75
105
|
| `showGrid` | `boolean` | `true` | Show grid |
|
|
@@ -80,14 +110,15 @@ That's it — you get a full-featured canvas editor with toolbar, style panel, k
|
|
|
80
110
|
| `contextMenuItems` | `ContextMenuItem[]` or `(ctx) => ContextMenuItem[]` | — | Extra context menu items |
|
|
81
111
|
| `renderContextMenu` | `(ctx) => ReactNode` | — | Replace built-in context menu |
|
|
82
112
|
| `collaboration` | `CollaborationConfig` | — | Enable real-time collaboration |
|
|
113
|
+
| `workerConfig` | `{ elbowWorkerUrl?: string, exportWorkerUrl?: string, disabled?: boolean }` | — | Worker URLs for Next.js ([docs](docs/NEXTJS_INTEGRATION.md)) |
|
|
83
114
|
|
|
84
|
-
## Ref API
|
|
115
|
+
## 🕹️ Ref API
|
|
85
116
|
|
|
86
117
|
Control the canvas programmatically via `ref`:
|
|
87
118
|
|
|
88
119
|
```tsx
|
|
89
120
|
import { useRef } from "react";
|
|
90
|
-
import type { FlowCanvasRef } from "f1ow
|
|
121
|
+
import type { FlowCanvasRef } from "f1ow";
|
|
91
122
|
|
|
92
123
|
const ref = useRef<FlowCanvasRef>(null);
|
|
93
124
|
|
|
@@ -115,7 +146,7 @@ const ref = useRef<FlowCanvasRef>(null);
|
|
|
115
146
|
| `importJSON(json)` | — | Load from JSON |
|
|
116
147
|
| `getStage()` | `Konva.Stage` | Raw Konva stage access |
|
|
117
148
|
|
|
118
|
-
## Keyboard Shortcuts
|
|
149
|
+
## ⌨️ Keyboard Shortcuts
|
|
119
150
|
|
|
120
151
|
`⌘` = Cmd (Mac) / Ctrl (Windows/Linux)
|
|
121
152
|
|
|
@@ -128,7 +159,7 @@ const ref = useRef<FlowCanvasRef>(null);
|
|
|
128
159
|
| `D` Diamond | `E` Eraser | `Del` Delete | `⌘⇧L` Lock toggle |
|
|
129
160
|
| `L` Line | `G` Grid | `⌘+/-/0` Zoom | `⌘]/[` Layer order |
|
|
130
161
|
|
|
131
|
-
## Theming
|
|
162
|
+
## 🎨 Theming
|
|
132
163
|
|
|
133
164
|
```tsx
|
|
134
165
|
<FlowCanvas
|
|
@@ -148,7 +179,7 @@ const ref = useRef<FlowCanvasRef>(null);
|
|
|
148
179
|
|
|
149
180
|
All properties are optional — only override what you need.
|
|
150
181
|
|
|
151
|
-
## Context Menu
|
|
182
|
+
## 🖱️ Context Menu
|
|
152
183
|
|
|
153
184
|
Append custom items or fully replace the built-in menu:
|
|
154
185
|
|
|
@@ -166,7 +197,7 @@ Append custom items or fully replace the built-in menu:
|
|
|
166
197
|
/>
|
|
167
198
|
```
|
|
168
199
|
|
|
169
|
-
## Collaboration (Experimental)
|
|
200
|
+
## 🤝 Collaboration (Experimental)
|
|
170
201
|
|
|
171
202
|
```tsx
|
|
172
203
|
<FlowCanvas
|
|
@@ -180,19 +211,19 @@ Append custom items or fully replace the built-in menu:
|
|
|
180
211
|
|
|
181
212
|
Provides CRDT-based real-time sync with cursor presence overlay. Requires a [Yjs WebSocket server](https://github.com/yjs/y-websocket).
|
|
182
213
|
|
|
183
|
-
## Element Types
|
|
214
|
+
## 🧩 Element Types
|
|
184
215
|
|
|
185
216
|
`CanvasElement` is a discriminated union of 8 types:
|
|
186
217
|
|
|
187
|
-
**Shapes** — `rectangle`, `ellipse`, `diamond`
|
|
188
|
-
**Connectors** — `line`, `arrow` (with bindings, routing, arrowheads)
|
|
189
|
-
**Content** — `text`, `image`, `freedraw`
|
|
218
|
+
- **Shapes** — `rectangle`, `ellipse`, `diamond`
|
|
219
|
+
- **Connectors** — `line`, `arrow` (with bindings, routing, arrowheads)
|
|
220
|
+
- **Content** — `text`, `image`, `freedraw`
|
|
190
221
|
|
|
191
222
|
All elements share: `id`, `x`, `y`, `width`, `height`, `rotation`, `style`, `isLocked`, `isVisible`, `boundElements`, `groupIds`.
|
|
192
223
|
|
|
193
224
|
> Full type definitions are bundled in the package `.d.ts` files.
|
|
194
225
|
|
|
195
|
-
## Development
|
|
226
|
+
## 🛠️ Development
|
|
196
227
|
|
|
197
228
|
```bash
|
|
198
229
|
pnpm install # Install dependencies
|
|
@@ -201,10 +232,10 @@ pnpm build:lib # Build library → dist/
|
|
|
201
232
|
pnpm typecheck # Type check (strict)
|
|
202
233
|
```
|
|
203
234
|
|
|
204
|
-
## Browser Support
|
|
235
|
+
## 🌐 Browser Support
|
|
205
236
|
|
|
206
237
|
Chrome/Edge ≥ 80 · Firefox ≥ 78 · Safari ≥ 14
|
|
207
238
|
|
|
208
|
-
## License
|
|
239
|
+
## 📄 License
|
|
209
240
|
|
|
210
|
-
[MIT](LICENSE) © [
|
|
241
|
+
[MIT](LICENSE) © [Nuumz](https://github.com/nuumz)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { FlowCanvasTheme } from '../../lib/FlowCanvasProps';
|
|
3
|
+
export interface PanelButtonProps {
|
|
4
|
+
/** Theme for color tokens */
|
|
5
|
+
theme: FlowCanvasTheme;
|
|
6
|
+
/**
|
|
7
|
+
* 'toggle' (default) — highlights with border + tinted bg when `isActive`
|
|
8
|
+
* 'action' — no active state; hover-only background tint
|
|
9
|
+
*/
|
|
10
|
+
variant?: 'toggle' | 'action';
|
|
11
|
+
/** Active / selected state (used in toggle variant) */
|
|
12
|
+
isActive?: boolean;
|
|
13
|
+
/** When hovered, use danger (red) color instead of accent */
|
|
14
|
+
dangerHover?: boolean;
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
title?: string;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
width?: number | string;
|
|
19
|
+
height?: number;
|
|
20
|
+
style?: React.CSSProperties;
|
|
21
|
+
/**
|
|
22
|
+
* Children may be a render-prop that receives `isHighlighted` so icons
|
|
23
|
+
* can change colour on hover/active without needing external hover state.
|
|
24
|
+
*
|
|
25
|
+
* `isHighlighted` is true when the button is hovered OR active.
|
|
26
|
+
*/
|
|
27
|
+
children: React.ReactNode | ((isHighlighted: boolean) => React.ReactNode);
|
|
28
|
+
}
|
|
29
|
+
export declare const PanelButton: React.FC<PanelButtonProps>;
|
|
30
|
+
/** Computed icon color helper — use inside PanelButton's render-prop children */
|
|
31
|
+
export declare const iconColor: (isHighlighted: boolean, theme: FlowCanvasTheme, options?: {
|
|
32
|
+
danger?: boolean;
|
|
33
|
+
isActive?: boolean;
|
|
34
|
+
}) => string;
|
|
35
|
+
export interface PanelTextButtonProps {
|
|
36
|
+
theme: FlowCanvasTheme;
|
|
37
|
+
isActive?: boolean;
|
|
38
|
+
onClick?: () => void;
|
|
39
|
+
title?: string;
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
flex?: number | string;
|
|
42
|
+
width?: number | string;
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
style?: React.CSSProperties;
|
|
45
|
+
}
|
|
46
|
+
export declare const PanelTextButton: React.FC<PanelTextButtonProps>;
|
|
47
|
+
export interface PanelSectionProps {
|
|
48
|
+
theme: FlowCanvasTheme;
|
|
49
|
+
/** Section label rendered as small bold uppercase caption */
|
|
50
|
+
label?: string;
|
|
51
|
+
/** Optional element rendered on the right side of the header (e.g. a dropdown) */
|
|
52
|
+
headerAction?: React.ReactNode;
|
|
53
|
+
/** Section body content — can be omitted for header-only sections */
|
|
54
|
+
children?: React.ReactNode;
|
|
55
|
+
style?: React.CSSProperties;
|
|
56
|
+
}
|
|
57
|
+
export declare const PanelSection: React.FC<PanelSectionProps>;
|
|
58
|
+
export declare const ButtonRow: React.FC<{
|
|
59
|
+
children: React.ReactNode;
|
|
60
|
+
gap?: number;
|
|
61
|
+
wrap?: boolean;
|
|
62
|
+
style?: React.CSSProperties;
|
|
63
|
+
}>;
|
|
64
|
+
export interface CompactPickerOption {
|
|
65
|
+
value: string | number;
|
|
66
|
+
/** Icon render-prop that receives the current display color */
|
|
67
|
+
icon: React.ReactNode | ((color: string) => React.ReactNode);
|
|
68
|
+
label: string;
|
|
69
|
+
}
|
|
70
|
+
export interface CompactDropdownPickerProps {
|
|
71
|
+
options: CompactPickerOption[];
|
|
72
|
+
value: string | number;
|
|
73
|
+
onChange: (value: string | number) => void;
|
|
74
|
+
theme: FlowCanvasTheme;
|
|
75
|
+
label: string;
|
|
76
|
+
isOpen: boolean;
|
|
77
|
+
onToggle: () => void;
|
|
78
|
+
pickerRef: React.RefObject<HTMLDivElement | null>;
|
|
79
|
+
/** Number of columns in the dropdown grid. Defaults to all items in a single row. */
|
|
80
|
+
columns?: number;
|
|
81
|
+
}
|
|
82
|
+
export declare const CompactDropdownPicker: React.FC<CompactDropdownPickerProps>;
|