Selection

Overview

Selection in BlockSuite is a data model that represents the user's current selection state in the editor. It follows a unidirectional data flow pattern:

  1. User interacts with the editor

  2. Selection model is updated

  3. View is rendered based on the selection state

Selection as a Data Model

Core Concept

  • Selection is a pure data model that describes what is currently selected

  • It's independent of how the selection is rendered

  • Changes to selection are managed through the selection extension

  • The model is synchronized across clients in collaborative scenarios

Data Flow

User Interaction → Selection Model Update → View Update

Selection Structure

Base Components

import { BaseSelection, SelectionExtension } from '@blocksuite/store';
import z from 'zod';

// 1. Define the data model schema
const SelectionSchema = z.object({
  blockId: z.string(),
  // ... other properties
});

// 2. Define the selection data model
export class CustomSelection extends BaseSelection {
  static override group = 'note';
  static override type = 'custom';

  // Convert from JSON to model
  static override fromJSON(json: Record<string, unknown>): CustomSelection {
    const result = SelectionSchema.parse(json);
    return new CustomSelection(result);
  }

  // Compare selection models
  override equals(other: BaseSelection): boolean {
    if (other instanceof CustomSelection) {
      return this.blockId === other.blockId;
    }
    return false;
  }

  // Convert model to JSON
  override toJSON(): Record<string, unknown> {
    return {
      type: this.type,
      blockId: this.blockId,
    };
  }
}

// 3. Register the selection model
export const CustomSelectionExtension = SelectionExtension(CustomSelection);

Selection Management

Updating Selection State

// Create new selection state
const selection = selectionExtension.create(CustomSelection, props);

// Update selection state
selectionExtension.set([selection]);

// Clear selection state
selectionExtension.clear();

Querying Selection State

// Get current selection state
const currentSelection = selectionExtension.find(CustomSelection);

// Get all selections of a type
const selections = selectionExtension.filter(CustomSelection);

Best Practices

  1. Data Model Design
  • Keep the model focused on selection state

  • Use Zod for runtime validation

  • Ensure proper serialization

  1. State Management
  • Update selection state through the extension

  • Handle selection lifecycle properly

  • Consider collaborative scenarios

  1. View Integration
  • Let the view layer handle rendering

  • Keep selection model independent of view

  • Use selection state to drive UI updates