Components

Title

The heading atom. Four sizes, all semibold, all mapped to type-scale tokens: small (text-sm), default (text-base), medium (text-xl), large (text-2xl). Two optional icon slots — left for the subject or a back control, right for a quiet help affordance.

Updated Jul 30, 2026 by Juan Pablo Turina

Anatomy

Payment methods

  1. 1
    Left icon slot

    Optional. The subject icon of the section, or a back control on a detail page. Rendered text-muted-foreground, 16px.

  2. 2
    Text

    The heading itself: font-semibold text-foreground, sentence case. The only element in foreground — it carries the weight. Truncates with min-w-0 so a long title never pushes the icons out of the row.

  3. 3
    Right icon slot

    Optional. Quiet help affordance, almost always an Info wrapped in a Tooltip. Same text-muted-foreground, 16px as the left slot.

  4. 4
    Row

    flex items-center with a frame that never changes: gap-3 (12px) between the text and either icon, icons shrink-0 and locked at 16px, and no padding of its own so the leading edge is flush.

Sizes

Four steps, one weight. Every size is font-semibold and uses a Tailwind scale token, never a px value: small = text-sm (14/20), default = text-base (16/24), medium = text-xl (20/28), large = text-2xl (24/32). tracking-tight kicks in from medium up, per the typography foundation. Only the type scale moves — gap and icon size are identical at every step, so the four sizes stay one family instead of four lookalikes. Pick the size by how much page the title governs, and pick the tag with `as` by document outline: two separate decisions.

Payment methods

size="small"·text-sm·14 / 20·font-semibold

Payment methods

size="default"·text-base·16 / 24·font-semibold

Payment methods

size="medium"·text-xl·20 / 28·font-semibold

Payment methods

size="large"·text-2xl·24 / 32·font-semibold
<Title size="small"   icon={<ArrowLeft weight="light" />} iconRight={<Info weight="light" />}>Payment methods</Title>
<Title size="default" icon={<ArrowLeft weight="light" />} iconRight={<Info weight="light" />}>Payment methods</Title>
<Title size="medium"  icon={<ArrowLeft weight="light" />} iconRight={<Info weight="light" />}>Payment methods</Title>
<Title size="large"   icon={<ArrowLeft weight="light" />} iconRight={<Info weight="light" />}>Payment methods</Title>

Icon slots

Both slots take any ReactNode and lock it to 16px through the slot wrapper ([&_svg]:size-4), at every size. That means a bare Phosphor icon and a button wrapping one land on the same grid, and a large title doesn't drag oversized icons with it. Both slots render text-muted-foreground: the text is the only thing in foreground, so the icons frame the title instead of competing with it. An interactive slot (a back button) can lift to text-foreground on hover.

Payment methods

Payment methods

Payment methods

Payment methods

{/* Both slots */}
<Title size="medium" icon={<ArrowLeft weight="light" />} iconRight={<Info weight="light" />}>
  Payment methods
</Title>

{/* Left only */}
<Title size="medium" icon={<ArrowLeft weight="light" />}>Payment methods</Title>

{/* Right only */}
<Title size="medium" iconRight={<Info weight="light" />}>Payment methods</Title>

{/* No icons */}
<Title size="medium">Payment methods</Title>

No padding of its own

Title never adds padding around itself. Its text sits flush against the leading edge, so inside a card it lines up with the card title, the description and the fields below it instead of floating 8px in. Spacing between a Title and its siblings is the container's job: the CardHeader gap, a Separator, a flex gap. A heading that carries its own margin silently breaks the alignment of every layout it lands in.

Connection settings

Retry policy

Up to 3 attempts over 24 hours.

Capture mode

Automatic on authorization.

{/* Flush: the Title, the description and the next block share one axis */}
<Card>
  <CardHeader>
    <Title size="default" as="h3">Connection settings</Title>
  </CardHeader>
  <CardContent className="flex flex-col gap-4">
    <div className="flex flex-col gap-1">
      <Title size="small" as="h4" iconRight={<Info weight="light" />}>Retry policy</Title>
      <p className="text-sm text-muted-foreground">Up to 3 attempts over 24 hours.</p>
    </div>
  </CardContent>
</Card>
Size is not hierarchy
`size` controls type scale only; `as` controls the document outline. A large visual title inside a modal can still be an h2. Never pick a bigger size just to get an h1, and never skip heading levels to get a smaller size.

Recipes

Ready-to-copy compositions covering the most common Yuno usages of this atom.

Page title with back navigation

Detail pages: large size, back arrow on the left, Info on the right. The arrow is a real button inside the slot, so it is focusable and announced; the Info is decorative and paired with a Tooltip.

Credit card

Configure how this payment method behaves at checkout.

<Title
  size="large"
  as="h1"
  icon={
    <button
      type="button"
      aria-label="Back to payment methods"
      className="flex items-center rounded-md transition-colors hover:text-foreground"
    >
      <ArrowLeft weight="light" />
    </button>
  }
  iconRight={
    <Tooltip>
      <TooltipTrigger asChild>
        <span tabIndex={0}><Info weight="light" aria-hidden="true" /></span>
      </TooltipTrigger>
      <TooltipContent>How this method is charged and settled.</TooltipContent>
    </Tooltip>
  }
>
  Credit card
</Title>
Section divider

medium size to break a long page into named blocks. The Info explains what the section covers without spending a description line.

Routing rules

Section content goes here.

<Title size="medium" as="h2" iconRight={<Info weight="light" />}>
  Routing rules
</Title>
<Separator className="my-4" />
Card title

default size — the same step CardTitle uses, so a Title with icons drops into a CardHeader without changing the rhythm.

Authorization rate

Last 30 days across all connections.
92.4%
<Card>
  <CardHeader>
    <Title size="default" as="h3" iconRight={<Info weight="light" />}>
      Authorization rate
    </Title>
    <CardDescription>Last 30 days across all connections.</CardDescription>
  </CardHeader>
  <CardContent>…</CardContent>
</Card>
Dense label inside a card

small size for the sub-blocks of a card or panel, where the card already owns the default-size title. This is a heading, not a form Label — use Label when there's a control to point at.

Connection settings

Retry policy

Up to 3 attempts over 24 hours.

Capture mode

Automatic on authorization.

<Title size="small" as="h4" iconRight={<Info weight="light" />}>
  Retry policy
</Title>

Import

Copy this import line at the top of the file where you compose this atom.

TitleSize is also exported for typing your own wrappers.
import { Title } from "@/components/ui/title";

Props

Everything else from the underlying HTML or Radix primitive is forwarded via ...props.

PropTypeDefaultDescription
size"small" | "default" | "medium" | "large""default"Type scale step. small = text-sm (14), default = text-base (16), medium = text-xl (20), large = text-2xl (24). All four are font-semibold; medium and large add tracking-tight. Only the text scales — gap-3 (12px) and 16px icons are constant at every size.
as"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div""h2"The tag rendered. Pick it by document outline, not by size. Use div when the heading is purely decorative or already announced by a parent (DialogTitle, CardTitle).
iconReact.ReactNodeLeft slot. Subject icon or a back control. Rendered text-muted-foreground and locked to 16px by the slot ([&_svg]:size-4). Pass a real <button> when it navigates.
iconRightReact.ReactNodeRight slot. Quiet help affordance, almost always Info + Tooltip. Same text-muted-foreground, 16px. Not for primary actions.
classNamestringMerged last. Use it for layout (w-full, justify-between), not to override size, weight, or to add padding — Title stays flush by design and spacing belongs to the container.
...propsReact.HTMLAttributes<HTMLHeadingElement>Everything else forwards to the heading element (id, onClick, aria-*). title is omitted to avoid clashing with the HTML attribute.

When to use

  • Naming a page, a section, a card, or a block inside a card.
  • Any heading that needs a subject icon or a help affordance next to it.
  • Detail pages that open with a back control before the title.
  • Anywhere you were about to write text-xl font-semibold by hand.

When not to use

  • Form-field captions — that's Label, which wires htmlFor to a control.
  • The top of a standard page — use the PageHeader organism, it already composes the title.
  • Body copy or descriptions — Title is semibold by definition, never use it for a paragraph.
  • Table column headers — use the Table primitive's <th>.
  • As a button — if the whole row is clickable, that's an Accordion trigger or a link, not a Title.

Usage

Do
  • Pick size by scope (page > section > card > block) and `as` by outline.
  • Keep titles sentence case, like every other section title at Yuno.
  • Wrap the right Info in a Tooltip, and mark it aria-hidden when the Tooltip already carries the text.
  • Put a real <button> in the left slot when it navigates back — the slot sizes it for you.
Don't
  • Don't override the size with a text-* class — add a step here instead of inventing one per screen.
  • Don't drop the weight to font-medium — a Title is semibold, that's what separates it from a Label.
  • Don't put actions in a Title. The right slot is help-only (Info + Tooltip): no buttons, no menus, no links, no collapse chevrons. Actions live in the page header, the card footer or a toolbar.
  • Don't stack two Titles of the same size to fake a title + description — use CardDescription or a muted paragraph.

Related

Cross-links to atoms and patterns you may reach for next.

  • CardCardTitle is the same default step. Use Title inside a CardHeader when the card title needs icons.
  • Page headerThe full page-top organism (eyebrow + title + description + actions). Use it instead of a bare Title at the top of a page.
  • LabelFor form-field captions. A Label points at a control; a Title names a region.
  • TooltipWhat the right Info slot is almost always wrapped in.
  • TypographyThe scale and the four weights these sizes come from.