---
title: "Blok Changelog — Release Notes & Versions"
description: "Every Blok release with its features, fixes, and breaking changes. Currently on 1.13.0."
source: https://blokeditor.com/changelog/
lastmod: 2026-09-04
---

Version History

# Changelog

Track every improvement, fix, and feature as Blok evolves

1. [v1.13.0](https://github.com/JackUait/blok/releases/tag/v1.13.0) Minor Sep 3, 2026 Added **Live collaboration** — Real-time multiplayer editing, turned on with `collaboration: { doc }`. Editors on the same `doc` see each other's edits, carets and avatars, named by `collaboration.user`. `offline: true` survives a reload by writing document content to browser storage. Every tool must support read-only, because a collaboration editor boots read-only. Added **`persistence`, `server` and `ticket`** — The document wiring that used to be yours to write. `persistence: { load, save }` loads on mount and saves as the document changes, against your endpoint. Saves are queued, never parallel, and only the newest pending document is sent. `server` fills in the uploader and preview endpoints. `ticket` names the endpoint minting an access pass. Added **Documents convert outside the browser** — `Blok.Server` runs the editor's own serializer in-process. `AddBlokDocuments()` registers it, and `AddBlokServer` already includes it. `IBlokDocumentConverter` gives Markdown, HTML and plain text out, and Markdown in. Markdown cannot express every block, so both directions report what changed. Added **Translate a document without handing a model its JSON** — `extractTexts` and `injectTexts` move the prose past a model. The model never sees the structure, so it cannot drop ids or reorder blocks. URLs, file names and code blocks are left out of the list. A list whose length does not match the document throws rather than misplacing a translation. Added **Markdown out of a saved document** — `blocksToMarkdown` is the synchronous, DOM-free twin of `markdownToBlocks`. Headings become `#`, lists `-` or `1.`, and tables GFM pipe grids. `blocksToMarkdownWithReport` also names every construct dropped or emitted lossily. Markup written into Markdown comes back as literal text, since Blok has no raw-HTML block. Added **A heading keeps the anchor its links point at** — `HeaderData.anchor` renders as the heading's `id`. It is captured from a pasted heading's own `id`, so in-document links survive a paste and a save. `restoreHeadingAnchors` repairs documents already imported without it. That pass reports every fragment it refused as `no-match` or `ambiguous`, rather than guessing. Added **An uploader can delete what it stored** — `delete?(url, ctx)` is a third optional method on `BlokUploader`. Blok sweeps the assets this session uploaded and then stopped using. With the method absent nothing is ever deleted, which is what happened until now. `UploaderConfig.headers` may now be a function, so a short-lived pass is minted per request. Added **Change a live document from outside the browser** — `POST /sync/{doc}/edit` and `/reset` work over HTTP. An edit inserts, updates or removes blocks, all-or-nothing, and reaches every open tab. A reset reloads the document from your endpoint and tells every tab to pick it up. Both require a pass with `write: true` naming that document. Fixed **Pasted HTML ran before anything sanitized it** — A pasted `<img src=x onerror=…>` executed before `clean()` saw it. Clipboard HTML was parsed into an element owned by the live document, which still loads resources. Untrusted parses now use a document with no browsing context. The URL scheme check moved inside `clean()`, so a pasted `javascript:` link is no longer clickable. Fixed **A long article could not be converted at all** — An article that died on the server's engine now converts in milliseconds. Both serializers reallocated the whole accumulated document for every block. `blocksToHtml` also sent every inline field through a sanitizer that parsed twice. Measured on the real engine: 600 KB went from failing outright to 7 ms. Fixed **A legacy document's nested content read as empty** — Plain text, Markdown and HTML all dropped a legacy block's children. Documents written before nesting moved to `parent` and `content` keep their children inside `data`. Those shapes are now expanded once, in the document model, so every reader sees them. One unreadable block is skipped and reported, rather than costing the caller the whole article. Fixed **Markdown export lost the fence language and the nesting** — Code fences exported unlabelled, and Tab-nested paragraphs exported as code. Four leading spaces after a blank line is an indented code block, so that indent survives only inside a list item. A container rendered only its direct children, so a list inside a toggle lost every level below the first. Lossy conversions now report what changed, instead of reading as "nothing was lost". Fixed **The caret did not survive a read-only round trip** — Entering read-only remembers where the caret stood, and leaving it puts it back. It holds on both the in-place toggle and the save, clear and render path. The restore declines when the user focused something else, or when the block is gone. A collaboration status blip that changes nothing no longer kills a live caret. Fixed **A link to somewhere on the same page opened a new tab** — A bare `#fragment` reopened the whole document instead of moving inside it. So did the absolute URL that "Copy link to block" hands out. A fragment now scrolls, an identical URL does nothing, and a query-only difference navigates in place. Following a link is reading, so the handler no longer unbinds in read-only. Changed **The server runs its own Yjs engine** — Nothing it ships carries native code any more. YDotNet and the native build matrix are replaced by a managed C# implementation. Each wave was verified against a shared Yjs oracle rather than against itself. A service account with no home directory now needs no configuration. Changed **`blok-sync.v2` is on the wire, and deliberately not spoken yet** — The service negotiates it, and the client still offers only v1. The operation, acknowledgement and rejection codecs exist on both sides against pinned fixtures. An operation id is settled and journalled before anyone can see the write. Do not build on the v2 frames until the client negotiates them. Changed **The documentation site was one step from being indexed as its error state** — A crawl recorded the homepage's only `<h1>` as "Application Error". A component drew with `Math.random()` during render, so React 19 discarded the server HTML. Docs had also not deployed for three days, blocked by a script demanding impossible release assets. A post-deploy smoke test now asserts what the host actually serves. Changed **`yarn serve` starts the collaboration backend** — The dev playground boots the sync service beside it. Multiplayer is exercised locally by default. Pass `--no-server` to run the playground alone. Changed **Gates and dependencies** — The .NET solution keeps three test layers plus conformance and package smoke tests. CI requires 80% line and branch coverage on merged production code. It audits NuGet packages, scans for secrets, scans the built image, and analyzes C# with CodeQL. Mutation testing runs on the diff alone, carrying surviving mutants between commits.
2. [v1.12.0](https://github.com/JackUait/blok/releases/tag/v1.12.0) Minor Aug 26, 2026 Added **`@bloklabs/server` is one C# implementation now, in two forms** — The Go service that shipped in 1.11.0 is ASP.NET Core. `Blok.Server.AspNetCore` runs the same handlers inside an app you already have, with no second process. `npx @bloklabs/server` and `ghcr.io/jackuait/blok-server` still deliver the standalone host. Routes, flags and every response wire are unchanged, pinned by a 58-case conformance suite. Added **Answers pasted from ChatGPT and Gemini keep their structure** — A pasted formula used to arrive as roughly 870 layout spans. Math is replaced by the `<span data-latex>` the equation tool already whitelists. A code block collapses to one `<pre><code>`, and its language rides as `data-blok-code-language`. There is deliberately no Claude branch: its share pages sit behind a bot check. Fixed **Markdown copied out of an AI answer lost half its structure** — A code fence nested under a list item vanished without trace. Nested content is emitted as sibling blocks, and later items carry `start` so markers do not restart at 1. Fence languages are normalized through one module that knows the aliases models emit. Bold, inline code and strikethrough inside a list item now survive a save. Changed **The Go implementation is gone, and the tag ships the C# one** — It was removed only after the dual-target conformance gate passed unwaived. The tag workflow packs both NuGet packages and proves them from an isolated feed. It smoke-tests the archive and the container image before publishing anything. The NuGet credential is minted over OIDC immediately before the push. Changed **Two gates that only CI could see** — The `dotnet format` check was red on `main` from the day it landed. The repository carried no `.editorconfig`, so the tool fell back to four-space indentation. That produced 12689 whitespace complaints, and every step after it never ran. The .NET tree now carries its own config, so a laptop and a runner agree.
3. [v1.11.0](https://github.com/JackUait/blok/releases/tag/v1.11.0) Minor Aug 23, 2026 Added **`@bloklabs/presets`** — Ready-made uploaders, so `config.uploader` is no longer something every project writes. `supabaseStorage`, `presignedStorage`, `cloudinaryStorage`, `fetchStorage` and `indexedDBStorage`. Zero runtime dependencies: a vendor client is passed in, never imported, so your own auth session applies. `BlokUploader`, `UploadContext` and `UploadedAsset` are now exported from `@bloklabs/core`. Added **`@bloklabs/server`** — A sidecar handling file uploads and link previews, so you write no backend for either. `POST /upload`, `POST /upload-by-url` and `GET /unfurl`, run through npx or the container image. Uploaded bytes land in a local directory or any S3-compatible bucket. Access modes `none`, `proxy` and `ticket` are enforced by startup interlocks rather than warnings. Added **Cross-block text selection** — Dragging across blocks selects the characters under the pointer, not whole blocks. Copy, cut, typing, Enter, paste and the mark engine all split the range per editing host. It works in Firefox, which Notion's own implementation does not. Escape promotes the text selection to a selection of the same blocks. Added **Block controls on either side** — `config.toolbarPosition: 'left' | 'right'` moves the plus button and drag handle. It is live through `toolbar.setPosition()`, and the reserved gutter width moves with it. Logical tokens throughout, so RTL mirrors for free. Before this, the only lever was hiding the controls entirely with `hideToolbar`. Added **Dev override seam** — Every `@bloklabs/core` entry consults `globalThis.__BLOK_DEV_OVERRIDE__` before its bundled implementation. It is a passive, in-realm read: nothing is fetched, evaluated or resolved from a URL. The editor root carries `data-blok-version`, so what is running is inspectable. To drop the branch from your bundle, alias the newly exported `./dist/*` subpath. Fixed **`onChange` fired late, or not at all** — Sustained typing produced zero calls until the user paused. Every mutation restarted the 400 ms window, which now opens on the first change and never extends. `onChange` leads the window on the next microtask, and the rest coalesces into one trailing call. `onSave` keeps the trailing edge only, since serializing the document is too expensive to front-run. Fixed **Selection beside a nested block** — A lasso drawn beside a nested table selected the whole toggle section. Selection now resolves which block owns a row through the same rule the toolbar uses. A fast drag no longer drops every row above the first throttled mousemove. One keystroke inside a nested block no longer runs the pipeline once per ancestor. Fixed **Empty-block placeholders displaced the caret** — An empty paragraph painted its caret 315 px to the right. A placeholder in normal flow consumes real inline advance at the start of the line box. Placeholders now paint their text while claiming zero advance. Media captions stay in normal flow, since a zero-width box would spill a centred caption sideways. Fixed **A bookmark that could not be previewed** — It showed an error after the paste, and an ordinary card after a reload. The error state never reached saved data. A failed preview now degrades to a plain link on both paths. Roughly 30% of sites publish no preview data, so this is the ordinary case rather than a fault. Fixed **Audio player card** — Descenders in the title and artist lines were sliced flat. `text-overflow: ellipsis` forces `overflow: hidden`, which clips at the padding box. At a line height of exactly 1, that box is shorter than the font's content area. Both lines now use the line-height token the file-name row already carries. Changed **Release and CI wiring** — Nothing here iterates workspaces, so a package missing from a list drops out silently. Both new packages are registered across all seven lists, from version lockstep to the publish gate. The server's binaries and image ship from a tag-triggered workflow, not from a maintainer's laptop. A compiler-API law fingerprints every type `@bloklabs/presets` hand-copies into its declaration. Changed **Docs** — New `/presets` and `/server` pages, linked from the navigation and localized in both languages. `/server` leads with the path that runs no service at all, and states its limits on the page. A new page documents the dev override seam, its threat model and its opt-out. `SECURITY.md` commits to acknowledging a report within five business days.
4. [v1.10.1](https://github.com/JackUait/blok/releases/tag/v1.10.1) Patch Aug 20, 2026 Added **Toggle heading adoption** — "Turn into → Toggle heading" now adopts the heading's section, matching Notion. Every sibling up to the next heading of equal or higher rank becomes a child of the new toggle. A heading inside a column adopts only within that column. The adoption runs inside a move transaction, so undo restores the section. Added **Toggle disclosure arrows** — The arrows now read as clickable. The hover pill used to appear only once the pointer was already inside the 28 px square. The chevron scales with its title's font size, so heading arrows grow with their level. A localized Expand or Collapse tooltip is read from the state-synced `aria-label`. Fixed **Nested block menus** — A block inside a toggle could never show its own menu. A nested table's menu also jumped away the moment the pointer crossed onto the cell padding. Hover and touch now share one resolver where the deepest block under the pointer owns the toolbar. Hover detection stands down entirely over the toolbar. Fixed **Accessible names for icon-only controls** — The entire inline toolbar was nameless to a screen reader. A hint wired via `aria-describedby` describes a control but never names it. An icon-only popover item now takes its name from its hint title, which repairs every one of them. Colour swatches, captions and the embed iframe are named too, with no new i18n keys. Fixed **List and popover semantics** — Every list item in the editor was an orphan. Items declared `role="listitem"` but nothing declared the list, so the wrapper now carries `role="list"`. Toolbox section headers were separators inside a listbox, and are now presentational. A popover is stamped as a menu only when it actually has menu items. Fixed **Table and database semantics** — Add-row, add-column and the row and column grips were pointer-only. They are now named, focusable buttons with keyboard activation. Heading cells expose `columnheader` and `rowheader`, matching the `<th>` the view renderer emits. The header toggle is a real `role="switch"`, and database view tabs are a real tablist. Fixed **Escape no longer strands focus** — Escape pressed inside the toolbar left focus on `<body>`. The document handler stopped propagation in the capture phase, so the caret could never be restored. It now stands down for targets inside the toolbar. Modal dialogs return focus to the element that opened them, which fixes focus loss on WebKit. Fixed **Contrast** — The grey text token cleared AA by 0.05 on white, so it failed on every tinted surface. It is darkened, along with links and embed text, and inline code becomes its own token. The Prism dark palette was dead: every rule was gated on a class nothing in Blok sets. Database column pills move onto a dedicated on-pill colour. Changed **Accessibility suite** — Two copy-pasted axe scans became a layered suite on Chromium, Firefox and WebKit. It scans all 20 block tools in edit and read-only, plus the editor chrome. No rule is waived, and every scan is preceded by a visibility assertion. Two defects stay pinned with reasons, including the inline toolbar stranding focus.
5. [v1.10.0](https://github.com/JackUait/blok/releases/tag/v1.10.0) Minor Aug 7, 2026 Added **Framework adapters** — `useBlocks` takes `{ within: blockId }`, so a container re-renders only for its own subtree. Unscoped, a page of N containers turned one keystroke into N re-renders. `childContentAttributes` applies per-child decoration on each child's content wrapper. `toolbarAnchorRef` and `ctx.setToolbarAnchor` answer `getToolbarAnchorElement` from inside the component tree. Added **View** — `renderLatex` and `createLatexRenderer` are exported from `@bloklabs/core/view`. The KaTeX chunk was already bundled, but hosts were told to add `katex` themselves. Both apply the options Blok trusts for untrusted input, including `trust: false`. `createLatexRenderer()` awaits the load once and hands back a synchronous renderer. Fixed **`insertChild({ caret })`** — The caret was permanently lost for a portal-rendered child. A React, Vue or Angular child returns an empty host and commits its editable a frame later. The block was not yet focusable, so the caret helper cleared the selection instead. Placement now re-applies once the child's holder produces an input, one-shot. Changed **Adapter parity** — The per-child decoration pass was triplicated across the adapters and is now one implementation. Three architecture laws pin the new surface. The view entry gained an export-to-declaration drift check.
6. [v1.9.0](https://github.com/JackUait/blok/releases/tag/v1.9.0) Minor Aug 6, 2026 Added **Container tools** — Five things a container block used to hand-roll are now declared. `static childTools = { allow?, deny? }` lets any container state which tools may be its direct children, enforced by core on insert (a disallowed tool is demoted to `allow[0]`, so Enter always produces a block), on a cross-boundary move (refused) and in the toolbox (hidden) — the selective, insert-aware counterpart to `ownsChildren`, and the generic form of the Table-only `restrictedTools`. `data-blok-keyboard-owner` marks a subtree whose keyboard belongs to the tool: block-level and editor-level keydown/input handling stand down inside it, tag-agnostically, replacing per-key `stopPropagation` handlers. `BlockAPI.insertChild` gained an `options` argument with the same vocabulary as the adapters' `useBlocks` insert (focus, caret, id, tunes, replace), threaded through `insertInsideParent`. Added **Inline tools** — `InlineToolConstructable.hydrate(root)` is a declared contract, called by `Block` after render, after an in-place `setData` and after `onPaste`. Whatever a hook writes is marked `data-blok-mutation-free`, so re-rendering derived markup is not an edit. Added **View** — `blocksToHtml` and `<BlokView>` accept `inlineRenderers`: tag-keyed, post-sanitize, output inserted verbatim — the inline counterpart of `renderers`. A DOM-free render can plug in `katex.renderToString` or a mention chip without Blok shipping either. Added **Block tree** — `{ blocks: [...] }` is now a spec node (`BlockRunSpec`), valid at the root or as a child of a tree node. A migration holding an already-flat saved document can splice it verbatim: ids are kept, only un-parented blocks are re-parented onto the enclosing node, and only those join its `content`. Passing a pre-flat block as a tree node throws instead of silently dropping its parent/content links. Fixed **Inline equations** — A KaTeX span's markup is derived from `data-latex`, and the sanitizer dropped its tags while keeping their text, so `E=mc^2` was persisted as `E=mc2E=mc^2E=mc2`. What was supposed to hide that — re-rendering on load — never ran: `EquationInlineTool.hydrate()` had zero call sites repo-wide, so equations went inert on every reload, in the editor and not just in the view. The sanitizer rule now rewrites an equation span's content back to its source on both the DOM and the parse5 pipeline, so new saves are clean and a load heals documents that already carry residue. `htmlTextContent` reads a mark's source, so previews, outline and search stop reading rendered fragments. Fixed **`onChange` arming** — The documented "handler presence arms the change pipeline" contract was false: core defaulted `onChange` to a no-op unconditionally, so the gate could never disarm and all three adapters' careful handler-presence omission was pointless. Hosts were passing dummy handlers to arm a pipeline that was already armed — and an `onSave` one also forces a full serialization per change batch. The injection is gone, so the contract holds as written. Fixed **Published types** — `types/data-attributes.d.ts` was hand-transcribed and had drifted: 17 attributes missing (including `nestedBlocks`, the container slot every nesting tool's stylesheet targets) and one phantom key the runtime never had. It is now generated from source and any drift fails an architecture test. The React `BlokViewProps` was also missing `classes`. Changed **Dependencies** — postcss, brace-expansion, fast-uri, ip-address and undici bumped across the root and docs workspaces.
7. [v1.8.0](https://github.com/JackUait/blok/releases/tag/v1.8.0) Minor Aug 6, 2026 Added **Superscript / subscript** — A new inline tool takes the tenth slot in the inline toolbar, bound to ⌘/Ctrl+Period and ⌘/Ctrl+Comma. The two modes are mutually exclusive, so applying one clears the other. Shipped with glyphs drawn into the shared inline-toolbar type system, translations in all 69 locales, and docs. Added **Toolbox** — Slash-menu entries are grouped under labeled sections, so a long tool list is scannable instead of a flat run of items. Each entry declares its own section. Added **Tool contract** — Blocks carry creation provenance (`user`/`load`/`api`/`paste`/`convert`/`replay`/`probe`), so a container can tell an author's gesture apart from a document load, a refetch or an undo replay. Enter's container-escape became a per-tool declaration instead of a hardcoded list of Blok's own tool names, so a custom container keeps Enter inside itself without an editor-global `onEnter` hook. `insertInsideParent` and `BlockAPI.insertChild` take an optional tool name, making an appended typed child one atomic operation and one undo entry. Added **Framework adapters** — The React, Vue and Angular block spec gained a general statics passthrough (toolbar anchor, `ownsChildren`, `conversionConfig`, the new Enter policy), an api handle, child-tree reactivity, per-child decoration, and an `onMounted` signal backed by a `block:childrenMounted` event. Handler presence is runtime-settable through `api.handlers.set()`, so passing `onEnter` at all no longer permanently decides Enter's semantics. Added **Editor** — A new opt-in `captureClicksBelowEditor` places the caret in the last block when the host clicks empty space below the editor. Off by default; registered as a config key in the React and Vue adapters too. Added **Link** — The link field sizes itself to its content, capped at the previous fixed width, and its create, error and edit states were polished. Fixed **Nesting** — `setBlockParent` no longer lets a container on the block's own ancestor or descendant chain veto a reparent; an enclosing container claiming a holder used to leave model and DOM permanently divergent (Enter inside a callout nested in another container), and a descendant doing the same nested every appended child inside its predecessor. `mountChildBlocks` now reclaims a holder stranded in any ancestor container, re-mounts it at its model position rather than last, and preserves the caret across the adoption. Depth indentation moved from an inline margin with a hardcoded exemption list to a depth multiplier resolved through `--blok-block-indent-step`, so a container tool declines the indent with ordinary CSS and no `!important`. Fixed **Block API** — Every handed-out `BlockAPI` is live, so `getChildren()` can no longer answer `[]` for a populated container and `setParent`/`insertChild`/`moveChild` can no longer silently no-op. `api.blocks.update()` prefers a tool's in-place `setData` when there are no tunes to apply, so it stops composing a replacement block that destroyed the previous one's portal and left the holder permanently empty. Fixed **Inline toolbar** — `destroy()` threw and aborted `blok.destroy()`, leaking listeners in every module torn down after it: `hide()` emits `Closed` synchronously, the handler then ran `close()`, which nulled the popover mid-teardown. The reference is now detached before hiding. Fixed **Popover** — Control-less HTML items (the new toolbox section headers) are no longer keyboard focus stops, so a `role="presentation"` header can't steal initial focus, shift every Arrow/Tab, or be pointed at by `aria-activedescendant`. Sibling active states refresh after an item is activated, and clicking the item that opened a popover now does nothing instead of reopening it. Fixed **List** — Tab/Shift+Tab moved the model but not the render: both handlers wrote depth into the tool's live data before calling `api.blocks.update`, whose in-place diff then saw no change, so `save()` and the DOM silently disagreed. Fixed **Events and data** — Keydown from a native form control a tool renders is no longer claimed by the editor. The toolbox merge and the `save()` extraction stop mutating tool-owned objects, so a toolbox entry carrying data no longer throws on a frozen `save()` result. A load is not an edit: a block arriving without a timestamp is no longer stamped at construction, so a save round-trip equals the document it came from. Fixed **Adapters** — The portal registries reject a teardown from a superseded instance, so a same-id re-register survives a late destroy; Vue additionally defined one wrapper component per tool *type*, so a re-register patched the superseded instance and rendered stale data — the wrapper is now per block instance. A React element toolbox icon serializes instead of rendering as `[object Object]`, and the imperative handle keeps the controlled baseline in sync so restoring a draft after `clear()` is no longer swallowed as an echo. Fixed **Styles** — The icon stroke is scoped to Blok's own icon markup instead of every path in the subtree. The column floor moved to `--blok-column-min-width` in CSS, and the static-gutter attribute plus the block-padding tokens are now declared. Changed **Build** — `scripts/build-angular.mjs` derived its adapters contract from a hand-copied list that silently drifted whenever a staged module gained an import; it now derives it from `src/adapters.ts`, and the staging law test walks the same graph so drift fails at test time instead of build time. Changed **Tests** — 23 red e2e tests were root-caused rather than weakened: three were real product bugs (fixed above) and four were stale specs asserting behaviour that later commits deliberately changed. A leaked 600ms language-detection debounce in the code-tool unit tests was also cancelled, removing a load-dependent flake.
8. [v1.7.0](https://github.com/JackUait/blok/releases/tag/v1.7.0) Minor Aug 4, 2026 Added **Embed** — A stored generic embed the host hasn't allowed to be framed now renders as a clickable link card instead of the inert "No embed link" state, so the URL stays visible in both read and edit views and can never be silently lost. A new `linkPaste.allowedEmbedOrigins` hostname/wildcard trust list gives hosts fine-grained control as a middle ground before the all-or-nothing `allowGenericEmbed` flag. Tampered stored data stays fully inert, and no new iframe paths are introduced. Fixed **Editor** — Queries for a block's first editable element now skip mutation-free markers such as a list item's bullet span, closing the remaining "marker ghost" sites where Enter could write an item's own HTML into the bullet and the toolbar centred on the marker's box instead of the text. An architecture test now enforces the guard on every `contenteditable` selector in the codebase.
9. [v1.6.2](https://github.com/JackUait/blok/releases/tag/v1.6.2) Patch Aug 2, 2026 Fixed **Callout** — Enter can leave the panel again. Previously it could only ever add another line inside, so every press stamped one more empty paragraph into the callout; those blanks are saved with the document, and the callout reloaded with its text pinned to the top of a panel padded out by invisible lines. Behaviour now matches Notion: Enter adds a line inside, Enter on an empty last line steps out. A callout nested in a column hands that block to the column rather than the document root, the exit block is saved in the position it renders in, and the whole exit is a single undo/redo step. Toggles and columns keep their existing behaviour.
10. [v1.6.1](https://github.com/JackUait/blok/releases/tag/v1.6.1) Patch Aug 2, 2026 Fixed **Callout** — The panel's vertical inset now reads its own `--blok-callout-padding-block` token (flat 5px default) instead of riding `--blok-block-padding-top/-bottom`, so a host's compact-rhythm override no longer collapses the callout card onto its text. The emoji button deliberately keeps reading the rhythm tokens so the glyph tracks the first text line under any rhythm a host sets. Defaults render byte-identically; hosts that wanted squashed callouts opt back in via `--blok-callout-padding-block: 0`. Changed **Docs** — 151 verified inaccuracies root-caused and fixed across the docs site, a new guide explains how to set per-block font sizes correctly, and the docs test suite now resolves Blok's public members through the TypeScript compiler instead of a regex.
11. [v1.6.0](https://github.com/JackUait/blok/releases/tag/v1.6.0) Minor Aug 1, 2026 Added **Font size** — `config.style.fontSize` now carries one entry per text scenario in every text-bearing block (paragraph, headings, quote, callout, code, toggle, list, checklist, table cells, captions, bookmark cards). Each entry writes that block's `--blok-*-font-size` custom property, so the same knob is reachable through `style.tokens`, `editor.tokens.set()` and plain CSS. An unconfigured editor renders byte-identically to before. Added **API** — `beginTransaction`/`endTransaction` group operations spanning a pointer gesture into a single undo entry, for cases where the synchronous `transact(fn)` cannot reach across async boundaries. Added **Table corner drag** — The bottom-right corner now behaves the way Notion documents it: the grid tracks the pointer through live geometry instead of a unit frozen at pointerdown, a Notion-style grip replaces the old 8px dot, hovering it explains the gesture, appended columns are full width, and the whole gesture commits as one undo entry. Added **Table auto-scroll** — Holding the corner at the scroll container's edge or in the viewport's top/bottom band scrolls and grows the table as it goes. Growth follows the pointer — 8px/s for every pixel held past the edge — rather than a fixed clock. Added **Table selection** — Dragging a row or column grip paints the entire dragged range instead of boxing only the focused cell. Added **Playground** — A text-size slider (80%–150%) scales every `style.fontSize` scenario from its own CSS default. Fixed **Table** — An inward corner drag stops at the first trailing row or column that holds content instead of deleting typed cells; the handle is anchored to the grid rather than the wrapper, so it no longer drifts inside the table as it grows; a caret click no longer leaves the corner handle and "+" buttons dead until the user clicks outside; clicking inside a merged cell boxes only that cell, and expanding a selection reaches merge origins, not just spans; a stale `pointercancel` listener no longer accumulates per completed drag. Fixed **Styles** — Callout emoji and list markers stay aligned with their text as the font size scales, and the bookmark card's padding, line boxes, gaps and favicon scale with the card's own type. `fontSize.callout` now wins over `fontSize.paragraph` in the callout body. Fixed **Types** — The public `Blok` class exposes its full API surface.
12. [v1.5.0](https://github.com/JackUait/blok/releases/tag/v1.5.0) Minor Jul 27, 2026 Added **View renderer** — `@bloklabs/core/view` now reaches visual parity with the read-only editor: every core block (paragraph, header, quote, list, checklist, code, callout, toggle, divider, spacer) renders from single-sourced class modules shared with the editor, `view.css` is generated from those modules, and a soft isolation root plus reproduced block scaffolding keep the output pixel-equal. A class-parity gate and a view↔read-only visual parity gate now run in CI, and the playground gains a side-by-side Blok View comparison panel. Added **Paste** — Google Docs layout tables are now recognized: multi-row two-column tables carrying photos convert into column blocks, and single-column layout tables unwrap into their content instead of arriving as one-cell tables. Added **Inline toolbar** — The convert menu now opens sideways with its trigger marked selected, and the convert row is styled as the card's header. Added **Callout** — A newly picked emoji jumps into the old one's place, and the emoji picker opens instantly without waiting on its dataset to download. Added **Tools** — `data-blok-tool` is now stamped on code, callout, divider and spacer roots. Added **Docs** — The docs site advertises its markdown mirrors and declares Content-Signal; the published `@bloklabs/core/icons` subpath is documented; the README is restructured around benefits, facts and a runnable example. Fixed **Security** — Stored `javascript:` XSS closed on two sinks: media download hrefs are scheme-gated, and stored embed renders are gated on the provider registry rather than a bare `https:` check. Fixed **Drag & Drop** — Drops on the seam between two blocks now resolve instead of dead-ending; the drop indicator no longer promises a nesting the drop would refuse; side-drops are gated on the columns tool actually being registered. Fixed **Columns** — The drop animation no longer balloons the row while a block lands. Fixed **Code** — In read-only mode the language label renders as plain text and the language dropdown toggle is hidden; the copy button keeps the same height in its "Copied!" state. Fixed **Toolbar** — Multiple editors on one page now show one set of block controls instead of stacking duplicates; the slash-search caret is sized to the input, not the block. Fixed **Tooltip** — A bubble is never parked in the viewport corner when its anchor stops rendering. Fixed **List** — The checklist checkbox is centred on its text at any font size. Fixed **Embed** — Provider popups (e.g. "open in app") can escape the iframe sandbox again. Fixed **Audio** — Cover art uploads are routed to the image pipeline instead of the audio endpoint. Fixed **Shortcuts** — `BACKSLASH`/`SLASH` render as `\` and `/` in shortcut hints. Fixed **Dependencies** — All 40 open Dependabot alerts remediated at their root causes.
13. [v1.4.5](https://github.com/JackUait/blok/releases/tag/v1.4.5) Patch Jul 25, 2026 Added **Migrate** — The legacy-format interpreter is now extensible from the host: `rules` entries are matched before the built-in grammar (so they can override it) while reusing container recursion, orphan re-parenting and 1:N splits; expanders may consume following siblings via `{ blocks, consumed }`; and passing `generateId` makes migration pure, so a document migrates to an equal result twice. Adds `migrate(data, options)` composing the data-rule and grammar passes in the correct order, `matchLegacyRule()` for per-block matching, and a `report` carrying `lossyFields`/`errors` instead of console-only warnings. Editor.js list v2 `meta` fields (`start`, `checked`) are now read. Fixed **Migrate** — `config.migrations` now runs before format analysis, so `dataModel: 'auto'` inspects post-migration blocks instead of collapsing the document back to its legacy shape on save. Fixed **Types** — `typesVersions` now maps the `migrate` subpath, fixing TS2307 for consumers on `moduleResolution: "node"`.
14. [v1.4.4](https://github.com/JackUait/blok/releases/tag/v1.4.4) Patch Jul 25, 2026 Added **Migrate** — Hosts can now declare per-block-type migration rules from the outside to upgrade stored blocks from an old data shape to a new one without editing the tool class. Rules are applied at load (after each tool's own `upgradeData`) and also exposed as a standalone `migrateOutputData` via `@bloklabs/core/migrate` for offline batch upgrades. Available on all three framework adapters.
15. [v1.4.3](https://github.com/JackUait/blok/releases/tag/v1.4.3) Patch Jul 24, 2026 Added **API** — The output-data helpers are promoted to a stable entry point, alongside new document-query utilities. Added **Types** — Named config aliases and a `BlokData` interface adapter. Added **Tools** — Type-safe tool authoring helpers, plus an explicit paste priority. Added **View** — Root-caused view gaps #29–#33 and #35 from the hr-platform/KB audit. Added **i18n** — Root-caused i18n audit gaps #36–#41. Added **Migrate / Tools / Paste** — Root-caused hr-platform/KB gaps #50–#53. Fixed **Controlled editor** — Five audit findings root-caused, followed by findings #7 and #9 (and the missing test for #8). Fixed **Marks / Paste** — Four inline-tool and sanitizer audit findings root-caused. Fixed **Build (Angular)** — `toRenderableData` is exported from the staged adapters-contract. Fixed **Types** — Widened the `exports` cast so the string-valued `./view.css` entry type-checks. Changed i18n message files are named by locale. Changed Repaired the test/build drift that blocked the release preflight.
16. [v1.4.2](https://github.com/JackUait/blok/releases/tag/v1.4.2) Patch Jul 23, 2026 Fixed **Markdown** — Typing a list marker (`-`, `1.`) inside a heading no longer converts the heading into a list; it stays a heading.
17. [v1.4.1](https://github.com/JackUait/blok/releases/tag/v1.4.1) Patch Jul 23, 2026 Fixed **Editor** — Enter now honours the IME composition and Shift contract; added an `onError` channel; `data-blok-tool` is opt-in. Fixed **Sanitize** — Redundant inline markup is now collapsed on every path that stores HTML. Fixed **Video** — Unplayable sources are surfaced to the user instead of rendering a black player. Fixed **View** — Added a `classList` facade so `MarkSpec` inline tools render correctly in `BlokView`. Fixed **i18n** — Localized video stats and database overflow, added `tr()` interpolation, and completed locale audits across Yiddish, Vietnamese, Traditional and Simplified Chinese, Urdu, Ukrainian, Uyghur, Turkish, Thai, Telugu, Tamil, Swahili, Serbian, Albanian and Slovenian.
18. [v1.4.0](https://github.com/JackUait/blok/releases/tag/v1.4.0) Minor Jul 23, 2026 Added **Marks** — New range-aware `api.marks` inline-formatting engine, with the built-in bold/italic/underline/strikethrough tools migrated onto it. Exposes `MarkSpec` identity/family/transparent semantics for authoring custom inline tools. Added **View renderer** — New synchronous, DOM-free view renderer published at `@bloklabs/core/view` (`defineBlokSchema` + a central dispatcher, plus a React `BlokView`), for rendering stored block content without booting a full editor. Added **i18n** — New runtime `editor.i18n.update()` API that makes `config.i18n` live and repaints already-rendered block DOM, wired reactively through all three adapters. Added **Config** — Reactive contract for `readOnly`, `hideToolbar` and `inlineToolbar`: setting them after construction now takes effect live across the React, Vue and Angular adapters (with sanitize-cache invalidation on `inlineToolbar`). Added **Readiness** — Scoped, reactive editor readiness: `whenAllReady({ within, settleOn })`, `readyState`/`subscribeReady`, and a `useBlokReady` hook in all three adapters. Added **Docs** — The documentation site is now crawlable (prerendered metadata, sitemap, AI mirrors) and carries Google Analytics coverage across pages. Added **Playground** — Dev settings panel gains a language picker and an RTL toggle. Fixed **Marks** — Fixed the trailing-whitespace extension eating later content when a mark ended on a boundary. Fixed **Styles** — Surface background tokens (`--blok-bg-light/-secondary/-tertiary`) are now a test-enforced public contract; the gutter stays put in plain read-only so `readOnly` flips no longer shift layout. Fixed **Types** — `MarkSpec` is now imported into the main declaration entry so it resolves for consumers. Fixed **Docs** — Russian pages are headed by their localized H1; `@bloklabs/core/view` resolves in the docs build and React fixtures. Fixed **Release** — The Angular README is now staged into the directory npm packs. Fixed **i18n** — Locale audits completed across Slovak, Sinhala, Sindhi, Russian, Romanian, Portuguese, Pashto, Polish, Punjabi, Norwegian, Dutch, Nepali, Burmese, Malay, Marathi, Mongolian, Malayalam, Macedonian, Latvian, Lithuanian, Lao, Sorani, Korean and Kannada. Changed Migrated the docs site to React Router framework mode. Changed Renamed the default branch from `master` to `main`. Changed Completed npm metadata across the package family and hardened the view/reactive-contract law tests.
19. [v1.3.0](https://github.com/JackUait/blok/releases/tag/v1.3.0) Minor Jul 21, 2026 Added **API** — New public `editor.tokens` getter/setter for runtime `--blok-*` theme tokens, with replace semantics and pre-ready buffering (like `theme`/`width`/`placeholder`). Wired reactively through all three adapters: React `style.tokens`, Vue `style.tokens`, Angular `[styleTokens]`. `--blok-content-max-width` is now honored by database centring and toolbar control placement. Added **Tools** — Custom-tool authoring fixes: `tools.update(name, { toolbox })` now flips a tool's toolbox entry at runtime (permission-style insert gating no longer requires recreating the editor), including its insertion shortcut; React `createReactBlock` accepts a `viewComponent` rendered while the editor is read-only; React toolbox icons may be React elements; `commit()` echo idempotency is now a documented public contract. Added **Embed** — Google Docs/Sheets/Slides/Forms/Drive embeds render at a user-adjustable pixel height with a bottom resize handle (200–2000px), persisted to `data.height`. Aspect-ratio media providers (YouTube, Vimeo, …) are unchanged. Fixed **CDN bundles** — `dist/blok.iife.js` and `dist/blok.umd.js` shipped **zero** generated Tailwind utilities since the v3→v4 migration, so every unpkg/jsDelivr consumer loaded an unstyled editor. Both configs now run the Tailwind plugin (+34KB gzip each), guarded by a dist-level assertion. Fixed **Adapters** — Five root causes from a downstream audit: a stale controlled-`data` echo no longer clobbers the caret (bounded echo window instead of last-payload-only dedup); `equalsOutputData` compares block ids only when both sides carry one; React inline tools accept a `titleKey` for localization; the zero-specificity gutter default is a test-enforced public contract. Fixed **Dependencies** — Seven phantom dependencies (bare imports resolving only via hoisting, including `@testing-library/jest-dom` used by the global unit setup) are now declared, with a law test preventing new ones. Fixed **i18n** — Review passes completing Armenian, Croatian, Dhivehi, Filipino, Georgian, Gujarati, Hebrew, Hungarian, Indonesian, Japanese, Kannada and Khmer, plus tool interpolation variable forwarding. Changed Upgraded to Node 26, Angular 22 and TypeScript 6, then root-caused six defects the upgrade shipped green — most importantly the entire `unit-angular` vitest project loading zero tests (a fake green), and the docs test suite missing the Node 26 webstorage guard. Changed Local E2E suite runtime cut from ~47.5 min to ~10 min (parallel/skip-when-fresh `build:test`, shared page per worker), plus broad E2E stabilization. Changed Fixed ESLint cache poisoning that replayed stale errors in CI lint runs.
20. [v1.2.6](https://github.com/JackUait/blok/releases/tag/v1.2.6) Patch Jul 20, 2026 Added **Paste** — Google Docs tables used as fake column layouts (every row has exactly 2 or 3 cells) now paste as real column layouts instead of table blocks. Genuine tables (4+ columns, ragged rows, single column, Google Sheets, nested tables) still paste as tables. Added **API** — Four first-class capabilities replacing host workarounds: a `style.nativeSelection` config opt-out for the forced `::selection` repaint, public `--blok-block-padding-top/-bottom/-inline` tokens for compact read-only rendering, a static `Blok.whenAllReady()` collective-readiness aggregate, and `createReactInlineTool` in the React adapter with a full inline-tool `destroy()` lifecycle. Fixed **Data integrity** — Three silent data-loss defects fixed: code containing `<` was corrupted on render and save (`if (a<b)` became `if (a`), empty code blocks were dropped on save, and a document whose only block was `/` saved as empty. Tools can now declare a field as literal text via a `PLAINTEXT` sanitizer rule. Fixed **Caret** — Highlighting a non-focusable block now blurs stale input focus, so Chromium can no longer restore the current block from a stale collapsed range. Fixed **i18n** — Locale audit corrections across dozens of locales, including Dutch color labels and shared toggle guidance.
21. [v1.2.5](https://github.com/JackUait/blok/releases/tag/v1.2.5) Patch Jul 20, 2026 Added **i18n** — New Taiwan Traditional Chinese locale (`zh-TW`) with its own emoji dictionary, bringing the corpus to 69 locale variants. A full audit pass over every shipped locale corrected terminology and localized previously hardcoded runtime strings (media captions, database defaults, emoji category scopes, recent color labels, action search, move announcements), with hardened locale validation. Added **Theming** — New `style.tokens` config lets each editor instance pass `--blok-*` token overrides that also reach body-mounted UI (popovers, menus). The edit-mode gutter now defaults to 56px and is owned by Blok, checklists get a dedicated padding token (falling back to the list token), `hideToolbar` config now actually hides the toolbar and collapses the gutter, and `--blok-placeholder-color` is a public hook. Added **Inline toolbar** — Restructured as a card with a convert row plus a five-column tool grid, including a new clear-format tool and redrawn toggle-heading icons. Added **Color** — Text and background tunes merged into a single Color submenu; the color picker gained a Recently Used section remembering the last 5 colors; slash-menu color command titles are localized. Added **Table** — Compact/comfortable text-size switch, grouped with density under a text-size submenu. Added **Header** — Heading level converts are grouped under a heading submenu in block settings. Added **Image** — Overlay controls use discrete size tiers (full/medium/compact) instead of fluid scaling, keeping them legible at small widths. Added **Data compatibility** — Editor.js-shaped data is accepted losslessly: null-tolerant `LooseOutputData` inputs, public `equalsOutputData`/`isEmptyOutputData` utilities, echo-safe `blocks.render()` (re-rendering identical data is a no-op), and a synchronous `isRendered` flag. Fixed **Popovers** — Block-settings menu placement fixes: the menu centers on the six-dots handle, stays attached to it near viewport edges, never touches the screen border, and submenus always open to the right and appear only when hovering the trigger or the submenu itself; page scroll is locked while the menu is open. Fixed **Editor** — Toggle-heading level conversion no longer strands child blocks in a detached DOM (silent data loss); a save-time invariant gate now rejects stranded holders outright. Fixed **Adapters/Core** — Six consumer runtime workarounds root-caused and fixed in core, types, and adapters. Fixed **UI** — Inputs show a single focus indicator (no double border), and the popover search icon was removed. Fixed **Accessibility** — Move and duplicate announcements are count-neutral and carry correct totals; search results announcements keep their context. Changed **CI** — Shorter critical path (parallel build start, faster lint), with contract tests enforcing the workflow shape. Changed **Tests** — Animation-frame APIs polyfilled for jsdom environments; extreme-position e2e sweeps guard menu placement at screen edges.
22. [v1.2.4](https://github.com/JackUait/blok/releases/tag/v1.2.4) Patch Jul 18, 2026 Fixed **i18n** — Capitalized `toolNames` keys (e.g. `toolNames.TestTool`) resolve again in the toolbox: the lookup now tries the raw tool name first, then the capitalized key, restoring the published contract that 1.2.3's raw-name lookup silently dropped. An empty toolbox title no longer short-circuits the fallback chain and renders a blank slash-menu item — it is treated as absent and falls back to the capitalized tool name. Changed **CI** — The docs site now deploys only on package releases, and the deploy is gated by a verifier that checks the published packages (tied to the release version family) before the site goes live.
23. [v1.2.3](https://github.com/JackUait/blok/releases/tag/v1.2.3) Patch Jul 18, 2026 Added **Theming** — More host customization hooks: heading tokens (keyed off `data-blok-heading-level`) and embed tokens, a `--blok-list-gap` token for list spacing, and palette tokens declared at zero specificity via `:where()` so host overrides always win. `--blok-content-max-width` is now authoritative when the editor is in `width: 'full'` mode. Added **Read-only** — The editor wrapper is stamped with `data-blok-readonly` as a public styling hook, and the block-controls gutter auto-collapses in read-only mode so content uses the full column. Added **Adapters** — The three React-integration workarounds were removed by fixing their root causes in core. Fixed **i18n** — Custom tool titles now localize via `toolNames.<toolName>` dictionary keys. Fixed **Image** — GIF→video auto-conversion is skipped when no video tool is registered, instead of failing the upload. Changed **Build** — `dist/` output is now minified and JSON data is emitted as `JSON.parse` strings, cutting published bundle weight. Changed **Docs** — Documented the theming hooks, `data-blok-readonly` attribute, `contentAlign`, `toolbox: false` gating, the GIF guard, the `readOnly` object form, and `toolNames` keys.
24. [v1.2.2](https://github.com/JackUait/blok/releases/tag/v1.2.2) Patch Jul 17, 2026 Added **Theming** — New public `--blok-*` custom properties let host apps customize editor layout without reaching into internals: `--blok-content-max-width` (content column cap), `--blok-editor-gutter-start`/`--blok-editor-gutter-end` (space reserved for the floating block controls, RTL-correct), `--blok-list-padding-start` (list indent), and `--blok-search-input-placeholder` (popover search placeholder color). Defaults preserve current behavior; documented in the docs-site Styles API section. Added **React** — First-class block authoring: `createReactBlock` renders block tools authored as React components through a shared portal host inside the host app's React tree, so app-level context (providers, themes, stores) reaches block components directly — no more `createRoot` per block or context bridges. Every function in a tool's config (including nested ones like `uploader.uploadByFile`) is now re-bound to the latest render's closure, so inline closures work without freezing identities or recreating the editor. Fixed **Floating UI** — A hardening sweep across every floating surface: popovers anchored inside nested scroll containers no longer drift or detach on scroll (snapshot anchors, virtual selection anchors, and fixed-position menus all track correctly); tooltips dismiss on nested scroll; the emoji picker and link hover card follow moving anchors; root boundary calculation is normalized for scrolled and 100vh host bodies. An architecture test now enforces that all floating UI goes through the central positioning module. Fixed **Renderer** — Stored block data is now sanitized on render with the same per-tool sanitize config the Saver applies, closing stored-HTML injection for legacy data that never round-tripped through save (e.g. a raw `<iframe width>` baked into paragraph text overflowing its column). Fixed-width iframes/embeds are additionally capped at `max-width: 100%`. Fixed **Link** — The hover card now requires actual pointer motion before opening, so it no longer opens when a link merely renders or scrolls under a stationary cursor. Changed **Release** — Preflight (eslint ∥ tsc ∥ vitest) and build pipelines were parallelized (~2× faster wall clock), with per-step timeouts so a hung build can no longer stall a release. GitHub Packages mirror tarballs now rewrite `@bloklabs/core` specifiers in every shipped file (previously react/vue `types/index.d.ts` still referenced the npm scope, breaking consumer `tsc` on GHP-only installs).
25. [v1.2.1](https://github.com/JackUait/blok/releases/tag/v1.2.1) Patch Jul 16, 2026 Added **Image** — Images now display at the full width of the article by default. Previously an image without an explicit size preset rendered at the medium (520px) preset; the default is now the `full` preset. Images with an explicitly saved `size` are unaffected. Fixed **Popover** — The search input's focus ring was clipped along its bottom edge by the context label's opaque background painting over it; the search wrapper now renders in the positioned paint layer so the full ring is visible. The gap between the search field and the context label was also widened slightly.
26. [v1.2.0](https://github.com/JackUait/blok/releases/tag/v1.2.0) Minor Jul 16, 2026 Added **Media** — Playback speed and loop preferences now persist across audio and video blocks. They are stored in `localStorage` under shared per-media-type keys (`blok:audio:rate`/`loop`, `blok:video:rate`/`loop`), joining the existing shared volume and per-source position keys, and are restored when a player attaches — without dirtying block data. Fixed **Quote** — Saving a quote block no longer strips `href`/`target`/`rel` from links (leaving dead anchors in stored content) or unwraps bold/italic marks. Quote now uses the same inline-text sanitize rules as paragraph and header, so links, formatting, and color styles survive save and conversion. Fixed **Audio** — OneDrive share links from SPO-migrated accounts (the new `/u/c/<cid>` form) can't be resolved anonymously and produced a silently dead player; they now surface a clear "needs an uploader backend" error instead. Fixed **Toolbar** — The plus button and drag handle no longer stay stuck at the wrong offset after the slash-command popover opens or closes; the toolbar repositions on toolbox open/close instead of relying on a resize side effect. Fixed **Toolbox** — Opening the toolbox silenced the current block's mutation watching and never re-armed it, leaving the block permanently deaf to later content changes until re-render. Watching is now re-armed on both close paths, and the toolbar follows any inner-geometry change that doesn't resize the block holder. Changed **CI** — The build artifact now ships the extracted `packages/*/dist` adapter bundles alongside `dist/`, fixing downstream unit and E2E jobs; `yarn.lock` was synced to the `^1.1.1` core peer range. Changed **Docs** — README and the docs site updated for the `@bloklabs/*` package family; the rename notice was subsequently dropped from the README.
27. [v1.1.1](https://github.com/JackUait/blok/releases/tag/v1.1.1) Patch Jul 15, 2026 Breaking **`@bloklabs/core` has zero peer dependencies.** The react/react-dom/vue optional peers are gone — installs no longer warn about frameworks you don't use, and the GitHub Packages `peerDependenciesMeta`-stripping bug (which forced Yarn Berry consumers to add a `packageExtensions` workaround) no longer applies. Delete that `.yarnrc.yml` entry after upgrading. Breaking **Adapters declare hard, accurate peers**: each requires its framework plus `@bloklabs/core` at the matching version. Breaking **GitHub Packages mirrors**: `@dodopizza/blok` remains the core mirror; adapters mirror as `@dodopizza/blok-react`, `@dodopizza/blok-vue`, `@dodopizza/blok-angular`; the CLI stays `@dodopizza/blok-cli`. Breaking **Migration**: the bundled codemod (`npx -p @bloklabs/core migrate-from-editorjs`) now also rewrites legacy `@jackuait/*` import specifiers and `package.json` dependency keys to the new names.
28. [v1.1.0](https://github.com/JackUait/blok/releases/tag/v1.1.0) Minor Jul 15, 2026 Added **Audio** — Share links from seven more services — Dropbox, OneDrive, GitHub, GitLab, Hugging Face, Google Cloud Storage, and Internet Archive — are recognized and rewritten to their direct-content form, so they play in the browser with no backend. Google Drive share links (hotlink-blocked server-side) are normalized and routed through the consumer's `uploadByUrl` backend, with a Drive-specific error message when none is configured. The error state gets a styled callout with a retry button. Added **Read-only** — `readOnly` now accepts an object form: `{ hideControls: true }` enables read-only mode and suppresses the toolbar, block settings, and inline toolbar. Exposed via `isControlsHidden`, normalized across the React, Vue, and Angular adapters, and `ReadOnlyModeConfig` is exported from the types root. Added **Image** — `compress: { format: 'avif' }` now produces real AVIF via WebCodecs when the canvas encoder cannot, and a new `fallbackFormat` option (e.g. `'webp'`) covers browsers with no AV1 encoder instead of silently uploading the original bytes. Fixed **Audio** — Audio inserted by URL is now enriched like uploads: waveform, title/artist metadata, and cover art, failing soft to a plain scrubber when the host blocks the CORS fetch. Fixed **Table** — Undo inside a table no longer duplicates cell blocks into invisible ghosts that reappear under the table after save; blocks placed at the top of a cell no longer drift to the bottom or become orphans on save. The Saver gains save-boundary guards for cell membership and cell block order (throw in dev/test, repair the emitted output in production). Fixed **Tooltip** — The tooltip bubble is click-transparent, so it never swallows clicks on controls it covers (e.g. color-picker swatches under a bottom-row tooltip). Fixed **Popover** — Nested popovers no longer collapse to their padding in WebKit; the marker color picker rendered as a 12px sliver in Safari. Fixed **Styles** — Body-mounted UI (link hover card, notifier toasts, drag previews) now carries the scope attribute, so its styles survive in consumer apps; a new architecture test enforces the invariant for every `document.body` mount. Fixed **Angular** — The ng-packagr build stages the readonly-config module, fixing a CI-only TS2307; an architecture test now walks the adapter's import graph to catch unstaged modules. Changed **Playground** — Gallery empty states run the real tool per state (with per-state tool config) instead of static mockups, including a live Google Drive error demo. Changed **Tests** — Adversarial table undo probes (merge undo, insert undo/redo), tooltip click-transparency lifecycle guards, and an exhaustive swatch hit-test sweep.
29. [v1.0.0](https://github.com/JackUait/blok/releases/tag/v1.0.0) Major Jul 14, 2026 Added **Header** — Toggle headings are now offered at all six levels, staying in sync 1:1 with regular headings. Fixed **Migration** — The legacy Editor.js grammar is now authored as ESM so consumer dev servers can load blok's source graph without a build step. Fixed **Columns** — Blocks inserted via the plus button no longer save at the bottom of the column; saved order now matches the on-screen (WYSIWYG) order. Fixed **Styles** — Injected utilities are scoped so a host application's CSS reset can't flatten the editor. Changed **Migration** — Single-source `LEGACY_GRAMMAR` shared by both the runtime and the codemod; the codemod's source rewrite is now AST-guided (via the consumer's `@babel/parser`) to avoid mangling comments, strings, and unrelated identifiers. Changed **CI** — Root-caused CI failures: scoped-utility drift on body-mounted UI, lint, and test flake fixes (webkit paste timing, six-level toggle-heading counts).
30. [v0.25.0](https://github.com/JackUait/blok/releases/tag/v0.25.0) Minor Jul 13, 2026 Added **Spacer** — New adjustable-height spacer block. Drag either edge to resize (dual-edge grips), with a text-block-height floor, snap-to-sibling and snap-to-column alignment guidelines, an on-edge capsule resize pill, and accent hover cues. Fully invisible in read-only/published renders. Added **Image** — Uploads are now automatically compressed and re-encoded (`compress`, on by default), with opt-in smaller output formats. In-cell images gain a resize floor and fluid chrome via container queries. Added **Toolbar** — `Cmd`/`Ctrl+Slash` opens the block menu in read-only mode. Fixed **Table** — Large batch of Notion-parity fixes: paste-header handling, the cell color picker, the cell menu, arrow-key navigation between cells, and column width reset. The cell box now follows the caret (instead of the pointer) and the resize handle no longer forces overflow. Focus stays inside a cell when its content is deleted, the caret stays put after clearing a multi-cell selection, multi-line cell selections merge into one rounded shape, drag-selecting several lines within a single cell works, and list items scale to the cell font instead of outsizing sibling paragraphs. Fixed **Columns** — Stranded resize separators left behind by removing a column no longer render as a phantom column. Fixed **Core** — Never Tab-indent a block into a tool-owned container. Fixed **Toolbox** — Keep plus-button blocks on a table out of its cells, and anchor fuzzy search at word boundaries. Fixed **Selection** — Stop hijacking intra-line text drags inside table cells. Fixed **Embed** — Validate stored URLs at render time (stored-XSS guard). Fixed **List** — Keep bullet markers non-editable so Enter never ghosts an item. Fixed **Toolbar** — Read-only drag-handle refinements: announce it as a menu button, show a pointer cursor, and drop the `⌘/` and "Drag to move" hint lines; no read-only handle appears beside blocks that paint nothing. Fixed **Tunes** — Hide the copy-link shortcut hint in read-only mode. Fixed **Styles** — Right `contentAlign` no longer collapses into centering, and preflight resets are scoped to `@layer base` so Blok's own utilities win. Fixed **React** — Guard against stale `dist` exports and a `StrictMode` readiness race.
31. [v0.24.3](https://github.com/JackUait/blok/releases/tag/v0.24.3) Patch Jul 10, 2026 Added **Header** — Opt-in `anchorIds` config derives stable heading anchor ids from heading text. Fixed **Link** — Pad the edit-menu input wrapper so the focus ring isn't clipped, and enlarge the remove-link (trash) icon. Changed **CI** — Fetch mirror tags before pushing to avoid creating over an existing tag.
32. [v0.24.2](https://github.com/JackUait/blok/releases/tag/v0.24.2) Patch Jul 9, 2026 Added **Link** — New `link.transform` config, a superset of `transformHref`: consumers can set per-anchor `href`/`target`/`rel` plus extra attributes (`class`/`title`/`data-*`) without post-processing the rendered DOM. Applies consistently across every anchor path (render, paste, and hand-created links); omitted fields fall back to existing defaults (including the same-page `_self` rule) and extra attributes never clobber the managed `href`/`target`/`rel`. Fixed **Columns** — Keep the inter-column gutter in read-only/published renders. The gap was previously produced entirely by the (no-op in read-only) resize handles, so read-only columns rendered flush; the gutter is now decoupled from the resizers. Fixed **Link** — Center the hover card under the pointer (shifting near viewport edges) with a fixed gap to the link, and stop the block toolbar leaking through the card when hovering top-layer chrome. Fixed **Notifier** — Fix top-layer placement so the toast stays in its corner (no UA Canvas box or top-left jump), remove the in-pill dismiss cross (auto-dismiss/Escape still close it), and tighten the pill's vertical padding.
33. [v0.24.1](https://github.com/JackUait/blok/releases/tag/v0.24.1) Patch Jul 9, 2026 Fixed **Types** — Fixed a publishing defect (introduced in 0.24.0) where importing `@dodopizza/blok/react` — or `@dodopizza/blok/markdown` — made a consumer's TypeScript compiler follow the published declarations into raw `src/` implementation, producing spurious errors about unresolved `micromark-util-types` / `@types/mdast` (`TS2307`) and implicit `any` (`TS7006`). The public `types/*.d.ts` surface is now self-contained and no longer re-exports from `src/`. Changed **Types** — Mechanically enforce that no published `types/*.d.ts` re-exports or imports from `src/`, and generate the self-contained icon declarations from source (`scripts/generate-icons-dts.mjs`).
34. [v0.24.0](https://github.com/JackUait/blok/releases/tag/v0.24.0) Minor Jul 9, 2026 Added **Vue** — New first-class `@jackuait/blok/vue` adapter: `BlokEditor` component, `useBlok`, and `provideBlok`, plus `createVueBlock`/`useBlocks` for authoring custom blocks and driving the block tree from Vue. Custom Vue blocks support read-only in-place toggling. Added **Angular** — New first-class `@jackuait/blok/angular` adapter shipped as an Angular Package Format build (ng-packagr): the editor component/directive, a block portal registry, the `BLOK_BLOCK_CONTEXT` render-context token, `createAngularBlock` authoring, and the reactive `injectBlocks` block-tree API. Added **React** — New `useBlocks` hook exported from `@jackuait/blok/react`: a reactive block-tree API with reads, `insert` (position + append-to-parent, explicit id, tunes, `replace`), `move` (before/after/toIndex), `nest`/`unnest`/`remove`/`transact`, `insertMany`, atomic `insertTree` for nested subtrees, and additive `insertMarkdown`. Block-creation semantics are hardened across hierarchy edges with compile-time drift guards against the core API. Added **Adapters** — Closed React/Vue/Angular parity gaps across component paths and escape hatches; shared one blocks-api core so Vue's `useBlocks` reaches React parity, and extracted shared `fillDefaults`/`PropSchema` helpers. Custom-block authoring is now first-class on the public API surface. Added **Accessibility** — Five-wave overhaul adapting shadcn/ui interaction patterns to Blok's UI primitives: dismissal-layer/popover teardown/scroll-lock/announcer foundations, an anchored-positioning engine and shared modal `Dialog`, keyboard reachability for toolbars/menus/radios/rename, and assistive-tech feedback parity across selection, drag, menus, and arrival. Added **Link** — Clickable links with a hover card in both edit and read-only modes (with enter/leave animation), an edit mode featuring a title field and remove-link action, refined hover-card chrome, blocking of unsafe-scheme navigation, and a consistent same-page/anchor-link rule that opens such links in the same window across all link-creation paths. Added **Blocks** — Structural `parentId` nesting: any block can now be nested inside any list (flat per-block indent), with list keyboard nesting and drag/serialization migrated onto the structural block tree. Added **Keyboard** — `Cmd+Left`/`Cmd+Right` navigate between blocks at block edges; `Backspace` at the start of a nested block removes one indent level; mixed-list `Tab` indents both kinds; and numerous Notion-parity `Tab`/arrow/Delete/Backspace fixes. Added **Paste** — Paste-without-formatting (`Cmd`/`Ctrl+Shift+V`); recovery of buildin/Notion toggles and soft breaks from lossy GFM HTML fallback. Added **Inline** — Link-markdown auto-format and a link-paste menu; shortcut-triggered Link/Equation/Marker now open a standalone menu positioned right under the selection. Added **Popover** — Custom cross-platform scrollbar that hides the classic OS bar while keeping a stable gutter; reel-like edge distortion replacing the scroll haze. Added **Convert** — Shared `buildConvertMenuEntries` with `titleKey` resolution, used by both block settings and the inline "Turn into" menu (which now lists the full text family), guarded by parity E2E. Added **Image** — Configurable auto-retry on image load failure (default 5). Fixed **CRDT/Yjs** — Undo/redo no longer yanks the caret to the top of the document; the caret restores to the correct position, `split()` inherits full tool data (correct heading undo caret), redo moves the caret to the new block on an Enter split, and five further Yjs sync gaps in tools and modules were closed. Fixed **List** — Closed dozens of Notion-parity divergences across convert, keyboard, drag, selection, and copy/paste; source ordered lists renumber when an item is dragged away; bullet glyphs refresh on depth change. Fixed **Text/Header** — Fixed 30+ Notion-parity bugs by root cause (slash+space, duplicate pulse, indent toolbar, caret offset preservation on turn-into, and more). Fixed **Table** — Preserve merged cells and lists when pasting external tables, and keep list markup when copying cells out to external apps. Fixed **Paste** — Preserve lists and quote-ness in pasted blockquotes; pasted links use the default link color; the link menu shows on non-empty blocks without erasing content; closed remaining sanitizer/merge data-loss gaps found by an audit. Fixed **Blocks** — Re-parent a merged block's children onto the survivor instead of orphaning them; release toggle children as siblings when turning a toggle into text; fire the tool `moved()` hook on `setBlockParent`; never write split text into a mutation-free decoration. Fixed **Columns** — Match Notion's inter-column gutter spacing; restore DOM order when undoing column creation. Fixed **Drag** — List-item drop line tucks under the text with a marker lead-in; depth changes apply on same-slot drops; non-list blocks stop previewing nested drops they can't reach. Fixed **Selection** — Fake highlight matches the native selection color and stays visible while a menu input is focused; `Cmd+A` container-scoped staging. Fixed **Marker** — Reset `<mark>` background so colored text never shows the browser's yellow highlight. Fixed **Toggle** — Arrow container stays a constant 28px square and pins to the first line for multi-line toggle/heading. Fixed **Styles** — Reserve a scrollbar gutter on all scrollable components and keep it in nested inline-toolbar menus; auto-hide scrollbars system-style while keeping the gutter. Changed **Paste** — Mechanically enforce the paste attribute law and the paste stamp law via architecture tests. Changed **Tests** — Repaired all CI-matrix E2E shards; added regression coverage across list keyboard shortcuts, columns undo order, popover scrollbar spec, and adapter integration/e2e. Changed **Lint** — Resolved all 69 root ESLint problems at the root cause.
35. [v0.23.5](https://github.com/JackUait/blok/releases/tag/v0.23.5) Patch Jun 25, 2026 Added **Core** — The `link` config (`{ target, rel, transformHref }`) now also applies on the **render** and **paste** paths, not just the interactive link tool. Anchors coming from stored block HTML (rendered via `blocks.render()`) and `<a>` arriving through the clipboard now get the configured `target`/`rel` forced and `transformHref` applied to their href — so consumers no longer need to post-process the rendered or pasted DOM. Because the render path rewrites live anchors whose href round-trips into saved data, `transformHref` must be idempotent. Added **Core** — New `onBeforeRender(blocks) => blocks` config transforms the blocks array before every render (the initial render and each `blocks.render()`), letting you run app-specific data migrations inside Blok instead of pre-processing the data yourself. It runs on the raw saved blocks before format analysis, so it can also inject blocks into an empty document. Added **Core** — New `onAfterRender(api)` config fires after a render completes and the blocks are in the DOM (initial render and every `blocks.render()`), for post-render side effects such as scroll restoration — distinct from the once-only `onReady`. Added **Core** — A stable `data-blok-rendered` attribute (exposed as `DATA_ATTR.rendered`) is now set on the editor wrapper when a render batch finishes inserting blocks, and removed while a re-render is in flight — a DOM-level render-readiness gate that complements the existing `blocks:rendered` event. Added **Block Tunes** — A custom tune's `render(context)` now receives an optional `BlockTuneRenderContext` whose `getPopoverElement()` returns the host tune popover element (`[data-blok-popover]`), so tunes can anchor sub-menus or portals inside Blok's popover without reaching into the DOM via `closest(...)`. The element resolves once the popover mounts (it is `null` synchronously during `render()`). Added **React** — `<BlokEditor>`/`useBlok` now accept `onBeforeRender` and `onAfterRender`. Both are attached only when provided and are ref-stable, so updating the callbacks never recreates the editor.
36. [v0.23.4](https://github.com/JackUait/blok/releases/tag/v0.23.4) Patch Jun 25, 2026 Added **Core** — New `onSave(data, api)` config delivers the full serialized `OutputData` (debounced via the existing change-batch window) whenever content changes — the "output half" of a controlled editor. Pair it with the `data` config to mirror editor state into your own store with a single callback instead of calling `saver.save()` by hand. Only user-driven changes trigger it; programmatic `render()` does not (the change observer is disabled during render), so a controlled round-trip won't recurse. Available to all consumers, not just React. Added **React** — `<BlokEditor>`/`useBlok` now accept `onSave`, making `<BlokEditor data={data} onSave={setData} />` a true controlled component to pair with the reactive `data` prop from 0.23.3. The callback is ref-stable (never recreates the editor) and attached only when provided. Echoing the payload straight back via `onSave={setData}` is caret-stable: the adapter records the editor's own emitted output as the content baseline, so the round-trip deep-equal–dedupes to a no-op (no re-render, no caret reset) while genuine external `data` changes still render in place.
37. [v0.23.3](https://github.com/JackUait/blok/releases/tag/v0.23.3) Patch Jun 25, 2026 Added **React** — The `<BlokEditor>`/`useBlok` `data` prop is now reactive: passing new content re-renders the editor in place via `editor.render()` instead of being read only once at creation. Identical content is de-duplicated (deep-equality) so the caret is never clobbered, rapid changes are serialized, and a freshly-seeded editor is not double-rendered. Added **Core** — New typed render events: `blocks:rendered` (payload `{ count }`) fires when a batch finishes rendering, and `block:rendered` (payload `{ blockId }`) fires per block. The runtime event-name constants `BlocksRendered`/`BlockRendered` are exported, so consumers can react to rendering instead of polling the DOM. The public `Events` API is now typed against an event/payload map while still accepting arbitrary string events. Added **Core** — New `link` config (`{ target, rel, transformHref }`) lets consumers configure the anchors the link tool creates instead of post-processing the DOM. Defaults (`_blank`/`nofollow`) are preserved, configured values now survive save, and URL validation/allowlisting is unchanged. Added **Paste** — New `onBeforePaste(html) => string | null` config hook transforms (or drops) raw clipboard HTML before Blok preprocessing; returning `null` falls back to plain-text paste. Added **API** — New `editor.tools.update(name, config)` shallow-merges a tool's config in place — e.g. swap an uploader — without recreating the editor. Changed **Tests** — Exported stable `TEST_ID` constants (plus button, settings toggler, block wrapper) wired into the editor chrome via `data-blok-testid`, so consumers no longer query internal selectors.
38. [v0.23.2](https://github.com/JackUait/blok/releases/tag/v0.23.2) Patch Jun 25, 2026 Changed **Docs** — Documented two React-adapter caveats. `<BlokEditor>` must not be wrapped in `styled()` or any HOC that reserves the `theme` prop: styled-components claims `theme` for its own `ThemeProvider`, so it never reaches the editor and theme sync silently breaks — render it directly and style the container via `className`. And `deps` values must be referentially stable (each value compared individually, not the array wrapper), otherwise the editor is recreated on every render. Both caveats now appear in the README, the docs site, and the `BlokEditor`/`useBlok` JSDoc and published type declarations.
39. [v0.23.1](https://github.com/JackUait/blok/releases/tag/v0.23.1) Patch Jun 25, 2026 Added **Core** — A new `editor.placeholder` runtime API (`get`/`set`) lets consumers read and change the empty-paragraph placeholder on a live editor, mirroring the existing `width` API. Updates apply to existing blocks and to blocks created afterwards. Added **React** — `<BlokEditor>` now accepts a reactive `placeholder` prop (backed by the new core API) that updates the editor in place without recreating it, and forwards all standard `<div>` attributes — `id`, `aria-*`, `data-*`, and the like — to the editor container.
40. [v0.23.0](https://github.com/JackUait/blok/releases/tag/v0.23.0) Minor Jun 24, 2026 Added **React** — A blessed `<BlokEditor>` component is now the recommended way to embed Blok in React. It forwards a typed ref to the live editor instance, takes an uncontrolled `data` seed, and reactively syncs `readOnly`, `autofocus`, `theme`, and `width` props without recreating the editor. Its `onReady` callback fires after the ref commits, so consumers can safely call `ref.current` from inside it. The lower-level `useBlok` hook plus `BlokContent` remain available as an escape hatch. Changed **React** — `useBlok` now reactively syncs `theme` and `width` prop changes to the editor instance, mirroring the existing `readOnly`/`autofocus` pattern. Changed **Docs** — The demo wrapper now dogfoods `BlokEditor`, and the README React section documents the recommended `BlokEditor` path, the uncontrolled `data` contract, reactive props, and the `useBlok` + `BlokContent` escape hatch. Changed **Tests** — Added e2e coverage for save-via-ref and live prop toggles, a published-vs-source type-drift guard, and `data-blok-testid`-based locators.
41. [v0.22.0](https://github.com/JackUait/blok/releases/tag/v0.22.0) Minor Jun 24, 2026 Added **Paste** — Content copied from buildin.ai now imports as native Blok blocks at full fidelity. buildin's clipboard carries a lossless `text/next-space-blocks` JSON payload beside a lossy Markdown/HTML twin; Blok previously fell back to the twin, where tables collapsed to literal `|pipes|`, media degraded to links, and callouts, toggles, columns, to-dos, and code language flattened away. A new handler decodes the JSON directly, reconstructing the same native blocks as a Blok→Blok paste — paragraphs, to-dos, H1–H4, tables (grid + parented cells), bulleted/numbered lists, toggles, dividers, quotes, callouts (emoji + colour), code (with language), equations, toggle-headings, column lists, and image/video/audio/file/embed-bookmark media. (Inline marks — bold/italic/link/colour — are a documented follow-up.) Fixed **Paste** — Callout body and colour now survive import from both Notion and buildin.ai. Blok's callout stores its body in child blocks, so the inline title/body text the parsers emitted as `data.text` was silently discarded — the callout is now emitted (colours only) plus a child paragraph carrying its text. Out-of-palette callout colours (e.g. buildin's British `grey`, or any name outside Blok's 9-colour preset) previously produced an undefined CSS variable that dropped both the background and the border; colours now normalize through Blok's preset palette (`grey`→`gray`; unknown names clamp to null).
42. [v0.21.1](https://github.com/JackUait/blok/releases/tag/v0.21.1) Patch Jun 24, 2026 Added **Media** — Image, video, audio, and file blocks can now be restricted to upload-only or link-only via configuration, so consumers can offer a single source instead of always exposing both. Changed **Media** — Deduped `MediaSource` into a single shared type across the media tools. Changed **Docs** — Documented the audio block tool, and added upload-only and link-only empty states to the playground gallery.
43. [v0.21.0](https://github.com/JackUait/blok/releases/tag/v0.21.0) Minor Jun 23, 2026 Fixed **Paste** — Rich clipboards (Notion and similar) ship both a faithful HTML payload and a lossy Markdown twin. Routing now prefers the HTML handler, so pasted images, links, and structure the Markdown twin drops are preserved. Fixed **Paste** — Notion content keeps its document order: nested children no longer render above their parents (only table cells stay children-first, since the table tool resolves cell ids on insert). Internal references that previously vanished — sub-pages, linked databases / collection views, and inline page mentions — now paste as Notion bookmarks/links instead of being dropped or leaking the raw "‣" glyph, and uploaded media whose binary isn't on the clipboard becomes a Notion-link bookmark carrying the filename rather than a bare filename paragraph. Fixed **Paste** — Pasted external Notion audio now shows its title (the player reads `data.title`, which was left blank), and a malformed inline date annotation no longer leaks the raw "‣" placeholder glyph. Changed **Tests** — Added regression coverage for HTML-over-Markdown routing, document-order preservation, internal-reference rescue, pasted audio titles, and date-glyph handling.
44. [v0.20.0](https://github.com/JackUait/blok/releases/tag/v0.20.0) Minor Jun 22, 2026 Added **Paste** — Content copied from Notion now migrates as native blocks with full state preserved. When Notion's lossless clipboard JSON is present it is used directly (the high-fidelity path), with an HTML fallback for sources that only expose markup. Inline equations and page mentions are mapped to their Blok equivalents. Added **Audio** — Custom cover art. A cover picker (file upload or image URL) opens from an editable overlay button on the player; covers can be set, replaced, or removed (via a "Remove cover" block setting), with an animated picker open, a sliding Upload/Link tab transition, a themed surface that matches the player, and i18n across all locales. Audio blocks with no cover now show an inertial spinning-vinyl turntable placeholder instead of an empty panel. Fixed **Audio** — Repaired the transport controls and the video-style playback-speed menu, which now stays open after picking a preset. The volume bar fill is fixed so a muted track reads differently from a full one, and the playing waveform pulses smoothly without gouging its dots. The caption toggle stays on the compositor, and the cover picker no longer jumps height on tab swap, gets an explicit width so the URL field isn't cramped, and revokes leaked cover blobs on a destroy race. Fixed **Table** — Pinned the top toolbar anchor flush to the table edge. Changed **Tests** — Added unit and e2e coverage for custom cover set/remove and for real Notion page-mention arity, and cleared the lint/type violations the cover-art work introduced.
45. [v0.19.2](https://github.com/JackUait/blok/releases/tag/v0.19.2) Patch Jun 20, 2026 Breaking **Types** — `OutputBlockData`'s `data` field is now typed `Record<string, unknown>` instead of `any` (matching `BlockToolData` and `SavedData`). Reading a property off a saved block's `data` — e.g. on `save()` output — now yields `unknown` rather than `any`, so code that indexes into `block.data` may need a cast or type guard. This is a type-only change with no runtime effect. Fixed **Types** — Published `.d.ts` declarations are now self-contained and no longer re-export raw `src/*.ts`. A bare `import { Blok } from '@jackuait/blok'` previously dragged editor source into the consumer's TypeScript program (through `tooltip` and `popover` → `flipper`), surfacing internal type errors under strict consumer flags such as `noUncheckedIndexedAccess`. The `tooltip` and `popover` declarations now inline their public types, so consuming the package no longer type-checks Blok's internals. (The opt-in `/markdown` subpath is unchanged.) Fixed **Types** — The published declarations are now internally consistent under `skipLibCheck: false`. Fixed an incorrect `BlockToolData` import path in the `database`/`header`/`list` tool declarations (which also produced spurious "incorrectly extends `BlockTool`" errors), added a missing `InlineToolConstructable`/`InlineToolConstructorOptions` import in the type entry, and removed phantom `Dictionary`/`DictValue` re-exports. Changed **Dependencies** — Moved `nanoid` to `devDependencies`; it is bundled into every dist artifact and was never a runtime external.
46. [v0.19.1](https://github.com/JackUait/blok/releases/tag/v0.19.1) Patch Jun 20, 2026 Added **Types** — `isReady` now resolves with the fully-initialized `Blok` instance (was `Promise<void>`), so `const editor = await blok.isReady` yields a ready, fully-typed editor without a cast. New exported `PendingBlok` type describes the surface available synchronously after `new Blok()` and before `isReady` resolves (`isReady`, `destroy`, `theme`, `width`) — type a reference held during that window as `PendingBlok` instead of widening to `Partial<Blok>`, then await `isReady` to narrow it to the full API. `new Blok()` still returns the full `Blok`, so existing usage is unaffected.
47. [v0.19.0](https://github.com/JackUait/blok/releases/tag/v0.19.0) Minor Jun 20, 2026 Added **Width** — New public `width` API on the editor instance: `instance.width.get()`, `set('full' | 'narrow')`, and `toggle()` switch the content layout between `'narrow'` (the default, constrained to `--max-width-content`) and `'full'` (the content `max-width` is removed so it fills its container). It mirrors the `theme` API, including buffering a `set()` call made before the editor is ready and replaying it once the editor is initialized. Fixed **Types** — Declare the `history` API on the exported `Blok` instance type. `history` (`clear()`, `undo()`/`redo()`, `canUndo()`/`canRedo()`) was already available at runtime; consumers no longer need to cast the instance to reach it.
48. [v0.18.0](https://github.com/JackUait/blok/releases/tag/v0.18.0) Minor Jun 19, 2026 Added **Audio** — New native Audio block tool. Now-playing card with cover art (lazy `music-metadata` extraction), a waveform canvas with click/drag seek, transport controls (play/pause, volume, playback speed, loop, keyboard shortcuts, persisted preferences), file and URL upload, paste handling routed away from the File block, read-only support, and i18n across all locales. The player card is a full-bleed redesign — a tall cover panel (music-note placeholder when there is no art), a hero waveform scrubber with rounded bars, a slim transport bar, and motion polish. Added **Media** — Image, video, and audio blocks now accept any file of their media family (`image/*`, `video/*`, `audio/*`) by default. Restrict the accepted types through the existing `types` config, which now accepts both exact MIME types (`image/png`) and family wildcards (`image/*`). Fixed **Types** — Export `File`, `Audio`, and `Video` (and their data/config/uploader types) and add the `file`/`audio`/`video` keys to `defaultBlockTools` from the `@jackuait/blok/tools` types entry. The runtime already exported these tools; consumers no longer need a local ambient type shim to import them. Changed **Playground** — Audio block states in the block-states gallery (real ID3-tagged track and a "No cover art" state) plus an e2e harness for insert/upload/play/seek.
49. [v0.17.0](https://github.com/JackUait/blok/releases/tag/v0.17.0) Minor Jun 19, 2026 Added **Video** — New native Video block with a custom Airbnb-style player, brought to YouTube parity: full keyboard control (`j`/`l`/`k`, `0`–`9`, `Home`/`End`, frame-step, volume, speed), a scrubber with buffered range, hover frame-preview tooltip and mini progress bar, an in-player gear menu (Notion-style playback speed with glide, loop, ambient-glow intensity), and view modes — picture-in-picture, a FLIP-morphed theater/cinema mode, and a fade-in ambient glow. Player polish includes click-to-toggle play/pause, a centre play/pause burst, press-and-hold for 2× playback, arrow-key ±5s seek with side indicators, idle auto-hide, buffer spinner, time-remaining toggle, right-click menu, stats overlay and persisted preferences. Added **Video** — Custom fullscreen surface with a top caption bar, a "Hide controls" tune for a control-free player, and GIF-style autoplay/loop tunes. Added **Image** — Auto-convert dropped, pasted and remote-URL GIFs into a looping Video block via WebCodecs + webm-muxer, gated by the `convertGifToVideo` config (default on); the original GIF is kept on CORS failure, with a "Converting…" label shown during conversion. Added **Media** — 30MB default upload limit with per-type `maxSize` configuration and human-readable too-large errors. Fixed **Paste** — URL paste always prompts now; the previous auto-embed behaviour has been removed. **Breaking:** consumers relying on silent auto-embed must opt in through the paste menu. Fixed **Video** — Reserve the aspect ratio before metadata loads to prevent squeeze-on-load, centre and letterbox the fullscreen player, strip editor chrome in fullscreen, and hide the bottom mini progress bar while fullscreen. Fixed **Video** — Exit theater mode reliably on Escape via a capture-phase listener with a smooth deferred dismiss, and drive the scrubber fill with `requestAnimationFrame` for smooth playback tracking. Changed **Build** — Move `webm-muxer` to devDependencies so it is bundled rather than treated as an external runtime dependency. Changed **README** — Replace the logo with the optimized noodle mascot. Changed **Playground** — Use real self-hosted videos in the block-states gallery.
50. [v0.16.0](https://github.com/JackUait/blok/releases/tag/v0.16.0) Minor Jun 16, 2026 Added **File** — New File block tool. Tabbed empty state with upload (validation, progress bar, cancel), URL and drag-and-drop; per-type icon and tint; editable filename; consumer upload endpoints and download card. Rich preview modal dispatched by kind: PDF (top-layer modal with open-in-new-tab), Office (docx/xlsx/pptx via lazy renderers, xlsx parsed through JSZip), and text/code/markdown — including advanced markdown (math, footnotes, references, alerts, anchors, safe block-level raw HTML) with an animated Rendered ⇄ Raw toggle. Read-only support, i18n in every locale, and Storybook stories. Added **Embed** — Generic embed: frame arbitrary URLs through a gated resolver, offered in the paste menu behind the `linkPaste.allowGenericEmbed` flag with an `api.config` accessor. Replace the source via an empty-state URL bar and an overlay more-menu item. Added **Migration** — Complete Editor.js block-type coverage plus a drop-in UMD build; adapt legacy Editor.js inline tools and `linkTool` data. Added **Playground** — Block-states selector as a fixed left side menu; real docx/xlsx/pptx, code and text samples for the File block; richer quarterly-budget sheet; File block wired into the editor demo. Fixed **Table** — Resolve merged-cell coordinate bugs; preserve merges on load; split overlapped merges on paste so no destination data is dropped; keep empty cells editable on the read-only→edit toggle; harden input, clipboard and move-guard handling. Fixed **File** — Unbreak pptx preview; vertically center the preview modal; stop wrong-colour strips and toggle flicker during preview transitions; block `javascript:` URLs in download hrefs. Fixed **Build** — Make the published install self-contained (ship `src`, keep markdown and nanoid as runtime deps) so bundlephobia can build; green the self-contained-install and css-token audits. Changed **Refactor** — Extract table visual-subsystem orchestration into `TableSubsystems`; split `BlockOperations` into focused worker classes; share the media uploader empty state across the image and file tools. Changed **Code** — Cover every Prism token in both the light and dark themes. Changed **Lint** — Resolve all lint errors by root cause and mute advisory-only rules. Changed **Docs** — Refresh the README tool list and entry points; add a File block tool reference entry.
51. [v0.15.1](https://github.com/JackUait/blok/releases/tag/v0.15.1) Patch Jun 13, 2026 Fixed **Types** — Declare `Embed` and `Bookmark` (and their `defaultBlockTools` entries) in the published `@jackuait/blok/tools` types. The runtime exported them in 0.15.0 but the `.d.ts` did not, so `import { Embed, Bookmark }` failed to typecheck.
52. [v0.15.0](https://github.com/JackUait/blok/releases/tag/v0.15.0) Minor Jun 12, 2026 Added **Link Paste** — Pasting a URL now offers a Notion-style menu to keep it as a link, or convert it into a Bookmark card or rich Embed block. The pasted link shows immediately with the menu anchored at its end, and menu labels name the detected link type via provider metadata. Added **Embed** — Worldwide embed registry covering ~115 services across video, audio, social, documents, design and developer domains, including Google published docs/forms and draw.io. Per-source minimum resize widths keep each provider's iframe legible, and fixed-width providers hug their content with figure, handles and toolbar. Added **Bookmark** — Notion-parity bookmark card with a dev unfurl endpoint; crawler-UA retry recovers metadata from bot-blocked sites. Added **Playground** — Smooth cross-fade theme switching via View Transitions, plus an Airbnb-style neutral redesign. Fixed **Embed** — Preserve the live iframe across every editor action: caption and alignment toggles now apply in place instead of reloading the player. Selection highlight hugs the figure dimensions. Fixed **Drag & Drop** — FLIP-animate the column drop moment and slim the vertical drop bar to read like the horizontal line. Fixed **Security** — Harden URL-scheme filtering and neutralize XSS gaps in markdown paste, the inline link tool, and the paste/render pipeline. Fixed **Tools** — Implement `setReadOnly` on embed, bookmark and column tools so read-only toggles in place without a full re-render. Fixed **Icons** — Unify the icon set on the 20×20 / 1.25 house spec; refine heading family, quote, caption, pencil, cells, toggles, and numbered-list glyphs. Fixed **CI** — Pin Node 24.14.1 to dodge a Playwright install hang; share Playwright setup to stop Storybook browser install hanging; repair 6 failing CI specs (5 stale expectations, 1 real drop-indicator regression). Changed **Dependencies** — Resolve all 52 open Dependabot alerts; bump brace-expansion, ws, smol-toml. Changed **Tests** — Embed/bookmark/link stories with screenshot baselines, wave-2 embed visual-regression baselines, verified real sample URLs replacing fixtures, refreshed `main.css` golden snapshot. Changed **Docs & Playground** — Embed, bookmark and link entries in tools data and the editor demo.
53. [v0.14.1](https://github.com/JackUait/blok/releases/tag/v0.14.1) Patch Jun 8, 2026 Added **Tools** — Register the Columns tool with a single `Columns` group key. Tool-group "provides" manifests expand into their underlying block tools during `prepare()`, so consumers add one key instead of wiring each block. Fixed **Tools** — Export `Columns` from public types for single-key registration; keep `defaultBlockTools` settings-only so the group key forwards settings without re-registering.
54. [v0.14.0](https://github.com/JackUait/blok/releases/tag/v0.14.0) Minor Jun 5, 2026 Added **Columns** — New side-by-side layout tool (#67). Create 2–5 column presets from the toolbox, or drag a block beside another to spawn a column. Drop anywhere left/right of a block to make a new column, or into a column body to stack inside it. Columns nest, auto-unwrap when emptied, and stack vertically on narrow viewports. Added **Columns** — "Turn into columns" command wraps a multi-block selection into a column layout, available from the Convert-to menu. Added **Columns** — Hover-revealed resize separators between columns: drag to resize, keyboard-resizable with ARIA slider semantics, double-click a divider to equalize widths. Added **Columns** — Horizontal arrow keys traverse between sibling columns; new columns animate in Notion-style. Added **Inline Toolbar** — Appears instantly on selection release, no animation delay. Fixed **Inline Toolbar** — Removed entry animation that delayed appearance. Changed **i18n** — Column resize aria-labels and turn-into-columns strings across all locales. Changed **CI** — Repair unit tests, e2e merge, and mirror push on master; mirror push works for both branch and tag events. Changed **Tests** — Exhaustive block-in-column compatibility suite, live-drag lifecycle specs for every block type, multi-select block-settings header i18n regression. Changed **Playground** — Columns example in the editor demo and block-states gallery.
55. [v0.13.2](https://github.com/JackUait/blok/releases/tag/v0.13.2) Patch May 30, 2026 Fixed **Read-Only** — Collapse the empty bottom click-to-add zone to 0px in read-only mode and restore the configured min-height when editing
56. [v0.13.1](https://github.com/JackUait/blok/releases/tag/v0.13.1) Patch May 29, 2026 Added **Image** — Auto-retry failed image loads with loading overlay; distinguish upload-failed vs broken-image error states; predict loading-placeholder dimensions from URL, SVG, and cache; pipe upload progress to bar (#41) Added **Codemod** — Default migrated images to `size: 'full'` and inherit the stretched flag into migrated image size Added **Block Link** — Highlight pulse on hash-link arrival Added **Read-Only** — Show copy-link menu on block hover Added **Playground** — Add loading image state demo in block-states gallery Fixed **Image** — Force full width and compact overlay for short images; reuse looping-arrows glyph for replace icon Fixed **Paste** — Keep Google Docs images inside tables and stop double-bolding headings; prevent default page background collapsing to gray preset Fixed **Table** — Recover migrated cell text detached by a pre-fix save Fixed **Toolbar** — Align plus/drag handle with content lane for stretched blocks Fixed **Block Settings** — Anchor popover to trigger instead of (0,0); translate popover context label Fixed **Database** — Center block toolbar on the title line Changed **i18n** — Translate strings identical to English across 25 locales Changed **Lint** — Resolve all ESLint and tsc problems Changed **Image** — Move inline upload-failed SVG to icons module Changed **Tests** — Cover migrated cell content surviving load→save round-trip; fix CSS guard test failures from image loading shimmer
57. [v0.12.0](https://github.com/JackUait/blok/releases/tag/v0.12.0) Minor Apr 22, 2026 Added **Image** — New image block tool (#66): drag-drop/URL/file upload, captions, alt text via inline popover, resize handles with symmetric growth, edge-pinned aspect-ratio resize, crop editor (rect/circle/oval) in modal, fullscreen lightbox with wheel/pinch zoom, drag-to-pan, rubber-band, alignment popover (left/center/right), block settings entries (size/download/copy-url), three-dots overflow menu for narrow images, empty/uploading/error states with unified card design, light-theme crop editor, legacy editor.js shape migration Added **Code** — Migrate from Shiki to Prism.js for syntax highlighting with lazy grammar loading and class-based applier; add auto-indent and bracket expansion on Enter; add Mermaid highlighting with One Dark/Light palette; gutter line-number click focuses the line Added **Fonts** — Bundle @fontsource fonts via generator script; new `fontFamilySans/Serif/Mono/Handwriting` config fields with CSS variable injection; `font-display: swap` for body text Added **Popover** — Render above all elements via CSS Top Layer; nested-submenu viewport clamping on both axes; close transition via ghost clone; tighter item sizing; end-of-list padding hidden on empty search; simpler animations Added **Toolbar** — Hide plus and dots buttons while toolbox is open; place block settings popover left of the dots button Added **Toolbox** — Nowrap pill with tighter radius and unified plus/slash search styling Added **Playground** — Icon gallery lightbox; block states gallery tab; settings panel shortcuts; hide header on scroll; logotype image example Added **CSS Variables** — Tokenize radii, spacing, icon sizes, border widths, z-index ladder, duration/easing, typography; extract direct `rgba` literals to palette tokens; migrate `@apply` arbitrary hex values; split `actions-icon`/`divider` vars; add audit test and visual regression baselines Added **Database** — Match Notion card shadow and radius on kanban cards; showcase all 10 column color variants Added **Block Settings** — Add shortcut keys to i18n with regression tests Added **Icons** — Migrate inline SVGs to shared icon layer Fixed **Inline Toolbar** — Tighten item padding and radius; suppress toolbar inside code blocks; apply symmetric top/bottom padding Fixed **Code** — Pin caret color so it does not inherit Prism token colors; restore trailing `<br>` after highlight so Enter works once; refresh gutter/highlight after native paste; focus line end when clicking empty strip of short lines; scope inline-code styling to not leak into code block; support `contenteditable="plaintext-only"` and preserve view mode on undo; correct syntax highlighting offset calculation Fixed **Toolbar** — Reposition + / ⋮⋮ live while hovered block resizes; disable pointer-events on every actions descendant for left-edge blocks; keep slash search in inserted block after plus button Fixed **Popover** — Distinguish synthesized hover from real hover; hide context label while searching; keep block settings menu visible and attached to dots trigger Fixed **Block Manager** — Skip cross-container auto-heal inside move group Fixed **Tooltip** — Anchor wrapper with `position: fixed` to survive page scroll; render above popover and survive UA stylesheet Fixed **Fonts** — Add error handling for font load failures Changed **Styles** — Split `main.css` into 11 concern-files Changed **License** — Add fork attribution and NOTICE file Changed **Build** — Replace shiki with prismjs Changed **Tests** — Fix 60+ unit + E2E failures across the suite; add Prism integration test for all highlightable languages Changed **Chore** — Untrack `.vscode`; remove stale root files; add favicon to dev playground; drop `.editorconfig`
58. [v0.11.1](https://github.com/JackUait/blok/releases/tag/v0.11.1) Patch Apr 16, 2026 Added **Bundles** — Ship CJS (`require()`) and IIFE (`<script>` tag / CDN) bundles alongside ESM; add `"main"`, `"browser"`, `"unpkg"`, and `"jsdelivr"` fields to `package.json` Changed **README** — Add installation section documenting ESM, CJS, and CDN usage
59. [v0.10.9](https://github.com/JackUait/blok/releases/tag/v0.10.9) Patch Apr 14, 2026 Added **Toggle** — Gray arrow icon when toggle body is empty Fixed **Drag** — Eliminate "wrong block dropped" with multi-layer stale-block defense; block paste, undo/redo, and move shortcuts during active drag; integrate drag-reparent with undo as a single step Fixed **Hierarchy** — Reject dangling parentId at universal chokepoint; reconcile remote Yjs reparents; close remaining container drift vectors; exempt Yjs remote sync from dangling parent throw Fixed **Paste** — Inherit container parent on replace-insert and x-blok root paste; harden container paste ejection across all container block types Fixed **Callout** — Restore plus button and drag handle; stop paste from ejecting children via stale contentIds; prevent Enter from inserting new block inside callout Fixed **Undo** — Collapse multi-block paste and alt-drag duplicate into one undo group; eliminate spurious entries from metadata-only writes Fixed **Toolbar** — Keep drag handle visible when editing inside table cell Fixed **Insert** — Universally protect all Enter paths from nested-block leak Fixed **Table** — Tighten list item spacing inside table cells Fixed **Yjs** — Map 'no-capture' origin to local to prevent mid-op sync clobbering tool state Changed **Yjs** — Make `DocumentStore.ydoc` private; enforce local origin whitelist with exhaustive mapper Changed **CI** — Shard E2E tests via reusable workflow; add merge-reports job; run spec-file coverage validator on every PR; remove size-limit bundle size check
60. [v0.10.8](https://github.com/JackUait/blok/releases/tag/v0.10.8) Patch Apr 13, 2026 Fixed **Table** — Normalize flat-array table child parents at every entry point Fixed **Data Model** — Recursively expand legacy nested toggleList/callout bodies
61. [v0.10.7](https://github.com/JackUait/blok/releases/tag/v0.10.7) Patch Apr 13, 2026 Fixed **Theme** — Prevent nested editor instances from overriding parent theme on prepare
62. [v0.10.6](https://github.com/JackUait/blok/releases/tag/v0.10.6) Patch Apr 12, 2026 Added **Config** — Replace `user.name` with `user.id` + `resolveUser` callback for multi-editor identity tracking Added **Keyboard** — Del shortcut for block delete; markdown shortcuts for quote (`"` + space) and code (``` + space) blocks Fixed **i18n** — Use Blok locale for date formatting with full month names; strip trailing abbreviation suffixes for ru/uk locales Fixed **Popover** — Display scroll haze instantly on open instead of fading in Changed **Deps** — Add lodash-es resolution to pin ^4.18.0
63. [v0.10.5](https://github.com/JackUait/blok/releases/tag/v0.10.5) Patch Apr 11, 2026 Added **Database** — DatabaseView rendering layer with kanban board DOM Fixed **i18n** — Localize hardcoded "Last edited" strings in block settings footer; add missing translations across 67 locales Fixed **Theme** — Expose theme API before `isReady` to prevent dark theme race condition Changed **Lint** — Resolve all 226 lint issues across source and test files Changed **CI** — Enable Corepack before setup-node to resolve Yarn version mismatch; remove dead version-check job Changed **Tests** — Resolve 119 failing tests across E2E, unit, and docs suites
64. [v0.10.4](https://github.com/JackUait/blok/releases/tag/v0.10.4) Patch Apr 11, 2026 Added **Database** — Kanban board view with drag-and-drop cards and columns, card drawer with nested editor, inline title editing, list view with collapsible sections, multi-view tabs with drag reorder, property-based data model, column controls, backend sync, and read-only mode Added **Copy block link** — `CopyLinkTune` block tune with Cmd+Ctrl+L shortcut and automatic scroll-to-block on URL hash load Added **Block edit metadata** — Track `lastEditedAt`/`lastEditedBy` on every block mutation with Yjs sync, saved output inclusion, and block settings footer display; new `user` config option Added **Popover** — Scroll haze indicators on popover lists Added **Shortcut keys** — Render shortcut keys as SVG icons with readable tooltip on hover Fixed **Inline tools** — Preserve trailing nbsp through format/unformat cycles; preserve trailing spaces when applying inline formatting; extend trailing-whitespace range detection; unwrap whitespace-only bold ancestors when un-bolding partial selection Fixed **Block** — Default `lastEditedAt` to `Date.now()` so footer always shows; preserve user-provided block IDs and deduplicate on render; validate block ID format in constructor Fixed **Paste** — Prevent new table block when pasting into table cell with lost focus; handle hsl/hsla color formats Fixed **Scroll to block** — Guard `decodeURIComponent` against malformed URL hash; encode block ID in URL hash Fixed **Theme** — Prevent nested editor from resetting parent theme
65. [v0.10.3](https://github.com/JackUait/blok/releases/tag/v0.10.3) Patch Apr 9, 2026 Fixed **Table** — Guard `addBlockToCell` and `setCellBlocks` against writing into covered (merged) cells; resolve paste target and copy source coordinates from model attributes instead of DOM visual position; fix overlay/pill missing and wrong merge/split button after rect expansion; expand selection rect to include full spans of merged cells; use logical cell coordinates in `getCellPosition`; don't intercept copy/cut when user has text selected in a single cell; `reindexCoordinates` assigns model coordinates instead of DOM physical indices; center row grip on merged cell using `getBoundingClientRect` Fixed **Toolbar** — Correct `marginLeft` for nested blocks and popover position when scrolled; restore focus to originally-typed block after plus+Escape Fixed **Toolbox** — Position popover at caret when inside nested blocks (toggle/callout) Fixed **Keyboard** — Prevent text-jumping by preserving focus on toolbar interactions
66. [v0.10.0](https://github.com/JackUait/blok/releases/tag/v0.10.0) Minor Apr 8, 2026 Added **Code block** — New `CodeTool` with syntax highlighting (via Shiki), line numbers toggle, language selector popover, copy button, wrap toggle, and preview tab for KaTeX/Mermaid rendering Added **Inline code** — New `InlineCodeTool` with CMD+E shortcut Added **Quote block** — Notion-style quote block with size options submenu Added **Divider block** — Horizontal rule block with `---` markdown shortcut Added **Callout block** — Callout block with emoji picker and skin tone persistence Added **Toggle list** — Collapsible toggle list block with drag & drop support inside toggles ([#46](https://github.com/JackUait/blok/pull/46), [#52](https://github.com/JackUait/blok/pull/52)) Added **Toggle headings** — Toggle heading blocks with markdown shortcuts (`>#`, `>##`, `>###`) and body placeholder Added **Marker inline tool** — Color text/background inline tool with color picker and dark mode support Added **Underline & Strikethrough** — New inline tools with CMD+U and CMD+SHIFT+S shortcuts Added **Table enhancements** — Cell color picker, cell placement picker, HTML `<table>` rendering, corner drag, Tab/Arrow escape from cells, and cross-table block protection ([#38](https://github.com/JackUait/blok/pull/38), [#45](https://github.com/JackUait/blok/pull/45), [#63](https://github.com/JackUait/blok/pull/63)) Added **Markdown import** — `importMarkdown()` API method and paste handler with GFM support including math (KaTeX) extensions Added **React adapter** — `useBlok` hook and `BlokContent` component for React integration Added **Read-only toggle** — Seamless in-place `readonly` mode toggle with scroll position preservation Added **Editor width API** — `editor.width` namespace with `WidthManager` module and `config.width` options Added **Content alignment** — `config.style.contentAlign` option for global block content alignment Added **Font family config** — `config.style.fontFamily` option for editor and popover typography Added **Theme API** — `ThemeAPI` module for programmatic dark/light theme control Added **Fuzzy toolbox search** — Ranked fuzzy search in slash menu with animated filtering Added **Toolbox plus button** — Opens blocks menu directly without inserting `/` Added **Link suggestion chip** — URL type detection chip in inline toolbar Added **Google Docs paste** — Expand `<details>` tags into toggle blocks with parent-child wiring Added **blok-cli package** — New `@jackuait/blok-cli` package with `convert` (HTML→JSON) and `convert-gdocs` commands Added **i18n search terms** — Multilingual toolbox search via `searchTermKeys` across all 68 locales Fixed **Drag & drop** — Toggle hierarchy, ghost preview, subtree depth preservation, and spring-load auto-expand for closed toggles Fixed **Toolbar** — Drag handle reachability, left-edge overflow, and actions not intercepting toggle arrow clicks Fixed **Inline toolbar** — Cross-block selection positioning, background element cleanup on close Fixed **Table** — Cross-table block stealing, undo/redo focus, cell selection border persistence, and arrow key navigation between blocks Fixed **Marker** — Partial selection color removal, dark theme palette, and active color display on toolbar button Fixed **Toggle** — Backspace/Delete boundary crossing, undo atomicity for Enter, children DOM nesting, and collapse in read-only mode Fixed **List** — Tab indent for multi-selected items, depth reduction cascade on outdent, and bullet marker pinning Fixed **Paste** — Table cell content appearing outside table, marker formatting preservation, and math formula detection
67. [v0.5.0](https://github.com/JackUait/blok/releases/tag/v0.5.0) Minor Jan 23, 2026 Added **CRDT-based undo/redo** — The undo/redo system now uses Conflict-Free Replicated Data Type principles for better conflict resolution and history tracking Fixed **toolbar hover behavior after cross-block selection** — The inline toolbar now resets its positioning state when extending selections across multiple blocks Fixed **PatternPasteEvent for internal cut/paste** — Internal cut and paste operations now emit PatternPasteEvent, so external code can react to all clipboard actions
68. [v0.4.1-beta.5](https://github.com/JackUait/blok/releases/tag/v0.4.1-beta.5) Patch Dec 7, 2025 Fixed **Tailwind CSS conflicts** — Fixed CSS conflicts that caused external plugins to break by isolating Tailwind's style precedence Added **data-blok-header-level attribute** — Headers in the formatting popover now include a `data-blok-header-level` attribute for styling and testing hooks
69. [v0.4.1-beta.3](https://github.com/JackUait/blok/releases/tag/v0.4.1-beta.3) Patch Dec 6, 2025 Added **undo/redo** — Added keyboard shortcuts (Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z) for editing history navigation
70. [v0.4.1-beta.0](https://github.com/JackUait/blok/releases/tag/v0.4.1-beta.0) Patch Dec 16, 2025 Added **RTL language support** — Added translations for Hebrew, Persian, Urdu, Yiddish, Pashto, Sindhi, Uyghur, Kurdish, and Dhivehi with right-to-left layout Added **Eastern European languages** — Added Czech, Romanian, and Hungarian translations Added **Southeast Asian languages** — Added Thai, Ukrainian, and Greek translations Added **South Asian languages** — Added Hindi, Bengali, Indonesian, and Vietnamese translations Added **Turkic languages** — Added Turkish and Azerbaijani translations Added **Arabic** — Added Arabic translation with RTL support Added **Northern European languages** — Added Dutch, Polish, and Swedish translations Added **Korean, Japanese, Italian, Portuguese, German, French, Spanish** — Added translations Added **Armenian, Chinese, Russian** — Added translations Added **rename checklist to to-do list** — Changed terminology from "checklist" to "to-do list" Added **drag & drop** — Rewrote the drag and drop system for smoother interactions Added **flat data model** — Changed from nested to flat structure using `parentId` and `contentIds` references Added **lists: flat data model** — List items now use the flat data structure Added **keyboard navigation** — Added keyboard shortcuts for editing without the mouse Added **list tools** — Added numbered lists, ordered (nested) lists, and to-do lists with checkboxes Added **paragraph tool: custom configuration** — The paragraph tool supports custom configuration for placeholder text and styling Added **header tool: custom configuration** — The header tool supports custom configuration for levels and placeholder text Added **navigation mode** — Added arrow key navigation through blocks, separate from text editing Added **UX improvements** — Focus management, cursor positioning, and block interactions Fixed **translation keys: camelCase** — Converted all translation keys to camelCase Fixed **translation key parsing** — Fixed nested translation key parsing Fixed **remove redundant translation keys** — Cleaned up duplicate and unused translation keys Fixed **fix Russian translation** — Corrected a missing word in the Russian translation Fixed **fake selection display** — Fixed how fake (visual-only) selections render Fixed **close inline toolbar on outside click** — The inline toolbar now closes when clicking outside the editor Fixed **toolbar centering** — Fixed toolbar positioning to stay centered regardless of content width
71. [v0.3.1-beta.0](https://github.com/JackUait/blok/releases/tag/v0.3.1-beta.0) Patch Dec 3, 2025 Changed **codemod improvements** — Better pattern matching and safer transformations for the Editor.js migration
72. [v0.3.0](https://github.com/JackUait/blok/releases/tag/v0.3.0) Minor Dec 2, 2025 Added **bundle paragraph and header tools** — These tools are now included by default in the core bundle
73. [v0.2.0](https://github.com/JackUait/blok/releases/tag/v0.2.0) Minor Dec 2, 2025 Added **drag & drop** — Block reordering via the block handle (☰) icon Fixed **remove debug logging** — Cleaned up console.log statements and resolved performance bottlenecks Changed **rebrand to Blok** — Updated logos, color schemes, and documentation
74. [v0.1.0](https://github.com/JackUait/blok/releases/tag/v0.1.0) Minor Nov 24, 2025 Changed **fork from Editor.js** — Blok forked from Editor.js, preserving the block-based editing architecture Changed **initial feature set** — Block management, inline formatting, slash toolbox, and plugin system
