DataTable & State Variations
Relevant source files
The following files were used as context for generating this wiki page:
The DataTable component provides a standardized way to render tabular data with integrated support for common UI states including loading, empty, and interactive rows. It avoids manual implementation of sticky headers, row hovering, and data boundaries by consolidating these behaviors into a single layout component.
Unlike many data table libraries, this component does not manage data fetching, sorting, or pagination. It serves exclusively as a rendering layer that consumes processed data provided by the user.
Sources: src/layout/DataTable.tsx:18-36, src/index.ts:108-111
Component Architecture
The DataTable follows three core design constraints:
- No Data Management: The component remains agnostic to the data source (polling, SSE, or shared stores). The user provides the
rowsand handles logic like filtering or sorting. - CSS Grid Alignment: It uses native browser column width algorithms via
<col>styles instead of manual percentage calculations. - Sticky Headers by Default: It enables
stickypositioning with abackdrop-blureffect to maintain context during long-scroll operations.
Sources: src/layout/DataTable.tsx:25-41
Data Flow and State Decision Logic
The component determines its visual output based on the priority of input states: Loading > Empty > Data.
State Variations
Loading State
When the loading prop is true, the table renders a set number of Skeleton rows (defaulting to 5). Each skeleton row uses varying widths to simulate natural data length.
- Logic: Uses
Array.fromto create placeholder rows. - Visuals: Utilizes
src/primitives/skeleton.tsxfor animated bars.
Sources: src/layout/DataTable.tsx:88-99
Empty and Error States
If the rows array is empty and the component is not loading, it renders the EmptyState component. The DataBoundary utility wrapper can further extend this to handle specific error states.
| State Kind | Icon | Purpose |
|---|---|---|
empty | solar--inbox-linear | Default state when no data exists. |
error | solar--danger-triangle-linear | Indicates a failure in data retrieval. |
loading | solar--refresh-linear | Indicates data is currently being fetched. |
denied | solar--lock-keyhole-minimalistic-linear | Indicates insufficient permissions. |
Sources: src/layout/EmptyState.tsx:14-38, src/layout/DataTable.tsx:128-130
Interactivity and Row States
Rows support hover states and click events. If onRowClick is provided, the table applies a cursor-pointer and enables keyboard accessibility (Enter/Space triggers).
Sources: src/layout/DataTable.tsx:103-120
Configuration and Props
DataTableColumn Definition
Each column is defined by a DataTableColumn<T> object, allowing for custom rendering and alignment.
| Property | Type | Description |
|---|---|---|
key | string | The ID of the column; looks up row[key] by default. |
header | ReactNode | The text or element to show in the header. |
render | (row: T, index: number) => ReactNode | Optional custom renderer for cell content. |
width | string | Manual width (e.g., "100px"), applied via CSS <col>. |
numeric | boolean | If true, applies right-alignment and tabular-nums. |
Sources: src/layout/DataTable.tsx:47-59
Search and Filtering Logic
The useTableSearch hook provides a standardized way to implement client-side filtering that remains synchronized with the table's state.
export function useTableSearch<T>(
rows: readonly T[],
match: (row: T, query: string) => boolean,
): { query: string; setQuery: (q: string) => void; filtered: readonly T[] } {
const [query, setQuery] = useState("");
const filtered = useMemo(() => {
const q = query.trim().toLowerCase();
if (!q) return rows;
return rows.filter((r) => match(r, q));
}, [rows, query, match]);
return { query, setQuery, filtered };
}
Sources: src/layout/DataTable.tsx:162-174
Visual Tokens
The table styling is derived from the global Design Tokens defined in src/tokens.css.
- Font Sizes: Header uses
--fs-xs(11px) while cells use--fs-sm-half(12.5px). - Colors: Uses
--borderfor row separators and--accentfor row hover highlights. - Sticky Header: Uses
bg-background/95withbackdrop-blur-smto prevent visible "hard edges" against rounded card corners.
Sources: src/layout/DataTable.tsx:77-80, src/tokens.css:170-184
Conclusion
The DataTable component serves as a robust layout wrapper that enforces visual consistency across the application. By centralizing the handling of loading, empty, and interactive states, it reduces code duplication and ensures high usability standards, such as accessible row interactions and sticky positioning, are met by default.