Heading

Semantic heading (h1–h6) with theme-overridable font-family, weight, and size design tokens. Install Heading from the VLLNT UI registry with the shadcn CLI.

Report a bug

Semantic heading (h1–h6) with theme-overridable font-family, weight, and size design tokens. Part of the core family in VLLNT UI, it ships as a machine-readable registry entry — copy the source directly into your app with the shadcn CLI and own it, no runtime dependency on a component library.

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Installation

Add Heading to your project with the shadcn CLI. The source lands in your codebase, ready to adapt:

pnpm dlx shadcn@latest add https://ui.vllnt.ai/r/heading.json

Source

import { cn } from "../../lib/utils"; /** Heading level 1–6. Drives both the semantic element and the scale step. */ export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6; /** Props for {@link Heading}. */ export type HeadingProps = React.HTMLAttributes<HTMLHeadingElement> & { /** Semantic rank — renders `h1`–`h6`, plus its scale step unless `size` overrides it. */ level?: HeadingLevel; ref?: React.Ref<HTMLHeadingElement>; /** * Visual scale step, decoupled from the semantic `level`. Defaults to `level`. * Use it to keep a correct document outline while matching a design — e.g. * `<Heading level={2} size={1}>` is an `h2` rendered at h1 size. */ size?: HeadingLevel; }; const headingTag = { 1: "h1", 2: "h2", 3: "h3", 4: "h4", 5: "h5", 6: "h6", } as const; const headingSize = { 1: "text-[length:var(--font-size-h1)] leading-[var(--line-height-h1)]", 2: "text-[length:var(--font-size-h2)] leading-[var(--line-height-h2)]", 3: "text-[length:var(--font-size-h3)] leading-[var(--line-height-h3)]", 4: "text-[length:var(--font-size-h4)] leading-[var(--line-height-h4)]", 5: "text-[length:var(--font-size-h5)] leading-[var(--line-height-h5)]", 6: "text-[length:var(--font-size-h6)] leading-[var(--line-height-h6)]", } as const; const headingBase = "font-[family-name:var(--font-display)] [font-weight:var(--font-weight-heading)] text-balance tracking-tight text-foreground"; /** * Semantic heading that reads its font family, weight, and size from * theme-overridable design tokens (`--font-display`, `--font-weight-heading`, * `--font-size-h{n}`). `level` sets the element (`h1`–`h6`); `size` overrides * the visual scale step (defaults to `level`), so a brand restyles every heading * by overriding tokens — no fork. * * @example * <Heading level={1}>Page title</Heading> * @example * <Heading level={2} size={1}>An h2 sized like an h1</Heading> */ const Heading = ({ className, level = 2, ref, size, ...props }: HeadingProps) => { const Tag = headingTag[level]; return ( <Tag className={cn(headingBase, headingSize[size ?? level], className)} ref={ref} {...props} /> ); }; Heading.displayName = "Heading"; export { Heading };

Stories

Explore every variant and state in the interactive Storybook:

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Dependencies

  • @vllnt/ui@^0.3.0