jattac.libs.web.responsive-table 0.12.0 → 0.13.0
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 +26 -6
- package/dist/Hooks/useTablePlugins.d.ts +0 -8
- package/dist/Plugins/IResponsiveTablePlugin.d.ts +0 -6
- package/dist/UI/DetailRow.d.ts +1 -2
- package/dist/UI/ResponsiveTable.d.ts +0 -11
- package/dist/UI/TableBodyRow.d.ts +6 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.es.js +156 -327
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +155 -327
- package/dist/index.js.map +1 -1
- package/docs/api.md +13 -17
- package/docs/development.md +1 -2
- package/docs/examples.md +57 -1
- package/docs/expand-collapse.md +630 -0
- package/docs/features.md +6 -0
- package/docs/recommendations.md +376 -0
- package/package.json +1 -1
- package/dist/Plugins/InfiniteScrollPlugin.d.ts +0 -13
- package/dist/UI/InfiniteTable.d.ts +0 -46
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# Recommendations and Pitfalls
|
|
2
|
+
## Best Practices, Anti-Patterns, and Module Compatibility
|
|
3
|
+
|
|
4
|
+
This document covers three topics: the known ESM/CJS module hazard with a peer dependency, general best practices for optimal usage, and anti-patterns to avoid.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
[← Previous: Handling Interactive Elements](./handling-interactive-elements.md) | [Return to README →](../README.md)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Table of Contents
|
|
13
|
+
|
|
14
|
+
- [ESM/CJS Module Compatibility](#esmcjs-module-compatibility)
|
|
15
|
+
- [Root Cause](#root-cause)
|
|
16
|
+
- [Symptoms](#symptoms)
|
|
17
|
+
- [Consumer Workarounds](#consumer-workarounds)
|
|
18
|
+
- [Planned Fix](#planned-fix)
|
|
19
|
+
- [Recommendations](#recommendations)
|
|
20
|
+
- [Row Identity and State Stability](#1-row-identity-and-state-stability)
|
|
21
|
+
- [Interactive Elements and Event Isolation](#2-interactive-elements-and-event-isolation)
|
|
22
|
+
- [Expandable Rows](#3-expandable-rows)
|
|
23
|
+
- [Theming and Visual Customization](#4-theming-and-visual-customization)
|
|
24
|
+
- [Performance and Rendering](#5-performance-and-rendering)
|
|
25
|
+
- [Data Fetching and Pagination](#6-data-fetching-and-pagination)
|
|
26
|
+
- [Column Definitions](#7-column-definitions)
|
|
27
|
+
- [Pitfalls](#pitfalls)
|
|
28
|
+
- [Chevron Transform Override](#1-chevron-transform-override)
|
|
29
|
+
- [rowIndex as a Stable Identifier](#2-rowindex-as-a-stable-identifier)
|
|
30
|
+
- [Missing rowIdKey on Sortable Tables](#3-missing-rowidkey-on-sortable-tables)
|
|
31
|
+
- [Missing data-rt-ignore-row-click](#4-missing-data-rt-ignore-row-click)
|
|
32
|
+
- [Non-null expandRowRenderer for Empty Detail](#5-non-null-expandrowrenderer-for-empty-detail)
|
|
33
|
+
- [Heavy Computation in expandRowRenderer](#6-heavy-computation-in-expandrowrenderer)
|
|
34
|
+
- [Inline Props Without useMemo](#7-inline-props-without-usememo)
|
|
35
|
+
- [No Error Handling with dataSource](#8-no-error-handling-with-datasource)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## ESM/CJS Module Compatibility
|
|
40
|
+
|
|
41
|
+
### Root Cause
|
|
42
|
+
|
|
43
|
+
The peer dependency `jattac.libs.web.zest-textbox` is published with `"type": "module"` in its `package.json`. This tells Node.js to treat all `.js` files in the package as ES modules. However, the file referenced by the `"require"` export condition — `dist/index.js` — is CommonJS (uses `require()` calls, `module.exports`).
|
|
44
|
+
|
|
45
|
+
The conflict:
|
|
46
|
+
1. Consumer calls `require('jattac.libs.web.zest-textbox')`
|
|
47
|
+
2. Node.js resolves via `"exports": { "require": "./dist/index.js" }`
|
|
48
|
+
3. Root `package.json` has `"type": "module"` → Node.js parses `dist/index.js` as ESM
|
|
49
|
+
4. ESM does not support `require()` → error
|
|
50
|
+
|
|
51
|
+
### Symptoms
|
|
52
|
+
|
|
53
|
+
- **Next.js Pages Router:** `ERR_REQUIRE_ESM` at build or server start
|
|
54
|
+
- **Jest tests:** `Jest failed to parse a file` — the test runner cannot `require()` the ESM-marked file
|
|
55
|
+
- **Webpack 4 / Create React App:** Module parse failure — bundler cannot handle the unexpected ESM/CJS mismatch
|
|
56
|
+
- **Next.js App Router:** Usually unaffected because `import` resolves to the separate `.esm.js` bundle which is genuine ESM
|
|
57
|
+
|
|
58
|
+
### Consumer Workarounds
|
|
59
|
+
|
|
60
|
+
#### Next.js
|
|
61
|
+
|
|
62
|
+
**App Router (13+):** If you still see the error, add the package to `transpilePackages`:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
// next.config.js
|
|
66
|
+
module.exports = {
|
|
67
|
+
transpilePackages: ['jattac.libs.web.zest-textbox'],
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Pages Router:** Force webpack to use the ESM entry:
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
// next.config.js
|
|
75
|
+
const path = require('path');
|
|
76
|
+
|
|
77
|
+
module.exports = {
|
|
78
|
+
webpack: (config) => {
|
|
79
|
+
config.resolve.alias['jattac.libs.web.zest-textbox'] =
|
|
80
|
+
path.resolve(__dirname, 'node_modules/jattac.libs.web.zest-textbox/dist/index.esm.js');
|
|
81
|
+
return config;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Jest
|
|
87
|
+
|
|
88
|
+
Add the package to `transformIgnorePatterns`:
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
// jest.config.js
|
|
92
|
+
module.exports = {
|
|
93
|
+
transformIgnorePatterns: [
|
|
94
|
+
'/node_modules/(?!(jattac.libs.web.zest-textbox)/)',
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### Vite
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
// vite.config.js
|
|
103
|
+
export default {
|
|
104
|
+
optimizeDeps: {
|
|
105
|
+
include: ['jattac.libs.web.zest-textbox'],
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Planned Fix
|
|
111
|
+
|
|
112
|
+
The next release of `jattac.libs.web.zest-textbox` will remove the `"type": "module"` field. The `"exports"` map already correctly routes `require` → CJS (`dist/index.js`) and `import` → ESM (`dist/index.esm.js`), so the field is redundant and harmful.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Recommendations
|
|
117
|
+
|
|
118
|
+
### 1. Row Identity and State Stability
|
|
119
|
+
|
|
120
|
+
**Always provide `selectionProps.rowIdKey`** when using expandable rows or selection on a table that supports sorting, filtering, or pagination. The key links a row's visual identity to a stable data field so that expand and selection states survive re-order operations.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
// Without rowIdKey: re-sort resets all expanded/selected rows
|
|
124
|
+
// With rowIdKey: "Order #1042" stays expanded wherever it moves
|
|
125
|
+
<ResponsiveTable
|
|
126
|
+
data={orders}
|
|
127
|
+
columnDefinitions={columns}
|
|
128
|
+
selectionProps={{
|
|
129
|
+
rowIdKey: 'id',
|
|
130
|
+
onSelectionChange: () => {},
|
|
131
|
+
}}
|
|
132
|
+
expandRowRenderer={(order) => <OrderLineItems orderId={order.id} />}
|
|
133
|
+
/>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Even if you do not need row selection, provide `selectionProps` solely to anchor expand state. The no-op `onSelectionChange` is harmless.
|
|
137
|
+
|
|
138
|
+
### 2. Interactive Elements and Event Isolation
|
|
139
|
+
|
|
140
|
+
When using `onRowClick`, always add `data-rt-ignore-row-click` to buttons, links, inputs, and any other interactive element inside a cell. The table uses an explicit opt-in contract rather than automatic detection because many UI libraries render with custom elements that are not standard `<button>` or `<a>` tags.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
const columns = [
|
|
144
|
+
{
|
|
145
|
+
displayLabel: 'Actions',
|
|
146
|
+
cellRenderer: (row) => (
|
|
147
|
+
<button data-rt-ignore-row-click onClick={() => deleteRow(row.id)}>
|
|
148
|
+
Delete
|
|
149
|
+
</button>
|
|
150
|
+
),
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The same attribute works on containers — any child click is ignored:
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<div data-rt-ignore-row-click>
|
|
159
|
+
<MyCustomToggle value={row.flag} onChange={(v) => setFlag(row.id, v)} />
|
|
160
|
+
</div>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
See the [Handling Interactive Elements](./handling-interactive-elements.md) guide for detailed scenarios.
|
|
164
|
+
|
|
165
|
+
### 3. Expandable Rows
|
|
166
|
+
|
|
167
|
+
- **Return `null` for rows with no detail content.** The toggle is completely absent — not hidden — for those rows. A visible chevron that opens an empty panel confuses users.
|
|
168
|
+
- **Keep `expandRowRenderer` lightweight.** It is called for every visible row on every render pass. Expensive work (data fetching, heavy computation) should live inside the detail component itself (which is lazy-mounted).
|
|
169
|
+
- **Use `expandChevronClassName` to customize the chevron.** Override `color`, `font-size`, etc. Never override `transform` or `transition` — these drive the collapse animation.
|
|
170
|
+
- **The chevron is keyboard-accessible.** It has `role="button"`, `tabIndex={0}`, and `aria-expanded`. Enter/Space toggle the panel — no additional configuration needed.
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
<ResponsiveTable
|
|
174
|
+
data={orders}
|
|
175
|
+
columnDefinitions={columns}
|
|
176
|
+
expandRowRenderer={(order) =>
|
|
177
|
+
order.lineItems.length > 0
|
|
178
|
+
? <OrderLineItems order={order} />
|
|
179
|
+
: null
|
|
180
|
+
}
|
|
181
|
+
expandChevronClassName="my-chevron"
|
|
182
|
+
/>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 4. Theming and Visual Customization
|
|
186
|
+
|
|
187
|
+
Override `--primary-color` at the `:root` level rather than targeting individual elements. The chevron, the expanded left-border indicator, selection highlights, focus rings, and the spinner all derive from this single variable.
|
|
188
|
+
|
|
189
|
+
```css
|
|
190
|
+
:root {
|
|
191
|
+
--primary-color: #7c3aed; /* violet accent */
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
For per-component overrides, scope the variable to the table's container:
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
.my-page .responsiveTable {
|
|
199
|
+
--primary-color: #059669; /* emerald green */
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 5. Performance and Rendering
|
|
204
|
+
|
|
205
|
+
- **Memoize props passed to `ResponsiveTable`.** Arrays and objects created inline (`columnDefinitions={[...]}`, `animationProps={{...}}`) create new references on every render, triggering unnecessary downstream work.
|
|
206
|
+
- **Use `useTableContext` sparingly.** Custom components rendered inside the table should `useMemo` their outputs when deriving data from context.
|
|
207
|
+
- **Avoid large `data` arrays without pagination.** Client-side rendering of thousands of rows will degrade performance. Use `dataSource` for server-side pagination or implement windowing.
|
|
208
|
+
- **Keep per-row callbacks stable.** Functions passed inside `cellRenderer` that capture state should use `useCallback` to avoid re-creating React elements for every row.
|
|
209
|
+
|
|
210
|
+
### 6. Data Fetching and Pagination
|
|
211
|
+
|
|
212
|
+
- **Prefer `dataSource` over manual pagination.** The table handles page tracking, `hasMore` detection, loading states, and error recovery automatically.
|
|
213
|
+
- **Return `{ items, totalCount }`** from your `dataSource` function for accurate `hasMore` detection. A plain array is also supported but `hasMore` is inferred from `pageSize`.
|
|
214
|
+
- **Always provide `selectionProps.rowIdKey` with `dataSource`.** Without it, expand and selection states reset every time a new page loads because indices no longer match.
|
|
215
|
+
- **Handle errors.** Provide `onDataSourceError` to show user-facing error messages. The table has a built-in retry button when the initial load fails and no data is available.
|
|
216
|
+
|
|
217
|
+
### 7. Column Definitions
|
|
218
|
+
|
|
219
|
+
- **Use the function form** `(row) => IResponsiveTableColumnDefinition<TData>` when columns need row-dependent options (visibility, class names, or rendering logic that differs per row).
|
|
220
|
+
- **Use `getSortableValue` for sorting.** This tells the built-in sort plugin how to compare cells. Without it, sorting falls back to `displayLabel` comparison which is rarely correct.
|
|
221
|
+
- **Use `getFilterableValue` for client-side filtering.** Without it, the filter plugin skips the column entirely.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Pitfalls
|
|
226
|
+
|
|
227
|
+
### 1. Chevron Transform Override
|
|
228
|
+
|
|
229
|
+
**Problem:** Applying `transform` or `transition` in `expandChevronClassName`. The collapse animation rotates the chevron from `-90deg` to `0deg` using these exact properties. Overriding them breaks the rotation.
|
|
230
|
+
|
|
231
|
+
**Fix:** Override only cosmetic properties — `color`, `font-size`, `opacity`, `margin`, etc.:
|
|
232
|
+
|
|
233
|
+
```css
|
|
234
|
+
/* Correct */
|
|
235
|
+
.myChevron {
|
|
236
|
+
color: var(--brand-color);
|
|
237
|
+
font-size: 1.5rem;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Wrong — breaks rotation */
|
|
241
|
+
.myChevron {
|
|
242
|
+
transform: scale(1.5);
|
|
243
|
+
transition: all 0.5s;
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 2. rowIndex as a Stable Identifier
|
|
248
|
+
|
|
249
|
+
**Problem:** Using `rowIndex` from `expandRowRenderer` or `cellRenderer` as a database key, cache key, or state identifier. `rowIndex` is the display-order position after sort and filter — it changes when the user re-orders or searches.
|
|
250
|
+
|
|
251
|
+
**Fix:** Use a stable field from the data object (`row.id`, `row.uuid`, etc.) for any cross-render correlation:
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
// Wrong — breaks after re-sort
|
|
255
|
+
expandRowRenderer={(row, rowIndex) => (
|
|
256
|
+
<DetailPanel row={row} cacheKey={rowIndex} />
|
|
257
|
+
)}
|
|
258
|
+
|
|
259
|
+
// Correct
|
|
260
|
+
expandRowRenderer={(row) => (
|
|
261
|
+
<DetailPanel row={row} cacheKey={row.id} />
|
|
262
|
+
)}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### 3. Missing rowIdKey on Sortable Tables
|
|
266
|
+
|
|
267
|
+
**Problem:** Omitting `selectionProps.rowIdKey` on a table with sorting, filtering, or `dataSource`. Expand state and selection state are tracked by array index. When the user re-sorts, indices shift and all open panels close.
|
|
268
|
+
|
|
269
|
+
**Fix:** Always provide `selectionProps` with a `rowIdKey` pointing to a stable unique field. If selection is not needed, use a no-op handler:
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
<ResponsiveTable
|
|
273
|
+
data={rows}
|
|
274
|
+
columnDefinitions={columns}
|
|
275
|
+
selectionProps={{
|
|
276
|
+
rowIdKey: 'id',
|
|
277
|
+
onSelectionChange: () => {}, // expand stability only
|
|
278
|
+
}}
|
|
279
|
+
expandRowRenderer={(row) => <Detail row={row} />}
|
|
280
|
+
/>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 4. Missing data-rt-ignore-row-click
|
|
284
|
+
|
|
285
|
+
**Problem:** Clicking a button or link inside a data row also fires `onRowClick`. This causes navigation, modals, or other side effects to fire unintentionally when the user tries to interact with a cell-level control.
|
|
286
|
+
|
|
287
|
+
**Fix:** Add `data-rt-ignore-row-click` to every interactive element inside a cell row when `onRowClick` is active:
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
<button data-rt-ignore-row-click onClick={...}>Edit</button>
|
|
291
|
+
<a data-rt-ignore-row-click href={`/detail/${row.id}`}>View</a>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### 5. Non-null expandRowRenderer for Empty Detail
|
|
295
|
+
|
|
296
|
+
**Problem:** The renderer always returns a `ReactNode` even when there is no meaningful detail content. Every row gets a toggle chevron, including rows where the panel would be empty or useless.
|
|
297
|
+
|
|
298
|
+
**Fix:** Return `null` for rows that have no detail content:
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
expandRowRenderer={(order) =>
|
|
302
|
+
order.lineItems.length > 0
|
|
303
|
+
? <LineItems items={order.lineItems} />
|
|
304
|
+
: null // ← no toggle for orders without line items
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### 6. Heavy Computation in expandRowRenderer
|
|
309
|
+
|
|
310
|
+
**Problem:** Performing expensive operations inside `expandRowRenderer` — API calls, heavy transforms, large array traversals. The renderer runs for every visible row on every render pass (sort, filter, page change, state update).
|
|
311
|
+
|
|
312
|
+
**Fix:** Move expensive work into the detail component, which only mounts on first expand:
|
|
313
|
+
|
|
314
|
+
```tsx
|
|
315
|
+
// Wrong — fetch runs on every render for every row
|
|
316
|
+
expandRowRenderer={(row) => {
|
|
317
|
+
const data = useExpensiveQuery(row.id); // hooks in renderer is illegal anyway
|
|
318
|
+
return <Detail data={data} />;
|
|
319
|
+
}}
|
|
320
|
+
|
|
321
|
+
// Correct — fetch runs once, on first expand
|
|
322
|
+
expandRowRenderer={(row) => <DetailPage rowId={row.id} />}
|
|
323
|
+
|
|
324
|
+
function DetailPage({ rowId }: { rowId: string }) {
|
|
325
|
+
const { data } = useExpensiveQuery(rowId); // lazy-mounted
|
|
326
|
+
return <Detail data={data} />;
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### 7. Inline Props Without useMemo
|
|
331
|
+
|
|
332
|
+
**Problem:** Passing arrays, objects, or callbacks as inline literals in JSX:
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
<ResponsiveTable
|
|
336
|
+
data={rows}
|
|
337
|
+
columnDefinitions={columns} // if this is a new array each render...
|
|
338
|
+
animationProps={{ animateOnLoad: true }} // ...or this is a new object
|
|
339
|
+
/>
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Each render creates new references. The table's comparison logic detects changes and triggers unnecessary re-computation and re-renders.
|
|
343
|
+
|
|
344
|
+
**Fix:** Define stable references:
|
|
345
|
+
|
|
346
|
+
```tsx
|
|
347
|
+
const columns = useMemo(() => [...], []);
|
|
348
|
+
const animProps = useMemo(() => ({ animateOnLoad: true }), []);
|
|
349
|
+
|
|
350
|
+
<ResponsiveTable
|
|
351
|
+
data={rows}
|
|
352
|
+
columnDefinitions={columns}
|
|
353
|
+
animationProps={animProps}
|
|
354
|
+
/>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### 8. No Error Handling with dataSource
|
|
358
|
+
|
|
359
|
+
**Problem:** Using `dataSource` without listening for errors. If the fetch fails and there is already cached data, the table continues showing stale data silently. If the initial fetch fails with no cached data, the user sees an empty skeleton indefinitely.
|
|
360
|
+
|
|
361
|
+
**Fix:** Provide `onDataSourceError` for logging or toast notifications, and use the built-in retry button for initial load failures:
|
|
362
|
+
|
|
363
|
+
```tsx
|
|
364
|
+
<ResponsiveTable
|
|
365
|
+
dataSource={fetchPage}
|
|
366
|
+
columnDefinitions={columns}
|
|
367
|
+
onDataSourceError={(error) => {
|
|
368
|
+
console.error('Failed to fetch page:', error);
|
|
369
|
+
toast.error('Could not load data. Please try again.');
|
|
370
|
+
}}
|
|
371
|
+
/>
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
**Previous:** [Handling Interactive Elements](./handling-interactive-elements.md) | **Next:** [Return to README](../README.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jattac.libs.web.responsive-table",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "A fully responsive, customizable, and lightweight React table component with a modern, mobile-first design and a powerful plugin system.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Nyingi Maina",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { IResponsiveTablePlugin, IPluginAPI } from './IResponsiveTablePlugin';
|
|
3
|
-
export declare class InfiniteScrollPlugin<TData> implements IResponsiveTablePlugin<TData> {
|
|
4
|
-
id: string;
|
|
5
|
-
private api;
|
|
6
|
-
private isLoadingMore;
|
|
7
|
-
constructor();
|
|
8
|
-
onPluginInit: (api: IPluginAPI<TData>) => void;
|
|
9
|
-
private attachScrollListener;
|
|
10
|
-
private handleScroll;
|
|
11
|
-
processData: (data: TData[]) => TData[];
|
|
12
|
-
renderFooter: () => string | number | true | Iterable<React.ReactNode> | React.JSX.Element | null;
|
|
13
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import React, { ReactNode } from 'react';
|
|
2
|
-
import { SortDirection } from '../Data/IResponsiveTableColumnDefinition';
|
|
3
|
-
import IFooterRowDefinition from '../Data/IFooterRowDefinition';
|
|
4
|
-
import { IResponsiveTablePlugin } from '../Plugins/IResponsiveTablePlugin';
|
|
5
|
-
import { ColumnDefinition } from '../Context/TableContext';
|
|
6
|
-
interface IInfiniteScrollProps<TData> {
|
|
7
|
-
onLoadMore: (currentData: TData[]) => Promise<TData[] | null>;
|
|
8
|
-
hasMore?: boolean;
|
|
9
|
-
loadingMoreComponent?: ReactNode;
|
|
10
|
-
noMoreDataComponent?: ReactNode;
|
|
11
|
-
}
|
|
12
|
-
interface ISortProps {
|
|
13
|
-
initialSortColumn?: string;
|
|
14
|
-
initialSortDirection?: SortDirection;
|
|
15
|
-
}
|
|
16
|
-
interface IProps<TData> {
|
|
17
|
-
columnDefinitions: ColumnDefinition<TData>[];
|
|
18
|
-
data: TData[];
|
|
19
|
-
noDataComponent?: ReactNode;
|
|
20
|
-
maxHeight?: string;
|
|
21
|
-
onRowClick?: (item: TData) => void;
|
|
22
|
-
footerRows?: IFooterRowDefinition[];
|
|
23
|
-
mobileBreakpoint?: number;
|
|
24
|
-
plugins?: IResponsiveTablePlugin<TData>[];
|
|
25
|
-
enablePageLevelStickyHeader?: boolean;
|
|
26
|
-
infiniteScrollProps?: IInfiniteScrollProps<TData>;
|
|
27
|
-
filterProps?: {
|
|
28
|
-
showFilter?: boolean;
|
|
29
|
-
filterPlaceholder?: string;
|
|
30
|
-
className?: string;
|
|
31
|
-
};
|
|
32
|
-
selectionProps?: {
|
|
33
|
-
onSelectionChange: (selectedItems: TData[]) => void;
|
|
34
|
-
rowIdKey: keyof TData;
|
|
35
|
-
mode?: 'single' | 'multiple';
|
|
36
|
-
selectedItems?: TData[];
|
|
37
|
-
selectedRowClassName?: string;
|
|
38
|
-
};
|
|
39
|
-
animationProps?: {
|
|
40
|
-
isLoading?: boolean;
|
|
41
|
-
animateOnLoad?: boolean;
|
|
42
|
-
};
|
|
43
|
-
sortProps?: ISortProps;
|
|
44
|
-
}
|
|
45
|
-
declare function InfiniteTable<TData>(props: IProps<TData>): React.JSX.Element;
|
|
46
|
-
export default InfiniteTable;
|