Table Filter Row
<sl-table-filter-row> | SlTableFilterRow
Used to support filtering table content.
<sl-table-filter-row placeholder="table filter row"></sl-table-filter-row>
Examples
Size
Visual difference between default and compact size is the height and padding.
Compact size is used when screen real estate is limited due to other important content on the page.
<sl-table-filter-row placeholder="table filter row"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row placeholder="table filter row" size="compact"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row placeholder="table filter row" has-full-border> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row placeholder="table filter row" has-full-border size="compact"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <style> .placeholder-block { display: inline-flex; justify-content: center; align-items: center; background: var(--hds-color-bg-secondary); color: white; } </style>
Position
Table filter row should fill the amount of space available of where it’s placed.
inline is the default position and has a slot for filters are right aligned on the same
row. It has a minimum width of 800px and will be responsive when the viewport is less than that.
stacked has a slot for filters that wraps to the next row below the search input. This
variant is recommended for mobile and tablet displays when horizontal space is limited. It has a
maximum width of 800px.
<sl-table-filter-row placeholder="table filter row" position="inline"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row class="demo-row" placeholder="table filter row" position="stacked"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row class="demo-row" placeholder="table filter row" size="compact" position="stacked"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row class="demo-row" placeholder="table filter row table filter row table filter row table filter row" position="stacked" has-full-border> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <br> <sl-table-filter-row class="demo-row" placeholder="table filter row" size="compact" position="stacked" has-full-border> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row> <style> .demo-row { width: 682px; } .placeholder-block { display: inline-flex; justify-content: center; align-items: center; background: var(--hds-color-bg-secondary); color: white; } </style>
Input values
While the component itself does not provide explicit filter rules, you can access the input values and create filter rules on application level.
<sl-table-filter-row placeholder="table filter row" position="inline"> <div slot="filter-slots"> <div class="placeholder-block">Placeholder block</div> <div class="placeholder-block">Placeholder block</div> </div> </sl-table-filter-row>
Appearance
Default
Default table filter row is attached to a table as the leading row unless specified otherwise by designer.
Created date
| Account | Reporting group | Nickname | Override perf inception date | Source | Balance | |
|---|---|---|---|---|---|---|
|
|
||||||
|
|
||||||
|
|
<div class="default-table-container"> <sl-table-filter-row placeholder="Filter by account or display name"> <div slot="filter-slots"> <div class="date-range-container"> <p>Created date</p> <sl-date-range-input always-editing hide-range-type show-shortcuts></sl-date-range-input> <sl-dropdown variant="secondary"> <sl-button slot="trigger" caret>Dropdown</sl-button> <sl-menu> <sl-menu-item>Dropdown Item 1</sl-menu-item> <sl-menu-item>Dropdown Item 2</sl-menu-item> </sl-menu> </sl-dropdown> </div> </div> </sl-table-filter-row> <table style="border-collapse: collapse;"> <thead> <tr> <th is-heading><sl-checkbox></sl-checkbox></th> <th is-heading>Account</th> <th is-heading>Reporting group</th> <th is-heading>Nickname</th> <th is-heading>Override perf inception date</th> <th is-heading>Source</th> <th is-heading>Balance</th> </tr> </thead> <tbody> <tr> <td><sl-table-cell><sl-checkbox></sl-checkbox></sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 1</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 2</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 3</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 4</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 5</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 6</sl-table-cell></td> </tr> <tr> <td><sl-table-cell><sl-checkbox></sl-checkbox></sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 1</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 2</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 3</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 4</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 5</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 6</sl-table-cell></td> </tr> <tr> <td><sl-table-cell><sl-checkbox></sl-checkbox></sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 1</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 2</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 3</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 4</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 5</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 6</sl-table-cell></td> </tr> </tbody> </table> </div> <style> .default-table-container { border-radius: var(--hds-border-radius-lg); border: 1px solid var(--hds-color-border); align-items: flex-start; } table { width: -webkit-fill-available; } .date-range-container { display: flex; gap: var(--hds-space-gap-md); align-items: baseline; } .date-range-container > p { color: var(--hds-color-fg); font-size: var(--hds-font-application-label-fontSize); } </style>
Full border
Table filter row alternatively can be encased with full border and detached from tables.
This style allows for elements or other relevant content to sit right above table headers.
Created date
| Account | Reporting group | Nickname | Override perf inception date | Source | Balance | |
|---|---|---|---|---|---|---|
|
|
||||||
|
|
||||||
|
|
<sl-table-filter-row placeholder="Search by fund or trustee name" has-full-border> <div slot="filter-slots"> <div class="date-range-container"> <p>Created date</p> <sl-date-range-input always-editing hide-range-type show-shortcuts></sl-date-range-input> <sl-dropdown variant="secondary"> <sl-button slot="trigger" caret>Dropdown</sl-button> <sl-menu> <sl-menu-item>Dropdown Item 1</sl-menu-item> <sl-menu-item>Dropdown Item 2</sl-menu-item> </sl-menu> </div> </div> </sl-table-filter-row> <div class="datapair-group"> <div>Applied(1):</div> <sl-tag removable>Open</sl-tag> <sl-button variant="naked" size="small">Clear all</sl-button> </div> <div class="full-border-table-container"> <table style="border-collapse: collapse;"> <thead> <tr> <th is-heading><sl-checkbox></sl-checkbox></th> <th is-heading>Account</th> <th is-heading>Reporting group</th> <th is-heading>Nickname</th> <th is-heading>Override perf inception date</th> <th is-heading>Source</th> <th is-heading>Balance</th> </tr> </thead> <tbody> <tr> <td><sl-table-cell><sl-checkbox></sl-checkbox></sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 1</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 2</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 3</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 4</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 5</sl-table-cell></td> <td><sl-table-cell>Row 1, Cell 6</sl-table-cell></td> </tr> <tr> <td><sl-table-cell><sl-checkbox></sl-checkbox></sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 1</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 2</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 3</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 4</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 5</sl-table-cell></td> <td><sl-table-cell>Row 2, Cell 6</sl-table-cell></td> </tr> <tr> <td><sl-table-cell><sl-checkbox></sl-checkbox></sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 1</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 2</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 3</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 4</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 5</sl-table-cell></td> <td><sl-table-cell>Row 3, Cell 6</sl-table-cell></td> </tr> </tbody> </table> </div> <style> .full-border-table-container { border-radius: var(--hds-border-radius-lg); border: 1px solid var(--hds-color-border); align-items: flex-start; } table { width: -webkit-fill-available; } .datapair-group { display: flex; padding: var(--hds-space-atom-xs) var(--hds-space-atom-md); align-items: center; gap: var(--hds-space-atom-sm); align-self: stretch; } </style>
Filtering usage example
Here is an example on how to filter table content by using input field and/or dropdown menu.
| Trustee name | Trustee email | Trustee status | Balance ($) |
|---|---|---|---|
<div class="example-table-container"> <sl-table-filter-row placeholder="Filter by trutee name or email address" id="filter-row"> <div slot="filter-slots"> <sl-dropdown variant="secondary"> <sl-button slot="trigger" caret>Status</sl-button> <sl-menu id="status-menu"> <sl-menu-item value="">All</sl-menu-item> <sl-menu-item value="active">Active</sl-menu-item> <sl-menu-item value="inactive">Inactive</sl-menu-item> </sl-menu> </sl-dropdown> </div> </sl-table-filter-row> <table style="border-collapse: collapse;" id="trustee-table"> <thead> <tr> <th is-heading>Trustee name</th> <th is-heading>Trustee email</th> <th is-heading>Trustee status</th> <th is-heading>Balance ($)</th> </tr> </thead> <tbody> <tr> <td><sl-table-cell>Charlie Smith</sl-table-cell></td> <td><sl-table-cell>charliesmith@email.com</sl-table-cell></td> <td><sl-table-cell value="active">Active</sl-table-cell></td> <td><sl-table-cell>12,000</sl-table-cell></td> </tr> <tr> <td><sl-table-cell>Jane Jacobs</sl-table-cell></td> <td><sl-table-cell>janejacobs@email.com</sl-table-cell></td> <td><sl-table-cell value="active">Active</sl-table-cell></td> <td><sl-table-cell>56,000</sl-table-cell></td> </tr> <tr> <td><sl-table-cell>Mary James</sl-table-cell></td> <td><sl-table-cell>maryjames@email.com</sl-table-cell></td> <td><sl-table-cell value="inactive">Inactive</sl-table-cell></td> <td><sl-table-cell>24,000</sl-table-cell></td> </tr> </tbody> </table> </div> <script type="module"> const filterRow = document.getElementById('filter-row'); const statusMenu = document.getElementById('status-menu'); const rows = [...document.querySelectorAll('#trustee-table tbody tr')]; let query = ''; let status = ''; function applyFilters() { const q = query.toLowerCase().trim(); rows.forEach(row => { const name = row.cells[1].textContent.toLowerCase(); const email = row.cells[2].textContent.toLowerCase(); const statusCell = row.cells[3].querySelector('sl-table-cell'); const rowStatus = statusCell?.getAttribute('value') ?? ''; const matchesQuery = !q || name.includes(q) || email.includes(q); const matchesStatus = !status || rowStatus === status; row.hidden = !(matchesQuery && matchesStatus); }); } // Typing "charlie" → only Charlie Smith stays visible filterRow.addEventListener('sl-input', () => { query = filterRow.inputValue; applyFilters(); }); // Choosing Active or Inactive status statusMenu.addEventListener('sl-select', event => { status = event.detail.item.value; applyFilters(); }); </script> <style> .example-table-container { border-radius: var(--hds-border-radius-lg); border: 1px solid var(--hds-color-border); align-items: flex-start; } table { width: -webkit-fill-available; } .date-range-container { display: flex; gap: var(--hds-space-gap-md); align-items: baseline; } .date-range-container > p { color: var(--hds-color-fg); font-size: var(--hds-font-application-label-fontSize); } </style>
[component-metadata:sl-table-filter-row]
Slots
| Name | Description |
|---|---|
filter-slots
|
Reserved for filter controls such as dropdowns, date range inputs, toggle button etc. The recommendation is maximum 4 filter controls. |
Learn more about using slots.
Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
placeholder
|
The placeholder text of the input element. |
string
|
''
|
|
size
|
The table filter row’s size. |
|
'default' | 'compact'
|
'default'
|
position
|
The table filter row’s position |
'inline' | 'stacked'
|
'inline'
|
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Events
| Name | React Event | Description | Event Detail |
|---|---|---|---|
sl-change |
|
Emitted when an item is selected. | - |
sl-input |
|
Emitted when the input value changes. | - |
Learn more about events.
Parts
| Name | Description |
|---|---|
base |
The component’s base wrapper. |
filter-slots |
The component’s filter slots wrapper. |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
<sl-icon><sl-input>