react-kd-grid 5.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/README.md +309 -0
- package/dist/components/CellEditor.d.ts +23 -0
- package/dist/components/ColumnFilterSelector.d.ts +18 -0
- package/dist/components/CustomSelect.d.ts +14 -0
- package/dist/components/FooterAggregate.d.ts +16 -0
- package/dist/components/GridHeader.d.ts +39 -0
- package/dist/components/GridRows.d.ts +53 -0
- package/dist/components/GroupBar.d.ts +12 -0
- package/dist/components/GroupHeader.d.ts +29 -0
- package/dist/components/LicenseError.d.ts +9 -0
- package/dist/components/NoDataMessage.d.ts +11 -0
- package/dist/components/PaginationControls.d.ts +18 -0
- package/dist/components/Popover.d.ts +17 -0
- package/dist/components/RowContextMenu.d.ts +18 -0
- package/dist/components/SearchToolbar.d.ts +66 -0
- package/dist/components/filters/BooleanFilter.d.ts +7 -0
- package/dist/components/filters/DateFilter.d.ts +9 -0
- package/dist/components/filters/FilterContent.d.ts +9 -0
- package/dist/components/filters/FilterPopup.d.ts +2 -0
- package/dist/components/filters/MultiselectFilter.d.ts +10 -0
- package/dist/components/filters/NumberFilter.d.ts +9 -0
- package/dist/components/filters/TextFilter.d.ts +8 -0
- package/dist/components/filters/index.d.ts +6 -0
- package/dist/components/ui/DatePicker.d.ts +10 -0
- package/dist/constants.d.ts +1 -0
- package/dist/core/DataGrid.d.ts +3 -0
- package/dist/hooks/useAdvancedFiltering.d.ts +18 -0
- package/dist/hooks/useCellSelection.d.ts +67 -0
- package/dist/hooks/useColumnState.d.ts +45 -0
- package/dist/hooks/useDataWorker.d.ts +11 -0
- package/dist/hooks/useEditingCell.d.ts +49 -0
- package/dist/hooks/useExport.d.ts +14 -0
- package/dist/hooks/useGrouping.d.ts +28 -0
- package/dist/hooks/useInfiniteScroll.d.ts +31 -0
- package/dist/hooks/useLoadingBar.d.ts +21 -0
- package/dist/hooks/usePagination.d.ts +28 -0
- package/dist/hooks/useScrollSync.d.ts +29 -0
- package/dist/hooks/useSelection.d.ts +13 -0
- package/dist/hooks/useVirtualization.d.ts +17 -0
- package/dist/icons/index.d.ts +54 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.esm.js +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +592 -0
- package/dist/utils/dateUtils.d.ts +16 -0
- package/dist/utils/highlightText.d.ts +15 -0
- package/dist/utils/license.d.ts +3 -0
- package/package.json +97 -0
package/README.md
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# React KD Grid
|
|
2
|
+
|
|
3
|
+
A feature-rich, performant React data grid component with virtualization, grouping, filtering, sorting, and export capabilities.
|
|
4
|
+
|
|
5
|
+
> **Note**: This package requires a license key for production use.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Virtualization**: Efficiently render large datasets with both vertical and horizontal virtualization
|
|
10
|
+
- **Grouping**: Multi-level grouping with expandable/collapsible groups
|
|
11
|
+
- **Filtering**: Global and column-specific filtering with multiple filter types
|
|
12
|
+
- **Sorting**: Multi-column sorting with customizable sort functions
|
|
13
|
+
- **Pagination**: Client and server-side pagination support
|
|
14
|
+
- **Export**: Export data to CSV, JSON, and Excel formats
|
|
15
|
+
- **Selection**: Row and cell selection with keyboard navigation
|
|
16
|
+
- **Responsive**: Flexible column sizing with flex support
|
|
17
|
+
- **Accessibility**: Full keyboard navigation and screen reader support
|
|
18
|
+
- **TypeScript**: Built with TypeScript for excellent type safety
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install react-kd-grid
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Basic Usage
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import React from "react";
|
|
30
|
+
import { KDGrid } from "react-kd-grid";
|
|
31
|
+
|
|
32
|
+
const columns = [
|
|
33
|
+
{ key: "id", header: "ID", width: 80 },
|
|
34
|
+
{ key: "name", header: "Name", width: 200, sortable: true },
|
|
35
|
+
{ key: "email", header: "Email", width: 300, sortable: true },
|
|
36
|
+
{ key: "department", header: "Department", width: 150, sortable: true },
|
|
37
|
+
{
|
|
38
|
+
key: "salary",
|
|
39
|
+
header: "Salary",
|
|
40
|
+
width: 120,
|
|
41
|
+
sortable: true,
|
|
42
|
+
aggregate: "avg",
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const data = [
|
|
47
|
+
{
|
|
48
|
+
id: 1,
|
|
49
|
+
name: "John Doe",
|
|
50
|
+
email: "john@example.com",
|
|
51
|
+
department: "Engineering",
|
|
52
|
+
salary: 75000,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 2,
|
|
56
|
+
name: "Jane Smith",
|
|
57
|
+
email: "jane@example.com",
|
|
58
|
+
department: "Marketing",
|
|
59
|
+
salary: 65000,
|
|
60
|
+
},
|
|
61
|
+
// ... more data
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
function App() {
|
|
65
|
+
return (
|
|
66
|
+
<div style={{ height: 600 }}>
|
|
67
|
+
<KDGrid
|
|
68
|
+
licenseKey="YOUR_LICENSE_KEY"
|
|
69
|
+
data={data}
|
|
70
|
+
columns={columns}
|
|
71
|
+
getRowId={(row) => row.id}
|
|
72
|
+
height={600}
|
|
73
|
+
filterable={true}
|
|
74
|
+
sortable={true}
|
|
75
|
+
groupable={true}
|
|
76
|
+
virtualized={true}
|
|
77
|
+
pagination={{
|
|
78
|
+
enabled: true,
|
|
79
|
+
mode: "client",
|
|
80
|
+
pageSize: 20,
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Advanced Features
|
|
89
|
+
|
|
90
|
+
### Column Configuration
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
const columns = [
|
|
94
|
+
{
|
|
95
|
+
key: "status",
|
|
96
|
+
header: "Status",
|
|
97
|
+
width: 120,
|
|
98
|
+
filterable: {
|
|
99
|
+
type: "multiselect",
|
|
100
|
+
options: [
|
|
101
|
+
{ label: "Active", value: "active" },
|
|
102
|
+
{ label: "Inactive", value: "inactive" },
|
|
103
|
+
{ label: "Pending", value: "pending" },
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
formatter: (value) => value.toUpperCase(),
|
|
107
|
+
aggregate: "count",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: "createdAt",
|
|
111
|
+
header: "Created",
|
|
112
|
+
width: 150,
|
|
113
|
+
filterable: {
|
|
114
|
+
type: "date",
|
|
115
|
+
placeholder: "Filter by date...",
|
|
116
|
+
},
|
|
117
|
+
formatter: (value) => new Date(value).toLocaleDateString(),
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
key: "actions",
|
|
121
|
+
header: "Actions",
|
|
122
|
+
width: 100,
|
|
123
|
+
cellRenderer: (value, row) => (
|
|
124
|
+
<button onClick={() => handleEdit(row)}>Edit</button>
|
|
125
|
+
),
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Server-Side Operations
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
function ServerGrid() {
|
|
134
|
+
const [data, setData] = useState([]);
|
|
135
|
+
const [loading, setLoading] = useState(false);
|
|
136
|
+
const [pagination, setPagination] = useState({
|
|
137
|
+
page: 1,
|
|
138
|
+
pageSize: 20,
|
|
139
|
+
total: 0,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const handleServerPagination = async (page: number, pageSize: number) => {
|
|
143
|
+
setLoading(true);
|
|
144
|
+
const result = await fetchServerData(page, pageSize);
|
|
145
|
+
setData(result.data);
|
|
146
|
+
setPagination((prev) => ({ ...prev, page, pageSize, total: result.total }));
|
|
147
|
+
setLoading(false);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const handleServerFilter = async (filters: any) => {
|
|
151
|
+
setLoading(true);
|
|
152
|
+
const result = await fetchFilteredData(filters);
|
|
153
|
+
setData(result.data);
|
|
154
|
+
setLoading(false);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<KDGrid
|
|
159
|
+
licenseKey="YOUR_LICENSE_KEY"
|
|
160
|
+
data={data}
|
|
161
|
+
columns={columns}
|
|
162
|
+
pagination={{
|
|
163
|
+
enabled: true,
|
|
164
|
+
mode: "server",
|
|
165
|
+
pageSize: pagination.pageSize,
|
|
166
|
+
serverConfig: {
|
|
167
|
+
onPageChange: handleServerPagination,
|
|
168
|
+
loading: loading,
|
|
169
|
+
totalRows: pagination.total,
|
|
170
|
+
},
|
|
171
|
+
}}
|
|
172
|
+
onFilterChange={handleServerFilter}
|
|
173
|
+
isLoading={loading}
|
|
174
|
+
/>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Custom Styling
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
const customRowStyle = (row) => ({
|
|
183
|
+
backgroundColor: row.status === "active" ? "#f0fff4" : "#fff5f5",
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const customCellStyle = (value, row) => ({
|
|
187
|
+
color: row.priority === "high" ? "#dc2626" : "#1f2937",
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
<KDGrid
|
|
191
|
+
licenseKey="YOUR_LICENSE_KEY"
|
|
192
|
+
// ... other props
|
|
193
|
+
rowStyle={customRowStyle}
|
|
194
|
+
columns={columns.map((col) => ({
|
|
195
|
+
...col,
|
|
196
|
+
cellStyle: customCellStyle,
|
|
197
|
+
}))}
|
|
198
|
+
/>;
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Event Handling
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
const handleRowClick = (row, event) => {
|
|
205
|
+
console.log("Row clicked:", row);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const handleCellClick = ({ row, column, value, event }) => {
|
|
209
|
+
console.log("Cell clicked:", { row, column, value });
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const handleSelectionChange = (selectedRows) => {
|
|
213
|
+
console.log("Selected rows:", Array.from(selectedRows));
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const handleSort = (columnKey, direction) => {
|
|
217
|
+
console.log("Sort changed:", { columnKey, direction });
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
<KDGrid
|
|
221
|
+
licenseKey="YOUR_LICENSE_KEY"
|
|
222
|
+
// ... other props
|
|
223
|
+
onRowClick={handleRowClick}
|
|
224
|
+
onCellClick={handleCellClick}
|
|
225
|
+
onSelectedRowsChange={handleSelectionChange}
|
|
226
|
+
onSort={handleSort}
|
|
227
|
+
selectable={true}
|
|
228
|
+
/>;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## API Reference
|
|
232
|
+
|
|
233
|
+
### KDGrid Props
|
|
234
|
+
|
|
235
|
+
| Prop | Type | Default | Description |
|
|
236
|
+
| ---------------------- | --------------------------------------------------------- | -------------------- | ----------------------------------------------------- |
|
|
237
|
+
| `licenseKey` | `string` | Required | License key for the grid (will not render without it) |
|
|
238
|
+
| `data` | `GridRow[]` | Required | Array of data rows to display |
|
|
239
|
+
| `columns` | `GridColumn[]` | Required | Array of column definitions |
|
|
240
|
+
| `getRowId` | `(row: GridRow) => string \| number` | Optional | Function to extract unique ID from row |
|
|
241
|
+
| `height` | `number` | 400 | Grid height in pixels |
|
|
242
|
+
| `density` | `'sm' \| 'md' \| 'lg'` | `'md'` | Row density (affects row height) |
|
|
243
|
+
| `selectable` | `boolean` | `false` | Enable row selection |
|
|
244
|
+
| `filterable` | `boolean` | `true` | Enable filtering |
|
|
245
|
+
| `sortable` | `boolean` | `true` | Enable sorting |
|
|
246
|
+
| `groupable` | `boolean` | `false` | Enable grouping |
|
|
247
|
+
| `virtualized` | `boolean` | `true` | Enable virtualization |
|
|
248
|
+
| `pagination` | `PaginationOptions` | `{ enabled: false }` | Pagination configuration |
|
|
249
|
+
| `loading` | `boolean` | `false` | Show loading state or skeleton |
|
|
250
|
+
| `editable` | `boolean` | `false` | Enable grid-level inline editing |
|
|
251
|
+
| `onRowSelect` | `(row: GridRow) => void` | Optional | Row selection callback |
|
|
252
|
+
| `onSelectedRowsChange` | `(selectedRows: Set<string \| number>) => void` | Optional | Selection change callback |
|
|
253
|
+
| `onFilterChange` | `(filters: ServerFilterChangePayload) => void` | Optional | Filter change callback |
|
|
254
|
+
| `onSort` | `(columnKey: string, direction: 'asc' \| 'desc') => void` | Optional | Sort change callback |
|
|
255
|
+
| `onCellEdit` | `(params: CellEditParams) => void` | Optional | Called when a cell edit is committed |
|
|
256
|
+
|
|
257
|
+
### Imperative API (via React Ref)
|
|
258
|
+
|
|
259
|
+
The `KDGrid` component exposes several methods through its ref:
|
|
260
|
+
|
|
261
|
+
| Method | Params | Description |
|
|
262
|
+
| ------------------- | --------------------------- | ----------------------------------------- |
|
|
263
|
+
| `scrollToRow` | `(rowId: string \| number)` | Scrolls to a specific row by its ID |
|
|
264
|
+
| `scrollToColumn` | `(columnKey: string)` | Scrolls to a specific column by its key |
|
|
265
|
+
| `expandAllGroups` | `()` | Expands all collapsed groups |
|
|
266
|
+
| `collapseAllGroups` | `()` | Collapses all expanded groups |
|
|
267
|
+
| `clearAllFilters` | `()` | Clears global and column-specific filters |
|
|
268
|
+
|
|
269
|
+
### Column Definition
|
|
270
|
+
|
|
271
|
+
| Property | Type | Default | Description |
|
|
272
|
+
| ------------------ | --------------------------------------------------------- | -------- | ------------------------- |
|
|
273
|
+
| `key` | `string` | Required | Unique column identifier |
|
|
274
|
+
| `header` | `string` | Required | Column header text |
|
|
275
|
+
| `width` | `number` | 100 | Column width in pixels |
|
|
276
|
+
| `flex` | `boolean \| number` | `false` | Flexible column sizing |
|
|
277
|
+
| `sortable` | `boolean` | `true` | Enable column sorting |
|
|
278
|
+
| `filterable` | `boolean \| ColumnFilter` | `false` | Enable column filtering |
|
|
279
|
+
| `formatter` | `(value: any) => string` | Optional | Custom value formatter |
|
|
280
|
+
| `cellRenderer` | `(value: any, row: GridRow) => ReactNode` | Optional | Custom cell renderer |
|
|
281
|
+
| `aggregate` | `'sum' \| 'avg' \| 'min' \| 'max' \| function` | Optional | Group aggregate function |
|
|
282
|
+
| `footer_aggregate` | `'count' \| 'sum' \| 'avg' \| 'min' \| 'max' \| function` | Optional | Footer aggregate function |
|
|
283
|
+
|
|
284
|
+
## Performance Tips
|
|
285
|
+
|
|
286
|
+
1. **Enable Virtualization**: For datasets with > 1000 rows, always enable virtualization
|
|
287
|
+
2. **Use Server-Side Operations**: For very large datasets, use server-side pagination and filtering
|
|
288
|
+
3. **Optimize Renderers**: Avoid creating new objects/functions in cell renderers
|
|
289
|
+
4. **Limit Column Count**: Horizontal virtualization kicks in at 50+ columns
|
|
290
|
+
5. **Use Memoization**: Memoize expensive calculations in formatters and renderers
|
|
291
|
+
|
|
292
|
+
## Browser Support
|
|
293
|
+
|
|
294
|
+
- Chrome 80+
|
|
295
|
+
- Firefox 75+
|
|
296
|
+
- Safari 13+
|
|
297
|
+
- Edge 80+
|
|
298
|
+
|
|
299
|
+
## License
|
|
300
|
+
|
|
301
|
+
MIT License - see LICENSE file for details.
|
|
302
|
+
|
|
303
|
+
## Contributing
|
|
304
|
+
|
|
305
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
306
|
+
|
|
307
|
+
## Support
|
|
308
|
+
|
|
309
|
+
If you encounter any issues or have questions, please [open an issue](https://github.com/yourusername/react-kd-grid/issues) on GitHub.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CellEditor
|
|
3
|
+
*
|
|
4
|
+
* Renders the appropriate input control for an inline cell edit session.
|
|
5
|
+
* Lifecycle:
|
|
6
|
+
* • mounts → auto-focuses, selects all existing text
|
|
7
|
+
* • Enter / Tab → commit (Tab also moves focus to next cell conceptually)
|
|
8
|
+
* • Escape → cancel
|
|
9
|
+
* • blur → commit (unless blur was caused by Escape)
|
|
10
|
+
*
|
|
11
|
+
* Props are intentionally minimal — the parent hook owns the "editing cell"
|
|
12
|
+
* identity; this component only owns the *draft value* and input DOM state.
|
|
13
|
+
*/
|
|
14
|
+
import type { GridColumn, GridRow } from "../types";
|
|
15
|
+
interface CellEditorProps {
|
|
16
|
+
column: GridColumn;
|
|
17
|
+
row: GridRow;
|
|
18
|
+
initialValue: any;
|
|
19
|
+
onCommit: (newValue: any) => void;
|
|
20
|
+
onCancel: () => void;
|
|
21
|
+
}
|
|
22
|
+
export declare const CellEditor: ({ column, row, initialValue, onCommit, onCancel, }: CellEditorProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface ColumnFilterSelectorProps {
|
|
2
|
+
columns: Array<{
|
|
3
|
+
key: string;
|
|
4
|
+
header: string;
|
|
5
|
+
filterable?: {
|
|
6
|
+
type?: string;
|
|
7
|
+
options?: Array<{
|
|
8
|
+
label: string;
|
|
9
|
+
value: string | number;
|
|
10
|
+
}>;
|
|
11
|
+
placeholder?: string;
|
|
12
|
+
};
|
|
13
|
+
}>;
|
|
14
|
+
columnFilters: Record<string, any>;
|
|
15
|
+
onColumnFilter?: (columnKey: string, filter: any) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const ColumnFilterSelector: ({ columns, columnFilters, onColumnFilter, }: ColumnFilterSelectorProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Option {
|
|
2
|
+
label: string;
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
interface CustomSelectProps {
|
|
6
|
+
options: Option[];
|
|
7
|
+
value?: string;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
searchable?: boolean;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const CustomSelect: ({ options, value, placeholder, onChange, searchable, className, }: CustomSelectProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { GridColumn, GridRow } from "../types";
|
|
3
|
+
interface FooterAggregateProps {
|
|
4
|
+
columns: (GridColumn & {
|
|
5
|
+
width: number;
|
|
6
|
+
})[];
|
|
7
|
+
data: GridRow[];
|
|
8
|
+
selectable: boolean;
|
|
9
|
+
/** Resolved row height so footer matches density */
|
|
10
|
+
rowHeight: number;
|
|
11
|
+
/** Pinned columns (same semantics as grid body) */
|
|
12
|
+
pinnedColumns?: Set<string>;
|
|
13
|
+
getRowId?: (row: GridRow) => string | number;
|
|
14
|
+
}
|
|
15
|
+
export declare const FooterAggregate: React.NamedExoticComponent<FooterAggregateProps>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { GridColumn, SortConfig, ActiveFilters, ColumnFilterValue, GridRow } from "../types";
|
|
3
|
+
interface GridHeaderProps {
|
|
4
|
+
pinnedColumns: GridColumn[];
|
|
5
|
+
unpinnedColumns: GridColumn[];
|
|
6
|
+
hvPadLeft?: number;
|
|
7
|
+
hvPadRight?: number;
|
|
8
|
+
headerHeight: number;
|
|
9
|
+
sortConfig: SortConfig;
|
|
10
|
+
columnFilters: ActiveFilters;
|
|
11
|
+
selectable: boolean;
|
|
12
|
+
selectedRows: Set<string | number>;
|
|
13
|
+
totalRows: number;
|
|
14
|
+
data: GridRow[];
|
|
15
|
+
onSort: (key: string) => void;
|
|
16
|
+
onColumnFilter: (key: string, filter: ColumnFilterValue | null) => void;
|
|
17
|
+
onSelectAll: () => void;
|
|
18
|
+
onColumnResize?: (columnKey: string, width: number) => void;
|
|
19
|
+
pinnedKeySet?: Set<string>;
|
|
20
|
+
onColumnPin?: (columnKey: string, pinned: boolean) => void;
|
|
21
|
+
groupable?: boolean;
|
|
22
|
+
groupedByColumn?: string | null;
|
|
23
|
+
onGroupBy?: (columnKey: string | null) => void;
|
|
24
|
+
groupedByColumns?: string[];
|
|
25
|
+
onGroupToggle?: (columnKey: string, nextGrouped: boolean) => void;
|
|
26
|
+
onAutosizeColumn?: (columnKey: string) => void;
|
|
27
|
+
onAutosizeAllColumns?: () => void;
|
|
28
|
+
onResetColumns?: () => void;
|
|
29
|
+
columnOrder: string[];
|
|
30
|
+
onColumnOrderChange: (order: string[]) => void;
|
|
31
|
+
paginationMode?: "client" | "server" | null;
|
|
32
|
+
/** Minimum column width enforced during drag-resize. Defaults to 80px. */
|
|
33
|
+
minResizeWidth?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare const GridHeader: React.MemoExoticComponent<{
|
|
36
|
+
({ pinnedColumns, unpinnedColumns, hvPadLeft, hvPadRight, headerHeight, sortConfig, columnFilters, selectable, selectedRows, totalRows, data, onSort, onColumnFilter, onSelectAll, onColumnResize, pinnedKeySet, onColumnPin, groupable, groupedByColumn, onGroupBy, groupedByColumns, onGroupToggle, onAutosizeColumn, onAutosizeAllColumns, onResetColumns, columnOrder, onColumnOrderChange, paginationMode, minResizeWidth, }: GridHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
displayName: string;
|
|
38
|
+
}>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CSSProperties, MouseEvent } from "react";
|
|
2
|
+
import { GridRow, GridColumn, VirtualizedRange, ContextMenuItem, RowEventParams, CellClickParams, CellContextMenuParams } from "../types";
|
|
3
|
+
interface GridRowsProps {
|
|
4
|
+
data: GridRow[];
|
|
5
|
+
columns: GridColumn[];
|
|
6
|
+
selectedRows: Set<string | number>;
|
|
7
|
+
virtualized: boolean;
|
|
8
|
+
virtualizedRange: VirtualizedRange;
|
|
9
|
+
rowHeight: number;
|
|
10
|
+
selectable: boolean;
|
|
11
|
+
isRowSelectable?: (row: GridRow) => boolean;
|
|
12
|
+
onRowSelect: (rowId: string | number, isSelected: boolean) => void;
|
|
13
|
+
pinnedColumns?: Set<string>;
|
|
14
|
+
hvPadLeft?: number;
|
|
15
|
+
hvPadRight?: number;
|
|
16
|
+
rowStyle?: (row: GridRow) => CSSProperties | undefined;
|
|
17
|
+
globalFilter?: string;
|
|
18
|
+
onContextMenu?: (params: RowEventParams) => void;
|
|
19
|
+
onRowDoubleClick?: (params: RowEventParams) => void;
|
|
20
|
+
onRowClick?: (params: RowEventParams) => void;
|
|
21
|
+
onCellClick?: (params: CellClickParams) => void;
|
|
22
|
+
isCellFocused?: (rowId: string | number, columnKey: string) => boolean;
|
|
23
|
+
isCellSelected?: (rowId: string | number, columnKey: string) => boolean;
|
|
24
|
+
onCellContextMenu?: (params: CellContextMenuParams) => void;
|
|
25
|
+
onCellMouseDown?: (args: {
|
|
26
|
+
row: GridRow;
|
|
27
|
+
column: GridColumn;
|
|
28
|
+
event: MouseEvent;
|
|
29
|
+
}) => void;
|
|
30
|
+
onCellMouseEnter?: (args: {
|
|
31
|
+
row: GridRow;
|
|
32
|
+
column: GridColumn;
|
|
33
|
+
event: MouseEvent;
|
|
34
|
+
}) => void;
|
|
35
|
+
/** Custom items for the row right-click context menu. */
|
|
36
|
+
contextMenuItems?: ContextMenuItem[];
|
|
37
|
+
getRowId?: (row: GridRow) => string | number;
|
|
38
|
+
/** Returns true when a specific (rowId, columnKey) pair is currently being edited. */
|
|
39
|
+
isEditing?: (rowId: string | number, columnKey: string) => boolean;
|
|
40
|
+
/** Called when the user double-clicks (or presses F2 on) an editable cell. */
|
|
41
|
+
onStartEdit?: (row: GridRow, column: GridColumn) => void;
|
|
42
|
+
/** Called by CellEditor when the user commits a value. */
|
|
43
|
+
onCommitEdit?: (newValue: any) => void;
|
|
44
|
+
/** Called by CellEditor when the user cancels without saving. */
|
|
45
|
+
onCancelEdit?: () => void;
|
|
46
|
+
/** The current edit initial value — passed down to CellEditor to initialise draft state. */
|
|
47
|
+
editingInitialValue?: any;
|
|
48
|
+
}
|
|
49
|
+
export declare const GridRows: import("react").MemoExoticComponent<{
|
|
50
|
+
({ data, columns, selectedRows, virtualized, virtualizedRange, rowHeight, selectable, isRowSelectable, onRowSelect, pinnedColumns, hvPadLeft, hvPadRight, rowStyle, globalFilter, onContextMenu, onRowDoubleClick, onRowClick, onCellClick, isCellFocused, isCellSelected, onCellContextMenu, onCellMouseDown, onCellMouseEnter, contextMenuItems, getRowId, isEditing, onStartEdit, onCommitEdit, onCancelEdit, editingInitialValue, }: GridRowsProps): import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
displayName: string;
|
|
52
|
+
}>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GridColumn } from "../types";
|
|
2
|
+
interface GroupBarProps {
|
|
3
|
+
columns: GridColumn[];
|
|
4
|
+
groupedKeys: string[];
|
|
5
|
+
onRemove: (columnKey: string) => void;
|
|
6
|
+
onReorder: (newOrder: string[]) => void;
|
|
7
|
+
onDropColumnKey: (columnKey: string) => void;
|
|
8
|
+
onToggleExpandAll?: () => void;
|
|
9
|
+
isAnyExpanded?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const GroupBar: ({ columns, groupedKeys, onRemove, onReorder, onDropColumnKey, onToggleExpandAll, isAnyExpanded, }: GroupBarProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { GridRow, KDGridProps } from "../types";
|
|
2
|
+
interface GroupHeaderProps {
|
|
3
|
+
row: GridRow & {
|
|
4
|
+
_isGroupHeader?: boolean;
|
|
5
|
+
_groupKey?: string;
|
|
6
|
+
_groupCount?: number;
|
|
7
|
+
};
|
|
8
|
+
isExpanded: boolean;
|
|
9
|
+
onToggle: (groupKey: string) => void;
|
|
10
|
+
viewportWidth: number;
|
|
11
|
+
selectable: boolean;
|
|
12
|
+
rowHeight?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Optional function to map a column key to its display label (header).
|
|
15
|
+
* If not provided, the raw column key will be used as a fallback.
|
|
16
|
+
*/
|
|
17
|
+
getHeaderLabel?: (columnKey: string) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Optional function to map a column key and raw group value to a display label.
|
|
20
|
+
* Useful to apply the column's formatter for group headers.
|
|
21
|
+
*/
|
|
22
|
+
getValueLabel?: (columnKey: string, rawValue: any) => string;
|
|
23
|
+
/**
|
|
24
|
+
* Optional custom renderer for actions on grouped rows.
|
|
25
|
+
*/
|
|
26
|
+
renderGroupActions?: KDGridProps["renderGroupActions"];
|
|
27
|
+
}
|
|
28
|
+
export declare const GroupHeader: import("react").MemoExoticComponent<({ row, isExpanded, onToggle, viewportWidth, selectable, rowHeight, getHeaderLabel, getValueLabel, renderGroupActions, }: GroupHeaderProps) => import("react/jsx-runtime").JSX.Element>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LicenseError
|
|
3
|
+
*
|
|
4
|
+
* Shown inside the grid body when an invalid or missing `licenseKey` is
|
|
5
|
+
* detected. Rendering it in the body (rather than replacing the entire
|
|
6
|
+
* component) keeps the column header visible so consumers can still see
|
|
7
|
+
* the grid structure and understand what data *should* be there.
|
|
8
|
+
*/
|
|
9
|
+
export declare const LicenseError: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
interface NoDataMessageProps {
|
|
3
|
+
hasFilters?: boolean;
|
|
4
|
+
hasData?: boolean;
|
|
5
|
+
/** Custom text message. Overridden by `renderer` if both are set. */
|
|
6
|
+
message?: string;
|
|
7
|
+
/** Fully custom empty-state renderer — takes precedence over `message`. */
|
|
8
|
+
renderer?: () => ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare const NoDataMessage: ({ hasFilters, hasData, message, renderer, }: NoDataMessageProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PaginationConfig } from "../types";
|
|
2
|
+
interface PaginationControlsProps {
|
|
3
|
+
paginationConfig: PaginationConfig;
|
|
4
|
+
currentPage: number;
|
|
5
|
+
isServerLoading: boolean;
|
|
6
|
+
selectedRowsCount: number;
|
|
7
|
+
totalDataLength: number;
|
|
8
|
+
filteredDataLength?: number;
|
|
9
|
+
paginationMode?: "client" | "server";
|
|
10
|
+
onPageChange: (page: number, pageSize: number) => void;
|
|
11
|
+
onPageSizeChange: (pageSize: number) => void;
|
|
12
|
+
showNoDataMessage?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare const PaginationControls: import("react").MemoExoticComponent<{
|
|
15
|
+
({ paginationConfig, currentPage, isServerLoading, selectedRowsCount, totalDataLength, filteredDataLength, paginationMode, onPageChange, onPageSizeChange, }: PaginationControlsProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
displayName: string;
|
|
17
|
+
}>;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type Placement } from "@floating-ui/react";
|
|
3
|
+
interface PopoverProps {
|
|
4
|
+
open: boolean;
|
|
5
|
+
anchorEl: HTMLElement | null;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
placement?: Placement;
|
|
8
|
+
offset?: number;
|
|
9
|
+
sameWidth?: boolean;
|
|
10
|
+
maxHeight?: number | string;
|
|
11
|
+
zIndex?: number;
|
|
12
|
+
className?: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
shouldIgnoreClose?: (target: Node) => boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const Popover: React.FC<PopoverProps>;
|
|
17
|
+
export default Popover;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { GridRow, ContextMenuItem } from "../types";
|
|
2
|
+
/** Ready-made starter items — ONLY for development / demos.
|
|
3
|
+
* All items are no-ops in dev environments (they log in DEV only).
|
|
4
|
+
* Do NOT rely on these in production; wire your own `contextMenuItems`. */
|
|
5
|
+
export declare const defaultContextMenuItems: ContextMenuItem[];
|
|
6
|
+
interface RowContextMenuProps {
|
|
7
|
+
row: GridRow;
|
|
8
|
+
position: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
};
|
|
12
|
+
isVisible: boolean;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
/** Custom menu items. If not provided the menu will not render. */
|
|
15
|
+
menuItems?: ContextMenuItem[];
|
|
16
|
+
}
|
|
17
|
+
export declare const RowContextMenu: ({ row, position, isVisible, onClose, menuItems, }: RowContextMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ReactNode, ChangeEvent } from "react";
|
|
2
|
+
import type { Density, BulkActionOption, SavedFilter, ExportFormat } from "../types";
|
|
3
|
+
interface ColumnVisibility {
|
|
4
|
+
[columnKey: string]: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface SearchToolbarProps {
|
|
7
|
+
globalFilter: string;
|
|
8
|
+
filteredDataLength: number;
|
|
9
|
+
totalDataLength: number;
|
|
10
|
+
paginationMode?: "client" | "server";
|
|
11
|
+
totalRows?: number;
|
|
12
|
+
selectedRowsCount?: number;
|
|
13
|
+
selectedRows?: Set<string | number>;
|
|
14
|
+
showExport?: boolean;
|
|
15
|
+
showRefresh?: boolean;
|
|
16
|
+
showColumnToggle?: boolean;
|
|
17
|
+
showBulkActions?: boolean;
|
|
18
|
+
showSavedFilters?: boolean;
|
|
19
|
+
columns?: Array<{
|
|
20
|
+
key: string;
|
|
21
|
+
header: string;
|
|
22
|
+
visible?: boolean;
|
|
23
|
+
filterOptions?: Array<{
|
|
24
|
+
label: string;
|
|
25
|
+
value: string | number;
|
|
26
|
+
}>;
|
|
27
|
+
filterType?: "text" | "select" | "multiselect";
|
|
28
|
+
filterable?: any;
|
|
29
|
+
}>;
|
|
30
|
+
columnVisibility?: ColumnVisibility;
|
|
31
|
+
columnFilters?: Record<string, any>;
|
|
32
|
+
savedFilters?: SavedFilter[];
|
|
33
|
+
bulkActions?: BulkActionOption[];
|
|
34
|
+
loading?: boolean;
|
|
35
|
+
exportOptions?: {
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
formats?: ExportFormat[];
|
|
38
|
+
filename?: string;
|
|
39
|
+
onExport?: (format: ExportFormat, exportSelected: boolean) => void;
|
|
40
|
+
};
|
|
41
|
+
onGlobalFilterChange: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
42
|
+
onClearFilters?: () => void;
|
|
43
|
+
onRefresh?: () => void;
|
|
44
|
+
onColumnVisibilityChange?: (columnKey: string, visible: boolean) => void;
|
|
45
|
+
onColumnFilter?: (columnKey: string, filter: any) => void;
|
|
46
|
+
onSaveFilter?: (filter: Omit<SavedFilter, "id">) => void;
|
|
47
|
+
onLoadFilter?: (filter: SavedFilter) => void;
|
|
48
|
+
onDeleteFilter?: (filterId: string) => void;
|
|
49
|
+
onRowSelect?: (selectedRows: number[]) => void;
|
|
50
|
+
onToggleFilters?: (show: boolean) => void;
|
|
51
|
+
onResetColumns?: () => void;
|
|
52
|
+
columnOrder?: string[];
|
|
53
|
+
onColumnOrderChange?: (order: string[]) => void;
|
|
54
|
+
pinnedColumns?: Set<string>;
|
|
55
|
+
onScrollToColumn?: (columnKey: string) => void;
|
|
56
|
+
density?: Density;
|
|
57
|
+
onDensityChange?: (density: Density) => void;
|
|
58
|
+
showDensityControl?: boolean;
|
|
59
|
+
customLeftContent?: ReactNode;
|
|
60
|
+
customRightContent?: ReactNode;
|
|
61
|
+
}
|
|
62
|
+
export declare const SearchToolbar: import("react").MemoExoticComponent<{
|
|
63
|
+
({ globalFilter, filteredDataLength, totalDataLength, selectedRowsCount, selectedRows, showExport, showColumnToggle, showBulkActions, columns, columnVisibility, columnFilters, bulkActions, exportOptions, onGlobalFilterChange, onClearFilters, onColumnVisibilityChange, onColumnFilter, onResetColumns, columnOrder, onColumnOrderChange, pinnedColumns, onScrollToColumn, density, onDensityChange, showDensityControl, customLeftContent, customRightContent, }: SearchToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
64
|
+
displayName: string;
|
|
65
|
+
}>;
|
|
66
|
+
export {};
|