Skip to content

BlockSuite API Documentation / @blocksuite/affine-gfx-template

@blocksuite/affine-gfx-template

Classes

Extension

TemplateTool

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
toolName

static toolName: string = 'template'

Overrides

BaseTool.toolName

Accessors
Methods

Other

TemplateJob

Constructors
Constructor

new TemplateJob(__namedParameters): TemplateJob

Parameters
__namedParameters

TemplateJobConfig

Returns

TemplateJob

Properties
job

job: Transformer

model

model: SurfaceBlockModel

slots

slots: object

beforeInsert

beforeInsert: Subject<SlotBlockPayload | { bound: Bound | null; template: DocSnapshot; type: "template"; }>

type

type: "template" | "sticker"

middlewares

static middlewares: (job) => void[] = []

Parameters
job

TemplateJob

Returns

void

Methods
insertTemplate()

insertTemplate(template): Promise<Bound | null>

Parameters
template

unknown

Returns

Promise<Bound | null>

walk()

walk(callback): void

Parameters
callback

(block, template) => void

Returns

void

create()

static create(options): TemplateJob

Parameters
options
middlewares

(job) => void[]

model

SurfaceBlockModel

type

string

Returns

TemplateJob


EdgelessTemplatePanel

Extends
  • LitElement<this> & DisposableClass<this>
Constructors
Other
draggableController

draggableController: EdgelessDraggableElementController<Template>

styles

static styles: CSSResult

Overrides

WithDisposable(LitElement).styles

templates

static templates: object = builtInTemplates

categories()

categories: () => Promise<string[]>

Returns

Promise<string[]>

list()

list: (category) => Promise<Template[]>

Parameters
category

string

Returns

Promise<Template[]>

search: (keyword, cateName?) => Promise<Template[]>

Parameters
keyword

string

cateName?

string

Returns

Promise<Template[]>

extend()

extend(manager): void

Parameters
manager

TemplateManager

Returns

void

edgeless
gfx
Get Signature

get gfx(): GfxController

Returns

GfxController

isDragging
attributes
controllers
dev-mode
lifecycle
connectedCallback()

connectedCallback(): void

Invoked when the component is added to the document's DOM.

In connectedCallback() you should setup tasks that should only occur when the element is connected to the document. The most common of these is adding event listeners to nodes external to the element, like a keydown event handler added to the window.

ts
connectedCallback() {
  super.connectedCallback();
  addEventListener('keydown', this._handleKeydown);
}

Typically, anything done in connectedCallback() should be undone when the element is disconnected, in disconnectedCallback().

Returns

void

Overrides

WithDisposable(LitElement).connectedCallback

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(LitElement).render

styles
updates
firstUpdated()

firstUpdated(): void

Invoked when the element is first updated. Implement to perform one time work on the element after update.

ts
firstUpdated() {
  this.renderRoot.getElementById('my-text-area').focus();
}

Setting properties inside this method will trigger the element to update again after this update cycle completes.

Returns

void

Overrides

WithDisposable(LitElement).firstUpdated

Interfaces

TemplateManager

Methods

categories()

categories(): string[] | Promise<string[]>

Returns

string[] | Promise<string[]>

extend()?

optional extend(manager): void

Parameters
manager

TemplateManager

Returns

void

list()

list(category): Template[] | Promise<Template[]>

Parameters
category

string

Returns

Template[] | Promise<Template[]>

search()

search(keyword, category?): Template[] | Promise<Template[]>

Parameters
keyword

string

category?

string

Returns

Template[] | Promise<Template[]>

Type Aliases

SlotBlockPayload

SlotBlockPayload = object

Properties

data

data: object

blockJson

blockJson: BlockSnapshot

index?

optional index: number

parent?

optional parent: string

type

type: "block"


SlotPayload

SlotPayload = SlotBlockPayload | { bound: Bound | null; template: DocSnapshot; type: "template"; }


Template

Template = object

Properties

assets?

optional assets: Record<string, string>

external assets

content

content: unknown

template content

name?

optional name: string

name of the sticker

if not provided, it cannot be searched

preview?

optional preview: string

type

type: "template" | "sticker"

type of template template: normal template, looks like an article sticker: sticker template, only contains one image block under surface block


TemplateCategory

TemplateCategory = object

Properties

name

name: string

templates

templates: Template[] | () => Promise<Template[]>


TemplateJobConfig

TemplateJobConfig = object

Properties

middlewares

middlewares: (job) => void[]

Parameters
job

TemplateJob

Returns

void

model

model: SurfaceBlockModel

type

type: string

Variables

templateSeniorTool

const templateSeniorTool: ExtensionType

Functions

createTemplateJob()

createTemplateJob(std, type, center?): TemplateJob

Parameters

std

BlockStdScope

type

"template" | "sticker"

center?
x

number

y

number

Returns

TemplateJob