Skip to content

BlockSuite API Documentation / @blocksuite/std / gfx

gfx

Enumerations

MouseButton

Enumeration Members

FIFTH

FIFTH: 4

FOURTH

FOURTH: 3

MAIN

MAIN: 0

MIDDLE

MIDDLE: 1

SECONDARY

SECONDARY: 2


SortOrder

Enumeration Members

AFTER

AFTER: 1

BEFORE

BEFORE: -1

SAME

SAME: 0

Classes

Extension

abstract GfxExtension

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Extended by
Constructors
Constructor

new GfxExtension(gfx): GfxExtension

Parameters
gfx

GfxController

Returns

GfxExtension

Overrides

Extension.constructor

Properties
gfx

protected readonly gfx: GfxController

key

static key: string

Accessors
std
Get Signature

get std(): BlockStdScope

Returns

BlockStdScope

Methods
mounted()

mounted(): void

Returns

void

unmounted()

unmounted(): void

Returns

void

extendGfx()

static extendGfx(_): void

Parameters
_

GfxController

Returns

void

setup()

static setup(di): void

Parameters
di

Container

Returns

void

Overrides

Extension.setup


GridManager

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Constructors
Properties
key

static key: string = 'grid'

Overrides

GfxExtension.key

Accessors
isEmpty
Get Signature

get isEmpty(): boolean

Returns

boolean

Methods
add()

add(element): void

Parameters
element

GfxModel | GfxLocalElementModel

Returns

void

boundHasChanged()

boundHasChanged(a, b): boolean

Parameters
a

IBound

b

IBound

Returns

boolean

has()

has(bound, strict, reverseChecking, filter?): boolean

Parameters
bound

IBound

strict

boolean = false

reverseChecking

boolean = false

If true, check if the bound is inside the elements instead of checking if the elements are inside the bound

filter?

(model) => boolean

Returns

boolean

mounted()

mounted(): void

Returns

void

Overrides

GfxExtension.mounted

remove()

remove(element): void

Parameters
element

GfxModel | GfxLocalElementModel

Returns

void

Call Signature

search<T>(bound, options?): BuiltInFilterModelMap[T][]

Search for elements in a bound.

Type Parameters
T

T extends "canvas" | "block" | "local" = "canvas" | "block"

Parameters
bound

IBound

options?
filter?

FilterFunc | (T | FilterFunc)[]

Use this to filter the elements, if not provided, it will return blocks and canvas elements by default

strict?

boolean

If true, only return elements that are completely inside the bound. Default is false.

useSet?

false

If true, return a set of elements instead of an array

Returns

BuiltInFilterModelMap[T][]

Call Signature

search<T>(bound, options): Set<BuiltInFilterModelMap[T]>

Search for elements in a bound.

Type Parameters
T

T extends "canvas" | "block" | "local" = "canvas" | "block"

Parameters
bound

IBound

options
filter?

FilterFunc | (T | FilterFunc)[]

strict?

boolean

useSet

true

Returns

Set<BuiltInFilterModelMap[T]>

unmounted()

unmounted(): void

Returns

void

Overrides

GfxExtension.unmounted

update()

update(element): void

Parameters
element

GfxModel | GfxLocalElementModel

Returns

void


InteractivityExtension

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Extended by
Constructors
Constructor

new InteractivityExtension(gfx): InteractivityExtension

Parameters
gfx

GfxController

Returns

InteractivityExtension

Overrides

Extension.constructor

Properties
action

action: Omit<InteractivityActionAPI, "emit">

event

event: Omit<InteractivityEventAPI, "emit">

gfx

protected readonly gfx: GfxController

key

static key: string

Accessors
std
Get Signature

get std(): BlockStdScope

Returns

BlockStdScope

Methods
mounted()

mounted(): void

Returns

void

unmounted()

unmounted(): void

Override this method should call super.unmounted()

Returns

void

setup()

static setup(di): void

Parameters
di

Container

Returns

void

Overrides

Extension.setup


InteractivityManager

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Constructors
Properties
activeInteraction$

activeInteraction$: Signal<{ elements: GfxModel[]; type: "move" | "resize" | "rotate"; } | null>

key

static key: string = 'interactivity-manager'

Overrides

GfxExtension.key

Accessors
interactExtensions
Get Signature

get interactExtensions(): Map<string, InteractivityExtension>

Returns

Map<string, InteractivityExtension>

keyboard
Get Signature

get keyboard(): KeyboardController

Returns

KeyboardController

Methods
dispatchEvent()

dispatchEvent(eventName, evt): { handledByView: boolean; preventDefaultState: boolean; } | undefined

Dispatch event to extensions and gfx view.

Parameters
eventName

ExtensionPointerHandler

evt

PointerEventState

Returns

{ handledByView: boolean; preventDefaultState: boolean; } | undefined

getResizeHandlers()

getResizeHandlers(options): ResizeHandle[]

Parameters
options
elements

GfxModel[]

Returns

ResizeHandle[]

getRotateConfig()

getRotateConfig(options): object

Parameters
options
elements

GfxModel[]

Returns

object

initialRotate

initialRotate: number

rotatable

rotatable: boolean

viewConfigMap

viewConfigMap: Map<string, { constraint: Required<RotateConstraint>; defaultHandlers: ViewRotateHandlers; handlers: ViewRotateHandlers; model: GfxModel; view: GfxBlockComponent<GfxBlockElementModel<GfxCompatibleProps>, BlockService, string> | GfxElementModelView<GfxPrimitiveElementModel<BaseElementProps> | GfxLocalElementModel, object>; }>

handleBoxSelection()

handleBoxSelection(context): GfxModel[]

Parameters
context
box

Readonly<IBound & object>

Returns

GfxModel[]

handleElementMove()

handleElementMove(options): void

Initialize elements movements. It will handle drag start, move and end events automatically. Note: Call this when mouse is already down.

Parameters
options

DragInitializationOption

Returns

void

handleElementResize()

handleElementResize(options): void

Parameters
options

Omit<OptionResize, "onResizeStart" | "onResizeMove" | "onResizeUpdate" | "onResizeEnd" | "lockRatio"> & object

Returns

void

handleElementRotate()

handleElementRotate(options): void

Parameters
options

Omit<RotateOption, "onRotateUpdate" | "onRotateStart" | "onRotateEnd"> & object

Returns

void

handleElementSelection()

handleElementSelection(evt): boolean

Handle element selection.

Parameters
evt

PointerEventState

The pointer event that triggered the selection.

Returns

boolean

True if the element was selected, false otherwise.

mounted()

mounted(): void

Returns

void

Overrides

GfxExtension.mounted

requestElementClone()

requestElementClone(options): Promise<{ elements: GfxModel[]; } | undefined>

Parameters
options

ExtensionElementsCloneContext

Returns

Promise<{ elements: GfxModel[]; } | undefined>

unmounted()

unmounted(): void

Returns

void

Overrides

GfxExtension.unmounted


LayerManager

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Constructors
Constructor

new LayerManager(gfx): LayerManager

Parameters
gfx

GfxController

Returns

LayerManager

Overrides

GfxExtension.constructor

Properties
blocks

blocks: GfxBlockElementModel<GfxCompatibleProps>[] = []

canvasElements

canvasElements: GfxPrimitiveElementModel<BaseElementProps>[] = []

canvasLayers

canvasLayers: object[] = []

elements

elements: GfxPrimitiveElementModel<BaseElementProps>[]

indexes

indexes: [string, string]

fractional index

set

set: Set<GfxPrimitiveElementModel<BaseElementProps>>

zIndex

zIndex: number

z-index, used for actual rendering

layers

layers: Layer[] = []

slots

slots: object

layerUpdated

layerUpdated: Subject<{ initiatingElement: GfxModel | GfxLocalElementModel; type: "delete" | "add" | "update"; }>

INITIAL_INDEX

static INITIAL_INDEX: string = 'a0'

key

static key: string = 'layerManager'

Overrides

GfxExtension.key

Accessors
Methods
add()

add(element): void

Parameters
element

GfxModel | GfxLocalElementModel

Returns

void

compare()

compare(a, b): SortOrder

Pass to the Array.sort to sort the elements by their index

Parameters
a

GfxModel

b

GfxModel

Returns

SortOrder

createIndexGenerator()

createIndexGenerator(): () => string

In some cases, we need to generate a bunch of indexes in advance before acutally adding the elements to the layer manager. Eg. when importing a template. The generateIndex is a function only depends on the current state of the manager. So we cannot use it because it will always return the same index if the element is not added to manager.

This function return a index generator that can "remember" the index it generated without actually adding the element to the manager.

Returns

(): string

Returns

string

Note

The generator cannot work with group element.

delete()

delete(element): void

Parameters
element

GfxModel | GfxLocalElementModel

Returns

void

generateIndex()

generateIndex(reverse): string

Parameters
reverse

boolean = false

if true, generate the index in reverse order

Returns

string

getCanvasLayers()

getCanvasLayers(): object[]

Returns
getReorderedIndex()

getReorderedIndex(element, direction): string

Parameters
element

GfxModel

direction

ReorderingDirection

Returns

string

getZIndex()

getZIndex(element): number

Parameters
element

GfxModel

Returns

number

mounted()

mounted(): void

Returns

void

Overrides

GfxExtension.mounted

unmounted()

unmounted(): void

Returns

void

Overrides

GfxExtension.unmounted

update()

update(element, props?, oldValues?): void

Parameters
element

GfxModel | GfxLocalElementModel

props?

Record<string, unknown>

oldValues?

Record<string, unknown>

Returns

void


abstract SurfaceMiddlewareBuilder

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Extended by
Constructors
Constructor

new SurfaceMiddlewareBuilder(std): SurfaceMiddlewareBuilder

Parameters
std

BlockStdScope

Returns

SurfaceMiddlewareBuilder

Overrides

Extension.constructor

Properties
middleware

abstract middleware: SurfaceMiddleware

std

protected std: BlockStdScope

key

static key: string = ''

Accessors
gfx
Get Signature

get gfx(): GfxController

Returns

GfxController

Methods
mounted()

mounted(): void

Returns

void

unmounted()

unmounted(): void

Returns

void

setup()

static setup(di): void

Parameters
di

Container

Returns

void

Overrides

Extension.setup


ToolController

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Constructors
Properties
currentToolName$

readonly currentToolName$: Signal<string>

dragging$

readonly dragging$: Signal<boolean>

draggingArea$

readonly draggingArea$: Signal<IBound & object>

The area that is being dragged. The coordinates are in model space.

draggingViewArea$

readonly draggingViewArea$: Signal<IBound & object>

The dragging area in browser coordinates space.

draggingViewportArea$

readonly draggingViewportArea$: ReadonlySignal<{ endX: number; endY: number; h: number; startX: number; startY: number; w: number; x: number; y: number; }>

The dragging area in browser coordinates space.

This is similar to draggingViewArea$, but if the viewport is changed during dragging, it will be reflected in this area.

lastMousePos$

readonly lastMousePos$: ReadonlySignal<{ x: number; y: number; }>

The last mouse position in model coordinates space.

lastMouseViewPos$

readonly lastMouseViewPos$: Signal<IPoint>

The last mouse move position in browser coordinates space.

key

static key: string = 'ToolController'

Overrides

GfxExtension.key

Accessors
currentTool$
Get Signature

get currentTool$(): object

Returns

object

value
Get Signature

get value(): BaseTool<Record<string, unknown>> | undefined

Returns

BaseTool<Record<string, unknown>> | undefined

peek()

peek(): BaseTool<Record<string, unknown>> | undefined

Returns

BaseTool<Record<string, unknown>> | undefined

currentToolOption$
Get Signature

get currentToolOption$(): object

Returns

object

value
Get Signature

get value(): ToolOptionWithType

Returns

ToolOptionWithType

peek()

peek(): ToolOptionWithType

Returns

ToolOptionWithType

Methods
get()

get<T>(type): T

Type Parameters
T

T extends BaseTool<Record<string, unknown>>

Parameters
type

ToolType<T>

Returns

T

mounted()

mounted(): void

Returns

void

Overrides

GfxExtension.mounted

setTool()

setTool<T>(toolType, options?): void

Type Parameters
T

T extends BaseTool<Record<string, unknown>>

Parameters
toolType

ToolType<T>

options?

ToolOptions<T>

Returns

void

unmounted()

unmounted(): void

Returns

void

Overrides

GfxExtension.unmounted

extendGfx()

static extendGfx(gfx): void

Parameters
gfx

GfxController

Returns

void

Overrides

GfxExtension.extendGfx


abstract BaseTool<Option>

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Extended by
Type Parameters
Option

Option = Record<string, unknown>

Constructors
Constructor

new BaseTool<Option>(gfx): BaseTool<Option>

Parameters
gfx

GfxController

Returns

BaseTool<Option>

Overrides

Extension.constructor

Properties
activatedOption

activatedOption: Option

addHook()

addHook: <K>(evtName, handler) => void

Add a hook before the event is handled by the tool. Return false to prevent the tool from handling the event.

Type Parameters
K

K extends "click" | "doubleClick" | "tripleClick" | "pointerDown" | "pointerMove" | "pointerUp" | "pointerOut" | "dragStart" | "dragMove" | "dragEnd" | "contextMenu" | keyof BuiltInEventMap

Parameters
evtName

K

handler

(evtState) => boolean | void

Returns

void

disposable

protected readonly disposable: DisposableGroup

The disposable will be disposed when the tool is unloaded.

gfx

readonly gfx: GfxController

toolName

static toolName: string = ''

Accessors
active
Get Signature

get active(): boolean

Returns

boolean

allowDragWithRightButton
Get Signature

get allowDragWithRightButton(): boolean

Returns

boolean

controller
Get Signature

get controller(): ToolController

Returns

ToolController

doc
Get Signature

get doc(): Store

Returns

Store

std
Get Signature

get std(): BlockStdScope

Returns

BlockStdScope

toolName
Get Signature

get toolName(): string

Returns

string

Methods
activate()

activate(_): void

Called when the tool is activated.

Parameters
_

Option

The data passed as second argument when calling ToolController.use.

Returns

void

click()

click(_): void

Parameters
_

PointerEventState

Returns

void

contextMenu()

contextMenu(_): void

Parameters
_

PointerEventState

Returns

void

deactivate()

deactivate(): void

Called when the tool is deactivated.

Returns

void

doubleClick()

doubleClick(_): void

Parameters
_

PointerEventState

Returns

void

dragEnd()

dragEnd(_): void

Parameters
_

PointerEventState

Returns

void

dragMove()

dragMove(_): void

Parameters
_

PointerEventState

Returns

void

dragStart()

dragStart(_): void

Parameters
_

PointerEventState

Returns

void

mounted()

mounted(): void

Called when the tool is registered.

Returns

void

pointerDown()

pointerDown(_): void

Parameters
_

PointerEventState

Returns

void

pointerMove()

pointerMove(_): void

Parameters
_

PointerEventState

Returns

void

pointerOut()

pointerOut(_): void

Parameters
_

PointerEventState

Returns

void

pointerUp()

pointerUp(_): void

Parameters
_

PointerEventState

Returns

void

tripleClick()

tripleClick(_): void

Parameters
_

PointerEventState

Returns

void

unmounted()

unmounted(): void

Called when the tool is unloaded, usually when the whole ToolController is destroyed.

Returns

void

setup()

static setup(di): void

Parameters
di

Container

Returns

void

Overrides

Extension.setup


ViewManager

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Constructors
Constructor

new ViewManager(gfx): ViewManager

Parameters
gfx

GfxController

Returns

ViewManager

Overrides

GfxExtension.constructor

Properties
key

static key: string = 'viewManager'

Overrides

GfxExtension.key

Accessors
Methods
get()

get(model): GfxBlockComponent<GfxBlockElementModel<GfxCompatibleProps>, BlockService, string> | GfxElementModelView<GfxPrimitiveElementModel<BaseElementProps> | GfxLocalElementModel, object> | null

Parameters
model

string | GfxModel | GfxLocalElementModel

Returns

GfxBlockComponent<GfxBlockElementModel<GfxCompatibleProps>, BlockService, string> | GfxElementModelView<GfxPrimitiveElementModel<BaseElementProps> | GfxLocalElementModel, object> | null

mounted()

mounted(): void

Returns

void

Overrides

GfxExtension.mounted

unmounted()

unmounted(): void

Returns

void

Overrides

GfxExtension.unmounted

extendGfx()

static extendGfx(gfx): void

Parameters
gfx

GfxController

Returns

void

Overrides

GfxExtension.extendGfx

Other

GfxController

A life cycle watcher is an extension that watches the life cycle of the editor. It is used to perform actions when the editor is created, mounted, rendered, or unmounted.

When creating a life cycle watcher, you must define a key that is unique to the watcher. The key is used to identify the watcher in the dependency injection container.

ts
class MyLifeCycleWatcher extends LifeCycleWatcher {
 static override readonly key = 'my-life-cycle-watcher';

In the life cycle watcher, the methods will be called in the following order:

  1. created: Called when the std is created.
  2. rendered: Called when std.render is called.
  3. mounted: Called when the editor host is mounted.
  4. unmounted: Called when the editor host is unmounted.
Extends
Constructors
Constructor

new GfxController(std): GfxController

Parameters
std

BlockStdScope

Returns

GfxController

Overrides

LifeCycleWatcher.constructor

Properties
cursor$

readonly cursor$: Signal<CursorType>

keyboard

readonly keyboard: KeyboardController

selection

readonly selection: GfxSelectionManager

tool

readonly tool: ToolController

view

readonly view: ViewManager

viewport

readonly viewport: Viewport

key

static key: string = gfxControllerKey

Overrides

LifeCycleWatcher.key

Accessors
doc
Get Signature

get doc(): Store

Returns

Store

elementsBound
Get Signature

get elementsBound(): Bound

Returns

Bound

gfxElements
Get Signature

get gfxElements(): GfxModel[]

Returns

GfxModel[]

grid
Get Signature

get grid(): GridManager

Returns

GridManager

layer
Get Signature

get layer(): LayerManager

Returns

LayerManager

surface
Get Signature

get surface(): SurfaceBlockModel | null

Returns

SurfaceBlockModel | null

surface$
Get Signature

get surface$(): Signal<SurfaceBlockModel | null>

Returns

Signal<SurfaceBlockModel | null>

surfaceComponent
Get Signature

get surfaceComponent(): BlockComponent<BlockModel<object>, BlockService, string> | null

Returns

BlockComponent<BlockModel<object>, BlockService, string> | null

Methods
deleteElement()

deleteElement(element): void

Parameters
element

string | BlockModel<object> | GfxModel

Returns

void

fitToScreen()

fitToScreen(options): void

Parameters
options
bounds?

Bound[]

padding?

[number, number, number, number]

smooth?

boolean

Returns

void

getElementById()

getElementById<T>(id): T | null

Get a block or element by its id. Note that non-gfx block can also be queried in this method.

Type Parameters
T

T extends BlockModel<object> | GfxModel = BlockModel<object> | GfxModel

Parameters
id

string

Returns

T | null

getElementByPoint()
Call Signature

getElementByPoint(x, y, options): GfxModel[]

Get elements on a specific point.

Parameters
x

number

y

number

options

object & PointTestOptions

Returns

GfxModel[]

Call Signature

getElementByPoint(x, y, options?): GfxModel | null

Get elements on a specific point.

Parameters
x

number

y

number

options?

object & PointTestOptions

Returns

GfxModel | null

getElementsByBound()
Call Signature

getElementsByBound(bound, options?): GfxModel[]

Query all elements in an area.

Parameters
bound

IBound | Bound

options?
type

"all"

Returns

GfxModel[]

Call Signature

getElementsByBound(bound, options): GfxPrimitiveElementModel<BaseElementProps>[]

Query all elements in an area.

Parameters
bound

IBound | Bound

options
type

"canvas"

Returns

GfxPrimitiveElementModel<BaseElementProps>[]

Call Signature

getElementsByBound(bound, options): GfxBlockElementModel<GfxCompatibleProps>[]

Query all elements in an area.

Parameters
bound

IBound | Bound

options
type

"block"

Returns

GfxBlockElementModel<GfxCompatibleProps>[]

getElementsByType()

getElementsByType(type): (BlockModel<object> | GfxModel)[]

Parameters
type

string

Returns

(BlockModel<object> | GfxModel)[]

mounted()

mounted(): void

Called when editor host is mounted. Which means the editor host emit the connectedCallback lifecycle event.

Returns

void

Overrides

LifeCycleWatcher.mounted

unmounted()

unmounted(): void

Called when editor host is unmounted. Which means the editor host emit the disconnectedCallback lifecycle event.

Returns

void

Overrides

LifeCycleWatcher.unmounted

updateElement()

updateElement(element, props): void

Parameters
element

string | GfxModel

props

Record<string, unknown>

Returns

void


GfxViewEventManager

Constructors
Constructor

new GfxViewEventManager(gfx): GfxViewEventManager

Parameters
gfx

GfxController

Returns

GfxViewEventManager

Methods
dispatch()

dispatch(eventName, evt): boolean | undefined

Parameters
eventName

keyof EventsHandlerMap

evt

PointerEventState

Returns

boolean | undefined


GfxBlockElementModel<Props>

The graphic block model that can be rendered in the graphics mode. All the graphic block model should extend this class. You can use GfxCompatibleBlockModel to convert a BlockModel to a subclass that extends it.

Extends
Extended by
Type Parameters
Props

Props extends GfxCompatibleProps = GfxCompatibleProps

Implements
Constructors
Properties
connectable

connectable: boolean = true

responseExtension

responseExtension: [number, number]

Defines the extension of the response area beyond the element's bounding box. This tuple specifies the horizontal and vertical margins to be added to the element's [x, y, width, height].

The first value represents the horizontal extension (added to both left and right sides), and the second value represents the vertical extension (added to both top and bottom sides).

The response area is computed as: [x - horizontal, y - vertical, width + 2 * horizontal, height + 2 * vertical].

Example:

  • Bounding box: [0, 0, 100, 100], responseExtension: [10, 20] Resulting response area: [-10, -20, 120, 140].
  • responseExtension: [0, 0] keeps the response area equal to the bounding box.
Implementation of

GfxCompatibleInterface.responseExtension

Accessors
deserializedXYWH
Get Signature

get deserializedXYWH(): XYWH

Returns

XYWH

Implementation of

GfxCompatibleInterface.deserializedXYWH

elementBound
Get Signature

get elementBound(): Bound

The bound of the element without considering the response extension.

Returns

Bound

The bound of the element without considering the response extension.

Implementation of

GfxCompatibleInterface.elementBound

externalBound
Get Signature

get externalBound(): Bound | null

Returns

Bound | null

externalXYWH
Get Signature

get externalXYWH(): `[${number},${number},${number},${number}]` | undefined

Returns

`[${number},${number},${number},${number}]` | undefined

Set Signature

set externalXYWH(xywh): void

Parameters
xywh

`[${number},${number},${number},${number}]` | undefined

Returns

void

group
Get Signature

get group(): GfxGroupModel | null

Returns

GfxGroupModel | null

Implementation of

GfxCompatibleInterface.group

groups
Get Signature

get groups(): GfxGroupModel[]

Returns

GfxGroupModel[]

Implementation of

GfxCompatibleInterface.groups

h
Get Signature

get h(): number

Returns

number

Implementation of

GfxCompatibleInterface.h

index
Get Signature

get index(): string

Returns

string

Set Signature

set index(index): void

Parameters
index

string

Returns

void

Implementation of

GfxCompatibleInterface.index

index$
Get Signature

get index$(): Signal<Props["index"]>

Returns

Signal<Props["index"]>

lockedBySelf
Get Signature

get lockedBySelf(): boolean | undefined

Indicates whether the current block is explicitly locked by self. For checking the lock status of the element, use isLocked instead. For (un)locking the element, use (un)lock instead.

Returns

boolean | undefined

Set Signature

set lockedBySelf(lockedBySelf): void

Indicates whether the current block is explicitly locked by self. For checking the lock status of the element, use isLocked instead. For (un)locking the element, use (un)lock instead.

Parameters
lockedBySelf

boolean | undefined

Returns

void

Indicates whether the current block is explicitly locked by self. For checking the lock status of the element, use isLocked instead. For (un)locking the element, use (un)lock instead.

Implementation of

GfxCompatibleInterface.lockedBySelf

lockedBySelf$
Get Signature

get lockedBySelf$(): Signal<Props["lockedBySelf"]>

Returns

Signal<Props["lockedBySelf"]>

responseBound
Get Signature

get responseBound(): Bound

The bound of the element considering the response extension.

Returns

Bound

The bound of the element considering the response extension.

Implementation of

GfxCompatibleInterface.responseBound

rotate
Get Signature

get rotate(): number

Returns

number

Set Signature

set rotate(rotate): void

Parameters
rotate

number

Returns

void

Implementation of

GfxCompatibleInterface.rotate

surface
Get Signature

get surface(): SurfaceBlockModel | null

Returns

SurfaceBlockModel | null

w
Get Signature

get w(): number

Returns

number

Implementation of

GfxCompatibleInterface.w

x
Get Signature

get x(): number

Returns

number

Implementation of

GfxCompatibleInterface.x

xywh
Get Signature

get xywh(): `[${number},${number},${number},${number}]`

Returns

`[${number},${number},${number},${number}]`

Set Signature

set xywh(xywh): void

Parameters
xywh

`[${number},${number},${number},${number}]`

Returns

void

Implementation of

GfxCompatibleInterface.xywh

xywh$
Get Signature

get xywh$(): Signal<Props["xywh"]>

Returns

Signal<Props["xywh"]>

y
Get Signature

get y(): number

Returns

number

Implementation of

GfxCompatibleInterface.y

Methods
containsBound()

containsBound(bounds): boolean

Parameters
bounds

Bound

Returns

boolean

Implementation of

GfxCompatibleInterface.containsBound

getLineIntersections()

getLineIntersections(start, end): PointLocation[] | null

Parameters
start

IVec

end

IVec

Returns

PointLocation[] | null

Implementation of

GfxCompatibleInterface.getLineIntersections

getNearestPoint()

getNearestPoint(point): IVec

Parameters
point

IVec

Returns

IVec

Implementation of

GfxCompatibleInterface.getNearestPoint

getRelativePointLocation()

getRelativePointLocation(relativePoint): PointLocation

Parameters
relativePoint

IVec

Returns

PointLocation

Implementation of

GfxCompatibleInterface.getRelativePointLocation

includesPoint()

includesPoint(x, y, opt, __): boolean

Parameters
x

number

y

number

opt

PointTestOptions

__

EditorHost

Returns

boolean

Implementation of

GfxCompatibleInterface.includesPoint

intersectsBound()

intersectsBound(bound): boolean

Parameters
bound

Bound

Returns

boolean

Implementation of

GfxCompatibleInterface.intersectsBound

isLocked()

isLocked(): boolean

Check if the element is locked. It will check the lock status of the element and its ancestors.

Returns

boolean

Implementation of

GfxCompatibleInterface.isLocked

isLockedByAncestor()

isLockedByAncestor(): boolean

Returns

boolean

Implementation of

GfxCompatibleInterface.isLockedByAncestor

isLockedBySelf()

isLockedBySelf(): boolean

Returns

boolean

Implementation of

GfxCompatibleInterface.isLockedBySelf

lock()

lock(): void

Returns

void

Implementation of

GfxCompatibleInterface.lock

unlock()

unlock(): void

Returns

void

Implementation of

GfxCompatibleInterface.unlock


abstract GfxGroupLikeElementModel<Props>

GfxGroupCompatibleElement is a model that can contain other models. It just like a group that in common graphic software.

Extends
Extended by
Type Parameters
Props

Props extends BaseElementProps = BaseElementProps

Implements
Constructors
Properties
[gfxGroupCompatibleSymbol]

[gfxGroupCompatibleSymbol]: true

Implementation of

GfxGroupCompatibleInterface.[gfxGroupCompatibleSymbol]

children

abstract children: YMap<any>

Accessors
childElements
Get Signature

get childElements(): GfxModel[]

All child element models of this container. Note that the childElements may not contains all the children in childIds, because some children may not be loaded.

Returns

GfxModel[]

All child element models of this container. Note that the childElements may not contains all the children in childIds, because some children may not be loaded.

Implementation of

GfxGroupCompatibleInterface.childElements

childIds
Get Signature

get childIds(): string[]

The ids of the children. Its role is to provide a unique way to access the children. You should update this field through setChildIds when the children are added or removed.

Returns

string[]

All child ids of this container.

Implementation of

GfxGroupCompatibleInterface.childIds

descendantElements
Get Signature

get descendantElements(): GfxModel[]

Returns

GfxModel[]

Implementation of

GfxGroupCompatibleInterface.descendantElements

xywh
Get Signature

get xywh(): `[${number},${number},${number},${number}]`

Returns

`[${number},${number},${number},${number}]`

Set Signature

set xywh(_): void

Parameters
_

`[${number},${number},${number},${number}]`

Returns

void

Implementation of

GfxGroupCompatibleInterface.xywh

Overrides

GfxPrimitiveElementModel.xywh

Methods
_getXYWH()

protected _getXYWH(): Bound

Returns

Bound

addChild()

abstract addChild(element): void

Parameters
element

GfxModel

Returns

void

Implementation of

GfxGroupCompatibleInterface.addChild

hasChild()

hasChild(element): boolean

The actual field that stores the children of the group. It should be a ymap decorated with @field.

Parameters
element

GfxCompatibleInterface

Returns

boolean

Implementation of

GfxGroupCompatibleInterface.hasChild

hasDescendant()

hasDescendant(element): boolean

Check if the group has the given descendant.

Parameters
element

GfxCompatibleInterface

Returns

boolean

Implementation of

GfxGroupCompatibleInterface.hasDescendant

invalidateXYWH()

invalidateXYWH(): void

Returns

void

refreshXYWH()

refreshXYWH(local): void

Parameters
local

boolean

Returns

void

removeChild()

abstract removeChild(element): void

Remove the child from the group

Parameters
element

GfxCompatibleInterface

Returns

void

Implementation of

GfxGroupCompatibleInterface.removeChild

setChildIds()

setChildIds(value, fromLocal): void

Set the new value of the childIds

Parameters
value

string[]

the new value of the childIds

fromLocal

boolean

if true, the change is happened in the local

Returns

void


abstract GfxPrimitiveElementModel<Props>

All the model that can be rendered in graphics mode should implement this interface.

Extended by
Type Parameters
Props

Props extends BaseElementProps = BaseElementProps

Implements
Constructors
Constructor

new GfxPrimitiveElementModel<Props>(options): GfxPrimitiveElementModel<Props>

Parameters
options
id

string

model

SurfaceBlockModel

onChange

(payload) => void

stashedStore

Map<unknown, unknown>

yMap

YMap<unknown>

Returns

GfxPrimitiveElementModel<Props>

Properties
_disposable

protected _disposable: DisposableGroup

_id

protected _id: string

_local

protected _local: Map<string | symbol, unknown>

_onChange()

protected _onChange: (payload) => void

Parameters
payload
local

boolean

oldValues

Record<string, unknown>

props

Record<string, unknown>

Returns

void

_preserved

protected _preserved: Map<string, unknown>

Used to store a copy of data in the yMap.

_stashed

protected _stashed: Map<string | keyof Props, unknown>

propsUpdated

propsUpdated: Subject<{ key: string; }>

rotate

abstract rotate: number

Implementation of

GfxCompatibleInterface.rotate

surface

surface: SurfaceBlockModel

xywh

abstract xywh: `[${number},${number},${number},${number}]`

Implementation of

GfxCompatibleInterface.xywh

yMap

yMap: YMap<unknown>

Accessors
comments
connectable
Get Signature

get connectable(): boolean

Returns

boolean

deserializedXYWH
Get Signature

get deserializedXYWH(): XYWH

Returns

XYWH

Implementation of

GfxCompatibleInterface.deserializedXYWH

display
elementBound
Get Signature

get elementBound(): Bound

The bound of the element after rotation. The bound without rotation should be created by Bound.deserialize(this.xywh).

Returns

Bound

The bound of the element without considering the response extension.

Implementation of

GfxCompatibleInterface.elementBound

externalBound
Get Signature

get externalBound(): Bound | null

Returns

Bound | null

externalXYWH

In some cases, you need to draw something related to the element, but it does not belong to the element itself. And it is also interactive, you can select element by clicking on it. E.g. the title of the group element. In this case, we need to store this kind of external xywh in order to do hit test. This property should not be synced to the doc. This property should be updated every time it gets rendered.

group
Get Signature

get group(): GfxGroupModel | null

Returns

GfxGroupModel | null

Implementation of

GfxCompatibleInterface.group

groups
Get Signature

get groups(): GfxGroupModel[]

Return the ancestor elements in order from the most recent to the earliest.

Returns

GfxGroupModel[]

Implementation of

GfxCompatibleInterface.groups

h
Get Signature

get h(): number

Returns

number

Implementation of

GfxCompatibleInterface.h

hidden
id
Get Signature

get id(): string

Returns

string

index
Implementation of

GfxCompatibleInterface.index

isConnected
Get Signature

get isConnected(): boolean

Returns

boolean

lockedBySelf

Indicates whether the current block is explicitly locked by self. For checking the lock status of the element, use isLocked instead. For (un)locking the element, use (un)lock instead.

Implementation of

GfxCompatibleInterface.lockedBySelf

opacity
responseBound
Get Signature

get responseBound(): Bound

The bound of the element considering the response extension.

Returns

Bound

The bound of the element considering the response extension.

Implementation of

GfxCompatibleInterface.responseBound

responseExtension

Defines the extension of the response area beyond the element's bounding box. This tuple specifies the horizontal and vertical margins to be added to the element's bound.

The first value represents the horizontal extension (added to both left and right sides), and the second value represents the vertical extension (added to both top and bottom sides).

The response area is computed as: [x - horizontal, y - vertical, w + 2 * horizontal, h + 2 * vertical].

Example:

  • xywh: [0, 0, 100, 100], responseExtension: [10, 20] Resulting response area: [-10, -20, 120, 140].
  • responseExtension: [0, 0] keeps the response area equal to the bounding box.
Implementation of

GfxCompatibleInterface.responseExtension

seed
type
Get Signature

get abstract type(): string

Returns

string

w
Get Signature

get w(): number

Returns

number

Implementation of

GfxCompatibleInterface.w

x
Get Signature

get x(): number

Returns

number

Implementation of

GfxCompatibleInterface.x

y
Get Signature

get y(): number

Returns

number

Implementation of

GfxCompatibleInterface.y

Methods
containsBound()

containsBound(bounds): boolean

Parameters
bounds

Bound

Returns

boolean

Implementation of

GfxCompatibleInterface.containsBound

getLineIntersections()

getLineIntersections(start, end): PointLocation[] | null

Parameters
start

IVec

end

IVec

Returns

PointLocation[] | null

Implementation of

GfxCompatibleInterface.getLineIntersections

getNearestPoint()

getNearestPoint(point): IVec

Parameters
point

IVec

Returns

IVec

Implementation of

GfxCompatibleInterface.getNearestPoint

getRelativePointLocation()

getRelativePointLocation(relativePoint): PointLocation

Parameters
relativePoint

IVec

Returns

PointLocation

Implementation of

GfxCompatibleInterface.getRelativePointLocation

includesPoint()

includesPoint(x, y, opt, __): boolean

Parameters
x

number

y

number

opt

PointTestOptions

__

EditorHost

Returns

boolean

Implementation of

GfxCompatibleInterface.includesPoint

intersectsBound()

intersectsBound(bound): boolean

Parameters
bound

Bound

Returns

boolean

Implementation of

GfxCompatibleInterface.intersectsBound

isLocked()

isLocked(): boolean

Check if the element is locked. It will check the lock status of the element and its ancestors.

Returns

boolean

Implementation of

GfxCompatibleInterface.isLocked

isLockedByAncestor()

isLockedByAncestor(): boolean

Returns

boolean

Implementation of

GfxCompatibleInterface.isLockedByAncestor

isLockedBySelf()

isLockedBySelf(): boolean

Returns

boolean

Implementation of

GfxCompatibleInterface.isLockedBySelf

lock()

lock(): void

Returns

void

Implementation of

GfxCompatibleInterface.lock

onCreated()

onCreated(): void

Returns

void

onDestroyed()

onDestroyed(): void

Returns

void

pop()

pop(prop): void

Parameters
prop

string | keyof Props

Returns

void

serialize()

serialize(): SerializedElement

Returns

SerializedElement

stash()

stash(prop): void

Parameters
prop

string | keyof Props

Returns

void

unlock()

unlock(): void

Returns

void

Implementation of

GfxCompatibleInterface.unlock


abstract GfxLocalElementModel

All the model that can be rendered in graphics mode should implement this interface.

Extended by
Implements
Constructors
Constructor

new GfxLocalElementModel(surfaceModel): GfxLocalElementModel

Parameters
surfaceModel

SurfaceBlockModel

Returns

GfxLocalElementModel

Properties
_local

protected _local: Map<string | symbol, unknown>

_props

protected _props: Set<string | symbol>

Used to store all the name of the properties that have been decorated with the @prop

_surface

protected _surface: SurfaceBlockModel

cache

cache: Map<string | symbol, unknown>

used to store the properties' cache key when the properties required heavy computation

creator

creator: GfxModel | null = null

id

id: string = ''

type

abstract readonly type: string

Accessors
deserializedXYWH
Get Signature

get deserializedXYWH(): XYWH

Returns

XYWH

Implementation of

GfxCompatibleInterface.deserializedXYWH

elementBound
Get Signature

get elementBound(): Bound

The bound of the element without considering the response extension.

Returns

Bound

The bound of the element without considering the response extension.

Implementation of

GfxCompatibleInterface.elementBound

group
Get Signature

get group(): GfxGroupModel | null

Returns

GfxGroupModel | null

Implementation of

GfxCompatibleInterface.group

groupId
groups
Get Signature

get groups(): GfxGroupModel[]

Returns

GfxGroupModel[]

Implementation of

GfxCompatibleInterface.groups

h
Get Signature

get h(): number

Returns

number

Implementation of

GfxCompatibleInterface.h

hidden
index
Implementation of

GfxCompatibleInterface.index

opacity
responseBound
Get Signature

get responseBound(): Bound

The bound of the element considering the response extension.

Returns

Bound

The bound of the element considering the response extension.

Implementation of

GfxCompatibleInterface.responseBound

responseExtension

Defines the extension of the response area beyond the element's bounding box. This tuple specifies the horizontal and vertical margins to be added to the element's bound.

The first value represents the horizontal extension (added to both left and right sides), and the second value represents the vertical extension (added to both top and bottom sides).

The response area is computed as: [x - horizontal, y - vertical, w + 2 * horizontal, h + 2 * vertical].

Example:

  • xywh: [0, 0, 100, 100], responseExtension: [10, 20] Resulting response area: [-10, -20, 120, 140].
  • responseExtension: [0, 0] keeps the response area equal to the bounding box.
Implementation of

GfxCompatibleInterface.responseExtension

rotate
Implementation of

GfxCompatibleInterface.rotate

seed
surface
Get Signature

get surface(): SurfaceBlockModel

Returns

SurfaceBlockModel

w
Get Signature

get w(): number

Returns

number

Implementation of

GfxCompatibleInterface.w

x
Get Signature

get x(): number

Returns

number

Implementation of

GfxCompatibleInterface.x

xywh
Implementation of

GfxCompatibleInterface.xywh

y
Get Signature

get y(): number

Returns

number

Implementation of

GfxCompatibleInterface.y

Methods
containsBound()

containsBound(bounds): boolean

Parameters
bounds

Bound

Returns

boolean

Implementation of

GfxCompatibleInterface.containsBound

getLineIntersections()

getLineIntersections(start, end): PointLocation[] | null

Parameters
start

IVec

end

IVec

Returns

PointLocation[] | null

Implementation of

GfxCompatibleInterface.getLineIntersections

getNearestPoint()

getNearestPoint(point): IVec

Parameters
point

IVec

Returns

IVec

Implementation of

GfxCompatibleInterface.getNearestPoint

getRelativePointLocation()

getRelativePointLocation(relativePoint): PointLocation

Parameters
relativePoint

IVec

Returns

PointLocation

Implementation of

GfxCompatibleInterface.getRelativePointLocation

includesPoint()

includesPoint(x, y, opt, __): boolean

Parameters
x

number

y

number

opt

PointTestOptions

__

EditorHost

Returns

boolean

Implementation of

GfxCompatibleInterface.includesPoint

intersectsBound()

intersectsBound(bound): boolean

Parameters
bound

Bound

Returns

boolean

Implementation of

GfxCompatibleInterface.intersectsBound

isLocked()

isLocked(): boolean

Check if the element is locked. It will check the lock status of the element and its ancestors.

Returns

boolean

Implementation of

GfxCompatibleInterface.isLocked

isLockedByAncestor()

isLockedByAncestor(): boolean

Returns

boolean

Implementation of

GfxCompatibleInterface.isLockedByAncestor

isLockedBySelf()

isLockedBySelf(): boolean

Returns

boolean

Implementation of

GfxCompatibleInterface.isLockedBySelf

lock()

lock(): void

Returns

void

Implementation of

GfxCompatibleInterface.lock

unlock()

unlock(): void

Returns

void

Implementation of

GfxCompatibleInterface.unlock


SurfaceBlockModel

Extends
Extended by
Constructors
Constructor

new SurfaceBlockModel(): SurfaceBlockModel

Returns

SurfaceBlockModel

Overrides

BlockModel.constructor

Properties
_decoratorState

protected _decoratorState: object

creating

creating: boolean = false

deriving

deriving: boolean = false

skipField

skipField: boolean = false

_elementCtorMap

protected _elementCtorMap: Record<string, Constructor<GfxPrimitiveElementModel, ConstructorParameters<typeof GfxPrimitiveElementModel>>>

_elementModels

protected _elementModels: Map<string, { model: GfxPrimitiveElementModel; mount: () => void; unmount: () => void; }>

_elementTypeMap

protected _elementTypeMap: Map<string, GfxPrimitiveElementModel<BaseElementProps>[]>

_groupChildIdsMap

protected _groupChildIdsMap: Map<string, string[]>

_groupLikeModels

protected _groupLikeModels: Map<string, GfxGroupModel>

_middlewares

protected _middlewares: SurfaceMiddleware[] = []

_parentGroupMap

protected _parentGroupMap: Map<string, string>

_surfaceBlockModel

protected _surfaceBlockModel: boolean = true

elementAdded

elementAdded: Subject<{ id: string; local: boolean; }>

elementRemoved

elementRemoved: Subject<{ id: string; local: boolean; model: GfxPrimitiveElementModel; type: string; }>

elementUpdated

elementUpdated: Subject<ElementUpdatedData>

localElementAdded

localElementAdded: Subject<GfxLocalElementModel>

localElementDeleted

localElementDeleted: Subject<GfxLocalElementModel>

localElements

protected localElements: Set<GfxLocalElementModel>

localElementUpdated

localElementUpdated: Subject<{ model: GfxLocalElementModel; oldValues: Record<string, unknown>; props: Record<string, unknown>; }>

Accessors
elementModels
Get Signature

get elementModels(): GfxPrimitiveElementModel<BaseElementProps>[]

Returns

GfxPrimitiveElementModel<BaseElementProps>[]

elements
Get Signature

get elements(): Boxed<YMap<YMap<unknown>>>

Returns

Boxed<YMap<YMap<unknown>>>

localElementModels
Get Signature

get localElementModels(): Set<GfxLocalElementModel>

Returns

Set<GfxLocalElementModel>

registeredElementTypes
Get Signature

get registeredElementTypes(): string[]

Returns

string[]

Methods
_extendElement()

protected _extendElement(ctorMap): void

Parameters
ctorMap

Record<string, Constructor<GfxPrimitiveElementModel, ConstructorParameters<typeof GfxPrimitiveElementModel>>>

Returns

void

_init()

protected _init(): void

Returns

void

addElement()

addElement<T>(props): string

Type Parameters
T

T extends object = Record<string, unknown>

Parameters
props

Partial<T> & object

Returns

string

addLocalElement()

addLocalElement(elem): void

Parameters
elem

GfxLocalElementModel

Returns

void

applyMiddlewares()

applyMiddlewares(middlewares): void

Parameters
middlewares

SurfaceMiddleware[]

Returns

void

deleteElement()

deleteElement(id): void

Parameters
id

string

Returns

void

deleteLocalElement()

deleteLocalElement(elem): void

Parameters
elem

GfxLocalElementModel

Returns

void

dispose()

dispose(): void

Returns

void

Overrides

BlockModel.dispose

getConstructor()

getConstructor(type): Constructor<GfxPrimitiveElementModel<BaseElementProps>, [object]>

Parameters
type

string

Returns

Constructor<GfxPrimitiveElementModel<BaseElementProps>, [object]>

getElementById()

getElementById(id): GfxPrimitiveElementModel<BaseElementProps> | null

Parameters
id

string

Returns

GfxPrimitiveElementModel<BaseElementProps> | null

getElementsByType()

getElementsByType(type): GfxPrimitiveElementModel<BaseElementProps>[]

Parameters
type

string

Returns

GfxPrimitiveElementModel<BaseElementProps>[]

getGroup()

getGroup(elem): GfxGroupModel | null

Parameters
elem

string | GfxModel

Returns

GfxGroupModel | null

getGroups()

getGroups(id): GfxGroupModel[]

Get all groups in the group chain. The last group is the top level group.

Parameters
id

string

Returns

GfxGroupModel[]

hasElementById()

hasElementById(id): boolean

Parameters
id

string

Returns

boolean

isEmpty()

isEmpty(): boolean

Returns

boolean

Overrides

BlockModel.isEmpty

isGroup()
Call Signature

isGroup(element): element is GfxModel & GfxGroupCompatibleInterface

Parameters
element

GfxModel

Returns

element is GfxModel & GfxGroupCompatibleInterface

Call Signature

isGroup(id): boolean

Parameters
id

string

Returns

boolean

updateElement()

updateElement<T>(id, props): void

Type Parameters
T

T extends object = Record<string, unknown>

Parameters
id

string

props

Partial<T>

Returns

void


GfxSelectionManager

GfxSelectionManager is just a wrapper of std selection providing convenient method and states in gfx

Extends
Constructors
Properties
disposable

disposable: DisposableGroup

slots

readonly slots: object

cursorUpdated

cursorUpdated: Subject<CursorSelection>

remoteCursorUpdated

remoteCursorUpdated: Subject<void>

remoteUpdated

remoteUpdated: Subject<void>

updated

updated: Subject<SurfaceSelection[]>

key

static key: string = 'gfxSelection'

Overrides

GfxExtension.key

Accessors
activeGroup
Get Signature

get activeGroup(): GfxGroupLikeElementModel<BaseElementProps> | null

Returns

GfxGroupLikeElementModel<BaseElementProps> | null

cursorSelection
Get Signature

get cursorSelection(): CursorSelection | null

Returns

CursorSelection | null

editing
Get Signature

get editing(): boolean

Returns

boolean

empty
Get Signature

get empty(): boolean

Returns

boolean

firstElement
Get Signature

get firstElement(): GfxModel

Returns

GfxModel

inoperable
Get Signature

get inoperable(): boolean

Returns

boolean

lastSurfaceSelections
Get Signature

get lastSurfaceSelections(): SurfaceSelection[]

Returns

SurfaceSelection[]

remoteCursorSelectionMap
Get Signature

get remoteCursorSelectionMap(): Map<number, CursorSelection>

Returns

Map<number, CursorSelection>

remoteSelectedSet
Get Signature

get remoteSelectedSet(): Set<string>

Returns

Set<string>

remoteSurfaceSelectionsMap
Get Signature

get remoteSurfaceSelectionsMap(): Map<number, SurfaceSelection[]>

Returns

Map<number, SurfaceSelection[]>

selectedBound
Get Signature

get selectedBound(): Bound

Returns

Bound

selectedElements
Get Signature

get selectedElements(): GfxModel[]

Returns

GfxModel[]

selectedIds
Get Signature

get selectedIds(): string[]

Returns

string[]

selectedSet
Get Signature

get selectedSet(): Set<string>

Returns

Set<string>

stdSelection
Get Signature

get stdSelection(): StoreSelectionExtension

Returns

StoreSelectionExtension

surfaceModel
Get Signature

get surfaceModel(): SurfaceBlockModel | null

Returns

SurfaceBlockModel | null

surfaceSelections
Get Signature

get surfaceSelections(): SurfaceSelection[]

Returns

SurfaceSelection[]

Methods
clear()

clear(): void

Returns

void

clearLast()

clearLast(): void

Returns

void

equals()

equals(selection): boolean

Parameters
selection

SurfaceSelection[]

Returns

boolean

has()

has(element): boolean

check if the element is selected in local

Parameters
element

string

Returns

boolean

hasRemote()

hasRemote(element): boolean

check if element is selected by remote peers

Parameters
element

string

Returns

boolean

isEmpty()

isEmpty(selections): boolean

Parameters
selections

SurfaceSelection[]

Returns

boolean

isInSelectedRect()

isInSelectedRect(modelX, modelY): boolean

Parameters
modelX

number

modelY

number

Returns

boolean

mounted()

mounted(): void

Returns

void

Overrides

GfxExtension.mounted

set()

set(selection): void

Parameters
selection

SurfaceSelectionState | SurfaceSelection[]

Returns

void

setCursor()

setCursor(cursor): void

Parameters
cursor

CursorSelection | IPoint

Returns

void

toggle()

toggle(element): void

Toggle the selection state of single element

Parameters
element

string | GfxModel

Returns

void

unmounted()

unmounted(): void

Returns

void

Overrides

GfxExtension.unmounted

extendGfx()

static extendGfx(gfx): void

Parameters
gfx

GfxController

Returns

void

Overrides

GfxExtension.extendGfx


SurfaceMiddlewareExtension

A life cycle watcher is an extension that watches the life cycle of the editor. It is used to perform actions when the editor is created, mounted, rendered, or unmounted.

When creating a life cycle watcher, you must define a key that is unique to the watcher. The key is used to identify the watcher in the dependency injection container.

ts
class MyLifeCycleWatcher extends LifeCycleWatcher {
 static override readonly key = 'my-life-cycle-watcher';

In the life cycle watcher, the methods will be called in the following order:

  1. created: Called when the std is created.
  2. rendered: Called when std.render is called.
  3. mounted: Called when the editor host is mounted.
  4. unmounted: Called when the editor host is unmounted.
Extends
Constructors
Properties
key

static key: string = 'surfaceMiddleware'

Overrides

LifeCycleWatcher.key

Methods
mounted()

mounted(): void

Called when editor host is mounted. Which means the editor host emit the connectedCallback lifecycle event.

Returns

void

Overrides

LifeCycleWatcher.mounted


GfxElementModelView<T, RendererContext>

The methods that a graphic element should implement. It is already included in the GfxCompatibleInterface interface.

Extended by
Type Parameters
T

T extends GfxLocalElementModel | GfxPrimitiveElementModel = GfxPrimitiveElementModel | GfxLocalElementModel

RendererContext

RendererContext = object

Implements
Constructors
Constructor

new GfxElementModelView<T, RendererContext>(model, gfx): GfxElementModelView<T, RendererContext>

Parameters
model

T

gfx

GfxController

Returns

GfxElementModelView<T, RendererContext>

Properties
disposable

protected disposable: DisposableGroup

gfx

readonly gfx: GfxController

model

readonly model: T

type

static type: string

Accessors
isConnected
Get Signature

get isConnected(): boolean

Returns

boolean

rotate
Get Signature

get rotate(): number

Returns

number

std
Get Signature

get std(): BlockStdScope

Returns

BlockStdScope

surface
Get Signature

get surface(): SurfaceBlockModel

Returns

SurfaceBlockModel

type
Get Signature

get type(): string

Returns

string

Methods
containsBound()

containsBound(bounds): boolean

Parameters
bounds

Bound

Returns

boolean

Implementation of

GfxElementGeometry.containsBound

dispatch()

dispatch<K>(event, evt): boolean

Dispatches an event to the view.

Type Parameters
K

K extends keyof EventsHandlerMap

Parameters
event

K

evt

EventsHandlerMap[K]

Returns

boolean

Whether the event view has any handlers for the event.

getLineIntersections()

getLineIntersections(start, end): PointLocation[] | null

Parameters
start

IVec

end

IVec

Returns

PointLocation[] | null

Implementation of

GfxElementGeometry.getLineIntersections

getNearestPoint()

getNearestPoint(point): IVec

Parameters
point

IVec

Returns

IVec

Implementation of

GfxElementGeometry.getNearestPoint

getRelativePointLocation()

getRelativePointLocation(relativePoint): PointLocation

Parameters
relativePoint

IVec

Returns

PointLocation

Implementation of

GfxElementGeometry.getRelativePointLocation

includesPoint()

includesPoint(x, y, _, __): boolean

Parameters
x

number

y

number

_

PointTestOptions

__

EditorHost

Returns

boolean

Implementation of

GfxElementGeometry.includesPoint

intersectsBound()

intersectsBound(bound): boolean

Parameters
bound

Bound

Returns

boolean

Implementation of

GfxElementGeometry.intersectsBound

off()

off<K>(event, callback): void

Type Parameters
K

K extends keyof EventsHandlerMap

Parameters
event

K

callback

(evt) => void

Returns

void

on()

on<K>(event, callback): () => void

Type Parameters
K

K extends keyof EventsHandlerMap

Parameters
event

K

callback

(evt) => void

Returns

(): void

Returns

void

onBoxSelected()

onBoxSelected(_): boolean | void

When the element is selected by box selection, return false to prevent the default selection behavior.

Parameters
_

BoxSelectionContext

Returns

boolean | void

Implementation of

GfxViewTransformInterface.onBoxSelected

once()

once<K>(event, callback): () => void

Type Parameters
K

K extends keyof EventsHandlerMap

Parameters
event

K

callback

(evt) => void

Returns

(): void

Returns

void

onCreated()

onCreated(): void

Returns

void

onDestroyed()

onDestroyed(): void

Called when the view is destroyed. Override this method requires calling super.onDestroyed().

Returns

void

onDragEnd()

onDragEnd(_): void

Parameters
_

DragMoveContext

Returns

void

Implementation of

GfxViewTransformInterface.onDragEnd

onDragMove()

onDragMove(__namedParameters): void

Parameters
__namedParameters

DragMoveContext

Returns

void

Implementation of

GfxViewTransformInterface.onDragMove

onDragStart()

onDragStart(_): void

Parameters
_

DragStartContext

Returns

void

Implementation of

GfxViewTransformInterface.onDragStart

render()

render(_): void

Parameters
_

RendererContext

Returns

void

setup()

static setup(di): void

Parameters
di

Container

Returns

void


GfxViewportElement

Extends
Constructors
Other
styles

static styles: CSSResult

Overrides

WithDisposable(ShadowlessElement).styles

enableChildrenSchedule
getModelsInViewport()
host
maxConcurrentRenders
viewport
connectedCallback()

connectedCallback(): void

Returns

void

Overrides

WithDisposable(ShadowlessElement).connectedCallback

disconnectedCallback()

disconnectedCallback(): void

Returns

void

Overrides

WithDisposable(ShadowlessElement).disconnectedCallback

scheduleUpdateChildren()?

optional scheduleUpdateChildren(id): Promise<void>

Parameters
id

string

Returns

Promise<void>

setBlocksActive()

setBlocksActive(blockIds): void

Parameters
blockIds

string[]

Returns

void

setBlocksIdle()

setBlocksIdle(blockIds): void

Parameters
blockIds

string[]

Returns

void

attributes
controllers
dev-mode
properties
rendering
render()

render(): TemplateResult<1>

Invoked on each update to perform rendering tasks. This method may return any value renderable by lit-html's ChildPart - typically a TemplateResult. Setting properties inside this method will not trigger the element to update.

Returns

TemplateResult<1>

Overrides

WithDisposable(ShadowlessElement).render

styles
updates

Viewport

Constructors
Constructor

new Viewport(): Viewport

Returns

Viewport

Properties
_center

protected _center: IPoint

_element

protected _element: GfxViewportElement | null = null

_height

protected _height: number = 0

_left

protected _left: number = 0

_locked

protected _locked: boolean = false

_rafId

protected _rafId: number | null = null

_shell

protected _shell: HTMLElement | null = null

_top

protected _top: number = 0

_width

protected _width: number = 0

_zoom

protected _zoom: number = 1.0

elementReady

elementReady: Subject<GfxViewportElement>

panning$

panning$: BehaviorSubject<boolean>

sizeUpdated

sizeUpdated: Subject<{ height: number; left: number; top: number; width: number; }>

viewportMoved

viewportMoved: Subject<IVec>

viewportUpdated

viewportUpdated: Subject<{ center: IVec; zoom: number; }>

ZOOM_MAX

ZOOM_MAX: number

ZOOM_MIN

ZOOM_MIN: number

zooming$

zooming$: BehaviorSubject<boolean>

Accessors
boundingClientRect
Get Signature

get boundingClientRect(): DOMRect

Returns

DOMRect

center
Get Signature

get center(): IPoint

Returns

IPoint

centerX
Get Signature

get centerX(): number

Returns

number

centerY
Get Signature

get centerY(): number

Returns

number

element
Get Signature

get element(): GfxViewportElement | null

Returns

GfxViewportElement | null

height
Get Signature

get height(): number

Returns

number

left
Get Signature

get left(): number

Returns

number

locked
Get Signature

get locked(): boolean

Returns

boolean

Set Signature

set locked(locked): void

Parameters
locked

boolean

Returns

void

top
Get Signature

get top(): number

Returns

number

translateX
Get Signature

get translateX(): number

Returns

number

translateY
Get Signature

get translateY(): number

Returns

number

viewportBounds
Get Signature

get viewportBounds(): Bound

Returns

Bound

viewportMaxXY
Get Signature

get viewportMaxXY(): object

Returns

object

x

x: number

y

y: number

viewportMinXY
Get Signature

get viewportMinXY(): object

Returns

object

x

x: number

y

y: number

viewportX
Get Signature

get viewportX(): number

Returns

number

viewportY
Get Signature

get viewportY(): number

Returns

number

viewScale
Get Signature

get viewScale(): number

Note this is different from the zoom property. The editor itself may be scaled by outer container which is common in nested editor scenarios. This property is used to calculate the scale of the editor.

Returns

number

width
Get Signature

get width(): number

Returns

number

zoom
Get Signature

get zoom(): number

Returns

number

Methods
applyDeltaCenter()

applyDeltaCenter(deltaX, deltaY): void

Parameters
deltaX

number

deltaY

number

Returns

void

clearViewportElement()

clearViewportElement(): void

Returns

void

deserializeRecord()

deserializeRecord(record?): ViewportRecord | null

Parameters
record?

string

Returns

ViewportRecord | null

dispose()

dispose(): void

Returns

void

getFitToScreenData()

getFitToScreenData(bounds?, padding?, maxZoom?, fitToScreenPadding?): object

Parameters
bounds?

Bound | null

padding?

[number, number, number, number] = ...

maxZoom?

number = ZOOM_MAX

fitToScreenPadding?

number = 100

Returns

object

centerX

centerX: number

centerY

centerY: number

zoom

zoom: number

isInViewport()

isInViewport(bound): boolean

Parameters
bound

Bound

Returns

boolean

onResize()

onResize(): void

Returns

void

serializeRecord()

serializeRecord(): string

Returns

string

setCenter()

setCenter(centerX, centerY, forceUpdate): void

Set the center of the viewport.

Parameters
centerX

number

The new x coordinate of the center of the viewport.

centerY

number

The new y coordinate of the center of the viewport.

forceUpdate

boolean = true

Whether to force complete any pending resize operations before setting the viewport.

Returns

void

setRect()

setRect(left, top, width, height): void

Parameters
left

number

top

number

width

number

height

number

Returns

void

setShellElement()

setShellElement(el): void

This is the outer container of the viewport, which is the host of the viewport element

Parameters
el

HTMLElement

Returns

void

setViewport()

setViewport(newZoom, newCenter, smooth, forceUpdate): void

Set the viewport to the new zoom and center.

Parameters
newZoom

number

The new zoom value.

newCenter

IVec = ...

The new center of the viewport.

smooth

boolean = false

Whether to animate the zooming and panning.

forceUpdate

boolean = true

Whether to force complete any pending resize operations before setting the viewport.

Returns

void

setViewportByBound()

setViewportByBound(bound, padding, smooth, forceUpdate): void

Set the viewport to fit the bound with padding.

Parameters
bound

Bound

The bound will be zoomed to fit the viewport.

padding

[number, number, number, number] = ...

The padding will be applied to the bound after zooming, default is [0, 0, 0, 0], the value may be reduced if there is not enough space for the padding. Use decimal less than 1 to represent percentage padding. e.g. [0.1, 0.1, 0.1, 0.1] means 10% padding.

smooth

boolean = false

whether to animate the zooming

forceUpdate

boolean = true

whether to force complete any pending resize operations before setting the viewport

Returns

void

setZoom()

setZoom(zoom, focusPoint?, wheel?, forceUpdate?): void

Set the viewport to the new zoom.

Parameters
zoom

number

The new zoom value.

focusPoint?

IPoint

The point to focus on after zooming, default is the center of the viewport.

wheel?

boolean = false

Whether the zoom is caused by wheel event.

forceUpdate?

boolean = true

Whether to force complete any pending resize operations before setting the viewport.

Returns

void

smoothTranslate()

smoothTranslate(x, y, numSteps): void

Parameters
x

number

y

number

numSteps

number = 10

Returns

void

smoothZoom()

smoothZoom(zoom, focusPoint?, numSteps?): void

Parameters
zoom

number

focusPoint?

IPoint

numSteps?

number = 10

Returns

void

toModelBound()

toModelBound(bound): Bound

Parameters
bound

Bound

Returns

Bound

toModelCoord()

toModelCoord(viewX, viewY, zoom, center?): IVec

Parameters
viewX

number

viewY

number

zoom

number = ...

center?

IPoint

Returns

IVec

toModelCoordFromClientCoord()

toModelCoordFromClientCoord(__namedParameters): IVec

Parameters
__namedParameters

IVec

Returns

IVec

toViewBound()

toViewBound(bound): Bound

Parameters
bound

Bound

Returns

Bound

toViewCoord()

toViewCoord(modelX, modelY): IVec

Parameters
modelX

number

modelY

number

Returns

IVec

toViewCoordFromClientCoord()

toViewCoordFromClientCoord(__namedParameters): IVec

Parameters
__namedParameters

IVec

Returns

IVec

Interfaces

GfxCompatibleInterface

All the model that can be rendered in graphics mode should implement this interface.

Extends

Extended by

Properties

deserializedXYWH

readonly deserializedXYWH: XYWH

elementBound

readonly elementBound: Bound

The bound of the element without considering the response extension.

forceFullRender?

optional forceFullRender: boolean

Whether to disable fallback rendering for this element, e.g., during zooming. Defaults to false (fallback to placeholder rendering is enabled).

group

readonly group: GfxGroupCompatibleInterface | null

groups

readonly groups: GfxGroupCompatibleInterface[]

index

index: string

lockedBySelf?

optional lockedBySelf: boolean

Indicates whether the current block is explicitly locked by self. For checking the lock status of the element, use isLocked instead. For (un)locking the element, use (un)lock instead.

responseBound

readonly responseBound: Bound

The bound of the element considering the response extension.

responseExtension

responseExtension: [number, number]

Defines the extension of the response area beyond the element's bounding box. This tuple specifies the horizontal and vertical margins to be added to the element's bound.

The first value represents the horizontal extension (added to both left and right sides), and the second value represents the vertical extension (added to both top and bottom sides).

The response area is computed as: [x - horizontal, y - vertical, w + 2 * horizontal, h + 2 * vertical].

Example:

  • xywh: [0, 0, 100, 100], responseExtension: [10, 20] Resulting response area: [-10, -20, 120, 140].
  • responseExtension: [0, 0] keeps the response area equal to the bounding box.
xywh

xywh: `[${number},${number},${number},${number}]`

Methods

isLocked()

isLocked(): boolean

Check if the element is locked. It will check the lock status of the element and its ancestors.

Returns

boolean

isLockedByAncestor()

isLockedByAncestor(): boolean

Returns

boolean

isLockedBySelf()

isLockedBySelf(): boolean

Returns

boolean

lock()

lock(): void

Returns

void

unlock()

unlock(): void

Returns

void


GfxElementGeometry

The methods that a graphic element should implement. It is already included in the GfxCompatibleInterface interface.

Extended by

Methods

containsBound()

containsBound(bound): boolean

Parameters
bound

Bound

Returns

boolean

getLineIntersections()

getLineIntersections(start, end): PointLocation[] | null

Parameters
start

IVec

end

IVec

Returns

PointLocation[] | null

getNearestPoint()

getNearestPoint(point): IVec

Parameters
point

IVec

Returns

IVec

getRelativePointLocation()

getRelativePointLocation(point): PointLocation

Parameters
point

IVec

Returns

PointLocation

includesPoint()

includesPoint(x, y, options, host): boolean

Parameters
x

number

y

number

options

PointTestOptions

host

EditorHost

Returns

boolean

intersectsBound()

intersectsBound(bound): boolean

Parameters
bound

Bound

Returns

boolean


GfxGroupCompatibleInterface

GfxGroupCompatibleElement is a model that can contain other models. It just like a group that in common graphic software.

Extends

Properties

[gfxGroupCompatibleSymbol]

[gfxGroupCompatibleSymbol]: true

childElements

childElements: GfxModel[]

All child element models of this container. Note that the childElements may not contains all the children in childIds, because some children may not be loaded.

childIds

childIds: string[]

All child ids of this container.

descendantElements

descendantElements: GfxModel[]

Methods

addChild()

addChild(element): void

Parameters
element

GfxCompatibleInterface

Returns

void

hasChild()

hasChild(element): boolean

Parameters
element

GfxCompatibleInterface

Returns

boolean

hasDescendant()

hasDescendant(element): boolean

Parameters
element

GfxCompatibleInterface

Returns

boolean

removeChild()

removeChild(element): void

Parameters
element

GfxCompatibleInterface

Returns

void


PointTestOptions

The options for the hit testing of a point.

Properties

hitThreshold?

optional hitThreshold: number

The threshold of the hit test. The unit is pixel.

ignoreTransparent?

optional ignoreTransparent: boolean

If true, the transparent area of the element will be ignored during the point inclusion test. Otherwise, the transparent area will be considered as filled area.

Default is true.

responsePadding?

optional responsePadding: [number, number]

The padding of the response area for each element when do the hit testing. The unit is pixel. The first value is the padding for the x-axis, and the second value is the padding for the y-axis.

useElementBound?

optional useElementBound: boolean

If true, the element bound will be used for the hit testing. By default, the response bound will be used.

zoom?

optional zoom: number

The zoom level of current view when do the hit testing.


RafCoalescer<T>

Type Parameters

T

T

Properties

cancel()

cancel: () => void

Returns

void

flush()

flush: () => void

Returns

void

schedule()

schedule: (payload) => void

Parameters
payload

T

Returns

void


ViewportRecord

Properties

left

left: number

top

top: number

viewportX

viewportX: number

viewportY

viewportY: number

viewScale

viewScale: number

zoom

zoom: number

Type Aliases

BaseElementProps

BaseElementProps = object

Properties

comments?

optional comments: Record<string, boolean>

index

index: string

lockedBySelf?

optional lockedBySelf: boolean

seed

seed: number


BoxSelectionContext

BoxSelectionContext = object

Properties

box

box: Readonly<IBound & object>


CursorType

CursorType = StandardCursor | URLCursor | URLCursorWithCoords | URLCursorWithFallback


DragEndContext

DragEndContext = DragMoveContext


DragExtensionInitializeContext

DragExtensionInitializeContext = object

Properties

dragStartPos

dragStartPos: Readonly<{ x: number; y: number; }>

The start position of the drag in model space.

elements

elements: GfxModel[]

The elements that are being dragged. The extension can modify this array to add or remove dragging elements.

preventDefault()

preventDefault: () => void

Prevent the default drag behavior. The following drag events will not be triggered.

Returns

void


DragInitializationOption

DragInitializationOption = object

Properties

event

event: PointerEvent | MouseEvent

movingElements

movingElements: GfxModel[]

onDragEnd()?

optional onDragEnd: () => void

Returns

void


DragMoveContext

DragMoveContext = DragStartContext & object

Type Declaration

dx

dx: number

The delta x of current drag position compared to the start position in model coordinate.

dy

dy: number

The delta y of current drag position compared to the start position in model coordinate.


DragStartContext

DragStartContext = object

Properties

currentBound

currentBound: Bound

The bound of element when drag starts

elements

elements: object[]

The elements that are being dragged

model

model: GfxModel

originalBound

originalBound: Bound

view

view: GfxBlockComponent | GfxElementModelView


EventsHandlerMap

EventsHandlerMap = object

Properties

click

click: PointerEventState

dblclick

dblclick: PointerEventState

dragend

dragend: PointerEventState

dragmove

dragmove: PointerEventState

dragstart

dragstart: PointerEventState

pointerdown

pointerdown: PointerEventState

pointerenter

pointerenter: PointerEventState

pointerleave

pointerleave: PointerEventState

pointermove

pointermove: PointerEventState

pointerup

pointerup: PointerEventState


ExtensionDragEndContext

ExtensionDragEndContext = ExtensionDragMoveContext


ExtensionDragMoveContext

ExtensionDragMoveContext = ExtensionBaseEvent & object

Type Declaration

dx

dx: number

dy

dy: number


ExtensionDragStartContext

ExtensionDragStartContext = ExtensionBaseEvent


GfxCommonBlockProps

GfxCommonBlockProps = GfxCompatibleProps & object

This type include the common props for the graphic block model. You can use this type with Omit to define the props of a graphic block model.

Type Declaration

rotate

rotate: number

scale

scale: number


GfxCompatibleProps

GfxCompatibleProps = object

The props that a graphics block model should have.

Properties

index

index: string

lockedBySelf?

optional lockedBySelf: boolean

xywh

xywh: SerializedXYWH


GfxInteractivityContext<EventState, RawEvent>

GfxInteractivityContext<EventState, RawEvent> = object

Type Parameters

EventState

EventState extends UIEventState = PointerEventState

RawEvent

RawEvent extends Event = EventState["event"]

Properties

event

event: EventState

preventDefault()

preventDefault: () => void

Prevent the default gfx interaction

Returns

void

raw

raw: RawEvent

The raw dom event.


GfxModel

GfxModel = GfxBlockElementModel | GfxPrimitiveElementModel


GfxViewInteractionConfig<T>

GfxViewInteractionConfig<T> = object

Type Parameters

T

T extends GfxBlockComponent | GfxElementModelView = GfxBlockComponent | GfxElementModelView

Properties

handleResize()?

optional handleResize: (context) => object

The function that will be called when the view is resized. You can add or delete the resize element before resize starts in this function., And return handlers to customize the resize behavior.

Parameters
context

ViewInteractionHandleContext<T>

Returns
beforeResize()?

optional beforeResize: (context) => void

Called before resize starts. When this method is called, the resize elements are confirmed and will not be changed. You can set the resize constraint in this method.

Parameters
context

BeforeResizeContext

Returns

void

onResizeEnd()?

optional onResizeEnd(context): void

Parameters
context

ResizeStartContext & ExtendedViewContext<T, ResizeStartContext, void>

Returns

void

onResizeMove()?

optional onResizeMove(context): void

Parameters
context

ResizeStartContext & object & ExtendedViewContext<T, ResizeMoveContext, void>

Returns

void

onResizeStart()?

optional onResizeStart(context): void

Parameters
context

ResizeStartContext & ExtendedViewContext<T, ResizeStartContext, void>

Returns

void

handleRotate()?

optional handleRotate: (context) => object

Parameters
context

ViewInteractionHandleContext<T>

Returns

object

beforeRotate()?

optional beforeRotate: (context) => void

Parameters
context

BeforeRotateContext

Returns

void

onRotateEnd()?

optional onRotateEnd(context): void

Parameters
context

RotateStartContext & ExtendedViewContext<T, RotateStartContext, void>

Returns

void

onRotateMove()?

optional onRotateMove(context): void

Parameters
context

RotateStartContext & object & ExtendedViewContext<T, RotateMoveContext, void>

Returns

void

onRotateStart()?

optional onRotateStart(context): void

Parameters
context

RotateStartContext & ExtendedViewContext<T, RotateStartContext, void>

Returns

void

handleSelection()?

optional handleSelection: (context) => object

Parameters
context

Omit<ViewInteractionHandleContext<T>, "add" | "delete">

Returns

object

onSelect()?

optional onSelect: (context) => boolean | void

Parameters
context

SelectContext & ExtendedViewContext<T, SelectContext, boolean | void>

Returns

boolean | void

selectable()?

optional selectable: (context) => boolean

Parameters
context

SelectableContext & ExtendedViewContext<T, SelectableContext, boolean>

Returns

boolean

resizeConstraint?

readonly optional resizeConstraint: ResizeConstraint


ReorderingDirection

ReorderingDirection = "front" | "forward" | "backward" | "back"


ResizeConstraint

ResizeConstraint = object

Properties

allowedHandlers?

optional allowedHandlers: ResizeHandle[]

lockRatio?

optional lockRatio: boolean | ResizeHandle[]

Whether to lock the aspect ratio of the element when resizing. If the value is an array, it will only lock the aspect ratio when resizing the specified handles.

maxHeight?

optional maxHeight: number

maxWidth?

optional maxWidth: number

minHeight?

optional minHeight: number

minWidth?

optional minWidth: number


ResizeEndContext

ResizeEndContext = ResizeStartContext


ResizeHandle

ResizeHandle = "top-left" | "top" | "top-right" | "right" | "bottom-right" | "bottom" | "bottom-left" | "left"


ResizeMoveContext

ResizeMoveContext = ResizeStartContext & object

Type Declaration

lockRatio

lockRatio: boolean

matrix

matrix: DOMMatrix

The matrix that used to transform the element.

newBound

newBound: Bound

originalBound

originalBound: Bound

The element bound when resize starts


ResizeStartContext

ResizeStartContext = object

Properties

constraint

constraint: Readonly<Required<ResizeConstraint>>

The resize constraint.

handle

handle: ResizeHandle

The handle that is used to resize the element


RotateConstraint

RotateConstraint = object

Properties

rotatable?

optional rotatable: boolean


RotateEndContext

RotateEndContext = RotateStartContext


RotateMoveContext

RotateMoveContext = RotateStartContext & object

Type Declaration

matrix

matrix: DOMMatrix

newBound

newBound: Bound

newRotate

newRotate: number

originalBound

originalBound: Bound

originalRotate

originalRotate: number


RotateStartContext

RotateStartContext = object

Properties

constraint

constraint: Readonly<Required<RotateConstraint>>


SelectContext

SelectContext = SelectableContext & object

Type Declaration

selected

selected: boolean

The selected state of the element


SerializedElement

SerializedElement = Record<string, unknown> & object

Type Declaration

comments?

optional comments: Record<string, boolean>

id

id: string

index

index: string

lockedBySelf?

optional lockedBySelf: boolean

props

props: Record<string, unknown>

type

type: string

xywh

xywh: SerializedXYWH


StandardCursor

StandardCursor = "default" | "pointer" | "move" | "text" | "crosshair" | "not-allowed" | "grab" | "grabbing" | "nwse-resize" | "nesw-resize" | "ew-resize" | "ns-resize" | "n-resize" | "s-resize" | "w-resize" | "e-resize" | "ne-resize" | "se-resize" | "sw-resize" | "nw-resize" | "zoom-in" | "zoom-out" | "help" | "wait" | "progress" | "copy" | "alias" | "context-menu" | "cell" | "vertical-text" | "no-drop" | "not-allowed" | "all-scroll" | "col-resize" | "row-resize" | "none" | "inherit" | "initial" | "unset"


SupportedEvent

SupportedEvent = keyof EventsHandlerMap


SurfaceBlockProps

SurfaceBlockProps = object

Properties

elements

elements: Boxed<Y.Map<Y.Map<unknown>>>


SurfaceMiddleware()

SurfaceMiddleware = (ctx) => void

Parameters

ctx

MiddlewareCtx

Returns

void


ToolOptions<T>

ToolOptions<T> = T extends BaseTool<infer O> ? O : never

Type Parameters

T

T extends BaseTool


ToolOptionWithType<T>

ToolOptionWithType<T> = object

Type Parameters

T

T extends BaseTool = BaseTool

Properties

options?

optional options: ToolOptions<T>

toolType?

optional toolType: ToolType<T>


ToolType()<T>

ToolType<T> = T

Type Parameters

T

T extends BaseTool = BaseTool

new ToolType(gfx): T

Parameters

gfx

GfxController

Returns

T

Properties

toolName

toolName: string

Variables

FIT_TO_SCREEN_PADDING

const FIT_TO_SCREEN_PADDING: 100 = 100


GfxControllerIdentifier

const GfxControllerIdentifier: ServiceIdentifier<GfxController>


GfxExtensionIdentifier

const GfxExtensionIdentifier: ServiceIdentifier<GfxExtension> & <U>(variant) => ServiceIdentifier<U>


gfxGroupCompatibleSymbol

const gfxGroupCompatibleSymbol: typeof gfxGroupCompatibleSymbol

The symbol to mark a model as a container.


InteractivityIdentifier

const InteractivityIdentifier: ServiceIdentifier<InteractivityManager>


SURFACE_TEXT_UNIQ_IDENTIFIER

const SURFACE_TEXT_UNIQ_IDENTIFIER: "affine:surface:text" = 'affine:surface:text'

Used for text field


SURFACE_YMAP_UNIQ_IDENTIFIER

const SURFACE_YMAP_UNIQ_IDENTIFIER: "affine:surface:ymap" = 'affine:surface:ymap'

Used for field that use Y.Map. E.g. group children field


ZOOM_INITIAL

const ZOOM_INITIAL: 1 = 1.0


ZOOM_MAX

const ZOOM_MAX: 6 = 6.0


ZOOM_MIN

const ZOOM_MIN: 0.1 = 0.1


ZOOM_STEP

const ZOOM_STEP: 0.25 = 0.25

Functions

batchAddChildren()

batchAddChildren(container, elements): void

Parameters

container

GfxGroupCompatibleInterface

elements

GfxModel[]

Returns

void


batchRemoveChildren()

batchRemoveChildren(container, elements): void

Parameters

container

GfxGroupCompatibleInterface

elements

GfxModel[]

Returns

void


canSafeAddToContainer()

canSafeAddToContainer(container, element): boolean

This checker is used to prevent circular reference, when adding a child element to a container.

Parameters

container

GfxGroupModel

element

GfxCompatibleInterface

Returns

boolean


clientToModelCoord()

clientToModelCoord(viewport, clientCoord): IVec

Parameters

viewport

ViewportRecord

clientCoord

[number, number]

Returns

IVec


compareLayer()

compareLayer(a, b): SortOrder

A comparator function for sorting elements in the surface. SortOrder.AFTER means a should be rendered after b and so on.

Parameters

a

GfxModel | GfxLocalElementModel

b

GfxModel | GfxLocalElementModel

Returns

SortOrder


convert()

convert<V, T>(fn): (_, context) => ClassAccessorDecoratorResult<T, V>

The convert decorator is used to convert the property value before it's set to the Y map.

Note:

  1. This decorator function will not execute in model initialization.

Type Parameters

V

V

T

T extends GfxPrimitiveElementModel<BaseElementProps>

Parameters

fn

(propValue, instance) => unknown

Returns

(_, context): ClassAccessorDecoratorResult<T, V>

Parameters
_

unknown

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<T, V>


convertProps()

convertProps(propName, propValue, receiver): unknown

Parameters

propName

string | symbol

propValue

unknown

receiver

unknown

Returns

unknown


createRafCoalescer()

createRafCoalescer<T>(apply): RafCoalescer<T>

Coalesce high-frequency updates and only process the latest payload in one frame.

Type Parameters

T

T

Parameters

apply

(payload) => void

Returns

RafCoalescer<T>


derive()

derive<V, T>(fn): (_, context) => ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>

The derive decorator is used to derive other properties' update when the decorated property is updated through assignment in the local.

Note:

  1. The first argument of the function is the new value of the decorated property before the convert decorator is called.
  2. The decorator function will execute after the decorated property has been updated.
  3. The decorator function will not execute during model creation.
  4. The decorator function will not execute if the decorated property is updated through the Y map. That is to say, if other peers update the property will not trigger this decorator

Type Parameters

V

V

T

T extends GfxPrimitiveElementModel<BaseElementProps>

Parameters

fn

(propValue, instance) => Record<string, unknown>

Returns

(_, context): ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>

Parameters
_

unknown

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>


descendantElementsImpl()

descendantElementsImpl(container): GfxModel[]

Parameters

container

GfxGroupCompatibleInterface

Returns

GfxModel[]


field()

field<V, T>(fallback?): (_, context) => ClassAccessorDecoratorResult<T, V>

Type Parameters

V

V

T

T extends GfxPrimitiveElementModel<BaseElementProps>

Parameters

fallback?

V

Returns

(_, context): ClassAccessorDecoratorResult<T, V>

Parameters
_

ClassAccessorDecoratorTarget<T, V>

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<T, V>


generateKeyBetween()

generateKeyBetween(a, b, digits?): string

Parameters

a

string | null | undefined

b

string | null | undefined

digits?

string

Returns

string


generateKeyBetweenV2()

generateKeyBetweenV2(a, b): string

generate a key between a and b, the result key is always satisfied with a < result < b. the key always has a random suffix, so there is no need to worry about collision.

make sure a and b are generated by this function.

Parameters

a

string | null

b

string | null

Returns

string


generateNKeysBetween()

generateNKeysBetween(a, b, n, digits?): string[]

same preconditions as generateKeysBetween. n >= 0. Returns an array of n distinct keys in sorted order. If a and b are both null, returns [a0, a1, ...] If one or the other is null, returns consecutive "integer" keys. Otherwise, returns relatively short keys between a and b.

Parameters

a

string | null | undefined

b

string | null | undefined

n

number

digits?

string

Returns

string[]


getDerivedProps()

getDerivedProps(prop, propValue, receiver): Record<string, unknown> | null

Parameters

prop

string | symbol

propValue

unknown

receiver

GfxPrimitiveElementModel

Returns

Record<string, unknown> | null


getFieldPropsSet()

getFieldPropsSet(target): Set<string | symbol>

Parameters

target

unknown

Returns

Set<string | symbol>


getTopElements()

getTopElements(elements): GfxModel[]

Get the top elements from the list of elements, which are in some tree structures.

For example: a list [G1, E1, G2, E2, E3, E4, G4, E5, E6], and they are in the elements tree like:

    G1         G4      E6
   /  \        |
 E1   G2       E5
      / \
     E2  G3*
        / \
       E3 E4

where the star symbol * denote it is not in the list.

The result should be [G1, G4, E6]

Parameters

elements

GfxModel[]

Returns

GfxModel[]


GfxCompatible()

GfxCompatible<Props, T>(BlockModelSuperClass): typeof GfxBlockElementModel

Convert a BlockModel to a GfxBlockElementModel.

Type Parameters

Props

Props extends GfxCompatibleProps

T

T extends Constructor<BlockModel<Props>> = Constructor<BlockModel<Props>>

Parameters

BlockModelSuperClass

T

The BlockModel class to be converted.

Returns

typeof GfxBlockElementModel

The returned class is a subclass of the GfxBlockElementModel class and the given BlockModelSuperClass.


GfxViewInteractionExtension()

GfxViewInteractionExtension<T>(viewType, config): ExtensionType

Type Parameters

T

T extends GfxBlockComponent<GfxBlockElementModel<GfxCompatibleProps>, BlockService, string> | GfxElementModelView<GfxPrimitiveElementModel<BaseElementProps> | GfxLocalElementModel, object>

Parameters

viewType

string

config

GfxViewInteractionConfig<T>

Returns

ExtensionType


hasDescendantElementImpl()

hasDescendantElementImpl(container, element): boolean

Parameters

container

GfxGroupCompatibleInterface

element

GfxCompatibleInterface

Returns

boolean


initializeObservers()

initializeObservers(proto, receiver): void

Parameters

proto

unknown

receiver

GfxPrimitiveElementModel

Returns

void


initializeWatchers()

initializeWatchers(prototype, receiver): void

Parameters

prototype

unknown

receiver

GfxPrimitiveElementModel

Returns

void


isGfxGroupCompatibleModel()

isGfxGroupCompatibleModel(elm): elm is GfxGroupModel

Check if the element is a container element.

Parameters

elm

unknown

Returns

elm is GfxGroupModel


isPrimitiveModel()

isPrimitiveModel(model): model is GfxPrimitiveElementModel<BaseElementProps>

Parameters

model

GfxModel

Returns

model is GfxPrimitiveElementModel<BaseElementProps>


local()

local<V, T>(): (_target, context) => ClassAccessorDecoratorResult<T, V>

A decorator to mark the property as a local property.

The local property act like it is a field property, but it's not synced to the Y map. Updating local property will also trigger the elementUpdated slot of the surface model

Type Parameters

V

V

T

T extends GfxPrimitiveElementModel<BaseElementProps>

Returns

(_target, context): ClassAccessorDecoratorResult<T, V>

Parameters
_target

ClassAccessorDecoratorTarget<T, V>

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<T, V>


measureOperation()

measureOperation<T>(name, fn): T

Measure operation cost via Performance API when available.

Marks are always cleared, while measure entries are intentionally retained so callers can inspect them from Performance tools.

Type Parameters

T

T

Parameters

name

string

fn

() => T

Returns

T


observe()

observe<V, E, T>(fn): (_, context) => ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>

A decorator to observe the y type property. You can think of it is just a decorator version of 'observe' method of Y.Array and Y.Map.

The observer function start to observe the property when the model is mounted. And it will re-observe the property automatically when the value is altered.

Type Parameters

V

V

E

E extends YEvent<any>

T

T extends GfxPrimitiveElementModel<BaseElementProps>

Parameters

fn

ObserveFn<E, T>

Returns

(_, context): ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>

Parameters
_

unknown

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>


prop()

prop<V, T>(): (_target, context) => ClassAccessorDecoratorResult<T, V>

Type Parameters

V

V

T

T extends GfxLocalElementModel

Returns

(_target, context): ClassAccessorDecoratorResult<T, V>

Parameters
_target

ClassAccessorDecoratorTarget<T, V>

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<T, V>


renderableInEdgeless()

renderableInEdgeless(doc, surface, block): boolean

Parameters

doc

Store

surface

SurfaceBlockModel

block

GfxBlockElementModel

Returns

boolean


updateDerivedProps()

updateDerivedProps(derivedProps, receiver): void

Parameters

derivedProps

Record<string, unknown> | null

receiver

GfxPrimitiveElementModel

Returns

void


watch()

watch<V, T>(fn): (_, context) => ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>

The watch decorator is used to watch the property change of the element. You can thinks of it as a decorator version of elementUpdated slot of the surface model.

Type Parameters

V

V

T

T extends GfxPrimitiveElementModel<BaseElementProps>

Parameters

fn

WatchFn<T>

Returns

(_, context): ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>

Parameters
_

unknown

context

ClassAccessorDecoratorContext

Returns

ClassAccessorDecoratorResult<GfxPrimitiveElementModel<BaseElementProps>, V>