Action bar
Action bar is a floating toolbar, at the bottom of the screen under its
table, shown while one or more rows of a
The table mounts one directly onto document.body whenever it has at
least one selected row and tears it down once the selection clears (a
plain, non-anchored position: fixed overlay needs no anchor-scoped portal
trick), but it's a fully standalone element too, usable on its own for a
custom selection UI built without a table at all, exactly like the demo
below.
Dependencies
The action bar below is repositioned within this preview box for the demo only (position: absolute instead of its own default fixed), since in real usage it always sits at the bottom of the viewport, centered under its table.
When to use
Used automatically by
Install & usage
npm install @eunomia/elements
import "@eunomia/elements/table-action-bar.js";
<eun-table-action-bar id="bar"></eun-table-action-bar>
<script type="module">
const bar = document.querySelector("#bar");
bar.selectedCount = 3;
bar.totalCount = 8;
bar.actions = [
{ key: "archive", label: "Archive", color: "critical", icon: "archive" },
];
bar.onSelectAll = () => {
/* select/deselect every row in your own list */
};
bar.onClose = () => {
/* clear your own selection */
};
bar.addEventListener("euntableaction", (event) => {
if (event.key === "archive") {
archiveSelected();
}
});
</script>
Properties
Action bar <eun-table-action-bar>
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
| selected-count | number | 0 | The number of currently selected rows |
| total-count | number | 0 | The total number of selectable rows, used for the select-all accessible label |
| collapsible | boolean | false | Whether the count badge and the select-all button shrink to their number and icon when the bar lacks room |
| viewport-centered-below | 'mobile' | 'tablet' | 'laptop' | 'desktop' | number | — | Centers the bar on the screen instead of the table below this width, a breakpoint name or a number of pixels. Wins over --table-action-bar-viewport-centered-below |
| viewport-centered | boolean | — | Set by the component while the bar is centered on the screen through viewport-centered-below or --table-action-bar-viewport-centered-below. Read only |
| toolbar-aria-label | string | 'Selection actions' | The accessible label for the toolbar itself ; translated from `locale` while unset |
| selected-label | string | 'selected' | Text shown after the count in the badge ; translated from `locale` while unset |
| select-all-label | string | 'Select all' | The label of the select-all button while not every row is selected ; translated from `locale` while unset |
| deselect-all-label | string | 'Deselect all' | The label of the select-all button once every row is selected ; translated from `locale` while unset |
| close-aria-label | string | 'Clear selection' | The accessible label for the close button ; translated from `locale` while unset |
Import the exact TypeScript type behind any property above, see
Properties
JS-only — no matching HTML attribute, set these from a script or a template binding.
| Name | Type | Default | Description |
|---|---|---|---|
| actions | Array<EunomiaTableAction> | [] | The custom actions rendered in the center region |
| onSelectAll | () => void | undefined | — | Called when the select-all/deselect-all button is clicked. Set by the owning `eun-table` (or a standalone consumer of this element). |
| onClose | () => void | undefined | — | Called when the close button is clicked. Set by the owning `eun-table` (or a standalone consumer of this element). |
| resolvedLocale | — | This instance's own `locale` when set, the shared default locale otherwise. Used for `Intl` formatting, so dates and numbers follow the same locale as dictionary. | |
| dictionary | — | This instance's locale-resolved string dictionary — see the class doc for the resolution order. |
Slots
| Name | Description |
|---|---|
| (default) | Extra content rendered in the center region, after the actions-driven buttons and dropdowns. An escape hatch for markup actions can't express, such as a custom control or a status message. The center region scrolls horizontally when its content doesn't fit |
Events
| Name | Type | Description |
|---|---|---|
| euntableaction | TableActionEvent | Fired when a custom action is activated |
Every event above follows the same naming convention, covered in
CSS custom properties
| Name | Description |
|---|---|
| --table-action-bar-offset-bottom | Sets the distance from the bottom of the viewport |
| --table-action-bar-center | Sets the horizontal center of the bar, in viewport coordinates. Defaults to the center of the table that shows it, or of the viewport for a standalone bar |
| --table-action-bar-background | Sets the background color |
| --table-action-bar-border-color | Sets the border color |
| --table-action-bar-shadow | Sets the box shadow |
| --table-action-bar-z-index | Sets the stacking order, 100 by default |
| --table-action-bar-border-radius | Sets the corner radius of the action bar |
| --table-action-bar-viewport-centered-below | Sets the width below which the bar centers on the screen instead of the table, a breakpoint name or a number of pixels. The viewport-centered-below attribute wins over it |
| --table-action-bar-max-width | Sets the max width of the bar. Defaults to the room left around its center, minus a margin on each side |
| --table-action-bar-padding | Sets the padding inside the bar |
| --table-action-bar-gap | Sets the gap between the bar's groups and buttons |
| --table-action-bar-action-color | Sets the text color of the actions without a color of their own |
| --table-action-bar-count-background | Sets the background color of the count badge |
| --table-action-bar-count-color | Sets the text color of the count badge |
CSS shadow parts
| Name | Description |
|---|---|
| bar | The bar's own surface box, carrying its padding, background, and border. Exposed for effects the bar's CSS custom properties don't cover |
Content
Plain button actions
The default shape: one or more eun-button actions, color: "critical"
rendering critical/transparent instead of the default flat style.
bar.actions = [
{ key: "duplicate", label: "Duplicate", icon: "content_copy" },
{ key: "delete", label: "Delete", color: "critical", icon: "delete" },
];
A dropdown action
Any actions entry with a dropdown array renders as a
eun-dropdown-button instead of a plain button, and euntableaction still
fires, carrying the chosen option's key as optionKey.
bar.actions = [
{
key: "export",
label: "Export",
icon: "download",
dropdown: [
{ key: "csv", label: "Export as CSV" },
{ key: "pdf", label: "Export as PDF" },
],
},
];
bar.addEventListener("euntableaction", (event) => {
if (event.key === "export") {
exportSelection(event.optionKey); // "csv" | "pdf"
}
});
Extra slotted content
actions covers a button or a dropdown, always, so for anything else in
the center region (a status message, a plain link, a custom control), the
default slot renders it right after them, as plain markup.
<eun-table-action-bar>
<eun-link href="/activity">View activity</eun-link>
</eun-table-action-bar>
Placement
Position
The bar sits at the bottom of the viewport, centered under the table that
shows it, so it stays aligned with the table when a sidebar or any other
column pushes the table aside. It follows the table as it resizes. A
standalone bar, shown without a table, is centered on the viewport.
--table-action-bar-center sets another horizontal center, in viewport
coordinates, and --table-action-bar-offset-bottom its distance from the
bottom.
eun-table-action-bar {
--table-action-bar-offset-bottom: 48px;
}
On smaller screens, a table pushed aside by a sidebar can leave the bar
off-center. viewport-centered-below takes a breakpoint (mobile, tablet,
laptop or desktop) or a number of pixels: below that width, the bar
centers on the screen instead of the table. On a table, set
action-bar-viewport-centered-below.
<eun-table selectable action-bar-viewport-centered-below="laptop"></eun-table>
<eun-table selectable action-bar-viewport-centered-below="900"></eun-table>
The same value can come from CSS, through
--table-action-bar-viewport-centered-below, for instance to change it with your
own media queries. Set it on the bar or on one of the page's ancestors,
since a table's bar is placed next to the table, not inside it. The
attribute wins over it.
eun-table-action-bar {
--table-action-bar-viewport-centered-below: 900px;
}
Narrow screens
When the actions don't fit, the center region scrolls sideways instead of wrapping onto a second line, so the bar keeps a single row and its height. What goes in the center stays up to you.
Add collapsible to win more room first: once the bar lacks space, the
count badge shows only the number and the select-all button only its
icon. Both keep their full label for screen readers, and the button shows
it as a tooltip on hover. The bar expands again as soon as there's room.
<eun-table-action-bar collapsible></eun-table-action-bar>
Customized
Every visual piece is a --table-action-bar-* custom property, so restyle
it to match a brand accent instead of the neutral default.
<eun-table-action-bar
style="
--table-action-bar-background: var(--eun-color-primary-alpha-20, #3d6fff33);
--table-action-bar-border-color: var(--eun-color-primary-500, #3d6fff);
--table-action-bar-shadow: var(--eun-shadow-l, 0 20px 25px -5px rgba(0, 0, 0, 0.1));
color: var(--eun-color-on-primary-500, #ffffff);
"
></eun-table-action-bar>
--table-action-bar-padding, --table-action-bar-gap and --table-action-bar-max-width adjust its spacing and width.
The custom properties that change colors, borders, shadows and corners, at a glance. The API tab lists every property of the component.
| Variable | Sets |
|---|---|
--table-action-bar-background |
Sets the background color |
--table-action-bar-border-color |
Sets the border color |
--table-action-bar-shadow |
Sets the box shadow |
--table-action-bar-border-radius |
Sets the corner radius of the action bar |
--table-action-bar-action-color |
Sets the text color of the actions without a color of their own |
--table-action-bar-count-background |
Sets the background color of the count badge |
--table-action-bar-count-color |
Sets the text color of the count badge |
role="region", with aria-label from toolbarAriaLabel (default
"Selection actions"), a labeled landmark rather than role="toolbar",
since its buttons stay ordinary, independent Tab stops with no shared
roving tabindex or arrow-key navigation between them. The landmark role
lets assistive tech jump straight to it through its own region/landmark
navigation command, rather than requiring a Tab run through everything
else on the page first, since the bar is portaled to the end of
document.body (see below) and so isn't necessarily anywhere near the
table in Tab order. The select-all button's accessible label includes
the total row count and reflects whether it currently reads "Select all"
or "Deselect all", while the close button's accessible label comes from
closeAriaLabel (default "Clear selection").
The count tag (visually "N selected") carries role="status" directly, a
live region, so the count is both exposed to assistive tech and
automatically re-announced every time it changes (a row is added to or
removed from the selection), not just readable once on first encounter.
Portaled directly onto document.body, outside eun-table's own DOM
subtree entirely: the same technique this library's tooltips/dropdown
menus use to always render above everything else, regardless of any
overflow/transform on an ancestor. Because of that, closing the bar
(the close button, or Escape while clearOnEscape is set) explicitly
hands focus back to the owning table, onto its header, or its first row
when it has none, rather than letting it silently fall to the document
body the way removing any other focused element would.
Its entrance animation is skipped under prefers-reduced-motion: reduce.