Action bar in three groups: search and filters at the start, a centered group, actions at the end. It paints no ground of its own and takes the one it sits on, above a table or inside a card. One tab stop; arrow keys move between the controls. variant="flush" is the bar across the top of an application shell.
The default bar paints no ground, border or rounding of its own, so it takes the surface it sits on and its controls line up with the table below. role="toolbar" sits on the host, so name the bar with a native aria-label. The element emits nothing; the controls inside carry their own events.
variant is the shape. plain, the default, has no edge. card is a bordered, rounded box on the white surface, the bar that floats on the canvas as its own card. flush squares the corners and keeps one bottom rule, so the bar can run edge to edge across a shell or inside a card.
tone is the ground. Unset, the bar is transparent and shows the canvas. surface is the white of the cards, sunken the well of a table header, canvas the app background, which only shows when the bar is sticky and content scrolls under it. brand is the navy chrome, shown below.
A flush rail and a flush bar on one canvas, each with one rule and no ground of its own, so the chrome reads as one piece and only the shell is rounded. landmark="region" makes the bar a named landmark for a shell embedded in a page, as here; landmark="banner" is for the one bar at the top of a whole page.
Projects
Four projects are open. The bar above runs from the rail to the right edge of the shell.
<div style="display:flex;align-items:stretch;border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;background:var(--canvas)">
<sui-side-nav id="tb-shell-nav" variant="flush" aria-label="Primary, Application shell" height="300" active="Projects"></sui-side-nav>
<div style="flex:1;min-width:0;display:flex;flex-direction:column">
<sui-toolbar variant="flush" landmark="region" aria-label="Workspace">
<sui-icon-field slot="start" icon="fa-solid fa-magnifying-glass" placeholder="Search" aria-label="Search the workspace" size="md" width="200"></sui-icon-field>
<sui-button slot="end" variant="outline" size="md" icon="fa-solid fa-file-export" label="Export"></sui-button>
<sui-button slot="end" variant="accent" size="md" icon="fa-solid fa-plus" label="New project"></sui-button>
</sui-toolbar>
<div style="padding:16px 18px;font:460 13px/1.7 var(--font-sans);color:var(--ink-muted);flex:1">
<b style="color:var(--ink);font-size:15px">Projects</b>
<div style="margin-top:6px">Four projects are open. The bar above runs from the rail to the right edge of the shell.</div>
</div>
</div>
</div>
tone="brand" paints the bar on the navy ground sui-side-nav paints under the same name, with inverse ink and an inverse rule. Quiet controls take their own inverse tone: the icon buttons here, and any quiet field with tone="inverse", like this select. An accent button reads on navy without one.
Northwind
The bar carries the same navy as the rail, so the two read as one piece of chrome.
<div style="border-radius:var(--radius-lg);overflow:hidden">
<sui-toolbar variant="flush" tone="brand" landmark="region" aria-label="Northwind workspace">
<b slot="start" style="font:730 14.5px var(--font-sans)">Northwind</b>
<sui-icon-field slot="start" icon="fa-solid fa-magnifying-glass" placeholder="Search" aria-label="Search the workspace" size="md" width="190"></sui-icon-field>
<sui-select id="tb-navy-period" slot="start" variant="quiet" tone="inverse" size="md" aria-label="Period"></sui-select>
<sui-icon-button slot="end" icon="fa-regular fa-bell" tone="inverse" size="md" aria-label="Notifications"></sui-icon-button>
<sui-icon-button slot="end" icon="fa-regular fa-circle-question" tone="inverse" size="md" aria-label="Help"></sui-icon-button>
<sui-button slot="end" variant="accent" size="md" icon="fa-solid fa-plus" label="New project"></sui-button>
</sui-toolbar>
<div style="padding:16px 18px;font:460 13px/1.7 var(--font-sans);color:var(--ink-muted);flex:1;background:var(--surface)">The bar carries the same navy as the rail, so the two read as one piece of chrome.</div>
</div>
A plain bar inside a card takes the card's white. For a filter strip that reads as part of the table, flush with tone="sunken" gives the well of the table header, running to both edges of the card, so the card keeps one outer border.
sticky pins the bar to the top of its scroll container; give it a tone, or the content scrolls through it. elevated adds the shadow that says the content is passing underneath, which a bottom rule alone does not say. Scroll the panel to see both.
Quarterly report
Revenue held flat across the quarter while headcount grew by six.
Support volume fell for the third month running.
Two regions moved onto the new plan without a migration window.
Storage costs are the only line item above forecast.
The renewal cohort closes in the second week of next month.
Everything else tracked to plan.
<div style="height:220px;overflow:auto;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface)">
<sui-toolbar variant="flush" tone="surface" sticky elevated aria-label="Report actions">
<span slot="start" style="font:550 13px var(--font-sans)">Quarterly report</span>
<sui-button slot="end" variant="outline" size="md" icon="fa-solid fa-print" label="Print"></sui-button>
<sui-button slot="end" variant="accent" size="md" label="Share"></sui-button>
</sui-toolbar>
<div style="padding:14px 18px;font:460 13px/1.9 var(--font-sans);color:var(--ink-muted)">
<p style="margin:0 0 10px">Revenue held flat across the quarter while headcount grew by six.</p>
<p style="margin:0 0 10px">Support volume fell for the third month running.</p>
<p style="margin:0 0 10px">Two regions moved onto the new plan without a migration window.</p>
<p style="margin:0 0 10px">Storage costs are the only line item above forecast.</p>
<p style="margin:0 0 10px">The renewal cohort closes in the second week of next month.</p>
<p style="margin:0">Everything else tracked to plan.</p>
</div>
</div>
One tab stop
The bar is a single tab stop for its buttons, links and selects, and it skips disabled ones. A text field keeps its own stop so the arrow keys still edit text. The log below listens to the native focusin, not to a component event.
Open the guideTab into the bar, then press the arrow keys.
Enters the bar at its current control, and leaves it on the next press. A text field inside keeps its own tab stop.
ArrowRight
Moves focus to the next button, link or select, wrapping to the first. Under dir="rtl" the pair swaps, so the arrow that points along the reading direction is always the forward one.
ArrowLeft
Moves focus to the previous button, link or select, wrapping to the last.
Home
Moves focus to the first control in the bar.
End
Moves focus to the last control in the bar.
API
<sui-toolbar>
Properties
Property
Attribute
Type
Default
Description
elevated
elevated
boolean
false
Casts a shadow under the bar, so a sticky bar reads as sitting above the content passing beneath it.
landmark
landmark
"banner" | "region" | "toolbar"
'toolbar'
Role the host carries. The default toolbar announces the bar as one composite widget whose arrow keys move between the controls. banner announces it as the page header instead, for the one bar at the top of a page; a banner inside another landmark is wrong by definition, so a shell embedded in a page takes region, a named landmark of its own. The arrow keys work under all three, but the toolbar role goes with either landmark. There is no label prop: the role sits on the host, so name the bar with a native aria-label, which a landmark needs.
sticky
sticky
boolean
false
Pins the bar to the top of its scroll container while the content moves under it. Pair it with a tone.
Ground the bar paints. Leave it unset and the bar is transparent, which is right for a bar in flow; give a sticky bar a ground, or the content scrolls through it. surface is the card of the cards, canvas the app background sui-side-nav paints under the same name, sunken the well of a table header, for a filter strip inside a card. brand is the brand chrome with inverse ink and an inverse rule; quiet controls inside it take their own inverse tone, and an accent button reads on it as it does on the rail. Anything else paints nothing.
variant
variant
SuiToolbarVariant"card" | "flush" | "plain"
'plain'
Shape of the bar, which is to say which edges carry a rule. plain is the default: no border, no rounding and no padding of its own, so the controls line up with whatever sits below the bar. card is a bordered, rounded box on the surface, for a bar that floats on the canvas as its own card. flush squares the corners and keeps a single bottom rule, for the bar across the top of an application shell or a strip that runs edge to edge inside a card. Anything else falls back to plain.
Methods
Method
Signature
Description
setFocus()
setFocus() => Promise<void>
Moves keyboard focus to the bar's one tab stop, the control the arrow keys last left it on.
Slots
Slot
Description
center
Centered group.
end
Right group (Export, the one accent action).
start
Left group (search field, filters).
Types
SuiToolbarTonetype
No members.
SuiToolbarVarianttype
No members.
Theming
Every design token this element can render with, read from its own stylesheets and the ones it imports. Set a token on :root or on any ancestor and every use below follows it. The values shown are the ones in the theme you are viewing. The list is read per stylesheet, so an element that imports a shared drawing module lists that module's tokens too, whether or not it paints with all of them.