Skip to content

React API

Complete API reference for the @tabula-lens/react package.

Terminal window
npm i @tabula-lens/react

The main component for displaying database data in your React application. It provides a complete, feature-rich data table with filtering, sorting, pagination, and customization options.

Prop Type Required Description
path string Yes API endpoint path for fetching data
Prop Type Default Description
initialTable string - Initial table to select
tableSelector 'dropdown' | 'sidebar' | 'none' 'dropdown' Table selector display mode
tableSelectorLabel string 'Select Table' Label for the table selector
tableSelectorComponent React.FC - Custom table selector component
Prop Type Default Description
getAuthHeaders () => Promise<Record<string, string>> - Function to get authentication headers
headers Record<string, string> - Static headers to include in requests
Prop Type Default Description
showFilter boolean true Whether to show the filter input
filterPlaceholder string 'Filter records...' Placeholder text for the filter input
filterPosition 'top' | 'bottom' | 'both' 'top' Position of the filter input
filterDebounceMs number 300 Debounce delay for filter input in milliseconds
filterComponent React.FC - Custom filter input component
defaultFilterColumns Record<string, string[]> - Default filter columns per table
showFilterColumnSelector boolean true Whether to show the filter column selector
Prop Type Default Description
showPagination boolean true Whether to show pagination controls
pageSize number 10 Number of records per page
pageSizeOptions number[] [10, 20, 30, 50, 100] Available page size options
showPageSizeSelector boolean true Whether to show the page size selector
paginationPosition 'top' | 'bottom' | 'both' 'bottom' Position of pagination controls
paginationComponent React.FC - Custom pagination component
Prop Type Default Description
enableSorting boolean true Whether to enable column sorting
sortableColumns string[] - Array of column names that can be sorted
defaultSort { column: string; direction: 'asc' | 'desc' } - Default sort configuration
multiSort boolean false Whether to enable multi-column sorting
sortIcon React.FC<{ direction: 'asc' | 'desc' | null }> - Custom sort icon component
Prop Type Default Description
formatHeader ((columnName: string) => string) | null - Custom column header formatter function
formatCell (value: unknown, column: string) => React.ReactNode - Custom cell value formatter function
Prop Type Default Description
className string - Additional CSS class name for the container
classNames ClassNames - Custom class names for specific elements
style React.CSSProperties - Inline style for the container
styles Styles - Custom styles for specific elements
Prop Type Default Description
refetchInterval number - Interval in milliseconds to refetch data
onError (error: Error) => void - Error callback function
queryOptions object - Additional TanStack Query options (staleTime, gcTime, retry, retryDelay, refetchOnWindowFocus, refetchOnReconnect, refetchOnMount)
Prop Type Default Description
logger Logger - Custom logger instance
enableLogging boolean false Whether to enable built-in logging
logLevel LogLevel - Log level when creating a default logger
logFetchErrors boolean true Whether to log fetch errors
logQueryErrors boolean true Whether to log query errors
logPerformanceMetrics boolean true Whether to log performance metrics
Prop Type Default Description
loadingComponent React.FC - Custom loading state component
errorComponent React.FC<{ error: Error; retry: () => void }> - Custom error state component
emptyComponent React.FC - Custom empty state component
import { DatabaseViewer } from '@tabula-lens/react';
function App() {
return (
<DatabaseViewer
path="/api/tabula-lens"
/>
);
}
import { DatabaseViewer } from '@tabula-lens/react';
function App() {
const getAuthHeaders = async () => ({
'Authorization': `Bearer ${getToken()}`
});
return (
<DatabaseViewer
path="/api/tabula-lens"
initialTable="users"
tableSelector="sidebar"
tableSelectorLabel="Choose Table"
getAuthHeaders={getAuthHeaders}
showFilter={true}
filterPlaceholder="Search records..."
filterPosition="top"
filterDebounceMs={300}
defaultFilterColumns={{
users: ['name', 'email'],
products: ['title', 'description']
}}
showPagination={true}
pageSize={25}
pageSizeOptions={[10, 25, 50, 100]}
paginationPosition="both"
enableSorting={true}
sortableColumns={['name', 'email', 'created_at']}
defaultSort={{ column: 'created_at', direction: 'desc' }}
formatHeader={(name) => name.toUpperCase()}
formatCell={(value, column) => {
if (column === 'email') {
return <a href={`mailto:${value}`}>{value}</a>;
}
return value;
}}
className="my-custom-class"
refetchInterval={30000}
onError={(error) => console.error('Database viewer error:', error)}
/>
);
}

A convenience wrapper that provides a QueryClient to DatabaseViewer. This is useful for SSR contexts (Next.js, Remix, etc.) where you need to prevent request data leakage between server-side renders.

Accepts all DatabaseViewer props plus:

Prop Type Default Description
queryClient QueryClient - Optional custom QueryClient instance. If not provided, a new one is created with default options.
import { DatabaseViewerWithProvider } from '@tabula-lens/react';
function App() {
return (
<DatabaseViewerWithProvider
path="/api/tabula-lens"
initialTable="users"
/>
);
}
import { DatabaseViewerWithProvider } from '@tabula-lens/react';
import { QueryClient } from '@tanstack/react-query';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes
gcTime: 10 * 60 * 1000, // 10 minutes
},
},
});
function App() {
return (
<DatabaseViewerWithProvider
queryClient={queryClient}
path="/api/tabula-lens"
initialTable="users"
/>
);
}
  • If you don’t provide a queryClient, a new one is created with these defaults:
    • refetchOnWindowFocus: false
    • retry: 1
  • This component is particularly useful in Next.js App Router or other SSR frameworks
  • For client-side only applications, you can use DatabaseViewer directly with your own QueryClientProvider

Component displayed while data is loading.

Prop Type Default Description
customComponent React.FC - Custom loading component
className string - Additional CSS class name
classNames ClassNames - Custom class names for specific elements
style React.CSSProperties - Custom inline style for the container
styles Styles - Custom styles for specific elements
import { LoadingState } from '@tabula-lens/react';
<LoadingState className="custom-loading" />

Component displayed when an error occurs.

Prop Type Default Description
error Error - Error object
onRetry () => void - Retry callback function
customComponent React.FC<{ error: Error; retry: () => void }> - Custom error component
className string - Additional CSS class name
classNames ClassNames - Custom class names for specific elements
style React.CSSProperties - Custom inline style for the container
styles Styles - Custom styles for specific elements
isRecoverable boolean true Whether to show the retry button
import { ErrorState } from '@tabula-lens/react';
<ErrorState
error={error}
onRetry={() => refetch()}
className="custom-error"
/>

Component displayed when no data is available.

Prop Type Default Description
customComponent React.FC - Custom empty state component
className string - Additional CSS class name
classNames ClassNames - Custom class names for specific elements
style React.CSSProperties - Custom inline style for the container
styles Styles - Custom styles for specific elements
hasActiveFilter boolean false Whether a filter is currently active (changes the empty message)
onClearFilter () => void - Callback to clear the active filter
import { EmptyState } from '@tabula-lens/react';
<EmptyState className="custom-empty" />

Component for selecting which table to view.

Prop Type Default Description
tables string[] - Available tables
selectedTable string | undefined - Currently selected table
onSelectTable (table: string) => void - Table selection callback
mode 'dropdown' | 'sidebar' 'dropdown' Display mode
label string 'Select Table' Selector label
className string - Additional CSS class name
classNames ClassNames - Custom class names
styles Styles - Custom styles
import { TableSelector } from '@tabula-lens/react';
<TableSelector
tables={['users', 'products', 'orders']}
selectedTable="users"
onSelectTable={(table) => console.log('Selected:', table)}
mode="dropdown"
label="Choose Table"
/>

Component for filtering table data.

Prop Type Default Description
value string - Current filter value
onChange (value: string) => void - Filter change callback
placeholder string 'Filter...' Input placeholder
className string - Additional CSS class name
classNames ClassNames - Custom class names
styles Styles - Custom styles
import { FilterInput } from '@tabula-lens/react';
<FilterInput
value={filter}
onChange={setFilter}
placeholder="Search..."
/>

Component for selecting which columns to include in filtering. This allows users to customize which columns are searched when using the filter input.

Prop Type Default Description
availableColumns string[] - All available column names
selectedColumns string[] - Currently selected column names for filtering
defaultColumns string[] - Default column names for filtering
onSelectionChange (columns: string[]) => void - Callback when column selection changes
onResetToDefault () => void - Callback to reset to default columns
className string - Additional CSS class name
classNames ClassNames - Custom class names for specific elements
styles Styles - Custom styles for specific elements
import { FilterColumnSelector } from '@tabula-lens/react';
<FilterColumnSelector
availableColumns={['id', 'name', 'email', 'created_at']}
selectedColumns={['name', 'email']}
defaultColumns={['name', 'email']}
onSelectionChange={(columns) => console.log('Selected columns:', columns)}
onResetToDefault={() => console.log('Reset to default')}
/>
  • The component uses a popover/dropdown interface for column selection
  • Columns marked as “default” are indicated with a badge
  • Supports “Select All”, “Deselect All”, and “Reset to Default” actions
  • Changes are applied when the user clicks “Apply”
  • Cancel button discards unsaved changes
  • This component is used internally by DatabaseViewer when showFilterColumnSelector is enabled

Component for paginating through table data.

Prop Type Default Description
pageIndex number - Current page index (0-based)
pageCount number - Total number of pages
pageSize number - Current page size
canPreviousPage boolean - Whether previous page is available
canNextPage boolean - Whether next page is available
onPageChange (pageIndex: number) => void - Callback when page changes
onPageSizeChange (pageSize: number) => void - Callback when page size changes
pageSizeOptions number[] - Available page size options
showPageSizeSelector boolean - Whether to show the page size selector
customComponent React.FC<{ pageIndex, pageCount, pageSize, canPreviousPage, canNextPage, previousPage, nextPage, firstPage, lastPage, setPageSize }> - Custom pagination component
className string - Additional CSS class name
classNames ClassNames - Custom class names
styles Styles - Custom styles
import { Pagination } from '@tabula-lens/react';
<Pagination
pageIndex={currentPage}
pageCount={totalPages}
pageSize={pageSize}
canPreviousPage={currentPage > 0}
canNextPage={currentPage < totalPages - 1}
onPageChange={(index) => setCurrentPage(index)}
onPageSizeChange={(size) => setPageSize(size)}
pageSizeOptions={[10, 25, 50, 100]}
showPageSizeSelector={true}
/>

Component for rendering the data table. Uses TanStack Table internally via @tanstack/react-table types.

Prop Type Default Description
data Record<string, unknown>[] - Table data records
columns ColumnDef<Record<string, unknown>>[] - TanStack Table column definitions
sorting SortingState - Current sorting state (from @tanstack/react-table)
onSortingChange (sorting: SortingState) => void - Sorting change callback
pagination PaginationState - Current pagination state (from @tanstack/react-table)
onPaginationChange (pagination: PaginationState) => void - Pagination change callback
pageCount number - Total number of pages
enableSorting boolean - Whether sorting is enabled
multiSort boolean false Whether multi-column sorting is enabled
sortIcon React.FC<{ direction: 'asc' | 'desc' | null }> - Custom sort icon component
formatHeader ((name: string) => string) | null - Column header formatter
formatCell (value: unknown, column: string) => React.ReactNode - Cell value formatter
emptyComponent React.FC - Custom empty state component
hasActiveFilter boolean - Whether a filter is active (affects empty message)
onClearFilter () => void - Callback to clear the active filter
className string - Additional CSS class name
classNames ClassNames - Custom class names for specific elements
style React.CSSProperties - Custom inline style for the container
styles Styles - Custom styles for specific elements

DataTable is intended to be used together with state from useTableState. Column definitions are normally built dynamically by DatabaseViewer from the query result. See the complete example in DatabaseViewer for the typical usage pattern.

Hook for logger initialization and component lifecycle logging.

Accepts a single options object:

Option Type Default Description
logger Logger - Custom logger instance to use
enableLogging boolean false Whether logging is enabled
logLevel LogLevel - Log level to use when creating a default logger
Return Type Description
logger Logger | null Logger instance (null if enableLogging is false)
componentId string Unique component ID for log correlation
import { useLogger } from '@tabula-lens/react';
function MyComponent() {
const { logger, componentId } = useLogger({ enableLogging: true, logLevel: 'debug' });
useEffect(() => {
logger?.info('Component mounted', { componentId });
}, []);
}

Hook for table state management (pagination, sorting, filtering). Uses TanStack Table types for sorting and pagination state.

Accepts a single options object:

Option Type Default Description
initialTable string - Initial table to select
pageSize number 10 Initial page size
defaultSort { column: string; direction: 'asc' | 'desc' } - Initial sort configuration
filterDebounceMs number 300 Debounce delay for filter input in milliseconds
Return Type Description
selectedTable string | undefined Currently selected table
setSelectedTable (table: string) => void Set the selected table
sorting SortingState Current TanStack Table sorting state
setSorting (sorting: SortingState) => void Update sorting state
pagination PaginationState Current TanStack Table pagination state ({ pageIndex, pageSize })
setPagination (pagination: PaginationState) => void Update pagination state
filter string Current raw filter value
setFilter (filter: string) => void Update filter value
debouncedFilter string Debounced filter value (used for actual queries)
import { useTableState } from '@tabula-lens/react';
function MyComponent() {
const {
selectedTable,
setSelectedTable,
sorting,
setSorting,
pagination,
setPagination,
filter,
setFilter,
debouncedFilter,
} = useTableState({
initialTable: 'users',
pageSize: 25,
defaultSort: { column: 'created_at', direction: 'desc' },
});
// Use state for data fetching
}

Hook for data fetching logic with authentication and error handling. Fetches both table data and the tables list.

Accepts a single options object:

Option Type Default Description
path string - API endpoint base path (e.g. '/api/tabula-lens')
selectedTable string | undefined - Currently selected table
queryParams string - URL query string (typically from buildQueryParams)
getAuthHeaders () => Promise<Record<string, string>> - Async function returning auth headers
headers Record<string, string> - Static headers to include in requests
logger Logger | null - Logger instance
componentId string - Component ID for logging
logFetchErrors boolean true Whether to log fetch errors
logPerformanceMetrics boolean true Whether to log performance metrics
queryOptions object {} Additional TanStack Query options
refetchInterval number - Interval in milliseconds to refetch data
tableSelectorMode 'dropdown' | 'sidebar' | 'none' 'dropdown' Table selector mode (affects whether table list is fetched)
Return Type Description
data QueryResult | undefined Query result data
tables string[] | undefined List of available table names
isLoading boolean Loading state for the data query
error Error | null Error object
refetch () => void Refetch the data query
import { useDatabaseData, buildQueryParams, useTableState } from '@tabula-lens/react';
function MyComponent() {
const tableState = useTableState({ initialTable: 'users' });
const queryParams = buildQueryParams({
selectedTable: tableState.selectedTable,
pagination: tableState.pagination,
sorting: tableState.sorting,
filter: tableState.debouncedFilter,
});
const { data, tables, isLoading, error, refetch } = useDatabaseData({
path: '/api/tabula-lens',
selectedTable: tableState.selectedTable,
queryParams,
getAuthHeaders: async () => ({ 'Authorization': `Bearer ${getToken()}` }),
refetchInterval: 30000,
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>Data: {JSON.stringify(data)}</div>;
}

Utility function for building a URL query string from table state. Used internally by DatabaseViewer to construct requests to the /query endpoint.

Accepts a single options object:

Option Type Default Description
selectedTable string | undefined - Currently selected table name
pagination PaginationState - TanStack Table pagination state ({ pageIndex, pageSize })
sorting SortingState - TanStack Table sorting state
filter string - Filter value
filterColumns string[] - Columns to filter

string - URL-encoded query string (e.g. "table=users&page=1&limit=25&filter=john").

import { buildQueryParams } from '@tabula-lens/react';
const queryString = buildQueryParams({
selectedTable: 'users',
pagination: { pageIndex: 0, pageSize: 25 },
sorting: [{ id: 'created_at', desc: true }],
filter: 'john',
filterColumns: ['name', 'email'],
});
// Result: "table=users&page=1&limit=25&sort=created_at%3Adesc&filter=john&filterColumns=name%2Cemail"

Type guard to check if an object is a valid QueryResult.

Parameter Type Description
value unknown Value to check

boolean - True if the value is a valid QueryResult.

import { isQueryResult } from '@tabula-lens/react';
if (isQueryResult(data)) {
console.log('Valid query result:', data.pagination);
}

Validates pagination parameters.

Parameter Type Description
pagination object Pagination object to validate

boolean - True if pagination is valid.

import { validatePagination } from '@tabula-lens/react';
const isValid = validatePagination({
page: 1,
limit: 25,
total: 100,
totalPages: 4
});

Sanitizes column data to ensure type safety.

Parameter Type Description
value unknown Value to sanitize

string - Sanitized value as a string.

import { sanitizeColumnData } from '@tabula-lens/react';
const sanitized = sanitizeColumnData(null); // Returns ''
const sanitized = sanitizeColumnData(123); // Returns '123'

Creates request headers with authentication.

Parameter Type Description
options object Fetch options including headers and auth function

Promise<HeadersInit> - Complete headers object with authentication.

import { createAuthenticatedHeaders } from '@tabula-lens/react';
const headers = await createAuthenticatedHeaders({
headers: { 'Content-Type': 'application/json' },
getAuthHeaders: async () => ({
'Authorization': 'Bearer token'
})
});

Validates HTTP response and checks content type.

Parameter Type Description
response Response Fetch response object
options object Validation options

Promise<void> - Throws error if validation fails.

import { validateResponse } from '@tabula-lens/react';
await validateResponse(response, {
logger,
componentId: 'MyComponent',
fetchId: 'fetch-123'
});

Merges class names with proper precedence.

Parameter Type Description
defaultClass string Default class name
customClass string | undefined Custom class name

string - Merged class name.

import { mergeClassName } from '@tabula-lens/react';
const className = mergeClassName('default-class', 'custom-class');

Merges style objects with proper precedence.

Parameter Type Description
defaultStyle React.CSSProperties Default style object
customStyle React.CSSProperties | undefined Custom style object

React.CSSProperties - Merged style object.

import { mergeStyle } from '@tabula-lens/react';
const style = mergeStyle(
{ color: 'blue', fontSize: '16px' },
{ color: 'red' }
);
// Result: { color: 'red', fontSize: '16px' }
export type {
QueryResult,
ClassNames,
Styles,
TableSelectorMode,
FilterPosition,
PaginationPosition,
DatabaseViewerProps
};
interface ClassNames {
container?: string;
tableWrapper?: string;
table?: string;
header?: string;
cell?: string;
filter?: string;
filterInput?: string;
pagination?: string;
paginationButton?: string;
paginationInfo?: string;
pageSize?: string;
tableSelector?: string;
tableSelectorDropdown?: string;
tableSelectorSidebar?: string;
empty?: string;
loading?: string;
error?: string;
retry?: string;
info?: string;
// ... more specific element classes
}
interface Styles {
container?: React.CSSProperties;
tableWrapper?: React.CSSProperties;
table?: React.CSSProperties;
th?: React.CSSProperties;
td?: React.CSSProperties;
header?: React.CSSProperties;
cell?: React.CSSProperties;
sortable?: React.CSSProperties;
sorted?: React.CSSProperties;
filter?: React.CSSProperties;
filterInput?: React.CSSProperties;
pagination?: React.CSSProperties;
paginationButton?: React.CSSProperties;
// ... more specific element styles
}
import React from 'react';
import { DatabaseViewer } from '@tabula-lens/react';
function App() {
const getAuthHeaders = async () => {
const token = localStorage.getItem('authToken');
return {
'Authorization': `Bearer ${token}`,
'X-Custom-Header': 'custom-value'
};
};
const handleError = (error) => {
console.error('Database viewer error:', error);
// Send error to monitoring service
};
return (
<div className="app-container">
<DatabaseViewer
path="/api/tabula-lens"
initialTable="users"
tableSelector="sidebar"
tableSelectorLabel="Data Tables"
getAuthHeaders={getAuthHeaders}
headers={{
'Accept': 'application/json'
}}
showFilter={true}
filterPlaceholder="Search records..."
filterPosition="top"
filterDebounceMs={300}
defaultFilterColumns={{
users: ['name', 'email', 'status'],
products: ['title', 'description', 'sku']
}}
showFilterColumnSelector={true}
showPagination={true}
pageSize={25}
pageSizeOptions={[10, 25, 50, 100]}
showPageSizeSelector={true}
paginationPosition="both"
enableSorting={true}
sortableColumns={['name', 'email', 'created_at', 'status']}
defaultSort={{ column: 'created_at', direction: 'desc' }}
multiSort={false}
formatHeader={(columnName) => {
// Convert snake_case to Title Case
return columnName
.split('_')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ');
}}
formatCell={(value, column) => {
if (column === 'email') {
return <a href={`mailto:${value}`} className="email-link">{value}</a>;
}
if (column === 'status') {
const statusColors = {
active: 'green',
inactive: 'red',
pending: 'yellow'
};
return (
<span
className={`status-badge ${statusColors[value] || 'gray'}`}
>
{value}
</span>
);
}
if (column === 'created_at') {
return new Date(value as string).toLocaleDateString();
}
return value;
}}
className="custom-database-viewer"
classNames={{
container: 'my-container',
table: 'my-table',
header: 'my-header',
cell: 'my-cell'
}}
styles={{
container: { padding: '20px' },
table: { width: '100%' },
header: { backgroundColor: '#f5f5f5' }
}}
refetchInterval={60000}
onError={handleError}
loadingComponent={() => (
<div className="custom-loading">
<div className="spinner"></div>
<p>Loading data...</p>
</div>
)}
errorComponent={({ error, retry }) => (
<div className="custom-error">
<p>Error loading data: {error.message}</p>
<button onClick={retry}>Retry</button>
</div>
)}
emptyComponent={() => (
<div className="custom-empty">
<p>No data available</p>
</div>
)}
/>
</div>
);
}
export default App;