Журнал изменений
Следите за каждым улучшением, исправлением и новой функцией в развитии Blok
- ИсправленоMarkdown — Typing a list marker (
-,1.) inside a heading no longer converts the heading into a list; it stays a heading. - ИсправленоEditor — Enter now honours the IME composition and Shift contract; added an
onErrorchannel;data-blok-toolis opt-in.ИсправленоSanitize — Redundant inline markup is now collapsed on every path that stores HTML.ИсправленоVideo — Unplayable sources are surfaced to the user instead of rendering a black player.ИсправленоView — Added aclassListfacade soMarkSpecinline tools render correctly inBlokView.Исправленоi18n — Localized video stats and database overflow, addedtr()interpolation, and completed locale audits across Yiddish, Vietnamese, Traditional and Simplified Chinese, Urdu, Ukrainian, Uyghur, Turkish, Thai, Telugu, Tamil, Swahili, Serbian, Albanian and Slovenian. Marks — New range-aware
api.marksinline-formatting engine, with the built-in bold/italic/underline/strikethrough tools migrated onto it. ExposesMarkSpecidentity/family/transparent semantics for authoring custom inline tools.ДобавленоMarks — New range-awareapi.marksinline-formatting engine, with the built-in bold/italic/underline/strikethrough tools migrated onto it. ExposesMarkSpecidentity/family/transparent semantics for authoring custom inline tools.ДобавленоView renderer — New synchronous, DOM-free view renderer published at@bloklabs/core/view(defineBlokSchema+ a central dispatcher, plus a ReactBlokView), for rendering stored block content without booting a full editor.Добавленоi18n — New runtimeeditor.i18n.update()API that makesconfig.i18nlive and repaints already-rendered block DOM, wired reactively through all three adapters.ДобавленоConfig — Reactive contract forreadOnly,hideToolbarandinlineToolbar: setting them after construction now takes effect live across the React, Vue and Angular adapters (with sanitize-cache invalidation oninlineToolbar).ДобавленоReadiness — Scoped, reactive editor readiness:whenAllReady({ within, settleOn }),readyState/subscribeReady, and auseBlokReadyhook in all three adapters.ДобавленоDocs — The documentation site is now crawlable (prerendered metadata, sitemap, AI mirrors) and carries Google Analytics coverage across pages.ДобавленоPlayground — Dev settings panel gains a language picker and an RTL toggle.ИсправленоMarks — Fixed the trailing-whitespace extension eating later content when a mark ended on a boundary.ИсправленоStyles — Surface background tokens (--blok-bg-light/-secondary/-tertiary) are now a test-enforced public contract; the gutter stays put in plain read-only soreadOnlyflips no longer shift layout.ИсправленоTypes —MarkSpecis now imported into the main declaration entry so it resolves for consumers.ИсправленоDocs — Russian pages are headed by their localized H1;@bloklabs/core/viewresolves in the docs build and React fixtures.ИсправленоRelease — The Angular README is now staged into the directory npm packs.Исправлено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.ИзмененоMigrated the docs site to React Router framework mode.ИзмененоRenamed the default branch frommastertomain.ИзмененоCompleted npm metadata across the package family and hardened the view/reactive-contract law tests.API — New public
editor.tokensgetter/setter for runtime--blok-*theme tokens, with replace semantics and pre-ready buffering (liketheme/width/placeholder). Wired reactively through all three adapters: Reactstyle.tokens, Vuestyle.tokens, Angular[styleTokens].--blok-content-max-widthis now honored by database centring and toolbar control placement.ДобавленоAPI — New publiceditor.tokensgetter/setter for runtime--blok-*theme tokens, with replace semantics and pre-ready buffering (liketheme/width/placeholder). Wired reactively through all three adapters: Reactstyle.tokens, Vuestyle.tokens, Angular[styleTokens].--blok-content-max-widthis now honored by database centring and toolbar control placement.Добавлено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; ReactcreateReactBlockaccepts aviewComponentrendered while the editor is read-only; React toolbox icons may be React elements;commit()echo idempotency is now a documented public contract.ДобавленоEmbed — Google Docs/Sheets/Slides/Forms/Drive embeds render at a user-adjustable pixel height with a bottom resize handle (200–2000px), persisted todata.height. Aspect-ratio media providers (YouTube, Vimeo, …) are unchanged.ИсправленоCDN bundles —dist/blok.iife.jsanddist/blok.umd.jsshipped 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.ИсправленоAdapters — Five root causes from a downstream audit: a stale controlled-dataecho no longer clobbers the caret (bounded echo window instead of last-payload-only dedup);equalsOutputDatacompares block ids only when both sides carry one; React inline tools accept atitleKeyfor localization; the zero-specificity gutter default is a test-enforced public contract.ИсправленоDependencies — Seven phantom dependencies (bare imports resolving only via hoisting, including@testing-library/jest-domused by the global unit setup) are now declared, with a law test preventing new ones.Исправленоi18n — Review passes completing Armenian, Croatian, Dhivehi, Filipino, Georgian, Gujarati, Hebrew, Hungarian, Indonesian, Japanese, Kannada and Khmer, plus tool interpolation variable forwarding.ИзмененоUpgraded to Node 26, Angular 22 and TypeScript 6, then root-caused six defects the upgrade shipped green — most importantly the entireunit-angularvitest project loading zero tests (a fake green), and the docs test suite missing the Node 26 webstorage guard.ИзмененоLocal E2E suite runtime cut from ~47.5 min to ~10 min (parallel/skip-when-freshbuild:test, shared page per worker), plus broad E2E stabilization.ИзмененоFixed ESLint cache poisoning that replayed stale errors in CI lint runs.- Добавлено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.ДобавленоAPI — Four first-class capabilities replacing host workarounds: a
style.nativeSelectionconfig opt-out for the forced::selectionrepaint, public--blok-block-padding-top/-bottom/-inlinetokens for compact read-only rendering, a staticBlok.whenAllReady()collective-readiness aggregate, andcreateReactInlineToolin the React adapter with a full inline-tooldestroy()lifecycle.ИсправленоData integrity — Three silent data-loss defects fixed: code containing<was corrupted on render and save (if (a<b)becameif (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 aPLAINTEXTsanitizer rule.Исправлено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.Исправленоi18n — Locale audit corrections across dozens of locales, including Dutch color labels and shared toggle guidance. - Добавлено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.ДобавленоTheming — Newstyle.tokensconfig 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),hideToolbarconfig now actually hides the toolbar and collapses the gutter, and--blok-placeholder-coloris a public hook.Добавлено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.Добавлено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.ДобавленоTable — Compact/comfortable text-size switch, grouped with density under a text-size submenu.ДобавленоHeader — Heading level converts are grouped under a heading submenu in block settings.ДобавленоImage — Overlay controls use discrete size tiers (full/medium/compact) instead of fluid scaling, keeping them legible at small widths.ДобавленоData compatibility — Editor.js-shaped data is accepted losslessly: null-tolerantLooseOutputDatainputs, publicequalsOutputData/isEmptyOutputDatautilities, echo-safeblocks.render()(re-rendering identical data is a no-op), and a synchronousisRenderedflag.Исправлено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.Исправлено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.ИсправленоAdapters/Core — Six consumer runtime workarounds root-caused and fixed in core, types, and adapters.ИсправленоUI — Inputs show a single focus indicator (no double border), and the popover search icon was removed.ИсправленоAccessibility — Move and duplicate announcements are count-neutral and carry correct totals; search results announcements keep their context.ИзмененоCI — Shorter critical path (parallel build start, faster lint), with contract tests enforcing the workflow shape.ИзмененоTests — Animation-frame APIs polyfilled for jsdom environments; extreme-position e2e sweeps guard menu placement at screen edges. - Исправленоi18n — Capitalized
toolNameskeys (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.Изменено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. - ДобавленоTheming — More host customization hooks: heading tokens (keyed off
data-blok-heading-level) and embed tokens, a--blok-list-gaptoken for list spacing, and palette tokens declared at zero specificity via:where()so host overrides always win.--blok-content-max-widthis now authoritative when the editor is inwidth: 'full'mode.ДобавленоRead-only — The editor wrapper is stamped withdata-blok-readonlyas a public styling hook, and the block-controls gutter auto-collapses in read-only mode so content uses the full column.ДобавленоAdapters — The three React-integration workarounds were removed by fixing their root causes in core.Исправленоi18n — Custom tool titles now localize viatoolNames.<toolName>dictionary keys.ИсправленоImage — GIF→video auto-conversion is skipped when no video tool is registered, instead of failing the upload.ИзмененоBuild —dist/output is now minified and JSON data is emitted asJSON.parsestrings, cutting published bundle weight.ИзмененоDocs — Documented the theming hooks,data-blok-readonlyattribute,contentAlign,toolbox: falsegating, the GIF guard, thereadOnlyobject form, andtoolNameskeys. - Добавлено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.ДобавленоReact — First-class block authoring:createReactBlockrenders 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 morecreateRootper block or context bridges. Every function in a tool's config (including nested ones likeuploader.uploadByFile) is now re-bound to the latest render's closure, so inline closures work without freezing identities or recreating the editor.Исправлено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.Исправлено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 atmax-width: 100%.Исправлено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.Изменено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/corespecifiers in every shipped file (previously react/vuetypes/index.d.tsstill referenced the npm scope, breaking consumertscon GHP-only installs). - Добавлено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
fullpreset. Images with an explicitly savedsizeare unaffected.Исправлено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. Media — Playback speed and loop preferences now persist across audio and video blocks. They are stored in
localStorageunder 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.ДобавленоMedia — Playback speed and loop preferences now persist across audio and video blocks. They are stored inlocalStorageunder 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.ИсправленоQuote — Saving a quote block no longer stripshref/target/relfrom 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.Исправлено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.Исправлено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.Исправлено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.ИзмененоCI — The build artifact now ships the extractedpackages/*/distadapter bundles alongsidedist/, fixing downstream unit and E2E jobs;yarn.lockwas synced to the^1.1.1core peer range.ИзмененоDocs — README and the docs site updated for the@bloklabs/*package family; the rename notice was subsequently dropped from the README.- Изменено`@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 apackageExtensionsworkaround) no longer applies. Delete that.yarnrc.ymlentry after upgrading.ИзмененоAdapters declare hard, accurate peers: each requires its framework plus@bloklabs/coreat the matching version.ИзмененоGitHub Packages mirrors:@dodopizza/blokremains the core mirror; adapters mirror as@dodopizza/blok-react,@dodopizza/blok-vue,@dodopizza/blok-angular; the CLI stays@dodopizza/blok-cli.ИзмененоMigration: the bundled codemod (npx -p @bloklabs/core migrate-from-editorjs) now also rewrites legacy@jackuait/*import specifiers andpackage.jsondependency keys to the new names. 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
uploadByUrlbackend, with a Drive-specific error message when none is configured. The error state gets a styled callout with a retry button.Добавлено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'suploadByUrlbackend, with a Drive-specific error message when none is configured. The error state gets a styled callout with a retry button.ДобавленоRead-only —readOnlynow accepts an object form:{ hideControls: true }enables read-only mode and suppresses the toolbar, block settings, and inline toolbar. Exposed viaisControlsHidden, normalized across the React, Vue, and Angular adapters, andReadOnlyModeConfigis exported from the types root.ДобавленоImage —compress: { format: 'avif' }now produces real AVIF via WebCodecs when the canvas encoder cannot, and a newfallbackFormatoption (e.g.'webp') covers browsers with no AV1 encoder instead of silently uploading the original bytes.Исправлено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.Исправлено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).Исправлено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).ИсправленоPopover — Nested popovers no longer collapse to their padding in WebKit; the marker color picker rendered as a 12px sliver in Safari.Исправлено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 everydocument.bodymount.Исправлено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.Изменено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.ИзмененоTests — Adversarial table undo probes (merge undo, insert undo/redo), tooltip click-transparency lifecycle guards, and an exhaustive swatch hit-test sweep.Header — Toggle headings are now offered at all six levels, staying in sync 1:1 with regular headings.
ДобавленоHeader — Toggle headings are now offered at all six levels, staying in sync 1:1 with regular headings.Исправлено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.Исправлено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.ИсправленоStyles — Injected utilities are scoped so a host application's CSS reset can't flatten the editor.ИзмененоMigration — Single-sourceLEGACY_GRAMMARshared 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.Изменено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).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.
Добавлено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.Добавлено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.ДобавленоToolbar —Cmd/Ctrl+Slashopens the block menu in read-only mode.Исправлено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.ИсправленоColumns — Stranded resize separators left behind by removing a column no longer render as a phantom column.ИсправленоCore — Never Tab-indent a block into a tool-owned container.ИсправленоToolbox — Keep plus-button blocks on a table out of its cells, and anchor fuzzy search at word boundaries.ИсправленоSelection — Stop hijacking intra-line text drags inside table cells.ИсправленоEmbed — Validate stored URLs at render time (stored-XSS guard).ИсправленоList — Keep bullet markers non-editable so Enter never ghosts an item.Исправлено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.ИсправленоTunes — Hide the copy-link shortcut hint in read-only mode.ИсправленоStyles — RightcontentAlignno longer collapses into centering, and preflight resets are scoped to@layer baseso Blok's own utilities win.ИсправленоReact — Guard against staledistexports and aStrictModereadiness race.- ДобавленоHeader — Opt-in
anchorIdsconfig derives stable heading anchor ids from heading text.ИсправленоLink — Pad the edit-menu input wrapper so the focus ring isn't clipped, and enlarge the remove-link (trash) icon.ИзмененоCI — Fetch mirror tags before pushing to avoid creating over an existing tag. - ДобавленоLink — New
link.transformconfig, a superset oftransformHref: consumers can set per-anchorhref/target/relplus 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_selfrule) and extra attributes never clobber the managedhref/target/rel.Исправлено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.Исправлено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.Исправлено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. - Исправлено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 rawsrc/implementation, producing spurious errors about unresolvedmicromark-util-types/@types/mdast(TS2307) and implicitany(TS7006). The publictypes/*.d.tssurface is now self-contained and no longer re-exports fromsrc/.ИзмененоTypes — Mechanically enforce that no publishedtypes/*.d.tsre-exports or imports fromsrc/, and generate the self-contained icon declarations from source (scripts/generate-icons-dts.mjs). Vue — New first-class
@jackuait/blok/vueadapter:BlokEditorcomponent,useBlok, andprovideBlok, pluscreateVueBlock/useBlocksfor authoring custom blocks and driving the block tree from Vue. Custom Vue blocks support read-only in-place toggling.ДобавленоVue — New first-class@jackuait/blok/vueadapter:BlokEditorcomponent,useBlok, andprovideBlok, pluscreateVueBlock/useBlocksfor authoring custom blocks and driving the block tree from Vue. Custom Vue blocks support read-only in-place toggling.ДобавленоAngular — New first-class@jackuait/blok/angularadapter shipped as an Angular Package Format build (ng-packagr): the editor component/directive, a block portal registry, theBLOK_BLOCK_CONTEXTrender-context token,createAngularBlockauthoring, and the reactiveinjectBlocksblock-tree API.ДобавленоReact — NewuseBlockshook 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, atomicinsertTreefor nested subtrees, and additiveinsertMarkdown. Block-creation semantics are hardened across hierarchy edges with compile-time drift guards against the core API.ДобавленоAdapters — Closed React/Vue/Angular parity gaps across component paths and escape hatches; shared one blocks-api core so Vue'suseBlocksreaches React parity, and extracted sharedfillDefaults/PropSchemahelpers. Custom-block authoring is now first-class on the public API surface.Добавлено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 modalDialog, keyboard reachability for toolbars/menus/radios/rename, and assistive-tech feedback parity across selection, drag, menus, and arrival.Добавлено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.ДобавленоBlocks — StructuralparentIdnesting: 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.ДобавленоKeyboard —Cmd+Left/Cmd+Rightnavigate between blocks at block edges;Backspaceat the start of a nested block removes one indent level; mixed-listTabindents both kinds; and numerous Notion-parityTab/arrow/Delete/Backspace fixes.ДобавленоPaste — Paste-without-formatting (Cmd/Ctrl+Shift+V); recovery of buildin/Notion toggles and soft breaks from lossy GFM HTML fallback.Добавлено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.ДобавленоPopover — Custom cross-platform scrollbar that hides the classic OS bar while keeping a stable gutter; reel-like edge distortion replacing the scroll haze.ДобавленоConvert — SharedbuildConvertMenuEntrieswithtitleKeyresolution, used by both block settings and the inline "Turn into" menu (which now lists the full text family), guarded by parity E2E.ДобавленоImage — Configurable auto-retry on image load failure (default 5).Исправлено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.Исправлено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.ИсправленоText/Header — Fixed 30+ Notion-parity bugs by root cause (slash+space, duplicate pulse, indent toolbar, caret offset preservation on turn-into, and more).ИсправленоTable — Preserve merged cells and lists when pasting external tables, and keep list markup when copying cells out to external apps.Исправлено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.Исправлено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 toolmoved()hook onsetBlockParent; never write split text into a mutation-free decoration.ИсправленоColumns — Match Notion's inter-column gutter spacing; restore DOM order when undoing column creation.Исправлено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.ИсправленоSelection — Fake highlight matches the native selection color and stays visible while a menu input is focused;Cmd+Acontainer-scoped staging.ИсправленоMarker — Reset<mark>background so colored text never shows the browser's yellow highlight.ИсправленоToggle — Arrow container stays a constant 28px square and pins to the first line for multi-line toggle/heading.Исправлено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.ИзмененоPaste — Mechanically enforce the paste attribute law and the paste stamp law via architecture tests.ИзмененоTests — Repaired all CI-matrix E2E shards; added regression coverage across list keyboard shortcuts, columns undo order, popover scrollbar spec, and adapter integration/e2e.ИзмененоLint — Resolved all 69 root ESLint problems at the root cause.- ДобавленоCore — The
linkconfig ({ 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 viablocks.render()) and<a>arriving through the clipboard now get the configuredtarget/relforced andtransformHrefapplied 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,transformHrefmust be idempotent.ДобавленоCore — NewonBeforeRender(blocks) => blocksconfig transforms the blocks array before every render (the initial render and eachblocks.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.ДобавленоCore — NewonAfterRender(api)config fires after a render completes and the blocks are in the DOM (initial render and everyblocks.render()), for post-render side effects such as scroll restoration — distinct from the once-onlyonReady.ДобавленоCore — A stabledata-blok-renderedattribute (exposed asDATA_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 existingblocks:renderedevent.ДобавленоBlock Tunes — A custom tune'srender(context)now receives an optionalBlockTuneRenderContextwhosegetPopoverElement()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 viaclosest(...). The element resolves once the popover mounts (it isnullsynchronously duringrender()).ДобавленоReact —<BlokEditor>/useBloknow acceptonBeforeRenderandonAfterRender. Both are attached only when provided and are ref-stable, so updating the callbacks never recreates the editor. - ДобавленоCore — New
onSave(data, api)config delivers the full serializedOutputData(debounced via the existing change-batch window) whenever content changes — the "output half" of a controlled editor. Pair it with thedataconfig to mirror editor state into your own store with a single callback instead of callingsaver.save()by hand. Only user-driven changes trigger it; programmaticrender()does not (the change observer is disabled during render), so a controlled round-trip won't recurse. Available to all consumers, not just React.ДобавленоReact —<BlokEditor>/useBloknow acceptonSave, making<BlokEditor data={data} onSave={setData} />a true controlled component to pair with the reactivedataprop from 0.23.3. The callback is ref-stable (never recreates the editor) and attached only when provided. Echoing the payload straight back viaonSave={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 externaldatachanges still render in place. - ДобавленоReact — The
<BlokEditor>/useBlokdataprop is now reactive: passing new content re-renders the editor in place viaeditor.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.ДобавленоCore — New typed render events:blocks:rendered(payload{ count }) fires when a batch finishes rendering, andblock:rendered(payload{ blockId }) fires per block. The runtime event-name constantsBlocksRendered/BlockRenderedare exported, so consumers can react to rendering instead of polling the DOM. The publicEventsAPI is now typed against an event/payload map while still accepting arbitrary string events.ДобавленоCore — Newlinkconfig ({ 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.ДобавленоPaste — NewonBeforePaste(html) => string | nullconfig hook transforms (or drops) raw clipboard HTML before Blok preprocessing; returningnullfalls back to plain-text paste.ДобавленоAPI — Neweditor.tools.update(name, config)shallow-merges a tool's config in place — e.g. swap an uploader — without recreating the editor.ИзмененоTests — Exported stableTEST_IDconstants (plus button, settings toggler, block wrapper) wired into the editor chrome viadata-blok-testid, so consumers no longer query internal selectors. - ИзмененоDocs — Documented two React-adapter caveats.
<BlokEditor>must not be wrapped instyled()or any HOC that reserves thethemeprop: styled-components claimsthemefor its ownThemeProvider, so it never reaches the editor and theme sync silently breaks — render it directly and style the container viaclassName. Anddepsvalues 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 theBlokEditor/useBlokJSDoc and published type declarations. - ДобавленоCore — A new
editor.placeholderruntime API (get/set) lets consumers read and change the empty-paragraph placeholder on a live editor, mirroring the existingwidthAPI. Updates apply to existing blocks and to blocks created afterwards.ДобавленоReact —<BlokEditor>now accepts a reactiveplaceholderprop (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. 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 uncontrolleddataseed, and reactively syncsreadOnly,autofocus,theme, andwidthprops without recreating the editor. ItsonReadycallback fires after the ref commits, so consumers can safely callref.currentfrom inside it. The lower-leveluseBlokhook plusBlokContentremain available as an escape hatch.Добавлено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 uncontrolleddataseed, and reactively syncsreadOnly,autofocus,theme, andwidthprops without recreating the editor. ItsonReadycallback fires after the ref commits, so consumers can safely callref.currentfrom inside it. The lower-leveluseBlokhook plusBlokContentremain available as an escape hatch.ИзмененоReact —useBloknow reactively syncsthemeandwidthprop changes to the editor instance, mirroring the existingreadOnly/autofocuspattern.ИзмененоDocs — The demo wrapper now dogfoodsBlokEditor, and the README React section documents the recommendedBlokEditorpath, the uncontrolleddatacontract, reactive props, and theuseBlok+BlokContentescape hatch.ИзмененоTests — Added e2e coverage for save-via-ref and live prop toggles, a published-vs-source type-drift guard, anddata-blok-testid-based locators.Paste — Content copied from buildin.ai now imports as native Blok blocks at full fidelity. buildin's clipboard carries a lossless
text/next-space-blocksJSON 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.)ДобавленоPaste — Content copied from buildin.ai now imports as native Blok blocks at full fidelity. buildin's clipboard carries a losslesstext/next-space-blocksJSON 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.)Исправлено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 asdata.textwas 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 Britishgrey, 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).- Добавлено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.ИзмененоMedia — Deduped
MediaSourceinto a single shared type across the media tools.ИзмененоDocs — Documented the audio block tool, and added upload-only and link-only empty states to the playground gallery. Tests — Added regression coverage for HTML-over-Markdown routing, document-order preservation, internal-reference rescue, pasted audio titles, and date-glyph handling.
Исправлено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.Исправлено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.ИсправленоPaste — Pasted external Notion audio now shows its title (the player readsdata.title, which was left blank), and a malformed inline date annotation no longer leaks the raw "‣" placeholder glyph.ИзмененоTests — Added regression coverage for HTML-over-Markdown routing, document-order preservation, internal-reference rescue, pasted audio titles, and date-glyph handling.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.
Добавлено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.Добавлено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.Исправлено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.ИсправленоTable — Pinned the top toolbar anchor flush to the table edge.Изменено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.- ИзмененоTypes —
OutputBlockData'sdatafield is now typedRecord<string, unknown>instead ofany(matchingBlockToolDataandSavedData). Reading a property off a saved block'sdata— e.g. onsave()output — now yieldsunknownrather thanany, so code that indexes intoblock.datamay need a cast or type guard. This is a type-only change with no runtime effect.ИсправленоTypes — Published.d.tsdeclarations are now self-contained and no longer re-export rawsrc/*.ts. A bareimport { Blok } from '@jackuait/blok'previously dragged editor source into the consumer's TypeScript program (throughtooltipandpopover→flipper), surfacing internal type errors under strict consumer flags such asnoUncheckedIndexedAccess. Thetooltipandpopoverdeclarations now inline their public types, so consuming the package no longer type-checks Blok's internals. (The opt-in/markdownsubpath is unchanged.)ИсправленоTypes — The published declarations are now internally consistent underskipLibCheck: false. Fixed an incorrectBlockToolDataimport path in thedatabase/header/listtool declarations (which also produced spurious "incorrectly extendsBlockTool" errors), added a missingInlineToolConstructable/InlineToolConstructorOptionsimport in the type entry, and removed phantomDictionary/DictValuere-exports.ИзмененоDependencies — MovednanoidtodevDependencies; it is bundled into every dist artifact and was never a runtime external. - ДобавленоTypes —
isReadynow resolves with the fully-initializedBlokinstance (wasPromise<void>), soconst editor = await blok.isReadyyields a ready, fully-typed editor without a cast. New exportedPendingBloktype describes the surface available synchronously afternew Blok()and beforeisReadyresolves (isReady,destroy,theme,width) — type a reference held during that window asPendingBlokinstead of widening toPartial<Blok>, then awaitisReadyto narrow it to the full API.new Blok()still returns the fullBlok, so existing usage is unaffected. Width — New public
widthAPI on the editor instance:instance.width.get(),set('full' | 'narrow'), andtoggle()switch the content layout between'narrow'(the default, constrained to--max-width-content) and'full'(the contentmax-widthis removed so it fills its container). It mirrors thethemeAPI, including buffering aset()call made before the editor is ready and replaying it once the editor is initialized.ДобавленоWidth — New publicwidthAPI on the editor instance:instance.width.get(),set('full' | 'narrow'), andtoggle()switch the content layout between'narrow'(the default, constrained to--max-width-content) and'full'(the contentmax-widthis removed so it fills its container). It mirrors thethemeAPI, including buffering aset()call made before the editor is ready and replaying it once the editor is initialized.ИсправленоTypes — Declare thehistoryAPI on the exportedBlokinstance type.history(clear(),undo()/redo(),canUndo()/canRedo()) was already available at runtime; consumers no longer need to cast the instance to reach it.Audio — New native Audio block tool. Now-playing card with cover art (lazy
music-metadataextraction), 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.ДобавленоAudio — New native Audio block tool. Now-playing card with cover art (lazymusic-metadataextraction), 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.Добавлено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 existingtypesconfig, which now accepts both exact MIME types (image/png) and family wildcards (image/*).ИсправленоTypes — ExportFile,Audio, andVideo(and their data/config/uploader types) and add thefile/audio/videokeys todefaultBlockToolsfrom the@jackuait/blok/toolstypes entry. The runtime already exported these tools; consumers no longer need a local ambient type shim to import them.Изменено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.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.Добавлено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.ДобавленоVideo — Custom fullscreen surface with a top caption bar, a "Hide controls" tune for a control-free player, and GIF-style autoplay/loop tunes.ДобавленоImage — Auto-convert dropped, pasted and remote-URL GIFs into a looping Video block via WebCodecs + webm-muxer, gated by theconvertGifToVideoconfig (default on); the original GIF is kept on CORS failure, with a "Converting…" label shown during conversion.ДобавленоMedia — 30MB default upload limit with per-typemaxSizeconfiguration and human-readable too-large errors.Исправлено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.Исправлено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.ИсправленоVideo — Exit theater mode reliably on Escape via a capture-phase listener with a smooth deferred dismiss, and drive the scrubber fill withrequestAnimationFramefor smooth playback tracking.ИзмененоBuild — Movewebm-muxerto devDependencies so it is bundled rather than treated as an external runtime dependency.ИзмененоREADME — Replace the logo with the optimized noodle mascot.ИзмененоPlayground — Use real self-hosted videos in the block-states gallery.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.
Добавлено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.ДобавленоEmbed — Generic embed: frame arbitrary URLs through a gated resolver, offered in the paste menu behind thelinkPaste.allowGenericEmbedflag with anapi.configaccessor. Replace the source via an empty-state URL bar and an overlay more-menu item.ДобавленоMigration — Complete Editor.js block-type coverage plus a drop-in UMD build; adapt legacy Editor.js inline tools andlinkTooldata.Добавлено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.Исправлено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.ИсправленоFile — Unbreak pptx preview; vertically center the preview modal; stop wrong-colour strips and toggle flicker during preview transitions; blockjavascript:URLs in download hrefs.ИсправленоBuild — Make the published install self-contained (shipsrc, keep markdown and nanoid as runtime deps) so bundlephobia can build; green the self-contained-install and css-token audits.ИзмененоRefactor — Extract table visual-subsystem orchestration intoTableSubsystems; splitBlockOperationsinto focused worker classes; share the media uploader empty state across the image and file tools.ИзмененоCode — Cover every Prism token in both the light and dark themes.ИзмененоLint — Resolve all lint errors by root cause and mute advisory-only rules.ИзмененоDocs — Refresh the README tool list and entry points; add a File block tool reference entry.- ИсправленоTypes — Declare
EmbedandBookmark(and theirdefaultBlockToolsentries) in the published@jackuait/blok/toolstypes. The runtime exported them in 0.15.0 but the.d.tsdid not, soimport { Embed, Bookmark }failed to typecheck. 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.
Добавлено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.Добавлено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.ДобавленоBookmark — Notion-parity bookmark card with a dev unfurl endpoint; crawler-UA retry recovers metadata from bot-blocked sites.ДобавленоPlayground — Smooth cross-fade theme switching via View Transitions, plus an Airbnb-style neutral redesign.Исправлено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.ИсправленоDrag & Drop — FLIP-animate the column drop moment and slim the vertical drop bar to read like the horizontal line.ИсправленоSecurity — Harden URL-scheme filtering and neutralize XSS gaps in markdown paste, the inline link tool, and the paste/render pipeline.ИсправленоTools — ImplementsetReadOnlyon embed, bookmark and column tools so read-only toggles in place without a full re-render.Исправлено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.Исправлено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).ИзмененоDependencies — Resolve all 52 open Dependabot alerts; bump brace-expansion, ws, smol-toml.ИзмененоTests — Embed/bookmark/link stories with screenshot baselines, wave-2 embed visual-regression baselines, verified real sample URLs replacing fixtures, refreshedmain.cssgolden snapshot.ИзмененоDocs & Playground — Embed, bookmark and link entries in tools data and the editor demo.- ДобавленоTools — Register the Columns tool with a single
Columnsgroup key. Tool-group "provides" manifests expand into their underlying block tools duringprepare(), so consumers add one key instead of wiring each block.ИсправленоTools — ExportColumnsfrom public types for single-key registration; keepdefaultBlockToolssettings-only so the group key forwards settings without re-registering. 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.
Добавлено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.ДобавленоColumns — "Turn into columns" command wraps a multi-block selection into a column layout, available from the Convert-to menu.ДобавленоColumns — Hover-revealed resize separators between columns: drag to resize, keyboard-resizable with ARIA slider semantics, double-click a divider to equalize widths.ДобавленоColumns — Horizontal arrow keys traverse between sibling columns; new columns animate in Notion-style.ДобавленоInline Toolbar — Appears instantly on selection release, no animation delay.ИсправленоInline Toolbar — Removed entry animation that delayed appearance.Измененоi18n — Column resize aria-labels and turn-into-columns strings across all locales.ИзмененоCI — Repair unit tests, e2e merge, and mirror push on master; mirror push works for both branch and tag events.ИзмененоTests — Exhaustive block-in-column compatibility suite, live-drag lifecycle specs for every block type, multi-select block-settings header i18n regression.ИзмененоPlayground — Columns example in the editor demo and block-states gallery.- ИсправленоRead-Only — Collapse the empty bottom click-to-add zone to 0px in read-only mode and restore the configured min-height when editing
- Добавлено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)ДобавленоCodemod — Default migrated images to
size: 'full'and inherit the stretched flag into migrated image sizeДобавленоBlock Link — Highlight pulse on hash-link arrivalДобавленоRead-Only — Show copy-link menu on block hoverДобавленоPlayground — Add loading image state demo in block-states galleryИсправленоImage — Force full width and compact overlay for short images; reuse looping-arrows glyph for replace iconИсправленоPaste — Keep Google Docs images inside tables and stop double-bolding headings; prevent default page background collapsing to gray presetИсправленоTable — Recover migrated cell text detached by a pre-fix saveИсправленоToolbar — Align plus/drag handle with content lane for stretched blocksИсправленоBlock Settings — Anchor popover to trigger instead of (0,0); translate popover context labelИсправленоDatabase — Center block toolbar on the title lineИзмененоi18n — Translate strings identical to English across 25 localesИзмененоLint — Resolve all ESLint and tsc problemsИзмененоImage — Move inline upload-failed SVG to icons moduleИзмененоTests — Cover migrated cell content surviving load→save round-trip; fix CSS guard test failures from image loading shimmer 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
Добавлено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Добавлено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ДобавленоFonts — Bundle @fontsource fonts via generator script; newfontFamilySans/Serif/Mono/Handwritingconfig fields with CSS variable injection;font-display: swapfor body textДобавлено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ДобавленоToolbar — Hide plus and dots buttons while toolbox is open; place block settings popover left of the dots buttonДобавленоToolbox — Nowrap pill with tighter radius and unified plus/slash search stylingДобавленоPlayground — Icon gallery lightbox; block states gallery tab; settings panel shortcuts; hide header on scroll; logotype image exampleДобавленоCSS Variables — Tokenize radii, spacing, icon sizes, border widths, z-index ladder, duration/easing, typography; extract directrgbaliterals to palette tokens; migrate@applyarbitrary hex values; splitactions-icon/dividervars; add audit test and visual regression baselinesДобавленоDatabase — Match Notion card shadow and radius on kanban cards; showcase all 10 column color variantsДобавленоBlock Settings — Add shortcut keys to i18n with regression testsДобавленоIcons — Migrate inline SVGs to shared icon layerИсправленоInline Toolbar — Tighten item padding and radius; suppress toolbar inside code blocks; apply symmetric top/bottom paddingИсправлено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; supportcontenteditable="plaintext-only"and preserve view mode on undo; correct syntax highlighting offset calculationИсправлено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ИсправленоPopover — Distinguish synthesized hover from real hover; hide context label while searching; keep block settings menu visible and attached to dots triggerИсправленоBlock Manager — Skip cross-container auto-heal inside move groupИсправленоTooltip — Anchor wrapper withposition: fixedto survive page scroll; render above popover and survive UA stylesheetИсправленоFonts — Add error handling for font load failuresИзмененоStyles — Splitmain.cssinto 11 concern-filesИзмененоLicense — Add fork attribution and NOTICE fileИзмененоBuild — Replace shiki with prismjsИзмененоTests — Fix 60+ unit + E2E failures across the suite; add Prism integration test for all highlightable languagesИзмененоChore — Untrack.vscode; remove stale root files; add favicon to dev playground; drop.editorconfig- ДобавленоBundles — Ship CJS (
require()) and IIFE (<script>tag / CDN) bundles alongside ESM; add"main","browser","unpkg", and"jsdelivr"fields topackage.jsonИзмененоREADME — Add installation section documenting ESM, CJS, and CDN usage - ДобавленоToggle — Gray arrow icon when toggle body is emptyИсправлено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ИсправленоHierarchy — Reject dangling parentId at universal chokepoint; reconcile remote Yjs reparents; close remaining container drift vectors; exempt Yjs remote sync from dangling parent throwИсправленоPaste — Inherit container parent on replace-insert and x-blok root paste; harden container paste ejection across all container block typesИсправленоCallout — Restore plus button and drag handle; stop paste from ejecting children via stale contentIds; prevent Enter from inserting new block inside calloutИсправленоUndo — Collapse multi-block paste and alt-drag duplicate into one undo group; eliminate spurious entries from metadata-only writesИсправленоToolbar — Keep drag handle visible when editing inside table cellИсправленоInsert — Universally protect all Enter paths from nested-block leakИсправленоTable — Tighten list item spacing inside table cellsИсправленоYjs — Map 'no-capture' origin to local to prevent mid-op sync clobbering tool stateИзмененоYjs — Make
DocumentStore.ydocprivate; enforce local origin whitelist with exhaustive mapperИзменено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 - ИсправленоTable — Normalize flat-array table child parents at every entry pointИсправленоData Model — Recursively expand legacy nested toggleList/callout bodies
- ИсправленоTheme — Prevent nested editor instances from overriding parent theme on prepare
- ДобавленоConfig — Replace
user.namewithuser.id+resolveUsercallback for multi-editor identity trackingДобавленоKeyboard — Del shortcut for block delete; markdown shortcuts for quote ("+ space) and code (``` + space) blocksИсправленоi18n — Use Blok locale for date formatting with full month names; strip trailing abbreviation suffixes for ru/uk localesИсправленоPopover — Display scroll haze instantly on open instead of fading inИзмененоDeps — Add lodash-es resolution to pin ^4.18.0 - ДобавленоDatabase — DatabaseView rendering layer with kanban board DOMИсправленоi18n — Localize hardcoded "Last edited" strings in block settings footer; add missing translations across 67 localesИсправленоTheme — Expose theme API before
isReadyto prevent dark theme race conditionИзмененоLint — Resolve all 226 lint issues across source and test filesИзмененоCI — Enable Corepack before setup-node to resolve Yarn version mismatch; remove dead version-check jobИзмененоTests — Resolve 119 failing tests across E2E, unit, and docs suites - Добавлено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ДобавленоCopy block link —
CopyLinkTuneblock tune with Cmd+Ctrl+L shortcut and automatic scroll-to-block on URL hash loadДобавленоBlock edit metadata — TracklastEditedAt/lastEditedByon every block mutation with Yjs sync, saved output inclusion, and block settings footer display; newuserconfig optionДобавленоPopover — Scroll haze indicators on popover listsДобавленоShortcut keys — Render shortcut keys as SVG icons with readable tooltip on hoverИсправлено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ИсправленоBlock — DefaultlastEditedAttoDate.now()so footer always shows; preserve user-provided block IDs and deduplicate on render; validate block ID format in constructorИсправленоPaste — Prevent new table block when pasting into table cell with lost focus; handle hsl/hsla color formatsИсправленоScroll to block — GuarddecodeURIComponentagainst malformed URL hash; encode block ID in URL hashИсправленоTheme — Prevent nested editor from resetting parent theme - ИсправленоTable — Guard
addBlockToCellandsetCellBlocksagainst 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 ingetCellPosition; don't intercept copy/cut when user has text selected in a single cell;reindexCoordinatesassigns model coordinates instead of DOM physical indices; center row grip on merged cell usinggetBoundingClientRectИсправленоToolbar — CorrectmarginLeftfor nested blocks and popover position when scrolled; restore focus to originally-typed block after plus+EscapeИсправленоToolbox — Position popover at caret when inside nested blocks (toggle/callout)ИсправленоKeyboard — Prevent text-jumping by preserving focus on toolbar interactions Code block — New
CodeToolwith syntax highlighting (via Shiki), line numbers toggle, language selector popover, copy button, wrap toggle, and preview tab for KaTeX/Mermaid renderingДобавленоCode block — NewCodeToolwith syntax highlighting (via Shiki), line numbers toggle, language selector popover, copy button, wrap toggle, and preview tab for KaTeX/Mermaid renderingДобавленоInline code — NewInlineCodeToolwith CMD+E shortcutДобавленоQuote block — Notion-style quote block with size options submenuДобавленоDivider block — Horizontal rule block with---markdown shortcutДобавленоCallout block — Callout block with emoji picker and skin tone persistenceДобавлено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))ДобавленоToggle headings — Toggle heading blocks with markdown shortcuts (>#,>##,>###) and body placeholderДобавленоMarker inline tool — Color text/background inline tool with color picker and dark mode supportДобавленоUnderline & Strikethrough — New inline tools with CMD+U and CMD+SHIFT+S shortcutsДобавлено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))ДобавленоMarkdown import —importMarkdown()API method and paste handler with GFM support including math (KaTeX) extensionsДобавленоReact adapter —useBlokhook andBlokContentcomponent for React integrationДобавленоRead-only toggle — Seamless in-placereadonlymode toggle with scroll position preservationДобавленоEditor width API —editor.widthnamespace withWidthManagermodule andconfig.widthoptionsДобавленоContent alignment —config.style.contentAlignoption for global block content alignmentДобавленоFont family config —config.style.fontFamilyoption for editor and popover typographyДобавленоTheme API —ThemeAPImodule for programmatic dark/light theme controlДобавленоFuzzy toolbox search — Ranked fuzzy search in slash menu with animated filteringДобавленоToolbox plus button — Opens blocks menu directly without inserting/ДобавленоLink suggestion chip — URL type detection chip in inline toolbarДобавленоGoogle Docs paste — Expand<details>tags into toggle blocks with parent-child wiringДобавленоblok-cli package — New@jackuait/blok-clipackage withconvert(HTML→JSON) andconvert-gdocscommandsДобавленоi18n search terms — Multilingual toolbox search viasearchTermKeysacross all 68 localesИсправленоDrag & drop — Toggle hierarchy, ghost preview, subtree depth preservation, and spring-load auto-expand for closed togglesИсправленоToolbar — Drag handle reachability, left-edge overflow, and actions not intercepting toggle arrow clicksИсправленоInline toolbar — Cross-block selection positioning, background element cleanup on closeИсправленоTable — Cross-table block stealing, undo/redo focus, cell selection border persistence, and arrow key navigation between blocksИсправленоMarker — Partial selection color removal, dark theme palette, and active color display on toolbar buttonИсправленоToggle — Backspace/Delete boundary crossing, undo atomicity for Enter, children DOM nesting, and collapse in read-only modeИсправленоList — Tab indent for multi-selected items, depth reduction cascade on outdent, and bullet marker pinningИсправленоPaste — Table cell content appearing outside table, marker formatting preservation, and math formula detectionCRDT-based undo/redo — The undo/redo system now uses Conflict-Free Replicated Data Type principles for better conflict resolution and history tracking
ДобавленоCRDT-based undo/redo — The undo/redo system now uses Conflict-Free Replicated Data Type principles for better conflict resolution and history trackingИсправленоtoolbar hover behavior after cross-block selection — The inline toolbar now resets its positioning state when extending selections across multiple blocksИсправленоPatternPasteEvent for internal cut/paste — Internal cut and paste operations now emit PatternPasteEvent, so external code can react to all clipboard actions- ИсправленоTailwind CSS conflicts — Fixed CSS conflicts that caused external plugins to break by isolating Tailwind's style precedenceДобавленоdata-blok-header-level attribute — Headers in the formatting popover now include a
data-blok-header-levelattribute for styling and testing hooks - Добавленоundo/redo — Added keyboard shortcuts (Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z) for editing history navigation
- ДобавленоRTL language support — Added translations for Hebrew, Persian, Urdu, Yiddish, Pashto, Sindhi, Uyghur, Kurdish, and Dhivehi with right-to-left layoutДобавленоEastern European languages — Added Czech, Romanian, and Hungarian translationsДобавленоSoutheast Asian languages — Added Thai, Ukrainian, and Greek translationsДобавленоSouth Asian languages — Added Hindi, Bengali, Indonesian, and Vietnamese translationsДобавленоTurkic languages — Added Turkish and Azerbaijani translationsДобавленоArabic — Added Arabic translation with RTL supportДобавленоNorthern European languages — Added Dutch, Polish, and Swedish translationsДобавленоKorean, Japanese, Italian, Portuguese, German, French, Spanish — Added translationsДобавленоArmenian, Chinese, Russian — Added translationsДобавленоrename checklist to to-do list — Changed terminology from "checklist" to "to-do list"Добавленоdrag & drop — Rewrote the drag and drop system for smoother interactionsДобавленоflat data model — Changed from nested to flat structure using
parentIdandcontentIdsreferencesДобавленоlists: flat data model — List items now use the flat data structureДобавленоkeyboard navigation — Added keyboard shortcuts for editing without the mouseДобавленоlist tools — Added numbered lists, ordered (nested) lists, and to-do lists with checkboxesДобавленоparagraph tool: custom configuration — The paragraph tool supports custom configuration for placeholder text and stylingДобавленоheader tool: custom configuration — The header tool supports custom configuration for levels and placeholder textДобавленоnavigation mode — Added arrow key navigation through blocks, separate from text editingДобавленоUX improvements — Focus management, cursor positioning, and block interactionsИсправленоtranslation keys: camelCase — Converted all translation keys to camelCaseИсправленоtranslation key parsing — Fixed nested translation key parsingИсправленоremove redundant translation keys — Cleaned up duplicate and unused translation keysИсправленоfix Russian translation — Corrected a missing word in the Russian translationИсправленоfake selection display — Fixed how fake (visual-only) selections renderИсправленоclose inline toolbar on outside click — The inline toolbar now closes when clicking outside the editorИсправленоtoolbar centering — Fixed toolbar positioning to stay centered regardless of content width - Измененоcodemod improvements — Better pattern matching and safer transformations for the Editor.js migration
bundle paragraph and header tools — These tools are now included by default in the core bundle
Добавленоbundle paragraph and header tools — These tools are now included by default in the core bundledrag & drop — Block reordering via the block handle (☰) icon
Добавленоdrag & drop — Block reordering via the block handle (☰) iconИсправленоremove debug logging — Cleaned up console.log statements and resolved performance bottlenecksИзмененоrebrand to Blok — Updated logos, color schemes, and documentationfork from Editor.js — Blok forked from Editor.js, preserving the block-based editing architecture
Измененоfork from Editor.js — Blok forked from Editor.js, preserving the block-based editing architectureИзмененоinitial feature set — Block management, inline formatting, slash toolbox, and plugin system