bolt-table 0.1.1 → 0.1.3
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 +37 -106
- package/dist/index.d.mts +8 -6
- package/dist/index.d.ts +8 -6
- package/dist/index.js +765 -725
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +766 -737
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# bolt-table
|
|
2
2
|
|
|
3
|
-
A high-performance,
|
|
3
|
+
A high-performance, zero-dependency\* React table component. Only the rows visible in the viewport are ever in the DOM — making it fast for datasets of any size uisng [TanStack Virtual](https://tanstack.com/virtual).
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/bolt-table)
|
|
6
6
|
[](./LICENSE)
|
|
@@ -10,7 +10,7 @@ A high-performance, fully-featured React table component built on [TanStack Virt
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
12
|
- **Row virtualization** — only visible rows are rendered, powered by TanStack Virtual
|
|
13
|
-
- **Drag to reorder columns** —
|
|
13
|
+
- **Drag to reorder columns** — custom zero-dependency drag-and-drop (no @dnd-kit needed)
|
|
14
14
|
- **Column pinning** — pin columns to the left or right edge via right-click
|
|
15
15
|
- **Column resizing** — drag the right edge of any header to resize
|
|
16
16
|
- **Column hiding** — hide/show columns via the right-click context menu
|
|
@@ -24,23 +24,18 @@ A high-performance, fully-featured React table component built on [TanStack Virt
|
|
|
24
24
|
- **Empty state** — custom renderer or default "No data" message
|
|
25
25
|
- **Auto height** — table shrinks/grows to fit rows, capped at 10 rows by default
|
|
26
26
|
- **Right-click context menu** — sort, filter, pin, hide, plus custom items
|
|
27
|
-
- **
|
|
27
|
+
- **Theme-agnostic** — works in light and dark mode out of the box, no CSS variables needed
|
|
28
|
+
- **Custom icons** — override any built-in icon via the `icons` prop
|
|
28
29
|
|
|
29
30
|
---
|
|
30
31
|
|
|
31
32
|
## Installation
|
|
32
33
|
|
|
33
34
|
```bash
|
|
34
|
-
npm install bolt-table
|
|
35
|
+
npm install bolt-table @tanstack/react-virtual
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
These must be installed separately in your project:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
npm install @tanstack/react-virtual @dnd-kit/core @dnd-kit/sortable lucide-react
|
|
43
|
-
```
|
|
38
|
+
That's it. No other peer dependencies.
|
|
44
39
|
|
|
45
40
|
---
|
|
46
41
|
|
|
@@ -83,7 +78,7 @@ export default function App() {
|
|
|
83
78
|
|
|
84
79
|
## Next.js (App Router)
|
|
85
80
|
|
|
86
|
-
BoltTable uses browser APIs and must be wrapped in a client boundary
|
|
81
|
+
BoltTable uses browser APIs and must be wrapped in a client boundary:
|
|
87
82
|
|
|
88
83
|
```tsx
|
|
89
84
|
'use client';
|
|
@@ -94,9 +89,27 @@ import { BoltTable } from 'bolt-table';
|
|
|
94
89
|
|
|
95
90
|
## Styling
|
|
96
91
|
|
|
97
|
-
BoltTable uses
|
|
92
|
+
BoltTable uses **inline CSS styles** for all defaults — no Tailwind, no CSS variables, no external stylesheets required. It works out of the box in any React project, light or dark mode.
|
|
93
|
+
|
|
94
|
+
You can customize everything via the `styles` and `classNames` props. If your project uses Tailwind, you can pass Tailwind classes through `classNames` and they'll be applied on top of the inline defaults.
|
|
95
|
+
|
|
96
|
+
### Custom icons
|
|
97
|
+
|
|
98
|
+
All built-in icons are inline SVGs. Override any icon via the `icons` prop:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import type { BoltTableIcons } from 'bolt-table';
|
|
102
|
+
|
|
103
|
+
<BoltTable
|
|
104
|
+
icons={{
|
|
105
|
+
gripVertical: <MyGripIcon size={12} />,
|
|
106
|
+
sortAsc: <MySortUpIcon size={12} />,
|
|
107
|
+
chevronsLeft: <MyFirstPageIcon size={12} />,
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
```
|
|
98
111
|
|
|
99
|
-
|
|
112
|
+
Available icon keys: `gripVertical`, `sortAsc`, `sortDesc`, `filter`, `filterClear`, `pin`, `pinOff`, `eyeOff`, `chevronDown`, `chevronLeft`, `chevronRight`, `chevronsLeft`, `chevronsRight`.
|
|
100
113
|
|
|
101
114
|
---
|
|
102
115
|
|
|
@@ -116,7 +129,8 @@ Make sure your project has Tailwind configured and the Shadcn CSS variables defi
|
|
|
116
129
|
| `className` | `string` | `''` | Class name for the outer wrapper |
|
|
117
130
|
| `classNames` | `ClassNamesTypes` | `{}` | Granular class overrides per table region |
|
|
118
131
|
| `styles` | `StylesTypes` | `{}` | Inline style overrides per table region |
|
|
119
|
-
| `
|
|
132
|
+
| `icons` | `BoltTableIcons` | — | Custom icon overrides for built-in SVG icons |
|
|
133
|
+
| `gripIcon` | `ReactNode` | — | Custom drag grip icon (deprecated, use `icons.gripVertical`) |
|
|
120
134
|
| `hideGripIcon` | `boolean` | `false` | Hide the drag grip icon from all headers |
|
|
121
135
|
| `pagination` | `PaginationType \| false` | — | Pagination config, or `false` to disable |
|
|
122
136
|
| `onPaginationChange` | `(page, pageSize) => void` | — | Called when page or page size changes |
|
|
@@ -172,7 +186,6 @@ const columns: ColumnType<User>[] = [
|
|
|
172
186
|
dataIndex: 'name',
|
|
173
187
|
title: 'Name',
|
|
174
188
|
sortable: true,
|
|
175
|
-
// Optional custom comparator:
|
|
176
189
|
sorter: (a, b) => a.name.localeCompare(b.name),
|
|
177
190
|
},
|
|
178
191
|
{
|
|
@@ -180,7 +193,6 @@ const columns: ColumnType<User>[] = [
|
|
|
180
193
|
dataIndex: 'age',
|
|
181
194
|
title: 'Age',
|
|
182
195
|
sortable: true,
|
|
183
|
-
// Default numeric comparator used when sorter is omitted
|
|
184
196
|
},
|
|
185
197
|
];
|
|
186
198
|
|
|
@@ -217,7 +229,6 @@ const columns: ColumnType<User>[] = [
|
|
|
217
229
|
dataIndex: 'status',
|
|
218
230
|
title: 'Status',
|
|
219
231
|
filterable: true,
|
|
220
|
-
// Exact match instead of default substring:
|
|
221
232
|
filterFn: (value, record) => record.status === value,
|
|
222
233
|
},
|
|
223
234
|
];
|
|
@@ -245,11 +256,9 @@ const columns: ColumnType<User>[] = [
|
|
|
245
256
|
```tsx
|
|
246
257
|
<BoltTable
|
|
247
258
|
columns={columns}
|
|
248
|
-
data={allUsers}
|
|
259
|
+
data={allUsers}
|
|
249
260
|
pagination={{ pageSize: 20 }}
|
|
250
|
-
onPaginationChange={(page, size) =>
|
|
251
|
-
setPage(page);
|
|
252
|
-
}}
|
|
261
|
+
onPaginationChange={(page, size) => setPage(page)}
|
|
253
262
|
/>
|
|
254
263
|
```
|
|
255
264
|
|
|
@@ -258,7 +267,7 @@ const columns: ColumnType<User>[] = [
|
|
|
258
267
|
```tsx
|
|
259
268
|
<BoltTable
|
|
260
269
|
columns={columns}
|
|
261
|
-
data={currentPageData}
|
|
270
|
+
data={currentPageData}
|
|
262
271
|
pagination={{
|
|
263
272
|
current: page,
|
|
264
273
|
pageSize: 20,
|
|
@@ -287,10 +296,9 @@ const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
|
|
287
296
|
data={data}
|
|
288
297
|
rowKey="id"
|
|
289
298
|
rowSelection={{
|
|
290
|
-
type: 'checkbox',
|
|
299
|
+
type: 'checkbox',
|
|
291
300
|
selectedRowKeys,
|
|
292
301
|
onChange: (keys, rows) => setSelectedRowKeys(keys),
|
|
293
|
-
// Disable selection for specific rows:
|
|
294
302
|
getCheckboxProps: (record) => ({
|
|
295
303
|
disabled: record.status === 'locked',
|
|
296
304
|
}),
|
|
@@ -315,12 +323,9 @@ const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
|
|
315
323
|
<pre>{JSON.stringify(record.details, null, 2)}</pre>
|
|
316
324
|
</div>
|
|
317
325
|
),
|
|
318
|
-
// Optional: control expanded state yourself
|
|
319
|
-
// expandedRowKeys={expandedKeys}
|
|
320
|
-
// onExpandedRowsChange={(keys) => setExpandedKeys(keys)}
|
|
321
326
|
}}
|
|
322
|
-
expandedRowHeight={150}
|
|
323
|
-
maxExpandedRowHeight={400}
|
|
327
|
+
expandedRowHeight={150}
|
|
328
|
+
maxExpandedRowHeight={400}
|
|
324
329
|
/>
|
|
325
330
|
```
|
|
326
331
|
|
|
@@ -353,8 +358,6 @@ const loadMore = async () => {
|
|
|
353
358
|
|
|
354
359
|
### Column pinning
|
|
355
360
|
|
|
356
|
-
Pinning via column definition:
|
|
357
|
-
|
|
358
361
|
```tsx
|
|
359
362
|
const columns: ColumnType<User>[] = [
|
|
360
363
|
{ key: 'name', dataIndex: 'name', title: 'Name', pinned: 'left', width: 200 },
|
|
@@ -367,58 +370,6 @@ Users can also pin/unpin columns at runtime via the right-click context menu.
|
|
|
367
370
|
|
|
368
371
|
---
|
|
369
372
|
|
|
370
|
-
### Custom cell rendering
|
|
371
|
-
|
|
372
|
-
```tsx
|
|
373
|
-
const columns: ColumnType<User>[] = [
|
|
374
|
-
{
|
|
375
|
-
key: 'status',
|
|
376
|
-
dataIndex: 'status',
|
|
377
|
-
title: 'Status',
|
|
378
|
-
width: 120,
|
|
379
|
-
render: (value, record) => (
|
|
380
|
-
<span
|
|
381
|
-
style={{
|
|
382
|
-
padding: '2px 8px',
|
|
383
|
-
borderRadius: 4,
|
|
384
|
-
fontSize: 12,
|
|
385
|
-
backgroundColor: record.status === 'active' ? '#d1fae5' : '#fee2e2',
|
|
386
|
-
color: record.status === 'active' ? '#065f46' : '#991b1b',
|
|
387
|
-
}}
|
|
388
|
-
>
|
|
389
|
-
{String(value)}
|
|
390
|
-
</span>
|
|
391
|
-
),
|
|
392
|
-
},
|
|
393
|
-
];
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
### Custom context menu items
|
|
399
|
-
|
|
400
|
-
```tsx
|
|
401
|
-
<BoltTable
|
|
402
|
-
columns={columns}
|
|
403
|
-
data={data}
|
|
404
|
-
columnContextMenuItems={[
|
|
405
|
-
{
|
|
406
|
-
key: 'copy',
|
|
407
|
-
label: 'Copy column data',
|
|
408
|
-
icon: <CopyIcon className="h-3 w-3" />,
|
|
409
|
-
onClick: (columnKey) => copyColumnToClipboard(columnKey),
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
key: 'reset-width',
|
|
413
|
-
label: 'Reset width',
|
|
414
|
-
onClick: (columnKey) => resetColumnWidth(columnKey),
|
|
415
|
-
},
|
|
416
|
-
]}
|
|
417
|
-
/>
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
---
|
|
421
|
-
|
|
422
373
|
### Styling overrides
|
|
423
374
|
|
|
424
375
|
```tsx
|
|
@@ -443,27 +394,6 @@ const columns: ColumnType<User>[] = [
|
|
|
443
394
|
|
|
444
395
|
---
|
|
445
396
|
|
|
446
|
-
### Loading skeleton
|
|
447
|
-
|
|
448
|
-
```tsx
|
|
449
|
-
// Full skeleton on initial load (no data yet)
|
|
450
|
-
<BoltTable
|
|
451
|
-
columns={columns}
|
|
452
|
-
data={[]}
|
|
453
|
-
isLoading={true}
|
|
454
|
-
pagination={{ pageSize: 20 }}
|
|
455
|
-
/>
|
|
456
|
-
|
|
457
|
-
// Layout skeleton before column widths are known
|
|
458
|
-
<BoltTable
|
|
459
|
-
columns={columns}
|
|
460
|
-
data={[]}
|
|
461
|
-
layoutLoading={true}
|
|
462
|
-
/>
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
---
|
|
466
|
-
|
|
467
397
|
### Fixed height (fill parent)
|
|
468
398
|
|
|
469
399
|
By default, BoltTable auto-sizes to its content. To fill a fixed-height container instead:
|
|
@@ -491,6 +421,7 @@ import type {
|
|
|
491
421
|
PaginationType,
|
|
492
422
|
SortDirection,
|
|
493
423
|
DataRecord,
|
|
424
|
+
BoltTableIcons,
|
|
494
425
|
} from 'bolt-table';
|
|
495
426
|
```
|
|
496
427
|
|
|
@@ -498,4 +429,4 @@ import type {
|
|
|
498
429
|
|
|
499
430
|
## License
|
|
500
431
|
|
|
501
|
-
MIT © [Venkatesh Sirigineedi](https://github.com
|
|
432
|
+
MIT © [Venkatesh Sirigineedi](https://github.com/venkateshsirigineedi)
|
package/dist/index.d.mts
CHANGED
|
@@ -278,7 +278,7 @@ interface ColumnContextMenuItem {
|
|
|
278
278
|
label: React.ReactNode;
|
|
279
279
|
/**
|
|
280
280
|
* Optional icon shown to the left of the label.
|
|
281
|
-
* Recommended size: 12–14px
|
|
281
|
+
* Recommended size: 12–14px .
|
|
282
282
|
*
|
|
283
283
|
* @example
|
|
284
284
|
* icon: <CopyIcon className="h-3 w-3" />
|
|
@@ -1238,11 +1238,13 @@ interface DraggableHeaderProps {
|
|
|
1238
1238
|
/**
|
|
1239
1239
|
* Called when the user presses down on the resize handle at the right edge
|
|
1240
1240
|
* of this header cell. Starts the resize drag operation in BoltTable.
|
|
1241
|
-
*
|
|
1242
|
-
* @param columnKey - The key of the column being resized
|
|
1243
|
-
* @param event - The React mouse event from the resize handle mousedown
|
|
1244
1241
|
*/
|
|
1245
1242
|
onResizeStart?: (columnKey: string, event: React$1.MouseEvent) => void;
|
|
1243
|
+
/**
|
|
1244
|
+
* Called when the user starts dragging this column header to reorder.
|
|
1245
|
+
* BoltTable handles the full drag lifecycle from this point.
|
|
1246
|
+
*/
|
|
1247
|
+
onColumnDragStart?: (columnKey: string, event: React$1.PointerEvent) => void;
|
|
1246
1248
|
/**
|
|
1247
1249
|
* Shared styling overrides for header cells.
|
|
1248
1250
|
* `styles.header` applies to all headers; `styles.pinnedHeader` applies
|
|
@@ -1264,7 +1266,7 @@ interface DraggableHeaderProps {
|
|
|
1264
1266
|
hideGripIcon?: boolean;
|
|
1265
1267
|
/**
|
|
1266
1268
|
* A custom React node to use as the drag grip icon.
|
|
1267
|
-
* When omitted, the default `GripVertical` icon
|
|
1269
|
+
* When omitted, the default `GripVertical` icon is used.
|
|
1268
1270
|
*
|
|
1269
1271
|
* @example
|
|
1270
1272
|
* gripIcon={<MyCustomDragIcon />}
|
|
@@ -1375,7 +1377,7 @@ interface DraggableHeaderProps {
|
|
|
1375
1377
|
*
|
|
1376
1378
|
* @internal This is an internal BoltTable component. Use BoltTable directly.
|
|
1377
1379
|
*/
|
|
1378
|
-
declare const DraggableHeader: React$1.MemoExoticComponent<({ column, visualIndex, accentColor, onResizeStart, styles, classNames, hideGripIcon, gripIcon, stickyOffset, onTogglePin, onToggleHide, isLastColumn, sortDirection, onSort, filterValue, onFilter, onClearFilter, customContextMenuItems, icons, }: DraggableHeaderProps) => react_jsx_runtime.JSX.Element>;
|
|
1380
|
+
declare const DraggableHeader: React$1.MemoExoticComponent<({ column, visualIndex, accentColor, onResizeStart, styles, classNames, hideGripIcon, gripIcon, stickyOffset, onTogglePin, onToggleHide, isLastColumn, sortDirection, onSort, filterValue, onFilter, onClearFilter, customContextMenuItems, icons, onColumnDragStart, }: DraggableHeaderProps) => react_jsx_runtime.JSX.Element>;
|
|
1379
1381
|
|
|
1380
1382
|
/**
|
|
1381
1383
|
* The imperative handle exposed by ResizeOverlay via `ref`.
|
package/dist/index.d.ts
CHANGED
|
@@ -278,7 +278,7 @@ interface ColumnContextMenuItem {
|
|
|
278
278
|
label: React.ReactNode;
|
|
279
279
|
/**
|
|
280
280
|
* Optional icon shown to the left of the label.
|
|
281
|
-
* Recommended size: 12–14px
|
|
281
|
+
* Recommended size: 12–14px .
|
|
282
282
|
*
|
|
283
283
|
* @example
|
|
284
284
|
* icon: <CopyIcon className="h-3 w-3" />
|
|
@@ -1238,11 +1238,13 @@ interface DraggableHeaderProps {
|
|
|
1238
1238
|
/**
|
|
1239
1239
|
* Called when the user presses down on the resize handle at the right edge
|
|
1240
1240
|
* of this header cell. Starts the resize drag operation in BoltTable.
|
|
1241
|
-
*
|
|
1242
|
-
* @param columnKey - The key of the column being resized
|
|
1243
|
-
* @param event - The React mouse event from the resize handle mousedown
|
|
1244
1241
|
*/
|
|
1245
1242
|
onResizeStart?: (columnKey: string, event: React$1.MouseEvent) => void;
|
|
1243
|
+
/**
|
|
1244
|
+
* Called when the user starts dragging this column header to reorder.
|
|
1245
|
+
* BoltTable handles the full drag lifecycle from this point.
|
|
1246
|
+
*/
|
|
1247
|
+
onColumnDragStart?: (columnKey: string, event: React$1.PointerEvent) => void;
|
|
1246
1248
|
/**
|
|
1247
1249
|
* Shared styling overrides for header cells.
|
|
1248
1250
|
* `styles.header` applies to all headers; `styles.pinnedHeader` applies
|
|
@@ -1264,7 +1266,7 @@ interface DraggableHeaderProps {
|
|
|
1264
1266
|
hideGripIcon?: boolean;
|
|
1265
1267
|
/**
|
|
1266
1268
|
* A custom React node to use as the drag grip icon.
|
|
1267
|
-
* When omitted, the default `GripVertical` icon
|
|
1269
|
+
* When omitted, the default `GripVertical` icon is used.
|
|
1268
1270
|
*
|
|
1269
1271
|
* @example
|
|
1270
1272
|
* gripIcon={<MyCustomDragIcon />}
|
|
@@ -1375,7 +1377,7 @@ interface DraggableHeaderProps {
|
|
|
1375
1377
|
*
|
|
1376
1378
|
* @internal This is an internal BoltTable component. Use BoltTable directly.
|
|
1377
1379
|
*/
|
|
1378
|
-
declare const DraggableHeader: React$1.MemoExoticComponent<({ column, visualIndex, accentColor, onResizeStart, styles, classNames, hideGripIcon, gripIcon, stickyOffset, onTogglePin, onToggleHide, isLastColumn, sortDirection, onSort, filterValue, onFilter, onClearFilter, customContextMenuItems, icons, }: DraggableHeaderProps) => react_jsx_runtime.JSX.Element>;
|
|
1380
|
+
declare const DraggableHeader: React$1.MemoExoticComponent<({ column, visualIndex, accentColor, onResizeStart, styles, classNames, hideGripIcon, gripIcon, stickyOffset, onTogglePin, onToggleHide, isLastColumn, sortDirection, onSort, filterValue, onFilter, onClearFilter, customContextMenuItems, icons, onColumnDragStart, }: DraggableHeaderProps) => react_jsx_runtime.JSX.Element>;
|
|
1379
1381
|
|
|
1380
1382
|
/**
|
|
1381
1383
|
* The imperative handle exposed by ResizeOverlay via `ref`.
|