Table Component
The <reeflow-table> component displays data in a tabular format with support for row clicks, extensible sorting, and client-side row limiting.
Basic usage
Section titled “Basic usage”import { ReeflowProvider, ReeflowTable } from '@reeflow/react';
<ReeflowProvider authToken="your-token"> <ReeflowTable title="Customer Orders" query={{ from: 'orders', dimensions: ['customer_name', 'order_date'], measures: [ { column: 'revenue', type: 'sum' }, { column: 'quantity', type: 'sum' }, ], }} /></ReeflowProvider>;<reeflow-provider auth-token="your-token"> <reeflow-table title="Customer Orders"> <script type="application/json" slot="query"> { "from": "orders", "dimensions": ["customer_name", "order_date"], "measures": [ { "column": "revenue", "type": "sum" }, { "column": "quantity", "type": "sum" } ] } </script> </reeflow-table></reeflow-provider>Attributes
Section titled “Attributes”title (optional)
Section titled “title (optional)”Display a title above the table:
<reeflow-table title="Sales Report"> <!-- query --></reeflow-table>page-size (optional)
Section titled “page-size (optional)”Maximum number of rows to display. Default: 20
This limits the number of rows rendered from the data result. For true pagination with navigation, you need to implement it using JSONQL limit and offset (see Advanced usage).
<reeflow-table page-size="50"> <!-- query --></reeflow-table>theme (optional)
Section titled “theme (optional)”Override the theme inherited from the Provider:
<reeflow-table theme="ocean"> <!-- query --></reeflow-table>theme-mode (optional)
Section titled “theme-mode (optional)”Override the theme mode (light/dark/auto):
<reeflow-table theme-mode="dark"> <!-- query --></reeflow-table>Programmatic API
Section titled “Programmatic API”The table component provides several properties and methods for programmatic control:
data- Set or get table data directly without API callrefresh()- Reload data from the APIreset(clearQuery?)- Reset table state
Example:
const table = document.querySelector('reeflow-table');
// Set data directlytable.data = { columns: [{ name: 'Product', type: 'string' }], rows: [['Widget A'], ['Widget B']],};
// Get current dataconsole.log(table.data);
// Reload from APIawait table.refresh();
// Reset statetable.reset();For complete API documentation, see the SDK Reference.
Events
Section titled “Events”The table component emits lifecycle and interaction events.
Lifecycle events (all frameworks)
Section titled “Lifecycle events (all frameworks)”reeflow-state-change- Fired when component state changes (detail:{ state: ReeflowComponentState, oldState: ReeflowComponentState })reeflow-data-loaded- Data successfully loaded (detail: QueryResult)reeflow-error- Error occurred during loading (detail: ApiError with code, message, and optional details)
Interactive events
Section titled “Interactive events”In React, use event handler props with automatic detail extraction:
import { ReeflowTable } from '@reeflow/react';import { useState } from 'react';
function OrdersTable() { const [selectedRow, setSelectedRow] = useState(null);
return ( <div> <ReeflowTable query={query} onTableRowClick={(detail) => { console.log('Row clicked:', detail.row); console.log('Row index:', detail.rowIndex); setSelectedRow(detail.row); }} onTableSortChange={(detail) => { console.log('Sort column:', detail.column); console.log('Sort direction:', detail.direction); }} />
{selectedRow && ( <div className="selection-panel"> <h3>Selected Row</h3> <pre>{JSON.stringify(selectedRow, null, 2)}</pre> </div> )} </div> );}Available table event handlers:
onTableRowClick- Fired when a table row is clicked (receives{ row, rowIndex })onTableSortChange- Fired when a column header is clicked (receives{ column, direction })
In vanilla JavaScript, use the Web Components API:
const table = document.querySelector('reeflow-table');
table.addEventListener('reeflow-table-row-click', (event) => { console.log('Row clicked:', event.detail.row); console.log('Row index:', event.detail.rowIndex);});
table.addEventListener('reeflow-table-sort-change', (event) => { console.log('Sort column:', event.detail.column); console.log('Sort direction:', event.detail.direction);});For complete event details and TypeScript types, see the SDK Reference.
Styling with CSS Parts
Section titled “Styling with CSS Parts”The table exposes several CSS parts for custom styling:
/* Container */reeflow-table::part(container) { padding: 20px; background: white; border-radius: 8px;}
/* Title */reeflow-table::part(title) { font-size: 24px; font-weight: 700; color: #1a1a1a; margin-bottom: 16px;}
/* Table element */reeflow-table::part(table) { width: 100%; border-collapse: collapse;}
/* Header row */reeflow-table::part(header) { background: #f5f5f5;}
reeflow-table::part(header-row) { border-bottom: 2px solid #e0e0e0;}
reeflow-table::part(header-cell) { padding: 12px 16px; text-align: left; font-weight: 600; cursor: pointer;}
reeflow-table::part(header-cell):hover { background: #ebebeb;}
/* Body rows */reeflow-table::part(body) { background: white;}
reeflow-table::part(row) { border-bottom: 1px solid #e0e0e0; transition: background 0.2s;}
reeflow-table::part(row):hover { background: #f9f9f9;}
reeflow-table::part(cell) { padding: 12px 16px;}
/* Loading state */reeflow-table::part(loading) { display: flex; align-items: center; gap: 12px; padding: 40px; color: #666;}
/* Error state */reeflow-table::part(error) { text-align: center; padding: 40px; color: #d32f2f;}
/* Empty state */reeflow-table::part(empty) { text-align: center; padding: 40px; color: #999;}Advanced usage
Section titled “Advanced usage”The table component provides events and extensibility points for implementing advanced features. Here are examples of common implementations.
Implementing sorting
Section titled “Implementing sorting”The table does not sort data automatically. You can implement sorting by listening to the table-sort-change event and updating the query:
const table = document.querySelector('reeflow-table');let currentSort = { column: null, direction: 'asc' };
table.addEventListener('reeflow-table-sort-change', (event) => { const column = event.detail.column;
// Toggle direction if same column if (currentSort.column === column) { currentSort.direction = currentSort.direction === 'asc' ? 'desc' : 'asc'; } else { currentSort.column = column; currentSort.direction = 'asc'; }
// Update query with order_by table.query = { ...table.query, order_by: [ { column: column, direction: currentSort.direction, }, ], };});Implementing pagination
Section titled “Implementing pagination”The page-size attribute only limits displayed rows. For full pagination with navigation, implement it using JSONQL limit and offset:
const table = document.querySelector('reeflow-table');let currentPage = 0;const pageSize = 20;
function goToPage(page) { currentPage = page; table.query = { ...table.query, limit: pageSize, offset: page * pageSize, };}
// Navigation buttonsdocument.getElementById('next').addEventListener('click', () => { goToPage(currentPage + 1);});
document.getElementById('prev').addEventListener('click', () => { if (currentPage > 0) { goToPage(currentPage - 1); }});Implementing row selection
Section titled “Implementing row selection”The table emits click events for rows but does not manage selection state. You can implement row selection tracking using the table-row-click event:
const table = document.querySelector('reeflow-table');const selectedRows = new Set();
table.addEventListener('reeflow-table-row-click', (event) => { const rowIndex = event.detail.rowIndex;
if (selectedRows.has(rowIndex)) { selectedRows.delete(rowIndex); } else { selectedRows.add(rowIndex); }
console.log('Selected rows:', Array.from(selectedRows));});TypeScript support
Section titled “TypeScript support”The table component is fully typed when using TypeScript:
import type { ReeflowTable } from '@reeflow/core';
const table = document.querySelector('reeflow-table') as ReeflowTable;
// All methods and properties are typedtable.query = { /* ... */};await table.refresh();For complete type definitions, see the SDK Reference.