Table Components Example
Demonstrates the full table system in src/common/components/table: DataTable, headers, cells, pagination and empty state.
Full-featured DataTable
Search, batch operations, row selection, sorting, filtering, column visibility, editable cells and pagination — all in one table.
| ID | Name | Status | Gender | Amount | Currency | Age | Active | Remark | Sort | Created | Actions | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Alice | alice@example.com | Enable | $1,280.50 | USD | 28 | 2023-11-15 06:13:20 | |||||||
2 | Bob | bob@example.com | Enable | €640.00 | EUR | 35 | 2023-11-15 06:13:22 | |||||||
3 | Carol | carol@example.com | Disable | $3,200.00 | USD | 42 | 2023-11-15 06:13:24 | |||||||
4 | David | david@example.com | Enable | CN¥900.00 | CNY | 31 | 2023-11-15 06:13:26 | |||||||
5 | Eve | eve@example.com | Disable | ¥1,560 | JPY | 26 | 2023-11-15 06:13:28 |
Tree table
Hierarchical rows with expand/collapse using TreeCell.
| Name | Amount | Status | ||||
|---|---|---|---|---|---|---|
Engineering | Engineering | eng@example.com | $5,000.00 | Enable | ||
Marketing | Marketing | mkt@example.com | €1,500.00 | Enable |
Pagination primitives
Standalone Pagination / PaginationContent / PaginationItem / PaginationLink building blocks.
Empty state
EmptyRow shows a placeholder when there are no rows.
| Name | Status | |
|---|---|---|
| No results. | ||
Table Components (components/table) Usage Guide
Overview
src/common/components/table/ is a table system built on @tanstack/react-table + shadcn/ui. The core is DataTable, working with headers (header/), cells (cell/) and pagination (pagination/pager).
DataTable enables via useReactTable: sorting, filtering, column visibility, row selection, expanding (tree) and manual pagination (manualPagination: true — you slice the page yourself, recordTotal is the total count).
DataTable — the core table
import {DataTable} from "@/common/components/table/data-table";
<DataTable<T>
columns={columns}
result={result}
setData={setResult}
tableName="UserExample"
primary="id"
i18n={true}
initHandler={init}
deleteHandler={deleteHandler}
EditComponent={EditPage}
RowOperationComponents={[]}
SearchComponent={Search}
OperationComponent={Operation}
defaultPager={{pageIndex: 0, pageSize: 10}}
/>
| Prop | Type | Required | Description |
|---|---|---|---|
| columns | ColumnDef<T,string>[] | Yes | Column definitions |
| result | Result | Yes | Data source; result.data = { list, recordTotal, dictionary } |
| setData | Dispatch<SetStateAction<Result>> | Yes | setState used to update result |
| initHandler | () => void | Yes | Reload (reset to page 1); called after row edit/delete |
| primary | string | No | Primary-key field name (used by deleteHandler) |
| tableName | string | No | i18n namespace; headers translate via useTranslations(tableName) |
| i18n | boolean | No | Translate headers (t.has(column.id)) and cell dictionaries (KVS.<field>.<value>) |
| hiddenColumns | VisibilityState | No | Initially hidden columns |
| SearchComponent | ComponentType<TableOperationProps> | No | Search bar; must assign meta.searchHandler |
| OperationComponent | ComponentType<TableOperationProps> | No | Toolbar (batch actions) |
| EditComponent | ComponentType<CellContextProps> | No | Row edit dialog content (wrapped in a Dialog by PopItem) |
| deleteHandler | (id) => void | No | Row delete callback |
| RowOperationComponents | ComponentType<CellContextProps>[] | No | Extra custom row actions in the action menu |
| parent | {} | No | Arbitrary context (the demo passes a controller via parent) |
| defaultPager | PaginationState | No | Default pagination |
Because
manualPaginationis true,result.data.listmust already be the current page; sorting/filtering stay client-side over the current page.
Cells (cell/)
Each cell factory returns a render component that you assign to a column's cell.
- NormalCell(field, width?, handler?) — plain text; maps through
result.data.dictionary[field]and translates viaKVS.<field>.<value>when i18n is on. - CheckBoxCell — row selection; pair with
CheckboxHeader; get selected ids viaTableUtils.getSelectedIds(table). - CurrencyCell(field, currencyField) — formats the amount with
Intl.NumberFormatusing the currency field. - InputCell(field, type, width?) — inline edit;
type="checkbox"renders a checkbox, otherwise an<Input>; writes back torow.original[field]. - SelectCell(field, i18n?, readOnly?) — inline select from
result.data.dictionary[field];readOnlyrenders text only. - SortableCell(field) — number input; on blur it re-sorts the current page by
sortand callssetData. - UnixTimestampCell(field, category?) — formats via
dayjstoYYYY-MM-DD HH:mm:ss. - TreeCell(field) — expand/collapse button + indent, showing
field; data must providesubRows. - OperationCell (internal) — triggered when a column's
cellis the string"Actions": edit (EditComponentdialog), delete (deleteHandler), custom row actions (RowOperationComponents).
Headers (header/)
- PlainTextHeader({columnTitle}) — plain text header;
i18noverrides witht(column.id). - NormalHeader({showFilter, showSort, columnTitle}) — wraps
ColumnOperationto add sort + filter. - CheckboxHeader — select-all / indeterminate.
- ColumnFilter() — column visibility dropdown listing columns where
getCanHide()is true. - EmptyHeader — blank header (used for the tree expander column).
Others
- ColumnOperation({columnTitle, showFilter, showSort, column}) — sort/filter controls inside a header.
- Pager({table}) — pagination bar for
DataTable; callsmeta.searchHandleron page change. - Pagination family — standalone pagination atoms (
Pagination/PaginationContent/PaginationItem/PaginationLink/PaginationPrevious/PaginationNext/PaginationFirst/PaginationLast/PaginationEllipsis). - EmptyRow({columnSize}) — no-data placeholder, rendered automatically by
DataTable. - CellRenderer — cell dispatcher (internal); routes
cell === "Actions"toOperationCell, otherwiseflexRender.