Перейти к содержимому
ФреймворкJavaScript

BlockAPI: работа с одним блоком

Интерфейс для работы с отдельными блоками. Возвращается методами blocks.getById(), blocks.getBlockByIndex() и blocks.insert().

Как получить экземпляр редактора

Методы ниже вызываются на редакторе, созданном через new Blok(). Они доступны после того, как разрешится editor.isReady.

TypeScript
// You already hold the instance returned by the constructor.
const editor = new Blok({ holder: 'editor' });
await editor.isReady;

// Call any API method on it.
editor.caret.setToLastBlock('end');

Методы

block.save()

Promise<void|SavedData>

Сохранить содержимое блока и вернуть его данные.

Когда использовать

Возвращает данные только этого блока — удобно проверить или сохранить один блок без полного обхода editor.save().

TypeScript
const block = editor.blocks.getById('block-123');
const saved = await block.save();
// saved resolves to a SavedData object (or undefined if extraction fails):
// { id: 'block-123', tool: 'paragraph', data: { text: 'Block content' }, time: 1717000000000 }
console.log(saved?.data); // { text: 'Block content' }

block.validate(data)

Promise<boolean>

Проверить данные блока по правилам валидации инструмента.

Когда использовать

Запускает validate() инструмента для переданных данных; используйте, чтобы отсеять пустые или некорректные блоки перед сохранением.

TypeScript
const block = editor.blocks.getById('block-123');
const isValid = await block.validate({ text: 'Hello' });
if (!isValid) {
  console.log('Block data is invalid');
}

block.call(methodName, param?)

void

Вызвать собственный метод инструмента блока.

Когда использовать

Запасной способ вызвать собственный метод инструмента — для поведения вне стандартного API BlockTool.

TypeScript
const block = editor.blocks.getById('block-123');
// Call a custom method defined in the tool
block.call('showNotification', { message: 'Hello' });

block.dispatchChange()

void

Вручную вызвать колбэк onChange для этого блока.

Когда использовать

Вызывайте, когда меняете блок в обход Blok (например, асинхронно), чтобы сработали события изменения и синхронизация CRDT.

TypeScript
const block = editor.blocks.getById('block-123');
// Trigger change after invisible modification
block.dispatchChange();

block.getActiveToolboxEntry()

Promise<ToolboxConfigEntry | undefined>

Получить активный пункт тулбокса для этого блока (например, Заголовок 1 или Заголовок 2).

Когда использовать

Определяет активный вариант в тулбоксе (например, Заголовок 1 или 2) — полезно для отражения состояния в своём UI.

TypeScript
const block = editor.blocks.getById('block-123');
const entry = await block.getActiveToolboxEntry();
if (entry) {
  console.log('Active entry:', entry.title);
}

block.getChildren()

BlockAPI[]

Прямые дочерние блоки этого блока как объекты BlockAPI, по порядку. Каждый BlockAPI, который выдаёт редактор, живой, поэтому возвращённые дочерние блоки можно обходить рекурсивно (`child.getChildren()`) и изменять (`child.setParent(...)`, `child.insertChild(...)`).

TypeScript
const block = editor.blocks.getById('toggle-123');
block?.getChildren().forEach((child) => console.log(child.id));

block.setParent(parentId)

void

Переподчинить этот блок родителю `parentId` или вернуть его на корневой уровень значением `null`. Проходит через универсальную единую точку ядра `setBlockParent`, поэтому `contentIds` родителя обновляется вместе с `parentId` этого блока.

TypeScript
const block = editor.blocks.getById('block-123');
block?.setParent('parent-block-id');

// Back to the root level
block?.setParent(null);

block.insertChild(childData?, position?, toolName?, options?)

BlockAPI

Вставить дочерний блок под ЭТОТ блок атомарно — создание и назначение родителя укладываются в один шаг отмены (делегирует в `blocks.insertInsideParent`). `position` — это `BlockChildPosition`: 'start' | 'end' | { before: childId } | { after: childId }, по умолчанию 'end' (добавляется в конец, за всё поддерево). `toolName` выбирает блочный инструмент дочернего блока и по умолчанию равен `config.defaultBlock`, поэтому ТИПИЗИРОВАННЫЙ дочерний блок — это одна операция вместо вставки с последующим переподчинением; инструмент, ограниченный внутри ячеек таблицы, понижается до блока по умолчанию, когда новый дочерний блок попал бы внутрь такой ячейки. `childData` по умолчанию равен `{ text: '' }` для блока по умолчанию и `{}`, когда `toolName` называет другой инструмент. `options` несёт тот же словарь `{ focus, caret, id, tunes, replace }`, что и расширенная спецификация `insert` у адаптеров фреймворков, поэтому контейнерному инструменту никогда не приходится вручную расставлять курсор или следом вызывать `update`, чтобы применить тюны.

Параметры

ПараметрТипОбязательныйПо умолчаниюОписание
childDataBlockToolData{ text: '' } / {}Данные для нового дочернего блока. По умолчанию — пустой объект данных параграфа для блочного инструмента по умолчанию и {} — что позволяет инструменту применить собственные значения по умолчанию — когда указан toolName.
positionBlockChildPosition'end'Куда среди существующих дочерних блоков вставлять: 'start', 'end', { before: childId } или { after: childId }.
toolNamestringconfig.defaultBlockБлочный инструмент, который нужно создать для дочернего блока. Понижается до блока по умолчанию, когда он ограничен внутри ячеек таблицы и новый дочерний блок попал бы внутрь такой ячейки.
optionsInsertChildOptions{}focus — сделать новый дочерний блок текущим. caret — поставить курсор внутрь него ({ position?, offset? }), применяется, только когда дочерний блок действительно создан. id — явный id; уже существующий id работает как «вставить, если нет» (возвращается этот дочерний блок, ничего не создаётся). tunes — данные тюнов блока, применяемые при создании. replace — перезаписать дочерний блок, названный объектной позицией, вместо вставки рядом с ним; с 'start'/'end' перезаписывать нечего, и вызов выбрасывает исключение.
TypeScript
const block = editor.blocks.getById('toggle-123');
const child = block?.insertChild({ text: 'Hidden content' });

// Place it among the existing children instead of appending
block?.insertChild({ text: 'First' }, 'start');
block?.insertChild({ text: 'After that one' }, { after: 'child-id' });

// A typed child, in a single undo entry
block?.insertChild({ text: 'Section', level: 3 }, 'end', 'header');

// Drop the caret into the new child at a specific offset
block?.insertChild({ text: 'Draft' }, 'end', undefined, { caret: { offset: 5 } });

// Idempotent: a re-running effect cannot duplicate this child
block?.insertChild({ text: 'Intro' }, 'start', undefined, { id: 'intro-row' });

// Child-level "turn into" — overwrite an existing child, keeping it parented
block?.insertChild({ text: 'Now a heading', level: 3 }, { before: 'child-id' }, 'header', { replace: true });

block.moveChild(childId, delta)

void

Переместить прямой дочерний блок на `delta` позиций среди его соседей, с ограничением по допустимому диапазону. Дочерний блок со своим поддеревом встаёт за потомками целевого соседа, а не внутрь них. No-op, когда `delta` равна 0, когда `childId` не является прямым дочерним блоком или когда ограниченное перемещение не изменит позицию.

TypeScript
const block = editor.blocks.getById('toggle-123');
block?.moveChild('child-id', -1); // one position toward the start
block?.moveChild('child-id', 1);  // one position toward the end

Свойства

СвойствоТипОписание
idstringУникальный идентификатор блока
namestringИмя инструмента (например, «paragraph», «header»)
configToolConfigКонфигурация инструмента, переданная при инициализации
holderHTMLElementОбёртка HTML-элемента инструмента
isEmptybooleanTrue, если содержимое блока пусто
selectedbooleanTrue, если блок входит в выбор на уровне БЛОКОВ (перетаскивание рамкой, Shift+Click, Shift+Arrow, Cmd/Ctrl+A). Перетаскивание по тексту нескольких блоков даёт вместо этого выделение на уровне символов, при котором ни один блок не помечен как выбранный — такое выделение читайте из собственного Selection документа.
focusablebooleanTrue, если у блока есть поля ввода, которые можно сфокусировать
stretchedbooleanГеттер/сеттер состояния растягивания блока
parentIdstring | nullId родительского блока или null, если у этого блока нет родителя
contentIdsreadonly string[]Id прямых дочерних блоков этого блока, по порядку — копия только для чтения, поэтому её изменение ничего не даёт. Аналог parentId на уровне блока: позволяет контейнерному инструменту читать свои дочерние блоки, не обращаясь к API редактора
preservedDataBlockToolDataПоследние успешно извлечённые данные блочного инструмента, синхронно — полезно, когда асинхронный save() неприменим, например при операциях с буфером обмена
preservedTunes{ [name: string]: BlockTuneData }Последние успешно извлечённые данные тюнов блока, синхронно — полезно, когда асинхронный save() неприменим, например при операциях с буфером обмена