Eunomia v1.0.0-beta.2
AllAngularReactNext.jsJavaScriptVue
EunomiaSalmonForestVioletOceanGoldFireCustom…
🇬🇧 English🇫🇷 Français

Item

Item is a single data row of a table. Slot in cell elements, one per column, in the same order the owning header's columns use, with content that's entirely free-form. An optional trailing action slot (a button or dropdown button, typically) renders in a trailing cell, revealed only on hover or focus.

Dependencies

eun-checkbox · renders this row's own checkbox, once the owning table is selectable
Overview API Examples Accessibility
Name Status Ada Lovelace Active

When to use

Set a stable row identifier from your own data whenever rows can be sorted, filtered, reordered, or paginated, since the fallback used when it's unset stays correct only while row order never changes. A dedicated pinning flag pins an individual row (a totals row, typically) to the bottom of the table's own scroll container, and the consumer marks which row or rows, rather than the table guessing "the last one" from DOM order, which would break the moment rows are re-sorted or a new one is appended.

Clicking a row fires a row-click event, unless the owning table is in selection mode (at least one row already checked), where a click toggles that row's own selection instead. Its selection state and the sticky-column flags are all pushed down by the owning table itself, so never set them directly.

Install & usage

npm install @eunomia/elements
import "@eunomia/elements/table-item.js";
import "@eunomia/elements/table-cell.js";
<eun-table-item row-key="1">
  <eun-table-cell>Ada Lovelace</eun-table-cell>
  <eun-table-cell>Active</eun-table-cell>
</eun-table-item>

<script type="module">
  document
    .querySelector("eun-table-item")
    .addEventListener("euntablerowclick", (event) => console.log(event.rowKey));
</script>

Everything beyond the checkbox (every eun-table-cell and whatever you slot into slot="action") is markup you author yourself.

Properties

Item <eun-table-item>

Attributes

NameTypeDefaultDescription
row-keystringThis row's stable identity, used for selection tracking. Falls back to a DOM-order-derived key when unset, which is unstable across client-side sort or filter, so set this explicitly for any such table
sticky-bottombooleanfalsePins this row to the bottom of its scroll container, such as a totals row. The consumer marks which rows, rather than the table inferring the last row from DOM order

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

Slots

NameDescription
(default)Table cell elements, one per column
actionOptional trailing action content, such as a button or a dropdown button, revealed on hover or focus, or always with the owning table's actionAlwaysVisible. Hidden and inert (unfocusable, unclickable) while any row is selected either way

Events

NameTypeDescription
euntablerowclickTableRowClickEventFired on a row click outside its checkbox or action cell and outside selection mode, whether or not this row or the owning table has any row-end action at all

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

CSS custom properties

NameDescription
--table-row-backgroundSets the background color
--table-row-hover-backgroundSets the background color on hover
--table-row-selected-backgroundSets the background color while selected
--table-sticky-row-backgroundSets the background color of this row while stickyBottom, at rest. Falls back to table-row-background
--table-sticky-column-backgroundSets the background color of this row's sticky first or last column cell, and its checkbox cell once the owning table is selectable, at rest. Falls back to table-row-background
--table-checkbox-backgroundSets the background color of this row's own unchecked checkbox, once the owning table is selectable
--table-checkbox-hoverSets the background color of this row's own unchecked checkbox while hovered, once the owning table is selectable
--table-sticky-border-colorSets the border color of this row's own top edge while stickyBottom, falling back to table-border-color, and of the trailing edge of the always-sticky checkbox cell and any sticky first or last column cell, transparent by default
--table-action-colorSets the text and icon color of a row-end action, bridging into a slotted button's or dropdown button's own text color
--table-sync-overlay-colorSets the highlight color of the shimmer sweep shown while the owning table's syncing is set
--table-sync-durationSets the duration of the syncing shimmer sweep, as a CSS time, defaulting to 1.6 seconds

Row-end action: dropdown vs. plain button

slot="action" accepts anything: most often a eun-dropdown-button for several choices, or a single eun-button when there's only ever one thing to do. Both are ordinary slotted content, so nothing stops one row from using a dropdown and another a plain button in the very same table (see each on its own below), and a mix of both together. Hover or focus a row to reveal its own trailing control.

Several choices: a dropdown button

Name Status Ada Lovelace Active Grace Hopper Active
<!-- A row whose action opens a menu of several choices -->
<eun-table-item row-key="1">
  <eun-table-cell>Ada Lovelace</eun-table-cell>
  <eun-table-cell><eun-tag severity="success">Active</eun-tag></eun-table-cell>
  <eun-dropdown-button
    slot="action"
    size="xs"
    appearance="ghost"
    icon="more_vert"
    aria-label="Row actions"
    .options=${[
      { key: "edit", label: "Edit" },
      { key: "archive", label: "Archive" },
    ]}
  ></eun-dropdown-button>
</eun-table-item>

Exactly one thing to do: a plain button

Name Status Grace Hopper Pending Alan Turing Pending
<!-- A row whose action is a single, one-click operation -->
<eun-table-item row-key="2">
  <eun-table-cell>Grace Hopper</eun-table-cell>
  <eun-table-cell><eun-tag severity="warning">Pending</eun-tag></eun-table-cell>
  <eun-button
    slot="action"
    size="xs"
    appearance="ghost"
    aria-label="Resend invite"
    @click="${()"
    =""
  >
    resendInvite(row)} >
    <eun-icon name="mail" size="16"></eun-icon>
  </eun-button>
</eun-table-item>

Mixed in the same table

Nothing stops one row from using a dropdown and another a plain button, in the very same table, since each row's own action is entirely independent.

Name Status Ada Lovelace Active Grace Hopper Pending

Pinned row

Give the table a bounded height (here 220px, via inline style or --table-max-height) so there's actually something to scroll: 8 team rows below don't all fit at once. Scroll the demo and watch the Total row stay pinned to the bottom the whole way, while every other row scrolls normally underneath it, exactly the "pin a totals row" case sticky-bottom is for.

Team Budget Engineering $120k Design $40k Product $50k Marketing $35k Sales $80k Support $28k Finance $45k Operations $32k Total $430k
<eun-table style="max-height: 220px;">
  <eun-table-header>
    <eun-table-column width="1fr">Team</eun-table-column>
    <eun-table-column width="120px">Budget</eun-table-column>
  </eun-table-header>
  <eun-table-item row-key="1">
    <eun-table-cell>Engineering</eun-table-cell>
    <eun-table-cell>$120k</eun-table-cell>
  </eun-table-item>
  <!-- ...6 more rows... -->
  <eun-table-item row-key="total" sticky-bottom style="font-weight: 600;">
    <eun-table-cell>Total</eun-table-cell>
    <eun-table-cell>$430k</eun-table-cell>
  </eun-table-item>
</eun-table>

role="row", with aria-selected reflecting selected while the owning table is selectable. It participates in the owning eun-table's roving-tabindex grid. See Table: Accessibility for the full keyboard pattern. Both the checkbox and the row-end action reveal on :hover and :focus-within, so a keyboard user tabbing toward either sees it appear before activating it.