EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
Table·hook·@astryxdesign/core

useTableRowStatus

Hook that returns a TablePlugin which prepends a narrow column signaling per-row status. Return {status, label} for a semantic success, warning, or error: Table resolves the matching glyph and tone through the active theme. Return {color, icon?, label} for a custom marker: every color is paint-only, an omitted icon renders the stable 8px dot, and an explicit icon renders that caller-selected glyph. Named custom icons keep their released Icon color mapping; raw CSS custom icons inherit the caller's exact paint instead of the previous primary fallback. Existing callers require no source migration. label is required and becomes the accessible image name plus supplemental hover tooltip; return null for no indicator. The column header is visually blank but carries a screen-reader-only localized name ("Row status", i18n key @astryx.table.rowStatus.columnHeader). Memoize getStatus with useCallback for a stable plugin identity.

Open in Playground @astryxdesign/core/Table

Signature

Call shape
useTableRowStatus()

Showcases and examples

1 documented example

useTableRowStatus - Semantic and Custom Markers

A job table using both row-status paths: status resolves themed semantic glyphs and tones, while color stays a custom paint choice with an optional caller-selected icon or the stable dot.

Preview loads on approachPreview loads on approach
Exact source · table-row-status-table
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {
  Table,
  useTableRowStatus,
  proportional,
  pixel,
} from '@astryxdesign/core/Table';
import type {
  TableColumn,
  UseTableRowStatusConfig,
} from '@astryxdesign/core/Table';

interface Job extends Record<string, unknown> {
  id: string;
  name: string;
  owner: string;
  state: 'failed' | 'running' | 'queued' | 'succeeded' | 'needsAttention';
}

const jobs: Job[] = [
  {id: 'j1', name: 'build-core', owner: 'Ava', state: 'failed'},
  {id: 'j2', name: 'lint', owner: 'Liam', state: 'running'},
  {id: 'j3', name: 'unit-tests', owner: 'Zoe', state: 'succeeded'},
  {id: 'j4', name: 'docsite-deploy', owner: 'Max', state: 'queued'},
  {id: 'j5', name: 'smoke-test', owner: 'Mia', state: 'succeeded'},
  {
    id: 'j6',
    name: 'snapshot-review',
    owner: 'Noah',
    state: 'needsAttention',
  },
];

const columns: TableColumn<Job>[] = [
  {key: 'name', header: 'Job', width: proportional(2)},
  {key: 'owner', header: 'Owner', width: pixel(120)},
  {key: 'state', header: 'State', width: pixel(120)},
];

const jobStatus: UseTableRowStatusConfig<Job>['getStatus'] = job => {
  switch (job.state) {
    case 'failed':
      return {status: 'error', label: 'Failed'};
    case 'running':
      return {color: 'warning', icon: 'clock', label: 'Running'};
    case 'queued':
      return {color: 'gray', label: 'Queued'};
    case 'succeeded':
      return {status: 'success', label: 'Succeeded'};
    case 'needsAttention':
      return {status: 'warning', label: 'Needs attention'};
  }
};

export default function TableRowStatusTable() {
  const rowStatus = useTableRowStatus<Job>({getStatus: jobStatus});

  return (
    <Table
      data={jobs}
      columns={columns}
      idKey="id"
      hasHover
      plugins={{rowStatus}}
    />
  );
}

Usage

Hook that returns a TablePlugin which prepends a narrow column signaling per-row status. Return {status, label} for a semantic success, warning, or error: Table resolves the matching glyph and tone through the active theme. Return {color, icon?, label} for a custom marker: every color is paint-only, an omitted icon renders the stable 8px dot, and an explicit icon renders that caller-selected glyph. Named custom icons keep their released Icon color mapping; raw CSS custom icons inherit the caller's exact paint instead of the previous primary fallback. Existing callers require no source migration. label is required and becomes the accessible image name plus supplemental hover tooltip; return null for no indicator. The column header is visually blank but carries a screen-reader-only localized name ("Row status", i18n key @astryx.table.rowStatus.columnHeader). Memoize getStatus with useCallback for a stable plugin identity.

Typed props

PropType and behavior
getStatus(item: T) => ({ status: 'success' | 'warning' | 'error'; color?: never; icon?: never; label: string } | { status?: never; color: 'accent' | 'success' | 'error' | 'warning' | 'red' | 'orange' | 'green' | 'yellow' | 'blue' | 'gray' | string; icon?: IconName; label: string }) | null · required
Derive either a semantic outcome or a custom marker. {status, label} accepts the closed success/error/warning vocabulary and resolves its glyph and tone through the active theme. {color, icon?, label} preserves the stable custom-marker path: color always selects paint, no icon renders an 8px dot, and icon renders the explicit caller glyph. Even color values named success/error/warning remain dots without icon. Valid icon names: close, chevronDown, chevronLeft, chevronRight, chevronsLeft, chevronsRight, check, success, error, warning, info, calendar, clock, externalLink, menu, moreHorizontal, search, arrowUp, arrowDown, arrowsUpDown, funnel, eyeSlash, viewColumns, copy, checkDouble, wrench, stop, microphone. The branches are exclusive, label is required and announced via role="img", and null leaves the row status cell empty. Memoize with useCallback for a stable plugin identity.