Action
Everything the user presses: commands, links, navigation and choices. With href it renders a link, without one a <button>.
Other components
Examples
Commands
Named for what they do. The look follows from the meaning: deleting is destructive, cancelling is quiet.
<Layout intent="layout.actions">
<Action intent="action.cancel">Cancel</Action>
<Action intent="action.save">Save changes</Action>
<Action intent="action.delete">Delete</Action>
</Layout>Links
With href the same component renders a link.
Read the guide to intents before you add one.
<Text intent="text.body">
Read the <Action intent="action.navigate" href="/docs/what-is-an-intent">guide to intents</Action> before you add one.
</Text>On and off
pressed sets aria-pressed, and the intent styles the pressed state.
<Layout intent="layout.toolbar">
<Action intent="choice.filter" pressed>All</Action>
<Action intent="choice.filter" pressed={false}>Unread</Action>
<Action intent="choice.filter" pressed={false}>Starred</Action>
</Layout>The page you are on
current sets aria-current on navigation.
<Layout intent="layout.group" className="flex-row gap-5">
<Action intent="nav.page" href="#current-page" current>Overview</Action>
<Action intent="nav.page" href="#current-page">Activity</Action>
<Action intent="nav.page" href="#current-page">Settings</Action>
</Layout>An icon alone
Without visible text, label is required: it is the accessible name.
<Action intent="action.dismiss" icon={<X aria-hidden className="size-4" />} label="Dismiss" />Intents it renders
3 domains, each with its own page of neighbours and examples. The intent decides the element; these are the starter intents.
Action action.*
27 intentsaction.submitSends a form
<button>action.saveKeeps changes the user made to something that already exists
<button>action.createMakes something new: a post, project, page or item
<button>action.startBegins the main flow a page exists for: get started, sign up, try it
<a>action.guideThe quieter call to action beside the main one, opening the guide to it: get started, read the docs
<button>action.nextMoves to the next step of a multi-step flow, or out of a finished one
<button>action.skipMoves to the next or previous item in a sequence someone steps through: the next track, the previous episode, the next photo in a dialog.media
<button>action.backReturns to the previous step of a flow without losing work
<button>action.signoutEnds the current session and signs the person out
<button>action.retryRepeats something that failed or needs doing again: try again, resend an email
<button>action.confirmAgrees to a decision the interface just asked about, usually in a dialog
<button>action.cancelAbandons the current task without keeping changes
<button>action.editOpens something that exists so it can be changed
<button>action.addPuts an existing thing into a list or collection: add a source, add a member
<button>action.removeTakes an item out of a list without destroying it: remove a source, unsubscribe
<button>action.deletePermanently destroys data
<button>action.shareSends something to other people or copies a link to it
<button>action.copyCopies the short text beside it, like a command, as an icon alone sized to the line. It stays pressable inside a card its link covers
<button>action.openOpens a piece of content to read or view it: an article title, "open original", a preview
<a>action.inspectOpens the details of a record in a table, on its name: the whole row becomes clickable and lights up on hover, while the other controls in it, like its menu, stay clickable
<button>action.toggleTurns a state on or off and shows which: follow, subscribe, like. Pass pressed={on}
<button>action.utilityA small helper command that changes no important data: refresh, mark all read
<button>action.dismissCloses or hides something without changing data: a dialog, notice or menu
<button>action.revealShows or hides content in place: show password, show more
<button>action.navigateGoes to another page or place from inside a sentence: an inline link
<a>action.moreA link on its own line to more about what is above it, with an arrow after it: Learn more, See all, Full changelog. Write only the words; the arrow (Lucide arrow-right) is added
<button>action.sortSorts a table by a column: the button inside its th. Put aria-sort="ascending" or "descending" on the th of the sorted column; the arrow follows it
<button>
Navigation nav.*
10 intentsnav.homeThe site or product name, linking to the home page
<a>nav.pageA link to a top-level page in site navigation. Pass current on the page you are on
<a>nav.areaA link to one area of the site that has its own sidebar: Docs, Reference. Pass current on the open one; it is marked by full-strength text, with no underline
<a>nav.entryThe name of an entry in an index or table, linking to its page: an intent in the vocabulary list
<a>nav.itemThe title of an item in a collection, opening its page. The link covers the item, so the whole item can be pressed; give the item position: relative
<a>nav.viewSwitches which view of the same content is shown: Following / For you, list / grid. Pass pressed on the active view
<a>nav.dotOne dot in a row over a photo that shows which of a set is open, and opens that one: the photos in a dialog.media. Pass current on the one shown, and a label like "Photo 2 of 5"
<a>nav.stepOne step in a multi-step flow. Pass current on the active step
<a>nav.pagingOne link in a layout.pager below a long list or table: a page number, Previous or Next. Pass current on the page shown
<a>nav.sequelThe previous or next page at the foot of a guide read in order, with an arrow pointing its way. Put the icon on the side it points to
<a>
Choice choice.*
4 intentschoice.optionOne of a small set of options for a setting: theme, layout, a category. Pass pressed on the chosen one
<button>choice.filterNarrows which items are shown: All, Unread, a source. Pass pressed while it applies
<button>choice.colorPicks a colour from presets. Pass the colour as vars={{ "--choice-color": value }} and pressed on the chosen one
<button>choice.openShows what is picked and opens the choices to change it: a sort order, sources. The trigger of a Popover picker
<button>
Props
Plus its element’s usual attributes (id, onClick, aria-*, data-*) and the shared layout props below. No className or style.
intentrequiredhrefMakes it a link (through the
LinkComponentinconfig.ts, e.g.next/link).stringpressedOn or off, for toggles, choices and views. Sets
aria-pressed; the intent styles it.booleancurrentMarks the page or step you are on. Sets
aria-current; the intent styles it.booleaniconAn icon shown before the text, or alone.
ReactNodelabelThe accessible name. Required when there is no visible text (an icon alone).
stringdisabledTurns it off. A disabled link loses its
href.booleantypeButtons are
type="button"unless the intent says otherwise (action.submitissubmit).'button' | 'submit' | 'reset'varsValues 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
Name it for what it does (
action.delete), not how it looks.prongs checkwarns when its label or handler says something else.State goes in
pressedorcurrent, never in a different intent or extra classes.An icon alone needs
label.No
classNameorstyle.