bolt-table 0.1.39 → 0.1.40
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 +152 -10
- package/package.json +5 -6
package/README.md
CHANGED
|
@@ -181,6 +181,14 @@ Available icon keys: `gripVertical`, `sortAsc`, `sortDesc`, `filter`, `filterCle
|
|
|
181
181
|
| `hideGlobalSearch` | `boolean` | `false` | Hide the global search input above the table |
|
|
182
182
|
| `globalSearchValue` | `string` | — | Controlled global search value |
|
|
183
183
|
| `onGlobalSearchChange` | `(value: string) => void` | — | Called when the global search input changes |
|
|
184
|
+
| `rowDragEnabled` | `boolean` | `false` | Show a drag grip handle on each row for drag-and-drop reordering |
|
|
185
|
+
| `onRowReorder` | `(fromIndex, toIndex) => void` | — | Called when the user drops a row into a new position |
|
|
186
|
+
| `aiMode` | `boolean` | `false` | Enable the AI assistant button in the toolbar |
|
|
187
|
+
| `aiConfig` | `BoltTableAIConfig` | — | AI provider configuration (API key, model, etc.) |
|
|
188
|
+
| `onAIQuery` | `(query, context) => Promise<AIResponse>` | — | Custom AI query handler (overrides built-in AI) |
|
|
189
|
+
| `onAIResponse` | `(response: AIResponse) => void` | — | Called after AI applies operations |
|
|
190
|
+
| `aiPlaceholder` | `string` | `"Ask AI anything..."` | Placeholder text for the AI search bar |
|
|
191
|
+
| `aiButtonLabel` | `ReactNode` | `"Ask AI"` | Label for the AI button |
|
|
184
192
|
|
|
185
193
|
---
|
|
186
194
|
|
|
@@ -749,6 +757,145 @@ By default, BoltTable auto-sizes to its content. To fill a fixed-height containe
|
|
|
749
757
|
</div>
|
|
750
758
|
```
|
|
751
759
|
|
|
760
|
+
### Row drag-and-drop reordering
|
|
761
|
+
|
|
762
|
+
Enable row reordering with a drag grip handle on each row. Users can drag rows to new positions.
|
|
763
|
+
|
|
764
|
+
```tsx
|
|
765
|
+
const [data, setData] = useState<User[]>(initialData);
|
|
766
|
+
|
|
767
|
+
<BoltTable
|
|
768
|
+
columns={columns}
|
|
769
|
+
data={data}
|
|
770
|
+
rowKey="id"
|
|
771
|
+
rowDragEnabled
|
|
772
|
+
onRowReorder={(fromIndex, toIndex) => {
|
|
773
|
+
setData(prev => {
|
|
774
|
+
const next = [...prev];
|
|
775
|
+
const [moved] = next.splice(fromIndex, 1);
|
|
776
|
+
next.splice(toIndex, 0, moved);
|
|
777
|
+
return next;
|
|
778
|
+
});
|
|
779
|
+
}}
|
|
780
|
+
/>
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
A grip icon appears as a pinned column on the left. Drag a row by its grip handle and drop it onto another row — the blue indicator line shows where it will land.
|
|
784
|
+
|
|
785
|
+
> **Note:** `onRowReorder` receives the indices within the current page's visible data. If you use server-side pagination, map these back to your full dataset accordingly.
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
### Column auto-fit width
|
|
790
|
+
|
|
791
|
+
Double-click the resize handle (right edge) of any column header to automatically fit the column width to its content. The table measures the header title and all visible cell content, then sets the optimal width (clamped between 60px and 800px).
|
|
792
|
+
|
|
793
|
+
```tsx
|
|
794
|
+
// No extra configuration needed — auto-fit is built into every column's resize handle.
|
|
795
|
+
// Just double-click the right edge of any header.
|
|
796
|
+
|
|
797
|
+
<BoltTable columns={columns} data={data} />
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
You still get notified via `onColumnResize` when an auto-fit happens:
|
|
801
|
+
|
|
802
|
+
```tsx
|
|
803
|
+
<BoltTable
|
|
804
|
+
columns={columns}
|
|
805
|
+
data={data}
|
|
806
|
+
onColumnResize={(columnKey, newWidth) => {
|
|
807
|
+
console.log(`Column ${columnKey} auto-fitted to ${newWidth}px`);
|
|
808
|
+
}}
|
|
809
|
+
/>
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
---
|
|
813
|
+
|
|
814
|
+
### AI mode
|
|
815
|
+
|
|
816
|
+
Enable the AI assistant to let users interact with the table using natural language. The AI can filter, sort, style, resize, reorder, pin columns, and navigate pages.
|
|
817
|
+
|
|
818
|
+
```tsx
|
|
819
|
+
<BoltTable
|
|
820
|
+
columns={columns}
|
|
821
|
+
data={data}
|
|
822
|
+
rowKey="id"
|
|
823
|
+
aiMode
|
|
824
|
+
aiConfig={{
|
|
825
|
+
provider: 'openai', // 'openai' | 'anthropic' | 'custom'
|
|
826
|
+
apiKey: 'sk-...',
|
|
827
|
+
model: 'gpt-4o-mini', // optional, defaults vary by provider
|
|
828
|
+
}}
|
|
829
|
+
onAIResponse={(response) => {
|
|
830
|
+
console.log('AI applied:', response.message);
|
|
831
|
+
}}
|
|
832
|
+
/>
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
**Custom AI handler** (bring your own backend):
|
|
836
|
+
|
|
837
|
+
```tsx
|
|
838
|
+
<BoltTable
|
|
839
|
+
columns={columns}
|
|
840
|
+
data={data}
|
|
841
|
+
aiMode
|
|
842
|
+
onAIQuery={async (query, { data, columns }) => {
|
|
843
|
+
const res = await fetch('/api/table-ai', {
|
|
844
|
+
method: 'POST',
|
|
845
|
+
body: JSON.stringify({ query, schema: columns.map(c => c.key) }),
|
|
846
|
+
});
|
|
847
|
+
return res.json(); // must return { operations: [...], message: "..." }
|
|
848
|
+
}}
|
|
849
|
+
/>
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
**Saved filters** — when AI answers a query, a "Save Filter" button appears. Clicking it saves the operations to localStorage. Saved filters can be re-applied instantly with zero AI calls. The saved filters dropdown appears automatically when you have saved filters.
|
|
853
|
+
|
|
854
|
+
```tsx
|
|
855
|
+
// Saved filters are stored automatically using the columnPersistence storageKey.
|
|
856
|
+
// To enable saved filters, just use aiMode with columnPersistence:
|
|
857
|
+
<BoltTable
|
|
858
|
+
columns={columns}
|
|
859
|
+
data={data}
|
|
860
|
+
aiMode
|
|
861
|
+
aiConfig={{ provider: 'openai', apiKey: 'sk-...' }}
|
|
862
|
+
columnPersistence={{ storageKey: 'my-table' }}
|
|
863
|
+
/>
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
---
|
|
867
|
+
|
|
868
|
+
### Safe row keys (NaN / undefined / duplicates)
|
|
869
|
+
|
|
870
|
+
BoltTable handles edge cases in row keys automatically. If your `rowKey` field contains `undefined`, `null`, `NaN`, or empty strings, the table falls back to index-based keys instead of producing broken or colliding keys.
|
|
871
|
+
|
|
872
|
+
```tsx
|
|
873
|
+
// All of these work correctly — no crashes, no duplicate key warnings:
|
|
874
|
+
|
|
875
|
+
// Missing id field
|
|
876
|
+
<BoltTable data={[{ name: 'Alice' }, { name: 'Bob' }]} rowKey="id" columns={columns} />
|
|
877
|
+
|
|
878
|
+
// NaN values
|
|
879
|
+
<BoltTable data={[{ id: NaN, name: 'Alice' }]} rowKey="id" columns={columns} />
|
|
880
|
+
|
|
881
|
+
// Duplicate ids — automatically deduplicated
|
|
882
|
+
<BoltTable
|
|
883
|
+
data={[
|
|
884
|
+
{ id: 1, name: 'Alice' },
|
|
885
|
+
{ id: 1, name: 'Alice (copy)' },
|
|
886
|
+
]}
|
|
887
|
+
rowKey="id"
|
|
888
|
+
columns={columns}
|
|
889
|
+
/>
|
|
890
|
+
|
|
891
|
+
// rowKey function that might return undefined
|
|
892
|
+
<BoltTable
|
|
893
|
+
data={data}
|
|
894
|
+
rowKey={(record) => record.uuid} // safe even if uuid is undefined
|
|
895
|
+
columns={columns}
|
|
896
|
+
/>
|
|
897
|
+
```
|
|
898
|
+
|
|
752
899
|
---
|
|
753
900
|
|
|
754
901
|
## Documentation
|
|
@@ -771,6 +918,11 @@ import type {
|
|
|
771
918
|
SortDirection,
|
|
772
919
|
DataRecord,
|
|
773
920
|
BoltTableIcons,
|
|
921
|
+
// AI types
|
|
922
|
+
AIResponse,
|
|
923
|
+
AIOperation,
|
|
924
|
+
BoltTableAIConfig,
|
|
925
|
+
BoltTableConfig,
|
|
774
926
|
} from 'bolt-table';
|
|
775
927
|
```
|
|
776
928
|
|
|
@@ -780,16 +932,6 @@ import type {
|
|
|
780
932
|
|
|
781
933
|
MIT © [Venkatesh Sirigineedi](https://github.com/venkateshwebdev)
|
|
782
934
|
|
|
783
|
-
|
|
784
|
-
[](https://www.npmjs.com/package/bolt-table)
|
|
785
|
-
[](./LICENSE)
|
|
786
|
-
[](https://github.com/venkateshwebdev/Bolt-Table)
|
|
787
|
-
[](https://bolt-table.vercel.app/)
|
|
788
|
-
|
|
789
|
-
---
|
|
790
|
-
|
|
791
|
-
## Features
|
|
792
|
-
|
|
793
935
|
- **Row virtualization** — only visible rows are rendered, powered by TanStack Virtual
|
|
794
936
|
- **Drag to reorder columns** — custom zero-dependency drag-and-drop (no @dnd-kit needed)
|
|
795
937
|
- **Column pinning** — pin columns to the left or right edge via right-click
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bolt-table",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
4
4
|
"description": "Virtualized React table with column drag & drop, pinning, resizing, sorting, filtering, and pagination.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,10 +18,6 @@
|
|
|
18
18
|
"README.md",
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
|
-
"scripts": {
|
|
22
|
-
"build": "tsup",
|
|
23
|
-
"prepublishOnly": "npm run build"
|
|
24
|
-
},
|
|
25
21
|
"peerDependencies": {
|
|
26
22
|
"@tanstack/react-virtual": "^3.13.22",
|
|
27
23
|
"react": ">=18",
|
|
@@ -32,5 +28,8 @@
|
|
|
32
28
|
"@types/react-dom": "^19.2.3",
|
|
33
29
|
"tsup": "^8.0.0",
|
|
34
30
|
"typescript": "^5.0.0"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup"
|
|
35
34
|
}
|
|
36
|
-
}
|
|
35
|
+
}
|