Toolbar
tier 2 — classes
The filter bar that sits above a table or list. .toolbar-filters groups the
controls on the leading side and .toolbar-actions the trailing one — give it those
two children and nothing else, because .toolbar is space-between and a
third floats in the middle.
Filters and a count
.toolbar-input narrows a .form-input or a
.form-select to a sensible 160px so it does not eat the row.
.toolbar-count is the muted result count.
<div class="toolbar">
<div class="toolbar-filters">
<input class="form-input toolbar-input" type="search" placeholder="Search orders…" />
<select class="form-select toolbar-input" aria-label="Filter by assignment group">
<option>All states</option>
<option>Pending</option>
<option>Decided</option>
</select>
<label class="form-check"><input type="checkbox" /> Only mine</label>
</div>
<span class="toolbar-count">18 of 128</span>
</div>
A wider search box
.toolbar-input--wide is 280px, for a search box that cannot fit its own
placeholder at 160px. The width is a knob, --toolbar-input-width, for a control
between the two sizes — as the department select does here — and
.toolbar-input--grow takes whatever room is left instead. A filter carrying a
leading icon is an .input-group, and
.toolbar-input goes on the group, not on the input inside it.
<div class="toolbar">
<div class="toolbar-filters">
<input class="form-input toolbar-input toolbar-input--wide" type="search"
placeholder="Staff ID, name, e-mail, cost centre, manager…" aria-label="Search employees" />
<select class="form-select toolbar-input" aria-label="Location">
<option>All locations</option>
<option>Zürich</option>
<option>Bern</option>
</select>
<select class="form-select toolbar-input" style="--toolbar-input-width: 12rem" aria-label="Department">
<option>All departments</option>
<option>Application Management</option>
</select>
</div>
<span class="toolbar-count">1 211 employees</span>
</div>
A search that takes the room
.toolbar-input--grow gives the field whatever the bar has left, floored at
12rem, for a search whose placeholder is a sentence. One control grows; give it to a
second and the two split the room and neither placeholder fits.
<div class="toolbar">
<div class="toolbar-filters">
<div class="input-group toolbar-input toolbar-input--grow">
<span class="input-affix"><i class="ri-search-line"></i></span>
<input class="form-input" type="search" placeholder="Order number, customer, address or carrier reference"
aria-label="Search orders" />
</div>
<select class="form-select toolbar-input" aria-label="Region">
<option>All regions</option>
<option>EU-West</option>
<option>EU-Central</option>
</select>
</div>
<div class="toolbar-actions">
<button class="btn btn-sm" type="button"><i class="ri-download-2-line"></i> Export</button>
</div>
</div>
Filters and actions
Put the buttons on the trailing side, with the primary action last.
.sedna-push does not rescue a third child, because an auto margin and
space-between are two answers to the same question.
<div class="toolbar">
<div class="toolbar-filters">
<input class="form-input toolbar-input" type="search" placeholder="Filter…" />
</div>
<div class="toolbar-actions">
<span class="toolbar-count">6 selected</span>
<button class="btn btn-sm btn-icon" aria-label="Refresh" data-tip="Reload from the server."><i class="ri-refresh-line"></i></button>
<button class="btn btn-sm">Export</button>
<button class="btn btn-sm btn-primary"><i class="ri-add-line"></i> New</button>
</div>
</div>
With a heading above it
The full top of a list page.
Approval queue
Items the AI proposed and is waiting on a human decision for.
| Order | Reservation | Age |
|---|---|---|
| ORD-4209 | Reroute to EU-West | 4 min |
| ORD-4204 | Raise to P2 | 22 min |
<div>
<h1>Approval queue</h1>
<p class="lede">Items the AI proposed and is waiting on a human decision for.</p>
<div class="toolbar">
<div class="toolbar-filters">
<input class="form-input toolbar-input" type="search" placeholder="Search…" />
<label class="form-check"><input type="checkbox" checked /> Hide claimed</label>
</div>
<span class="toolbar-count">3 pending</span>
</div>
<div class="card">
<table class="table">
<thead><tr><th>Order</th><th>Reservation</th><th>Age</th></tr></thead>
<tbody>
<tr><td>ORD-4209</td><td>Reroute to EU-West</td><td class="col-muted">4 min</td></tr>
<tr><td>ORD-4204</td><td>Raise to P2</td><td class="col-muted">22 min</td></tr>
</tbody>
</table>
</div>
</div>
With a selection
Live — open the overflow menu. The count and the two ways out of it on the
leading side, the actions that apply to the selection on the trailing side. Say how many are
selected in text, and offer “select all 128” separately — selecting a page is not
selecting a result set. The overflow is a .menu-anchor with
data-menu-toggle, and anything destructive goes in there behind
.menu-item--danger, naming the count it will act on.
<div class="toolbar">
<div class="toolbar-filters">
<label class="form-check">
<input type="checkbox" checked /> <span>4 selected</span>
</label>
<button class="btn btn-sm btn-ghost" type="button">Select all 128</button>
<button class="btn btn-sm btn-ghost" type="button">Clear</button>
</div>
<div class="toolbar-actions">
<button class="btn btn-sm btn-go" type="button"><i class="ri-send-plane-line"></i> Dispatch</button>
<button class="btn btn-sm" type="button"><i class="ri-user-shared-line"></i> Reassign</button>
<div class="menu-anchor">
<button class="btn btn-sm btn-icon" type="button" data-menu-toggle
aria-label="More actions for the selected orders" aria-expanded="false">
<i class="ri-more-2-line"></i>
</button>
<div class="menu" hidden>
<button class="menu-item" type="button"><i class="ri-download-2-line"></i> Export as CSV</button>
<button class="menu-item" type="button"><i class="ri-timer-line"></i> Hold for stock</button>
<hr class="menu-sep" />
<button class="menu-item menu-item--danger" type="button">
<i class="ri-close-circle-line"></i> Cancel 4 orders
</button>
</div>
</div>
</div>
</div>