react-kd-grid 2.2.4 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/GridRows.d.ts +10 -18
- package/dist/components/RowContextMenu.d.ts +6 -10
- package/dist/components/SearchToolbar.d.ts +2 -18
- package/dist/hooks/useExport.d.ts +1 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +310 -308
- package/package.json +3 -3
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { CSSProperties, MouseEvent, ReactNode } from "react";
|
|
2
|
+
/** Used internally by useVirtualization and GridRows. Not part of the public API. */
|
|
3
|
+
export interface VirtualizedRange {
|
|
4
|
+
startIndex: number;
|
|
5
|
+
endIndex: number;
|
|
6
|
+
offsetY: number;
|
|
7
|
+
}
|
|
2
8
|
export type FilterType = "text" | "multiselect" | "number" | "date" | "boolean";
|
|
3
9
|
export type Density = "sm" | "md" | "lg";
|
|
10
|
+
export type SortDirection = "asc" | "desc" | null;
|
|
11
|
+
export type PaginationMode = "client" | "server";
|
|
12
|
+
export type SearchMode = "contains" | "exact" | "startsWith" | "endsWith" | "regex";
|
|
4
13
|
export interface FilterOption {
|
|
5
14
|
label: string;
|
|
6
|
-
|
|
15
|
+
/** Tightened from `any` — filter values must be scalar. */
|
|
16
|
+
value: string | number | boolean;
|
|
7
17
|
}
|
|
18
|
+
/** Inline column filter configuration (used as `filterable: { type, ... }`). */
|
|
8
19
|
export interface ColumnFilter {
|
|
9
20
|
type: FilterType;
|
|
10
21
|
options?: FilterOption[];
|
|
@@ -12,251 +23,344 @@ export interface ColumnFilter {
|
|
|
12
23
|
min?: number;
|
|
13
24
|
max?: number;
|
|
14
25
|
}
|
|
26
|
+
export interface ColumnFilterValue {
|
|
27
|
+
type: FilterType;
|
|
28
|
+
/**
|
|
29
|
+
* The filter value.
|
|
30
|
+
* - Text/boolean: `string | boolean`
|
|
31
|
+
* - Number: `number | string`
|
|
32
|
+
* - Date: `Date | string`
|
|
33
|
+
* - Multiselect: `any[]` (array of selected option values)
|
|
34
|
+
*/
|
|
35
|
+
value: string | number | boolean | Date | any[] | null;
|
|
36
|
+
operator?: "equals" | "contains" | "startsWith" | "endsWith" | "gt" | "lt" | "gte" | "lte" | "between";
|
|
37
|
+
/** Secondary value for the `between` operator. */
|
|
38
|
+
secondValue?: string | number | boolean | Date | null;
|
|
39
|
+
}
|
|
40
|
+
export interface ActiveFilters {
|
|
41
|
+
[columnKey: string]: ColumnFilterValue;
|
|
42
|
+
}
|
|
43
|
+
/** @internal Used by FilterPopup component. */
|
|
44
|
+
export interface FilterPopupProps {
|
|
45
|
+
column: GridColumn;
|
|
46
|
+
data: GridRow[];
|
|
47
|
+
currentFilter?: ColumnFilterValue;
|
|
48
|
+
onApplyFilter: (filter: ColumnFilterValue | null) => void;
|
|
49
|
+
onClose: () => void;
|
|
50
|
+
position: {
|
|
51
|
+
top: number;
|
|
52
|
+
left: number;
|
|
53
|
+
};
|
|
54
|
+
autoApply?: boolean;
|
|
55
|
+
}
|
|
15
56
|
export interface GridColumn {
|
|
16
57
|
key: string;
|
|
17
58
|
header: string;
|
|
18
59
|
width?: number;
|
|
19
60
|
/**
|
|
20
|
-
* Flexible sizing. When true or a positive number
|
|
21
|
-
* available horizontal space.
|
|
22
|
-
* Note: runtime support may require renderer updates; currently a type hint.
|
|
61
|
+
* Flexible sizing. When `true` or a positive number the column can expand to
|
|
62
|
+
* fill available horizontal space. A number sets the flex-grow weight.
|
|
23
63
|
*/
|
|
24
64
|
flex?: boolean | number;
|
|
25
|
-
/** Minimum width in pixels
|
|
65
|
+
/** Minimum width in pixels. */
|
|
26
66
|
minWidth?: number;
|
|
27
|
-
/** Maximum width in pixels
|
|
67
|
+
/** Maximum width in pixels. */
|
|
28
68
|
maxWidth?: number;
|
|
29
|
-
/**
|
|
69
|
+
/** Allow the user to drag-resize this column. */
|
|
30
70
|
resizable?: boolean;
|
|
71
|
+
/** Whether the column header is clickable to sort. Default `true`. */
|
|
72
|
+
sortable?: boolean;
|
|
31
73
|
/**
|
|
32
|
-
*
|
|
74
|
+
* Enable or configure the column filter.
|
|
75
|
+
* `true` → text filter with defaults
|
|
76
|
+
* `false` → no filter (overrides the grid-level `filterable` prop)
|
|
77
|
+
* object → full configuration
|
|
33
78
|
*/
|
|
34
|
-
sortable?: boolean;
|
|
35
79
|
filterable?: boolean | ColumnFilter;
|
|
80
|
+
/** Format the raw cell value to a display string. */
|
|
36
81
|
formatter?: (value: any) => string;
|
|
82
|
+
/** Fully custom cell renderer; takes precedence over `formatter`. */
|
|
37
83
|
cellRenderer?: (value: any, row: GridRow) => ReactNode;
|
|
84
|
+
/** Whether the column is visible. Default `true`. */
|
|
38
85
|
visible?: boolean;
|
|
39
86
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
87
|
+
* Aggregate function applied to this column's values inside group footers.
|
|
88
|
+
* Built-ins: `"sum" | "avg" | "min" | "max"`.
|
|
89
|
+
* Custom: `(values: any[]) => any`.
|
|
42
90
|
*/
|
|
43
91
|
aggregate?: "sum" | "avg" | "min" | "max" | ((values: any[]) => any);
|
|
44
|
-
/**
|
|
45
|
-
* Optional formatter for the aggregate value displayed in group footers.
|
|
46
|
-
* Falls back to the column's formatter if not provided.
|
|
47
|
-
*/
|
|
92
|
+
/** Formatter for the group-footer aggregate value. Falls back to `formatter`. */
|
|
48
93
|
aggregateFormatter?: (value: any) => string;
|
|
49
94
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Optional formatter for the footer aggregate value.
|
|
56
|
-
* Falls back to the column's formatter if not provided.
|
|
95
|
+
* Aggregate function for the global footer row at the bottom of all rows.
|
|
96
|
+
* Built-ins: `"count" | "sum" | "avg" | "min" | "max"`.
|
|
97
|
+
*
|
|
98
|
+
* @renamed Was `footer_aggregate` (snake_case) in v2. Now `footerAggregate`.
|
|
57
99
|
*/
|
|
100
|
+
footerAggregate?: "count" | "sum" | "avg" | "min" | "max" | ((values: any[]) => any);
|
|
101
|
+
/** Formatter for the global footer aggregate value. Falls back to `formatter`. */
|
|
58
102
|
footerAggregateFormatter?: (value: any) => string;
|
|
59
|
-
/**
|
|
60
|
-
* Horizontal alignment for cell content: left | center | right
|
|
61
|
-
*/
|
|
103
|
+
/** Horizontal alignment for cell content. */
|
|
62
104
|
align?: "left" | "center" | "right";
|
|
63
|
-
/**
|
|
64
|
-
* Horizontal alignment for header content: left | center | right
|
|
65
|
-
*/
|
|
105
|
+
/** Horizontal alignment for the header cell. */
|
|
66
106
|
headerAlign?: "left" | "center" | "right";
|
|
67
|
-
/**
|
|
107
|
+
/** CSS class for body cells — static string or derived from value + row. */
|
|
68
108
|
className?: string | ((value: any, row: GridRow) => string);
|
|
69
|
-
/**
|
|
109
|
+
/** Inline style for body cells — static or derived. */
|
|
70
110
|
cellStyle?: CSSProperties | ((value: any, row: GridRow) => CSSProperties);
|
|
71
|
-
/**
|
|
111
|
+
/** CSS class for the header cell. */
|
|
72
112
|
headerClassName?: string;
|
|
73
|
-
/**
|
|
113
|
+
/** Remove default padding from the cell container. */
|
|
74
114
|
noPadding?: boolean;
|
|
75
|
-
/**
|
|
115
|
+
/** Set to `false` to opt out of the default truncation wrapper. */
|
|
76
116
|
wrapCellContent?: boolean;
|
|
77
117
|
}
|
|
78
118
|
export interface GridRow {
|
|
119
|
+
/** Optional unique identifier. Provide `getRowId` on the grid for custom keys. */
|
|
79
120
|
id?: string | number;
|
|
80
121
|
[key: string]: any;
|
|
81
122
|
}
|
|
123
|
+
/** Runtime multi-level grouping state. */
|
|
82
124
|
export interface GroupConfig {
|
|
83
125
|
/** Ordered list of column keys to group by (multi-level). */
|
|
84
126
|
columnKeys: string[];
|
|
85
127
|
/**
|
|
86
|
-
* Expanded group paths. Each path is a stable string
|
|
87
|
-
* grouping values, e.g. "City=SF|Status=Open"
|
|
128
|
+
* Expanded group paths. Each path is a stable string built from the sequence
|
|
129
|
+
* of grouping values, e.g. `"City=SF|Status=Open"`.
|
|
88
130
|
*/
|
|
89
131
|
expanded: Set<string>;
|
|
90
132
|
}
|
|
91
|
-
export interface
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
count: number;
|
|
95
|
-
};
|
|
133
|
+
export interface SortConfig {
|
|
134
|
+
key: string | null;
|
|
135
|
+
direction: SortDirection;
|
|
96
136
|
}
|
|
97
|
-
export
|
|
98
|
-
|
|
99
|
-
|
|
137
|
+
export interface PaginationConfig {
|
|
138
|
+
enabled: boolean;
|
|
139
|
+
pageSize: number;
|
|
140
|
+
currentPage: number;
|
|
141
|
+
totalPages: number;
|
|
142
|
+
totalRows: number;
|
|
143
|
+
showPageSizeSelector?: boolean;
|
|
144
|
+
pageSizeOptions?: number[];
|
|
145
|
+
}
|
|
146
|
+
export interface ServerPaginationConfig {
|
|
147
|
+
enabled: boolean;
|
|
148
|
+
onPageChange: (page: number, pageSize: number) => Promise<void> | void;
|
|
149
|
+
onPageSizeChange?: (pageSize: number) => Promise<void> | void;
|
|
150
|
+
loading?: boolean;
|
|
151
|
+
totalRows: number;
|
|
152
|
+
}
|
|
153
|
+
/** Supported export file formats. */
|
|
154
|
+
export type ExportFormat = "csv" | "json" | "xlsx";
|
|
155
|
+
/** Export configuration for the grid toolbar. */
|
|
156
|
+
export interface ExportOptions {
|
|
157
|
+
/** Allowed export formats. Defaults to `["xlsx"]`. */
|
|
158
|
+
formats?: ExportFormat[];
|
|
159
|
+
/** Default filename without extension. Defaults to `"grid-data"`. */
|
|
160
|
+
filename?: string;
|
|
161
|
+
/** When `false`, export is disabled even if `showExport` is `true`. */
|
|
162
|
+
enabled?: boolean;
|
|
163
|
+
/** `"client"` processes data in the browser; `"server"` calls `onServerExport`. */
|
|
164
|
+
exportMode?: "client" | "server";
|
|
165
|
+
/**
|
|
166
|
+
* Called when `exportMode === "server"`.
|
|
167
|
+
* @param format Requested file format.
|
|
168
|
+
* @param exportSelected Whether only selected rows should be exported.
|
|
169
|
+
* @param selectedRowIds IDs of selected rows when `exportSelected` is `true`.
|
|
170
|
+
*/
|
|
171
|
+
onServerExport?: (format: "csv" | "json" | "xlsx", exportSelected: boolean, selectedRowIds?: Array<string | number>) => void;
|
|
172
|
+
}
|
|
173
|
+
/** Client/server pagination options passed to the `pagination` prop. */
|
|
174
|
+
export interface PaginationOptions {
|
|
175
|
+
enabled?: boolean;
|
|
176
|
+
mode?: PaginationMode;
|
|
177
|
+
pageSize?: number;
|
|
178
|
+
showPageSizeSelector?: boolean;
|
|
179
|
+
pageSizeOptions?: number[];
|
|
180
|
+
serverConfig?: ServerPaginationConfig;
|
|
181
|
+
}
|
|
182
|
+
/** Performance tuning knobs for large datasets. */
|
|
183
|
+
export interface PerformanceConfig {
|
|
184
|
+
/** Enable horizontal (column) virtualization. Default `true`. */
|
|
185
|
+
enableHorizontalVirtualization?: boolean;
|
|
186
|
+
/** Column count above which horizontal virtualization activates. Default `50`. */
|
|
187
|
+
horizontalVirtualizationThreshold?: number;
|
|
188
|
+
/** Row count above which sorting is offloaded to a Web Worker. Default `5000`. Set to `0` to disable. */
|
|
189
|
+
sortWorkerThreshold?: number;
|
|
190
|
+
/** Maximum search-cache size for global filtering. Default `5000`. */
|
|
191
|
+
maxFilterCacheSize?: number;
|
|
192
|
+
/** Enable aggressive memoization for large datasets. Default `true`. */
|
|
193
|
+
enableAggressiveMemoization?: boolean;
|
|
194
|
+
}
|
|
195
|
+
export interface ContextMenuItem {
|
|
100
196
|
id: string;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
197
|
+
label: string;
|
|
198
|
+
icon?: ReactNode;
|
|
199
|
+
onClick: (row: GridRow) => void;
|
|
200
|
+
disabled?: boolean;
|
|
201
|
+
/** Renders as a horizontal divider; `label` and `onClick` are ignored. */
|
|
202
|
+
separator?: boolean;
|
|
105
203
|
}
|
|
106
204
|
export interface BulkActionOption {
|
|
107
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Unique identifier for this action.
|
|
207
|
+
* Open string type — add any custom id (e.g. `"approve"`, `"flag"`).
|
|
208
|
+
*/
|
|
209
|
+
id: string;
|
|
108
210
|
label: string;
|
|
109
211
|
icon: ReactNode;
|
|
110
212
|
onClick: (selectedRows: Set<string | number>) => void;
|
|
111
213
|
disabled?: boolean;
|
|
112
214
|
destructive?: boolean;
|
|
113
215
|
}
|
|
216
|
+
export interface SavedFilter {
|
|
217
|
+
id: string;
|
|
218
|
+
name: string;
|
|
219
|
+
globalFilter: string;
|
|
220
|
+
columnFilters: Record<string, ColumnFilterValue>;
|
|
221
|
+
searchMode: SearchMode;
|
|
222
|
+
}
|
|
223
|
+
export interface ServerFilterChangePayload {
|
|
224
|
+
globalFilter: string;
|
|
225
|
+
columnFilters: ActiveFilters;
|
|
226
|
+
filterableKeys: string[];
|
|
227
|
+
searchMode?: SearchMode;
|
|
228
|
+
}
|
|
229
|
+
export interface ColumnConfig {
|
|
230
|
+
columnWidths: Record<string, number>;
|
|
231
|
+
columnVisibility: Record<string, boolean>;
|
|
232
|
+
pinnedColumns: string[];
|
|
233
|
+
sortConfig: SortConfig;
|
|
234
|
+
/** Multi-level grouping state persisted to storage. */
|
|
235
|
+
groupConfig?: {
|
|
236
|
+
columnKeys?: string[];
|
|
237
|
+
};
|
|
238
|
+
filters: {
|
|
239
|
+
globalFilter: string;
|
|
240
|
+
columnFilters: ActiveFilters;
|
|
241
|
+
};
|
|
242
|
+
columnOrder?: string[];
|
|
243
|
+
density?: Density;
|
|
244
|
+
}
|
|
245
|
+
export interface RowEventParams {
|
|
246
|
+
row: GridRow;
|
|
247
|
+
event: MouseEvent;
|
|
248
|
+
}
|
|
249
|
+
export interface CellClickParams {
|
|
250
|
+
row: GridRow;
|
|
251
|
+
column: GridColumn;
|
|
252
|
+
value: any;
|
|
253
|
+
event: MouseEvent;
|
|
254
|
+
}
|
|
255
|
+
export interface CellContextMenuParams {
|
|
256
|
+
row: GridRow;
|
|
257
|
+
column: GridColumn;
|
|
258
|
+
value: any;
|
|
259
|
+
displayValue: string;
|
|
260
|
+
event: MouseEvent;
|
|
261
|
+
}
|
|
262
|
+
export interface CellFocusParams {
|
|
263
|
+
row: GridRow;
|
|
264
|
+
column: GridColumn;
|
|
265
|
+
value: any;
|
|
266
|
+
rowIndex: number;
|
|
267
|
+
colIndex: number;
|
|
268
|
+
}
|
|
269
|
+
export interface CellSelectionPayload {
|
|
270
|
+
bounds: {
|
|
271
|
+
rowStart: number;
|
|
272
|
+
rowEnd: number;
|
|
273
|
+
colStart: number;
|
|
274
|
+
colEnd: number;
|
|
275
|
+
} | null;
|
|
276
|
+
cells: Array<CellFocusParams>;
|
|
277
|
+
}
|
|
278
|
+
export interface CopyCellsPayload {
|
|
279
|
+
text: string;
|
|
280
|
+
bounds?: {
|
|
281
|
+
rowStart: number;
|
|
282
|
+
rowEnd: number;
|
|
283
|
+
colStart: number;
|
|
284
|
+
colEnd: number;
|
|
285
|
+
} | null;
|
|
286
|
+
cells: Array<CellFocusParams>;
|
|
287
|
+
isRectangular: boolean;
|
|
288
|
+
isFocusedCell: boolean;
|
|
289
|
+
}
|
|
114
290
|
export interface KDGridProps {
|
|
115
291
|
data: GridRow[];
|
|
116
292
|
columns: GridColumn[];
|
|
117
293
|
/**
|
|
118
|
-
*
|
|
119
|
-
* Priority order:
|
|
120
|
-
* 1. If getRowId is provided, use it to extract the ID from the row
|
|
121
|
-
* 2. Else if row.id exists, use it
|
|
122
|
-
* 3. Else use the row's index as fallback (may cause issues with pagination/filtering)
|
|
294
|
+
* Derive a unique row identifier from a row object.
|
|
123
295
|
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* Recommendation: Always provide either row.id or getRowId prop for best results.
|
|
296
|
+
* Priority:
|
|
297
|
+
* 1. `getRowId(row)` if provided
|
|
298
|
+
* 2. `row.id` if present
|
|
299
|
+
* 3. Row index (⚠️ may cause issues with pagination / filtering)
|
|
130
300
|
*/
|
|
131
301
|
getRowId?: (row: GridRow) => string | number;
|
|
302
|
+
/** Fixed height of the grid container in pixels. */
|
|
132
303
|
height?: number;
|
|
304
|
+
/** Row density. Default `"md"`. */
|
|
133
305
|
density?: Density;
|
|
134
306
|
onDensityChange?: (density: Density) => void;
|
|
135
|
-
/**
|
|
136
|
-
* Optional header size controls (independent of row density).
|
|
137
|
-
* - If headerHeight is provided, it takes precedence (fixed pixel height).
|
|
138
|
-
* - Else if headerDensity is provided, it maps to the density sizing (sm|md|lg).
|
|
139
|
-
* - Else defaults to medium (md).
|
|
140
|
-
*/
|
|
141
|
-
headerDensity?: Density;
|
|
142
|
-
headerHeight?: number;
|
|
307
|
+
/** Show a density toggle in the toolbar. */
|
|
143
308
|
showDensityControl?: boolean;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
309
|
+
/** Override the header row height in pixels. Takes precedence over `headerDensity`. */
|
|
310
|
+
headerHeight?: number;
|
|
311
|
+
/** Independent density for the header row. */
|
|
312
|
+
headerDensity?: Density;
|
|
313
|
+
rowHeight?: number;
|
|
314
|
+
overscan?: number;
|
|
150
315
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
316
|
+
* When total post-filter rows ≤ this number, virtualization is disabled for
|
|
317
|
+
* simpler DOM. Default `300`.
|
|
153
318
|
*/
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
formats?: Array<"csv" | "json" | "xlsx">;
|
|
157
|
-
/** Default exported filename without extension (defaults to "grid-data") */
|
|
158
|
-
filename?: string;
|
|
159
|
-
/** Enable/disable export action (defaults to true; combined with showExport) */
|
|
160
|
-
enabled?: boolean;
|
|
161
|
-
/** Export execution mode. Default: 'client'. */
|
|
162
|
-
exportMode?: "client" | "server";
|
|
163
|
-
/**
|
|
164
|
-
* Optional handler to perform server-side export when exportMode === 'server'.
|
|
165
|
-
* If exportSelected is true, selectedRowIds will contain the ids that are currently selected in the grid.
|
|
166
|
-
*/
|
|
167
|
-
onServerExport?: (format: "csv" | "json" | "xlsx", exportSelected: boolean, selectedRowIds?: Array<string | number>) => void;
|
|
168
|
-
};
|
|
319
|
+
virtualizationThreshold?: number;
|
|
320
|
+
selectable?: boolean;
|
|
169
321
|
sortable?: boolean;
|
|
170
322
|
filterable?: boolean;
|
|
171
323
|
groupable?: boolean;
|
|
172
324
|
virtualized?: boolean;
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}) => void;
|
|
185
|
-
onCellContextMenu?: (args: {
|
|
186
|
-
row: GridRow;
|
|
187
|
-
column: GridColumn;
|
|
188
|
-
value: any;
|
|
189
|
-
displayValue: string;
|
|
190
|
-
event: MouseEvent;
|
|
191
|
-
}) => void;
|
|
192
|
-
cellFocusEnabled?: boolean;
|
|
193
|
-
onCellFocusChange?: (args: {
|
|
194
|
-
row: GridRow;
|
|
195
|
-
column: GridColumn;
|
|
196
|
-
value: any;
|
|
197
|
-
rowIndex: number;
|
|
198
|
-
colIndex: number;
|
|
199
|
-
}) => void;
|
|
200
|
-
cellSelectionEnabled?: boolean;
|
|
201
|
-
canSelectCell?: (row: GridRow, column: GridColumn) => boolean;
|
|
202
|
-
onCellSelectionChange?: (payload: {
|
|
203
|
-
bounds: {
|
|
204
|
-
rowStart: number;
|
|
205
|
-
rowEnd: number;
|
|
206
|
-
colStart: number;
|
|
207
|
-
colEnd: number;
|
|
208
|
-
} | null;
|
|
209
|
-
cells: Array<{
|
|
210
|
-
row: GridRow;
|
|
211
|
-
column: GridColumn;
|
|
212
|
-
value: any;
|
|
213
|
-
rowIndex: number;
|
|
214
|
-
colIndex: number;
|
|
215
|
-
}>;
|
|
216
|
-
}) => void;
|
|
217
|
-
onAutosizeColumn?: (columnKey: string) => void;
|
|
218
|
-
onAutosizeAllColumns?: () => void;
|
|
219
|
-
onResetColumns?: () => void;
|
|
220
|
-
pagination?: {
|
|
221
|
-
enabled?: boolean;
|
|
222
|
-
mode?: PaginationMode;
|
|
223
|
-
pageSize?: number;
|
|
224
|
-
showPageSizeSelector?: boolean;
|
|
225
|
-
pageSizeOptions?: number[];
|
|
226
|
-
serverConfig?: ServerPaginationConfig;
|
|
227
|
-
};
|
|
228
|
-
/** If provided, when total (post-filter) rows <= threshold virtualization is auto-disabled for simpler DOM (default: 300). */
|
|
229
|
-
virtualizationThreshold?: number;
|
|
325
|
+
/** Show a loading overlay / skeleton. Replaces `isLoading` from v2. */
|
|
326
|
+
loading?: boolean;
|
|
327
|
+
/** Text to show when there are no rows to display. */
|
|
328
|
+
noDataMessage?: string;
|
|
329
|
+
/** Fully custom empty-state renderer; overrides `noDataMessage`. */
|
|
330
|
+
noDataRenderer?: () => ReactNode;
|
|
331
|
+
showToolbar?: boolean;
|
|
332
|
+
showExport?: boolean;
|
|
333
|
+
exportOptions?: ExportOptions;
|
|
334
|
+
toolbarLeft?: ReactNode;
|
|
335
|
+
toolbarRight?: ReactNode;
|
|
230
336
|
onRefresh?: () => void;
|
|
231
|
-
|
|
337
|
+
/** Externally controlled selection ids (controlled mode). */
|
|
338
|
+
selectedRowIds?: Iterable<string | number> | null;
|
|
339
|
+
onRowSelect?: (row: GridRow) => void;
|
|
340
|
+
onSelectedRowsChange?: (selectedRows: Set<string | number>) => void;
|
|
341
|
+
/** Predicate; return `false` to make a specific row non-selectable. */
|
|
342
|
+
isRowSelectable?: (row: GridRow) => boolean;
|
|
232
343
|
bulkActions?: BulkActionOption[];
|
|
344
|
+
pagination?: PaginationOptions;
|
|
345
|
+
/**
|
|
346
|
+
* Controls how the global search bar matches text.
|
|
347
|
+
* Default `"contains"`.
|
|
348
|
+
*/
|
|
349
|
+
searchMode?: SearchMode;
|
|
233
350
|
savedFilters?: SavedFilter[];
|
|
234
351
|
onSaveFilter?: (filter: Omit<SavedFilter, "id">) => void;
|
|
235
352
|
onLoadFilter?: (filter: SavedFilter) => void;
|
|
236
353
|
onDeleteFilter?: (filterId: string) => void;
|
|
354
|
+
/** Fired on every filter change — useful for server-side filtering. */
|
|
237
355
|
onFilterChange?: (payload: ServerFilterChangePayload) => void;
|
|
238
|
-
onSort?: (columnKey: string, direction: "asc" | "desc") => void;
|
|
239
|
-
onColumnConfigChange?: (config: ColumnConfig) => void;
|
|
240
|
-
initialColumnConfig?: Partial<ColumnConfig>;
|
|
241
|
-
toolbarLeft?: ReactNode;
|
|
242
|
-
toolbarRight?: ReactNode;
|
|
243
356
|
/**
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
* - 'auto': show only when there are active grouped columns
|
|
247
|
-
* - 'visible': always show when groupable is true
|
|
357
|
+
* Called when the user sorts a column.
|
|
358
|
+
* `direction` is `null` when the sort is cleared.
|
|
248
359
|
*/
|
|
360
|
+
onSort?: (columnKey: string, direction: "asc" | "desc" | null) => void;
|
|
249
361
|
groupBarVisibility?: "hidden" | "auto" | "visible";
|
|
250
|
-
/**
|
|
251
|
-
* How to render group aggregation footer rows when grouping is enabled.
|
|
252
|
-
* - 'chips': render a colored summary bar with chips (default)
|
|
253
|
-
* - 'columns': render a full-width colored row placing aggregate values under their respective columns
|
|
254
|
-
*/
|
|
255
362
|
groupFooterVariant?: "chips" | "columns";
|
|
256
|
-
|
|
257
|
-
* Optional custom renderer for actions on grouped rows.
|
|
258
|
-
* Receives information about the group and its rows.
|
|
259
|
-
*/
|
|
363
|
+
showGroupExpandControls?: boolean;
|
|
260
364
|
renderGroupActions?: (groupInfo: {
|
|
261
365
|
groupKey: string;
|
|
262
366
|
columnKey: string;
|
|
@@ -265,160 +369,58 @@ export interface KDGridProps {
|
|
|
265
369
|
count: number;
|
|
266
370
|
level: number;
|
|
267
371
|
}) => ReactNode;
|
|
372
|
+
/** CSS class applied to each row — static string or derived from row + index. */
|
|
373
|
+
rowClassName?: string | ((row: GridRow, index: number) => string);
|
|
374
|
+
rowStyle?: (row: GridRow) => CSSProperties | undefined;
|
|
375
|
+
onRowClick?: (params: RowEventParams) => void;
|
|
376
|
+
onRowDoubleClick?: (params: RowEventParams) => void;
|
|
377
|
+
/** Right-click on a row (before the built-in context menu opens). */
|
|
378
|
+
onContextMenu?: (params: RowEventParams) => void;
|
|
379
|
+
/** Custom items for the row right-click context menu. */
|
|
380
|
+
contextMenuItems?: ContextMenuItem[];
|
|
381
|
+
onCellClick?: (params: CellClickParams) => void;
|
|
382
|
+
onCellContextMenu?: (params: CellContextMenuParams) => void;
|
|
383
|
+
/** Enable single-cell focus with arrow-key navigation. */
|
|
384
|
+
cellFocusEnabled?: boolean;
|
|
385
|
+
onCellFocusChange?: (params: CellFocusParams) => void;
|
|
386
|
+
/** Enable rectangular cell selection (disables browser text selection). */
|
|
387
|
+
cellSelectionEnabled?: boolean;
|
|
388
|
+
/** Return `false` to prevent a specific cell from being selected. */
|
|
389
|
+
canSelectCell?: (row: GridRow, column: GridColumn) => boolean;
|
|
390
|
+
onCellSelectionChange?: (payload: CellSelectionPayload) => void;
|
|
268
391
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*/
|
|
272
|
-
showGroupExpandControls?: boolean;
|
|
273
|
-
/**
|
|
274
|
-
* Callback invoked when user copies cells (Ctrl/Cmd + C) while cell focus or rectangular selection is active.
|
|
275
|
-
* Provides the plain text that was written to the clipboard (tab/newline delimited) and metadata.
|
|
276
|
-
*/
|
|
277
|
-
onCopyCells?: (payload: {
|
|
278
|
-
text: string;
|
|
279
|
-
/** Present only for rectangular selections */
|
|
280
|
-
bounds?: {
|
|
281
|
-
rowStart: number;
|
|
282
|
-
rowEnd: number;
|
|
283
|
-
colStart: number;
|
|
284
|
-
colEnd: number;
|
|
285
|
-
} | null;
|
|
286
|
-
cells: Array<{
|
|
287
|
-
row: GridRow;
|
|
288
|
-
column: GridColumn;
|
|
289
|
-
value: any;
|
|
290
|
-
rowIndex: number;
|
|
291
|
-
colIndex: number;
|
|
292
|
-
}>;
|
|
293
|
-
isRectangular: boolean;
|
|
294
|
-
isFocusedCell: boolean;
|
|
295
|
-
}) => void;
|
|
296
|
-
/** Optional controlled selection ids */
|
|
297
|
-
selectedRowIds?: Iterable<string | number> | null;
|
|
298
|
-
/** Performance optimization settings for large datasets */
|
|
299
|
-
performanceConfig?: {
|
|
300
|
-
/** Enable horizontal virtualization for large column sets (default: true) */
|
|
301
|
-
enableHorizontalVirtualization?: boolean;
|
|
302
|
-
/** Column count threshold to enable horizontal virtualization (default: 50) */
|
|
303
|
-
horizontalVirtualizationThreshold?: number;
|
|
304
|
-
/** Row count threshold to offload sorting to a Web Worker (default: 5000). Set to 0 to always sort inline. */
|
|
305
|
-
sortWorkerThreshold?: number;
|
|
306
|
-
/** Maximum cache size for filtering operations (default: 5000) */
|
|
307
|
-
maxFilterCacheSize?: number;
|
|
308
|
-
/** Enable aggressive memoization for large datasets (default: true) */
|
|
309
|
-
enableAggressiveMemoization?: boolean;
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
export interface ContextMenuItem {
|
|
313
|
-
id: string;
|
|
314
|
-
label: string;
|
|
315
|
-
icon?: ReactNode;
|
|
316
|
-
onClick: (row: GridRow) => void;
|
|
317
|
-
disabled?: boolean;
|
|
318
|
-
separator?: boolean;
|
|
319
|
-
}
|
|
320
|
-
export type SortDirection = "asc" | "desc" | null;
|
|
321
|
-
export interface SortConfig {
|
|
322
|
-
key: string | null;
|
|
323
|
-
direction: SortDirection;
|
|
324
|
-
}
|
|
325
|
-
export interface VirtualizedRange {
|
|
326
|
-
startIndex: number;
|
|
327
|
-
endIndex: number;
|
|
328
|
-
offsetY: number;
|
|
329
|
-
}
|
|
330
|
-
export interface ColumnFilterValue {
|
|
331
|
-
type: FilterType;
|
|
332
|
-
value: any;
|
|
333
|
-
operator?: "equals" | "contains" | "startsWith" | "endsWith" | "gt" | "lt" | "gte" | "lte" | "between";
|
|
334
|
-
secondValue?: any;
|
|
335
|
-
}
|
|
336
|
-
export interface ActiveFilters {
|
|
337
|
-
[columnKey: string]: ColumnFilterValue;
|
|
338
|
-
}
|
|
339
|
-
export interface ColumnConfig {
|
|
340
|
-
columnWidths: Record<string, number>;
|
|
341
|
-
columnVisibility: Record<string, boolean>;
|
|
342
|
-
pinnedColumns: string[];
|
|
343
|
-
sortConfig: SortConfig;
|
|
344
|
-
/**
|
|
345
|
-
* Persisted grouping configuration. New multi-level shape uses columnKeys.
|
|
346
|
-
* The legacy single-key field (columnKey) is retained for backward compatibility.
|
|
392
|
+
* Called when the user copies cells with Ctrl/⌘+C while cell focus or
|
|
393
|
+
* rectangular selection is active.
|
|
347
394
|
*/
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
};
|
|
356
|
-
columnOrder?: string[];
|
|
357
|
-
density?: Density;
|
|
358
|
-
}
|
|
359
|
-
export interface PaginationConfig {
|
|
360
|
-
enabled: boolean;
|
|
361
|
-
pageSize: number;
|
|
362
|
-
currentPage: number;
|
|
363
|
-
totalPages: number;
|
|
364
|
-
totalRows: number;
|
|
365
|
-
showPageSizeSelector?: boolean;
|
|
366
|
-
pageSizeOptions?: number[];
|
|
367
|
-
}
|
|
368
|
-
export interface ServerPaginationConfig {
|
|
369
|
-
enabled: boolean;
|
|
370
|
-
onPageChange: (page: number, pageSize: number) => Promise<void> | void;
|
|
371
|
-
onPageSizeChange?: (pageSize: number) => Promise<void> | void;
|
|
372
|
-
loading?: boolean;
|
|
373
|
-
totalRows: number;
|
|
374
|
-
}
|
|
375
|
-
export type PaginationMode = "client" | "server";
|
|
376
|
-
export interface FilterPopupProps {
|
|
377
|
-
column: GridColumn;
|
|
378
|
-
data: GridRow[];
|
|
379
|
-
currentFilter?: ColumnFilterValue;
|
|
380
|
-
onApplyFilter: (filter: ColumnFilterValue | null) => void;
|
|
381
|
-
onClose: () => void;
|
|
382
|
-
position: {
|
|
383
|
-
top: number;
|
|
384
|
-
left: number;
|
|
385
|
-
};
|
|
386
|
-
autoApply?: boolean;
|
|
387
|
-
}
|
|
388
|
-
export interface ServerFilterChangePayload {
|
|
389
|
-
globalFilter: string;
|
|
390
|
-
columnFilters: ActiveFilters;
|
|
391
|
-
filterableKeys: string[];
|
|
392
|
-
searchMode?: SearchMode;
|
|
395
|
+
onCopyCells?: (payload: CopyCellsPayload) => void;
|
|
396
|
+
onAutosizeColumn?: (columnKey: string) => void;
|
|
397
|
+
onAutosizeAllColumns?: () => void;
|
|
398
|
+
onResetColumns?: () => void;
|
|
399
|
+
onColumnConfigChange?: (config: ColumnConfig) => void;
|
|
400
|
+
initialColumnConfig?: Partial<ColumnConfig>;
|
|
401
|
+
performanceConfig?: PerformanceConfig;
|
|
393
402
|
}
|
|
394
|
-
/**
|
|
395
|
-
* Imperative handle for KDGrid to allow external control of grouping.
|
|
396
|
-
* Use with React.forwardRef and useImperativeHandle in the grid component.
|
|
397
|
-
*/
|
|
398
403
|
export interface KDGridRef {
|
|
399
|
-
/** Replace the entire ordered grouping
|
|
404
|
+
/** Replace the entire ordered grouping key list. */
|
|
400
405
|
setGroupKeys: (keys: string[]) => void;
|
|
401
|
-
/**
|
|
406
|
+
/** Append a grouping key if not already present. */
|
|
402
407
|
addGroupKey: (key: string) => void;
|
|
403
|
-
/** Remove a specific grouping key */
|
|
408
|
+
/** Remove a specific grouping key. */
|
|
404
409
|
removeGroupKey: (key: string) => void;
|
|
405
|
-
/** Expand
|
|
410
|
+
/** Expand every group for the current grouping keys. */
|
|
406
411
|
expandAllGroups: () => void;
|
|
407
|
-
/** Collapse all
|
|
412
|
+
/** Collapse all groups. */
|
|
408
413
|
collapseAllGroups: () => void;
|
|
409
|
-
/** Toggle a specific group path, e.g. "City=SF|Status=Open" */
|
|
414
|
+
/** Toggle a specific group path, e.g. `"City=SF|Status=Open"`. */
|
|
410
415
|
toggleGroupExpansion: (groupPath: string) => void;
|
|
411
|
-
/** Read the current
|
|
416
|
+
/** Read the current grouping configuration. */
|
|
412
417
|
getGroupConfig: () => GroupConfig;
|
|
413
|
-
/**
|
|
414
|
-
setColumnFilter: (columnKey: string, filter:
|
|
415
|
-
/** Clear a
|
|
418
|
+
/** Apply a column filter programmatically. Pass `null` to clear. */
|
|
419
|
+
setColumnFilter: (columnKey: string, filter: ColumnFilterValue | null) => void;
|
|
420
|
+
/** Clear a single column filter. */
|
|
416
421
|
clearColumnFilter: (columnKey: string) => void;
|
|
417
|
-
/** Clear all
|
|
422
|
+
/** Clear all active filters (global + column). */
|
|
418
423
|
clearAllFilters: () => void;
|
|
419
|
-
/** Set global
|
|
424
|
+
/** Set the global search text. */
|
|
420
425
|
setGlobalFilter: (value: string) => void;
|
|
421
426
|
}
|
|
422
|
-
export interface CustomDataGridProps extends KDGridProps {
|
|
423
|
-
}
|
|
424
|
-
export type CustomDataGridRef = KDGridRef;
|