canvu-react 0.3.5
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/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/camera-BwQjm5oh.d.cts +50 -0
- package/dist/camera-KwCYYPhm.d.ts +50 -0
- package/dist/chatbot.cjs +221 -0
- package/dist/chatbot.cjs.map +1 -0
- package/dist/chatbot.d.cts +36 -0
- package/dist/chatbot.d.ts +36 -0
- package/dist/chatbot.js +218 -0
- package/dist/chatbot.js.map +1 -0
- package/dist/index.cjs +1920 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +276 -0
- package/dist/index.d.ts +276 -0
- package/dist/index.js +1867 -0
- package/dist/index.js.map +1 -0
- package/dist/native.cjs +2572 -0
- package/dist/native.cjs.map +1 -0
- package/dist/native.d.cts +217 -0
- package/dist/native.d.ts +217 -0
- package/dist/native.js +2562 -0
- package/dist/native.js.map +1 -0
- package/dist/react.cjs +8540 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +481 -0
- package/dist/react.d.ts +481 -0
- package/dist/react.js +8492 -0
- package/dist/react.js.map +1 -0
- package/dist/realtime.cjs +2338 -0
- package/dist/realtime.cjs.map +1 -0
- package/dist/realtime.d.cts +309 -0
- package/dist/realtime.d.ts +309 -0
- package/dist/realtime.js +2317 -0
- package/dist/realtime.js.map +1 -0
- package/dist/shape-builders-DTYvub8W.d.ts +93 -0
- package/dist/shape-builders-DxPoOecg.d.cts +93 -0
- package/dist/tldraw.cjs +1948 -0
- package/dist/tldraw.cjs.map +1 -0
- package/dist/tldraw.d.cts +98 -0
- package/dist/tldraw.d.ts +98 -0
- package/dist/tldraw.js +1941 -0
- package/dist/tldraw.js.map +1 -0
- package/dist/types--ALu1mF-.d.ts +356 -0
- package/dist/types-B58i5k-u.d.cts +35 -0
- package/dist/types-CB0TZZuk.d.cts +157 -0
- package/dist/types-CB0TZZuk.d.ts +157 -0
- package/dist/types-D1ftVsOQ.d.cts +356 -0
- package/dist/types-DgEArHkA.d.ts +35 -0
- package/package.json +103 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, RefObject } from 'react';
|
|
3
|
+
import { R as Rect, V as VectorSceneItem } from './types-CB0TZZuk.js';
|
|
4
|
+
import { C as Camera2D } from './camera-KwCYYPhm.js';
|
|
5
|
+
|
|
6
|
+
type PlacementPreview = {
|
|
7
|
+
kind: "rect" | "ellipse";
|
|
8
|
+
rect: Rect;
|
|
9
|
+
}
|
|
10
|
+
/** Multi-select drag (world rect), like image crop / rubber-band selection. */
|
|
11
|
+
| {
|
|
12
|
+
kind: "marquee";
|
|
13
|
+
rect: Rect;
|
|
14
|
+
} | {
|
|
15
|
+
kind: "line" | "arrow";
|
|
16
|
+
start: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
};
|
|
20
|
+
end: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
25
|
+
kind: "stroke";
|
|
26
|
+
tool: "draw" | "marker" | "laser";
|
|
27
|
+
points: {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
}[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Describes one entry in {@link VectorToolbar}.
|
|
35
|
+
*/
|
|
36
|
+
type VectorToolDefinition = {
|
|
37
|
+
/** Stable id passed to `onChange` (e.g. `"hand"`, `"rect"`). */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Visible label and default accessible name. */
|
|
40
|
+
label: string;
|
|
41
|
+
/**
|
|
42
|
+
* English (or other) name for the hover tooltip only. Defaults to {@link label}.
|
|
43
|
+
*/
|
|
44
|
+
tooltipLabel?: string;
|
|
45
|
+
/** Optional icon; if omitted, the label text is shown. */
|
|
46
|
+
icon?: ReactNode;
|
|
47
|
+
/** Shown in `aria-keyshortcuts` when set (informational only). */
|
|
48
|
+
shortcutHint?: string;
|
|
49
|
+
/** Extra `aria-label` when you need more than `label`. */
|
|
50
|
+
ariaLabel?: string;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
type RealtimeConnectionState = "connecting" | "connected" | "reconnecting" | "offline" | "error";
|
|
54
|
+
/**
|
|
55
|
+
* In-progress freehand stroke from a remote peer (before it becomes a committed `VectorSceneItem`).
|
|
56
|
+
*/
|
|
57
|
+
type RemotePresenceMarkupStroke = {
|
|
58
|
+
readonly points: readonly {
|
|
59
|
+
readonly x: number;
|
|
60
|
+
readonly y: number;
|
|
61
|
+
}[];
|
|
62
|
+
readonly tool: "draw" | "pencil" | "brush" | "marker" | "laser";
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* One connected participant. Your WebSocket layer maps server messages → this shape;
|
|
66
|
+
* {@link VectorViewport} renders it in world space.
|
|
67
|
+
*/
|
|
68
|
+
type RemotePresencePeer = {
|
|
69
|
+
readonly id: string;
|
|
70
|
+
/** Stable color for cursor + stroke (e.g. `#2563eb`). If omitted, a hue is derived from `id`. */
|
|
71
|
+
readonly color?: string;
|
|
72
|
+
/** Short display name near the cursor. */
|
|
73
|
+
readonly displayName?: string;
|
|
74
|
+
/** Optional profile image / avatar URL for richer collaboration UIs. */
|
|
75
|
+
readonly image?: string;
|
|
76
|
+
/** Last known pointer position in **world** units, or `null` if off-canvas / idle. */
|
|
77
|
+
readonly cursor: {
|
|
78
|
+
readonly x: number;
|
|
79
|
+
readonly y: number;
|
|
80
|
+
} | null;
|
|
81
|
+
/** Optional live stroke while the peer is drawing (same semantics as local placement preview). */
|
|
82
|
+
readonly markupStroke?: RemotePresenceMarkupStroke | null;
|
|
83
|
+
/** Connection-scoped id when collaboration is backed by a realtime session. */
|
|
84
|
+
readonly clientId?: string;
|
|
85
|
+
/** Stable participant identity when collaboration is backed by a realtime session. */
|
|
86
|
+
readonly peerId?: string;
|
|
87
|
+
/** Room/session id when provided by the collaboration transport. */
|
|
88
|
+
readonly roomId?: string;
|
|
89
|
+
/** Lifecycle timestamps in epoch milliseconds. */
|
|
90
|
+
readonly joinedAt?: number;
|
|
91
|
+
readonly lastSeenAt?: number;
|
|
92
|
+
/** Distinguishes the local participant from remote peers. */
|
|
93
|
+
readonly isSelf?: boolean;
|
|
94
|
+
/** Optional active tool hint for richer presence UIs. */
|
|
95
|
+
readonly activeTool?: string;
|
|
96
|
+
/** Session-level connection state, useful for richer rosters. */
|
|
97
|
+
readonly connectionState?: RealtimeConnectionState;
|
|
98
|
+
};
|
|
99
|
+
type PresenceOverlayRenderContext = {
|
|
100
|
+
camera: Camera2D;
|
|
101
|
+
/** Bumps when the camera changes so overlays stay aligned with the scene. */
|
|
102
|
+
cameraVersion: number;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
type WorldPointerDownDetail = {
|
|
106
|
+
worldX: number;
|
|
107
|
+
worldY: number;
|
|
108
|
+
toolId: string;
|
|
109
|
+
pointerType: string;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Imperative API for pan/zoom and integrations (e.g. AI agents following a region).
|
|
113
|
+
* Call {@link requestRender} after mutating the {@link Camera2D} from {@link getCamera}.
|
|
114
|
+
*/
|
|
115
|
+
type VectorViewportHandle = {
|
|
116
|
+
/** The live camera instance, or `null` before mount / after unmount. */
|
|
117
|
+
getCamera: () => Camera2D | null;
|
|
118
|
+
/**
|
|
119
|
+
* Re-run SVG + overlay after changing `x`, `y`, or `zoom` on the camera from {@link getCamera}.
|
|
120
|
+
*/
|
|
121
|
+
requestRender: () => void;
|
|
122
|
+
/** CSS pixel size of the scene surface (`clientWidth` / `clientHeight`). */
|
|
123
|
+
getViewportSize: () => {
|
|
124
|
+
width: number;
|
|
125
|
+
height: number;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Sets pan/zoom so `worldRect` fits in the viewport with optional margin (fraction of rect size per side, default `0.08`).
|
|
129
|
+
*/
|
|
130
|
+
fitWorldRect: (worldRect: Rect, options?: {
|
|
131
|
+
padding?: number;
|
|
132
|
+
}) => void;
|
|
133
|
+
};
|
|
134
|
+
/** Drag-to-place a custom shape (same interaction as rectangle). Use with `createCustomShapeItem` from `canvu`. */
|
|
135
|
+
type CustomShapePlacementOptions = {
|
|
136
|
+
toolId: string;
|
|
137
|
+
createItem: (args: {
|
|
138
|
+
id: string;
|
|
139
|
+
bounds: Rect;
|
|
140
|
+
}) => VectorSceneItem;
|
|
141
|
+
};
|
|
142
|
+
type VectorViewportProps = {
|
|
143
|
+
/** Vector items to draw (SVG fragments). */
|
|
144
|
+
items: readonly VectorSceneItem[];
|
|
145
|
+
className?: string;
|
|
146
|
+
/** Accessible name for the application region. */
|
|
147
|
+
ariaLabel: string;
|
|
148
|
+
/**
|
|
149
|
+
* When `applePencilNav` is true, used with `attachApplePencilNavigation` to decide
|
|
150
|
+
* when finger touches navigate (e.g. `"hand"` vs `"draw"`).
|
|
151
|
+
*/
|
|
152
|
+
toolId?: string;
|
|
153
|
+
/** Enable Apple Pencil vs finger split (optional). */
|
|
154
|
+
applePencilNav?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* When true, selection, drag-to-move, resize handles, and drag-to-create shapes are enabled.
|
|
157
|
+
* Requires `onItemsChange` to persist mutations.
|
|
158
|
+
*/
|
|
159
|
+
interactive?: boolean;
|
|
160
|
+
/** Selected item ids (order preserved). Empty = none. */
|
|
161
|
+
selectedIds?: readonly string[];
|
|
162
|
+
onSelectionChange?: (ids: string[]) => void;
|
|
163
|
+
onItemsChange?: (items: VectorSceneItem[]) => void;
|
|
164
|
+
/**
|
|
165
|
+
* Fires on primary pointer down on the viewport in **world** coordinates.
|
|
166
|
+
* Not called when `toolId` is `"hand"` (use that tool for panning).
|
|
167
|
+
* Ignored when `interactive` is true (placement uses drag-to-define).
|
|
168
|
+
*/
|
|
169
|
+
onWorldPointerDown?: (detail: WorldPointerDownDetail) => void;
|
|
170
|
+
/**
|
|
171
|
+
* Floating UI above the scene. Compose with `VectorCanvas.Toolbar` + {@link VectorToolbar}
|
|
172
|
+
* so the strip anchors at the bottom center (`data-slot="vector-canvas-toolbar"`).
|
|
173
|
+
*/
|
|
174
|
+
toolbar?: ReactNode;
|
|
175
|
+
/**
|
|
176
|
+
* Floating bottom-left zoom / undo / minimap bar. Omit to render the default `NavMenu`.
|
|
177
|
+
* Pass `<VectorCanvas.NavMenu position="..." />` to relocate or style it. Pass `null` to hide it.
|
|
178
|
+
*/
|
|
179
|
+
navMenu?: ReactNode | null;
|
|
180
|
+
/**
|
|
181
|
+
* Floating selection / active-tool style inspector. Omit to render the default `VectorSelectionInspector`.
|
|
182
|
+
* Pass `<VectorCanvas.SelectionInspector position="..." />` to relocate or style it. Pass `null` to hide it.
|
|
183
|
+
*/
|
|
184
|
+
selectionInspector?: ReactNode | null;
|
|
185
|
+
/**
|
|
186
|
+
* Plug and play board extensions.
|
|
187
|
+
*
|
|
188
|
+
* First-party plugins such as `chatbotPlugin(...)` and `realtimeCollaborationPlugin(...)`
|
|
189
|
+
* should be passed here. Advanced authors can create their own plugins with `createCanvuPlugin(...)`.
|
|
190
|
+
*/
|
|
191
|
+
plugins?: readonly CanvasPlugin[];
|
|
192
|
+
/**
|
|
193
|
+
* Called after the scene/camera redraw (pan, zoom, items update, or {@link VectorViewportHandle.requestRender}).
|
|
194
|
+
* Can fire often during gestures — throttle/debounce if needed.
|
|
195
|
+
*/
|
|
196
|
+
onCameraChange?: () => void;
|
|
197
|
+
/**
|
|
198
|
+
* When `interactive` is true, enables drag (or tap) placement for `toolId`, like built-in shapes.
|
|
199
|
+
* Implement `createItem` with `createCustomShapeItem` from `canvu`.
|
|
200
|
+
*/
|
|
201
|
+
customPlacement?: CustomShapePlacementOptions;
|
|
202
|
+
/**
|
|
203
|
+
* Multiple custom placements contributed by plugins or app code.
|
|
204
|
+
*
|
|
205
|
+
* When both `customPlacement` and `customPlacements` are provided, they are combined and the active
|
|
206
|
+
* placement is resolved by the current `toolId`.
|
|
207
|
+
*/
|
|
208
|
+
customPlacements?: readonly CustomShapePlacementOptions[];
|
|
209
|
+
/**
|
|
210
|
+
* When false (default), finishing a draw/place/erase gesture requests switching back to `autoResetToolTo`.
|
|
211
|
+
* Use with controlled tool state (`onToolChangeRequest`) to keep "select-after-use" behavior.
|
|
212
|
+
*/
|
|
213
|
+
toolLocked?: boolean;
|
|
214
|
+
/** Tool id requested after one-shot actions complete. Default `"select"`. */
|
|
215
|
+
autoResetToolTo?: string;
|
|
216
|
+
/** Called when viewport requests a tool change (e.g. auto reset to select). */
|
|
217
|
+
onToolChangeRequest?: (toolId: string) => void;
|
|
218
|
+
/**
|
|
219
|
+
* Remote participants (cursors + optional in-progress strokes). Renders a world-space overlay
|
|
220
|
+
* below the local interaction layer. Transport is your app (WebSocket, party server, …).
|
|
221
|
+
*/
|
|
222
|
+
remotePresence?: readonly RemotePresencePeer[];
|
|
223
|
+
/**
|
|
224
|
+
* Replace the default presence layer (e.g. custom cursors). When set, `remotePresence` is not
|
|
225
|
+
* rendered unless you read it from the parent closure inside this callback.
|
|
226
|
+
*/
|
|
227
|
+
presenceOverlay?: (ctx: PresenceOverlayRenderContext) => ReactNode;
|
|
228
|
+
/**
|
|
229
|
+
* Throttled pointer position in **world** space while the cursor moves over the viewport
|
|
230
|
+
* (for broadcasting your cursor). Pair with `onWorldPointerLeave`.
|
|
231
|
+
*/
|
|
232
|
+
onWorldPointerMove?: (world: {
|
|
233
|
+
x: number;
|
|
234
|
+
y: number;
|
|
235
|
+
}) => void;
|
|
236
|
+
/** Fires when the pointer leaves the viewport (clear your broadcast cursor). */
|
|
237
|
+
onWorldPointerLeave?: () => void;
|
|
238
|
+
/**
|
|
239
|
+
* Fires when drag placement preview updates (rect, line, freehand stroke, …). Use it to broadcast
|
|
240
|
+
* {@link RemotePresencePeer.markupStroke} for other participants while drawing.
|
|
241
|
+
*/
|
|
242
|
+
onPlacementPreviewChange?: (preview: PlacementPreview | null) => void;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Full-viewport vector canvas: SVG rendering + pan/zoom/pinch + optional Apple Pencil navigation.
|
|
246
|
+
* Pass a `className` that includes `touch-action: none` (e.g. Tailwind `touch-none`) on the viewport.
|
|
247
|
+
*/
|
|
248
|
+
declare const VectorViewport: react.ForwardRefExoticComponent<VectorViewportProps & react.RefAttributes<VectorViewportHandle>>;
|
|
249
|
+
|
|
250
|
+
type CanvasPluginRenderContext = {
|
|
251
|
+
/** Live viewport handle when the plugin needs camera or viewport size. */
|
|
252
|
+
viewportRef?: RefObject<VectorViewportHandle | null>;
|
|
253
|
+
};
|
|
254
|
+
type CanvasPluginItemsChangeMiddlewareContext = {
|
|
255
|
+
/** Current board items before the pending change is applied. */
|
|
256
|
+
currentItems: readonly VectorSceneItem[];
|
|
257
|
+
/** Continue the item change pipeline. */
|
|
258
|
+
next: NonNullable<VectorViewportProps["onItemsChange"]>;
|
|
259
|
+
/** Original consumer callback passed to `VectorViewport`. */
|
|
260
|
+
consumerOnItemsChange?: VectorViewportProps["onItemsChange"];
|
|
261
|
+
/** Live viewport handle for advanced integrations. */
|
|
262
|
+
viewportRef?: RefObject<VectorViewportHandle | null>;
|
|
263
|
+
};
|
|
264
|
+
type CanvasPluginContribution = {
|
|
265
|
+
/** Additional tools injected into the board toolbar/runtime. */
|
|
266
|
+
tools?: readonly VectorToolDefinition[];
|
|
267
|
+
/** Transform the resolved tool list (reorder, replace, or filter existing tools). */
|
|
268
|
+
toolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];
|
|
269
|
+
/** Multiple custom placements contributed by plugins; the active one is resolved by `toolId`. */
|
|
270
|
+
customPlacements?: readonly CustomShapePlacementOptions[];
|
|
271
|
+
/** Simple viewport prop overrides owned by the plugin runtime. */
|
|
272
|
+
viewportProps?: Partial<Pick<VectorViewportProps, "remotePresence" | "presenceOverlay">>;
|
|
273
|
+
/** Event callbacks chained into the viewport without manual wiring in app code. */
|
|
274
|
+
callbacks?: Partial<Pick<VectorViewportProps, "onWorldPointerMove" | "onWorldPointerLeave" | "onPlacementPreviewChange" | "onCameraChange">>;
|
|
275
|
+
/** Middleware around `onItemsChange` for collaboration, comments, persistence, etc. */
|
|
276
|
+
wrapOnItemsChange?: (nextItems: VectorSceneItem[], ctx: CanvasPluginItemsChangeMiddlewareContext) => void;
|
|
277
|
+
};
|
|
278
|
+
type CanvasPluginComponentProps = {
|
|
279
|
+
/** Stable plugin id so the component can register contributions. */
|
|
280
|
+
pluginId: string;
|
|
281
|
+
};
|
|
282
|
+
type CanvasPlugin = {
|
|
283
|
+
/** Stable id, e.g. `canvu.plugin.chatbot`. */
|
|
284
|
+
id: string;
|
|
285
|
+
/**
|
|
286
|
+
* Legacy/simple rendering path for purely visual plugins.
|
|
287
|
+
*
|
|
288
|
+
* Prefer `Component` for plugins that need hooks, document integration, tools, or runtime contributions.
|
|
289
|
+
*/
|
|
290
|
+
render?: (ctx: CanvasPluginRenderContext) => ReactNode;
|
|
291
|
+
/**
|
|
292
|
+
* Preferred plugin entrypoint for first-party and advanced plugins.
|
|
293
|
+
*
|
|
294
|
+
* The component can use hooks and register contributions through `useCanvuPluginContribution`.
|
|
295
|
+
*/
|
|
296
|
+
Component?: (props: CanvasPluginComponentProps) => ReactNode;
|
|
297
|
+
};
|
|
298
|
+
type CanvuPluginViewportSnapshot = Pick<VectorViewportProps, "items" | "onItemsChange" | "toolId" | "interactive" | "toolLocked" | "onToolChangeRequest">;
|
|
299
|
+
type CanvuPluginContextValue = {
|
|
300
|
+
viewportRef?: RefObject<VectorViewportHandle | null>;
|
|
301
|
+
viewport: CanvuPluginViewportSnapshot;
|
|
302
|
+
resolvedTools: VectorToolDefinition[];
|
|
303
|
+
registerContribution: (pluginId: string, contribution: CanvasPluginContribution) => void;
|
|
304
|
+
unregisterContribution: (pluginId: string) => void;
|
|
305
|
+
};
|
|
306
|
+
declare const CanvuPluginContext: react.Context<CanvuPluginContextValue | null>;
|
|
307
|
+
/**
|
|
308
|
+
* Creates a typed canvu plugin descriptor.
|
|
309
|
+
*
|
|
310
|
+
* Use this helper when authoring custom plugins so your editor can infer the plugin shape
|
|
311
|
+
* and surface better hover documentation for the returned object.
|
|
312
|
+
*/
|
|
313
|
+
declare function createCanvuPlugin(plugin: CanvasPlugin): CanvasPlugin;
|
|
314
|
+
/**
|
|
315
|
+
* Returns the low-level canvu plugin runtime context.
|
|
316
|
+
*
|
|
317
|
+
* This is an advanced API for custom plugin authors. Prefer first-party plugin factories such as
|
|
318
|
+
* `chatbotPlugin(...)` and `realtimeCollaborationPlugin(...)` for the common path.
|
|
319
|
+
*/
|
|
320
|
+
declare function useCanvuPluginContext(): CanvuPluginContextValue;
|
|
321
|
+
/**
|
|
322
|
+
* Returns the current viewport-facing board state exposed to plugins.
|
|
323
|
+
*
|
|
324
|
+
* Use this when a custom plugin needs access to items, the active tool, or the consumer's
|
|
325
|
+
* `onToolChangeRequest` callback.
|
|
326
|
+
*/
|
|
327
|
+
declare function useCanvuViewportContext(): {
|
|
328
|
+
viewportRef?: RefObject<VectorViewportHandle | null>;
|
|
329
|
+
viewport: CanvuPluginViewportSnapshot;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Returns the board document context exposed to plugins.
|
|
333
|
+
*
|
|
334
|
+
* This hook is intended for advanced plugins that need to read items or integrate with the board's
|
|
335
|
+
* `onItemsChange` lifecycle.
|
|
336
|
+
*/
|
|
337
|
+
declare function useCanvuDocumentContext(): {
|
|
338
|
+
items: readonly VectorSceneItem[];
|
|
339
|
+
onItemsChange?: VectorViewportProps["onItemsChange"];
|
|
340
|
+
};
|
|
341
|
+
/**
|
|
342
|
+
* Returns the tool list already resolved by the plugin runtime.
|
|
343
|
+
*
|
|
344
|
+
* `VectorToolbar` consumes this automatically when you omit its `tools` prop, so most apps do not
|
|
345
|
+
* need this hook directly.
|
|
346
|
+
*/
|
|
347
|
+
declare function useCanvuResolvedTools(): VectorToolDefinition[];
|
|
348
|
+
/**
|
|
349
|
+
* Registers non-visual plugin contributions with the current `VectorViewport` runtime.
|
|
350
|
+
*
|
|
351
|
+
* Use this inside `plugin.Component` when you want to inject tools, viewport behavior, or document
|
|
352
|
+
* middleware without requiring the consumer to wire hooks manually.
|
|
353
|
+
*/
|
|
354
|
+
declare function useCanvuPluginContribution(pluginId: string, contribution: CanvasPluginContribution): void;
|
|
355
|
+
|
|
356
|
+
export { type CanvasPlugin as C, type PlacementPreview as P, type RemotePresenceMarkupStroke as R, type VectorToolDefinition as V, type WorldPointerDownDetail as W, type CanvasPluginComponentProps as a, type CanvasPluginContribution as b, type CanvasPluginItemsChangeMiddlewareContext as c, type CanvasPluginRenderContext as d, CanvuPluginContext as e, type CanvuPluginContextValue as f, type CanvuPluginViewportSnapshot as g, type CustomShapePlacementOptions as h, VectorViewport as i, type VectorViewportHandle as j, type VectorViewportProps as k, createCanvuPlugin as l, useCanvuPluginContext as m, useCanvuPluginContribution as n, useCanvuResolvedTools as o, useCanvuViewportContext as p, type RemotePresencePeer as q, type RealtimeConnectionState as r, type PresenceOverlayRenderContext as s, useCanvuDocumentContext as u };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { V as VectorSceneItem } from './types-CB0TZZuk.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Serializable document for persistence (localStorage, API, WebSocket).
|
|
5
|
+
* Extend with your own fields when saving to your backend.
|
|
6
|
+
*/
|
|
7
|
+
type VectorCanvasSnapshot = {
|
|
8
|
+
items: VectorSceneItem[];
|
|
9
|
+
/** Bump when the JSON shape changes. */
|
|
10
|
+
version?: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Plug your database, IndexedDB, or HTTP API: load/save full snapshots.
|
|
14
|
+
*/
|
|
15
|
+
type VectorCanvasPersistenceAdapter = {
|
|
16
|
+
load: () => Promise<VectorCanvasSnapshot | null>;
|
|
17
|
+
save: (snapshot: VectorCanvasSnapshot) => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Wire your WebSocket / SSE / polling: receive full `items` from the server
|
|
21
|
+
* and optionally push local changes upstream.
|
|
22
|
+
*/
|
|
23
|
+
type VectorCanvasRemoteAdapter = {
|
|
24
|
+
/**
|
|
25
|
+
* Called when the server sends a new scene. Replace local `items` with this.
|
|
26
|
+
* Return an unsubscribe function.
|
|
27
|
+
*/
|
|
28
|
+
subscribe: (onItems: (items: VectorSceneItem[]) => void) => () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Optional: called after local edits (debounced) so you can `ws.send(JSON.stringify(items))`.
|
|
31
|
+
*/
|
|
32
|
+
send?: (items: VectorSceneItem[]) => void;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type { VectorCanvasPersistenceAdapter as V, VectorCanvasRemoteAdapter as a, VectorCanvasSnapshot as b };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Axis-aligned rectangle in 2D (world or screen space).
|
|
3
|
+
*/
|
|
4
|
+
type Rect = {
|
|
5
|
+
readonly x: number;
|
|
6
|
+
readonly y: number;
|
|
7
|
+
readonly width: number;
|
|
8
|
+
readonly height: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Returns whether two axis-aligned rectangles intersect (edges touching count).
|
|
12
|
+
*/
|
|
13
|
+
declare function rectsIntersect(a: Rect, b: Rect): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Normalizes a rect so width and height are non-negative.
|
|
16
|
+
*/
|
|
17
|
+
declare function normalizeRect(r: Rect): Rect;
|
|
18
|
+
|
|
19
|
+
/** Identifies how `childrenSvg` was produced for editing (resize, handles). */
|
|
20
|
+
type VectorToolKind = "rect" | "ellipse" | "line" | "arrow" | "draw" | "pencil" | "brush" | "marker" | "text" | "image" | "custom";
|
|
21
|
+
/** Local segment for line/arrow (relative to item `x`, `y`). */
|
|
22
|
+
type LineEndpointsLocal = {
|
|
23
|
+
x1: number;
|
|
24
|
+
y1: number;
|
|
25
|
+
x2: number;
|
|
26
|
+
y2: number;
|
|
27
|
+
};
|
|
28
|
+
type VectorPathPoint = {
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
pressure?: number;
|
|
32
|
+
};
|
|
33
|
+
/** Arrow endpoint glued to a shape boundary (normalized anchor in target local 0…1 space). */
|
|
34
|
+
type ArrowEndpointBinding = {
|
|
35
|
+
targetId: string;
|
|
36
|
+
anchor: {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
type ArrowBindings = {
|
|
42
|
+
start?: ArrowEndpointBinding;
|
|
43
|
+
end?: ArrowEndpointBinding;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* One drawable vector item in world space. `childrenSvg` is inner markup for an SVG `<g>`
|
|
47
|
+
* (paths, circles, text — no outer `<svg>` wrapper).
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const item: VectorSceneItem = {
|
|
52
|
+
* id: "a1",
|
|
53
|
+
* x: 0,
|
|
54
|
+
* y: 0,
|
|
55
|
+
* bounds: { x: 0, y: 0, width: 200, height: 100 },
|
|
56
|
+
* childrenSvg: '<rect width="200" height="100" fill="#eee" />',
|
|
57
|
+
* };
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
type VectorSceneItem = {
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** World-space bounds used for visibility culling and selection. */
|
|
63
|
+
readonly bounds: Rect;
|
|
64
|
+
/**
|
|
65
|
+
* SVG fragment placed inside `<g transform="translate(x,y)">`.
|
|
66
|
+
* Use local coordinates within [0, bounds.width] × [0, bounds.height] for predictable layout.
|
|
67
|
+
*/
|
|
68
|
+
readonly childrenSvg: string;
|
|
69
|
+
/** World position of the item’s top-left corner. */
|
|
70
|
+
readonly x: number;
|
|
71
|
+
readonly y: number;
|
|
72
|
+
/** How the SVG was built — used for resize / handle editing. */
|
|
73
|
+
readonly toolKind?: VectorToolKind;
|
|
74
|
+
/**
|
|
75
|
+
* Stroke color for shapes and lines; for {@link toolKind} `"text"` this is used as **fill** color.
|
|
76
|
+
* Default when omitted: `#2563eb`.
|
|
77
|
+
*/
|
|
78
|
+
readonly stroke?: string;
|
|
79
|
+
/** SVG stroke width in local space (same visual scales with zoom). Default `2`. */
|
|
80
|
+
readonly strokeWidth?: number;
|
|
81
|
+
/** Optional stroke opacity (e.g. highlighter `~0.45`). */
|
|
82
|
+
readonly strokeOpacity?: number;
|
|
83
|
+
/**
|
|
84
|
+
* Polyline for freehand tools (`draw`, `marker`; legacy `pencil` / `brush`) in **local** coords relative to `x`,`y`.
|
|
85
|
+
*/
|
|
86
|
+
readonly pathPointsLocal?: readonly VectorPathPoint[];
|
|
87
|
+
/** Counter-clockwise rotation around the center of `bounds` (radians). Omitted = 0. */
|
|
88
|
+
readonly rotation?: number;
|
|
89
|
+
/**
|
|
90
|
+
* When true, the item still renders but is ignored by direct user interaction
|
|
91
|
+
* such as selection, resize, rotate, editing, and erasing.
|
|
92
|
+
* Useful for protected background pages that should allow drawing on top.
|
|
93
|
+
*/
|
|
94
|
+
readonly locked?: boolean;
|
|
95
|
+
/** Line/arrow endpoints in local space; required for directed lines/arrows. */
|
|
96
|
+
readonly line?: LineEndpointsLocal;
|
|
97
|
+
/** When set on an arrow, endpoints follow the bound shapes when they move or resize. */
|
|
98
|
+
readonly arrowBind?: ArrowBindings;
|
|
99
|
+
/** User text for `toolKind === "text"` (plain text, newlines allowed). */
|
|
100
|
+
readonly text?: string;
|
|
101
|
+
/**
|
|
102
|
+
* When true, `bounds` are user-controlled (e.g. resize handles) and text wraps inside;
|
|
103
|
+
* when false/undefined, bounds grow with content (no fixed width).
|
|
104
|
+
*/
|
|
105
|
+
readonly textFixedBounds?: boolean;
|
|
106
|
+
/** Local font size in px for `toolKind === "text"` (default 18). Scales on resize like tldraw. */
|
|
107
|
+
readonly textFontSize?: number;
|
|
108
|
+
/**
|
|
109
|
+
* For `toolKind === "image"`: embedded bitmap as `data:image/...` for a single SVG `<image>`.
|
|
110
|
+
* Preferred over path-tracing for performance and visual quality on screenshots/photos.
|
|
111
|
+
*/
|
|
112
|
+
readonly imageRasterHref?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Session-scoped `blob:` URL for the 256px thumbnail.
|
|
115
|
+
* Used for progressive loading: render thumbnail first, swap to full-res in background.
|
|
116
|
+
* Not persisted — recreated on load by the persistence adapter.
|
|
117
|
+
*/
|
|
118
|
+
readonly imageThumbnailHref?: string;
|
|
119
|
+
/** Pixel size of {@link imageRasterHref} before scaling into `bounds`. */
|
|
120
|
+
readonly imageIntrinsicSize?: {
|
|
121
|
+
width: number;
|
|
122
|
+
height: number;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* IndexedDB blob ID for the original image file.
|
|
126
|
+
* When set, the persistence adapter stores the blob separately from the JSON document,
|
|
127
|
+
* enabling full-resolution images without bloating the serialized snapshot.
|
|
128
|
+
*/
|
|
129
|
+
readonly imageBlobId?: string;
|
|
130
|
+
/**
|
|
131
|
+
* IndexedDB blob ID for the 256px thumbnail.
|
|
132
|
+
* Used for progressive loading (thumbnail → full-res swap).
|
|
133
|
+
*/
|
|
134
|
+
readonly imageThumbnailBlobId?: string;
|
|
135
|
+
/**
|
|
136
|
+
* Optional: traced SVG fragment (advanced / legacy) in {@link imageVectorLocalSize} space.
|
|
137
|
+
*/
|
|
138
|
+
readonly imageVectorInnerSvg?: string;
|
|
139
|
+
readonly imageVectorLocalSize?: {
|
|
140
|
+
width: number;
|
|
141
|
+
height: number;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* For {@link toolKind} `"custom"`: inner SVG drawn in {@link customIntrinsicSize} space.
|
|
145
|
+
* When set with {@link customIntrinsicSize}, resize keeps proportions by scaling this markup.
|
|
146
|
+
*/
|
|
147
|
+
readonly customInnerSvg?: string;
|
|
148
|
+
/** Pixel size that {@link customInnerSvg} is authored for (usually matches initial `bounds`). */
|
|
149
|
+
readonly customIntrinsicSize?: {
|
|
150
|
+
width: number;
|
|
151
|
+
height: number;
|
|
152
|
+
};
|
|
153
|
+
/** Optional app/plugin metadata persisted alongside the item. */
|
|
154
|
+
readonly pluginData?: Record<string, unknown>;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export { type ArrowEndpointBinding as A, type LineEndpointsLocal as L, type Rect as R, type VectorSceneItem as V, type ArrowBindings as a, type VectorPathPoint as b, normalizeRect as n, rectsIntersect as r };
|