docs / patterns / section-label

SectionLabel

a heading row that names a region: a mono index, a title, an accent hairline, and a trailing aside. add a description and it becomes a full section header.

intensity · structuresrsc · server

provenance

shaped from personal-website

layer

core / patterns

intensity

structures · organizes a region, stays out of the content

composition

at the top of every major page region, index counting upaside carries the region's one metadata fact, like a countnot a page title. it labels a section, PageHeader opens the pagenever stack two without content between them

a11y

the title is a real h2 heading · the hairline is aria-hiddenjest-axe
label row
01

Selected work

6 projects
02

Writing

Now

2026
section header
03

About

est. 2024

with a description the label grows into a section header. the row keeps its rhythm and the lede stays muted below it.

props

proptypedefaultnotes
indexstringmono, glowing accent index before the title (e.g. 01).
titleReactNodethe section title, rendered as an h2.
asideReactNodetrailing content after the hairline (e.g. a count).
descriptionReactNodea lede below the row. turns the label into a section header.
tone"accent" | "accent-alt""accent"the index color. accent glows, accent-alt does not.

get it

npx shadcn add https://usva.build/r/section-label.jsoncopy
source · components/ui/section-label.tsxexactly what this command copiescopy
import * as React from "react";
import { cn } from "@/lib/utils";

export type SectionLabelTone = "accent" | "accent-alt";

export interface SectionLabelProps
  extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
  index?: string;
  title: React.ReactNode;
  aside?: React.ReactNode;
  /** Optional lede below the label row. Turns the label into a section header. */
  description?: React.ReactNode;
  tone?: SectionLabelTone;
}

const indexTone: Record<SectionLabelTone, string> = {
  accent: "text-accent [filter:drop-shadow(var(--usva-glow-accent-strong))]",
  "accent-alt": "text-accent-alt",
};

export const SectionLabel = React.forwardRef<HTMLDivElement, SectionLabelProps>(
  (
    { className, index, title, aside, description, tone = "accent", ...props },
    ref,
  ) => {
    const row = (
      <div className="flex items-center gap-3.5">
        {index != null && (
          <span
            className={cn(
              "font-mono text-[0.7rem] font-medium uppercase leading-none tracking-[0.2em] tabular-nums",
              indexTone[tone],
            )}
          >
            {index}
          </span>
        )}
        <h2 className="text-balance text-sm font-medium lowercase leading-none tracking-[0.01em] text-ink">
          {title}
        </h2>
        <span aria-hidden="true" className="hairline-accent h-px flex-1" />
        {aside != null && (
          <span className="shrink-0 font-mono text-[0.7rem] leading-none tabular-nums text-muted">
            {aside}
          </span>
        )}
      </div>
    );

    if (description == null) {
      return (
        <div ref={ref} className={className} {...props}>
          {row}
        </div>
      );
    }

    return (
      <div
        ref={ref}
        className={cn("flex flex-col gap-3", className)}
        {...props}
      >
        {row}
        <p className="max-w-prose text-pretty text-sm leading-relaxed text-muted">
          {description}
        </p>
      </div>
    );
  },
);
SectionLabel.displayName = "SectionLabel";