BlockAPI: работа с одним блоком
Интерфейс для работы с отдельными блоками. Возвращается методами blocks.getById(), blocks.getBlockByIndex() и blocks.insert().
Как получить экземпляр редактора
Методы ниже вызываются на редакторе, созданном через new Blok(). Они доступны после того, как разрешится editor.isReady.
// 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().
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() инструмента для переданных данных; используйте, чтобы отсеять пустые или некорректные блоки перед сохранением.
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.
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.
const block = editor.blocks.getById('block-123');
// Trigger change after invisible modification
block.dispatchChange();block.getActiveToolboxEntry()
Promise<ToolboxConfigEntry | undefined>Получить активный пункт тулбокса для этого блока (например, Заголовок 1 или Заголовок 2).
Когда использовать
Определяет активный вариант в тулбоксе (например, Заголовок 1 или 2) — полезно для отражения состояния в своём UI.
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(...)`).
const block = editor.blocks.getById('toggle-123');
block?.getChildren().forEach((child) => console.log(child.id));block.setParent(parentId)
voidПереподчинить этот блок родителю `parentId` или вернуть его на корневой уровень значением `null`. Проходит через универсальную единую точку ядра `setBlockParent`, поэтому `contentIds` родителя обновляется вместе с `parentId` этого блока.
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`, чтобы применить тюны.
Параметры
| Параметр | Тип | Обязательный | По умолчанию | Описание |
|---|---|---|---|---|
childData | BlockToolData | — | { text: '' } / {} | Данные для нового дочернего блока. По умолчанию — пустой объект данных параграфа для блочного инструмента по умолчанию и {} — что позволяет инструменту применить собственные значения по умолчанию — когда указан toolName. |
position | BlockChildPosition | — | 'end' | Куда среди существующих дочерних блоков вставлять: 'start', 'end', { before: childId } или { after: childId }. |
toolName | string | — | config.defaultBlock | Блочный инструмент, который нужно создать для дочернего блока. Понижается до блока по умолчанию, когда он ограничен внутри ячеек таблицы и новый дочерний блок попал бы внутрь такой ячейки. |
options | InsertChildOptions | — | {} | focus — сделать новый дочерний блок текущим. caret — поставить курсор внутрь него ({ position?, offset? }), применяется, только когда дочерний блок действительно создан. id — явный id; уже существующий id работает как «вставить, если нет» (возвращается этот дочерний блок, ничего не создаётся). tunes — данные тюнов блока, применяемые при создании. replace — перезаписать дочерний блок, названный объектной позицией, вместо вставки рядом с ним; с 'start'/'end' перезаписывать нечего, и вызов выбрасывает исключение. |
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` не является прямым дочерним блоком или когда ограниченное перемещение не изменит позицию.
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Свойства
| Свойство | Тип | Описание |
|---|---|---|
id | string | Уникальный идентификатор блока |
name | string | Имя инструмента (например, «paragraph», «header») |
config | ToolConfig | Конфигурация инструмента, переданная при инициализации |
holder | HTMLElement | Обёртка HTML-элемента инструмента |
isEmpty | boolean | True, если содержимое блока пусто |
selected | boolean | True, если блок входит в выбор на уровне БЛОКОВ (перетаскивание рамкой, Shift+Click, Shift+Arrow, Cmd/Ctrl+A). Перетаскивание по тексту нескольких блоков даёт вместо этого выделение на уровне символов, при котором ни один блок не помечен как выбранный — такое выделение читайте из собственного Selection документа. |
focusable | boolean | True, если у блока есть поля ввода, которые можно сфокусировать |
stretched | boolean | Геттер/сеттер состояния растягивания блока |
parentId | string | null | Id родительского блока или null, если у этого блока нет родителя |
contentIds | readonly string[] | Id прямых дочерних блоков этого блока, по порядку — копия только для чтения, поэтому её изменение ничего не даёт. Аналог parentId на уровне блока: позволяет контейнерному инструменту читать свои дочерние блоки, не обращаясь к API редактора |
preservedData | BlockToolData | Последние успешно извлечённые данные блочного инструмента, синхронно — полезно, когда асинхронный save() неприменим, например при операциях с буфером обмена |
preservedTunes | { [name: string]: BlockTuneData } | Последние успешно извлечённые данные тюнов блока, синхронно — полезно, когда асинхронный save() неприменим, например при операциях с буфером обмена |