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.
Files changed (2) hide show
  1. package/README.md +152 -10
  2. 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
- [![npm version](https://img.shields.io/npm/v/bolt-table)](https://www.npmjs.com/package/bolt-table)
785
- [![license](https://img.shields.io/npm/l/bolt-table)](./LICENSE)
786
- [![github](https://img.shields.io/badge/GitHub-Source-181717?logo=github)](https://github.com/venkateshwebdev/Bolt-Table)
787
- [![website](https://img.shields.io/badge/Website-Live_Demo-blue?logo=vercel)](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.39",
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
+ }