canvu-react 0.4.77 → 0.4.79

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/dist/react.d.cts CHANGED
@@ -4,8 +4,8 @@ import { V as VectorViewportAssetKind, a as VectorViewportAssetStore } from './r
4
4
  export { b as RasterImageCanvasRenderRequest, c as RasterImageCanvasRenderTarget, d as RasterImageCanvasRenderTargetResolver, R as RasterImageCanvasRenderingOptions, e as RasterImageCanvasSource, f as RasterImageCanvasSourceRequest, g as RasterImageCanvasSourceResolver, h as RasterImageCanvasSourceSizeRequest, i as RasterImageCanvasSourceSizeResolver, j as VectorViewportAssetHydrationRequest, k as VectorViewportAssetResolveRequest, l as VectorViewportAssetResolveResult, m as VectorViewportAssetUploadRequest, n as VectorViewportAssetUploadResult } from './raster-image-canvas-ByaCKEVw.cjs';
5
5
  import { I as IndexedDbImageStore } from './asset-hydration-6swZ6ciN.cjs';
6
6
  export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-6swZ6ciN.cjs';
7
- import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-DOUBapS4.cjs';
8
- export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, x as SelectModeItemClickDetail, y as SelectModeItemClickResult, z as ShapeContextMenu, A as ShapeContextMenuItem, D as ShapeContextMenuProps, E as ShapeContextMenuRenderContext, F as VectorCanvasSpacePosition, G as VectorItemsChangeInfo, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './types-DOUBapS4.cjs';
7
+ import { V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorItemsChangeInfo, B as BoardComponentPosition, e as VectorSelectionInspector } from './VectorViewport-MlKilYoG.cjs';
8
+ export { f as CanvasPluginComponentProps, g as CanvasPluginContribution, h as CanvasPluginItemsChangeMiddlewareContext, i as CanvasPluginRenderContext, j as CanvuAfterInteractionDetail, k as CanvuBeforeInteractionResult, l as CanvuChromeActiveToolStyle, m as CanvuChromeContext, n as CanvuChromeContextValue, o as CanvuChromeSelectionStyleChange, p as CanvuInteractionDetail, q as CanvuInteractionKind, r as CanvuInteractionOutcome, s as CanvuInteractionPoint, t as CanvuPluginContext, u as CanvuPluginContextValue, v as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, w as ReadOnlyItemClickCandidateDetail, x as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, y as SelectModeItemClickDetail, z as SelectModeItemClickResult, A as ShapeContextMenu, D as ShapeContextMenuItem, E as ShapeContextMenuProps, F as ShapeContextMenuRenderContext, G as VectorCanvasSpacePosition, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './VectorViewport-MlKilYoG.cjs';
9
9
  import * as react_jsx_runtime from 'react/jsx-runtime';
10
10
  import * as react from 'react';
11
11
  import { CSSProperties, ReactNode, ReactElement, SVGProps } from 'react';
@@ -164,6 +164,74 @@ type IngestAssetFilesToSceneItemsResult = {
164
164
  */
165
165
  declare function ingestAssetFilesToSceneItems(options: IngestAssetFilesToSceneItemsOptions): Promise<IngestAssetFilesToSceneItemsResult>;
166
166
 
167
+ type CreateToolPluginOptions = VectorToolDefinition & {
168
+ /**
169
+ * Optional custom placement factory for tools that create scene items directly.
170
+ *
171
+ * When provided, the resulting plugin contributes a `customPlacement` entry for this tool id.
172
+ */
173
+ createItem?: (args: {
174
+ id: string;
175
+ bounds: {
176
+ x: number;
177
+ y: number;
178
+ width: number;
179
+ height: number;
180
+ };
181
+ }) => VectorSceneItem;
182
+ /**
183
+ * Whether items created by this tool should become selected immediately after placement.
184
+ *
185
+ * Defaults to `true`. Set to `false` for clickable custom tools such as pins,
186
+ * reactions, or cards that should act without showing selection handles on placement.
187
+ */
188
+ selectAfterCreate?: CustomShapePlacementOptions["selectAfterCreate"];
189
+ /**
190
+ * Handles plain clicks on this tool's items while the viewport is in select mode.
191
+ *
192
+ * Resize and rotate handles still take priority. Returning `"handled"` marks the
193
+ * click as owned by the tool; dragging past the tap threshold still falls back to
194
+ * normal move behavior.
195
+ */
196
+ onSelectModeItemClick?: CustomShapePlacementOptions["onSelectModeItemClick"];
197
+ /**
198
+ * Runs before Canvu handles this tool's accepted pointer interaction.
199
+ *
200
+ * Return `"handled"` to claim the gesture and skip Canvu's built-in behavior.
201
+ * The hook is automatically scoped to this tool id.
202
+ */
203
+ onBeforeInteraction?: CanvuBeforeInteractionHook;
204
+ /**
205
+ * Runs once after this tool's accepted pointer interaction completes or is
206
+ * cancelled.
207
+ *
208
+ * The hook is automatically scoped to this tool id. Use it for custom cleanup,
209
+ * analytics, or side effects that should happen after the gesture lifecycle.
210
+ */
211
+ onAfterInteraction?: CanvuAfterInteractionHook;
212
+ /**
213
+ * Optional tool list transform applied after this tool is merged.
214
+ *
215
+ * Use this when you need custom ordering or to replace an existing tool position.
216
+ */
217
+ toolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];
218
+ };
219
+ /**
220
+ * Creates a lightweight plugin that contributes a single tool to `VectorViewport`.
221
+ *
222
+ * Use this for isolated tools such as custom shapes, review pins, or lightweight creation flows.
223
+ * For larger features that also need presence, panels, or network integration, prefer a dedicated
224
+ * feature plugin such as `realtimeCollaborationPlugin(...)`.
225
+ */
226
+ declare function createToolPlugin(options: CreateToolPluginOptions): CanvasPlugin;
227
+
228
+ /**
229
+ * CSS `cursor` for the active toolbar tool id (see default vector tools).
230
+ * SVG cursors matching Lucide toolbar glyphs are used for freehand tools only.
231
+ * Shape tools keep the old native crosshair cursor.
232
+ */
233
+ declare function cursorForVectorToolId(toolId: string): string;
234
+
167
235
  type ImagesMenuLabels = {
168
236
  title?: string;
169
237
  dragHandle?: string;
@@ -211,7 +279,27 @@ type ImagesMenuCollapsedButtonRenderProps = {
211
279
  type ImagesMenuActionId = "duplicate" | "rotate" | "delete";
212
280
  type ImagesMenuProps = {
213
281
  items: readonly VectorSceneItem[];
214
- onItemsChange: (items: VectorSceneItem[]) => void;
282
+ /**
283
+ * Called when the managed image list changes.
284
+ *
285
+ * The optional `info` argument matches {@link VectorViewportProps.onItemsChange}
286
+ * metadata. Built-in menu actions emit `"duplicate"`, `"rotate"`, `"delete"`,
287
+ * or `"reorder"` motives with affected item ids when known, so middleware,
288
+ * analytics, and confirmation flows can treat image-menu mutations like other
289
+ * Canvu-owned actions. Simple state setters can ignore the second argument.
290
+ *
291
+ * @example
292
+ * ```tsx
293
+ * <ImagesMenu
294
+ * items={items}
295
+ * onItemsChange={(next, info) => {
296
+ * if (info?.motive === "delete") confirmDelete(next);
297
+ * else setItems(next);
298
+ * }}
299
+ * />
300
+ * ```
301
+ */
302
+ onItemsChange: (items: VectorSceneItem[], info?: VectorItemsChangeInfo) => void;
215
303
  /**
216
304
  * Fires when the user clicks an image's thumbnail/label area. Use this to
217
305
  * pan/zoom the canvas to the item (e.g. `viewportRef.current?.fitWorldRect(item.bounds)`).
@@ -469,74 +557,6 @@ type UseVectorCanvasDocumentResult = {
469
557
  */
470
558
  declare function useVectorCanvasDocument(options?: UseVectorCanvasDocumentOptions): UseVectorCanvasDocumentResult;
471
559
 
472
- /**
473
- * CSS `cursor` for the active toolbar tool id (see default vector tools).
474
- * SVG cursors matching Lucide toolbar glyphs are used for freehand tools only.
475
- * Shape tools keep the old native crosshair cursor.
476
- */
477
- declare function cursorForVectorToolId(toolId: string): string;
478
-
479
- type CreateToolPluginOptions = VectorToolDefinition & {
480
- /**
481
- * Optional custom placement factory for tools that create scene items directly.
482
- *
483
- * When provided, the resulting plugin contributes a `customPlacement` entry for this tool id.
484
- */
485
- createItem?: (args: {
486
- id: string;
487
- bounds: {
488
- x: number;
489
- y: number;
490
- width: number;
491
- height: number;
492
- };
493
- }) => VectorSceneItem;
494
- /**
495
- * Whether items created by this tool should become selected immediately after placement.
496
- *
497
- * Defaults to `true`. Set to `false` for clickable custom tools such as pins,
498
- * reactions, or cards that should act without showing selection handles on placement.
499
- */
500
- selectAfterCreate?: CustomShapePlacementOptions["selectAfterCreate"];
501
- /**
502
- * Handles plain clicks on this tool's items while the viewport is in select mode.
503
- *
504
- * Resize and rotate handles still take priority. Returning `"handled"` marks the
505
- * click as owned by the tool; dragging past the tap threshold still falls back to
506
- * normal move behavior.
507
- */
508
- onSelectModeItemClick?: CustomShapePlacementOptions["onSelectModeItemClick"];
509
- /**
510
- * Runs before Canvu handles this tool's accepted pointer interaction.
511
- *
512
- * Return `"handled"` to claim the gesture and skip Canvu's built-in behavior.
513
- * The hook is automatically scoped to this tool id.
514
- */
515
- onBeforeInteraction?: CanvuBeforeInteractionHook;
516
- /**
517
- * Runs once after this tool's accepted pointer interaction completes or is
518
- * cancelled.
519
- *
520
- * The hook is automatically scoped to this tool id. Use it for custom cleanup,
521
- * analytics, or side effects that should happen after the gesture lifecycle.
522
- */
523
- onAfterInteraction?: CanvuAfterInteractionHook;
524
- /**
525
- * Optional tool list transform applied after this tool is merged.
526
- *
527
- * Use this when you need custom ordering or to replace an existing tool position.
528
- */
529
- toolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];
530
- };
531
- /**
532
- * Creates a lightweight plugin that contributes a single tool to `VectorViewport`.
533
- *
534
- * Use this for isolated tools such as custom shapes, review pins, or lightweight creation flows.
535
- * For larger features that also need presence, panels, or network integration, prefer a dedicated
536
- * feature plugin such as `realtimeCollaborationPlugin(...)`.
537
- */
538
- declare function createToolPlugin(options: CreateToolPluginOptions): CanvasPlugin;
539
-
540
560
  /**
541
561
  * Tool ids shown in the overflow menu at the end of the default toolbar (horizontal layout).
542
562
  * Order: shapes, marker, laser, image.
@@ -845,4 +865,4 @@ type VectorToolbarWithStatics = ((props: VectorToolbarProps) => ReactElement) &
845
865
  */
846
866
  declare const VectorToolbar: VectorToolbarWithStatics;
847
867
 
848
- export { BoardComponentPosition, CanvasPlugin, CanvuAfterInteractionHook, CanvuBeforeInteractionHook, type CreateLocalStoragePersistenceAdapterOptions, type CreateToolPluginOptions, CustomShapePlacementOptions, DEFAULT_OVERFLOW_TOOL_IDS, DEFAULT_VECTOR_CANVAS_STORAGE_KEY, DEFAULT_VECTOR_TOOLS, IconArchitecturalCloud, IconArrow, IconDraw, IconEllipse, IconHand, IconImage, IconLaser, IconLine, IconRect, IconSelect, IconText, ImagesMenu, type ImagesMenuActionId, type ImagesMenuCollapsedButtonProps, type ImagesMenuCollapsedButtonRenderProps, type ImagesMenuLabels, type ImagesMenuProps, type IngestAssetFileError, type IngestAssetFilesToSceneItemsOptions, type IngestAssetFilesToSceneItemsResult, type IngestedAssetItemContext, NavMenu, type NavMenuMinimapProps, type NavMenuProps, type NavMenuUndoRedoProps, type NavMenuZoomControlsProps, type UseVectorCanvasDocumentOptions, type UseVectorCanvasDocumentResult, VectorCanvas, VectorCanvasBody, VectorCanvasHeader, VectorCanvasMain, VectorCanvasPersistenceAdapter, VectorCanvasRemoteAdapter, VectorCanvasRoot, type VectorCanvasSlotProps, type VectorCanvasSpaceProps, VectorCanvasToolbar, type VectorCanvasToolbarProps, VectorCanvasViewportSurface, VectorSelectionInspector, VectorToolDefinition, VectorToolbar, type VectorToolbarOverflowProps, type VectorToolbarProps, type VectorToolbarRenderContext, type VectorToolbarToolLockProps, type VectorToolbarToolProps, VectorViewportAssetKind, VectorViewportAssetStore, createIndexedDbPersistenceAdapter, createLocalStoragePersistenceAdapter, createNoopPersistenceAdapter, createToolPlugin, cursorForVectorToolId, ingestAssetFilesToSceneItems, useVectorCanvasDocument };
868
+ export { BoardComponentPosition, CanvasPlugin, CanvuAfterInteractionHook, CanvuBeforeInteractionHook, type CreateLocalStoragePersistenceAdapterOptions, type CreateToolPluginOptions, CustomShapePlacementOptions, DEFAULT_OVERFLOW_TOOL_IDS, DEFAULT_VECTOR_CANVAS_STORAGE_KEY, DEFAULT_VECTOR_TOOLS, IconArchitecturalCloud, IconArrow, IconDraw, IconEllipse, IconHand, IconImage, IconLaser, IconLine, IconRect, IconSelect, IconText, ImagesMenu, type ImagesMenuActionId, type ImagesMenuCollapsedButtonProps, type ImagesMenuCollapsedButtonRenderProps, type ImagesMenuLabels, type ImagesMenuProps, type IngestAssetFileError, type IngestAssetFilesToSceneItemsOptions, type IngestAssetFilesToSceneItemsResult, type IngestedAssetItemContext, NavMenu, type NavMenuMinimapProps, type NavMenuProps, type NavMenuUndoRedoProps, type NavMenuZoomControlsProps, type UseVectorCanvasDocumentOptions, type UseVectorCanvasDocumentResult, VectorCanvas, VectorCanvasBody, VectorCanvasHeader, VectorCanvasMain, VectorCanvasPersistenceAdapter, VectorCanvasRemoteAdapter, VectorCanvasRoot, type VectorCanvasSlotProps, type VectorCanvasSpaceProps, VectorCanvasToolbar, type VectorCanvasToolbarProps, VectorCanvasViewportSurface, VectorItemsChangeInfo, VectorSelectionInspector, VectorToolDefinition, VectorToolbar, type VectorToolbarOverflowProps, type VectorToolbarProps, type VectorToolbarRenderContext, type VectorToolbarToolLockProps, type VectorToolbarToolProps, VectorViewportAssetKind, VectorViewportAssetStore, createIndexedDbPersistenceAdapter, createLocalStoragePersistenceAdapter, createNoopPersistenceAdapter, createToolPlugin, cursorForVectorToolId, ingestAssetFilesToSceneItems, useVectorCanvasDocument };
package/dist/react.d.ts CHANGED
@@ -4,8 +4,8 @@ import { V as VectorViewportAssetKind, a as VectorViewportAssetStore } from './r
4
4
  export { b as RasterImageCanvasRenderRequest, c as RasterImageCanvasRenderTarget, d as RasterImageCanvasRenderTargetResolver, R as RasterImageCanvasRenderingOptions, e as RasterImageCanvasSource, f as RasterImageCanvasSourceRequest, g as RasterImageCanvasSourceResolver, h as RasterImageCanvasSourceSizeRequest, i as RasterImageCanvasSourceSizeResolver, j as VectorViewportAssetHydrationRequest, k as VectorViewportAssetResolveRequest, l as VectorViewportAssetResolveResult, m as VectorViewportAssetUploadRequest, n as VectorViewportAssetUploadResult } from './raster-image-canvas-D3ZrySjr.js';
5
5
  import { I as IndexedDbImageStore } from './asset-hydration-P0M5hn-p.js';
6
6
  export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-P0M5hn-p.js';
7
- import { B as BoardComponentPosition, V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorSelectionInspector } from './types-C5wxwquF.js';
8
- export { e as CanvasPluginComponentProps, f as CanvasPluginContribution, g as CanvasPluginItemsChangeMiddlewareContext, h as CanvasPluginRenderContext, i as CanvuAfterInteractionDetail, j as CanvuBeforeInteractionResult, k as CanvuChromeActiveToolStyle, l as CanvuChromeContext, m as CanvuChromeContextValue, n as CanvuChromeSelectionStyleChange, o as CanvuInteractionDetail, p as CanvuInteractionKind, q as CanvuInteractionOutcome, r as CanvuInteractionPoint, s as CanvuPluginContext, t as CanvuPluginContextValue, u as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, v as ReadOnlyItemClickCandidateDetail, w as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, x as SelectModeItemClickDetail, y as SelectModeItemClickResult, z as ShapeContextMenu, A as ShapeContextMenuItem, D as ShapeContextMenuProps, E as ShapeContextMenuRenderContext, F as VectorCanvasSpacePosition, G as VectorItemsChangeInfo, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './types-C5wxwquF.js';
7
+ import { V as VectorToolDefinition, C as CustomShapePlacementOptions, a as CanvuBeforeInteractionHook, b as CanvuAfterInteractionHook, c as CanvasPlugin, d as VectorItemsChangeInfo, B as BoardComponentPosition, e as VectorSelectionInspector } from './VectorViewport-bSpT1CrU.js';
8
+ export { f as CanvasPluginComponentProps, g as CanvasPluginContribution, h as CanvasPluginItemsChangeMiddlewareContext, i as CanvasPluginRenderContext, j as CanvuAfterInteractionDetail, k as CanvuBeforeInteractionResult, l as CanvuChromeActiveToolStyle, m as CanvuChromeContext, n as CanvuChromeContextValue, o as CanvuChromeSelectionStyleChange, p as CanvuInteractionDetail, q as CanvuInteractionKind, r as CanvuInteractionOutcome, s as CanvuInteractionPoint, t as CanvuPluginContext, u as CanvuPluginContextValue, v as CanvuPluginViewportSnapshot, P as PlacementPreview, R as ReadOnlyInteractionOptions, w as ReadOnlyItemClickCandidateDetail, x as ReadOnlyItemClickScope, S as SHAPE_CONTEXT_MENU_ITEM_IDS, y as SelectModeItemClickDetail, z as SelectModeItemClickResult, A as ShapeContextMenu, D as ShapeContextMenuItem, E as ShapeContextMenuProps, F as ShapeContextMenuRenderContext, G as VectorCanvasSpacePosition, H as VectorItemsChangeMotive, I as VectorSelectionInspectorProps, J as VectorViewport, K as VectorViewportHandle, L as VectorViewportProps, W as WorldPointerDownDetail, M as createCanvuPlugin, N as getBoardPositionStyle, O as useCanvuChromeContext, Q as useCanvuDocumentContext, T as useCanvuPluginContext, U as useCanvuPluginContribution, X as useCanvuResolvedTools, Y as useCanvuViewportContext } from './VectorViewport-bSpT1CrU.js';
9
9
  import * as react_jsx_runtime from 'react/jsx-runtime';
10
10
  import * as react from 'react';
11
11
  import { CSSProperties, ReactNode, ReactElement, SVGProps } from 'react';
@@ -164,6 +164,74 @@ type IngestAssetFilesToSceneItemsResult = {
164
164
  */
165
165
  declare function ingestAssetFilesToSceneItems(options: IngestAssetFilesToSceneItemsOptions): Promise<IngestAssetFilesToSceneItemsResult>;
166
166
 
167
+ type CreateToolPluginOptions = VectorToolDefinition & {
168
+ /**
169
+ * Optional custom placement factory for tools that create scene items directly.
170
+ *
171
+ * When provided, the resulting plugin contributes a `customPlacement` entry for this tool id.
172
+ */
173
+ createItem?: (args: {
174
+ id: string;
175
+ bounds: {
176
+ x: number;
177
+ y: number;
178
+ width: number;
179
+ height: number;
180
+ };
181
+ }) => VectorSceneItem;
182
+ /**
183
+ * Whether items created by this tool should become selected immediately after placement.
184
+ *
185
+ * Defaults to `true`. Set to `false` for clickable custom tools such as pins,
186
+ * reactions, or cards that should act without showing selection handles on placement.
187
+ */
188
+ selectAfterCreate?: CustomShapePlacementOptions["selectAfterCreate"];
189
+ /**
190
+ * Handles plain clicks on this tool's items while the viewport is in select mode.
191
+ *
192
+ * Resize and rotate handles still take priority. Returning `"handled"` marks the
193
+ * click as owned by the tool; dragging past the tap threshold still falls back to
194
+ * normal move behavior.
195
+ */
196
+ onSelectModeItemClick?: CustomShapePlacementOptions["onSelectModeItemClick"];
197
+ /**
198
+ * Runs before Canvu handles this tool's accepted pointer interaction.
199
+ *
200
+ * Return `"handled"` to claim the gesture and skip Canvu's built-in behavior.
201
+ * The hook is automatically scoped to this tool id.
202
+ */
203
+ onBeforeInteraction?: CanvuBeforeInteractionHook;
204
+ /**
205
+ * Runs once after this tool's accepted pointer interaction completes or is
206
+ * cancelled.
207
+ *
208
+ * The hook is automatically scoped to this tool id. Use it for custom cleanup,
209
+ * analytics, or side effects that should happen after the gesture lifecycle.
210
+ */
211
+ onAfterInteraction?: CanvuAfterInteractionHook;
212
+ /**
213
+ * Optional tool list transform applied after this tool is merged.
214
+ *
215
+ * Use this when you need custom ordering or to replace an existing tool position.
216
+ */
217
+ toolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];
218
+ };
219
+ /**
220
+ * Creates a lightweight plugin that contributes a single tool to `VectorViewport`.
221
+ *
222
+ * Use this for isolated tools such as custom shapes, review pins, or lightweight creation flows.
223
+ * For larger features that also need presence, panels, or network integration, prefer a dedicated
224
+ * feature plugin such as `realtimeCollaborationPlugin(...)`.
225
+ */
226
+ declare function createToolPlugin(options: CreateToolPluginOptions): CanvasPlugin;
227
+
228
+ /**
229
+ * CSS `cursor` for the active toolbar tool id (see default vector tools).
230
+ * SVG cursors matching Lucide toolbar glyphs are used for freehand tools only.
231
+ * Shape tools keep the old native crosshair cursor.
232
+ */
233
+ declare function cursorForVectorToolId(toolId: string): string;
234
+
167
235
  type ImagesMenuLabels = {
168
236
  title?: string;
169
237
  dragHandle?: string;
@@ -211,7 +279,27 @@ type ImagesMenuCollapsedButtonRenderProps = {
211
279
  type ImagesMenuActionId = "duplicate" | "rotate" | "delete";
212
280
  type ImagesMenuProps = {
213
281
  items: readonly VectorSceneItem[];
214
- onItemsChange: (items: VectorSceneItem[]) => void;
282
+ /**
283
+ * Called when the managed image list changes.
284
+ *
285
+ * The optional `info` argument matches {@link VectorViewportProps.onItemsChange}
286
+ * metadata. Built-in menu actions emit `"duplicate"`, `"rotate"`, `"delete"`,
287
+ * or `"reorder"` motives with affected item ids when known, so middleware,
288
+ * analytics, and confirmation flows can treat image-menu mutations like other
289
+ * Canvu-owned actions. Simple state setters can ignore the second argument.
290
+ *
291
+ * @example
292
+ * ```tsx
293
+ * <ImagesMenu
294
+ * items={items}
295
+ * onItemsChange={(next, info) => {
296
+ * if (info?.motive === "delete") confirmDelete(next);
297
+ * else setItems(next);
298
+ * }}
299
+ * />
300
+ * ```
301
+ */
302
+ onItemsChange: (items: VectorSceneItem[], info?: VectorItemsChangeInfo) => void;
215
303
  /**
216
304
  * Fires when the user clicks an image's thumbnail/label area. Use this to
217
305
  * pan/zoom the canvas to the item (e.g. `viewportRef.current?.fitWorldRect(item.bounds)`).
@@ -469,74 +557,6 @@ type UseVectorCanvasDocumentResult = {
469
557
  */
470
558
  declare function useVectorCanvasDocument(options?: UseVectorCanvasDocumentOptions): UseVectorCanvasDocumentResult;
471
559
 
472
- /**
473
- * CSS `cursor` for the active toolbar tool id (see default vector tools).
474
- * SVG cursors matching Lucide toolbar glyphs are used for freehand tools only.
475
- * Shape tools keep the old native crosshair cursor.
476
- */
477
- declare function cursorForVectorToolId(toolId: string): string;
478
-
479
- type CreateToolPluginOptions = VectorToolDefinition & {
480
- /**
481
- * Optional custom placement factory for tools that create scene items directly.
482
- *
483
- * When provided, the resulting plugin contributes a `customPlacement` entry for this tool id.
484
- */
485
- createItem?: (args: {
486
- id: string;
487
- bounds: {
488
- x: number;
489
- y: number;
490
- width: number;
491
- height: number;
492
- };
493
- }) => VectorSceneItem;
494
- /**
495
- * Whether items created by this tool should become selected immediately after placement.
496
- *
497
- * Defaults to `true`. Set to `false` for clickable custom tools such as pins,
498
- * reactions, or cards that should act without showing selection handles on placement.
499
- */
500
- selectAfterCreate?: CustomShapePlacementOptions["selectAfterCreate"];
501
- /**
502
- * Handles plain clicks on this tool's items while the viewport is in select mode.
503
- *
504
- * Resize and rotate handles still take priority. Returning `"handled"` marks the
505
- * click as owned by the tool; dragging past the tap threshold still falls back to
506
- * normal move behavior.
507
- */
508
- onSelectModeItemClick?: CustomShapePlacementOptions["onSelectModeItemClick"];
509
- /**
510
- * Runs before Canvu handles this tool's accepted pointer interaction.
511
- *
512
- * Return `"handled"` to claim the gesture and skip Canvu's built-in behavior.
513
- * The hook is automatically scoped to this tool id.
514
- */
515
- onBeforeInteraction?: CanvuBeforeInteractionHook;
516
- /**
517
- * Runs once after this tool's accepted pointer interaction completes or is
518
- * cancelled.
519
- *
520
- * The hook is automatically scoped to this tool id. Use it for custom cleanup,
521
- * analytics, or side effects that should happen after the gesture lifecycle.
522
- */
523
- onAfterInteraction?: CanvuAfterInteractionHook;
524
- /**
525
- * Optional tool list transform applied after this tool is merged.
526
- *
527
- * Use this when you need custom ordering or to replace an existing tool position.
528
- */
529
- toolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];
530
- };
531
- /**
532
- * Creates a lightweight plugin that contributes a single tool to `VectorViewport`.
533
- *
534
- * Use this for isolated tools such as custom shapes, review pins, or lightweight creation flows.
535
- * For larger features that also need presence, panels, or network integration, prefer a dedicated
536
- * feature plugin such as `realtimeCollaborationPlugin(...)`.
537
- */
538
- declare function createToolPlugin(options: CreateToolPluginOptions): CanvasPlugin;
539
-
540
560
  /**
541
561
  * Tool ids shown in the overflow menu at the end of the default toolbar (horizontal layout).
542
562
  * Order: shapes, marker, laser, image.
@@ -845,4 +865,4 @@ type VectorToolbarWithStatics = ((props: VectorToolbarProps) => ReactElement) &
845
865
  */
846
866
  declare const VectorToolbar: VectorToolbarWithStatics;
847
867
 
848
- export { BoardComponentPosition, CanvasPlugin, CanvuAfterInteractionHook, CanvuBeforeInteractionHook, type CreateLocalStoragePersistenceAdapterOptions, type CreateToolPluginOptions, CustomShapePlacementOptions, DEFAULT_OVERFLOW_TOOL_IDS, DEFAULT_VECTOR_CANVAS_STORAGE_KEY, DEFAULT_VECTOR_TOOLS, IconArchitecturalCloud, IconArrow, IconDraw, IconEllipse, IconHand, IconImage, IconLaser, IconLine, IconRect, IconSelect, IconText, ImagesMenu, type ImagesMenuActionId, type ImagesMenuCollapsedButtonProps, type ImagesMenuCollapsedButtonRenderProps, type ImagesMenuLabels, type ImagesMenuProps, type IngestAssetFileError, type IngestAssetFilesToSceneItemsOptions, type IngestAssetFilesToSceneItemsResult, type IngestedAssetItemContext, NavMenu, type NavMenuMinimapProps, type NavMenuProps, type NavMenuUndoRedoProps, type NavMenuZoomControlsProps, type UseVectorCanvasDocumentOptions, type UseVectorCanvasDocumentResult, VectorCanvas, VectorCanvasBody, VectorCanvasHeader, VectorCanvasMain, VectorCanvasPersistenceAdapter, VectorCanvasRemoteAdapter, VectorCanvasRoot, type VectorCanvasSlotProps, type VectorCanvasSpaceProps, VectorCanvasToolbar, type VectorCanvasToolbarProps, VectorCanvasViewportSurface, VectorSelectionInspector, VectorToolDefinition, VectorToolbar, type VectorToolbarOverflowProps, type VectorToolbarProps, type VectorToolbarRenderContext, type VectorToolbarToolLockProps, type VectorToolbarToolProps, VectorViewportAssetKind, VectorViewportAssetStore, createIndexedDbPersistenceAdapter, createLocalStoragePersistenceAdapter, createNoopPersistenceAdapter, createToolPlugin, cursorForVectorToolId, ingestAssetFilesToSceneItems, useVectorCanvasDocument };
868
+ export { BoardComponentPosition, CanvasPlugin, CanvuAfterInteractionHook, CanvuBeforeInteractionHook, type CreateLocalStoragePersistenceAdapterOptions, type CreateToolPluginOptions, CustomShapePlacementOptions, DEFAULT_OVERFLOW_TOOL_IDS, DEFAULT_VECTOR_CANVAS_STORAGE_KEY, DEFAULT_VECTOR_TOOLS, IconArchitecturalCloud, IconArrow, IconDraw, IconEllipse, IconHand, IconImage, IconLaser, IconLine, IconRect, IconSelect, IconText, ImagesMenu, type ImagesMenuActionId, type ImagesMenuCollapsedButtonProps, type ImagesMenuCollapsedButtonRenderProps, type ImagesMenuLabels, type ImagesMenuProps, type IngestAssetFileError, type IngestAssetFilesToSceneItemsOptions, type IngestAssetFilesToSceneItemsResult, type IngestedAssetItemContext, NavMenu, type NavMenuMinimapProps, type NavMenuProps, type NavMenuUndoRedoProps, type NavMenuZoomControlsProps, type UseVectorCanvasDocumentOptions, type UseVectorCanvasDocumentResult, VectorCanvas, VectorCanvasBody, VectorCanvasHeader, VectorCanvasMain, VectorCanvasPersistenceAdapter, VectorCanvasRemoteAdapter, VectorCanvasRoot, type VectorCanvasSlotProps, type VectorCanvasSpaceProps, VectorCanvasToolbar, type VectorCanvasToolbarProps, VectorCanvasViewportSurface, VectorItemsChangeInfo, VectorSelectionInspector, VectorToolDefinition, VectorToolbar, type VectorToolbarOverflowProps, type VectorToolbarProps, type VectorToolbarRenderContext, type VectorToolbarToolLockProps, type VectorToolbarToolProps, VectorViewportAssetKind, VectorViewportAssetStore, createIndexedDbPersistenceAdapter, createLocalStoragePersistenceAdapter, createNoopPersistenceAdapter, createToolPlugin, cursorForVectorToolId, ingestAssetFilesToSceneItems, useVectorCanvasDocument };
package/dist/react.js CHANGED
@@ -2248,6 +2248,10 @@ var defaultLabels = {
2248
2248
  collapse: "Collapse images menu",
2249
2249
  expand: "Open images menu"
2250
2250
  };
2251
+ function getAddedItemIds(before, after) {
2252
+ const beforeIds = new Set(before.map((item) => item.id));
2253
+ return after.filter((item) => !beforeIds.has(item.id)).map((item) => item.id);
2254
+ }
2251
2255
  function ImagesMenu({
2252
2256
  items,
2253
2257
  onItemsChange,
@@ -2306,12 +2310,17 @@ function ImagesMenu({
2306
2310
  const onDragEnd = (event) => {
2307
2311
  const { active, over } = event;
2308
2312
  if (!over || active.id === over.id) return;
2309
- const oldIndex = managed.findIndex((i) => i.id === active.id);
2310
- const newIndex = managed.findIndex((i) => i.id === over.id);
2313
+ const activeId = String(active.id);
2314
+ const overId = String(over.id);
2315
+ const oldIndex = managed.findIndex((i) => i.id === activeId);
2316
+ const newIndex = managed.findIndex((i) => i.id === overId);
2311
2317
  if (oldIndex < 0 || newIndex < 0) return;
2312
2318
  const reorderedManaged = arrayMove(managed, oldIndex, newIndex);
2313
2319
  const orderedIds = reorderedManaged.map((i) => i.id);
2314
- onItemsChange(reorderManagedImages(items, orderedIds));
2320
+ onItemsChange(reorderManagedImages(items, orderedIds), {
2321
+ motive: "reorder",
2322
+ itemIds: [activeId]
2323
+ });
2315
2324
  };
2316
2325
  return /* @__PURE__ */ jsxs(
2317
2326
  "section",
@@ -2349,9 +2358,22 @@ function ImagesMenu({
2349
2358
  labels: resolvedLabels,
2350
2359
  hiddenActionSet,
2351
2360
  onFocus: onFocusItem ? () => onFocusItem(item) : void 0,
2352
- onCopy: () => onItemsChange(copyManagedImage(items, item.id)),
2353
- onRotate: () => onItemsChange(rotateManagedImage(items, item.id)),
2354
- onDelete: () => onItemsChange(deleteManagedImage(items, item.id))
2361
+ onCopy: () => {
2362
+ const next = copyManagedImage(items, item.id);
2363
+ const addedIds = getAddedItemIds(items, next);
2364
+ onItemsChange(next, {
2365
+ motive: "duplicate",
2366
+ itemIds: addedIds.length > 0 ? addedIds : [item.id]
2367
+ });
2368
+ },
2369
+ onRotate: () => onItemsChange(rotateManagedImage(items, item.id), {
2370
+ motive: "rotate",
2371
+ itemIds: [item.id]
2372
+ }),
2373
+ onDelete: () => onItemsChange(deleteManagedImage(items, item.id), {
2374
+ motive: "delete",
2375
+ itemIds: [item.id]
2376
+ })
2355
2377
  },
2356
2378
  item.id
2357
2379
  )) })
@@ -7752,6 +7774,22 @@ var SvgVectorRenderer = class {
7752
7774
  }
7753
7775
  };
7754
7776
 
7777
+ // src/scene/draw-stroke-memory.ts
7778
+ var DEFAULT_DRAW_STROKE_WIDTH = 10;
7779
+ function resolveDrawStrokeWidthMemory({
7780
+ toolId,
7781
+ previousToolId,
7782
+ currentStrokeWidth,
7783
+ lastDrawStrokeWidth
7784
+ }) {
7785
+ const leavingDrawTool = previousToolId === "draw" && toolId !== "draw";
7786
+ const nextLastDrawStrokeWidth = leavingDrawTool ? currentStrokeWidth : lastDrawStrokeWidth;
7787
+ return {
7788
+ drawStrokeWidth: nextLastDrawStrokeWidth,
7789
+ nextLastDrawStrokeWidth
7790
+ };
7791
+ }
7792
+
7755
7793
  // src/react/VectorViewport.tsx
7756
7794
  init_link_item();
7757
7795
 
@@ -9631,6 +9669,8 @@ var VectorViewport = forwardRef(
9631
9669
  ...DEFAULT_STROKE_STYLE,
9632
9670
  textFontSize: DEFAULT_TEXT_TOOL_FONT_SIZE
9633
9671
  });
9672
+ const lastDrawStrokeWidthRef = useRef(DEFAULT_DRAW_STROKE_WIDTH);
9673
+ const previousToolIdRef = useRef(null);
9634
9674
  const [strokeStyleState, setStrokeStyleState] = useState({
9635
9675
  ...DEFAULT_STROKE_STYLE,
9636
9676
  textFontSize: DEFAULT_TEXT_TOOL_FONT_SIZE
@@ -10703,6 +10743,14 @@ var VectorViewport = forwardRef(
10703
10743
  }, [renderFrame]);
10704
10744
  useEffect(() => {
10705
10745
  const current = strokeStyleRef.current;
10746
+ const { drawStrokeWidth, nextLastDrawStrokeWidth } = resolveDrawStrokeWidthMemory({
10747
+ toolId,
10748
+ previousToolId: previousToolIdRef.current,
10749
+ currentStrokeWidth: current.strokeWidth,
10750
+ lastDrawStrokeWidth: lastDrawStrokeWidthRef.current
10751
+ });
10752
+ lastDrawStrokeWidthRef.current = nextLastDrawStrokeWidth;
10753
+ previousToolIdRef.current = toolId;
10706
10754
  if (toolId === "marker") {
10707
10755
  setCurrentStrokeStyle({
10708
10756
  ...current,
@@ -10713,7 +10761,7 @@ var VectorViewport = forwardRef(
10713
10761
  if (isDefaultMarkerToolStyle(current)) {
10714
10762
  setCurrentStrokeStyle({
10715
10763
  stroke: DEFAULT_STROKE_STYLE.stroke,
10716
- strokeWidth: toolId === "draw" ? 10 : DEFAULT_STROKE_STYLE.strokeWidth,
10764
+ strokeWidth: toolId === "draw" ? drawStrokeWidth : DEFAULT_STROKE_STYLE.strokeWidth,
10717
10765
  strokeDash: current.strokeDash,
10718
10766
  textFontSize: current.textFontSize
10719
10767
  });
@@ -10721,7 +10769,7 @@ var VectorViewport = forwardRef(
10721
10769
  }
10722
10770
  setCurrentStrokeStyle({
10723
10771
  stroke: current.stroke,
10724
- strokeWidth: toolId === "draw" ? 10 : current.strokeWidth,
10772
+ strokeWidth: toolId === "draw" ? drawStrokeWidth : current.strokeWidth,
10725
10773
  strokeDash: current.strokeDash,
10726
10774
  textFontSize: current.textFontSize
10727
10775
  });