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>Save the block content and return its data.
Когда использовать
Возвращает данные только этого блока — удобно проверить или сохранить один блок без полного обхода 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 block data against the tool's validation rules.
Когда использовать
Запускает 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?)
voidCall a custom method on the block's tool.
Когда использовать
Запасной способ вызвать собственный метод инструмента — для поведения вне стандартного API BlockTool.
const block = editor.blocks.getById('block-123');
// Call a custom method defined in the tool
block.call('showNotification', { message: 'Hello' });block.dispatchChange()
voidManually trigger the onChange callback for this block.
Когда использовать
Вызывайте, когда меняете блок в обход Blok (например, асинхронно), чтобы сработали события изменения и синхронизация CRDT.
const block = editor.blocks.getById('block-123');
// Trigger change after invisible modification
block.dispatchChange();block.getActiveToolboxEntry()
Promise<ToolboxConfigEntry | undefined>Get the active toolbox entry for this block (e.g., Heading 1 vs Heading 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[]This block's direct children as BlockAPI objects, in order. Every BlockAPI the editor hands out is live, so the children it returns can be walked recursively (`child.getChildren()`) and mutated (`child.setParent(...)`, `child.insertChild(...)`).
const block = editor.blocks.getById('toggle-123');
block?.getChildren().forEach((child) => console.log(child.id));block.setParent(parentId)
voidReparent this block under `parentId`, or back to the root level with `null`. Routes through core's universal `setBlockParent` chokepoint, so the parent's `contentIds` is updated together with this block's `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?)
BlockAPIInsert a child block under THIS block atomically — creation and parent assignment land in a single undo entry (it delegates to `blocks.insertInsideParent`). `position` is a `BlockChildPosition`: 'start' | 'end' | { before: childId } | { after: childId }, defaulting to 'end' (appended past the whole subtree). `toolName` picks the child's block tool and defaults to `config.defaultBlock`, so a TYPED child is one operation instead of insert-then-reparent; a tool restricted inside table cells is demoted to the default block when the new child would land inside one. `childData` defaults to `{ text: '' }` for the default block and to `{}` when `toolName` names a different tool. `options` carries the same `{ focus, caret, id, tunes, replace }` vocabulary the framework adapters' rich `insert` spec uses, so a container tool never has to hand-roll caret placement or follow up with an `update` to apply tunes.
Параметры
| Параметр | Тип | Обязательный | По умолчанию | Описание |
|---|---|---|---|---|
childData | BlockToolData | — | { text: '' } / {} | Data for the new child block. Defaults to an empty paragraph blob for the default block tool, and to {} — letting the tool apply its own defaults — when toolName is given. |
position | BlockChildPosition | — | 'end' | Where among the existing children to insert: 'start', 'end', { before: childId } or { after: childId }. |
toolName | string | — | config.defaultBlock | Block tool to create for the child. Demoted to the default block when it is restricted inside table cells and the new child would land inside one. |
options | InsertChildOptions | — | {} | focus — make the new child the current block. caret — place the caret inside it ({ position?, offset? }), applied only when a child is actually created. id — explicit id; an id that already exists is insert-if-absent (that child is returned, nothing is created). tunes — block tune data applied at creation. replace — overwrite the child named by an object position instead of inserting beside it; with 'start'/'end' there is nothing to overwrite and the call throws. |
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)
voidMove a direct child by `delta` positions among its siblings, clamped to the valid range. A child carrying its own subtree lands past the target sibling's descendants, not inside them. No-op when `delta` is 0, when `childId` is not a direct child, or when the clamped move would not change the position.
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 | Unique block identifier |
name | string | Tool name (e.g., "paragraph", "header") |
config | ToolConfig | Tool config passed on initialization |
holder | HTMLElement | Wrapper of Tool's HTML element |
isEmpty | boolean | True if block content is empty |
selected | boolean | True if the block is part of a BLOCK-level selection (rubber-band drag, Shift+Click, Shift+Arrow, Cmd/Ctrl+A). A drag across the text of several blocks makes a character-level selection instead, which marks no block as selected — read that one from the document's own Selection. |
focusable | boolean | True if block has inputs to be focused |
stretched | boolean | Getter/setter for block stretch state |
parentId | string | null | Id of the parent block, or null if this block has no parent |
contentIds | readonly string[] | Ids of this block's direct children, in order — a read-only copy, so mutating it changes nothing. The block-level counterpart of parentId: it lets a container tool read its children without reaching for the editor API |
preservedData | BlockToolData | Last successfully extracted block tool data, synchronous — useful when async save() is not feasible, e.g. clipboard operations |
preservedTunes | { [name: string]: BlockTuneData } | Last successfully extracted block tune data, synchronous — useful when async save() is not feasible, e.g. clipboard operations |