component — display
Eyebrow
The Label role outside a form: mono, uppercase, tracked, fg-subtle — kickers above a headline, scene labels, timecodes and counts. Written lowercase in the source; CSS sets the caps.
- typography
- label
- kicker
- eyebrow
- caption
- brand
use a eyebrow when
- A kicker above a headline or a low title: "scene 01 — the studio".
- A count beside a section heading: "04 entries".
- A timecode or a short index: "00:01:24", "a", "b".
don't
- Never more than one line, and never a sentence — running text is Inter at body size.
- Not a form field's label. That is
Labelfrom Field, which is bound to its control. - Don't write it in capitals in the source; the utility sets the caps, and copy-paste and screen readers get what you wrote.
02 examples
Kickers, counts and timecodes
Written lowercase; the caps come from CSS. An em dash with spaces separates parts.
scene 01 — the studio
studio — issue 04
00:01:24
Beside a section heading
`as="span"` for a count that sits on the heading's baseline.
selected work
04 entrieswhat to use instead
by jobBy what the eyebrow was doing.
- Labelling a form control
- Field — Its `Label` wears the same type and is a real `<label>`.
source
eyebrow.tsxCopy this into your project. Resolve its dependencies from the registryDependencies in the component's API entry.
import { cn } from "@/lib/utils"
/**
* Eyebrow — quebi design system
*
* The Label role outside a form: mono, uppercase, tracked, always `fg-subtle`.
* Kickers above a headline, scene labels, timecodes, counts ("04 entries").
* A field's label is `Label` from `@/components/field`, which wears the same
* type but is a `<label>` bound to its control; this one labels nothing.
*
* Write it in lowercase in the source — the utility sets the caps, so the text
* a screen reader or a copy-paste gets stays lowercase. Use an em dash with
* spaces between parts ("scene 01 — the studio"). Never more than one line.
*/
type EyebrowElement = "p" | "span" | "div"
export interface EyebrowProps extends React.HTMLAttributes<HTMLElement> {
/** The element to render. `p` (default) for a kicker on its own line, `span` inline. */
as?: EyebrowElement
}
export function Eyebrow({ as: Element = "p", className, ...props }: EyebrowProps) {
return <Element data-slot="eyebrow" className={cn("quebi-eyebrow m-0", className)} {...props} />
}