Components

Action cell

The trailing action column of a Yuno table, pinned right so the action stays in reach when the table scrolls sideways. The Eye when the click goes straight to the detail; the dots when it opens a menu first, even a menu of one. ActionHead is its header. They are the table cells themselves: put them in the row, not inside a <TableCell>.

Updated Oct 12, 2026 by Juan Pablo Turina

Anatomy

A <td> pinned to the right edge (sticky right-0 z-10, w-10, pl-4 pr-4) holding one 32px icon button with a tooltip. While columns are hidden to the right it gets a divider and its header a CaretRight; its fill is the row's own, at rest, on hover and when selected.

RuleStatusActions
Block high-risk BINsActive
  1. 1
    Pinned cell

    sticky right-0 z-10 w-10 pl-4 pr-4. The fill follows the row: bg-background at rest (like the Table frame), the row's hover tint on hover, bg-muted when the row is selected, so nothing scrolling underneath shows through and the cell never reads as a separate block.

  2. 2
    Divider and caret

    While columns are hidden to the right (Table marks the frame data-more-right), the column draws a 1px divider (an inset shadow: a collapsed border would scroll away from a pinned cell) and ActionHead shows a CaretRight, centred over the column like the eye or dots below it: there is more to the right, passing under this column. On a table that fits, or one scrolled to its end, neither: the last column then sits right beside it.

  3. 3
    Icon button

    32px, transparent until hover (border, bg-background, shadow-xs), muted icon going to foreground. Eye (light) when the click goes straight to the detail, DotsThreeOutline (fill) when a menu comes first. Its tooltip is the label; its click never reaches the row.

Recipes

Click a row, an eye, or a menu item: this line says which fired.

Straight to the detail: the eye

The click goes straight to the detail, a Sheet or a page, with no menu in between. The row can open the same detail on its own click; the eye is the visible, keyboard-reachable way in. The eye's click does not also fire the row's (try both).

RuleStatusActions
Block high-risk BINsActive
3DS above 500 USDActive
Retry soft declinesInactive
import { ActionCell, ActionHead } from "@/components/ui/action-cell";
import { StatusBadge } from "@/components/ui/badge";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";

const rules = [
  { name: "Block high-risk BINs", status: "succeeded", label: "Active" },
  { name: "Retry soft declines", status: "inactive", label: "Inactive" },
] as const;
const openRule = (rule: (typeof rules)[number]) => { /* open its Sheet */ };

<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Rule</TableHead>
      <TableHead>Status</TableHead>
      <ActionHead />
    </TableRow>
  </TableHeader>
  <TableBody>
    {rules.map((r) => (
      <TableRow key={r.name} className="cursor-pointer" onClick={() => openRule(r)}>
        <TableCell>{r.name}</TableCell>
        <TableCell><StatusBadge status={r.status}>{r.label}</StatusBadge></TableCell>
        <ActionCell label="View details" onClick={() => openRule(r)} />
      </TableRow>
    ))}
  </TableBody>
</Table>
A menu first: the dots

The click opens a menu first: edit, duplicate, delete. A menu of one item is still the dots. Pass the DropdownMenuItems as children and the cell becomes the dots opening them, aligned to the end. Choosing an item never opens the row.

RuleStatusActions
Block high-risk BINsActive
3DS above 500 USDActive
Retry soft declinesInactive
import { ActionCell } from "@/components/ui/action-cell";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";

// Inside a row, as its last cell; r is the row's data.
<ActionCell label="Actions">
  <DropdownMenuItem onSelect={() => edit(r)}>Edit</DropdownMenuItem>
  <DropdownMenuItem onSelect={() => duplicate(r)}>Duplicate</DropdownMenuItem>
  <DropdownMenuItem onSelect={() => remove(r)}>Delete</DropdownMenuItem>
</ActionCell>
A table that scrolls

More columns than the container is wide. The action column stays pinned, with its divider and a CaretRight in its header, because there are columns hidden to the right, passing under it. Scroll to the end: the last column lands beside it and both go. In the tables above, which fit, neither shows.

OrderMerchantMethodCountryProviderCreatedActions
ORD-88213RappiVisaColombiaAdyenFeb 8, 2023, 10:00 a.m.
ORD-88214RappiPIXBrazildLocalFeb 8, 2023, 10:04 a.m.
ORD-88215RappiMastercardMexicoStripeFeb 8, 2023, 10:09 a.m.
import { ActionCell, ActionHead } from "@/components/ui/action-cell";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";

// Nothing to add: the column pins itself, and its divider and the
// header's CaretRight appear only while columns are hidden to the right.
<Table>
  <TableHeader>
    <TableRow>
      <TableHead className="min-w-40">Order</TableHead>
      {/* …more columns than the container is wide… */}
      <ActionHead />
    </TableRow>
  </TableHeader>
  <TableBody>
    {rows.map((r) => (
      <TableRow key={r.id}>
        <TableCell>{r.id}</TableCell>
        {/* … */}
        <ActionCell label="View details" onClick={() => openPayment(r)} />
      </TableRow>
    ))}
  </TableBody>
</Table>

Import

Copy this import line at the top of the file where you compose this atom.

ActionCell and ActionHead come together: ActionHead in the header row, ActionCell as the last cell of each body row. Both need the app's TooltipProvider, like every kit tooltip.
import { ActionCell, ActionHead } from "@/components/ui/action-cell";

Props

Everything else from the underlying HTML or Radix primitive is forwarded via ...props.

PropTypeDefaultDescription
labelstring (required)—ActionCell: the button's accessible name and tooltip. "View details" for the eye, "Actions" for the menu.
onClick() => void—ActionCell: where the eye goes, straight to the detail. Ignored when children are given.
childrenReactNode—ActionCell: DropdownMenuItems. When present the cell shows the dots and opens this menu, even with one item.
label (ActionHead)string"Actions"ActionHead: the column's name for screen readers. It is not shown.
classNamestring—Extra classes on the <td> / <th>. Rarely needed: the pinning, divider and fill are the point of the component.

Related

Cross-links to atoms and patterns you may reach for next.

  • TableThe host, and the Cell types list this cell came from (Eye action, Dots action).
  • Dropdown menuWhat the dots open; its items go in as children.