import * as React from 'react'; import { FilterOperator, FilterTextMask, ConditionalRule } from '../../lib/table-properties-types.js'; import { ColumnCellKind } from '../../lib/column-cell-kind.js'; type SortDir = "asc" | "desc"; interface ColumnDef { /** Unique key — must match a key of TData or be synthetic (e.g. "select", "actions") */ key: string; /** Header label */ label: string; /** Default width in px */ width?: number; minWidth?: number; /** Whether this column can be sorted */ sortable?: boolean; /** * Key of TData used for sorting comparisons. * If omitted but sortable=true, falls back to `key`. */ sortKey?: keyof TData & string; /** Pin to left or right by default */ defaultPin?: "left" | "right"; /** If true, user cannot unpin this column */ lockPin?: boolean; /** Render the cell content. If omitted, renders String(row[key]). */ cell?: (row: TData, ctx: CellContext) => React.ReactNode; /** Custom header renderer — overrides the default label text */ header?: () => React.ReactNode; /** * Semantic cell kind — sets default filter icon, type, and static options when * `filter` is omitted or partial. Pair with named cells from `table-cells.tsx`. */ cellKind?: ColumnCellKind; /** * When the column embeds a favorite/star control, expose a companion **Favorite** * filter (`isStarred` by default). Filter-only — does not add a table column. */ favoriteFilter?: boolean | { fieldKey?: string; label?: string; }; /** Filter-only synthetic columns — hidden from the grid, used in filter menus only. */ filterOnly?: boolean; /** Filter config — drives per-column "Filter by this column" option */ filter?: { type?: "select" | "text" | "date" | "date-range" | "range"; /** icon class for filter pills, e.g. "fa-circle-dot" */ icon?: string; options?: { value: string; label: string; /** * Optional rich rendering for this option in filter dropdowns and * the Properties drawer (e.g. status chip, colored swatch). Falls * back to `label` plain text when omitted. */ node?: React.ReactNode; }[]; operators?: FilterOperator[]; /** Avatar list picker for person columns — usually from `cellKind: "person"`. */ selectVariant?: "default" | "person"; /** When `type` is `text`, optional mask for filter popover + drawer. */ textMask?: FilterTextMask; /** When `type` is `range` and min/max omitted — derive from dataset. */ dataBounds?: boolean; /** When `type` is `range` — defaults from `cellKind: "progress"` (0–100%). */ rangeMin?: number; rangeMax?: number; rangeStep?: number; rangeUnit?: string; }; } interface CellContext<_TData> { rowIndex: number; selected: boolean; onSelect: (selected: boolean) => void; } interface DataTableProps> { /** Row data */ data: TData[]; /** Column definitions */ columns: ColumnDef[]; /** Returns a stable unique ID for each row (used for selection keys) */ getRowId?: (row: TData, index: number) => string | number; /** * Accessible name for each row’s selection checkbox (e.g. primary column value). * If omitted, a generic label is used. */ getRowSelectionLabel?: (row: TData, rowIndex: number) => string; /** Enable row selection checkboxes */ selectable?: boolean; /** Enable global search */ searchable?: boolean; /** Enable "Group by" feature */ groupable?: boolean; /** Custom empty state */ emptyState?: React.ReactNode; /** Called when a row is clicked */ onRowClick?: (row: TData) => void; /** Default sort */ defaultSort?: { key: string; dir: SortDir; }; /** Conditional formatting rules — apply bg color to cells based on value */ conditionalRules?: ConditionalRule[]; } interface PaginationConfig { /** Rows per page. Default 10. */ pageSize?: number; /** Options shown in the page-size selector. Default [10, 25, 50, 100]. */ pageSizeOptions?: number[]; } export { type CellContext, ColumnCellKind, type ColumnDef, ConditionalRule, type DataTableProps, FilterTextMask, type PaginationConfig, type SortDir };