bigbullui logobigbullui
Componentnavigation

Heading

Semantic heading with level-based scale, optional mono eyebrow and per-level entrance animation.

Preview

Live Preview

Banner Edition

Main Heading

Sub Heading

Installation

Tokens guide →

Add to your project via CLI (zero dependencies, code you own):

npx bigbullui add heading

Or install the full npm package:

npm install bigbullui

Usage

import { Heading } from "@/components/ui/heading";

<Heading level={2} eyebrow="Section 01">Ticket sales open</Heading>

Source code

heading.tsx

Zero dependencies (only React + utils). Copy and paste directly into your project:

import * as React from "react";
import { cn } from "./lib/utils";

export interface HeadingProps {
  level?: 1 | 2 | 3 | 4 | 5 | 6;
  size?: "lg" | "md" | "sm";
  eyebrow?: string;
  className?: string;
  children: React.ReactNode;
}

const levelClasses: Record<1 | 2 | 3 | 4 | 5 | 6, string> = {
  1: "text-3xl font-extrabold tracking-tight",
  2: "text-2xl font-bold tracking-tight",
  3: "text-xl font-bold",
  4: "text-lg font-semibold",
  5: "text-base font-semibold",
  6: "text-sm font-semibold uppercase tracking-[0.15em]",
};

const sizeOverride: Record<"lg" | "md" | "sm", string> = {
  lg: "text-4xl md:text-5xl",
  md: "text-2xl",
  sm: "text-lg",
};

export function Heading({ level = 1, size, eyebrow, className, children }: HeadingProps) {
  const Tag = `h${level}` as const;

  return (
    <Tag
      className={cn(
        "font-mono uppercase text-foreground animate-[fade-in-up_0.3s_ease-out_both] motion-reduce:animate-none",
        levelClasses[level],
        size && sizeOverride[size],
        className
      )}
      style={{ animationDelay: `${(level - 1) * 12}ms` }}
    >
      {eyebrow && (
        <span className="mb-2 block font-mono text-[10px] font-bold uppercase tracking-[0.15em] text-muted-foreground animate-[stamp_0.4s_ease-out_both] motion-reduce:animate-none">
          {eyebrow}
        </span>
      )}
      {children}
    </Tag>
  );
}

Props

PropTypeDescription
level1 | 2 | 3 | 4 | 5 | 6Heading depth; drives size, weight and staggered entrance delay.
size"lg" | "md" | "sm"Optional size override with its own entrance animation.
eyebrowstringMono uppercase micro label rendered above the heading.
classNamestringAdditional classes merged onto the heading.
childrenReact.ReactNodeHeading text content.