KQ-1309 · BLOCK/EDITOR

Block Editor

A document of text, heading, to-do and quote blocks, each a plain auto-growing textarea underneath, whose inline marks are plain text that renders formatted while the block rests. A block's grip drags it 1:1 with a lift on flick and a rubber band past the ends while its neighbours glide out of its way, and on release every block FLIPs on glide from where it was drawn to where the new order puts it, the dropped one carrying its release velocity; Alt+Up and Alt+Down make the same move with focus and caret kept. `/` opens a block menu at the caret on snap, a selection raises a formatting bubble over itself on snap, and Enter splits, Backspace joins and Up and Down cross between blocks at their first and last lines.

KQ-1309 · BLOCK/EDITOR

Field notes · North basin survey

Fieldline · shared with the survey team

9 blocks · 87 words

Alt+Up or Alt+Down moves the block. Type / for block types. Select text for formatting, or press Alt+F10 to reach it.

9 blocks · 87 words · 1 of 3 to-dos done

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/block-editor

Props

blocks / defaultBlocks
EditorBlock[]
default defaultEditorBlocks
The document: each block's id, type (paragraph, heading, subheading, todo, quote), text and, for a to-do, its tick. Controlled or uncontrolled.
onBlocksChange
(blocks: EditorBlock[]) => void
default —
Fires from the keystroke, drag, menu pick or tick that changed the document, with every block.
title
string
default "Field notes · North basin survey"
The document's name: the surface's heading and accessible name.
meta
string
default "Fieldline · shared with the survey team"
One quiet line under the title.
placeholder
string
default "Type “/” for blocks"
What an empty block says while you are in it.
handles
"hover" | "always" | "off"
default "hover"
The gutter's grip and + button: on hover and focus (faintly always on a phone), always, or none. Alt+Up and Alt+Down move blocks either way.
slash
"list" | "grid" | "off"
default "list"
The block menu that `/` and + open: rows with hints, a grid of tiles, or none (`/` is just a character; the markdown openings # , ## , [] and > still work).
bubble
"full" | "compact" | "off"
default "full"
The toolbar over a selection: bold, italic, code, strike and link; the first three; or none (the shortcuts still work).
status
"ready" | "loading" | "error"
default "ready"
Loading draws placeholder lines; error offers Retry.
onRetry
() => void
default —
The Retry button of the error state.
onFocusChange
(blockId: string | null) => void
default —
Fires with the block being written in, or null when focus leaves the document.
readOnly
boolean
default false
Reads without writing, moving or ticking; the gutter is hidden.
label
string
default —
The region's accessible name, when it should differ from the title.
sound
boolean
default false
Play a tick on menu moves, drag slot changes and Alt-moves, and a click on drops, picks, ticks and formats. Off unless asked for.
disabled
boolean
default false
Shows the document dimmed and takes no input.
className
string
default —
Classes for the root. The root is h-[560px] by default; pass a height to change it.