Text
Headings, running text and feedback messages. The intent decides the element (<h1>, <p>, <span>, <pre>) and the look.
Other components
Examples
A page title
A kicker names the section, the page heading is the one <h1>, and the lead introduces the page.
Settings
Notifications
Choose what we email you about, and how often.
<Layout intent="layout.group">
<Text intent="heading.kicker">Settings</Text>
<Text intent="heading.page">Notifications</Text>
<Text intent="text.lead">Choose what we email you about, and how often.</Text>
</Layout>An item and its facts
Facts about one thing go in text.meta, side by side in a layout.meta.
Quarterly report
Revenue grew in every region, led by new customers in the north.
<Layout intent="layout.group">
<Text intent="heading.item">Quarterly report</Text>
<Layout intent="layout.meta">
<Text intent="text.meta">PDF</Text>
<Text intent="text.meta">2.4 MB</Text>
<Text intent="text.meta">Updated 3 days ago</Text>
</Layout>
<Text intent="text.excerpt">Revenue grew in every region, led by new customers in the north.</Text>
</Layout>Messages
feedback.* intents are announced to screen readers: errors at once, the rest politely.
Your changes were saved.
That address is already taken.
<Layout intent="layout.group">
<Text intent="feedback.success">Your changes were saved.</Text>
<Text intent="feedback.error">That address is already taken.</Text>
</Layout>Figures
A headline number is text.stat; the words that name it are text.label.
12
Projects4
Members2.1 GB
Storage<Layout intent="layout.collection" className="grid-cols-3">
<Layout intent="layout.group">
<Text intent="text.stat">12</Text>
<Text intent="text.label">Projects</Text>
</Layout>
<Layout intent="layout.group">
<Text intent="text.stat">4</Text>
<Text intent="text.label">Members</Text>
</Layout>
<Layout intent="layout.group">
<Text intent="text.stat">2.1 GB</Text>
<Text intent="text.label">Storage</Text>
</Layout>
</Layout>Intents it renders
3 domains, each with its own page of neighbours and examples. The intent decides the element; these are the starter intents.
Heading heading.*
6 intentsheading.pitchThe persuasive headline of a marketing page: what the product does for you
<h1>heading.pageThe one title of a page: Settings, Sign in, Privacy policy, a profile name
<h1>heading.sectionTitle of a major part of a page
<h2>heading.itemTitle of a single thing: a list item, a panel, a dialog. A link in it keeps the heading colour
<h3>heading.sideThe name of one side in a side-by-side comparison: With intents, Without. A step smaller than heading.item, so it reads as a label over what is compared
<h3>heading.kickerA short label above a heading that names its category
<p>
Text text.*
27 intentstext.bodyRunning text: sentences and paragraphs that explain something
<p>text.leadIntroductory paragraph directly under a page or section title
<p>text.captionA supporting sentence next to something else: helper text under a field, a note under an image
<p>text.labelA few words that name a value: field labels, setting names, column headers. Use as="label" htmlFor=... for form fields
<span>text.currentThe page you are on, named at the end of a breadcrumb trail. Not a link. Pass aria-current="page"
<span>text.termThe name of a fact, above its value in a layout.fact: Profile, Status, Raised with
<p>text.valueThe value of a fact, under its text.term. A value that links somewhere goes in a text.topic; plain words do not
<div>text.metaSmall facts about an item: timestamps, authors, @handles, file sizes
<span>text.quoteWords quoted from someone, set apart from the text around them: a pull quote in an article, a testimonial. Renders <blockquote>
<blockquote>text.excerptA short extract of a longer text, shown as a preview: an article summary
<p>text.topicNames a topic or category an item belongs to: News, Science. Sits one surface level above what holds it. A link inside it covers the whole chip; without one, a link covering its item covers the chip too
<span>text.statusThe state something is in, as a word in an outlined pill: Flying, Charging, On time. data-tone="success", "info", "pending", "warning", "danger" or "muted" colours it
<span>text.countA number that sums something up: unread notifications, items waiting
<span>text.indicatorA dot that marks something as new or unread, or shows a status, with no number. Give it an aria-label, like "Unread" or "Charging"; data-tone="success", "info", "warning", "danger" or "muted" colours a status; data-busy makes it pulse while something is in progress
<span>text.summaryThe line that stays visible in a layout.disclosure; pressing it opens or closes the content
<summary>text.lineOne line in an agent terminal; data-kind says what it is: "ask" for the person (or "prompt", set as a chat bubble), "skip" for a step that turned up nothing useful and "keep" for one that found what was wanted, "agent" for its reply, "step" for something it did, "run" for a check still running, "fail" for one that failed, "pass" for one that passed. Steps lead with an icon, and any output follows in a text.output
<div>text.outputThe message a step in an agent terminal produced, such as what a check found, set under the step behind a thin rule. Code inside it goes in a text.snippet
<span>text.diffThe change a step in an agent terminal made to a file: its removed and added lines, each a text.diff.line
<div>text.diff.lineOne line of a text.diff; data-change="add" or "remove" marks and tints it
<span>text.tokenA highlighted piece of code; data-token names it: "tag", "attr", "string" or "punct"
<span>text.snippetA short piece of code inside a sentence: an element, an intent, a command
<code>text.tallyThe number in a layout.tally.item, counting up as the work it measures happens
<span>text.deltaHow a number differs from the one it is compared with, beside it, like −74%: data-tone="good" or "bad" colours it by whether the change is an improvement; with no data-tone it stays hidden
<span>text.markerThe label an inspector shows on the element it points at: its intent. Starts at the element's left edge, or its right edge when the layout.marker has data-align="end"
<span>text.statA headline number on its own: a metric, a result, a price
<p>text.codeA block of code or terminal output shown to the reader
<pre>text.addressThe address in a layout.window.bar
<span>
Feedback feedback.*
4 intentsfeedback.errorSomething failed or input is invalid. Announced to screen readers immediately
<p>feedback.warningSomething may go wrong unless the user acts
<p>feedback.successAn action the user took worked
<p>feedback.infoA neutral status about the current state: loading, searching, nothing to show yet
<p>
Props
Plus its element’s usual attributes (id, onClick, aria-*, data-*) and the shared layout props below. No className or style.
intentrequiredWhat this text is for:
heading.*,text.*orfeedback.*.TextIntentasChanges the element for document structure only, like
as="label"for a field label oras="h2"for a dialog title. The intent still decides the look.'h1'…'h6' | 'p' | 'span' | 'div' | 'label'htmlForWith
as="label": theidof the field it labels.stringvarsValues that come from data, as CSS variables the intent reads:
vars={{ '--accent': user.color }}.Record<`--${string}`, string | number>unsafeClassNameBypasses the intent. Needs a
// prongs-unsafe: <reason>comment on the line above, andprongs checkcounts it.string
Layout props
Where the element sits, never how it looks. Spacing between elements comes from the parent <Layout>.
alignOn text, the text alignment. On anything else, pushes it to that end of its row or column.
'start' | 'center' | 'end'widthFull width, or a maximum width.
'auto' | 'full' | 'prose' | 'sm' | 'md' | 'lg'hideBelowHidden on screens narrower than this breakpoint.
'sm' | 'md' | 'lg'showBelowShown only on screens narrower than this breakpoint.
'sm' | 'md' | 'lg'truncateOne line, cut off with an ellipsis.
booleannowrapKeeps the text on one line.
boolean
Rules
No
classNameorstyle. If text needs to look different, it is a different intent.Use
asonly to fix document structure, never to change the look.Emphasis inside a sentence is plain
<strong>or<em>, not another<Text>.