Skip to content

feat: support header.level (1-4) on header block#68

Open
programad wants to merge 1 commit into
mainfrom
add-header-level
Open

feat: support header.level (1-4) on header block#68
programad wants to merge 1 commit into
mainfrom
add-header-level

Conversation

@programad
Copy link
Copy Markdown
Collaborator

@programad programad commented May 21, 2026

Summary

Adds support for the level field on the header block. The field is part of Slack's documented public schema as of the 2026-03-06 Block Kit refresh but was missing from this library, so headers all render at one size regardless of intended hierarchy.

From Slack's header block reference:

level | Integer | Optional. Set the level of the heading. Values 1-4 correspond to H1-H4 heading levels, respectively.

What changed

  • src/types/layout.ts — extend HeaderBlock with level?: 1 | 2 | 3 | 4 and JSDoc pointing at the Slack docs.
  • src/components/blocks/header.tsx — pick the semantic heading tag (<h1> / <h2> / <h3> / <h4>) from level and apply a per-level size class. When level is omitted, rendering is unchanged (<h3> + text-header / 18px), preserving back-compat with the pre-rollout single-size behavior.
  • KNOWLEDGE_BASE.md — chapter 4.1 mentions the new level prop.

Back-compat

  • level is optional. Existing usage (no level) renders identically to before — same <h3> tag, same text-header styling.
  • Setting level: 3 is intentionally equivalent to the legacy default so consumers can opt in incrementally.
  • Adds an opt-in data-header-level attribute on the heading element for consumers who want to style further.

Size class choices

I picked reasonable defaults:

level Tag Size class
1 <h1> text-[28px] leading-[1.2]
2 <h2> text-[22px] leading-[1.27]
3 <h3> text-header (18px) — matches legacy default
4 <h4> text-base (15px)
undefined <h3> text-header — legacy fallback

The library's existing fontSize tokens (text-header: 18px, text-base: 15px) cover H3 and H4. H1 and H2 use inline arbitrary values since the library didn't have heading-1/heading-2 tokens previously. Happy to switch to dedicated tokens (e.g., text-header-1, text-header-2) in tailwind.config.js if preferred — wanted to keep this PR minimal.

Testing

  • pnpm lint (tsc) — clean
  • pnpm build (tsup + postcss) — clean; built dist/index.d.ts includes the new level?: 1 | 2 | 3 | 4 field
  • Manual exercise via the existing test fixtures TBD by reviewer

Motivation

Apps syndicating rich content into Slack (e.g., a CMS pushing posts with multi-level headings) want their preview to match what Slack actually renders. Slack now distinguishes H1-H4 visually after the 2026-03-06 rollout, but this library still renders every header at the same size, so any preview built on it diverges from the real Slack message. This change closes that gap.

References

Adds the optional `level` field to `HeaderBlock` and renders the header
with the matching semantic h-tag (h1-h4) and a size class. `level` is
part of Slack's documented header schema as of the 2026-03-06 Block Kit
refresh and was missing from this library.

- `src/types/layout.ts` — add `level?: 1 | 2 | 3 | 4` with JSDoc pointing
  at the Slack docs and changelog.
- `src/components/blocks/header.tsx` — pick `<h1>`/`<h2>`/`<h3>`/`<h4>`
  from `level` and apply a per-level size class. When `level` is omitted,
  rendering is unchanged (`<h3>` + `text-header`/18px), preserving
  back-compat with the pre-rollout single-size behavior.
- `KNOWLEDGE_BASE.md` — chapter 4.1 mentions the new `level` prop.

Docs:
- https://docs.slack.dev/reference/block-kit/blocks/header-block
- https://docs.slack.dev/changelog/2026/03/06/block-kit-rich-text/
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.

1 participant