Filter bar and chips
A chip is a small pill with a label and a remove button. A filter bar is a wrapping row of chips with a Clear all button; removing a chip tells the page so it can filter again.
Filter bar
Remove a chip or clear all.
<div class="filter-bar" role="group" aria-label="Active filters" id="fb1">
<span class="chip" data-value="status:paid">Status: Paid<button type="button" aria-label="Remove Status: Paid"><i class="icon icon-x" aria-hidden="true"></i></button></span>
<span class="chip" data-value="date:30d">Last 30 days<button type="button" aria-label="Remove Last 30 days"><i class="icon icon-x" aria-hidden="true"></i></button></span>
<span class="chip" data-value="country:th">Country: Thailand<button type="button" aria-label="Remove Country: Thailand"><i class="icon icon-x" aria-hidden="true"></i></button></span>
<button type="button" class="btn" data-variant="ghost" data-size="sm" data-clear>Clear all</button>
</div>
<small id="fb1-out" aria-live="polite">Remove a chip or clear all.</small>
<script>
document.getElementById("fb1").addEventListener("tsunami:filterchange", (e) => {
document.getElementById("fb1-out").textContent = "Filters left: " + (e.detail.values.join(", ") || "none");
});
</script>
Chips on their own
<span class="chip">Draft</span>
<span class="chip" data-variant="accent">Selected</span>
<span class="chip" data-variant="muted">Add filter</span>
Behavior
- A chip with a remove button is a
span.chipwith abuttoninside. The button needs anaria-labelsuch as "Remove Status: Paid". - Removing a chip moves focus to the next chip, or the last one left, so the keyboard keeps its place.
- The Clear all button (
data-clear) is hidden when there are no chips. - Chips you add later work too. The script reads the page, so there is nothing to start.
- Chips outside a
.filter-barare only styled. Handle their buttons yourself.
API
Methods
| Method | Description |
|---|---|
tsunami.filterBar.values(bar) | The data-value of each chip (its text when there is none). |
tsunami.filterBar.clear(bar) | Removes every chip and sends tsunami:filterchange. |
tsunami.filterBar.mount(root?) | Refreshes the Clear all button of each bar inside root. |
Events
| Event | On | Description |
|---|---|---|
tsunami:chipremove | the chip, bubbles, cancelable | Sent before a chip is removed. event.detail is { value, label }. Call preventDefault() to keep the chip. |
tsunami:filterchange | the .filter-bar, bubbles | Sent after a chip is removed or all are cleared. event.detail.values lists the chips left. |
Keyboard
| Key | Description |
|---|---|
| Tab | Moves between the remove buttons and Clear all. |
| Enter Space | Removes the chip, or clears all. |
Attributes
| Attribute / element | Values | Description |
|---|---|---|
.chip | on a span | The pill. Put the label first and an optional remove button last. |
data-variant | accent, muted | On a chip: an accent outline, or a dashed quiet one. |
data-value | text | On a chip: what tsunami:chipremove and values() report. |
.filter-bar | on a div | A wrapping row of chips. Give it role="group" and an aria-label. |
data-clear | present | On a button in the bar: removes every chip. |