@sineways/react-tablefront
Version:
React Data Table and Data Grid for TypeScript. Zero config with fast search and filters, pagination and infinite scroll, table grid and masonry layouts. Built on TanStack Table.
1,380 lines (1,364 loc) • 58 kB
TypeScript
import * as react_jsx_runtime from 'react/jsx-runtime';
import React$1, { ChangeEvent, KeyboardEvent } from 'react';
import { ColumnFiltersState, ColumnDef, PaginationState } from '@tanstack/react-table';
import { ClassValue } from 'clsx';
import * as lucide_react from 'lucide-react';
type FilterDataType = 'number' | 'string' | 'date';
type ComparisonOperator = '>' | '<' | '>=' | '<=' | '=' | '!=' | '*' | '!*';
interface FilterOption {
id: string;
label: string;
type: 'comparison' | 'categorical';
field: string;
operator?: string;
value: number | string | RegExp;
originalDisplay?: string;
}
interface FilterField {
id: string;
label: string;
displayName?: string;
type: FilterDataType;
description: string;
path?: string | ((item: any) => any);
aliases?: string[];
preferredValues?: string[];
defaultNumericValue?: number;
defaultOperator?: ComparisonOperator;
isPercentage?: boolean;
suggestedValue?: string;
}
interface FilterProcessorConfig {
filterFields: FilterField[];
searchFields: FilterField[];
}
/**
* Core filter processing engine
*
* Performance optimizations:
* - Reduced debounce from 300ms to 150ms for more responsive search
* - Replaced Array.some() with for loops for better performance
* - Memoized search fields to avoid repeated calls
* - Optimized extractFilters to use for loops instead of filter/map chains
* - Replaced Map with plain object for filter grouping
* - Added early returns to avoid unnecessary processing
*/
declare class FilterProcessor {
private config;
private fieldsById;
constructor(config: FilterProcessorConfig);
private resolvePath;
getFieldValue(item: any, fieldId: string, context?: any): any;
applyFilter(item: any, filter: {
id: string;
value: any;
}, context?: any): boolean;
/**
* Parses a filter token into a structured filter
*/
parseFilterToken(token: string): {
id: string;
value: any;
} | null;
/**
* Gets all available filter fields
*/
getFilterFields(): FilterField[];
/**
* Gets all search fields
*/
getSearchFields(): FilterField[];
/**
* Gets a specific filter field by ID
*/
getFilterField(id: string): FilterField | undefined;
/**
* Extracts filters from a search string
*/
extractFilters(searchValue: string): ColumnFiltersState;
/**
* Generates filter suggestions from field definitions
*/
generateFilterSuggestions(): FilterOption[];
/**
* Applies filters to a dataset
*/
filter<T>(items: T[], filters: ColumnFiltersState, context?: any): T[];
getFields(): {
filter: FilterField[];
search: FilterField[];
};
applyFilters: <T>(items: T[], filters: ColumnFiltersState, context?: any) => T[];
}
interface TableStyles {
container: string;
searchBar: {
wrapper: string;
containerWrapper: string;
container: string;
icon: string;
input: string;
clearButton: string;
clearButtonIcon: string;
};
header: {
container: string;
leftSection: string;
resultCount: string;
clearFiltersButton: string;
clearFiltersIcon: string;
rightSection: string;
};
table: {
scrollArea: string;
table: string;
tableHeader: string;
tableRow: string;
tableRowSelected: string;
tableRowHover: string;
tableCell: string;
tableHeaderCell: string;
expandHeader: string;
expandButton: string;
};
grid: {
container: string;
item: string;
itemHover: string;
itemSelected: string;
itemContent: string;
expandButton: string;
itemFields: string;
field: string;
fieldLabel: string;
fieldValue: string;
expandedContent: string;
};
masonry: {
container: string;
column: string;
item: string;
itemHover: string;
itemSelected: string;
itemContent: string;
expandButton: string;
itemFields: string;
field: string;
fieldLabel: string;
fieldValue: string;
expandedContent: string;
};
loadingState: {
container: string;
content: string;
icon: string;
text: string;
};
emptyState: {
container: string;
content: string;
text: string;
};
pagination: {
variant?: "version1" | "version2";
container: string;
info: string;
controls: string;
buttonGroup: string;
button: string;
buttonIcon: string;
};
columnVisibility: {
trigger: string;
triggerIcon: string;
content: string;
header: string;
toggleAllButton: string;
itemList: string;
item: string;
checkbox: string;
};
filterPopover: {
trigger: string;
triggerIcon: string;
content: string;
container: string;
header: string;
title: string;
grid: string;
column: string;
filterButton: string;
filterButtonActive: string;
filterButtonInactive: string;
filterLabel: string;
};
dragDrop: {
dragGhost: string;
dropIndicator: string;
dragTarget: string;
dragSource: string;
};
resize: {
handle: string;
indicator: string;
overlay: string;
hitslop: string;
};
}
type PartialTableStyles = Partial<TableStyles>;
declare function useTableStyles(customStyles?: PartialTableStyles): TableStyles;
/**
* Column resize timing constants
*/
declare const DEFAULT_RESIZE_DOUBLE_CLICK_DELAY = 150;
declare const DEFAULT_RESIZE_RESET_DEBOUNCE = 50;
interface ResizeTimingConfig {
doubleClickDelay?: number;
resetDebounce?: number;
}
declare function cn(...inputs: ClassValue[]): string;
interface DragState {
isDragging: boolean;
draggedColumnId: string | null;
dragStartX: number;
dragStartY: number;
currentX: number;
currentY: number;
dropTargetIndex: number | null;
dropTargetColumnId: string | null;
}
interface ResizeState {
isResizing: boolean;
columnId: string | null;
startX: number;
startWidth: number;
}
interface IconProps$1 {
className?: string;
size?: number;
[key: string]: any;
}
declare const DefaultIcons: {
readonly Loader: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly PaginationPrevious: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly PaginationNext: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly SortAscending: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly SortDescending: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly SortUnsorted: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly ExpandIcon: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly CollapseIcon: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly ClearFilters: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly Search: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly X: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly Filter: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly ColumnSettings: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
};
interface DataTableIcons$1 {
Loader?: React$1.ComponentType<IconProps$1>;
PaginationPrevious?: React$1.ComponentType<IconProps$1>;
PaginationNext?: React$1.ComponentType<IconProps$1>;
SortAscending?: React$1.ComponentType<IconProps$1>;
SortDescending?: React$1.ComponentType<IconProps$1>;
SortUnsorted?: React$1.ComponentType<IconProps$1>;
ExpandIcon?: React$1.ComponentType<IconProps$1>;
CollapseIcon?: React$1.ComponentType<IconProps$1>;
ClearFilters?: React$1.ComponentType<IconProps$1>;
Search?: React$1.ComponentType<IconProps$1>;
X?: React$1.ComponentType<IconProps$1>;
Filter?: React$1.ComponentType<IconProps$1>;
ColumnSettings?: React$1.ComponentType<IconProps$1>;
}
declare function useDataTableIcons(iconOverrides?: DataTableIcons$1): {
readonly Loader: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly PaginationPrevious: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly PaginationNext: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly SortAscending: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly SortDescending: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly SortUnsorted: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly ExpandIcon: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly CollapseIcon: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly ClearFilters: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly Search: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly X: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly Filter: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
readonly ColumnSettings: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>>;
} | {
Loader: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
PaginationPrevious: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
PaginationNext: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
SortAscending: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
SortDescending: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
SortUnsorted: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
ExpandIcon: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
CollapseIcon: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
ClearFilters: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
Search: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
X: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
Filter: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
ColumnSettings: React$1.ForwardRefExoticComponent<Omit<lucide_react.LucideProps, "ref"> & React$1.RefAttributes<SVGSVGElement>> | React$1.ComponentType<IconProps$1>;
};
type EffectiveIcons = ReturnType<typeof useDataTableIcons>;
/**
* Smart header component that auto-truncates text when column gets too narrow
*/
interface SmartHeaderProps {
text: string;
columnId: string;
sortIcon: React$1.ReactNode;
isHeaderEmpty: boolean;
resizeState: ResizeState;
headerAlignment: 'left' | 'center' | 'right';
}
/**
* UI Components that can be overridden for customization
*/
interface DataTableUIComponents {
/** Button component used throughout. @example ({ className, ...p }) => <button {...p} /> */
Button?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
/** Trigger for Filter popover. */
FilterButton?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
/** Trigger for Column Visibility popover. */
ColumnButton?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
/** Clear filters button. */
ClearButton?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
/** Clear search input button. */
ClearSearchButton?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
/** Pagination button component. */
PaginationButton?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>> | React$1.ForwardRefExoticComponent<React$1.ButtonHTMLAttributes<HTMLButtonElement> & React$1.RefAttributes<HTMLButtonElement>>;
/** Button used for individual filter chips inside FilterPopover. */
FilterItemButton?: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
/** Scroll area wrapper used around table/grid. */
ScrollArea?: React$1.ComponentType<{
className?: string;
children?: React$1.ReactNode;
}> | React$1.ForwardRefExoticComponent<{
className?: string;
children?: React$1.ReactNode;
} & React$1.RefAttributes<HTMLDivElement>>;
/** Popover root component. */
Popover?: React$1.ComponentType<{
children: React$1.ReactNode;
open?: boolean;
onOpenChange?: (open: boolean) => void;
}>;
/** Popover trigger wrapper. */
PopoverTrigger?: React$1.ComponentType<{
children: React$1.ReactNode;
asChild?: boolean;
}>;
/** Popover content wrapper. */
PopoverContent?: React$1.ComponentType<{
children: React$1.ReactNode;
className?: string;
align?: 'center' | 'start' | 'end';
sideOffset?: number;
}>;
/** Tooltip root component. */
Tooltip?: React$1.ComponentType<{
children: React$1.ReactNode;
}>;
/** Tooltip trigger wrapper. */
TooltipTrigger?: React$1.ComponentType<{
children: React$1.ReactNode;
asChild?: boolean;
}>;
/** Tooltip content wrapper. */
TooltipContent?: React$1.ComponentType<{
children: React$1.ReactNode;
className?: string;
}>;
/** Switch control used in visibility popover. */
Switch?: React$1.ComponentType<{
checked?: boolean;
onCheckedChange?: (checked: boolean) => void;
className?: string;
id?: string;
}>;
/** Label component used in settings. */
Label?: React$1.ComponentType<{
children?: React$1.ReactNode;
htmlFor?: string;
className?: string;
}>;
/** Separator line used in settings. */
Separator?: React$1.ComponentType<{
className?: string;
}>;
/** Fallback icon used for settings trigger. */
Settings02Icon?: React$1.ComponentType<{
className?: string;
}>;
}
/**
* Main DataTable component props
*/
interface DataTableProps<TData> {
/**
* The array of data objects to render.
* @example
* const rows = [{ id: 1, name: 'Alice' }];
* <DataTable data={rows} />
*/
data: TData[];
/**
* Column definitions compatible with @tanstack/react-table.
* If omitted, columns can be auto-generated upstream.
* @example
* const columns = [{ accessorKey: 'name', header: 'Name' }];
*/
columns?: ColumnDef<TData, any>[];
/**
* Override visibility, header, cell, alignment, and meta per column id.
* @default {}
* @example
* { name: { header: 'Full name', headerAlignment: 'center' } }
*/
columnOverrides?: ColumnOverrides$1<TData>;
/**
* Initial column visibility applied on first use only.
* - byId: map of columnId => boolean (true show, false hide)
* - hideAll: if true, hide all by default (byId can override)
* @example
* { byId: { name: true, internal: false }, hideAll: false }
*/
initialColumnVisibility?: InitialColumnVisibilityConfig;
/**
* Field-level overrides for filtering/searching metadata.
* @example
* { amount: { type: 'number', label: 'Amount ($)' } }
*/
fieldOverrides?: FieldOverrides$1<TData>;
/**
* Partial style tokens merged into the active variant.
*/
customStyles?: PartialTableStyles;
/**
* Swap any internal UI piece (buttons, popovers, etc.).
* @default {}
*/
uiComponents?: DataTableUIComponents;
/**
* Legacy alias for uiComponents. If provided, overrides take precedence over uiComponents.
*/
customUIComponents?: DataTableUIComponents;
/**
* Replace built-in icons with your own set.
*/
icons?: DataTableIcons;
/**
* Optional stable id to isolate table state in the store.
* @example
* storeId="users-table"
*/
storeId?: string;
/**
* Row click handler. If omitted, selection is managed internally.
* @example
* onRowClick={(row) => setActive(row)}
*/
onRowClick?: (row: TData) => void;
/**
* Control the selected row externally.
* @default null
*/
selectedRow?: TData | null;
/**
* When true, arrow-key navigation will promote highlight to selection.
* @default true
*/
autoSelect?: boolean;
/**
* Enable expand/collapse per row.
* @default false
*/
expandable?: boolean;
/**
* Controlled expansion state by row id.
* @default {}
*/
expandedRows?: Record<string, boolean>;
/**
* Called when a row should toggle expansion (controlled mode).
*/
onToggleExpand?: (row: TData) => void;
/**
* Notifies parent with the new expanded rows map.
*/
onExpansionChange?: (expandedRows: Record<string, boolean>) => void;
/**
* Render content below a row when expanded.
* @example
* renderExpandedContent={(row) => <Details row={row} />}
*/
renderExpandedContent?: (row: TData) => React$1.ReactNode;
/**
* Clamp expanded content width to the scroll container in table mode.
* @default true
*/
clampExpandedContentToContainer?: boolean;
/**
* Clamp custom static rows to the scroll container width.
* @default true
*/
clampStaticRowsToContainer?: boolean;
/**
* Custom element rendered at the right of the header row.
*/
headerRightElement?: React$1.ReactNode;
/**
* Custom renderer for grid/masonry items.
*/
customRenderGridItem?: (row: TData, index: number, isSelected: boolean) => React$1.ReactNode;
/**
* Extra rows rendered at the top of the tbody.
* @default []
*/
customStaticRows?: React$1.ReactNode[];
/**
* When true, custom static rows stick below the header.
* @default true
*/
customStaticRowsSticky?: boolean;
/**
* Placeholder text for the search input.
* @default "Search..."
*/
searchPlaceholder?: string;
/**
* Text displayed when there are no rows to show.
* @default "No items found"
*/
emptyStateText?: string;
/**
* Loading indicator text.
* @default "Loading..."
*/
loadingText?: string;
/**
* Global loading state for the table.
* @default false
*/
isLoading?: boolean;
/**
* Visual layout and feature toggles for header/search/visibility, etc.
* See `DataTableLayout` for per-field defaults.
* @default {}
* @example
* { displayMode: 'grid', showSearchBar: false }
*/
layout?: DataTableLayout;
/**
* Enable pagination and configure page size.
* If omitted, the table uses infinite or full rendering.
* @example
* { pageSize: 50 }
*/
paginationConfig?: DataTablePaginationConfig;
/**
* Configure infinite or adaptive scrolling behavior.
* @example
* { enabled: true, pageSize: 50, increment: 25 }
*/
infiniteScrollConfig?: InfiniteScrollConfig;
/**
* Allow dragging column headers to reorder.
* @default true
*/
enableColumnDrag?: boolean;
/**
* Allow resizing columns by dragging header edges.
* @default true
*/
enableColumnResize?: boolean;
/**
* Timing config for resize interactions.
* @default { doubleClickDelay: 150, resetDebounce: 50 }
*/
resizeTimingConfig?: ResizeTimingConfig;
}
/**
* Layout configuration for the DataTable
*/
interface DataTableLayout {
/** Show the search input above the table. @default true */
showSearchBar?: boolean;
/** Show the header area (search, settings, etc.). @default true */
showHeader?: boolean;
/** Show the table header row (column labels). @default true */
showTableHeaders?: boolean;
/** Show the column visibility/settings control. @default true */
showColumnVisibility?: boolean;
/** Show the filters button. @default true */
showFilterButton?: boolean;
/** Show a reset button inside settings popover. @default false */
showResetTableButtonInSettings?: boolean;
/** Rendering mode. @default 'table' */
displayMode?: 'table' | 'grid' | 'masonry';
/**
* If > 0, render exactly this many grid columns.
* If 0/undefined, use responsive auto-fit with gridItemMinWidth.
*/
gridColumns?: number;
/** Minimum grid item width for responsive auto-fit. @default 250 */
gridItemMinWidth?: number;
/** If > 0, render exactly this many masonry columns. */
masonryColumns?: number;
/** Minimum masonry item width for responsive auto-fit. @default 300 */
masonryItemMinWidth?: number;
/** Gap between items in pixels. @default 16 */
masonryGap?: number;
}
/**
* Pagination configuration
*/
interface DataTablePaginationConfig {
/**
* Whether to auto-fit page size to the viewport.
* (Behavior depends on the consuming UI.)
*/
autoFit?: boolean;
/**
* Items per page. If omitted, falls back to infiniteScrollConfig.pageSize or STANDARD_PAGE_SIZE (25).
* @default 25
*/
pageSize?: number;
}
/**
* Infinite scrolling configuration (unified for both regular and adaptive)
*/
interface InfiniteScrollConfig {
/** Enable infinite scrolling. @default false */
enabled?: boolean;
/** Use adaptive windowed scrolling instead of regular. @default false */
adaptive?: boolean;
/** Distance from viewport edge to trigger load (px). @default 100 */
loadThreshold?: number;
/** Items per page/load. @default 25 */
pageSize?: number;
/** Items to add per scroll step. @default 25 */
increment?: number;
/**
* Max items to keep in memory (adaptive). Defaults to 3x pageSize or 3x viewport-estimated items.
* @default pageSize * 3 (when viewport unknown)
*/
maxItems?: number;
}
/**
* Header alignment options
*/
type HeaderAlignment$1 = 'left' | 'center' | 'right';
/**
* Column override system for maximum flexibility
*/
interface ColumnOverrides$1<TData = any> {
[columnId: string]: {
/** Show or hide the column. @default true */
visible?: boolean;
/** Header content (string or render function). */
header?: string | (() => React$1.ReactNode);
/** Cell renderer for full control. */
cell?: (info: any) => React$1.ReactNode;
/** Header text and sort icon alignment. @default 'left' */
headerAlignment?: HeaderAlignment$1;
/** Column-level styling (width, classes, etc.). @default {} */
meta?: {
/** Class applied to header and cells. */
className?: string;
[key: string]: any;
};
};
}
/**
* Column visibility overrides
*/
interface ColumnVisibilityOverrides$1 {
[columnId: string]: boolean;
}
/**
* Initial column visibility configuration used to set defaults on first render
*/
interface InitialColumnVisibilityConfig {
/** Map of columnId => visibility (true show, false hide). @default {} */
byId?: {
[columnId: string]: boolean;
};
/** Hide all columns by default (byId can opt-in). @default false */
hideAll?: boolean;
}
/**
* Field overrides for filtering and searching
*/
interface FieldOverrides$1<TData = any> {
[fieldId: string]: {
/** Enable as a filter field. @default true (if auto-generated) */
filterable?: boolean;
/** Enable as a search field. @default true (if auto-generated) */
searchable?: boolean;
/** Short label used in UI. */
label?: string;
/** Friendly display name shown to users. */
displayName?: string;
/** Data type guiding filter/search behavior. @example 'number' */
type?: FilterDataType;
/** Help text shown in tooltips/docs. */
description?: string;
/** Custom accessor path or resolver. @example (row) => row.profile.name */
path?: string | ((item: TData) => any);
/** Alternate field names to search. @example ['full_name','name'] */
aliases?: string[];
/** Preferred categorical values to suggest. */
preferredValues?: string[];
/** Default numeric value for comparison filters. */
defaultNumericValue?: number;
/** Default operator for numeric/date filters. @example '>=' */
defaultOperator?: '>' | '<' | '>=' | '<=' | '=' | '!=' | '*' | '!*';
/** Whether numeric values are percentages. */
isPercentage?: boolean;
/** Suggested free-text value for search. */
suggestedValue?: string;
/** Include only in filters, exclude from search. @default false */
filterOnly?: boolean;
/** Include only in search, exclude from filters. @default false */
searchOnly?: boolean;
};
}
/**
* Icon component interface
*/
interface IconProps {
className?: string;
size?: number;
[key: string]: any;
}
/**
* Icon overrides interface
*/
interface DataTableIcons {
/** Loading spinner for states. */
Loader?: React$1.ComponentType<IconProps>;
/** Prev page icon. */
PaginationPrevious?: React$1.ComponentType<IconProps>;
/** Next page icon. */
PaginationNext?: React$1.ComponentType<IconProps>;
/** Sort ascending indicator. */
SortAscending?: React$1.ComponentType<IconProps>;
/** Sort descending indicator. */
SortDescending?: React$1.ComponentType<IconProps>;
/** Unsorted indicator. */
SortUnsorted?: React$1.ComponentType<IconProps>;
/** Expand row icon. */
ExpandIcon?: React$1.ComponentType<IconProps>;
/** Collapse row icon. */
CollapseIcon?: React$1.ComponentType<IconProps>;
/** Clear filters icon. */
ClearFilters?: React$1.ComponentType<IconProps>;
/** Search icon. */
Search?: React$1.ComponentType<IconProps>;
/** Small X/close icon. */
X?: React$1.ComponentType<IconProps>;
/** Filters popover trigger icon. */
Filter?: React$1.ComponentType<IconProps>;
/** Column settings trigger icon. */
ColumnSettings?: React$1.ComponentType<IconProps>;
}
/**
* Column width state with user resize tracking
*/
interface ColumnWidthInfo {
width: number;
isUserSet: boolean;
}
/**
* Column width state mapping
*/
interface ColumnWidthState {
[columnId: string]: ColumnWidthInfo;
}
/**
* Table state interface
*/
interface TableState {
sorting: any[];
pagination: PaginationState;
columnVisibility: Record<string, boolean>;
columnOrder: string[];
columnWidths: ColumnWidthState;
getState: () => Omit<TableState, 'getState' | 'resetTableState' | 'setSorting' | 'setPagination' | 'setColumnVisibility' | 'setColumnOrder' | 'setColumnWidth' | 'resetColumnWidth'>;
setSorting: (updaterOrValue: any) => void;
setPagination: (updaterOrValue: any) => void;
setColumnVisibility: (updaterOrValue: any) => void;
setColumnOrder: (updaterOrValue: any) => void;
setColumnWidth: (columnId: string, width: number) => void;
resetColumnWidth: (columnId: string) => void;
resetTableState: () => void;
}
/**
* Table store configuration
*/
interface TableStoreConfig {
name: string;
initialColumnVisibility?: Record<string, boolean>;
initialPageSize?: number;
}
/**
* Generic updater function type
*/
type UpdaterFn<T> = (updaterOrValue: any) => void;
/**
* Row data with index for rendering
*/
interface RowDataWithIndex<TData> {
data: TData;
index: number;
isSelected: boolean;
}
/**
* Grid item rendering context
*/
interface GridItemContext<TData> {
row: TData;
index: number;
isSelected: boolean;
isExpanded: boolean;
onToggleExpand: (e: React$1.MouseEvent) => void;
}
/**
* Table cell rendering context
*/
interface TableCellContext<TData> {
row: TData;
column: ColumnDef<TData, any>;
value: any;
isSelected: boolean;
}
/**
* Row click event handler
*/
type RowClickHandler<TData> = (row: TData, event?: React$1.MouseEvent) => void;
/**
* Row expansion event handler
*/
type RowExpansionHandler<TData> = (row: TData, expanded: boolean) => void;
/**
* Search change event handler
*/
type SearchChangeHandler = (value: string) => void;
/**
* Filter change event handler
*/
type FilterChangeHandler = (filters: FilterField[]) => void;
/**
* Custom grid item renderer
*/
type GridItemRenderer<TData> = (row: TData, index: number, isSelected: boolean) => React$1.ReactNode;
/**
* Custom expanded content renderer
*/
type ExpandedContentRenderer<TData> = (row: TData) => React$1.ReactNode;
/**
* Custom cell renderer
*/
type CellRenderer<TData> = (context: TableCellContext<TData>) => React$1.ReactNode;
/**
* Selection state
*/
interface SelectionState<TData> {
selectedItem: TData | null;
setSelectedItem: (item: TData | null) => void;
}
/**
* Expansion state
*/
interface ExpansionState {
expandedRows: Record<string, boolean>;
setExpandedRows: (rows: Record<string, boolean>) => void;
toggleRow: (rowId: string) => void;
}
/**
* Search state
*/
interface SearchState {
searchValue: string;
setSearchValue: (value: string) => void;
clearSearch: () => void;
}
/**
* Filter state
*/
interface FilterState {
filters: FilterField[];
setFilters: (filters: FilterField[]) => void;
clearFilters: () => void;
}
/**
* DataTable state hook return type
*/
interface DataTableStateHook<TData> {
table: any;
data: TData[];
filteredData: TData[];
columns: ColumnDef<TData, any>[];
columnVisibility: Record<string, boolean>;
pagination: PaginationState;
isUsingPagination: boolean;
selectedItem: TData | null;
setSelectedItem: (item: TData | null) => void;
expandedRows: Record<string, boolean>;
setExpandedRows: (rows: Record<string, boolean>) => void;
searchValue: string;
setSearchValue: (value: string) => void;
filters: FilterField[];
setFilters: (filters: FilterField[]) => void;
clearSearch: () => void;
clearFilters: () => void;
}
/**
* DataTable interactions hook return type
*/
interface DataTableInteractionsHook<TData> {
handleKeyDown: (event: React$1.KeyboardEvent) => void;
dragState: DragState;
handleDragStart: (e: React$1.DragEvent, columnId: string) => void;
handleDragOver: (e: React$1.DragEvent) => void;
handleDrop: (e: React$1.DragEvent) => void;
handleDragEnd: () => void;
resizeState: ResizeState;
handleResizeStart: (e: React$1.MouseEvent, columnId: string) => void;
handleResizeReset: (e: React$1.MouseEvent, columnId: string) => void;
handleRowClick: (row: TData) => void;
handleToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
loadMoreItems: () => void;
isLoadingMore: boolean;
}
/**
* DataTable search hook return type
*/
interface DataTableSearchHook {
searchValue: string;
setSearchValue: (value: string) => void;
debouncedSetSearchValue: (value: string) => void;
clearSearch: () => void;
handleSearchChange: (e: React$1.ChangeEvent<HTMLInputElement>) => void;
handleSearchKeyDown: (e: React$1.KeyboardEvent<HTMLInputElement>) => void;
handleClearSearch: () => void;
resetSearch: () => void;
handleClearFilters: () => void;
}
/**
* DataTable - A comprehensive, self-contained data table component
*
* Features:
* - Zero configuration with auto-generated columns and filters
* - Built-in search, filtering, sorting, and pagination
* - Keyboard navigation and row selection
* - Expandable rows with custom content
* - Responsive design with multiple style variants
* - Type-safe with full TypeScript support
*/
declare function DataTable<TData>({ data, columns, columnOverrides, initialColumnVisibility, fieldOverrides, customStyles, uiComponents, customUIComponents, icons, storeId, onRowClick: onRowClickProp, selectedRow, expandable, expandedRows, onToggleExpand, onExpansionChange, headerRightElement, autoSelect, renderExpandedContent, clampExpandedContentToContainer, clampStaticRowsToContainer, customRenderGridItem, customStaticRows, customStaticRowsSticky, searchPlaceholder, emptyStateText, loadingText, isLoading, layout, paginationConfig, infiniteScrollConfig, enableColumnDrag, enableColumnResize, resizeTimingConfig, }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
/**
* Smart header component that auto-truncates text when column gets too narrow
*/
declare function SmartHeader({ text, columnId, sortIcon, isHeaderEmpty, resizeState, headerAlignment }: SmartHeaderProps): react_jsx_runtime.JSX.Element;
/**
* Props for the DataTableStates component
*/
interface DataTableStatesProps {
showLoadingState: boolean;
showEmptyState: boolean;
isLoading: boolean;
loadingText: string;
emptyStateText: string;
tableStyles: {
loadingState: {
container: string;
content: string;
icon: string;
text: string;
};
emptyState: {
container: string;
content: string;
text: string;
};
};
icons: DataTableIcons;
}
/**
* DataTableStates - Handles loading, empty, and error states
*/
declare function DataTableStates({ showLoadingState, showEmptyState, isLoading, loadingText, emptyStateText, tableStyles, icons }: DataTableStatesProps): react_jsx_runtime.JSX.Element | null;
/**
* LoadingState component for standalone use
*/
declare function LoadingState({ text, tableStyles, icons }: {
text?: string;
tableStyles: DataTableStatesProps['tableStyles'];
icons: DataTableIcons;
}): react_jsx_runtime.JSX.Element;
/**
* EmptyState component for standalone use
*/
declare function EmptyState({ text, tableStyles }: {
text?: string;
tableStyles: DataTableStatesProps['tableStyles'];
}): react_jsx_runtime.JSX.Element;
/**
* Props for the DataTablePagination component
*/
interface DataTablePaginationProps {
table: any;
isUsingPagination: boolean;
normalRowsLength: number;
PaginationBtn: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>> | React$1.ForwardRefExoticComponent<React$1.ButtonHTMLAttributes<HTMLButtonElement> & React$1.RefAttributes<HTMLButtonElement>>;
tableStyles: {
pagination: {
container: string;
controls: string;
button: string;
buttonIcon: string;
info: string;
buttonGroup: string;
};
};
icons: DataTableIcons;
}
/**
* DataTablePagination - Handles pagination controls and display
*/
declare function DataTablePagination({ table, isUsingPagination, normalRowsLength, PaginationBtn, tableStyles, icons }: DataTablePaginationProps): react_jsx_runtime.JSX.Element | null;
/**
* PaginationInfo component for standalone use
*/
declare function PaginationInfo({ currentPage, totalPages, tableStyles }: {
currentPage: number;
totalPages: number;
tableStyles: DataTablePaginationProps['tableStyles'];
}): react_jsx_runtime.JSX.Element;
/**
* PaginationControls component for standalone use
*/
declare function PaginationControls({ onPrevious, onNext, canPrevious, canNext, PaginationBtn, tableStyles, icons }: {
onPrevious: () => void;
onNext: () => void;
canPrevious: boolean;
canNext: boolean;
PaginationBtn: React$1.ComponentType<React$1.ButtonHTMLAttributes<HTMLButtonElement>>;
tableStyles: DataTablePaginationProps['tableStyles'];
icons: DataTableIcons;
}): react_jsx_runtime.JSX.Element;
/**
* Props for the DataTableHeader component
*/
interface DataTableHeaderProps<TData> {
searchPlaceholder?: string;
searchValue: string;
onSearchChange: (e: ChangeEvent<HTMLInputElement>) => void;
onSearchKeyDown: (e: KeyboardEvent<HTMLInputElement>) => void;
onClearSearch: () => void;
searchInputRef?: React$1.RefObject<HTMLInputElement | null>;
filterStore?: any;
filters: any[];
onClearFilters: () => void;
onResetTable?: () => void;
layout: {
showHeader?: boolean;
showSearchBar?: boolean;
showColumnVisibility?: boolean;
showFilterButton?: boolean;
showResetTableButtonInSettings?: boolean;
};
headerRightElement?: React$1.ReactNode;
filteredDataLength: number;
table: any;
uiComponents: DataTableUIComponents;
tableStyles: {
searchBar: {
wrapper: string;
containerWrapper: string;
container: string;
icon: string;
input: string;
clearButton: string;
clearButtonIcon: string;
};
header: {
container: string;
leftSection: string;
rightSection: string;
resultCount: string;
clearFiltersButton: string;
clearFiltersIcon: string;
};
columnVisibility: any;
filterPopover: any;
};
icons: DataTableIcons;
}
/**
* DataTableHeader - Handles search, filters, and header controls
*/
declare const DataTableHeader: React$1.MemoExoticComponent<(<TData>({ searchPlaceholder, searchValue, onSearchChange, onSearchKeyDown, onClearSearch, searchInputRef: externalSearchInputRef, filterStore, filters, onClearFilters, onResetTable, layout, headerRightElement, filteredDataLength, table, uiComponents, tableStyles, icons }: DataTableHeaderProps<TData>) => react_jsx_runtime.JSX.Element)>;
/**
* ClearFiltersButton component for standalone use
*/
declare const ClearFiltersButton: React$1.NamedExoticComponent<{
[key: string]: any;
onClick: () => void;
children: React$1.ReactNode;
className?: string;
}>;
/**
* SearchInput component for standalone use
*/
declare const SearchInput: React$1.NamedExoticComponent<{
[key: string]: any;
value: string;
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
onKeyDown?: (e: KeyboardEvent<HTMLInputElement>) => void;
placeholder?: string;
className?: string;
inputRef?: React$1.RefObject<HTMLInputElement>;
}>;
/**
* Props for the DataTableBody component
*/
interface DataTableBodyProps<TData> {
displayRows: TData[];
table: any;
idField: keyof TData;
selectedId: any;
highlightedId?: any;
onRowClick: (row: TData) => void;
expandable: boolean;
isRowExpanded: (row: TData) => boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
renderExpandedContent?: (row: TData) => React$1.ReactNode;
customStaticRows?: React$1.ReactNode[];
customStaticRowsSticky?: boolean;
enableColumnResize: boolean;
tableStyles: {
table: {
tableRow: string;
tableRowHover: string;
tableRowSelected: string;
tableCell: string;
expandButton: string;
};
};
icons: DataTableIcons;
clampExpandedContentToContainer?: boolean;
scrollAreaRef?: React$1.RefObject<HTMLDivElement | null>;
clampStaticRowsToContainer?: boolean;
}
/**
* DataTableBody - Handles table body rendering, rows, cells, and expandable functionality
*/
declare function DataTableBody<TData>({ displayRows, table, idField, selectedId, highlightedId, onRowClick, expandable, isRowExpanded, onToggleExpand, renderExpandedContent, customStaticRows, customStaticRowsSticky, enableColumnResize, tableStyles, icons, clampExpandedContentToContainer, clampStaticRowsToContainer, scrollAreaRef }: DataTableBodyProps<TData>): react_jsx_runtime.JSX.Element;
/**
* TableRow component for standalone use
*/
declare function TableRow<TData>({ rowData, index, isSelected, onRowClick, expandable, expanded, onToggleExpand, children, className, ...props }: {
rowData: TData;
index: number;
isSelected: boolean;
onRowClick: (row: TData) => void;
expandable: boolean;
expanded: boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
children: React$1.ReactNode;
className?: string;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
/**
* TableCell component for standalone use
*/
declare function TableCell({ children, className, style, ...props }: {
children: React$1.ReactNode;
className?: string;
style?: React$1.CSSProperties;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
/**
* ExpandButton component for standalone use
*/
declare function ExpandButton<TData>({ rowData, expanded, onToggleExpand, icons, className, ...props }: {
rowData: TData;
expanded: boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
icons: DataTableIcons;
className?: string;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
/**
* Props for the DataGrid component
*/
interface DataGridProps<TData> {
displayRows: TData[];
displayMode: 'grid';
idField: keyof TData;
gridColumns?: number;
gridItemMinWidth: number;
selectedId: any;
highlightedId?: any;
onRowClick: (row: TData) => void;
expandable: boolean;
isRowExpanded: (row: TData) => boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
renderExpandedContent?: (row: TData) => React$1.ReactNode;
effectiveColumns: any[];
columnOverrides: any;
columnVisibility: any;
table: any;
customRenderGridItem?: (row: TData, index: number, isSelected: boolean) => React$1.ReactNode;
customStaticRows?: React$1.ReactNode[];
customStaticRowsSticky?: boolean;
isLoadingMore: boolean;
isLoadingLess?: boolean;
shouldEnableInfiniteScroll: boolean;
tableStyles: {
grid: {
container: string;
item: string;
itemHover: string;
itemSelected: string;
itemContent: string;
expandButton: string;
itemFields: string;
field: string;
fieldLabel: string;
fieldValue: string;
expandedContent: string;
};
};
icons: DataTableIcons;
}
/**
* DataGrid - Handles grid layout rendering and grid item management
*/
declare function DataGrid<TData>({ displayRows, displayMode, idField, gridColumns, gridItemMinWidth, selectedId, highlightedId, onRowClick, expandable, isRowExpanded, onToggleExpand, renderExpandedContent, effectiveColumns, columnOverrides, columnVisibility, table, customRenderGridItem, customStaticRows, customStaticRowsSticky, isLoadingMore, isLoadingLess, shouldEnableInfiniteScroll, tableStyles, icons }: DataGridProps<TData>): react_jsx_runtime.JSX.Element;
/**
* GridItem component for standalone use
*/
declare function GridItem<TData>({ rowData, index, isSelected, onRowClick, expandable, expanded, onToggleExpand, children, className, ...props }: {
rowData: TData;
index: number;
isSelected: boolean;
onRowClick: (row: TData) => void;
expandable: boolean;
expanded: boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
children: React$1.ReactNode;
className?: string;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
/**
* GridField component for standalone use
*/
declare function GridField({ label, value, children, className, ...props }: {
label: string;
value?: any;
children?: React$1.ReactNode;
className?: string;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
/**
* Props for the DataMasonry component
*/
interface DataMasonryProps<TData> {
displayRows: TData[];
displayMode: 'masonry';
idField: keyof TData;
masonryColumns?: number;
masonryItemMinWidth: number;
selectedId: any;
highlightedId?: any;
onRowClick: (row: TData) => void;
expandable: boolean;
isRowExpanded: (row: TData) => boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
renderExpandedContent?: (row: TData) => React$1.ReactNode;
effectiveColumns: any[];
columnOverrides: any;
columnVisibility: any;
table: any;
customRenderMasonryItem?: (row: TData, index: number, isSelected: boolean) => React$1.ReactNode;
customStaticRows?: React$1.ReactNode[];
customStaticRowsSticky?: boolean;
isLoadingMore: boolean;
isLoadingLess?: boolean;
shouldEnableInfiniteScroll: boolean;
tableStyles: {
masonry: {
container: string;
column: string;
item: string;
itemHover: string;
itemSelected: string;
itemContent: string;
expandButton: string;
itemFields: string;
field: string;
fieldLabel: string;
fieldValue: string;
expandedContent: string;
};
};
icons: DataTableIcons;
}
/**
* DataMasonry - Handles Pinterest-style masonry layout rendering
* Uses a proper masonry algorithm that always places items in the shortest column
*/
declare function DataMasonry<TData>({ displayRows, displayMode, idField, masonryColumns, masonryItemMinWidth, selectedId, highlightedId, onRowClick, expandable, isRowExpanded, onToggleExpand, renderExpandedContent, effectiveColumns, columnOverrides, columnVisibility, table, customRenderMasonryItem, customStaticRows, customStaticRowsSticky, isLoadingMore, isLoadingLess, shouldEnableInfiniteScroll, tableStyles, icons }: DataMasonryProps<TData>): react_jsx_runtime.JSX.Element;
/**
* MasonryItem component for standalone use
*/
declare function MasonryItem<TData>({ rowData, index, isSelected, onRowClick, expandable, expanded, onToggleExpand, children, className, ...props }: {
rowData: TData;
index: number;
isSelected: boolean;
onRowClick: (row: TData) => void;
expandable: boolean;
expanded: boolean;
onToggleExpand: (row: TData, e: React$1.MouseEvent) => void;
children: React$1.ReactNode;
className?: string;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
/**
* MasonryField component for standalone use
*/
declare function MasonryField({ label, value, children, className, ...props }: {
label: string;
value?: any;
children?: React$1.ReactNode;
className?: string;
[key: string]: any;
}): react_jsx_runtime.JSX.Element;
interface UseInfiniteScrollManagerParams<TData> {
normalRows: TData[];
displayRows: TData[];
scrollAreaRef: React.RefObject<HTMLDivElement | null>;
pagination: PaginationState;
setPagination: (updater: PaginationState | ((prev: PaginationState) => PaginationState)) => void;
infiniteScrollConfig?: InfiniteScrollConfig;
isUsingPagination: boolean;
displayMode: 'table' | 'grid' | 'masonry';
windowSize?: {
width: number;
height: number;
};
}
declare function useInfiniteScrollManager<TData>({ normalRows, displayRows, scrollAreaRef, pagination, setPagination, infiniteScrollConfig, isUsingPagination, displayMode, windowSize, }: UseInfiniteScrollManagerParams<TData>): {
effectiveDisplayRows: TData[];
effectiveIsLoadingMore: boolean;
adaptiveIsLoadingLess: boolean | undefined;
adaptiveScrollEnabled: boolean;
shouldEnableInfiniteScroll: boolean;
};
type HeaderAlignment = 'left' | 'center' | 'right';
interface ColumnOverrides<TData = any> {
[columnId: string]: {
visible?: boolean;
header