Skip to content

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

@blocksuite/affine-gfx-text ​

Classes ​

Extension ​

TextTool ​

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 = 'text'

Overrides ​

BaseTool.toolName

Accessors ​
Methods ​
click() ​

click(e): void

Parameters ​
e ​

PointerEventState

Returns ​

void

Overrides ​

BaseTool.click

Other ​

EdgelessTextEditor ​

Extends ​
Constructors ​
Other ​
BORDER_WIDTH ​

static BORDER_WIDTH: number = 1

PADDING_HORIZONTAL ​

static PADDING_HORIZONTAL: number = 10

PADDING_VERTICAL ​

static PADDING_VERTICAL: number = 6

PLACEHOLDER_TEXT ​

static PLACEHOLDER_TEXT: string = 'Type from here'

styles ​

static styles: CSSResult

Overrides ​

WithDisposable(ShadowlessElement).styles

crud ​
Get Signature ​

get crud(): EdgelessCRUDExtension

Returns ​

EdgelessCRUDExtension

element ​
gfx ​
Get Signature ​

get gfx(): GfxController

Returns ​

GfxController

inlineEditor ​
Get Signature ​

get inlineEditor(): AffineInlineEditor | null

Returns ​

AffineInlineEditor | null

inlineEditorContainer ​
Get Signature ​

get inlineEditorContainer(): InlineRootElement<AffineTextAttributes> | null | undefined

Returns ​

InlineRootElement<AffineTextAttributes> | null | undefined

richText ​
std ​
connectedCallback() ​

connectedCallback(): void

Returns ​

void

Overrides ​

WithDisposable(ShadowlessElement).connectedCallback

getContainerOffset() ​

getContainerOffset(): string

Returns ​

string

getCoordsOnCenterAlign() ​

getCoordsOnCenterAlign(rect, w1, h1): object

Parameters ​
rect ​
h ​

number

r ​

number

w ​

number

x ​

number

y ​

number

w1 ​

number

h1 ​

number

Returns ​

object

x ​

x: number

y ​

y: number

getCoordsOnLeftAlign() ​

getCoordsOnLeftAlign(rect, w1, h1): object

Parameters ​
rect ​
h ​

number

r ​

number

w ​

number

x ​

number

y ​

number

w1 ​

number

h1 ​

number

Returns ​

object

x ​

x: number

y ​

y: number

getCoordsOnRightAlign() ​

getCoordsOnRightAlign(rect, w1, h1): object

Parameters ​
rect ​
h ​

number

r ​

number

w ​

number

x ​

number

y ​

number

w1 ​

number

h1 ​

number

Returns ​

object

x ​

x: number

y ​

y: number

getVisualPosition() ​

getVisualPosition(element): IVec

Parameters ​
element ​

TextElementModel

Returns ​

IVec

setKeeping() ​

setKeeping(keeping): void

Parameters ​
keeping ​

boolean

Returns ​

void

attributes ​
controllers ​
dev-mode ​
lifecycle ​
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 ​
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(ShadowlessElement).firstUpdated

getUpdateComplete() ​

getUpdateComplete(): Promise<boolean>

Override point for the updateComplete promise.

It is not safe to override the updateComplete getter directly due to a limitation in TypeScript which means it is not possible to call a superclass getter (e.g. super.updateComplete.then(...)) when the target language is ES5 (https://github.com/microsoft/TypeScript/issues/338). This method should be overridden instead. For example:

ts
class MyElement extends LitElement {
  override async getUpdateComplete() {
    const result = await super.getUpdateComplete();
    await this._myChild.updateComplete;
    return result;
  }
}
Returns ​

Promise<boolean>

A promise of a boolean that resolves to true if the update completed without triggering another update.

Overrides ​

WithDisposable(ShadowlessElement).getUpdateComplete


TextElementView ​

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

Extends ​
Constructors ​
Properties ​
type ​

static type: string = 'text'

Overrides ​

GfxElementModelView.type

Accessors ​
Methods ​
onCreated() ​

onCreated(): void

Returns ​

void

Overrides ​

GfxElementModelView.onCreated

Type Aliases ​

TextDelta ​

TextDelta = object

Properties ​

attributes? ​

optional attributes?: Record<string, unknown>

insert ​

insert: string

Variables ​

charWidth ​

const charWidth: object

Type Declaration ​

calculate ​

calculate: (char, font) => number

Parameters ​
char ​

string

font ​

string

Returns ​

number

getCache ​

getCache: (font) => number[] | undefined

Parameters ​
font ​

string

Returns ​

number[] | undefined


insertEdgelessTextCommand ​

const insertEdgelessTextCommand: Command<{ x: number; y: number; }, { textId: string; }>


text ​

const text: ElementRenderer<TextElementModel>


TextElementRendererExtension ​

const TextElementRendererExtension: ExtensionType & object

Type Declaration ​

identifier ​

identifier: ServiceIdentifier<ElementRenderer<TextElementModel>>


TextInteraction ​

const TextInteraction: ExtensionType


textToMarkdownAdapterMatcher ​

const textToMarkdownAdapterMatcher: ExtensionType & object

Type Declaration ​

identifier ​

identifier: ServiceIdentifier<ElementToMarkdownAdapterMatcher>


textToolbarConfig ​

const textToolbarConfig: object

Type Declaration ​

actions ​

readonly actions: [{ id: "a.font"; content: TemplateResult<1> | null; }, { id: "b.text-color"; content: TemplateResult<1> | null; }, { id: "c.font-style"; content: TemplateResult<1> | null; }, { id: "d.font-size"; when: boolean; content: TemplateResult<1> | null; }, { id: "e.alignment"; content: TemplateResult<1> | null; }]

when ​

readonly when: (ctx) => boolean

Parameters ​
ctx ​

ToolbarContext

Returns ​

boolean


textToolbarExtension ​

const textToolbarExtension: ExtensionType


textToPlainTextAdapterMatcher ​

const textToPlainTextAdapterMatcher: ExtensionType & object

Type Declaration ​

identifier ​

identifier: ServiceIdentifier<ElementToPlainTextAdapterMatcher>

Functions ​

addText() ​

addText(edgeless, event): void

Parameters ​

edgeless ​

BlockComponent

event ​

PointerEventState

Returns ​

void

Deprecated ​

Canvas Text has been deprecated


createTextActions() ​

createTextActions<K, T>(klass, type, update?, mapInto?, stash?): [{ id: "a.font"; content: TemplateResult<1> | null; }, { id: "b.text-color"; content: TemplateResult<1> | null; }, { id: "c.font-style"; content: TemplateResult<1> | null; }, { id: "d.font-size"; when: boolean; content: TemplateResult<1> | null; }, { id: "e.alignment"; content: TemplateResult<1> | null; }]

Type Parameters ​

K ​

K extends (...args) => any

T ​

T extends keyof SurfaceTextModelMap

Parameters ​

klass ​

K

type ​

T

update? ​

(ctx, model, props) => void

mapInto? ​

(model) => TextStyleProps

stash? ​

<P>(model, type, field) => void

Returns ​

[{ id: "a.font"; content: TemplateResult<1> | null; }, { id: "b.text-color"; content: TemplateResult<1> | null; }, { id: "c.font-style"; content: TemplateResult<1> | null; }, { id: "d.font-size"; when: boolean; content: TemplateResult<1> | null; }, { id: "e.alignment"; content: TemplateResult<1> | null; }]


getCursorByCoord() ​

getCursorByCoord(model, coord): number

Parameters ​

model ​

TextElementModel

coord ​
x ​

number

y ​

number

Returns ​

number


getFontMetrics() ​

getFontMetrics(fontFamily, fontSize, fontWeight): TextMetrics

Parameters ​

fontFamily ​

string

fontSize ​

number

fontWeight ​

string

Returns ​

TextMetrics


getFontString() ​

getFontString(__namedParameters): string

Parameters ​

__namedParameters ​
fontFamily ​

string

fontSize ​

number

fontStyle ​

string

fontWeight ​

string

Returns ​

string


getLineHeight() ​

getLineHeight(fontFamily, fontSize, fontWeight): number

Parameters ​

fontFamily ​

string

fontSize ​

number

fontWeight ​

string

Returns ​

number


getLineWidth() ​

getLineWidth(text, font): number

Parameters ​

text ​

string

font ​

string

Returns ​

number


getTextCursorPosition() ​

getTextCursorPosition(model, coord): number[]

Parameters ​

model ​

TextElementModel

coord ​
x ​

number

y ​

number

Returns ​

number[]


getTextHeight() ​

getTextHeight(text, lineHeight): number

Parameters ​

text ​

string

lineHeight ​

number

Returns ​

number


getTextWidth() ​

getTextWidth(text, font): number

Parameters ​

text ​

string

font ​

string

Returns ​

number


isFontStyleSupported() ​

isFontStyleSupported(fontFamily, style): boolean

Parameters ​

fontFamily ​

string

style ​

FontStyle

Returns ​

boolean


isFontWeightSupported() ​

isFontWeightSupported(fontFamily, weight): boolean

Parameters ​

fontFamily ​

string

weight ​

FontWeight

Returns ​

boolean


isRTL() ​

isRTL(text): boolean

Parameters ​

text ​

string

Returns ​

boolean


measureTextInDOM() ​

measureTextInDOM(fontFamily, fontSize, fontWeight): object

Parameters ​

fontFamily ​

string

fontSize ​

number

fontWeight ​

string

Returns ​

object

lineGap ​

lineGap: number

lineHeight ​

lineHeight: number


mountTextElementEditor() ​

mountTextElementEditor(textElement, edgeless, focusCoord?): void

Parameters ​

textElement ​

TextElementModel

edgeless ​

BlockComponent

focusCoord? ​

IModelCoord

Returns ​

void


normalizeText() ​

normalizeText(text): string

Parameters ​

text ​

string

Returns ​

string


normalizeTextBound() ​

normalizeTextBound(__namedParameters, bound, dragging?): Bound

Parameters ​

__namedParameters ​
fontFamily ​

FontFamily

fontSize ​

number

fontStyle ​

FontStyle

fontWeight ​

FontWeight

hasMaxWidth? ​

boolean

maxWidth? ​

number

yText ​

YText

bound ​

Bound

dragging? ​

boolean = false

Returns ​

Bound


parseTokens() ​

parseTokens(text): string[]

Parameters ​

text ​

string

Returns ​

string[]


splitIntoLines() ​

splitIntoLines(text): string[]

Parameters ​

text ​

string

Returns ​

string[]


truncateTextByWidth() ​

truncateTextByWidth(text, font, width): string

Parameters ​

text ​

string

font ​

string

width ​

number

Returns ​

string


wrapText() ​

wrapText(text, font, maxWidth): string

Parameters ​

text ​

string

font ​

string

maxWidth ​

number

Returns ​

string


wrapTextDeltas() ​

wrapTextDeltas(text, font, w): TextDelta[]

Parameters ​

text ​

YText

font ​

string

w ​

number

Returns ​

TextDelta[]