import type { TPColumnDef } from './types'; import { type SxProps, type TableCellProps, type Theme } from '@mui/material'; import { type ServerFilterDef } from './DynamicFilterBar'; export type { ServerFilterDef }; export type { TPColumnDef } from './types'; /** Shape that fetchPage must return. */ export interface PagedResult { data: TData[]; totalRecords: number; } /** Preset for toolbar, filter chips, and pagination footer sizing. */ export type GridUiDensity = 'default' | 'compact'; /** Fine-grained UI sizing overrides (merged on top of `uiDensity` preset). */ export interface GridUiDensityOptions { footerMinHeight?: number; footerFontSize?: number; footerIconSize?: number; footerPaddingY?: number; filterChipFontSize?: number; filterChipMinHeight?: number; filterLabelFontSize?: number; toolbarIconFontSize?: number | string; /** Header column title font size (px number). */ headerFontSize?: number; /** Body cell data font size (px number). */ bodyFontSize?: number; /** MRT built-in toolbar control density (show/hide columns, density toggle, etc.). */ mrtDensity?: 'comfortable' | 'compact' | 'spacious'; } export interface GenericPaginatedGridProps { /** * Column definitions. Use `TPColumnDef` (a superset of `MRT_ColumnDef`) * to get top-level `filterType` and `options` support with no `meta` boilerplate. * * The grid automatically injects the right `filterFn` for each `filterType`, * and wires up the correct chip in Manage Filters → Column Filters. */ columns: TPColumnDef[]; /** * Async function called on every page/filter change. * Receives the current flat filter map and the 0-based page index. */ fetchPage: (filters: Record, pageIndex: number) => Promise>; /** Base react-query cache key. */ queryKey: unknown[]; /** Server-side filter chip definitions. */ serverFilterDefs: ServerFilterDef[]; /** Initial key → value map for every server filter. */ defaultFilters: Record; /** * Explicit list of chip IDs visible on first render. * When omitted the grid derives visible chips from `defaultVisible: true` * on each `ServerFilterDef` entry, falling back to the first chip. */ defaultVisibleFilterIds?: string[]; /** Number of rows fetched per API call. Default: 10 000. */ batchSize?: number; /** Excel (.xlsx) file name prefix (e.g. "invoice" → "invoice-page1.xlsx"). Default: "export". */ exportFilename?: string; /** * ID prefix applied to every interactive element in this grid instance. * Useful for automated testing and deep-linking. Defaults to `exportFilename`. * Pattern: `{gridId}_refresh_icon`, `{gridId}_export_icon`, `{gridId}_status_chip`, etc. */ gridId?: string; /** * Height of the entire grid component. * When omitted (default) the grid auto-sizes to fill the remaining viewport * height from its top position on mount and window resize only (not on scroll). * Pass an explicit CSS value to pin height (e.g. "600px", "calc(100vh - 300px)"). */ tableHeight?: string; /** * Minimum height of the grid wrapper (CSS length). * Used in auto-height `clamp()` and as `minHeight` when `tableHeight` is set. * Default: `300px`. */ tableMinHeight?: string; /** * Maximum height of the grid wrapper (CSS length). * Caps auto-calculated viewport height. Default: none (only viewport clamp). */ tableMaxHeight?: string; /** * When false, disables viewport auto-height; use `tableHeight` or `tableMinHeight` only. * Default: true (unless `tableHeight` is provided). */ autoFillViewport?: boolean; /** * MRT column layout. Default `grid` — columns grow to fill width (no trailing spacer column). * Use `grid-no-grow` only when you need fixed column widths with horizontal scroll. */ layoutMode?: 'grid' | 'semantic' | 'grid-no-grow'; /** * Compact toolbar, filter chips, and footer. * When omitted, the grid auto-selects `compact` at the `tablet`/`mobile` * responsive tiers and `default` at `desktop`. Pass explicitly to opt out * of that auto-switch. */ uiDensity?: GridUiDensity; /** Override individual sizes from the `uiDensity` preset. */ uiDensityOptions?: GridUiDensityOptions; /** * Viewport-width cutoffs (px) for the three responsive tiers: * `desktop` (above `tablet`), `tablet` (between `mobile` and `tablet`), * and `mobile` (at/below `mobile`). Each tier gets progressively tighter * defaults — density, filter-chip cap, toolbar wrap, footer layout. * Default: `{ tablet: 1024, mobile: 640 }`. */ responsiveBreakpoints?: { tablet?: number; mobile?: number; }; /** * Opt out of all automatic responsive-tier adjustments (density, filter * cap, toolbar wrap, footer layout) — the grid always behaves as `desktop`. * Default: `false`. */ disableResponsive?: boolean; /** Choices shown in the "Rows per page" footer dropdown. Default: [1 000, 5 000, 10 000]. */ pageSizeOptions?: number[]; /** * Show the Global Search input expanded by default (instead of requiring a * click on the search icon to reveal it). The icon remains in the top-right * toolbar actions and can still be used to collapse/expand the input. * Default: `false`. */ showGlobalSearchByDefault?: boolean; /** * Show the "Toggle density" icon (Show/Hide Columns row) in the top-right * toolbar actions. Default: `false` (hidden) — the grid's own `uiDensity` * prop already controls row/header density, so this MRT-native toggle is * usually redundant. */ showDensityToggle?: boolean; /** * Background colour applied to every header cell. * Accepts any valid CSS colour string. */ headerBgColor?: string; /** * Background colour for the Excel export header row. * Accepts a hex colour string (`#RRGGBB`). * Falls back to `headerBgColor` when omitted, then to the default blue `#1565C0`. */ exportHeaderBgColor?: string; /** * Text colour for the Excel export header row. * Accepts a hex colour string (`#RRGGBB`). * Defaults to white (`#FFFFFF`) when omitted. */ exportHeaderTextColor?: string; /** * Minimum height of every header cell (CSS length or px number). * Default: `40px` (`34px` when `uiDensity="compact"`). */ headerMinHeight?: string | number; /** * Maximum height of the header row — **all columns use the same height**. * Long titles wrap inside this box. Default: `72px` (`56px` compact). */ headerMaxHeight?: string | number; /** * Optional max lines for header text (`-webkit-line-clamp`). * Omit to allow text to use the full `headerMaxHeight` (recommended for tall headers). */ headerMaxLines?: number; /** * Font size for header column titles (CSS length or px number). * Default: `12px` (`11px` when `uiDensity="compact"`). Overridden by `uiDensityOptions.headerFontSize`. */ headerFontSize?: string | number; /** * Font size for body/data cells (CSS length or px number). * Default: `12px` (`11px` compact). Overridden by `uiDensityOptions.bodyFontSize`. */ bodyFontSize?: string | number; /** * Maximum number of filter chips that can be visible at once. * Prevents the filter bar from wrapping to a second row on typical screens. * Default: 4. */ maxVisibleFilters?: number; /** * Grid-level body cell props — applied to **every** data cell and merged with * any column-level `muiTableBodyCellProps` (column takes precedence for non-sx * props; `sx` objects are combined as a MUI sx array so neither is lost). * * Use this to set `title`, `className`, padding, etc. once at the grid level * instead of repeating the same props on every column: * * ```tsx * muiTableBodyCellProps={({ cell }) => ({ * title: cell.getValue(), // hover tooltip on every cell * className: 'body_cell', * })} * ``` * * Individual columns can still add layout-only overrides (e.g. `align: 'right'` * for numeric columns) without losing the global `title`/`className`. */ muiTableBodyCellProps?: TableCellProps | ((params: { cell: any; column: any; row: any; table: any; }) => TableCellProps); /** * Grid-level head cell props — applied to **every** header cell and merged * with any column-level `muiTableHeadCellProps` (column takes precedence). * * ```tsx * muiTableHeadCellProps={{ className: 'Header_cell' }} * ``` */ muiTableHeadCellProps?: TableCellProps | ((params: { column: any; table: any; }) => TableCellProps); /** * Per-row conditional styling — e.g. highlighting a row's background based * on a status field. Called once per row with that row's **original data** * (not the MRT `row` wrapper), so the condition logic reads naturally: * * ```tsx * const STATUS_COLORS: Record = { * Pending: '#ffe0b2', // orange * Acknowledged: '#fff9c4', // yellow * Completed: '#bbdefb', // blue * Released: '#c8e6c9', // green * Overdue: '#f8bbd0', // pink * }; * * ({ backgroundColor: STATUS_COLORS[row.status] })} * // ... * /> * ``` * * Return `undefined` (or omit a case) for rows that shouldn't be * highlighted. Combines safely with row hover/selection styling — this * only sets the base background, `sx` arrays layer on top. * * The same `backgroundColor` (a plain hex string, as in the example above) * is also applied as a cell fill in the **Excel export**, so downloaded * rows carry the same highlight seen on screen. A `color` (text colour) in * the same object is likewise carried over as the exported cell's font * colour — note that `color` only affects the Excel export; on screen, * MUI's table cells already set their own text colour per cell, so a * row-level `color` here has no visible effect in the grid itself (only * `backgroundColor` is visible on screen). A theme-function `sx` (e.g. * `(theme) => ({...})`) can't be resolved for the export without a live * theme, so only plain `{ backgroundColor: '#RRGGBB', color: '#RRGGBB' }` * objects (or arrays of them) are reflected there. */ getRowSx?: (row: TData) => SxProps | undefined; /** * Per-column conditional header styling — e.g. drawing attention to a * specific column's header with its own background/text colour. Called * once per header cell with that column's `id` (its `accessorKey`) and * resolved `header` label: * * ```tsx * * col.id === 'priority' ? { backgroundColor: '#c62828', color: '#ffffff' } : undefined * } * // ... * /> * ``` * * Return `undefined` (or omit a case) for columns whose header should use * the grid's normal `headerBgColor` styling. Merged on top of * `headerBgColor`/column-level `muiTableHeadCellProps`, so it only needs to * describe the override, not the whole header cell style. * * The same `backgroundColor`/`color` (plain hex strings) are also applied * to that column's header cell in the **Excel export**, overriding * `exportHeaderBgColor`/`exportHeaderTextColor` for just that column. Same * theme-function limitation as `getRowSx` — only plain colour objects are * reflected in the export. */ getHeaderSx?: (column: { id: string; header: string; }) => SxProps | undefined; /** * Optional render function for expanded row detail panels. * When provided, enables row expansion and renders custom content for each expanded row. * * ```tsx * renderDetailPanel={({ row }) => ( * * * * )} * ``` */ renderDetailPanel?: (params: { row: any; table: any; }) => React.ReactNode; /** * Enable row expansion functionality. Auto-enabled if `renderDetailPanel` is provided. * Default: false. */ enableExpanding?: boolean; } declare function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize, exportFilename, gridId, tableHeight, tableMinHeight, tableMaxHeight, autoFillViewport, layoutMode, uiDensity, uiDensityOptions, responsiveBreakpoints, disableResponsive, pageSizeOptions, showGlobalSearchByDefault, showDensityToggle, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, getRowSx, getHeaderSx, renderDetailPanel, enableExpanding, }: GenericPaginatedGridProps): import("react/jsx-runtime").JSX.Element; export default GenericPaginatedGrid;