@keenmate/web-grid 1.0.0-rc15 → 1.0.1

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.
@@ -0,0 +1,429 @@
1
+ KEYBOARD NAVIGATION AND SHORTCUTS
2
+ ==================================
3
+ This document covers all keyboard interactions in @keenmate/web-grid:
4
+ cell navigation, editing triggers, row operations, custom shortcuts,
5
+ and the shortcuts help overlay.
6
+
7
+
8
+ NAVIGATION KEYS
9
+ ---------------
10
+ These keys work when a cell is focused but NOT in edit mode (navigate state).
11
+ Arrow keys move one cell at a time. Other keys jump farther.
12
+
13
+ Arrow Up Move focus one row up (same column)
14
+ Arrow Down Move focus one row down (same column)
15
+ Arrow Left Move focus one column left (same row)
16
+ Arrow Right Move focus one column right (same row)
17
+
18
+ Tab Move to next editable column. Wraps to first editable
19
+ column of next row when at the end of a row.
20
+ Shift+Tab Move to previous editable column. Wraps to last editable
21
+ column of previous row when at the start of a row.
22
+
23
+ Home Move to first column in the current row
24
+ End Move to last column in the current row
25
+ Ctrl+Home Move to first cell in the grid (row 0, column 0)
26
+ Ctrl+End Move to last cell in the grid (last row, last column)
27
+
28
+ PageUp Move up ~10 rows (same column)
29
+ PageDown Move down ~10 rows (same column)
30
+ Ctrl+PageUp Move to first row (same column)
31
+ Ctrl+PageDown Move to last row (same column)
32
+
33
+ Enter Move to next row (same column). If Tab was used before
34
+ Enter, the column resets to where Tab traversal started
35
+ (Excel-like behavior).
36
+
37
+ Ctrl+G Open "Go To Row" dialog for jumping to a specific row number
38
+
39
+ Tab traversal tracks a "start column." When you Tab across columns and then
40
+ press Enter, focus moves down to the next row at the column where you started
41
+ Tab traversal. Arrow keys reset this tracking.
42
+
43
+
44
+ EDITING KEYS
45
+ ------------
46
+ These keys start or control cell editing. Behavior depends on the column's
47
+ editor type (text, number, checkbox, select, combobox, autocomplete, date,
48
+ custom) and the grid's editTrigger setting.
49
+
50
+ Enter Start editing for dropdown/date editors (if
51
+ shouldOpenDropdownOnEnter is true). For text/number
52
+ editors, Enter navigates down (does not start editing).
53
+ F2 Start editing the focused cell. For dropdown editors,
54
+ also opens the dropdown. For date editors, opens the
55
+ date picker. For custom editors, calls cellEditCallback.
56
+ Space Toggle checkbox value. For dropdown/date/custom editors,
57
+ starts editing and opens the respective picker/editor.
58
+ Escape If editing with dropdown/datepicker open: first press
59
+ closes the dropdown/datepicker. Second press cancels the
60
+ edit and returns to navigate mode. If no dropdown is open,
61
+ first press cancels the edit. If not editing, clears focus.
62
+ Delete Clear cell content (sets value to null) for editable cells.
63
+ Ctrl+C Copy focused cell value (or cell selection) to clipboard.
64
+
65
+ Any printable Start editing with that character as initial input. For
66
+ character text editors, the character replaces the cell value. For
67
+ combobox/autocomplete, it becomes the initial search query.
68
+ For number editors, only digits/dot/minus are accepted.
69
+
70
+ When a dropdown is open during editing:
71
+ Arrow Up/Down Navigate through dropdown options
72
+ PageUp/PageDown Jump ~10 options in the dropdown
73
+ Home/End Jump to first/last option (select/combobox only;
74
+ autocomplete lets the browser handle cursor movement)
75
+ Enter Select the highlighted option and commit
76
+ Tab Select the highlighted option and move to next cell
77
+ Escape Close dropdown (first press), cancel edit (second press)
78
+
79
+
80
+ ROW OPERATION KEYS
81
+ ------------------
82
+ These built-in keys operate on the currently focused row.
83
+
84
+ Ctrl+Delete Fire the onrowdelete callback and dispatch a 'rowdelete'
85
+ CustomEvent. Does NOT delete the row automatically.
86
+ The consumer must handle deletion in the callback.
87
+
88
+ grid.onrowdelete = ({ rowIndex, row }) => {
89
+ grid.items = grid.items.filter((_, i) => i !== rowIndex)
90
+ }
91
+
92
+ Row move operations (Ctrl+Up to move row up, Ctrl+Down to move row down)
93
+ are available as predefined toolbar items ('moveUp', 'moveDown'), not as
94
+ built-in keyboard shortcuts. To add them as keyboard shortcuts, use
95
+ rowShortcuts (see below).
96
+
97
+
98
+ ROW SHORTCUTS
99
+ -------------
100
+ rowShortcuts defines keyboard shortcuts that operate on a single focused row.
101
+ Each shortcut requires key, id, label, and action. The action receives a
102
+ context with the row data and position.
103
+
104
+ Type definition:
105
+
106
+ type RowShortcut<T> = {
107
+ key: string // Key combo string
108
+ id: string // Unique identifier
109
+ label: string // Display label for help overlay
110
+ action: (ctx: ShortcutContext<T>) => void // Handler function
111
+ disabled?: boolean | ((ctx) => boolean) // Optionally disable
112
+ }
113
+
114
+ type ShortcutContext<T> = {
115
+ row: T // The data object for the focused row
116
+ rowIndex: number // Index in displayItems
117
+ colIndex: number // Currently focused column index
118
+ column: Column<T> // Column definition at colIndex
119
+ cellValue: unknown // Raw value of the focused cell
120
+ }
121
+
122
+ Example:
123
+
124
+ grid.rowShortcuts = [
125
+ {
126
+ key: 'Delete',
127
+ id: 'delete-row',
128
+ label: 'Delete row',
129
+ action: (ctx) => {
130
+ grid.items = grid.items.filter((_, i) => i !== ctx.rowIndex)
131
+ }
132
+ },
133
+ {
134
+ key: 'Ctrl+D',
135
+ id: 'duplicate-row',
136
+ label: 'Duplicate row',
137
+ action: (ctx) => {
138
+ const copy = { ...ctx.row, id: Date.now() }
139
+ grid.items = [
140
+ ...grid.items.slice(0, ctx.rowIndex + 1),
141
+ copy,
142
+ ...grid.items.slice(ctx.rowIndex + 1)
143
+ ]
144
+ }
145
+ },
146
+ {
147
+ key: 'Ctrl+Up',
148
+ id: 'move-up',
149
+ label: 'Move row up',
150
+ action: (ctx) => {
151
+ if (ctx.rowIndex === 0) return
152
+ const items = [...grid.items]
153
+ ;[items[ctx.rowIndex - 1], items[ctx.rowIndex]] =
154
+ [items[ctx.rowIndex], items[ctx.rowIndex - 1]]
155
+ grid.items = items
156
+ }
157
+ },
158
+ {
159
+ key: 'Shift+F2',
160
+ id: 'edit-details',
161
+ label: 'Edit in modal',
162
+ disabled: (ctx) => ctx.row.locked,
163
+ action: (ctx) => openEditModal(ctx.row)
164
+ }
165
+ ]
166
+
167
+ Shortcuts are checked before built-in key handlers. If a shortcut matches,
168
+ it consumes the event (preventDefault) and the built-in behavior is skipped.
169
+
170
+ Shortcuts also work on hovered rows when the row toolbar is visible. The grid
171
+ sets up document-level keydown listeners for the toolbar and inline toolbar
172
+ modes, so shortcuts fire even without cell focus.
173
+
174
+
175
+ RANGE SHORTCUTS
176
+ ---------------
177
+ rangeShortcuts defines keyboard shortcuts that operate on multiple selected
178
+ rows or a selected cell range. They work with both row selection (clicking
179
+ row number column) and cell range selection (click+drag or Shift+click).
180
+
181
+ Type definition:
182
+
183
+ type RangeShortcut<T> = {
184
+ key: string // Key combo string
185
+ id: string // Unique identifier
186
+ label: string // Display label
187
+ action: (ctx: RangeShortcutContext<T>) => void // Handler function
188
+ disabled?: boolean | ((ctx) => boolean) // Optionally disable
189
+ }
190
+
191
+ type RangeShortcutContext<T> = {
192
+ // Always present (populated for row selection, empty arrays for cell range)
193
+ rows: T[] // Selected row data objects (display order)
194
+ rowIndices: number[] // Selected row indices (sorted ascending)
195
+
196
+ // Present only when a cell range is selected
197
+ cellRange?: CellRange // { startRowIndex, startColIndex, endRowIndex,
198
+ // endColIndex, startField, endField }
199
+ cells?: Array<{ // Individual cells in the selected range
200
+ row: T
201
+ rowIndex: number
202
+ colIndex: number
203
+ field: string
204
+ value: unknown
205
+ }>
206
+ }
207
+
208
+ Example:
209
+
210
+ grid.rangeShortcuts = [
211
+ {
212
+ key: 'Delete',
213
+ id: 'delete-selected',
214
+ label: 'Delete selected rows',
215
+ action: (ctx) => {
216
+ const indexSet = new Set(ctx.rowIndices)
217
+ grid.items = grid.items.filter((_, i) => !indexSet.has(i))
218
+ }
219
+ },
220
+ {
221
+ key: 'Ctrl+E',
222
+ id: 'export-selection',
223
+ label: 'Export selection',
224
+ action: (ctx) => {
225
+ if (ctx.cells) {
226
+ // Cell range selected - export cell data
227
+ exportCells(ctx.cells)
228
+ } else {
229
+ // Row selection - export full rows
230
+ exportRows(ctx.rows)
231
+ }
232
+ }
233
+ }
234
+ ]
235
+
236
+ Range shortcuts are checked in two places:
237
+ 1. On the focused cell's keydown handler (when rows are selected)
238
+ 2. On the grid container's keydown handler (for cell range and row/column
239
+ selection when no individual cell has focus)
240
+
241
+ Built-in range keys (no rangeShortcuts needed):
242
+ Ctrl+C Copy selected rows/columns/cells to clipboard as TSV
243
+ Escape Clear the current selection
244
+
245
+
246
+ SHORTCUTS HELP OVERLAY
247
+ ----------------------
248
+ When isShortcutsHelpVisible is true and rowShortcuts has entries, the grid
249
+ displays a small info icon. Hovering or focusing the icon reveals an overlay
250
+ listing all registered shortcuts with their key combinations and labels.
251
+
252
+ Properties:
253
+
254
+ isShortcutsHelpVisible boolean, default false
255
+ Show the shortcuts help icon
256
+
257
+ shortcutsHelpPosition 'top-right' (default) or 'top-left'
258
+ Where to place the icon in the grid
259
+
260
+ shortcutsHelpContentCallback () => string
261
+ Return custom HTML to display above the
262
+ shortcuts list in the overlay
263
+
264
+ Example:
265
+
266
+ grid.isShortcutsHelpVisible = true
267
+ grid.shortcutsHelpPosition = 'top-right'
268
+
269
+ grid.shortcutsHelpContentCallback = () => {
270
+ return '<p>Use these shortcuts when a row is focused:</p>'
271
+ }
272
+
273
+
274
+ KEY FORMAT
275
+ ----------
276
+ Key combination strings use '+' as a separator between modifiers and the
277
+ main key. Case-insensitive for modifiers, case-insensitive matching for
278
+ letters.
279
+
280
+ Modifiers:
281
+ Ctrl (or Control)
282
+ Shift
283
+ Alt
284
+ Meta (or Cmd, Command)
285
+
286
+ Examples:
287
+ 'Delete' Delete key alone
288
+ 'Ctrl+D' Ctrl and D
289
+ 'Ctrl+Alt+E' Ctrl, Alt, and E
290
+ 'Shift+F2' Shift and F2
291
+ 'Ctrl+Up' Ctrl and Arrow Up (use 'ArrowUp' for the key name)
292
+ 'Ctrl+Shift+Z' Ctrl, Shift, and Z
293
+
294
+ Note: The key name in the combo is matched against KeyboardEvent.key. For
295
+ arrow keys, you can use either 'Up' or 'ArrowUp' since matching is done via
296
+ e.key.toLowerCase(). The parsed combo stores the key as provided; matching
297
+ compares lowercase versions.
298
+
299
+ Under the hood, parseKeyCombo() splits on '+', identifies modifiers (ctrl,
300
+ shift, alt, meta), and the remaining part becomes the key. matchesKeyCombo()
301
+ checks that all modifier flags match and the key matches (case-insensitive).
302
+
303
+
304
+ NAVIGATION BEHAVIOR BY EDIT MODE
305
+ ---------------------------------
306
+ The editTrigger property (grid-level or per-column) changes how keyboard
307
+ navigation interacts with editing. There are five modes: navigate, always,
308
+ click, dblclick, and button.
309
+
310
+ NAVIGATE MODE (editTrigger: 'navigate')
311
+ This is the mode set by mode: 'excel'. Cells display values. Arrow keys
312
+ move between cells. Typing starts editing with the typed character. F2
313
+ starts editing. Enter/Tab commit edits and move focus.
314
+
315
+ When not editing:
316
+ - Arrow keys move focus between cells
317
+ - Tab/Shift+Tab move between editable cells only
318
+ - Enter moves down (or starts edit for dropdown if configured)
319
+ - F2 starts edit
320
+ - Space toggles checkbox / opens dropdown / opens datepicker
321
+ - Printable characters start edit with that character
322
+ - Delete clears cell value
323
+
324
+ When editing:
325
+ - Arrow Up/Down for text editors: commit and navigate (pipeline mode)
326
+ - Arrow Left/Right for text editors: cursor movement (native browser)
327
+ - Arrow Left/Right for dropdown editors: cancel edit and navigate
328
+ - Tab commits and moves to next editable cell
329
+ - Enter commits and moves down
330
+ - Escape cancels edit (two-phase if dropdown is open)
331
+
332
+ ALWAYS MODE (editTrigger: 'always')
333
+ This is the mode set by mode: 'input-matrix'. All cells render as editors
334
+ permanently. Focus moves between editor inputs directly.
335
+
336
+ - Tab/Shift+Tab commit current cell and move to next/previous editor
337
+ - Enter commits and moves to next row
338
+ - Arrow Up/Down commit and move up/down
339
+ - Arrow Left/Right are handled by the input (cursor movement) for text
340
+ editors; for dropdown editors, they navigate options when open
341
+ - Escape closes dropdown (first press) or clears focus (second press)
342
+ - The grid uses the action pipeline exclusively in this mode
343
+
344
+ CLICK MODE (editTrigger: 'click')
345
+ Single click on a cell starts editing. Keyboard navigation works the same
346
+ as navigate mode when not editing.
347
+
348
+ - Click starts editing immediately
349
+ - While not editing, all navigation keys work normally
350
+ - While editing, same behavior as navigate mode editing
351
+
352
+ DBLCLICK MODE (editTrigger: 'dblclick')
353
+ Double-click on a cell starts editing. This is the default editTrigger.
354
+
355
+ - Double-click starts editing
356
+ - While not editing, all navigation keys work normally
357
+ - While editing, same behavior as navigate mode editing
358
+ - In navigate mode, double-click also starts editing
359
+
360
+ BUTTON MODE (editTrigger: 'button')
361
+ Editing is only triggered by the edit button (isEditButtonVisible: true).
362
+ Keyboard navigation works but does not start editing.
363
+
364
+ READ-ONLY (isEditable: false or mode: 'read-only')
365
+ Navigation keys work normally (arrows, Tab, Home, End, PageUp, PageDown).
366
+ No editing keys function. Ctrl+C copies. Cell selection works if enabled.
367
+
368
+
369
+ EDITOR-SPECIFIC NAVIGATION
370
+ ---------------------------
371
+ Different editor types handle keys differently during editing:
372
+
373
+ TEXT / NUMBER EDITORS:
374
+ - Arrow Left/Right: cursor movement within the input (native)
375
+ - Arrow Up/Down: commit edit and navigate (navigate/click/dblclick modes)
376
+ - Enter: commit and move down
377
+ - Tab: commit and move to next editable cell
378
+ - Escape: cancel edit
379
+
380
+ CHECKBOX EDITOR:
381
+ - Space: toggle checked state
382
+ - Arrow keys: consumed (noop) while in edit mode
383
+ - Enter: commit and move down
384
+ - Tab: commit and move to next cell
385
+ - isCheckboxAlwaysEditable: when true, Space toggles checkbox even in
386
+ navigate mode without entering edit state
387
+
388
+ SELECT / COMBOBOX / AUTOCOMPLETE EDITORS:
389
+ When dropdown is CLOSED:
390
+ - Arrow Left/Right: cancel edit and navigate to adjacent cell
391
+ (navigate mode only)
392
+ - Space/F2/Enter: open the dropdown
393
+ - Typing: for select, type-to-filter (keys accumulate as filter text,
394
+ Backspace removes last character)
395
+
396
+ When dropdown is OPEN:
397
+ - Arrow Up/Down: navigate through options (skip disabled)
398
+ - PageUp/PageDown: jump ~10 options
399
+ - Home/End: first/last option (select/combobox only)
400
+ - Enter: select highlighted option, commit, move down
401
+ - Tab: select highlighted option, commit, move to next cell
402
+ - Escape: close dropdown (first press); cancel edit (second press).
403
+ For combobox/autocomplete, first Escape restores original display
404
+ value if input was modified.
405
+ - Arrow Left/Right: for autocomplete, cursor movement in input.
406
+ For select/combobox, consumed (noop).
407
+
408
+ DATE EDITOR:
409
+ - When datepicker is open, Arrow/PageUp/PageDown/Home/End/Enter/Escape/Tab
410
+ are handled by the datepicker component, not the grid
411
+ - F2 or Space from navigate mode: start edit and open datepicker
412
+ - Enter from navigate mode: start edit and open datepicker
413
+
414
+ CUSTOM EDITOR:
415
+ - F2 or Space from navigate mode: start edit and call cellEditCallback
416
+ - The custom editor receives commit() and cancel() functions
417
+ - Grid does not handle keydown inside custom editors
418
+
419
+
420
+ CLIPBOARD KEYS
421
+ --------------
422
+ Ctrl+C Copy focused cell, selected rows, selected columns, or
423
+ cell range to clipboard as TSV (tab-separated values).
424
+ Compatible with Excel paste.
425
+ Ctrl+V Paste TSV data from clipboard into the grid starting at
426
+ the focused cell. Multi-cell paste supported.
427
+
428
+ shouldCopyWithHeaders (boolean, default false): when true, column headers
429
+ are included as the first row when copying cell selections.
@@ -0,0 +1,231 @@
1
+ PUBLIC METHODS
2
+ ==============
3
+ @keenmate/web-grid - Complete reference for all public methods.
4
+
5
+
6
+ All methods are called on the <web-grid> DOM element:
7
+ const grid = document.getElementById('grid')
8
+ grid.focusCell(0, 1)
9
+
10
+
11
+ ----------------------------------------------------------------------
12
+ FOCUS AND EDITING
13
+ ----------------------------------------------------------------------
14
+
15
+ focusCell(rowIndex: number, colIndex: number): void
16
+ Programmatically focus a cell. In navigate mode (editTrigger='navigate'),
17
+ this sets the blue focus border on the specified cell. Does not start
18
+ editing.
19
+
20
+ startEditing(rowIndex: number, colIndex: number): void
21
+ Programmatically start editing a cell. The cell must be editable
22
+ (column.isEditable = true, row not locked). Opens the appropriate
23
+ editor for the column's editor type.
24
+
25
+ openCustomEditor(rowIndex: number, colIndex: number): void
26
+ Open the custom editor for a cell with editor: 'custom'. Invokes the
27
+ column's cellEditCallback with { value, row, rowIndex, field, commit,
28
+ cancel }.
29
+
30
+
31
+ ----------------------------------------------------------------------
32
+ DRAFT MANAGEMENT
33
+ ----------------------------------------------------------------------
34
+ Drafts are uncommitted cell edits. When a user edits a cell, the new value
35
+ is stored in a draft row until committed. Invalid values remain in the
36
+ draft but are flagged with validation errors.
37
+
38
+ getRowDraft(rowIndex: number): T | undefined
39
+ Get the draft (edited but uncommitted values) for a row. Returns
40
+ undefined if the row has no draft.
41
+
42
+ hasRowDraft(rowIndex: number): boolean
43
+ Check if a row has any uncommitted changes.
44
+
45
+ discardRowDraft(rowIndex: number): void
46
+ Discard all draft changes for a specific row. Reverts cells to their
47
+ original values.
48
+
49
+ getDraftRowIndices(): number[]
50
+ Get indices of all rows that have drafts (uncommitted changes).
51
+
52
+ discardAllDrafts(): void
53
+ Discard all draft changes across all rows. Reverts every edited cell
54
+ to its original value.
55
+
56
+
57
+ ----------------------------------------------------------------------
58
+ VALIDATION
59
+ ----------------------------------------------------------------------
60
+
61
+ isCellInvalid(rowIndex: number, field: string): boolean
62
+ Check if a cell has a validation error (from beforeCommitCallback or
63
+ external invalidCells).
64
+
65
+ getCellValidationError(rowIndex: number, field: string): string | null
66
+ Get the validation error message for a cell. Returns null if the cell
67
+ is valid.
68
+
69
+ canEditCell(rowIndex: number, field: string): boolean
70
+ Check if a cell can be edited. Considers:
71
+ - Column isEditable setting
72
+ - Row locking state and lockedEditBehavior
73
+ - canEditLockedCallback result
74
+
75
+
76
+ ----------------------------------------------------------------------
77
+ ROW IDENTIFICATION
78
+ ----------------------------------------------------------------------
79
+ Requires idValueMember or idValueCallback to be configured.
80
+
81
+ getRowId(row: T): unknown | undefined
82
+ Get the unique ID of a row using the configured idValueMember or
83
+ idValueCallback.
84
+
85
+ findRowById(id: unknown): { row: T, index: number } | null
86
+ Find a row by its unique ID. Returns the row object and its current
87
+ index, or null if not found.
88
+
89
+
90
+ ----------------------------------------------------------------------
91
+ ROW UPDATES
92
+ ----------------------------------------------------------------------
93
+ For live data updates (WebSocket, polling). Requires row identification.
94
+
95
+ updateRowById(id: unknown, newData: Partial<T>): boolean
96
+ Merge partial data into an existing row. Only the provided properties
97
+ are updated; other properties remain unchanged. Returns true if the
98
+ row was found and updated.
99
+
100
+ grid.updateRowById(42, { status: 'approved', updatedAt: new Date() })
101
+
102
+ replaceRowById(id: unknown, newRow: T): boolean
103
+ Replace an entire row object by ID. Returns true if the row was found
104
+ and replaced.
105
+
106
+ grid.replaceRowById(42, newRowData)
107
+
108
+
109
+ ----------------------------------------------------------------------
110
+ ROW LOCKING
111
+ ----------------------------------------------------------------------
112
+ Query methods accept either a row object or a row ID.
113
+ External lock methods require row identification (idValueMember or
114
+ idValueCallback).
115
+
116
+ isRowLocked(rowOrId: T | unknown): boolean
117
+ Check if a row is locked (from any source: property, callback, or
118
+ external).
119
+
120
+ getRowLockInfo(rowOrId: T | unknown): RowLockInfo | null
121
+ Get lock information for a row. Returns null if not locked.
122
+
123
+ lockRowById(id: unknown, lockerInfo?: RowLockInfo): boolean
124
+ Lock a row externally. Returns true if the row was found. Fires
125
+ onrowlockchange event.
126
+
127
+ grid.lockRowById(42, {
128
+ isLocked: true,
129
+ lockedBy: 'Jane',
130
+ lockedAt: new Date()
131
+ })
132
+
133
+ unlockRowById(id: unknown): boolean
134
+ Unlock an externally locked row. Returns true if the row was found
135
+ and was locked.
136
+
137
+ getExternalLocks(): Map<unknown, RowLockInfo>
138
+ Get all external locks as a Map keyed by row ID.
139
+
140
+ clearExternalLocks(): void
141
+ Remove all external locks at once.
142
+
143
+
144
+ ----------------------------------------------------------------------
145
+ ROW SELECTION
146
+ ----------------------------------------------------------------------
147
+
148
+ selectRow(rowIndex: number, mode?: 'replace' | 'toggle' | 'range'): void
149
+ Select a row.
150
+ 'replace' (default): Clear existing selection, select this row
151
+ 'toggle': Toggle this row's selection without affecting others
152
+ 'range': Select all rows from last selected to this row
153
+
154
+ selectRowRange(fromIndex: number, toIndex: number): void
155
+ Select a contiguous range of rows (inclusive).
156
+
157
+ clearSelection(): void
158
+ Clear all row selections.
159
+
160
+ isRowSelected(rowIndex: number): boolean
161
+ Check if a specific row is selected.
162
+
163
+ getSelectedRowsData(): T[]
164
+ Get the data objects for all selected rows.
165
+
166
+ copySelectedRowsToClipboard(): Promise<boolean>
167
+ Copy selected rows as TSV (tab-separated values) to the clipboard.
168
+ Returns true if successful. TSV format is compatible with Excel paste.
169
+
170
+
171
+ ----------------------------------------------------------------------
172
+ CELL SELECTION
173
+ ----------------------------------------------------------------------
174
+
175
+ selectCellRange(range: CellRange): void
176
+ Select a rectangular cell range programmatically.
177
+ CellRange: { startRowIndex, startColIndex, endRowIndex, endColIndex,
178
+ startField, endField }
179
+
180
+ clearCellSelection(): void
181
+ Clear the current cell range selection.
182
+
183
+ getSelectedCells(): Array<{ row: T, rowIndex: number, colIndex: number, field: string, value: unknown }>
184
+ Get data for all cells in the current selection.
185
+
186
+ copyCellSelectionToClipboard(): Promise<boolean>
187
+ Copy selected cells as TSV to clipboard. If shouldCopyWithHeaders is
188
+ true, column headers are included as the first row. Returns true if
189
+ successful.
190
+
191
+
192
+ ----------------------------------------------------------------------
193
+ COLUMN WIDTH
194
+ ----------------------------------------------------------------------
195
+
196
+ setColumnWidth(field: string, width: string): void
197
+ Set the width of a single column.
198
+
199
+ grid.setColumnWidth('name', '200px')
200
+
201
+ setColumnWidths(widths: ColumnWidthState[]): void
202
+ Set widths for multiple columns at once.
203
+ ColumnWidthState: { field: string, width: string }
204
+
205
+ grid.setColumnWidths([
206
+ { field: 'name', width: '200px' },
207
+ { field: 'email', width: '300px' }
208
+ ])
209
+
210
+ getColumnWidthsState(): ColumnWidthState[]
211
+ Get current widths of all columns. Returns array of { field, width }.
212
+ Same format used by localStorage persistence and setColumnWidths.
213
+
214
+
215
+ ----------------------------------------------------------------------
216
+ COLUMN ORDER
217
+ ----------------------------------------------------------------------
218
+
219
+ setColumnOrder(order: ColumnOrderState[]): void
220
+ Set column display order.
221
+ ColumnOrderState: { field: string, order: number }
222
+
223
+ grid.setColumnOrder([
224
+ { field: 'name', order: 0 },
225
+ { field: 'email', order: 1 },
226
+ { field: 'id', order: 2 }
227
+ ])
228
+
229
+ getColumnOrderState(): ColumnOrderState[]
230
+ Get current column order. Returns array of { field, order }.
231
+ Same format used by localStorage persistence and setColumnOrder.