Skip to content

cms-admin: Allow restricting selectable heading levels in TipTap rich text block - #6223

Draft
VPS-Andreas wants to merge 3 commits into
mainfrom
tiptap-heading-levels
Draft

cms-admin: Allow restricting selectable heading levels in TipTap rich text block#6223
VPS-Andreas wants to merge 3 commits into
mainfrom
tiptap-heading-levels

Conversation

@VPS-Andreas

Copy link
Copy Markdown

Summary

  • Add a new headingLevels?: number[] option to createTipTapRichTextBlock to restrict which heading levels (1-6) are selectable in the toolbar dropdown, markdown input rules, and keyboard shortcuts. Defaults to [1, 2, 3, 4, 5, 6], so existing usages are unaffected.
  • Validate headingLevels at block-creation time (non-empty, unique integers 1-6) so a typo fails fast instead of producing an invalid heading tag at runtime.

Needed for an upcoming Headline block migration to TipTap, which should only offer H2-H4 (no H1/H5/H6), matching the previous Draft.js implementation.

Test plan

  • pnpm run lint:fix passes
  • tsc --noEmit passes
  • New Storybook stories: HeadingLevels (dropdown restricted to H2-H4, keyboard shortcut for a disallowed level is blocked, combined with textBlockStyles to cover the code path the Headline block actually uses) and InvalidHeadingLevels (invalid configs throw)
  • Added changeset (@dextinity/cms-admin, minor)

Supersedes #6222, which was closed because its feature/-prefixed branch is protected against direct pushes and couldn't take a follow-up commit.

🤖 Generated with Claude Code

Consumers previously had no way to restrict which heading levels (H1-H6)
are selectable in the TipTap-based rich text editor, since the level
choice depends on TipTap's own StarterKit/Heading defaults. The new
headingLevels option lets a factory consumer (e.g. a Headline block)
narrow this down generically instead of hard-coding it per block.
@VPS-Andreas
VPS-Andreas requested a review from nsams August 20, 2026 13:41
@VPS-Andreas VPS-Andreas self-assigned this Aug 20, 2026
@VPS-Andreas
VPS-Andreas marked this pull request as draft August 20, 2026 13:41
@github-actions
github-actions Bot requested a review from VPS-Obi August 20, 2026 13:42
A typo such as [0, 2, 3] would otherwise reach TipTap's Heading
extension unchecked and produce an invalid <h0> tag in
TextBlockStyleHeadingView, since node.attrs.level is used directly to
build the HTML tag name. Throw early instead when headingLevels is
empty, contains duplicates, or contains a value outside 1-6.
@VPS-Andreas
VPS-Andreas force-pushed the tiptap-heading-levels branch from a1e213f to 07163ec Compare August 20, 2026 13:53
Mirrors the admin-side headingLevels option: restricts which heading
levels the schema allows via the same TipTap Heading `levels`
extension option, and rejects stored content with a disallowed
heading level during validation (via IsTipTapContent and
isValidTipTapContentSync), consistent with how maxTextBlocks and
listLevelMax are already enforced server-side rather than trusting
client-only validation.
Comment thread packages/api/cms-api/src/blocks/tipTap/createTipTapRichTextBlock.ts
@nsams

nsams commented Aug 21, 2026

Copy link
Copy Markdown
Member

Lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants