EXEPERTAI LAB

Research alpha

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

Table Selection Toolbar

Selection-aware bulk-action surface built on Toolbar. Pass selectionState from useTableSelectionState so count, visibility, and complete clearing stay synchronized with the Table selection plugin. The component owns no table or sticky layout: place it in flow or apply caller-owned positioning through xstyle.

Open in Playground @astryxdesign/core/Table

Showcases and examples

12 documented examples · Context from Table

Table — Paginated Data

Paginated data table navigating through a larger dataset page by page.

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

'use client';

import {useState} from 'react';
import {
  Table,
  useTablePagination,
  paginateData,
  proportional,
} from '@astryxdesign/core/Table';
import type {TableColumn} from '@astryxdesign/core/Table';
import {Section} from '@astryxdesign/core/Section';

interface User extends Record<string, unknown> {
  id: string;
  name: string;
  email: string;
  role: string;
}

const names = [
  'Alice Johnson',
  'Bob Smith',
  'Charlie Brown',
  'Diana Prince',
  'Eve Davis',
  'Frank Miller',
  'Grace Lee',
  'Hank Wilson',
  'Ivy Chen',
  'Jack Turner',
  'Karen White',
  'Leo Garcia',
  'Mia Thompson',
  'Noah Martinez',
  'Olivia Clark',
  'Paul Harris',
  'Quinn Walker',
  'Rachel Adams',
  'Sam Robinson',
  'Tina Scott',
];

const roles = ['Engineer', 'Designer', 'Manager', 'Admin', 'Analyst'];

const users: User[] = names.map((name, i) => ({
  id: String(i + 1),
  name,
  email: `${name.split(' ')[0].toLowerCase()}@example.com`,
  role: roles[i % roles.length],
}));

const columns: TableColumn<User>[] = [
  {key: 'name', header: 'Name', width: proportional(1)},
  {key: 'email', header: 'Email', width: proportional(2)},
  {key: 'role', header: 'Role', width: proportional(1)},
];

export default function TablePaginatedTable() {
  const [page, setPage] = useState(1);
  const pageSize = 5;

  const plugin = useTablePagination<User>({
    page,
    onPageChange: setPage,
    totalItems: users.length,
    pageSize,
  });

  return (
    <Section>
      <Table
        data={paginateData(users, page, pageSize)}
        columns={columns}
        idKey="id"
        plugins={{pagination: plugin}}
      />
    </Section>
  );
}

Usage

Pass both outputs of useTableSelectionState to their matching consumers: selectionConfig to useTableSelection and selectionState to TableSelectionToolbar. Render product actions through startContent. Keep fixed or floating placement in the surrounding layout.

  • Pass selectionState directly from useTableSelectionState so the count and clear action stay synchronized with row selection.
  • Provide product actions as startContent instead of encoding them as configuration objects.
  • Inject the toolbar through the Table plugin or its horizontal scroll wrapper.

Typed props

PropType and behavior
selectionTableSelectionState · required
Shared selection state returned by useTableSelectionState: selectedKeys, selectedCount, hasSelection, and clearSelection.
startContentReactNode
Product-owned action controls aligned to the logical start. Child controls inherit the toolbar size.
labelstring · default Bulk actions
Accessible name for the action surface.
renderSelectionLabel(selectedCount: number) => ReactNode · default count => `${count} selected`
Overrides the visible count text for localisation or domain-specific copy.
clearLabelstring · default Unselect All
Visible label for the command that clears the complete controlled selection.
size'sm' | 'md' | 'lg' · default sm
Toolbar size. Cascades to product action controls and the clear action.
variantSectionVariant · default muted
Toolbar surface variant.
xstyleStyleXStyles
Caller-owned layout styles, including sticky positioning for floating compositions.