Skip to content

Releases

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 15:14
dbca83b

Page tree operations (@slash-editor/core, @slash-editor/react):

  • Optional PageStore.setTrashed(ids, trashed) and PageStore.move(id, { parentId, index }). Trash/restore pages and re-parent or reorder them. The library never calls them; they are the contract for your page-tree UI and for onSubPagesDetached/onSubPagesAttached. listChildren is now documented as returning siblings in order (trashed included), which usePageTree renders as-is. move's index counts among listChildren(parentId) without the moved page, clamped; moving a page into itself or a descendant is a no-op.
  • The registry createDemoPageStore implements both and persists sibling order.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 15:06
aa7718a

Emoji and highlighted code blocks move to their own entries (@slash-editor/core, @slash-editor/react):

  • Breaking: @slash-editor/core/emoji and @slash-editor/core/code-block subpaths. Emoji, emoji, searchEmojis and the EmojiItem/EmojiMenuState/EmojiMenuStorage/EmojiOptions types now import from @slash-editor/core/emoji; CodeBlock, codeBlock and the CodeBlockOptions/Lowlight types from @slash-editor/core/code-block. The root entry no longer exports them.
  • Breaking: createBlockKit takes the built node. emoji and codeBlock accept the extension instead of its options (codeBlock still accepts false for no code block), so the kit never imports the emoji dataset or lowlight. createBlockKit() drops from ~323 KB to ~198 KB gzipped (minified browser bundle, dependencies included) when neither is used.
  • "sideEffects": false in both packages, so bundlers can drop unused modules.

Migration:

// Before
import { CodeBlock, createBlockKit } from "@slash-editor/core";

createBlockKit({ emoji: { limit: 24 }, codeBlock: { lowlight } });
createBlockKit({ codeBlock: false, extend: [CodeBlock.extend({ addNodeView })] });

// After
import { createBlockKit } from "@slash-editor/core";
import { CodeBlock, codeBlock } from "@slash-editor/core/code-block";
import { emoji } from "@slash-editor/core/emoji";

createBlockKit({ emoji: emoji({ limit: 24 }), codeBlock: codeBlock({ lowlight }) });
createBlockKit({ codeBlock: CodeBlock.extend({ addNodeView }) });

Media upload result mapping and display URLs (@slash-editor/core, @slash-editor/react):

  • toAttrs option on image, file, and video. Maps the adapter's full upload result onto node attrs (default { src: result.url }) on the first success and on every retry, merged over the existing attrs — persist a server's canonical name/size/mime or id without reimplementing retryImage/retryFile/retryVideo. Also reachable through createBlockKit({ image | file | video: { toAttrs } }).
  • Display-only resolveSrc option on image, file, video, and embed (embed receives its stored url). Rewrites the URL a node view displays — signed URLs, files behind auth — while getHTML(), markdown, and JSON keep the canonical stored value. New ResolveSrc and UploadToAttrs types.
  • useResolvedSrc(src, node, resolveSrc) hook: sync results on the same render, async results once settled (stale results for a changed src are discarded), errors fall back to the stored URL. The registry node-views image/file/video/embed views apply it.

starterKit option on createBlockKit. Options are forwarded to Tiptap's StarterKit, so createBlockKit({ starterKit: { underline: false } }) drops the underline mark (and Mod-u / ++text++ markdown) without reconfiguring the returned extension by hand. Keys the kit owns (heading, undoRedo, link, codeBlock, blockquote, gapcursor) are excluded from the BlockKitStarterKitOptions type; use headingLevels, history, link, and codeBlock for those.

Keep the block handle inside the hover zone. BlockDrag now measures gutterWidth from the hovered block's left edge (or the editor box, whichever is further left) and defaults it to the new BLOCK_GUTTER_WIDTH (80px), which the registry BlockHandle lays itself out in — so the handle no longer vanishes on the way to it in an editor with little or no left padding. The geometry is exported as the pure resolveHoverRect.

unsetComment(threadId) now removes the thread's anchors across the whole document instead of only the selection (new pure removeCommentThread helper), so useComments().removeAnchor works from a sidebar; it no longer focuses the editor.

Markdown import reads a mention or page link that starts a line as inline content. Such a paragraph (including one holding only the mention, or a list item, blockquote or callout line starting with one) used to import as literal comment text or be dropped entirely, so serializeMarkdown output with a leading mention did not round-trip.

Bind Mod-k to openLinkEditor, matching the bubble toolbar's advertised ⌘K. The key falls through when there is nothing to link; change or remove it with linkEditor: { shortcut: "…" | false }.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 12:36
dc75644

Syntax-highlighted code blocks (@slash-editor/core):

  • codeBlock option. createBlockKit({ codeBlock: {} }) swaps StarterKit's plain code block for @tiptap/extension-code-block-lowlight under the same codeBlock name, so block types, slash items, and markdown are unchanged. Opt-in; pass lowlight to choose grammars (default: lowlight's common set). codeBlock: false leaves it to a CodeBlock.extend(...) via extend.
  • CodeBlock / codeBlock() exports, plus the code-block-node-view registry item: a language selector and hljs-* token CSS themed from shadcn tokens.

Emoji picker (@slash-editor/core, @slash-editor/react):

  • emoji extension. Wraps @tiptap/extension-emoji (MIT) with a :-triggered picker that exposes the same subscribe/state shape as mention. :shortcode: input and paste rules, unicode-to-node conversion, and markdown (:shortcode:, unknown shortcodes stay text) are included. Opt-in: createBlockKit({ emoji: {} }).
  • /emoji slash item. Shown only while the node is registered; types the : that opens the picker.
  • useEmoji hook and emoji-menu registry item. Command-in-Popover surface that follows the mention-menu pattern. Included in slash-editor-kit.

Localization (@slash-editor/core, @slash-editor/react):

  • messages option on createBlockKit. Overrides slash item, block type, and AI action text by id (title, description, aliases, keywords), slash menu group headings, the slash hint, empty-block placeholders, block menu titles, and bubble toolbar labels. Partial translations keep English for everything left out; the existing slash.hint and placeholder.text options still win.
  • localizeItems, localizeBlockMenuItems, localizeBubbleToolbarItems helpers, the messages extension, and editor.storage.messages.
  • useBlockMenu returns translated titles. The registry block-handle and bubble-toolbar now read block types from useBlockTypes so translated titles reach their menus.
  • Pages and uploads. untitledPage and uploadFailed messages; pageTitle, pages and withPageMentions take an optional untitled argument. /page and /link to page are translated through items/groups.

Pages (@slash-editor/core, @slash-editor/react):

  • subPage block and pageLink inline node. Each carries only a pageId; titles, icons and the tree live in a host-owned PageStore. Opt-in: createBlockKit({ pages: { store, currentPageId, onNavigate } }). Adds /page and /link to page, and merges page results into the @ menu (MentionItem.kind: "page").
  • Detach/attach reporting. onSubPagesDetached/onSubPagesAttached report local deletes, undo and paste; moves and remote edits stay silent. Duplicating or pasting a sub-page owned elsewhere becomes a pageLink.
  • Helpers. collectPageRefs, getPagesOptions, pageTitle, a nodeViews option for UI layers, and markdown export/import of both nodes.
  • React hooks. usePage, usePageTree, useBreadcrumb and useBacklinks read a PageStore with no editor.

v0.5.1

Choose a tag to compare

@buiducnhat buiducnhat released this 30 Sep 03:41

Notion-style block editor for React: a headless Tiptap v3 core, React hooks, and a shadcn registry UI you own. MIT end to end.

Fixes

  • SSR-safe @slash-editor/react. Importing the package no longer throws DOMRect is not defined during SSR/prerender.
  • Self-contained registry installs. shadcn add @slash-editor/slash-editor-kit now works in an app that never ran shadcn init: popover/dropdown-menu declare @base-ui/react and cn.

New

bun add @slash-editor/core @slash-editor/react
bunx --bun shadcn@latest add @slash-editor/slash-editor-kit

Playground: https://slasheditor.dev/playground · Docs: https://slasheditor.dev/docs