---
title: "Blocks API — вставка, перенос и удаление блоков"
description: "Программная вставка, перенос, удаление, конвертация и рендер блоков, включая вложенные блоки и вставку markdown."
source: https://blokeditor.com/ru/docs/blocks-api/
lastmod: 2026-09-07
---

Фреймворк JavaScript

Основное Блоки

На этой странице blocks.clear()

# Blocks API: вставка, перенос и удаление блоков

Управление блоками в редакторе — создание, удаление, обновление и переупорядочивание контента.

[Редактировать на GitHub](https://github.com/JackUait/blok/blob/main/docs/src/components/api/api-data.ts)

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

Методы ниже вызываются на редакторе, созданном через 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');
```

## Методы

### blocks.clear()

Promise<void>

Удалить все блоки из редактора.

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

То же, что `clear()` верхнего уровня, но на модуле blocks. Используйте, когда уже есть ссылка на `editor.blocks`.

TypeScript

```
await editor.blocks.clear();
// All content removed; editor keeps one empty paragraph
```

### blocks.render(data)

Promise<void>

Отрисовать переданные JSON-данные как блоки, заменив текущий документ. Устойчив к эху: когда входящий документ структурно равен текущему сохранённому содержимому (`time`/`version` игнорируются), вызов оказывается no-op с сохранением курсора — круговому пути `data → render → onSave → setState → data` не нужна дедупликация на стороне потребителя. Принимает нестрогий формат (`LooseOutputData`); редактор делает глубокую копию данных, поэтому переданный объект никогда не мутируется и не удерживается — замороженное состояние хранилища (Redux, Immer) можно передавать напрямую.

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

Заменяет весь документ. Повторная передача собственного вывода редактора — no-op с сохранением курсора, дедупликация на стороне потребителя не нужна. Чтобы добавить блоки без очистки, используйте `insert()` или `insertMany()`.

TypeScript

```
const data = {
  blocks: [
    { id: '1', type: 'paragraph', data: { text: 'Hello World' } },
    { id: '2', type: 'header', data: { text: 'Title', level: 1 } }
  ]
};
await editor.blocks.render(data);
```

### blocks.renderFromHTML(data)

Promise<void>

Отрисовать HTML-строку как блоки, преобразовав её в формат блоков.

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

Удобно для импорта старого HTML, но результат зависит от обработчиков вставки инструментов — JSON через `render()` сохраняет больше точности, когда источник под контролем.

TypeScript

```
const html = '<h1>Title</h1><p>Hello World</p>';
await editor.blocks.renderFromHTML(html);
// HTML is converted to appropriate blocks
```

### blocks.importMarkdown(md, options?)

Promise<OutputData>

Преобразовать Markdown-строку в блоки и отрисовать их, ЗАМЕНИВ текущий документ, — внутри вызывается `blocks.render()`. Конвертер загружается лениво при первом вызове, а OutputData, которым резолвится промис, — это отрисованный документ. `options` — это `MarkdownImportConfig` (сопоставление инструментов, переключатель GFM, расширения micromark/mdast). Для аддитивной вставки используйте `markdownToBlocks()` из отдельного подпути `@bloklabs/core/markdown` вместе с `blocks.insertMany()`.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `md` | `string` | Обязательный | — | Исходная Markdown-строка. |
| `options` | `MarkdownImportConfig` | — | `undefined` | Сопоставление инструментов, переключатель GFM и расширения micromark/mdast. |

TypeScript

```
const data = await editor.blocks.importMarkdown('# Title\n\n- one\n- two');
// The whole document is replaced; data is the rendered OutputData
```

### blocks.exportMarkdown()

Promise<string>

Сериализовать текущий документ в Markdown — исходящий близнец `importMarkdown`. Блоки читаются через Saver, поэтому вывод отражает сохранённый (провалидированный) документ, а не сырой DOM, и промис резолвится в '', когда сохранять нечего. Блоки, принадлежащие ячейке таблицы, сериализуются внутри pipe-таблицы, а не повторяются как отдельные строки. То, что Markdown выразить не может, деградирует: `colspan`/`rowspan` таблицы и столбцы заголовков отбрасываются, а таблица без строки заголовков получает пустую строку заголовка, поскольку GFM её требует.

TypeScript

```
const md = await editor.blocks.exportMarkdown();
// → '# Title\n\n- one\n- two'
```

### blocks.delete(index?, setCaret?)

Promise<void>

Удалить блок по указанному индексу или текущий блок, если индекс не передан.

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

Без индекса удаляет блок в фокусе. Удаление последнего оставшегося блока автоматически вставляет свежий пустой параграф, поэтому редактор никогда не остаётся без цели для курсора.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `index` | `number` | — | `current block index` | Индекс блока для удаления. |
| `setCaret` | `boolean` | — | `true` | Перемещать ли курсор на уцелевший блок после удаления; передайте false, чтобы не отбирать курсор у пользователя при программном удалении. |

TypeScript

```
// Delete current block
await editor.blocks.delete();

// Delete block at index 0
await editor.blocks.delete(0);

// Delete without moving the user's caret (programmatic deletion)
await editor.blocks.delete(0, false);
```

### blocks.move(toIndex, fromIndex?)

void

Перемещает блок на новую позицию. Если fromIndex не передан, перемещает текущий блок.

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

`toIndex` — это индекс после удаления: при перемещении вперёд вычтите 1, иначе блок встанет на позицию дальше нужной.

TypeScript

```
// Move current block to top
editor.blocks.move(0);

// Move block from index 2 to index 0
editor.blocks.move(0, 2);
```

### blocks.getBlockByIndex(index)

BlockAPI | undefined

Получить объект BlockAPI для блока по указанному индексу.

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

Возвращает `undefined` для индексов вне диапазона — вызов метода на `undefined` приведёт к ошибке, поэтому сначала проверьте результат.

TypeScript

```
const block = editor.blocks.getBlockByIndex(0);
if (block) {
  console.log(block.id, block.name);
}
```

### blocks.getById(id)

BlockAPI | null

Получить объект BlockAPI для блока с указанным ID.

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

Надёжный способ ссылаться на блок между правками, так как индексы смещаются. Возвращает `null`, если id больше не существует.

TypeScript

```
const block = editor.blocks.getById('block-123');
if (block) {
  await editor.blocks.update(block.id, { text: 'New content' });
}
```

### blocks.getCurrentBlockIndex()

number

Получить индекс блока, который сейчас в фокусе.

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

Отражает блок с курсором. Возвращает `-1`, когда ничего не в фокусе, — проверяйте перед использованием как индекс.

TypeScript

```
const index = editor.blocks.getCurrentBlockIndex();
console.log('Current block index:', index);
```

### blocks.getBlockIndex(blockId)

number | undefined

Получить индекс блока по его ID.

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

Узнаёт текущую позицию известного блока; сочетайте с `getById()`, когда есть id, а нужна позиция.

TypeScript

```
const index = editor.blocks.getBlockIndex('block-123');
if (index !== undefined) {
  console.log('Block is at index:', index);
}
```

### blocks.getBlockByElement(element)

BlockAPI | undefined

Получить объект BlockAPI для блока, который содержит переданный HTML-элемент.

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

Мост от DOM-узла (например, цели клика) обратно к его блоку — полезно в собственных обработчиках.

TypeScript

```
document.addEventListener('click', (e) => {
  const block = editor.blocks.getBlockByElement(e.target);
  if (block) {
    console.log('Clicked on block:', block.id);
  }
});
```

### blocks.scrollToBlock(id)

void

Прокрутить страницу к блоку, выбрать его, мигнуть подсветкой прибытия и объявить переход вспомогательным технологиям — публичный аналог прокрутки по хешу URL при загрузке. No-op, когда в документе нет блока с таким id. Адаптеры фреймворков, монтирующиеся в отсоединённый холдер (React/Vue/Angular), отрисовывают засеянный контент до того, как он попадёт на страницу, поэтому загрузочная прокрутка по хешу откладывается; @bloklabs/react выполняет её автоматически, как только холдер подключается, — для глубоких ссылок вызывайте этот метод сами после готовности редактора.

TypeScript

```
editor.blocks.scrollToBlock(nodeId);
```

### blocks.getChildren(parentId)

BlockAPI[]

Получить все дочерние блоки родительского блока-контейнера.

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

Возвращает прямых потомков блока-контейнера (колонки, тоггла или базы данных). Пустой массив, если потомков нет.

TypeScript

```
const children = editor.blocks.getChildren('parent-block-id');
children.forEach(child => {
  console.log('Child:', child.id);
});
```

### blocks.setBlockParent(blockId, parentId)

void

Сменить родителя блока: обновляет `parentId` блока и `contentIds` родителя через единственную в ядре точку смены родителя. Передайте `null`, чтобы вернуть блок на корневой уровень. Неизвестный `blockId` — это no-op с записью предупреждения в лог; `parentId`, который сделал бы блок потомком самого себя, выбрасывает ошибку.

TypeScript

```
// Move a block into a container block
editor.blocks.setBlockParent('child-block-id', 'parent-block-id');

// Move it back to the root level
editor.blocks.setBlockParent('child-block-id', null);
```

### blocks.insertInsideParent(parentId, insertIndex, childData?, toolName?)

BlockAPI

Вставить блок как дочерний для `parentId` атомарно: создание и назначение родителя объединяются в ОДИН шаг отмены, поэтому одно нажатие Cmd+Z убирает его полностью (предпочтительнее, чем `insert()` с последующей сменой родителя, где шага два). `insertIndex` — это ПЛОСКИЙ индекс документа, по которому должен появиться дочерний блок. `toolName` выбирает блочный инструмент дочернего блока и по умолчанию равен `config.defaultBlock`; инструмент, запрещённый внутри ячеек таблицы, понижается до блока по умолчанию, когда новый дочерний блок оказался бы внутри такой ячейки, а незарегистрированное имя выбрасывает ошибку до того, как что-либо будет записано. `childData` по умолчанию равен `{ text: '' }` для блока по умолчанию и `{}` — позволяя инструменту применить собственные значения по умолчанию — всякий раз, когда `toolName` называет другой инструмент.

TypeScript

```
const parentIndex = editor.blocks.getBlockIndex('parent-block-id') ?? 0;
const child = editor.blocks.insertInsideParent(
  'parent-block-id',
  parentIndex + 1,
  { text: 'Nested content' },
);

// A TYPED child in the same single undo entry — no insert-then-reparent
editor.blocks.insertInsideParent(
  'parent-block-id',
  parentIndex + 1,
  { text: 'Nested heading', level: 2 },
  'header',
);
```

### blocks.getBlocksCount()

number

Получить общее количество блоков в редакторе.

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

Считает все блоки, включая вложенные дочерние (колонки, тогглы, ячейки таблиц), а не только блоки верхнего уровня. Используйте для границ перед `insert()` или `move()` по индексу.

TypeScript

```
const count = editor.blocks.getBlocksCount();
console.log('Total blocks:', count);
```

### blocks.insert(type?, data?, config?, index?, needToFocus?, replace?, id?, tunes?, origin?)

BlockAPI

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

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

Все параметры необязательны — `insert()` даёт пустой параграф, либо передайте `type`/`data`/`index` для контроля. `replace: true` заменяет блок по индексу `index`.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `type` | `string` | — | `config.defaultBlock` | Имя инструмента для создания блока. |
| `data` | `BlockToolData` | — | `{}` | Начальные данные инструмента для нового блока. |
| `config` | `ToolConfig` | — | `{}` | Игнорируется — принимается только ради сохранения позиционной сигнатуры. Редактор связывает его с `_config` и никогда не читает, а опции вставки в block-manager не содержат поля `config`, поэтому созданный блок использует конфигурацию инструмента уровня редактора из `config.tools`. Передавайте `undefined`. |
| `index` | `number` | — | `current block index + 1` | Позиция для вставки блока. |
| `needToFocus` | `boolean` | — | `true` | Переводить ли фокус на вставленный блок. Передайте false, чтобы вставить блок, не перемещая курсор. |
| `replace` | `boolean` | — | `false` | Заменить существующий блок по индексу вместо вставки рядом с ним. |
| `id` | `string` | — | `auto-generated` | Собственный id для нового блока. |
| `tunes` | `{ [name: string]: BlockTuneData }` | — | `undefined` | Необязательные данные тюнов, применяемые при создании, с ключами по имени тюна. |
| `origin` | `BlockOrigin` | — | `'api'` | Почему блок создаётся. Передаётся в конструктор инструмента как `origin` — именно так контейнерный инструмент отличает настоящее создание (можно засеять детей по умолчанию) от повторной материализации: загрузки документа, воспроизведения undo/redo или вставки (засевать нельзя). Передавайте `'user'`, когда вставка идёт из вашего собственного интерфейса — своей панели, тулбокса или горячей клавиши, — чтобы встроенные контейнеры Blok (`column_list`, `column`) и ваши собственные вели себя так же, как при вставке из штатного меню. Для программных вставок и перезагрузки данных параметр можно не передавать: значение по умолчанию `'api'` тоже считается созданием, но никогда не выдаётся за жест пользователя. |

Ошибки

- Не указан `type`, и в конфигурации не задан `defaultBlock`. Could not insert Block. Tool name is not specified. Передайте явный `type` или задайте `defaultBlock` в конфигурации редактора.
- Определённое имя инструмента не зарегистрировано в редакторе. Could not compose Block. Tool «<type>» not found. Зарегистрируйте инструмент в конфигурации `tools` редактора перед вставкой блока этого типа.
- Передан `replace: true`, но по `index` нет блока. Could not replace Block at index <index>. Block not found. Проверьте `index` через `blocks.getBlocksCount()` перед вызовом с `replace: true`.

TypeScript

```
// Insert after the current block with the default type
const block = editor.blocks.insert();
// → BlockAPI { id: 'kP3xQ...', name: 'paragraph', ... }

// Insert paragraph with data at index 0
const block = editor.blocks.insert('paragraph', { text: 'Hello' }, undefined, 0);

// Insert with custom ID
const block = editor.blocks.insert('header', { text: 'Title' }, undefined, undefined, undefined, undefined, 'custom-id');

// From your own slash menu / toolbar: declare the user gesture so a container
// tool seeds its default children (see BlockOrigin on the tool contract)
const block = editor.blocks.insert('column_list', undefined, undefined, index, undefined, undefined, undefined, undefined, 'user');
```

### blocks.insertMany(blocks, index?)

BlockAPI[]

Вставить несколько блоков за раз. Когда индекс не передан, блоки добавляются в конец документа.

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

Массовая вставка за одну операцию (и один шаг отмены) — гораздо дешевле цикла из `insert()` для больших вставок или импорта.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `blocks` | `OutputBlockData[] | LooseOutputBlockData[]` | Обязательный | — | Блоки для вставки. Принимаются нестрогие блоки — `null` в `data` становится `{}`, `null`/пустой `id` заменяется сгенерированным. |
| `index` | `number` | — | `end of document` | Позиция для вставки. Когда не передана, по умолчанию блоки добавляются в конец документа. |

Ошибки

- Переданный `index` отрицательный. Index should be greater than or equal to 0 Передайте `index` не меньше 0 либо не передавайте его, чтобы добавить в конец.

TypeScript

```
const blocksToInsert = [
  { id: '1', type: 'paragraph', data: { text: 'First' } },
  { id: '2', type: 'paragraph', data: { text: 'Second' } }
];
const inserted = editor.blocks.insertMany(blocksToInsert, 0);
console.log('Inserted:', inserted.length, 'blocks');
```

### blocks.composeBlockData(toolName)

Promise<BlockToolData>

Создать пустые данные блока для указанного типа инструмента.

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

Создаёт данные инструмента по умолчанию, ничего не вставляя — удобно, когда нужен корректный пустой payload для `insert()` или `update()`.

Ошибки

- `toolName` не является зарегистрированным инструментом. Block Tool with type "<toolName>" not found Сначала зарегистрируйте инструмент в конфигурации `tools` редактора.

TypeScript

```
const emptyData = await editor.blocks.composeBlockData('paragraph');
// Returns: { text: '' } or appropriate empty state for the tool
```

### blocks.update(id, data?, tunes?)

Promise<BlockAPI>

Обновить данные и/или тюны блока. Когда инструмент блока реализует `setData(newData)` в своём прототипе — так делает каждый React/Vue/Angular-блок, а также встроенные инструменты заголовка, списка, кода, тоггла и таблицы, — обновление данных применяется НА МЕСТЕ: тот же экземпляр блока, тот же DOM-холдер, тот же смонтированный компонент продолжают жить, поэтому эфемерное состояние инструмента, принятые дочерние блоки и курсор сохраняются. Именно поэтому `update()` безопасно вызывать на каждое нажатие клавиши (переименование карточки, пока пользователь печатает). Инструменты без `setData`, инструмент, чей `setData` возвращает `false` (ему нужна другая форма DOM), и любой вызов, передающий `tunes`, откатываются к пересборке блока: новый экземпляр инструмента заменяет старый, а старый уничтожается.

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

Изменяет data/tunes на месте, сохраняя id и тип блока. Чтобы сменить тип, используйте `convert()`.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `id` | `string` | Обязательный | — | Id блока для обновления. |
| `data` | `Partial<BlockToolData>` | — | `undefined` | Частичные данные, объединяемые с существующими данными блока. |
| `tunes` | `Record<string, BlockTuneData>` | — | `undefined` | Данные тюнов, объединяемые с существующими тюнами блока. |

Ошибки

- Блок с указанным `id` не существует. Block with id "<id>" not found Проверьте id через `blocks.getById()` перед вызовом `update()`.

TypeScript

```
// Update block data
const block = await editor.blocks.update('block-123', { text: 'New text' });

// Update with tunes
const block = await editor.blocks.update('block-123', undefined, { alignment: 'center' });

// Guard against an id that no longer exists (e.g. the block was deleted
// concurrently) instead of letting the rejection surface unhandled
try {
  await editor.blocks.update(staleId, { text: 'New text' });
} catch {
  console.warn('Block was already removed, skipping update');
}
```

### blocks.convert(id, newType, dataOverrides?)

Promise<BlockAPI>

Преобразовать блок в другой тип. Оба инструмента должны поддерживать конфигурацию преобразования.

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

И исходный, и целевой инструменты должны объявлять `conversionConfig`, иначе вызов выбросит ошибку. По возможности сохраняет текст.

Параметры

| Параметр | Тип | Обязательный | По умолчанию | Описание |
| --- | --- | --- | --- | --- |
| `id` | `string` | Обязательный | — | Id блока для преобразования. Его инструмент должен объявлять `conversionConfig.export`. |
| `newType` | `string` | Обязательный | — | Имя зарегистрированного инструмента для преобразования. Его инструмент должен объявлять `conversionConfig.import`. |
| `dataOverrides` | `BlockToolData` | — | `undefined` | Поля данных для перезаписи в результирующем блоке после преобразования. |

Ошибки

- Блок с указанным `id` не существует. Block with id "<id>" not found Проверьте id через `blocks.getById()` перед вызовом `convert()`.
- `newType` не является зарегистрированным инструментом. Block Tool with type "<newType>" not found Зарегистрируйте целевой инструмент в конфигурации `tools` редактора.
- У исходного инструмента нет `conversionConfig.export`, у целевого нет `conversionConfig.import`, либо нет ни того, ни другого. Conversion from "<sourceType>" to "<newType>" is not possible. <ToolName(s)> tool(s) should provide a "conversionConfig" Добавьте `conversionConfig` тому инструменту, у которого его нет, либо конвертируйте через промежуточный инструмент, поддерживающий оба направления.

TypeScript

```
// Convert paragraph to header
const headerBlock = await editor.blocks.convert('block-123', 'header', { level: 2 });

// Convert with data overrides
const headerBlock = await editor.blocks.convert('block-123', 'header', { text: 'New Title', level: 1 });

// Not every pair of tools supports conversion — guard it rather than
// assuming the target type is always convertible
try {
  await editor.blocks.convert('block-123', 'table');
} catch (error) {
  console.warn('Conversion not supported between these tools:', error);
}
```

### blocks.splitBlock(currentBlockId, currentBlockData, newBlockType, newBlockData, insertIndex)

BlockAPI

Атомарно разделить блок, обновив текущий блок и вставив новый. Обе операции объединяются в один шаг отмены.

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

Используйте для разбиения с учётом курсора (например, Enter посреди текста); update и insert образуют один шаг отмены.

TypeScript

```
// Split a paragraph at cursor position
const newBlock = editor.blocks.splitBlock(
  'current-block-id',
  { text: 'First part' },
  'paragraph',
  { text: 'Second part' },
  1
);
```

### blocks.stopBlockMutationWatching(index)

void

Остановить наблюдение за мутациями блока по указанному индексу. Используйте это, чтобы предотвратить ложные события block-changed при операциях замены блока.

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

Нишевое: вызывайте перед программной заменой DOM блока, чтобы подавить ложные события `block-changed`; следующий рендер включит наблюдение снова.

TypeScript

```
// Replace a block without triggering change events
editor.blocks.stopBlockMutationWatching(0);
// Perform block replacement...
// Mutation observer will not fire for this block
```

### blocks.startBlockMutationWatching(blockId)

void

Снова включить наблюдение за мутациями блока, ранее заглушённого через `stopBlockMutationWatching`. Метод принимает **id**, а не индекс, потому что вставки и замены между двумя вызовами сдвигают индексы; несуществующий id молча пропускается — блок, заменённый на месте, был создан с собственным наблюдателем.

TypeScript

```
const blockId = editor.blocks.getBlockByIndex(0)?.id;
editor.blocks.stopBlockMutationWatching(0);
// Perform block replacement...
if (blockId) {
  editor.blocks.startBlockMutationWatching(blockId);
}
```

### blocks.transact(fn)

void

Объединить каждую операцию с блоками, выполненную внутри `fn`, в один шаг отмены. `fn` должна быть СИНХРОННОЙ — операции, попадающие туда после await, в группу уже не входят. Используйте это, чтобы структурные правки нельзя было отменить частично.

TypeScript

```
editor.blocks.transact(() => {
  editor.blocks.insert('paragraph', { text: 'One' });
  editor.blocks.insert('paragraph', { text: 'Two' });
});
// A single Cmd+Z removes both blocks
```

### blocks.beginTransaction()

void

Открыть группу отмены, которая остаётся открытой через асинхронные границы. Каждая операция с блоками до `endTransaction()` попадает в один шаг отмены. Используйте это для жестов указателя, непрерывно меняющих документ (перетаскивание угла таблицы для добавления строк), где `transact()` не помогает, потому что оборачивает только синхронную функцию. Каждый вызов должен быть сопряжён с `endTransaction()`.

TypeScript

```
editor.blocks.beginTransaction();
// ... continuous mutations across async boundaries ...
editor.blocks.endTransaction();
```

### blocks.endTransaction()

void

Закрыть группу отмены, открытую через `beginTransaction()`.

TypeScript

```
editor.blocks.beginTransaction();
// ... continuous mutations across async boundaries ...
editor.blocks.endTransaction();
```

### blocks.transactWithoutCapture(fn)

void

Выполнить операции с блоками, ничего не записывая в историю отмен. Используйте это для автопочинки и нормализации (например, чтобы в пустой ячейке всегда был блок), через которые Cmd+Z никогда не должен проходить.

TypeScript

```
editor.blocks.transactWithoutCapture(() => {
  editor.blocks.insert('paragraph', {}, undefined, 0);
});
// Nothing was added to the undo history
```

### blocks.setPointerDragActive(active)

void

Сообщить ядру, что перетаскивание указателем началось или закончилось. Пока оно активно, синхронизации Yjs, запускаемые мутациями DOM, подавляются, чтобы непрерывные изменения DOM в браузере во время перетаскивания не могли испортить состояние Yjs.

TypeScript

```
editor.blocks.setPointerDragActive(true);
// ... run the drag gesture ...
editor.blocks.setPointerDragActive(false);
```

## Свойства

| Свойство | Тип | Описание |
| --- | --- | --- |
| `isSyncingFromYjs` | `boolean` | Геттер только для чтения — true, пока идёт операция синхронизации Yjs (отмена/повтор). Инструменты читают его, чтобы пропустить очистку, которая конфликтовала бы с состоянием отмены. Обратите внимание: это СВОЙСТВО на `editor.blocks`, в отличие от метода `isSyncingFromYjs()` React-хука. |
| `isPointerDragActive` | `boolean` | Геттер только для чтения — true, пока активно перетаскивание указателем. Адаптеры фреймворков читают его, чтобы отложить программный `dispatchChange` посреди перетаскивания (ядро молча отбрасывает такое изменение) и отправить его повторно, когда перетаскивание закончится. |
