canvasAssetLibraryExtension<TSourceDocument> function

EditorExtension<TSourceDocument> canvasAssetLibraryExtension<TSourceDocument>({
  1. required CanvasAssetLibrary library,
  2. required CanvasAssetLibrarySelectionPresenter presentSelection,
})

Creates an editor extension that inserts assets selected from library.

The host owns the catalog and selection UI. The extension owns the shared editor behavior after selection:

  • persists CanvasAssetLibraryItem.sourceRef, never thumbnailRef;
  • preserves the intrinsic aspect ratio for the initial image size;
  • places the image at the centre of the artboard;
  • inserts through editor history and selects the new node.

The action is hidden when library contains no items.

Implementation

EditorExtension<TSourceDocument> canvasAssetLibraryExtension<TSourceDocument>({
  required CanvasAssetLibrary library,
  required CanvasAssetLibrarySelectionPresenter presentSelection,
}) {
  final hasAssets = library.items.isNotEmpty;

  return StaticEditorExtension<TSourceDocument>(
    actionSpecs: <EditorActionSpec>[
      EditorActionSpec(
        id: const EditorActionId('assetLibrary.open'),
        section: EditorToolbarSection.add,
        labelBuilder: (_) => 'Assets',
        iconBuilder: (_) => Icons.collections_outlined,
        isEnabled: (_) => hasAssets,
        isVisible: (_) => hasAssets,
        priority: 85,
        invoke: (context) async {
          final selected = await presentSelection(
            context.buildContext,
            library,
          );

          if (selected == null || !context.buildContext.mounted) {
            return;
          }

          final artboard = context.editableScene.artboardSize;
          final size = _initialAssetSize(selected);

          final node = ImageNode(
            id: _nextAssetNodeId(),
            data: ImageData(
              sourcePath: selected.sourceRef,
              size: size,
              fit: ImageFit.contain,
              align: const Vec2(0.5, 0.5),
            ),
            xf: Transform2D(position: Vec2(artboard.w * 0.5, artboard.h * 0.5)),
          );

          context.addNodeAndSelect(node);
        },
      ),
    ],
  );
}