The DataTb component provides a powerful, flexible way to display tabular data from various sources with built-in sorting, filtering, and pagination. Built on React and TanStack Table.


Live Examples

Minimal example

Load data from a CSV file with automatic column detection:

<DataTb
csv="/data/ksa.csv"
searchable
pagination
client:load
/>
Loading data...

CSV with Custom Columns

Same data with customized column display and formatting:

<DataTb
csv="/data/ksa.csv"
columns={[
{ key: 'Item_Label', header: 'Site ID', sortable: true },
{ key: 'Name', header: 'Name', sortable: true },
{ key: 'Site_Name', header: 'Site Name' },
{ key: 'Survey_Year', header: 'Survey Year', format: 'number' },
{ key: 'Subregion', header: 'Subregion' }
]}
searchable
pagination={{ pageSize: 5, showPageSize: true }}
initialSort={{ columnKey: 'Item_Label', direction: 'asc' }}
client:load
/>
Loading data...

Inline JSON Data

Display data directly from JSON:

export const jsonData = [
{ language: 'JavaScript', year: 1995, creator: 'Brendan Eich' },
{ language: 'Python', year: 1991, creator: 'Guido van Rossum' },
{ language: 'Java', year: 1995, creator: 'James Gosling' },
{ language: 'TypeScript', year: 2012, creator: 'Anders Hejlsberg' },
{ language: 'Rust', year: 2010, creator: 'Graydon Hoare' }
];
<DataTb
json={jsonData}
searchable
pagination={false}
client:load
/>
Loading data...

API with Transformer

Fetch data from a public API and transform it:

<DataTb
api="https://jsonplaceholder.typicode.com/todos"
columns={[
{ key: 'title', header: 'Title', sortable: true },
{ key: 'userId', header: 'User ID' },
{ key: 'completed', header: 'Status', labels: { 'true': '✅ Done', 'false': '⏳ Pending' } }
]}
searchable
pagination={{ pageSize: 10 }}
client:load
/>
Loading data...

Directus Integration

Load data from a Directus collection using the simplified interface.

Note: This example requires PUBLIC_DIRECTUS_URL and PUBLIC_DIRECTUS_TOKEN environment variables in your .env file

<DataTb
directus={{
table: "scms_ksa",
queryString: "limit=-1&offset=0",
}}
searchable
pagination
client:load
/>
Loading data...

Complex Transformations (The Wrapper Pattern)

Question: “Can I use functions for complex transformations?”

Answer: Not directly inside MDX props (due to serialization limits), but YES by using a Wrapper Component.

Create a React component (AdvancedTable.tsx) that defines your columns with functions, and import it here.

AdvancedTable.tsx
export default function AdvancedTable() {
const columns = [
{
key: 'priority',
render: (val) => <span className={...}>{val}</span>
},
{
key: 'action',
render: (_, row) => <button onClick={() => alert(row.title)}>Click Me</button>
}
];
return <DataTb columns={columns} ... />
}
// YourPage.mdx
import AdvancedTable from '@components/AdvancedTable';
<AdvancedTable client:load />
Loading data...

Props API

DataTbProps

PropTypeDefaultDescription
csvstringURL to a CSV file
jsonany[] | stringInline array or URL to JSON
apistringAPI endpoint URL (returns array)
directusDirectusShorthandDirectus collection shorthand
sourceSourceConfigAdvanced source configuration
columnsColumnConfig[]auto-detectedColumn definitions
searchablebooleanfalseShow global search box
paginationboolean | PaginationConfigfalseEnable pagination
sortablebooleantrueEnable column sorting
initialSort{ columnKey, direction }Default sort state
truncateContentbooleantrueTruncate long cell values
truncateMaxWidthstring'20rem'CSS max-width for truncated cells
contentSize'sm' | 'md''sm'Table body font size
loadingMessagestringCustom loading text
emptyMessagestringCustom empty-state text
errorMessagestringCustom error text

ColumnConfig

interface ColumnConfig {
key: string; // Data property key
header: string; // Display header
sortable?: boolean;
format?: 'date' | 'number' | 'currency' | 'percent';
labels?: Record<string, string>; // Value mapping, e.g. { "true": "Yes" }
width?: string; // CSS width
render?: (value: any, row: DataRow) => React.ReactNode;
}

PaginationConfig

interface PaginationConfig {
pageSize?: number; // Default: 10
showPageSize?: boolean; // Show page-size selector
pageSizeOptions?: number[];
}

SourceConfig (advanced)

type SourceConfig =
| { type: 'csv'; url: string; delimiter?: string; skipRows?: number; }
| { type: 'json'; data?: any[]; url?: string; }
| { type: 'api'; url: string; method?: 'GET'|'POST'; headers?: Record<string,string>; transformer?: (data: any) => any[]; }
| { type: 'directus'; config: { url: string; token: string; }; collection: string; filter?: ...; fields?: ...; limit?: number; }
| { type: 'geojson'; url?: string; data?: any; }
| { type: 'vector'; url?: string; }

DirectusShorthand

interface DirectusShorthand {
table: string;
queryString?: string; // e.g. "filter[status][_eq]=published&limit=10"
url?: string; // defaults to PUBLIC_DIRECTUS_URL env var
token?: string; // defaults to PUBLIC_DIRECTUS_TOKEN env var
}

Accessibility

  • Full keyboard navigation for sorting and pagination
  • Proper ARIA labels and table semantics
  • Clear focus indicators and logical tab order
  • Accessible loading and error state announcements