Skip to content

Table

Introduction

The Table component provides a highly flexible and feature-rich data table for displaying, sorting, searching, selecting, and paginating tabular data. It supports custom cell rendering, multiple visual variants, selectable rows, loading and empty states, and advanced customization for headers, footers, and row styling. The API is designed to be both declarative and extensible, making it suitable for dashboards, admin panels, and any data-driven UI.

Import

ts
import { Table } from '@odyssee/components';

LiveCodeEditor examples

Basic Table

Code Éditable
Résultat

Striped, Bordered, and Rounded Variants

Code Éditable
Résultat

Selectable Rows

Code Éditable
Résultat

Sortable and Searchable

Code Éditable
Résultat

Paginated Table

Code Éditable
Résultat

Custom Cell Render

Code Éditable
Résultat

Props

PropTypeDefaultDescription
columnsTable.Column<T>[]Array of column definitions (see below for shape).
dataT[]Array of row data.
variant"default" | "striped" | "bordered" | "rounded" | "shadow""default"Visual style of the table.
theadVariant"default" | "gray" | "divided""default"Style of the table header.
size"sm" | "md" | "lg""md"Table size (affects row/cell padding).
hoverablebooleanfalseHighlight rows on hover.
selectablebooleanfalseEnable row selection (checkboxes).
selectedRowsSignal<(string | number)[]> | (string | number)[]Controlled selected row IDs.
onSelectionChange(selected: (string | number)[]) => voidCallback when selection changes.
sortablebooleanfalseEnable sorting on sortable columns.
sortBySignal<string | null> | string | nullControlled sort column key.
sortDirectionSignal<"asc" | "desc" | null> | "asc" | "desc" | nullControlled sort direction.
onSort(column: string, direction: "asc" | "desc" | null) => voidCallback when sorting changes.
searchablebooleanfalseEnable search input above the table.
searchValueSignal<string> | stringControlled search value.
searchPlaceholderstringPlaceholder for the search input.
onSearch(value: string) => voidCallback when search value changes.
paginatedbooleanfalseEnable pagination controls.
currentPageSignal<number> | numberControlled current page.
pageSizenumberNumber of rows per page.
totalPagesnumberTotal number of pages.
onPageChange(page: number) => voidCallback when page changes.
captionstringTable caption (displayed above the table).
showFooterbooleanShow the table footer.
footerContentJSX.ElementCustom footer content.
headlessbooleanfalseHide the table header.
loadingboolean | Signal<boolean>falseShow loading state (skeleton rows).
loadingRowsnumber5Number of skeleton rows to show when loading.
emptyMessagestring | JSX.ElementMessage to display when there is no data.
onRowClick(row: T, index: number) => voidCallback when a row is clicked.
rowClassName(row: T, index: number) => stringFunction to add custom classes to rows.
rowKeykeyof TProperty to use as the row key (defaults to id if present).
classNamestringAdditional CSS classes for the table container.
...restAny other props are spread to the root container.

Table.Column shape

PropTypeDefaultDescription
keystringUnique key for the column (matches property in row data).
labelstringColumn header label.
widthstringCSS width for the column (e.g., "120px" or "20%").
align"start" | "center" | "end"Cell alignment.
sortablebooleanfalseWhether the column is sortable.
render(value, row, index) => JSX.Element | stringCustom cell renderer for this column.
headerRender() => JSX.Element | stringCustom header renderer for this column.
classNamestringAdditional classes for cells in this column.
headerClassNamestringAdditional classes for the column header.

Implementation notes

  • The Table component is fully controlled or uncontrolled for selection, sorting, searching, and pagination.
  • Supports custom cell and header rendering via render and headerRender in columns.
  • Visual variants (striped, bordered, rounded, shadow) and header variants (gray, divided) are available.
  • Loading and empty states are handled natively.
  • Row selection, sorting, searching, and pagination can be combined.
  • The rowClassName prop allows dynamic row styling (e.g., highlight inactive rows).
  • The table is responsive and supports custom sizing via the size prop.

Accessibility

  • The table uses semantic <table>, <thead>, <tbody>, <tr>, <th>, and <td> elements.
  • Checkbox selection is accessible via keyboard and screen readers.
  • Sorting and pagination controls are accessible and labeled.
  • The caption is rendered with the <caption> element for assistive technologies.
  • Ensure custom cell renderers and interactive content are accessible and keyboard-navigable.

Best practices

  • Use concise, descriptive column labels.
  • Prefer unique id or rowKey for row identification.
  • Use variant and theadVariant to match your application's style.
  • For large datasets, enable pagination and search for better usability.
  • Use custom cell renderers for avatars, badges, or action buttons.
  • Avoid overloading the table with too many columns; keep it readable and focused.

Released under the MIT License.