Eunomia v1.1.0
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

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 table are selected, made up of a count badge, a "select/deselect all" toggle, any number of custom actions, and a close button that clears the selection.

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

eun-tag · shows the selected count eun-button · renders the select-all/close controls and every plain action eun-dropdown-button · renders an action once it sets its own dropdown eun-divider · separates the three regions eun-icon · renders the action/select-all/close icons
Overview API Examples Accessibility

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 table once it's set to be selectable and at least one row is checked. See Table: Selection and the floating action bar. Use it directly, on its own, only when building a custom selection UI outside a table (a card grid with checkboxes, say) that wants the exact same bulk-action chrome.

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

NameTypeDefaultDescription
selected-countnumber0The number of currently selected rows
total-countnumber0The total number of selectable rows, used for the select-all accessible label
collapsiblebooleanfalseWhether 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-centeredboolean—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-labelstring'Selection actions'The accessible label for the toolbar itself ; translated from `locale` while unset
selected-labelstring'selected'Text shown after the count in the badge ; translated from `locale` while unset
select-all-labelstring'Select all'The label of the select-all button while not every row is selected ; translated from `locale` while unset
deselect-all-labelstring'Deselect all'The label of the select-all button once every row is selected ; translated from `locale` while unset
close-aria-labelstring'Clear selection'The accessible label for the close button ; translated from `locale` while unset

Import the exact TypeScript type behind any property above, see Types.

Properties

JS-only — no matching HTML attribute, set these from a script or a template binding.

NameTypeDefaultDescription
actionsArray<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

NameDescription
(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

NameTypeDescription
euntableactionTableActionEventFired when a custom action is activated

Every event above follows the same naming convention, covered in Events.

CSS custom properties

NameDescription
--table-action-bar-offset-bottomSets the distance from the bottom of the viewport
--table-action-bar-centerSets 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-backgroundSets the background color
--table-action-bar-border-colorSets the border color
--table-action-bar-shadowSets the box shadow
--table-action-bar-z-indexSets the stacking order, 100 by default
--table-action-bar-border-radiusSets the corner radius of the action bar
--table-action-bar-viewport-centered-belowSets 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-widthSets the max width of the bar. Defaults to the room left around its center, minus a margin on each side
--table-action-bar-paddingSets the padding inside the bar
--table-action-bar-gapSets the gap between the bar's groups and buttons
--table-action-bar-action-colorSets the text color of the actions without a color of their own
--table-action-bar-count-backgroundSets the background color of the count badge
--table-action-bar-count-colorSets the text color of the count badge

CSS shadow parts

NameDescription
barThe 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.

View activity
<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.