wandertable 0.1.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/LICENSE +21 -0
- package/README.md +505 -0
- package/dist/style.css +1 -0
- package/dist/types/WanderTable.d.ts +112 -0
- package/dist/types/WanderTable.d.ts.map +1 -0
- package/dist/types/__tests__/ColumnModel.test.d.ts +2 -0
- package/dist/types/__tests__/ColumnModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/CommandBus.test.d.ts +2 -0
- package/dist/types/__tests__/CommandBus.test.d.ts.map +1 -0
- package/dist/types/__tests__/DataModel.test.d.ts +2 -0
- package/dist/types/__tests__/DataModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/Export.test.d.ts +2 -0
- package/dist/types/__tests__/Export.test.d.ts.map +1 -0
- package/dist/types/__tests__/GroupedHeaders.test.d.ts +2 -0
- package/dist/types/__tests__/GroupedHeaders.test.d.ts.map +1 -0
- package/dist/types/__tests__/MergeModel.test.d.ts +2 -0
- package/dist/types/__tests__/MergeModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/SelectionModel.test.d.ts +2 -0
- package/dist/types/__tests__/SelectionModel.test.d.ts.map +1 -0
- package/dist/types/__tests__/ViewMapping.test.d.ts +2 -0
- package/dist/types/__tests__/ViewMapping.test.d.ts.map +1 -0
- package/dist/types/columns/ColumnModel.d.ts +25 -0
- package/dist/types/columns/ColumnModel.d.ts.map +1 -0
- package/dist/types/columns/GroupedHeaders.d.ts +20 -0
- package/dist/types/columns/GroupedHeaders.d.ts.map +1 -0
- package/dist/types/core/CommandBus.d.ts +63 -0
- package/dist/types/core/CommandBus.d.ts.map +1 -0
- package/dist/types/core/DataModel.d.ts +27 -0
- package/dist/types/core/DataModel.d.ts.map +1 -0
- package/dist/types/core/EventEmitter.d.ts +10 -0
- package/dist/types/core/EventEmitter.d.ts.map +1 -0
- package/dist/types/core/MergeModel.d.ts +35 -0
- package/dist/types/core/MergeModel.d.ts.map +1 -0
- package/dist/types/core/PaginationModel.d.ts +24 -0
- package/dist/types/core/PaginationModel.d.ts.map +1 -0
- package/dist/types/core/RowGroupModel.d.ts +36 -0
- package/dist/types/core/RowGroupModel.d.ts.map +1 -0
- package/dist/types/core/SelectionModel.d.ts +47 -0
- package/dist/types/core/SelectionModel.d.ts.map +1 -0
- package/dist/types/core/ViewMapping.d.ts +37 -0
- package/dist/types/core/ViewMapping.d.ts.map +1 -0
- package/dist/types/core/ViewportModel.d.ts +9 -0
- package/dist/types/core/ViewportModel.d.ts.map +1 -0
- package/dist/types/editors/BlankEditor.d.ts +20 -0
- package/dist/types/editors/BlankEditor.d.ts.map +1 -0
- package/dist/types/editors/DropdownEditor.d.ts +23 -0
- package/dist/types/editors/DropdownEditor.d.ts.map +1 -0
- package/dist/types/editors/EditorManager.d.ts +22 -0
- package/dist/types/editors/EditorManager.d.ts.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interaction/ClipboardManager.d.ts +19 -0
- package/dist/types/interaction/ClipboardManager.d.ts.map +1 -0
- package/dist/types/interaction/ColumnReorder.d.ts +20 -0
- package/dist/types/interaction/ColumnReorder.d.ts.map +1 -0
- package/dist/types/interaction/ColumnResize.d.ts +15 -0
- package/dist/types/interaction/ColumnResize.d.ts.map +1 -0
- package/dist/types/interaction/FillHandle.d.ts +39 -0
- package/dist/types/interaction/FillHandle.d.ts.map +1 -0
- package/dist/types/interaction/KeyboardNav.d.ts +19 -0
- package/dist/types/interaction/KeyboardNav.d.ts.map +1 -0
- package/dist/types/interaction/RowResize.d.ts +15 -0
- package/dist/types/interaction/RowResize.d.ts.map +1 -0
- package/dist/types/plugins/ContextMenu.d.ts +44 -0
- package/dist/types/plugins/ContextMenu.d.ts.map +1 -0
- package/dist/types/plugins/Export.d.ts +16 -0
- package/dist/types/plugins/Export.d.ts.map +1 -0
- package/dist/types/render/AutoFit.d.ts +23 -0
- package/dist/types/render/AutoFit.d.ts.map +1 -0
- package/dist/types/render/DOMRenderer.d.ts +91 -0
- package/dist/types/render/DOMRenderer.d.ts.map +1 -0
- package/dist/types/render/LoadingOverlay.d.ts +9 -0
- package/dist/types/render/LoadingOverlay.d.ts.map +1 -0
- package/dist/types/render/PaginationBar.d.ts +20 -0
- package/dist/types/render/PaginationBar.d.ts.map +1 -0
- package/dist/types/renderers/BadgeRenderer.d.ts +5 -0
- package/dist/types/renderers/BadgeRenderer.d.ts.map +1 -0
- package/dist/types/renderers/BlankRenderer.d.ts +9 -0
- package/dist/types/renderers/BlankRenderer.d.ts.map +1 -0
- package/dist/types/renderers/CheckboxRenderer.d.ts +5 -0
- package/dist/types/renderers/CheckboxRenderer.d.ts.map +1 -0
- package/dist/types/renderers/NumberRenderer.d.ts +7 -0
- package/dist/types/renderers/NumberRenderer.d.ts.map +1 -0
- package/dist/types/renderers/ProgressRenderer.d.ts +5 -0
- package/dist/types/renderers/ProgressRenderer.d.ts.map +1 -0
- package/dist/types/renderers/RendererRegistry.d.ts +10 -0
- package/dist/types/renderers/RendererRegistry.d.ts.map +1 -0
- package/dist/types/renderers/TextRenderer.d.ts +5 -0
- package/dist/types/renderers/TextRenderer.d.ts.map +1 -0
- package/dist/types/rows/RowModel.d.ts +20 -0
- package/dist/types/rows/RowModel.d.ts.map +1 -0
- package/dist/types/themes.d.ts +5 -0
- package/dist/types/themes.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +348 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/wandertable.cjs +14 -0
- package/dist/wandertable.cjs.map +1 -0
- package/dist/wandertable.global.js +14 -0
- package/dist/wandertable.global.js.map +1 -0
- package/dist/wandertable.js +2757 -0
- package/dist/wandertable.js.map +1 -0
- package/dist/wandertable.umd.js +14 -0
- package/dist/wandertable.umd.js.map +1 -0
- package/package.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Wilson Glasser
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
# WanderTable
|
|
2
|
+
|
|
3
|
+
[](https://github.com/wilsonglasser/wandertable/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/wandertable)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://ko-fi.com/wilsonglasser)
|
|
7
|
+
[](https://buymeacoffee.com/wilsonglasser)
|
|
8
|
+
|
|
9
|
+
High-performance grid/spreadsheet library for the web. Zero dependencies, TypeScript, DOM-virtualized.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **Two modes**: Spreadsheet (independent cells) and Table (column-driven rows)
|
|
14
|
+
- **Two layouts**: `scroll` (fixed height, internal scroll, virtualized) and `auto` (grows with content, page scroll)
|
|
15
|
+
- **DOM virtualized**: Only visible cells exist in the DOM (~750 nodes max). Recycled on scroll.
|
|
16
|
+
- **Rich cell content**: Each cell is a real `<div>` - any HTML, CSS, hover effects, transitions
|
|
17
|
+
- **Renderers**: text, number, checkbox, badge, progress, blank - or register your own
|
|
18
|
+
- **Editors**: text, dropdown (async, searchable, multi-select), blank - or register your own
|
|
19
|
+
- **Cell-level types**: Each cell can have its own renderer/editor independent of the column
|
|
20
|
+
- **Selection**: Single, range (Shift), multi-range (Ctrl), full row/column, select all
|
|
21
|
+
- **Keyboard navigation**: Arrows, Tab, Enter, Escape, Home/End, Ctrl+arrows, typing to edit
|
|
22
|
+
- **Clipboard**: Copy/paste/cut as TSV (compatible with Excel/Sheets). Single-cell paste fills selection.
|
|
23
|
+
- **Undo/Redo**: Command pattern with configurable stack limit
|
|
24
|
+
- **Sorting**: Per-column, asc/desc, custom comparator, external callback for server-side
|
|
25
|
+
- **Filtering**: Per-column, custom filter functions, external callback for server-side
|
|
26
|
+
- **Merge cells**: Merge/unmerge arbitrary ranges
|
|
27
|
+
- **Frozen panes**: Sticky rows and columns that stay visible on scroll
|
|
28
|
+
- **Grouped headers**: Multi-level column headers (e.g. "Months / Jan Feb Mar")
|
|
29
|
+
- **Pagination**: Built-in pagination bar with page size, total rows, navigation
|
|
30
|
+
- **Context menu**: Dynamic items with `visible`/`disabled` as callbacks, per-target (cell/column/row header)
|
|
31
|
+
- **Resize**: Column and row resize by dragging header edges (individually toggleable)
|
|
32
|
+
- **Auto-fit**: Columns and rows auto-size to content
|
|
33
|
+
- **Auto row height**: Rows automatically grow to fit cell content
|
|
34
|
+
- **Export**: CSV and JSON with download, configurable columns/headers
|
|
35
|
+
- **Themes**: Light, Dark, Minimal presets - or define your own via CSS variables
|
|
36
|
+
- **Loading overlay**: Show/hide spinner overlay for async operations
|
|
37
|
+
- **Events**: Typed event system for cell changes, selection, scroll, commands, editor lifecycle
|
|
38
|
+
- **Command events**: `command:execute`, `command:undo`, `command:redo` for syncing with external databases
|
|
39
|
+
- **Fill handle**: Drag to fill cells in any direction (including diagonal), with custom callback
|
|
40
|
+
- **Column reorder**: Drag headers to reorder columns
|
|
41
|
+
- **Row grouping**: Expand/collapse groups of rows
|
|
42
|
+
- **Infinite mode**: Grid auto-expands on navigate/scroll beyond bounds
|
|
43
|
+
- **Lazy loading**: `onLoadMore` callback when scroll reaches the edge
|
|
44
|
+
- **Sparse data model**: Map-based, only cells with data consume memory. Patches for partial updates.
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install wandertable
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
### Spreadsheet Mode
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { WanderTable } from 'wandertable';
|
|
58
|
+
import 'wandertable/style.css';
|
|
59
|
+
|
|
60
|
+
const table = new WanderTable(document.getElementById('grid'), {
|
|
61
|
+
mode: 'spreadsheet',
|
|
62
|
+
rowCount: 1000,
|
|
63
|
+
colCount: 26,
|
|
64
|
+
showRowHeaders: true,
|
|
65
|
+
showColHeaders: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Set individual cells
|
|
69
|
+
table.setCellValue(0, 0, 'Hello');
|
|
70
|
+
table.setCellValue(0, 1, 42);
|
|
71
|
+
|
|
72
|
+
// Bulk load
|
|
73
|
+
table.applyPatch([
|
|
74
|
+
{ row: 1, col: 0, data: { value: 'World', style: { fontWeight: 'bold' } } },
|
|
75
|
+
{ row: 1, col: 1, data: { value: true, type: 'checkbox' } },
|
|
76
|
+
{ row: 2, col: 0, data: { value: 75, type: 'progress' } },
|
|
77
|
+
{ row: 2, col: 1, data: { value: 'active', type: 'badge' } },
|
|
78
|
+
]);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Table Mode
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const table = new WanderTable(document.getElementById('grid'), {
|
|
85
|
+
mode: 'table',
|
|
86
|
+
layout: 'auto', // grows with content, scroll on page
|
|
87
|
+
autoRowHeight: true,
|
|
88
|
+
columns: [
|
|
89
|
+
{ key: 'name', label: 'Name', width: 180 },
|
|
90
|
+
{ key: 'email', label: 'Email', width: 200 },
|
|
91
|
+
{ key: 'status', label: 'Status', type: 'badge', width: 100 },
|
|
92
|
+
{ key: 'active', label: 'Active', type: 'checkbox', width: 70 },
|
|
93
|
+
],
|
|
94
|
+
tableData: [
|
|
95
|
+
{ name: 'Alice', email: 'alice@test.com', status: 'active', active: true },
|
|
96
|
+
{ name: 'Bob', email: 'bob@test.com', status: 'pending', active: false },
|
|
97
|
+
],
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Grouped Column Headers
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
const table = new WanderTable(el, {
|
|
105
|
+
mode: 'table',
|
|
106
|
+
columns: [
|
|
107
|
+
{ key: 'name', label: 'Name', width: 180 },
|
|
108
|
+
{
|
|
109
|
+
label: 'Q4 Sales',
|
|
110
|
+
children: [
|
|
111
|
+
{ key: 'oct', label: 'Oct', type: 'number', width: 80 },
|
|
112
|
+
{ key: 'nov', label: 'Nov', type: 'number', width: 80 },
|
|
113
|
+
{ key: 'dec', label: 'Dec', type: 'number', width: 80 },
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
label: 'Metrics',
|
|
118
|
+
children: [
|
|
119
|
+
{ key: 'score', label: 'Score', type: 'progress', width: 120 },
|
|
120
|
+
{ key: 'active', label: 'Active', type: 'checkbox', width: 70 },
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
tableData: [...],
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Options
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
new WanderTable(container, {
|
|
132
|
+
// ── Mode & Layout ──
|
|
133
|
+
mode: 'spreadsheet' | 'table', // default: 'spreadsheet'
|
|
134
|
+
layout: 'scroll' | 'auto', // default: 'scroll'
|
|
135
|
+
|
|
136
|
+
// ── Data ──
|
|
137
|
+
data: CellPatch[], // initial cell patches (spreadsheet mode)
|
|
138
|
+
tableData: Record<string, unknown>[], // initial row objects (table mode)
|
|
139
|
+
columns: ColumnConfig[], // column definitions
|
|
140
|
+
rowCount: number, // default: 100
|
|
141
|
+
colCount: number, // default: 26
|
|
142
|
+
|
|
143
|
+
// ── Dimensions ──
|
|
144
|
+
defaultRowHeight: number, // default: 28
|
|
145
|
+
defaultColWidth: number, // default: 100
|
|
146
|
+
autoRowHeight: boolean, // auto-fit row height to content. default: false
|
|
147
|
+
|
|
148
|
+
// ── Display ──
|
|
149
|
+
showRowHeaders: boolean, // show row numbers. default: true
|
|
150
|
+
showColHeaders: boolean, // show column letters/labels. default: true
|
|
151
|
+
showGridLines: boolean, // show cell borders. default: true
|
|
152
|
+
showBorder: boolean, // show outer border. default: true
|
|
153
|
+
loading: boolean, // show loading overlay. default: false
|
|
154
|
+
|
|
155
|
+
// ── Frozen Panes ──
|
|
156
|
+
frozenRows: number, // sticky rows at top. default: 0
|
|
157
|
+
frozenCols: number, // sticky columns at left. default: 0
|
|
158
|
+
|
|
159
|
+
// ── Permissions ──
|
|
160
|
+
readOnly: boolean, // no editing at all. default: false
|
|
161
|
+
allowEditing: boolean, // allow cell editing. default: true
|
|
162
|
+
allowSelection: boolean, // allow cell selection. default: true
|
|
163
|
+
allowRangeSelection: boolean, // allow multi-cell selection. default: true
|
|
164
|
+
allowColResize: boolean, // column resize by drag. default: true
|
|
165
|
+
allowRowResize: boolean, // row resize by drag. default: true
|
|
166
|
+
allowClipboard: boolean, // copy/paste/cut. default: true
|
|
167
|
+
allowContextMenu: boolean, // right-click menu. default: true
|
|
168
|
+
allowKeyboardNav: boolean, // keyboard navigation. default: true
|
|
169
|
+
allowUndoRedo: boolean, // undo/redo. default: true
|
|
170
|
+
|
|
171
|
+
// ── Cell Defaults ──
|
|
172
|
+
defaultCellType: string, // renderer for cells without type. default: 'text'
|
|
173
|
+
undoLimit: number, // max undo stack size. default: 100
|
|
174
|
+
|
|
175
|
+
// ── Merge & Sort & Filter ──
|
|
176
|
+
merges: MergeRange[], // initial merged ranges
|
|
177
|
+
sort: { col, direction }, // initial sort
|
|
178
|
+
filters: Record<number, FilterFn>, // initial filters
|
|
179
|
+
pagination: PaginationConfig, // pagination settings
|
|
180
|
+
|
|
181
|
+
// ── Theme ──
|
|
182
|
+
theme: Partial<ThemeConfig>, // or use THEME_DARK, THEME_MINIMAL
|
|
183
|
+
|
|
184
|
+
// ── Callbacks ──
|
|
185
|
+
onCellChange: (row, col, oldValue, newValue) => void,
|
|
186
|
+
onSelectionChange: (ranges) => void,
|
|
187
|
+
onScroll: (viewport) => void,
|
|
188
|
+
onContextMenu: (row, col, event) => void,
|
|
189
|
+
onSort: (col, direction, key?) => boolean | void, // return true for external sort
|
|
190
|
+
onFilter: (col, key, active) => boolean | void, // return true for external filter
|
|
191
|
+
onPageChange: (page, pageSize) => void,
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## API
|
|
196
|
+
|
|
197
|
+
### Data
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
table.setCell(row, col, cellData) // set full cell data
|
|
201
|
+
table.getCell(row, col) // get cell data
|
|
202
|
+
table.setCellValue(row, col, value) // set just the value (with undo)
|
|
203
|
+
table.deleteCell(row, col) // remove cell
|
|
204
|
+
table.applyPatch(patches) // bulk update (with undo)
|
|
205
|
+
table.transaction(() => { ... }) // batch changes, single re-render
|
|
206
|
+
table.setTableData(rows) // replace all data (table mode)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Selection
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
table.getSelection() // get selected ranges
|
|
213
|
+
table.getSelectionInfo() // rich info: focus, bounds, cellCount, isFullRow, etc.
|
|
214
|
+
table.setSelection(ranges) // set selection programmatically
|
|
215
|
+
table.scrollTo(row, col) // scroll to make cell visible
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Undo / Redo
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
table.undo()
|
|
222
|
+
table.redo()
|
|
223
|
+
table.commands.canUndo // boolean
|
|
224
|
+
table.commands.canRedo // boolean
|
|
225
|
+
table.commands.clear() // clear history
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Sort & Filter
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
table.sort(col, 'asc' | 'desc' | null, compareFn?)
|
|
232
|
+
table.clearSort()
|
|
233
|
+
table.getSortState()
|
|
234
|
+
|
|
235
|
+
table.setFilter(col, (row, data) => boolean)
|
|
236
|
+
table.removeFilter(col)
|
|
237
|
+
table.clearFilters()
|
|
238
|
+
table.getActiveFilters() // column indices with active filters
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Merge
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
table.mergeCells(row, col, rowSpan, colSpan)
|
|
245
|
+
table.unmergeCells(row, col)
|
|
246
|
+
table.getMerge(row, col) // get merge at cell
|
|
247
|
+
table.clearMerges()
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Layout
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
table.setColumnWidth(col, width)
|
|
254
|
+
table.setRowHeight(row, height)
|
|
255
|
+
table.autoFitColumn(col) // auto-size to content
|
|
256
|
+
table.autoFitRow(row) // auto-size to content
|
|
257
|
+
table.insertRow(at)
|
|
258
|
+
table.insertColumn(at)
|
|
259
|
+
table.refresh() // force re-render
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Export
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
table.exportCSV(options?) // returns CSV string
|
|
266
|
+
table.exportJSON(options?) // returns object[]
|
|
267
|
+
table.downloadCSV('file.csv', options?)
|
|
268
|
+
table.downloadJSON('file.json', options?)
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Options: `{ visibleOnly, columns, includeHeaders, headers }`
|
|
272
|
+
|
|
273
|
+
### Pagination
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
table.setPage(page) // 0-based
|
|
277
|
+
table.setPageSize(size)
|
|
278
|
+
table.getPaginationState() // { page, pageSize, totalRows, totalPages, startRow, endRow }
|
|
279
|
+
table.pagination.nextPage()
|
|
280
|
+
table.pagination.prevPage()
|
|
281
|
+
table.pagination.firstPage()
|
|
282
|
+
table.pagination.lastPage()
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Loading
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
table.setLoading(true) // show spinner overlay
|
|
289
|
+
table.setLoading(false) // hide
|
|
290
|
+
table.isLoading // boolean
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Renderers & Editors
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// Register custom renderer
|
|
297
|
+
table.registerRenderer('my-type', {
|
|
298
|
+
render(cell: HTMLElement, data: CellData | undefined, state: CellState) {
|
|
299
|
+
cell.innerHTML = `<div class="custom">${data?.value ?? ''}</div>`;
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Register custom editor
|
|
304
|
+
table.registerEditor('my-editor', () => ({
|
|
305
|
+
createElement(container) { ... },
|
|
306
|
+
open(value, bounds, cellData) { ... },
|
|
307
|
+
getValue() { ... },
|
|
308
|
+
close() { ... },
|
|
309
|
+
}));
|
|
310
|
+
|
|
311
|
+
// Use per cell
|
|
312
|
+
table.setCell(0, 0, { value: 'hello', type: 'my-type' });
|
|
313
|
+
|
|
314
|
+
// Or per column
|
|
315
|
+
columns: [{ key: 'status', type: 'my-type', editor: 'my-editor' }]
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Built-in renderers: `text`, `number`, `checkbox`, `badge`, `progress`, `blank`
|
|
319
|
+
|
|
320
|
+
### Context Menu
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// Override menu items
|
|
324
|
+
table.contextMenuItems = [
|
|
325
|
+
{
|
|
326
|
+
label: 'My Action',
|
|
327
|
+
shortcut: 'Ctrl+M',
|
|
328
|
+
visible: (ctx) => ctx.target === 'cell', // show only for cells
|
|
329
|
+
disabled: (ctx) => ctx.readOnly, // disable when readOnly
|
|
330
|
+
action: (ctx) => console.log(ctx.row, ctx.col),
|
|
331
|
+
},
|
|
332
|
+
{ label: '', separator: true },
|
|
333
|
+
{
|
|
334
|
+
label: 'Column Action',
|
|
335
|
+
visible: (ctx) => ctx.target === 'column-header',
|
|
336
|
+
action: (ctx) => console.log('col', ctx.col),
|
|
337
|
+
},
|
|
338
|
+
];
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
`MenuContext` fields: `target`, `row`, `col`, `selectedCount`, `isMultiSelect`, `isFullRow`, `isFullCol`, `readOnly`, `canUndo`, `canRedo`
|
|
342
|
+
|
|
343
|
+
### Events
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
table.on('cell:change', ({ row, col, oldValue, newValue }) => { ... })
|
|
347
|
+
table.on('cell:click', ({ row, col, event }) => { ... })
|
|
348
|
+
table.on('cell:dblclick', ({ row, col, event }) => { ... })
|
|
349
|
+
table.on('cell:contextmenu', ({ row, col, event }) => { ... })
|
|
350
|
+
table.on('selection:change', ({ ranges }) => { ... })
|
|
351
|
+
table.on('editor:open', ({ row, col }) => { ... })
|
|
352
|
+
table.on('editor:close', ({ row, col, value, cancelled }) => { ... })
|
|
353
|
+
table.on('scroll', ({ viewport }) => { ... })
|
|
354
|
+
table.on('column:resize', ({ col, width }) => { ... })
|
|
355
|
+
table.on('row:resize', ({ row, height }) => { ... })
|
|
356
|
+
table.on('data:patch', ({ patches }) => { ... })
|
|
357
|
+
table.on('command:execute', ({ changes }) => { ... }) // sync with DB
|
|
358
|
+
table.on('command:undo', ({ changes }) => { ... })
|
|
359
|
+
table.on('command:redo', ({ changes }) => { ... })
|
|
360
|
+
|
|
361
|
+
// Unsubscribe
|
|
362
|
+
const unsub = table.on('cell:change', handler);
|
|
363
|
+
unsub();
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Themes
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { THEME_LIGHT, THEME_DARK, THEME_MINIMAL } from 'wandertable';
|
|
370
|
+
|
|
371
|
+
new WanderTable(el, { theme: THEME_DARK });
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
Or define your own via CSS variables:
|
|
375
|
+
|
|
376
|
+
```css
|
|
377
|
+
.wt-root {
|
|
378
|
+
--wt-bg: #0f172a;
|
|
379
|
+
--wt-cell-bg: #1e293b;
|
|
380
|
+
--wt-cell-text: #e2e8f0;
|
|
381
|
+
--wt-header-bg: #0f172a;
|
|
382
|
+
--wt-header-text: #94a3b8;
|
|
383
|
+
--wt-grid-line: #334155;
|
|
384
|
+
--wt-sel-bg: rgba(59, 130, 246, 0.15);
|
|
385
|
+
--wt-sel-border: #3b82f6;
|
|
386
|
+
--wt-focus-border: #60a5fa;
|
|
387
|
+
--wt-font: 'Inter', sans-serif;
|
|
388
|
+
--wt-font-size: 13px;
|
|
389
|
+
--wt-header-font-size: 12px;
|
|
390
|
+
--wt-cell-padding: 8px;
|
|
391
|
+
--wt-header-height: 28px;
|
|
392
|
+
--wt-row-header-width: 50px;
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Fill Handle
|
|
397
|
+
|
|
398
|
+
Drag the small square at the bottom-right corner of a selection to fill cells.
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
new WanderTable(el, {
|
|
402
|
+
allowFillHandle: true, // default: true
|
|
403
|
+
|
|
404
|
+
// Optional: override default fill behavior
|
|
405
|
+
onFill: (source, fill, direction) => {
|
|
406
|
+
// direction: 'down' | 'up' | 'right' | 'left' | 'diagonal'
|
|
407
|
+
|
|
408
|
+
// Return CellPatch[] for custom values
|
|
409
|
+
// Return true to cancel fill
|
|
410
|
+
// Return void to use default (repeat pattern)
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Column Reorder
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
new WanderTable(el, {
|
|
419
|
+
allowColReorder: true, // drag column headers to reorder
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
table.reorderColumn(fromCol, toCol); // programmatic
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Row Grouping
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
new WanderTable(el, {
|
|
429
|
+
rowGroups: [
|
|
430
|
+
{ startRow: 0, count: 5, label: 'Group 1', expanded: true },
|
|
431
|
+
{ startRow: 6, count: 3, label: 'Group 2', expanded: false },
|
|
432
|
+
],
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
table.addRowGroup(startRow, count, label);
|
|
436
|
+
table.toggleRowGroup(startRow);
|
|
437
|
+
table.expandAllGroups();
|
|
438
|
+
table.collapseAllGroups();
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Lazy Loading
|
|
442
|
+
|
|
443
|
+
```typescript
|
|
444
|
+
new WanderTable(el, {
|
|
445
|
+
onLoadMore: (direction) => {
|
|
446
|
+
// direction: 'down' | 'right'
|
|
447
|
+
fetchMoreData().then(rows => {
|
|
448
|
+
table.applyPatch(rows);
|
|
449
|
+
});
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Infinite Mode
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
new WanderTable(el, {
|
|
458
|
+
infinite: true, // grid expands as you navigate/scroll beyond bounds
|
|
459
|
+
rowCount: 50, // initial size
|
|
460
|
+
colCount: 26,
|
|
461
|
+
});
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Utilities
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
import { columnLabel } from 'wandertable';
|
|
468
|
+
|
|
469
|
+
columnLabel(0) // 'A'
|
|
470
|
+
columnLabel(25) // 'Z'
|
|
471
|
+
columnLabel(26) // 'AA'
|
|
472
|
+
columnLabel(701) // 'ZZ'
|
|
473
|
+
columnLabel(702) // 'AAA'
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## Build Output
|
|
477
|
+
|
|
478
|
+
| File | Size | Description |
|
|
479
|
+
|------|------|-------------|
|
|
480
|
+
| `dist/wandertable.js` | ~112 KB | ESM module |
|
|
481
|
+
| `dist/wandertable.cjs` | ~85 KB | CommonJS module |
|
|
482
|
+
| `dist/wandertable.umd.js` | ~85 KB | UMD module |
|
|
483
|
+
| `dist/wandertable.global.js` | ~85 KB | IIFE standalone (`window.WanderTable`) |
|
|
484
|
+
| `dist/style.css` | ~8 KB | Styles |
|
|
485
|
+
| `dist/types/` | | TypeScript declarations |
|
|
486
|
+
|
|
487
|
+
## Development
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
npm install
|
|
491
|
+
npm run dev # dev server at http://localhost:5173
|
|
492
|
+
npm run build # build library (ESM + CJS + types + CSS)
|
|
493
|
+
npm run typecheck # type check
|
|
494
|
+
npm run test # run 47 unit tests
|
|
495
|
+
npm run test:watch # tests in watch mode
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
## CI/CD
|
|
499
|
+
|
|
500
|
+
- **CI** (`.github/workflows/ci.yml`): Runs on push/PR to main. Typecheck + tests + build on Node 20 and 22.
|
|
501
|
+
- **Publish** (`.github/workflows/publish.yml`): Publishes to npm on GitHub release. Requires `NPM_TOKEN` secret.
|
|
502
|
+
|
|
503
|
+
## License
|
|
504
|
+
|
|
505
|
+
MIT
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.wt-root{position:relative;overflow:hidden;background:var(--wt-bg, #ffffff);font-family:var(--wt-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);font-size:var(--wt-font-size, 13px);color:var(--wt-cell-text, #1e293b);outline:none;border:1px solid var(--wt-grid-line, #e2e8f0);box-sizing:border-box;user-select:none;-webkit-user-select:none}.wt-root--no-border{border:none}.wt-root--no-gridlines .wt-cell{border-right:none;border-bottom:none}.wt-root--no-gridlines .wt-header-cell,.wt-root--no-gridlines .wt-corner{border-right:none;border-bottom:1px solid var(--wt-grid-line, #e2e8f0)}.wt-root--auto{overflow:visible;height:auto!important}.wt-root *,.wt-root *:before,.wt-root *:after{box-sizing:border-box}.wt-scroll-container{position:absolute;overflow:auto;will-change:scroll-position}.wt-scroll-sentinel{position:absolute;top:0;left:0;pointer-events:none;visibility:hidden}.wt-viewport{position:absolute;top:0;left:0;width:100%;pointer-events:auto}.wt-row{position:absolute;top:0;left:0;width:100%;contain:layout style}.wt-cell{position:absolute;top:0;overflow:hidden;contain:layout style paint;display:flex;align-items:center;padding:0 var(--wt-cell-padding, 8px);background:var(--wt-cell-bg, #ffffff);border-right:1px solid var(--wt-grid-line, #e2e8f0);border-bottom:1px solid var(--wt-grid-line, #e2e8f0);white-space:nowrap;text-overflow:ellipsis;line-height:1.4;cursor:default}.wt-cell--selected{background:var(--wt-sel-bg, rgba(59, 130, 246, .08))}.wt-cell--focused{box-shadow:inset 0 0 0 2px var(--wt-focus-border, #3b82f6);z-index:1}.wt-corner{position:absolute;top:0;left:0;z-index:3;background:var(--wt-header-bg, #f8fafc);border-right:1px solid var(--wt-grid-line, #e2e8f0);border-bottom:1px solid var(--wt-grid-line, #e2e8f0);cursor:pointer}.wt-corner:hover{background:#e2e8f0}.wt-col-headers{position:absolute;top:0;overflow:hidden;z-index:2}.wt-col-headers-inner{position:relative;height:100%}.wt-row-headers{position:absolute;left:0;overflow:hidden;z-index:2}.wt-row-headers-inner{position:relative;width:100%}.wt-header-cell{position:absolute;display:flex;align-items:center;justify-content:center;font-size:var(--wt-header-font-size, 12px);font-weight:500;color:var(--wt-header-text, #475569);background:var(--wt-header-bg, #f8fafc);border-right:1px solid var(--wt-grid-line, #e2e8f0);border-bottom:1px solid var(--wt-grid-line, #e2e8f0);-webkit-user-select:none;user-select:none;cursor:pointer}.wt-header-cell:hover{background:#e2e8f0}.wt-col-header-cell{top:0;cursor:pointer}.wt-col-header-cell:after{content:"";position:absolute;right:0;top:0;width:5px;height:100%;cursor:col-resize}.wt-row-header-cell{left:0}.wt-editor-overlay{position:absolute;z-index:10;pointer-events:auto}.wt-editor-input{width:100%;height:100%;border:2px solid var(--wt-focus-border, #3b82f6);outline:none;font-family:inherit;font-size:inherit;padding:0 var(--wt-cell-padding, 8px);box-sizing:border-box;background:#fff}.wt-dropdown{position:absolute;top:100%;left:0;min-width:100%;max-height:240px;background:#fff;border:1px solid var(--wt-grid-line, #e2e8f0);border-radius:6px;box-shadow:0 4px 16px #0000001f;overflow:hidden;z-index:20}.wt-dropdown-search{width:100%;padding:8px 12px;border:none;border-bottom:1px solid var(--wt-grid-line, #e2e8f0);outline:none;font-family:inherit;font-size:inherit}.wt-dropdown-list{max-height:200px;overflow-y:auto}.wt-dropdown-item{padding:6px 12px;cursor:pointer;display:flex;align-items:center;gap:8px}.wt-dropdown-item:hover,.wt-dropdown-item--highlight{background:var(--wt-sel-bg, rgba(59, 130, 246, .08))}.wt-dropdown-item--selected{background:#3b82f61f;font-weight:500}.wt-dropdown-item--disabled{opacity:.5;cursor:not-allowed}.wt-dropdown-icon{flex-shrink:0}.wt-scroll-container::-webkit-scrollbar{width:8px;height:8px}.wt-scroll-container::-webkit-scrollbar-track{background:transparent}.wt-scroll-container::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.wt-scroll-container::-webkit-scrollbar-thumb:hover{background:#94a3b8}.wt-scroll-container::-webkit-scrollbar-corner{background:transparent}.wt-checkbox{display:flex;align-items:center;justify-content:center;width:100%;cursor:pointer}.wt-checkbox-box{width:16px;height:16px;border:1.5px solid #94a3b8;border-radius:3px;display:flex;align-items:center;justify-content:center;transition:all .15s}.wt-checkbox-box--checked{background:#3b82f6;border-color:#3b82f6;color:#fff}.wt-badge{display:inline-block;padding:2px 8px;border-radius:9999px;font-size:11px;font-weight:500;line-height:1.4;white-space:nowrap}.wt-progress{display:flex;align-items:center;gap:8px;width:100%;position:relative}.wt-progress-bar{height:6px;border-radius:3px;flex:1;overflow:hidden;background:#e2e8f0}.wt-progress-label{font-size:11px;color:#64748b;min-width:32px;text-align:right}.wt-context-menu{position:fixed;z-index:50;min-width:180px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 24px #00000026;padding:4px 0;font-size:13px}.wt-context-menu-item{display:flex;align-items:center;gap:8px;padding:6px 12px;cursor:pointer;color:#334155}.wt-context-menu-item:hover{background:#f1f5f9}.wt-context-menu-item--disabled{opacity:.4;cursor:not-allowed}.wt-context-menu-item--disabled:hover{background:none}.wt-context-menu-shortcut{margin-left:auto;font-size:11px;color:#94a3b8}.wt-context-menu-separator{height:1px;background:#e2e8f0;margin:4px 0}.wt-fill-handle{position:absolute;width:8px;height:8px;background:var(--wt-focus-border, #3b82f6);border:1px solid #fff;border-radius:1px;cursor:crosshair;z-index:5;pointer-events:auto}.wt-fill-handle:hover{transform:scale(1.3)}.wt-fill-shadow{position:absolute;border:2px dashed var(--wt-focus-border, #3b82f6);background:#3b82f60f;pointer-events:none;z-index:4}.wt-reorder-ghost{position:fixed;padding:4px 12px;background:var(--wt-header-bg, #f8fafc);border:1px solid var(--wt-grid-line, #e2e8f0);border-radius:4px;box-shadow:0 4px 12px #00000026;font-size:var(--wt-header-font-size, 12px);font-weight:500;color:var(--wt-header-text, #475569);pointer-events:none;z-index:100;transform:translate(-50%);opacity:.9}.wt-reorder-indicator{position:absolute;top:0;width:2px;height:100%;background:var(--wt-focus-border, #3b82f6);z-index:10;pointer-events:none}.wt-group-toggle{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border:1px solid #cbd5e1;border-radius:3px;background:#fff;cursor:pointer;font-size:10px;color:#64748b;margin-right:4px;flex-shrink:0}.wt-group-toggle:hover{background:#f1f5f9;border-color:#94a3b8}.wt-row-header-cell:after{content:"";position:absolute;bottom:0;left:0;width:100%;height:4px;cursor:row-resize}.wt-col-header-group{position:absolute;display:flex;align-items:center;justify-content:center;font-size:var(--wt-header-font-size, 12px);font-weight:600;color:var(--wt-header-text, #475569);background:var(--wt-header-bg, #f8fafc);border-right:1px solid var(--wt-grid-line, #e2e8f0);border-bottom:1px solid var(--wt-grid-line, #e2e8f0);-webkit-user-select:none;user-select:none}.wt-pagination{display:flex;align-items:center;gap:8px;padding:6px 12px;background:var(--wt-header-bg, #f8fafc);border-top:1px solid var(--wt-grid-line, #e2e8f0);font-size:12px;color:var(--wt-header-text, #475569);-webkit-user-select:none;user-select:none}.wt-pagination-info{margin-right:auto}.wt-pagination-btn{width:28px;height:28px;display:flex;align-items:center;justify-content:center;border:1px solid var(--wt-grid-line, #e2e8f0);border-radius:4px;background:var(--wt-cell-bg, #fff);color:var(--wt-cell-text, #1e293b);font-size:14px;cursor:pointer;padding:0}.wt-pagination-btn:hover:not(:disabled){background:#e2e8f0}.wt-pagination-btn:disabled{opacity:.3;cursor:not-allowed}.wt-pagination-input{width:48px;height:28px;text-align:center;border:1px solid var(--wt-grid-line, #e2e8f0);border-radius:4px;font-size:12px;outline:none;-moz-appearance:textfield}.wt-pagination-input::-webkit-inner-spin-button,.wt-pagination-input::-webkit-outer-spin-button{-webkit-appearance:none}.wt-loading-overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:50;background:#ffffffb3;display:flex;align-items:center;justify-content:center;pointer-events:all}.wt-loading-spinner{width:32px;height:32px;border:3px solid #e2e8f0;border-top-color:#3b82f6;border-radius:50%;animation:wt-spin .6s linear infinite}@keyframes wt-spin{to{transform:rotate(360deg)}}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { CellData, CellEditor, CellPatch, CellRenderer, SelectionRange, Viewport, WanderTableEvents, WanderTableOptions } from './types/index.js';
|
|
2
|
+
import { DataModel } from './core/DataModel.js';
|
|
3
|
+
import { EventEmitter } from './core/EventEmitter.js';
|
|
4
|
+
import { SelectionModel } from './core/SelectionModel.js';
|
|
5
|
+
import { CommandBus } from './core/CommandBus.js';
|
|
6
|
+
import { ColumnModel } from './columns/ColumnModel.js';
|
|
7
|
+
import { RowModel } from './rows/RowModel.js';
|
|
8
|
+
import { type MenuItemConfig } from './plugins/ContextMenu.js';
|
|
9
|
+
import { RowGroupModel } from './core/RowGroupModel.js';
|
|
10
|
+
import { ViewMapping, type SortDirection, type FilterFn } from './core/ViewMapping.js';
|
|
11
|
+
import { MergeModel, type MergeRange } from './core/MergeModel.js';
|
|
12
|
+
import { PaginationModel } from './core/PaginationModel.js';
|
|
13
|
+
import { type ExportOptions } from './plugins/Export.js';
|
|
14
|
+
export declare class WanderTable extends EventEmitter<WanderTableEvents> {
|
|
15
|
+
readonly data: DataModel;
|
|
16
|
+
readonly selection: SelectionModel;
|
|
17
|
+
readonly columns: ColumnModel;
|
|
18
|
+
readonly rows: RowModel;
|
|
19
|
+
readonly commands: CommandBus;
|
|
20
|
+
readonly viewMapping: ViewMapping;
|
|
21
|
+
readonly merges: MergeModel;
|
|
22
|
+
readonly pagination: PaginationModel;
|
|
23
|
+
readonly rowGroups: RowGroupModel;
|
|
24
|
+
private renderer;
|
|
25
|
+
private rendererRegistry;
|
|
26
|
+
private editorManager;
|
|
27
|
+
private keyboard;
|
|
28
|
+
private clipboard;
|
|
29
|
+
private columnResize;
|
|
30
|
+
private rowResize;
|
|
31
|
+
private contextMenu;
|
|
32
|
+
private autoFit;
|
|
33
|
+
private paginationBar;
|
|
34
|
+
private loadingOverlay;
|
|
35
|
+
private fillHandle;
|
|
36
|
+
private columnReorder;
|
|
37
|
+
private headerRows;
|
|
38
|
+
private theme;
|
|
39
|
+
private options;
|
|
40
|
+
private isDragging;
|
|
41
|
+
private _infiniteScrollHandler;
|
|
42
|
+
private _lazyLoadHandler;
|
|
43
|
+
private _keydownHandler;
|
|
44
|
+
constructor(container: HTMLElement, options?: WanderTableOptions);
|
|
45
|
+
private wireCallbacks;
|
|
46
|
+
/** Override this to customize context menu items */
|
|
47
|
+
contextMenuItems: MenuItemConfig[];
|
|
48
|
+
private buildMenuContext;
|
|
49
|
+
private openContextMenu;
|
|
50
|
+
setCell(row: number, col: number, data: CellData): void;
|
|
51
|
+
getCell(row: number, col: number): CellData | undefined;
|
|
52
|
+
setCellValue(row: number, col: number, value: unknown): void;
|
|
53
|
+
deleteCell(row: number, col: number): void;
|
|
54
|
+
applyPatch(patches: CellPatch[]): void;
|
|
55
|
+
transaction(fn: () => void): void;
|
|
56
|
+
undo(): void;
|
|
57
|
+
redo(): void;
|
|
58
|
+
getSelection(): SelectionRange[];
|
|
59
|
+
getSelectionInfo(): import("./index.js").SelectionInfo;
|
|
60
|
+
setSelection(ranges: SelectionRange[]): void;
|
|
61
|
+
scrollTo(row: number, col: number): void;
|
|
62
|
+
registerRenderer(name: string, renderer: CellRenderer): void;
|
|
63
|
+
registerEditor(name: string, factory: () => CellEditor): void;
|
|
64
|
+
setColumnWidth(col: number, width: number): void;
|
|
65
|
+
setRowHeight(row: number, height: number): void;
|
|
66
|
+
autoFitColumn(col: number): void;
|
|
67
|
+
autoFitRow(row: number): void;
|
|
68
|
+
insertRow(at: number): void;
|
|
69
|
+
insertColumn(at: number): void;
|
|
70
|
+
sort(col: number, direction: SortDirection, compareFn?: (a: unknown, b: unknown) => number): void;
|
|
71
|
+
clearSort(): void;
|
|
72
|
+
getSortState(): import("./index.js").SortState | null;
|
|
73
|
+
setFilter(col: number, fn: FilterFn): void;
|
|
74
|
+
removeFilter(col: number): void;
|
|
75
|
+
clearFilters(): void;
|
|
76
|
+
getActiveFilters(): number[];
|
|
77
|
+
mergeCells(row: number, col: number, rowSpan: number, colSpan: number): void;
|
|
78
|
+
unmergeCells(row: number, col: number): void;
|
|
79
|
+
getMerge(row: number, col: number): MergeRange | null;
|
|
80
|
+
clearMerges(): void;
|
|
81
|
+
addRowGroup(startRow: number, count: number, label?: string, expanded?: boolean): void;
|
|
82
|
+
removeRowGroup(startRow: number): void;
|
|
83
|
+
toggleRowGroup(startRow: number): void;
|
|
84
|
+
expandAllGroups(): void;
|
|
85
|
+
collapseAllGroups(): void;
|
|
86
|
+
exportCSV(options?: ExportOptions): string;
|
|
87
|
+
exportJSON(options?: ExportOptions): object[];
|
|
88
|
+
downloadCSV(filename?: string, options?: ExportOptions): void;
|
|
89
|
+
downloadJSON(filename?: string, options?: ExportOptions): void;
|
|
90
|
+
getViewport(): Viewport;
|
|
91
|
+
refresh(): void;
|
|
92
|
+
destroy(): void;
|
|
93
|
+
private startEditing;
|
|
94
|
+
private deleteSelected;
|
|
95
|
+
private pasteWithUndo;
|
|
96
|
+
private cutWithUndo;
|
|
97
|
+
private execCommand;
|
|
98
|
+
/** Move a column from one index to another, shifting data */
|
|
99
|
+
reorderColumn(fromCol: number, toCol: number): void;
|
|
100
|
+
private expandIfNeeded;
|
|
101
|
+
private isFullRowOrColSelected;
|
|
102
|
+
/** Load row objects into the sparse DataModel using column keys */
|
|
103
|
+
private loadTableData;
|
|
104
|
+
/** Replace all table data (table mode) */
|
|
105
|
+
setTableData(rows: Record<string, unknown>[]): void;
|
|
106
|
+
setLoading(loading: boolean): void;
|
|
107
|
+
get isLoading(): boolean;
|
|
108
|
+
setPage(page: number): void;
|
|
109
|
+
setPageSize(size: number): void;
|
|
110
|
+
getPaginationState(): import("./index.js").PaginationState;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=WanderTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WanderTable.d.ts","sourceRoot":"","sources":["../../src/WanderTable.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColumnModel.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/ColumnModel.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandBus.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/CommandBus.test.ts"],"names":[],"mappings":""}
|