@toolbox-web/grid 0.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.
- package/all.d.ts +3518 -0
- package/all.js +3762 -0
- package/all.js.map +1 -0
- package/index.d.ts +2367 -0
- package/index.js +3105 -0
- package/index.js.map +1 -0
- package/lib/plugins/clipboard/index.js +365 -0
- package/lib/plugins/clipboard/index.js.map +1 -0
- package/lib/plugins/column-virtualization/index.js +255 -0
- package/lib/plugins/column-virtualization/index.js.map +1 -0
- package/lib/plugins/context-menu/index.js +341 -0
- package/lib/plugins/context-menu/index.js.map +1 -0
- package/lib/plugins/export/index.js +305 -0
- package/lib/plugins/export/index.js.map +1 -0
- package/lib/plugins/filtering/index.js +759 -0
- package/lib/plugins/filtering/index.js.map +1 -0
- package/lib/plugins/grouping-columns/index.js +283 -0
- package/lib/plugins/grouping-columns/index.js.map +1 -0
- package/lib/plugins/grouping-rows/index.js +494 -0
- package/lib/plugins/grouping-rows/index.js.map +1 -0
- package/lib/plugins/master-detail/index.js +303 -0
- package/lib/plugins/master-detail/index.js.map +1 -0
- package/lib/plugins/multi-sort/index.js +270 -0
- package/lib/plugins/multi-sort/index.js.map +1 -0
- package/lib/plugins/pinned-columns/index.js +221 -0
- package/lib/plugins/pinned-columns/index.js.map +1 -0
- package/lib/plugins/pinned-rows/index.js +459 -0
- package/lib/plugins/pinned-rows/index.js.map +1 -0
- package/lib/plugins/pivot/index.js +326 -0
- package/lib/plugins/pivot/index.js.map +1 -0
- package/lib/plugins/reorder/index.js +260 -0
- package/lib/plugins/reorder/index.js.map +1 -0
- package/lib/plugins/selection/index.js +426 -0
- package/lib/plugins/selection/index.js.map +1 -0
- package/lib/plugins/server-side/index.js +241 -0
- package/lib/plugins/server-side/index.js.map +1 -0
- package/lib/plugins/tree/index.js +383 -0
- package/lib/plugins/tree/index.js.map +1 -0
- package/lib/plugins/undo-redo/index.js +289 -0
- package/lib/plugins/undo-redo/index.js.map +1 -0
- package/lib/plugins/visibility/index.js +430 -0
- package/lib/plugins/visibility/index.js.map +1 -0
- package/package.json +53 -0
- package/themes/dg-theme-contrast.css +43 -0
- package/themes/dg-theme-large.css +54 -0
- package/themes/dg-theme-standard.css +19 -0
- package/themes/dg-theme-vibrant.css +16 -0
- package/umd/grid.all.umd.js +660 -0
- package/umd/grid.all.umd.js.map +1 -0
- package/umd/grid.umd.js +105 -0
- package/umd/grid.umd.js.map +1 -0
- package/umd/plugins/clipboard.umd.js +9 -0
- package/umd/plugins/clipboard.umd.js.map +1 -0
- package/umd/plugins/column-virtualization.umd.js +2 -0
- package/umd/plugins/column-virtualization.umd.js.map +1 -0
- package/umd/plugins/context-menu.umd.js +53 -0
- package/umd/plugins/context-menu.umd.js.map +1 -0
- package/umd/plugins/export.umd.js +14 -0
- package/umd/plugins/export.umd.js.map +1 -0
- package/umd/plugins/filtering.umd.js +175 -0
- package/umd/plugins/filtering.umd.js.map +1 -0
- package/umd/plugins/grouping-columns.umd.js +29 -0
- package/umd/plugins/grouping-columns.umd.js.map +1 -0
- package/umd/plugins/grouping-rows.umd.js +40 -0
- package/umd/plugins/grouping-rows.umd.js.map +1 -0
- package/umd/plugins/master-detail.umd.js +27 -0
- package/umd/plugins/master-detail.umd.js.map +1 -0
- package/umd/plugins/multi-sort.umd.js +26 -0
- package/umd/plugins/multi-sort.umd.js.map +1 -0
- package/umd/plugins/pinned-columns.umd.js +2 -0
- package/umd/plugins/pinned-columns.umd.js.map +1 -0
- package/umd/plugins/pinned-rows.umd.js +73 -0
- package/umd/plugins/pinned-rows.umd.js.map +1 -0
- package/umd/plugins/pivot.umd.js +8 -0
- package/umd/plugins/pivot.umd.js.map +1 -0
- package/umd/plugins/reorder.umd.js +31 -0
- package/umd/plugins/reorder.umd.js.map +1 -0
- package/umd/plugins/selection.umd.js +34 -0
- package/umd/plugins/selection.umd.js.map +1 -0
- package/umd/plugins/server-side.umd.js +2 -0
- package/umd/plugins/server-side.umd.js.map +1 -0
- package/umd/plugins/tree.umd.js +11 -0
- package/umd/plugins/tree.umd.js.map +1 -0
- package/umd/plugins/undo-redo.umd.js +2 -0
- package/umd/plugins/undo-redo.umd.js.map +1 -0
- package/umd/plugins/visibility.umd.js +94 -0
- package/umd/plugins/visibility.umd.js.map +1 -0
package/all.d.ts
ADDED
|
@@ -0,0 +1,3518 @@
|
|
|
1
|
+
/** Fired when keyboard navigation or programmatic focus changes active cell. */
|
|
2
|
+
export declare interface ActivateCellDetail {
|
|
3
|
+
/** Zero-based row index now focused. */
|
|
4
|
+
row: number;
|
|
5
|
+
/** Zero-based column index now focused. */
|
|
6
|
+
col: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for an aggregation row (footer/header row with computed values).
|
|
11
|
+
* Replaces the core FooterRowConfig functionality.
|
|
12
|
+
*/
|
|
13
|
+
declare interface AggregationRowConfig {
|
|
14
|
+
/** Optional identifier (useful for diffing or targeted updates) */
|
|
15
|
+
id?: string;
|
|
16
|
+
/** Position: 'top' renders above grid body, 'bottom' renders below (default: 'bottom') */
|
|
17
|
+
position?: 'top' | 'bottom';
|
|
18
|
+
/** If true, row rendered as single spanning cell with label */
|
|
19
|
+
fullWidth?: boolean;
|
|
20
|
+
/** Label when in fullWidth mode */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** Static or computed cell values keyed by field */
|
|
23
|
+
cells?: Record<string, unknown | string | ((rows: unknown[], field: string, column?: ColumnConfig) => unknown)>;
|
|
24
|
+
/** Per-field aggregator override; string maps to registered aggregator key */
|
|
25
|
+
aggregators?: Record<string, AggregatorRef_3>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Aggregators Core Registry
|
|
30
|
+
*
|
|
31
|
+
* Provides a central registry for aggregator functions.
|
|
32
|
+
* Built-in aggregators are provided by default.
|
|
33
|
+
* Plugins can register additional aggregators.
|
|
34
|
+
*
|
|
35
|
+
* The registry is exposed as a singleton object that can be accessed:
|
|
36
|
+
* - By ES module imports: import { aggregatorRegistry } from '@toolbox-web/grid'
|
|
37
|
+
* - By UMD/CDN: TbwGrid.aggregatorRegistry
|
|
38
|
+
* - By plugins via context: ctx.aggregatorRegistry
|
|
39
|
+
*/
|
|
40
|
+
declare type AggregatorFn = (rows: any[], field: string, column?: any) => any;
|
|
41
|
+
|
|
42
|
+
/** Map of field names to aggregator references */
|
|
43
|
+
declare type AggregatorMap = Record<string, AggregatorRef_2>;
|
|
44
|
+
|
|
45
|
+
export declare type AggregatorRef = string | ((rows: any[], field: string, column?: any) => any);
|
|
46
|
+
|
|
47
|
+
declare type AggregatorRef_2 = string | AggregatorFn;
|
|
48
|
+
|
|
49
|
+
/** Aggregator reference - string key for built-in or custom function */
|
|
50
|
+
declare type AggregatorRef_3 = string | ((rows: unknown[], field: string, column?: ColumnConfig) => unknown);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Base contract for a column. Public; kept intentionally lean so host apps can extend via intersection types.
|
|
54
|
+
* Prefer adding optional properties here only when broadly useful to most grids.
|
|
55
|
+
*/
|
|
56
|
+
export declare interface BaseColumnConfig<TRow = any, TValue = any> {
|
|
57
|
+
/** Unique field key referencing property in row objects */
|
|
58
|
+
field: keyof TRow & string;
|
|
59
|
+
/** Visible header label; defaults to capitalized field */
|
|
60
|
+
header?: string;
|
|
61
|
+
/** Column data type; inferred if omitted */
|
|
62
|
+
type?: PrimitiveColumnType;
|
|
63
|
+
/** Column width in pixels; fixed size (no flexibility) */
|
|
64
|
+
width?: string | number;
|
|
65
|
+
/** Minimum column width in pixels (stretch mode only); when set, column uses minmax(minWidth, 1fr) */
|
|
66
|
+
minWidth?: number;
|
|
67
|
+
/** Whether column can be sorted */
|
|
68
|
+
sortable?: boolean;
|
|
69
|
+
/** Whether column can be resized by user */
|
|
70
|
+
resizable?: boolean;
|
|
71
|
+
/** Optional custom comparator for sorting (a,b) -> number */
|
|
72
|
+
sortComparator?: (a: TValue, b: TValue, rowA: TRow, rowB: TRow) => number;
|
|
73
|
+
/** Whether the field is editable (enables editors) */
|
|
74
|
+
editable?: boolean;
|
|
75
|
+
/** Optional custom editor factory or element tag name */
|
|
76
|
+
editor?: ColumnEditorSpec<TRow, TValue>;
|
|
77
|
+
/** For select/typeahead types - available options */
|
|
78
|
+
options?: Array<{
|
|
79
|
+
label: string;
|
|
80
|
+
value: any;
|
|
81
|
+
}> | (() => Array<{
|
|
82
|
+
label: string;
|
|
83
|
+
value: any;
|
|
84
|
+
}>);
|
|
85
|
+
/** For select/typeahead - allow multi select */
|
|
86
|
+
multi?: boolean;
|
|
87
|
+
/** Optional formatter */
|
|
88
|
+
format?: (value: TValue, row: TRow) => string;
|
|
89
|
+
/** Arbitrary extra metadata */
|
|
90
|
+
meta?: Record<string, any>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Abstract base class for all grid plugins.
|
|
95
|
+
*
|
|
96
|
+
* @template TConfig - Configuration type for the plugin
|
|
97
|
+
*/
|
|
98
|
+
export declare abstract class BaseGridPlugin<TConfig = unknown> {
|
|
99
|
+
/** Unique plugin identifier (derived from class name by default) */
|
|
100
|
+
abstract readonly name: string;
|
|
101
|
+
/** Plugin version - override in subclass if needed */
|
|
102
|
+
readonly version: string;
|
|
103
|
+
/** CSS styles to inject into the grid's shadow DOM */
|
|
104
|
+
readonly styles?: string;
|
|
105
|
+
/** Custom cell renderers keyed by type name */
|
|
106
|
+
readonly cellRenderers?: Record<string, CellRenderer>;
|
|
107
|
+
/** Custom header renderers keyed by type name */
|
|
108
|
+
readonly headerRenderers?: Record<string, HeaderRenderer>;
|
|
109
|
+
/** Custom cell editors keyed by type name */
|
|
110
|
+
readonly cellEditors?: Record<string, CellEditor>;
|
|
111
|
+
/** The grid instance this plugin is attached to */
|
|
112
|
+
protected grid: GridElement_2;
|
|
113
|
+
/** Plugin configuration - merged with defaults in attach() */
|
|
114
|
+
protected config: TConfig;
|
|
115
|
+
/** User-provided configuration from constructor */
|
|
116
|
+
private readonly userConfig;
|
|
117
|
+
/**
|
|
118
|
+
* Default configuration - subclasses should override this getter.
|
|
119
|
+
* Note: This must be a getter (not property initializer) for proper inheritance
|
|
120
|
+
* since property initializers run after parent constructor.
|
|
121
|
+
*/
|
|
122
|
+
protected get defaultConfig(): Partial<TConfig>;
|
|
123
|
+
constructor(config?: Partial<TConfig>);
|
|
124
|
+
/**
|
|
125
|
+
* Called when the plugin is attached to a grid.
|
|
126
|
+
* Override to set up event listeners, initialize state, etc.
|
|
127
|
+
*/
|
|
128
|
+
attach(grid: GridElement_2): void;
|
|
129
|
+
/**
|
|
130
|
+
* Called when the plugin is detached from a grid.
|
|
131
|
+
* Override to clean up event listeners, timers, etc.
|
|
132
|
+
*/
|
|
133
|
+
detach(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Get another plugin instance from the same grid.
|
|
136
|
+
* Use for inter-plugin communication.
|
|
137
|
+
*/
|
|
138
|
+
protected getPlugin<T extends BaseGridPlugin>(PluginClass: new (...args: any[]) => T): T | undefined;
|
|
139
|
+
/**
|
|
140
|
+
* Emit a custom event from the grid.
|
|
141
|
+
*/
|
|
142
|
+
protected emit<T>(eventName: string, detail: T): void;
|
|
143
|
+
/**
|
|
144
|
+
* Request a re-render of the grid.
|
|
145
|
+
*/
|
|
146
|
+
protected requestRender(): void;
|
|
147
|
+
/**
|
|
148
|
+
* Request a lightweight style update without rebuilding DOM.
|
|
149
|
+
* Use this instead of requestRender() when only CSS classes need updating.
|
|
150
|
+
*/
|
|
151
|
+
protected requestAfterRender(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Get the current rows from the grid.
|
|
154
|
+
*/
|
|
155
|
+
protected get rows(): any[];
|
|
156
|
+
/**
|
|
157
|
+
* Get the original unfiltered/unprocessed rows from the grid.
|
|
158
|
+
* Use this when you need all source data regardless of active filters.
|
|
159
|
+
*/
|
|
160
|
+
protected get sourceRows(): any[];
|
|
161
|
+
/**
|
|
162
|
+
* Get the current columns from the grid.
|
|
163
|
+
*/
|
|
164
|
+
protected get columns(): ColumnConfig[];
|
|
165
|
+
/**
|
|
166
|
+
* Get only visible columns from the grid (excludes hidden).
|
|
167
|
+
* Use this for rendering that needs to match the grid template.
|
|
168
|
+
*/
|
|
169
|
+
protected get visibleColumns(): ColumnConfig[];
|
|
170
|
+
/**
|
|
171
|
+
* Get the shadow root of the grid.
|
|
172
|
+
*/
|
|
173
|
+
protected get shadowRoot(): ShadowRoot | null;
|
|
174
|
+
/**
|
|
175
|
+
* Log a warning message.
|
|
176
|
+
*/
|
|
177
|
+
protected warn(message: string): void;
|
|
178
|
+
/**
|
|
179
|
+
* Transform rows before rendering.
|
|
180
|
+
* Called during each render cycle before rows are rendered to the DOM.
|
|
181
|
+
* Use this to filter, sort, or add computed properties to rows.
|
|
182
|
+
*
|
|
183
|
+
* @param rows - The current rows array (readonly to encourage returning a new array)
|
|
184
|
+
* @returns The modified rows array to render
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* processRows(rows: readonly any[]): any[] {
|
|
189
|
+
* // Filter out hidden rows
|
|
190
|
+
* return rows.filter(row => !row._hidden);
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* processRows(rows: readonly any[]): any[] {
|
|
197
|
+
* // Add computed properties
|
|
198
|
+
* return rows.map(row => ({
|
|
199
|
+
* ...row,
|
|
200
|
+
* _fullName: `${row.firstName} ${row.lastName}`
|
|
201
|
+
* }));
|
|
202
|
+
* }
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
processRows?(rows: readonly any[]): any[];
|
|
206
|
+
/**
|
|
207
|
+
* Transform columns before rendering.
|
|
208
|
+
* Called during each render cycle before column headers and cells are rendered.
|
|
209
|
+
* Use this to add, remove, or modify column definitions.
|
|
210
|
+
*
|
|
211
|
+
* @param columns - The current columns array (readonly to encourage returning a new array)
|
|
212
|
+
* @returns The modified columns array to render
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* processColumns(columns: readonly ColumnConfig[]): ColumnConfig[] {
|
|
217
|
+
* // Add a selection checkbox column
|
|
218
|
+
* return [
|
|
219
|
+
* { field: '_select', header: '', width: 40 },
|
|
220
|
+
* ...columns
|
|
221
|
+
* ];
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
processColumns?(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
226
|
+
/**
|
|
227
|
+
* Called before each render cycle begins.
|
|
228
|
+
* Use this to prepare state or cache values needed during rendering.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* beforeRender(): void {
|
|
233
|
+
* this.visibleRowCount = this.calculateVisibleRows();
|
|
234
|
+
* }
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
beforeRender?(): void;
|
|
238
|
+
/**
|
|
239
|
+
* Called after each render cycle completes.
|
|
240
|
+
* Use this for DOM manipulation, adding event listeners to rendered elements,
|
|
241
|
+
* or applying visual effects like selection highlights.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* afterRender(): void {
|
|
246
|
+
* // Apply selection styling to rendered rows
|
|
247
|
+
* const rows = this.shadowRoot?.querySelectorAll('.data-row');
|
|
248
|
+
* rows?.forEach((row, i) => {
|
|
249
|
+
* row.classList.toggle('selected', this.selectedRows.has(i));
|
|
250
|
+
* });
|
|
251
|
+
* }
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
afterRender?(): void;
|
|
255
|
+
/**
|
|
256
|
+
* Render a custom row, bypassing the default row rendering.
|
|
257
|
+
* Use this for special row types like group headers, detail rows, or footers.
|
|
258
|
+
*
|
|
259
|
+
* @param row - The row data object
|
|
260
|
+
* @param rowEl - The row DOM element to render into
|
|
261
|
+
* @param rowIndex - The index of the row in the data array
|
|
262
|
+
* @returns `true` if the plugin handled rendering (prevents default), `false`/`void` for default rendering
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* renderRow(row: any, rowEl: HTMLElement, rowIndex: number): boolean | void {
|
|
267
|
+
* if (row._isGroupHeader) {
|
|
268
|
+
* rowEl.innerHTML = `<div class="group-header">${row._groupLabel}</div>`;
|
|
269
|
+
* return true; // Handled - skip default rendering
|
|
270
|
+
* }
|
|
271
|
+
* // Return void to let default rendering proceed
|
|
272
|
+
* }
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
renderRow?(row: any, rowEl: HTMLElement, rowIndex: number): boolean | void;
|
|
276
|
+
/**
|
|
277
|
+
* Handle keyboard events on the grid.
|
|
278
|
+
* Called when a key is pressed while the grid or a cell has focus.
|
|
279
|
+
*
|
|
280
|
+
* @param event - The native KeyboardEvent
|
|
281
|
+
* @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```ts
|
|
285
|
+
* onKeyDown(event: KeyboardEvent): boolean | void {
|
|
286
|
+
* // Handle Ctrl+A for select all
|
|
287
|
+
* if (event.ctrlKey && event.key === 'a') {
|
|
288
|
+
* this.selectAllRows();
|
|
289
|
+
* return true; // Prevent default browser select-all
|
|
290
|
+
* }
|
|
291
|
+
* }
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
onKeyDown?(event: KeyboardEvent): boolean | void;
|
|
295
|
+
/**
|
|
296
|
+
* Handle cell click events.
|
|
297
|
+
* Called when a data cell is clicked (not headers).
|
|
298
|
+
*
|
|
299
|
+
* @param event - Cell click event with row/column context
|
|
300
|
+
* @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```ts
|
|
304
|
+
* onCellClick(event: CellClickEvent): boolean | void {
|
|
305
|
+
* if (event.field === '_select') {
|
|
306
|
+
* this.toggleRowSelection(event.rowIndex);
|
|
307
|
+
* return true; // Handled
|
|
308
|
+
* }
|
|
309
|
+
* }
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
onCellClick?(event: CellClickEvent): boolean | void;
|
|
313
|
+
/**
|
|
314
|
+
* Handle row click events.
|
|
315
|
+
* Called when any part of a data row is clicked.
|
|
316
|
+
* Note: This is called in addition to onCellClick, not instead of.
|
|
317
|
+
*
|
|
318
|
+
* @param event - Row click event with row context
|
|
319
|
+
* @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```ts
|
|
323
|
+
* onRowClick(event: RowClickEvent): boolean | void {
|
|
324
|
+
* if (this.config.mode === 'row') {
|
|
325
|
+
* this.selectRow(event.rowIndex, event.originalEvent);
|
|
326
|
+
* return true;
|
|
327
|
+
* }
|
|
328
|
+
* }
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
onRowClick?(event: RowClickEvent): boolean | void;
|
|
332
|
+
/**
|
|
333
|
+
* Handle header click events.
|
|
334
|
+
* Called when a column header is clicked. Commonly used for sorting.
|
|
335
|
+
*
|
|
336
|
+
* @param event - Header click event with column context
|
|
337
|
+
* @returns `true` to prevent default behavior and stop propagation, `false`/`void` to allow default
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* onHeaderClick(event: HeaderClickEvent): boolean | void {
|
|
342
|
+
* if (event.column.sortable !== false) {
|
|
343
|
+
* this.toggleSort(event.field);
|
|
344
|
+
* return true;
|
|
345
|
+
* }
|
|
346
|
+
* }
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
onHeaderClick?(event: HeaderClickEvent): boolean | void;
|
|
350
|
+
/**
|
|
351
|
+
* Handle scroll events on the grid viewport.
|
|
352
|
+
* Called during scrolling. Note: This may be called frequently; debounce if needed.
|
|
353
|
+
*
|
|
354
|
+
* @param event - Scroll event with scroll position and viewport dimensions
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```ts
|
|
358
|
+
* onScroll(event: ScrollEvent): void {
|
|
359
|
+
* // Update sticky column positions
|
|
360
|
+
* this.updateStickyPositions(event.scrollLeft);
|
|
361
|
+
* }
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
onScroll?(event: ScrollEvent): void;
|
|
365
|
+
/**
|
|
366
|
+
* Handle cell mousedown events.
|
|
367
|
+
* Used for initiating drag operations like range selection or column resize.
|
|
368
|
+
*
|
|
369
|
+
* @param event - Mouse event with cell context
|
|
370
|
+
* @returns `true` to indicate drag started (prevents text selection), `false`/`void` otherwise
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* ```ts
|
|
374
|
+
* onCellMouseDown(event: CellMouseEvent): boolean | void {
|
|
375
|
+
* if (event.rowIndex !== undefined && this.config.mode === 'range') {
|
|
376
|
+
* this.startDragSelection(event.rowIndex, event.colIndex);
|
|
377
|
+
* return true; // Prevent text selection
|
|
378
|
+
* }
|
|
379
|
+
* }
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
onCellMouseDown?(event: CellMouseEvent): boolean | void;
|
|
383
|
+
/**
|
|
384
|
+
* Handle cell mousemove events during drag operations.
|
|
385
|
+
* Only called when a drag is in progress (after mousedown returned true).
|
|
386
|
+
*
|
|
387
|
+
* @param event - Mouse event with current cell context
|
|
388
|
+
* @returns `true` to continue handling the drag, `false`/`void` otherwise
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* ```ts
|
|
392
|
+
* onCellMouseMove(event: CellMouseEvent): boolean | void {
|
|
393
|
+
* if (this.isDragging && event.rowIndex !== undefined) {
|
|
394
|
+
* this.extendSelection(event.rowIndex, event.colIndex);
|
|
395
|
+
* return true;
|
|
396
|
+
* }
|
|
397
|
+
* }
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
onCellMouseMove?(event: CellMouseEvent): boolean | void;
|
|
401
|
+
/**
|
|
402
|
+
* Handle cell mouseup events to end drag operations.
|
|
403
|
+
*
|
|
404
|
+
* @param event - Mouse event with final cell context
|
|
405
|
+
* @returns `true` if drag was finalized, `false`/`void` otherwise
|
|
406
|
+
*
|
|
407
|
+
* @example
|
|
408
|
+
* ```ts
|
|
409
|
+
* onCellMouseUp(event: CellMouseEvent): boolean | void {
|
|
410
|
+
* if (this.isDragging) {
|
|
411
|
+
* this.finalizeDragSelection();
|
|
412
|
+
* this.isDragging = false;
|
|
413
|
+
* return true;
|
|
414
|
+
* }
|
|
415
|
+
* }
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
onCellMouseUp?(event: CellMouseEvent): boolean | void;
|
|
419
|
+
/**
|
|
420
|
+
* Provide context menu items when right-clicking on the grid.
|
|
421
|
+
* Multiple plugins can contribute items; they are merged into a single menu.
|
|
422
|
+
*
|
|
423
|
+
* @param params - Context about where the menu was triggered (row, column, etc.)
|
|
424
|
+
* @returns Array of menu items to display
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* getContextMenuItems(params: ContextMenuParams): ContextMenuItem[] {
|
|
429
|
+
* if (params.isHeader) {
|
|
430
|
+
* return [
|
|
431
|
+
* { id: 'sort-asc', label: 'Sort Ascending', action: () => this.sortAsc(params.field) },
|
|
432
|
+
* { id: 'sort-desc', label: 'Sort Descending', action: () => this.sortDesc(params.field) },
|
|
433
|
+
* ];
|
|
434
|
+
* }
|
|
435
|
+
* return [
|
|
436
|
+
* { id: 'copy', label: 'Copy Cell', action: () => this.copyCell(params) },
|
|
437
|
+
* ];
|
|
438
|
+
* }
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
getContextMenuItems?(params: ContextMenuParams): ContextMenuItem[];
|
|
442
|
+
/**
|
|
443
|
+
* Contribute plugin-specific state for a column.
|
|
444
|
+
* Called by the grid when collecting column state for serialization.
|
|
445
|
+
* Plugins can add their own properties to the column state.
|
|
446
|
+
*
|
|
447
|
+
* @param field - The field name of the column
|
|
448
|
+
* @returns Partial column state with plugin-specific properties, or undefined if no state to contribute
|
|
449
|
+
*
|
|
450
|
+
* @example
|
|
451
|
+
* ```ts
|
|
452
|
+
* getColumnState(field: string): Partial<ColumnState> | undefined {
|
|
453
|
+
* const filterModel = this.filterModels.get(field);
|
|
454
|
+
* if (filterModel) {
|
|
455
|
+
* // Uses module augmentation to add filter property to ColumnState
|
|
456
|
+
* return { filter: filterModel } as Partial<ColumnState>;
|
|
457
|
+
* }
|
|
458
|
+
* return undefined;
|
|
459
|
+
* }
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
getColumnState?(field: string): Partial<ColumnState> | undefined;
|
|
463
|
+
/**
|
|
464
|
+
* Apply plugin-specific state to a column.
|
|
465
|
+
* Called by the grid when restoring column state from serialized data.
|
|
466
|
+
* Plugins should restore their internal state based on the provided state.
|
|
467
|
+
*
|
|
468
|
+
* @param field - The field name of the column
|
|
469
|
+
* @param state - The column state to apply (may contain plugin-specific properties)
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```ts
|
|
473
|
+
* applyColumnState(field: string, state: ColumnState): void {
|
|
474
|
+
* // Check for filter property added via module augmentation
|
|
475
|
+
* const filter = (state as any).filter;
|
|
476
|
+
* if (filter) {
|
|
477
|
+
* this.filterModels.set(field, filter);
|
|
478
|
+
* this.applyFilter();
|
|
479
|
+
* }
|
|
480
|
+
* }
|
|
481
|
+
* ```
|
|
482
|
+
*/
|
|
483
|
+
applyColumnState?(field: string, state: ColumnState): void;
|
|
484
|
+
/**
|
|
485
|
+
* Register a tool panel for this plugin.
|
|
486
|
+
* Return undefined if plugin has no tool panel.
|
|
487
|
+
* The shell will create a toolbar toggle button and render the panel content
|
|
488
|
+
* when the user opens the panel.
|
|
489
|
+
*
|
|
490
|
+
* @returns Tool panel definition, or undefined if plugin has no panel
|
|
491
|
+
*
|
|
492
|
+
* @example
|
|
493
|
+
* ```ts
|
|
494
|
+
* getToolPanel(): ToolPanelDefinition | undefined {
|
|
495
|
+
* return {
|
|
496
|
+
* id: 'columns',
|
|
497
|
+
* title: 'Columns',
|
|
498
|
+
* icon: '☰',
|
|
499
|
+
* tooltip: 'Show/hide columns',
|
|
500
|
+
* order: 10,
|
|
501
|
+
* render: (container) => {
|
|
502
|
+
* this.renderColumnList(container);
|
|
503
|
+
* return () => this.cleanup();
|
|
504
|
+
* },
|
|
505
|
+
* };
|
|
506
|
+
* }
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
getToolPanel?(): ToolPanelDefinition | undefined;
|
|
510
|
+
/**
|
|
511
|
+
* Register content for the shell header center section.
|
|
512
|
+
* Return undefined if plugin has no header content.
|
|
513
|
+
* Examples: search input, selection summary, status indicators.
|
|
514
|
+
*
|
|
515
|
+
* @returns Header content definition, or undefined if plugin has no header content
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* ```ts
|
|
519
|
+
* getHeaderContent(): HeaderContentDefinition | undefined {
|
|
520
|
+
* return {
|
|
521
|
+
* id: 'quick-filter',
|
|
522
|
+
* order: 10,
|
|
523
|
+
* render: (container) => {
|
|
524
|
+
* const input = document.createElement('input');
|
|
525
|
+
* input.type = 'text';
|
|
526
|
+
* input.placeholder = 'Search...';
|
|
527
|
+
* input.addEventListener('input', this.handleInput);
|
|
528
|
+
* container.appendChild(input);
|
|
529
|
+
* return () => input.removeEventListener('input', this.handleInput);
|
|
530
|
+
* },
|
|
531
|
+
* };
|
|
532
|
+
* }
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
getHeaderContent?(): HeaderContentDefinition | undefined;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Cell click event
|
|
540
|
+
*/
|
|
541
|
+
declare interface CellClickEvent {
|
|
542
|
+
rowIndex: number;
|
|
543
|
+
colIndex: number;
|
|
544
|
+
field: string;
|
|
545
|
+
value: any;
|
|
546
|
+
row: any;
|
|
547
|
+
cellEl: HTMLElement;
|
|
548
|
+
originalEvent: MouseEvent;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export declare interface CellCommitDetail<TRow = any> {
|
|
552
|
+
/** The mutated row after commit. */
|
|
553
|
+
row: TRow;
|
|
554
|
+
/** Field name whose value changed. */
|
|
555
|
+
field: string;
|
|
556
|
+
/** New value stored. */
|
|
557
|
+
value: any;
|
|
558
|
+
/** Index of the row in current data set. */
|
|
559
|
+
rowIndex: number;
|
|
560
|
+
/** All rows that have at least one committed change (snapshot list). */
|
|
561
|
+
changedRows: TRow[];
|
|
562
|
+
/** Indices parallel to changedRows. */
|
|
563
|
+
changedRowIndices: number[];
|
|
564
|
+
/** True if this row just entered the changed set. */
|
|
565
|
+
firstTimeForRow: boolean;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Runtime cell context used internally for compiled template execution.
|
|
570
|
+
*/
|
|
571
|
+
declare interface CellContext<T = any> {
|
|
572
|
+
row: T;
|
|
573
|
+
value: any;
|
|
574
|
+
field: string;
|
|
575
|
+
column: ColumnInternal<T>;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Cell coordinates
|
|
580
|
+
*/
|
|
581
|
+
declare interface CellCoords {
|
|
582
|
+
row: number;
|
|
583
|
+
col: number;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Cell editor interface for plugins.
|
|
588
|
+
*/
|
|
589
|
+
declare interface CellEditor {
|
|
590
|
+
create(ctx: PluginCellRenderContext, commitFn: (value: any) => void, cancelFn: () => void): HTMLElement;
|
|
591
|
+
getValue?(element: HTMLElement): any;
|
|
592
|
+
focus?(element: HTMLElement): void;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Cell mouse event (for drag operations, selection, etc.)
|
|
597
|
+
*/
|
|
598
|
+
declare interface CellMouseEvent {
|
|
599
|
+
/** Event type: mousedown, mousemove, or mouseup */
|
|
600
|
+
type: 'mousedown' | 'mousemove' | 'mouseup';
|
|
601
|
+
/** Row index, undefined if not over a data cell */
|
|
602
|
+
rowIndex?: number;
|
|
603
|
+
/** Column index, undefined if not over a cell */
|
|
604
|
+
colIndex?: number;
|
|
605
|
+
/** Field name, undefined if not over a cell */
|
|
606
|
+
field?: string;
|
|
607
|
+
/** Cell value, undefined if not over a data cell */
|
|
608
|
+
value?: unknown;
|
|
609
|
+
/** Row data object, undefined if not over a data row */
|
|
610
|
+
row?: unknown;
|
|
611
|
+
/** Column configuration, undefined if not over a column */
|
|
612
|
+
column?: ColumnConfig;
|
|
613
|
+
/** The cell element, undefined if not over a cell */
|
|
614
|
+
cellElement?: HTMLElement;
|
|
615
|
+
/** The row element, undefined if not over a row */
|
|
616
|
+
rowElement?: HTMLElement;
|
|
617
|
+
/** Whether the event is over a header cell */
|
|
618
|
+
isHeader: boolean;
|
|
619
|
+
/** Cell coordinates if over a valid data cell */
|
|
620
|
+
cell?: CellCoords;
|
|
621
|
+
/** The original mouse event */
|
|
622
|
+
originalEvent: MouseEvent;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/** Public representation of a cell range (for events) */
|
|
626
|
+
export declare interface CellRange {
|
|
627
|
+
/** Starting cell coordinates */
|
|
628
|
+
from: {
|
|
629
|
+
row: number;
|
|
630
|
+
col: number;
|
|
631
|
+
};
|
|
632
|
+
/** Ending cell coordinates */
|
|
633
|
+
to: {
|
|
634
|
+
row: number;
|
|
635
|
+
col: number;
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Context passed to custom view renderers (pure display – no commit helpers).
|
|
641
|
+
*/
|
|
642
|
+
export declare interface CellRenderContext<TRow = any, TValue = any> {
|
|
643
|
+
/** Row object for the cell being rendered. */
|
|
644
|
+
row: TRow;
|
|
645
|
+
/** Value at field. */
|
|
646
|
+
value: TValue;
|
|
647
|
+
/** Field key. */
|
|
648
|
+
field: keyof TRow & string;
|
|
649
|
+
/** Column configuration reference. */
|
|
650
|
+
column: ColumnConfig<TRow>;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Cell renderer function type for plugins.
|
|
655
|
+
*/
|
|
656
|
+
declare type CellRenderer = (ctx: PluginCellRenderContext) => string | HTMLElement;
|
|
657
|
+
|
|
658
|
+
/** Emitted when the changed rows tracking set is cleared programmatically. */
|
|
659
|
+
export declare interface ChangedRowsResetDetail<TRow = any> {
|
|
660
|
+
/** New (empty) changed rows array after reset. */
|
|
661
|
+
rows: TRow[];
|
|
662
|
+
/** Parallel indices (likely empty). */
|
|
663
|
+
indices: number[];
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Clipboard Plugin Types
|
|
668
|
+
*
|
|
669
|
+
* Type definitions for clipboard copy/paste functionality.
|
|
670
|
+
*/
|
|
671
|
+
/** Configuration options for the clipboard plugin */
|
|
672
|
+
declare interface ClipboardConfig {
|
|
673
|
+
/** Whether clipboard functionality is enabled (default: true) */
|
|
674
|
+
enabled?: boolean;
|
|
675
|
+
/** Include column headers in copied text (default: false) */
|
|
676
|
+
includeHeaders?: boolean;
|
|
677
|
+
/** Column delimiter character (default: '\t' for tab) */
|
|
678
|
+
delimiter?: string;
|
|
679
|
+
/** Row delimiter/newline character (default: '\n') */
|
|
680
|
+
newline?: string;
|
|
681
|
+
/** Wrap string values with quotes (default: false) */
|
|
682
|
+
quoteStrings?: boolean;
|
|
683
|
+
/** Custom cell value processor for copy operations */
|
|
684
|
+
processCell?: (value: unknown, field: string, row: unknown) => string;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Clipboard Plugin for tbw-grid
|
|
689
|
+
*
|
|
690
|
+
* @example
|
|
691
|
+
* ```ts
|
|
692
|
+
* new ClipboardPlugin({ includeHeaders: true })
|
|
693
|
+
* ```
|
|
694
|
+
*/
|
|
695
|
+
export declare class ClipboardPlugin extends BaseGridPlugin<ClipboardConfig> {
|
|
696
|
+
#private;
|
|
697
|
+
readonly name = "clipboard";
|
|
698
|
+
readonly version = "1.0.0";
|
|
699
|
+
protected get defaultConfig(): Partial<ClipboardConfig>;
|
|
700
|
+
/** The last copied text (for reference/debugging) */
|
|
701
|
+
private lastCopied;
|
|
702
|
+
detach(): void;
|
|
703
|
+
onKeyDown(event: KeyboardEvent): boolean;
|
|
704
|
+
/**
|
|
705
|
+
* Copy currently selected rows to clipboard.
|
|
706
|
+
* @returns The copied text
|
|
707
|
+
*/
|
|
708
|
+
copy(): Promise<string>;
|
|
709
|
+
/**
|
|
710
|
+
* Copy specific rows by index to clipboard.
|
|
711
|
+
* @param indices - Array of row indices to copy
|
|
712
|
+
* @returns The copied text
|
|
713
|
+
*/
|
|
714
|
+
copyRows(indices: number[]): Promise<string>;
|
|
715
|
+
/**
|
|
716
|
+
* Read and parse clipboard content.
|
|
717
|
+
* @returns Parsed 2D array of cell values, or null if clipboard is empty
|
|
718
|
+
*/
|
|
719
|
+
paste(): Promise<string[][] | null>;
|
|
720
|
+
/**
|
|
721
|
+
* Get the last copied text and timestamp.
|
|
722
|
+
* @returns The last copied info or null
|
|
723
|
+
*/
|
|
724
|
+
getLastCopied(): {
|
|
725
|
+
text: string;
|
|
726
|
+
timestamp: number;
|
|
727
|
+
} | null;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Full column configuration including optional custom view/renderer & grouping metadata.
|
|
732
|
+
*/
|
|
733
|
+
export declare interface ColumnConfig<TRow = any> extends BaseColumnConfig<TRow, any> {
|
|
734
|
+
/** Optional custom view renderer used instead of default text rendering */
|
|
735
|
+
viewRenderer?: ColumnViewRenderer<TRow, any>;
|
|
736
|
+
/** External view spec (lets host app mount any framework component) */
|
|
737
|
+
externalView?: {
|
|
738
|
+
component: any;
|
|
739
|
+
props?: Record<string, any>;
|
|
740
|
+
mount?: (options: {
|
|
741
|
+
placeholder: HTMLElement;
|
|
742
|
+
context: CellRenderContext<TRow, any>;
|
|
743
|
+
spec: any;
|
|
744
|
+
}) => void | {
|
|
745
|
+
dispose?: () => void;
|
|
746
|
+
};
|
|
747
|
+
};
|
|
748
|
+
/** Whether the column is initially hidden */
|
|
749
|
+
hidden?: boolean;
|
|
750
|
+
/** Prevent this column from being hidden by the visibility plugin */
|
|
751
|
+
lockVisible?: boolean;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
export declare type ColumnConfigMap<TRow = any> = ColumnConfig<TRow>[];
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Context object provided to editor factories allowing mutation (commit/cancel) of a cell value.
|
|
758
|
+
*/
|
|
759
|
+
export declare interface ColumnEditorContext<TRow = any, TValue = any> {
|
|
760
|
+
/** Underlying full row object for the active edit. */
|
|
761
|
+
row: TRow;
|
|
762
|
+
/** Current cell value (mutable only via commit). */
|
|
763
|
+
value: TValue;
|
|
764
|
+
/** Field name being edited. */
|
|
765
|
+
field: keyof TRow & string;
|
|
766
|
+
/** Column configuration reference. */
|
|
767
|
+
column: ColumnConfig<TRow>;
|
|
768
|
+
/** Accept the edit; triggers change tracking + rerender. */
|
|
769
|
+
commit: (newValue: TValue) => void;
|
|
770
|
+
/** Abort edit without persisting changes. */
|
|
771
|
+
cancel: () => void;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/** External editor spec: tag name, factory function, or external mount spec */
|
|
775
|
+
export declare type ColumnEditorSpec<TRow = any, TValue = any> = string | ((context: ColumnEditorContext<TRow, TValue>) => HTMLElement | string) | {
|
|
776
|
+
/** Arbitrary component reference (class, function, token) */
|
|
777
|
+
component: any;
|
|
778
|
+
/** Optional static props passed to mount */
|
|
779
|
+
props?: Record<string, any>;
|
|
780
|
+
/** Optional custom mount function; if provided we call it directly instead of emitting an event */
|
|
781
|
+
mount?: (options: {
|
|
782
|
+
placeholder: HTMLElement;
|
|
783
|
+
context: ColumnEditorContext<TRow, TValue>;
|
|
784
|
+
spec: any;
|
|
785
|
+
}) => void | {
|
|
786
|
+
dispose?: () => void;
|
|
787
|
+
};
|
|
788
|
+
};
|
|
789
|
+
|
|
790
|
+
/** Column group definition */
|
|
791
|
+
declare interface ColumnGroup<T = any> {
|
|
792
|
+
/** Unique group identifier */
|
|
793
|
+
id: string;
|
|
794
|
+
/** Display label for the group header */
|
|
795
|
+
label?: string;
|
|
796
|
+
/** Columns belonging to this group */
|
|
797
|
+
columns: ColumnConfig<T>[];
|
|
798
|
+
/** Index of first column in this group */
|
|
799
|
+
firstIndex: number;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
declare interface ColumnInternal<T = any> extends ColumnConfig<T> {
|
|
803
|
+
__autoSized?: boolean;
|
|
804
|
+
__userResized?: boolean;
|
|
805
|
+
__renderedWidth?: number;
|
|
806
|
+
__viewTemplate?: HTMLElement;
|
|
807
|
+
__editorTemplate?: HTMLElement;
|
|
808
|
+
__headerTemplate?: HTMLElement;
|
|
809
|
+
__compiledView?: (ctx: CellContext<T>) => string;
|
|
810
|
+
__compiledEditor?: (ctx: EditorExecContext<T>) => string;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/** Column resize event detail containing final pixel width. */
|
|
814
|
+
export declare interface ColumnResizeDetail {
|
|
815
|
+
/** Resized column field key. */
|
|
816
|
+
field: string;
|
|
817
|
+
/** New width in pixels. */
|
|
818
|
+
width: number;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Sort state for a column
|
|
823
|
+
*/
|
|
824
|
+
export declare interface ColumnSortState {
|
|
825
|
+
/** Sort direction */
|
|
826
|
+
direction: 'asc' | 'desc';
|
|
827
|
+
/** Priority for multi-sort (0 = primary, 1 = secondary, etc.) */
|
|
828
|
+
priority: number;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* State for a single column. Captures user-driven changes at runtime.
|
|
833
|
+
* Plugins can extend this interface via module augmentation to add their own state.
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```ts
|
|
837
|
+
* // In filtering plugin
|
|
838
|
+
* declare module '@toolbox-web/grid' {
|
|
839
|
+
* interface ColumnState {
|
|
840
|
+
* filter?: FilterValue;
|
|
841
|
+
* }
|
|
842
|
+
* }
|
|
843
|
+
* ```
|
|
844
|
+
*/
|
|
845
|
+
export declare interface ColumnState {
|
|
846
|
+
/** Column field identifier */
|
|
847
|
+
field: string;
|
|
848
|
+
/** Position index after reordering (0-based) */
|
|
849
|
+
order: number;
|
|
850
|
+
/** Width in pixels (undefined = use default) */
|
|
851
|
+
width?: number;
|
|
852
|
+
/** Visibility state */
|
|
853
|
+
visible: boolean;
|
|
854
|
+
/** Sort state (undefined = not sorted) */
|
|
855
|
+
sort?: ColumnSortState;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
export declare type ColumnViewRenderer<TRow = any, TValue = any> = (ctx: CellRenderContext<TRow, TValue>) => Node | string | void;
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Column Virtualization Plugin Types
|
|
862
|
+
*
|
|
863
|
+
* Type definitions for horizontal column virtualization feature.
|
|
864
|
+
*/
|
|
865
|
+
/** Configuration options for the column virtualization plugin */
|
|
866
|
+
declare interface ColumnVirtualizationConfig {
|
|
867
|
+
/** Whether the plugin is enabled (default: true) */
|
|
868
|
+
enabled?: boolean;
|
|
869
|
+
/** Auto-enable when column count exceeds threshold (default: true) */
|
|
870
|
+
autoEnable?: boolean;
|
|
871
|
+
/** Column count threshold for auto-enabling (default: 30) */
|
|
872
|
+
threshold?: number;
|
|
873
|
+
/** Extra columns to render on each side for smooth scrolling (default: 3) */
|
|
874
|
+
overscan?: number;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Column Virtualization Plugin for tbw-grid
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```ts
|
|
882
|
+
* new ColumnVirtualizationPlugin({ threshold: 30, overscan: 3 })
|
|
883
|
+
* ```
|
|
884
|
+
*/
|
|
885
|
+
export declare class ColumnVirtualizationPlugin extends BaseGridPlugin<ColumnVirtualizationConfig> {
|
|
886
|
+
readonly name = "columnVirtualization";
|
|
887
|
+
readonly version = "1.0.0";
|
|
888
|
+
protected get defaultConfig(): Partial<ColumnVirtualizationConfig>;
|
|
889
|
+
private isVirtualized;
|
|
890
|
+
private startCol;
|
|
891
|
+
private endCol;
|
|
892
|
+
private scrollLeft;
|
|
893
|
+
private totalWidth;
|
|
894
|
+
private columnWidths;
|
|
895
|
+
private columnOffsets;
|
|
896
|
+
attach(grid: GridElement_2): void;
|
|
897
|
+
detach(): void;
|
|
898
|
+
processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
899
|
+
afterRender(): void;
|
|
900
|
+
onScroll(event: ScrollEvent): void;
|
|
901
|
+
/**
|
|
902
|
+
* Check if column virtualization is currently active.
|
|
903
|
+
*/
|
|
904
|
+
getIsVirtualized(): boolean;
|
|
905
|
+
/**
|
|
906
|
+
* Get the current visible column range.
|
|
907
|
+
*/
|
|
908
|
+
getVisibleColumnRange(): {
|
|
909
|
+
start: number;
|
|
910
|
+
end: number;
|
|
911
|
+
};
|
|
912
|
+
/**
|
|
913
|
+
* Scroll the grid to bring a specific column into view.
|
|
914
|
+
* @param columnIndex - Index of the column to scroll to
|
|
915
|
+
*/
|
|
916
|
+
scrollToColumn(columnIndex: number): void;
|
|
917
|
+
/**
|
|
918
|
+
* Get the left offset for a specific column.
|
|
919
|
+
* @param columnIndex - Index of the column
|
|
920
|
+
*/
|
|
921
|
+
getColumnOffset(columnIndex: number): number;
|
|
922
|
+
/**
|
|
923
|
+
* Get the total width of all columns.
|
|
924
|
+
*/
|
|
925
|
+
getTotalWidth(): number;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* Configuration options for the context menu plugin.
|
|
930
|
+
*/
|
|
931
|
+
declare interface ContextMenuConfig {
|
|
932
|
+
/** Whether the context menu is enabled (default: true) */
|
|
933
|
+
enabled?: boolean;
|
|
934
|
+
/** Menu items - static array or function returning items */
|
|
935
|
+
items?: ContextMenuItem_2[] | ((params: ContextMenuParams_2) => ContextMenuItem_2[]);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Context menu item
|
|
940
|
+
*/
|
|
941
|
+
declare interface ContextMenuItem {
|
|
942
|
+
id: string;
|
|
943
|
+
label: string;
|
|
944
|
+
icon?: string;
|
|
945
|
+
disabled?: boolean;
|
|
946
|
+
separator?: boolean;
|
|
947
|
+
children?: ContextMenuItem[];
|
|
948
|
+
action?: (params: ContextMenuParams) => void;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Context Menu Plugin Types
|
|
953
|
+
*
|
|
954
|
+
* Type definitions for the context menu feature.
|
|
955
|
+
*/
|
|
956
|
+
/**
|
|
957
|
+
* Context menu item definition.
|
|
958
|
+
* Supports icons, shortcuts, submenus, separators, and dynamic disabled/hidden states.
|
|
959
|
+
*/
|
|
960
|
+
declare interface ContextMenuItem_2 {
|
|
961
|
+
/** Unique identifier for the menu item */
|
|
962
|
+
id: string;
|
|
963
|
+
/** Display label for the menu item */
|
|
964
|
+
name: string;
|
|
965
|
+
/** Optional icon (HTML string, emoji, or icon class) */
|
|
966
|
+
icon?: string;
|
|
967
|
+
/** Optional keyboard shortcut hint (display only) */
|
|
968
|
+
shortcut?: string;
|
|
969
|
+
/** Whether the item is disabled (static or dynamic) */
|
|
970
|
+
disabled?: boolean | ((params: ContextMenuParams_2) => boolean);
|
|
971
|
+
/** Whether the item is hidden (static or dynamic) */
|
|
972
|
+
hidden?: boolean | ((params: ContextMenuParams_2) => boolean);
|
|
973
|
+
/** Action handler when the item is clicked */
|
|
974
|
+
action?: (params: ContextMenuParams_2) => void;
|
|
975
|
+
/** Nested submenu items */
|
|
976
|
+
subMenu?: ContextMenuItem_2[];
|
|
977
|
+
/** Whether this is a separator (id and name required but ignored) */
|
|
978
|
+
separator?: boolean;
|
|
979
|
+
/** Optional CSS class to add to the menu item */
|
|
980
|
+
cssClass?: string;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Context menu parameters
|
|
985
|
+
*/
|
|
986
|
+
declare interface ContextMenuParams {
|
|
987
|
+
x: number;
|
|
988
|
+
y: number;
|
|
989
|
+
rowIndex?: number;
|
|
990
|
+
colIndex?: number;
|
|
991
|
+
field?: string;
|
|
992
|
+
value?: any;
|
|
993
|
+
row?: any;
|
|
994
|
+
column?: ColumnConfig;
|
|
995
|
+
isHeader?: boolean;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Parameters passed to context menu callbacks.
|
|
1000
|
+
* Provides context about what element triggered the menu.
|
|
1001
|
+
*/
|
|
1002
|
+
declare interface ContextMenuParams_2 {
|
|
1003
|
+
/** The row data object (null for header clicks) */
|
|
1004
|
+
row: unknown;
|
|
1005
|
+
/** The row index (-1 for header clicks) */
|
|
1006
|
+
rowIndex: number;
|
|
1007
|
+
/** The column configuration */
|
|
1008
|
+
column: unknown;
|
|
1009
|
+
/** The column index */
|
|
1010
|
+
columnIndex: number;
|
|
1011
|
+
/** The field name of the column */
|
|
1012
|
+
field: string;
|
|
1013
|
+
/** The cell value (null for header clicks) */
|
|
1014
|
+
value: unknown;
|
|
1015
|
+
/** Whether the context menu was triggered on a header */
|
|
1016
|
+
isHeader: boolean;
|
|
1017
|
+
/** The original mouse event */
|
|
1018
|
+
event: MouseEvent;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* Context Menu Plugin for tbw-grid
|
|
1023
|
+
*
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```ts
|
|
1026
|
+
* new ContextMenuPlugin({
|
|
1027
|
+
* enabled: true,
|
|
1028
|
+
* items: [
|
|
1029
|
+
* { id: 'edit', name: 'Edit', action: (params) => console.log('Edit', params) },
|
|
1030
|
+
* { separator: true, id: 'sep', name: '' },
|
|
1031
|
+
* { id: 'delete', name: 'Delete', action: (params) => console.log('Delete', params) },
|
|
1032
|
+
* ],
|
|
1033
|
+
* })
|
|
1034
|
+
* ```
|
|
1035
|
+
*/
|
|
1036
|
+
export declare class ContextMenuPlugin extends BaseGridPlugin<ContextMenuConfig> {
|
|
1037
|
+
readonly name = "contextMenu";
|
|
1038
|
+
readonly version = "1.0.0";
|
|
1039
|
+
protected get defaultConfig(): Partial<ContextMenuConfig>;
|
|
1040
|
+
private isOpen;
|
|
1041
|
+
private position;
|
|
1042
|
+
private params;
|
|
1043
|
+
private menuElement;
|
|
1044
|
+
attach(grid: GridElement_2): void;
|
|
1045
|
+
detach(): void;
|
|
1046
|
+
private installGlobalHandlers;
|
|
1047
|
+
afterRender(): void;
|
|
1048
|
+
/**
|
|
1049
|
+
* Programmatically show the context menu at the specified position.
|
|
1050
|
+
* @param x - X coordinate
|
|
1051
|
+
* @param y - Y coordinate
|
|
1052
|
+
* @param params - Partial context menu parameters
|
|
1053
|
+
*/
|
|
1054
|
+
showMenu(x: number, y: number, params: Partial<ContextMenuParams_2>): void;
|
|
1055
|
+
/**
|
|
1056
|
+
* Hide the context menu.
|
|
1057
|
+
*/
|
|
1058
|
+
hideMenu(): void;
|
|
1059
|
+
/**
|
|
1060
|
+
* Check if the context menu is currently open.
|
|
1061
|
+
* @returns Whether the menu is open
|
|
1062
|
+
*/
|
|
1063
|
+
isMenuOpen(): boolean;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
export declare type DataGridCustomEvent<K extends keyof DataGridEventMap<any>, TRow = any> = CustomEvent<DataGridEventMap<TRow>[K]>;
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* High-performance data grid web component.
|
|
1070
|
+
* During migration, uses tbw-grid tag to avoid conflicts with existing datagrid.
|
|
1071
|
+
* Will be renamed back to data-grid when migration is complete.
|
|
1072
|
+
*
|
|
1073
|
+
* ## Configuration Architecture
|
|
1074
|
+
*
|
|
1075
|
+
* The grid follows a **single source of truth** pattern where all configuration
|
|
1076
|
+
* converges into `#effectiveConfig`. Users can set configuration via multiple inputs:
|
|
1077
|
+
*
|
|
1078
|
+
* **Input Sources (precedence low → high):**
|
|
1079
|
+
* 1. `gridConfig` property - base configuration object
|
|
1080
|
+
* 2. Light DOM elements:
|
|
1081
|
+
* - `<tbw-grid-column>` → `effectiveConfig.columns`
|
|
1082
|
+
* - `<tbw-grid-header title="...">` → `effectiveConfig.shell.header.title`
|
|
1083
|
+
* - `<tbw-grid-header-content>` → `effectiveConfig.shell.header.content`
|
|
1084
|
+
* 3. `columns` property → merged into `effectiveConfig.columns`
|
|
1085
|
+
* 4. `fitMode` property → merged into `effectiveConfig.fitMode`
|
|
1086
|
+
* 5. `editOn` property → merged into `effectiveConfig.editOn`
|
|
1087
|
+
* 6. Column inference from first row (if no columns defined)
|
|
1088
|
+
*
|
|
1089
|
+
* **Derived State:**
|
|
1090
|
+
* - `_columns` - processed columns from `effectiveConfig.columns` after plugin hooks
|
|
1091
|
+
* - `_rows` - processed rows after plugin hooks (grouping, filtering, etc.)
|
|
1092
|
+
*
|
|
1093
|
+
* The `#mergeEffectiveConfig()` method is the single place where all inputs converge.
|
|
1094
|
+
* All rendering and logic should read from `effectiveConfig` or derived state.
|
|
1095
|
+
*
|
|
1096
|
+
* @element tbw-grid
|
|
1097
|
+
*
|
|
1098
|
+
* @csspart container - The main grid container
|
|
1099
|
+
* @csspart header - The header row container
|
|
1100
|
+
* @csspart body - The body/rows container
|
|
1101
|
+
*
|
|
1102
|
+
* @fires cell-commit - Fired when a cell value is committed
|
|
1103
|
+
* @fires row-commit - Fired when a bulk row edit session commits
|
|
1104
|
+
* @fires changed-rows-reset - Fired after resetChangedRows() unless silent
|
|
1105
|
+
* @fires mount-external-view - Fired to request mounting of an external view renderer
|
|
1106
|
+
* @fires mount-external-editor - Fired to request mounting of an external editor renderer
|
|
1107
|
+
* @fires sort-change - Fired when sort state changes for a column
|
|
1108
|
+
* @fires column-resize - Fired after a column resize drag completes
|
|
1109
|
+
* @fires activate-cell - Fired when a cell activation intent occurs
|
|
1110
|
+
* @fires group-toggle - Fired when a group row is toggled
|
|
1111
|
+
*
|
|
1112
|
+
* @cssprop --tbw-color-bg - Background color
|
|
1113
|
+
* @cssprop --tbw-color-fg - Foreground/text color
|
|
1114
|
+
*/
|
|
1115
|
+
declare class DataGridElement<T = any> extends HTMLElement implements InternalGrid<T> {
|
|
1116
|
+
#private;
|
|
1117
|
+
static readonly tagName = "tbw-grid";
|
|
1118
|
+
_rows: T[];
|
|
1119
|
+
get _columns(): ColumnInternal<T>[];
|
|
1120
|
+
set _columns(value: ColumnInternal<T>[]);
|
|
1121
|
+
get visibleColumns(): ColumnInternal<T>[];
|
|
1122
|
+
rowPool: HTMLElement[];
|
|
1123
|
+
__rowRenderEpoch: number;
|
|
1124
|
+
activeEditRows: number;
|
|
1125
|
+
resizeController: ResizeController;
|
|
1126
|
+
__didInitialAutoSize: boolean;
|
|
1127
|
+
__lightDomColumnsCache?: ColumnInternal[];
|
|
1128
|
+
__originalColumnNodes?: HTMLElement[];
|
|
1129
|
+
headerRowEl: HTMLElement;
|
|
1130
|
+
bodyEl: HTMLElement;
|
|
1131
|
+
virtualization: VirtualState;
|
|
1132
|
+
sortState: {
|
|
1133
|
+
field: string;
|
|
1134
|
+
direction: 1 | -1;
|
|
1135
|
+
} | null;
|
|
1136
|
+
__originalOrder: T[];
|
|
1137
|
+
focusRow: number;
|
|
1138
|
+
focusCol: number;
|
|
1139
|
+
gridTemplate: string;
|
|
1140
|
+
rowEditSnapshots: Map<number, T>;
|
|
1141
|
+
_changedRowIndices: Set<number>;
|
|
1142
|
+
get rows(): T[];
|
|
1143
|
+
set rows(value: T[]);
|
|
1144
|
+
/**
|
|
1145
|
+
* Get the original unfiltered/unprocessed rows.
|
|
1146
|
+
* Use this when you need access to all source data regardless of active filters.
|
|
1147
|
+
*/
|
|
1148
|
+
get sourceRows(): T[];
|
|
1149
|
+
get columns(): ColumnConfig<T>[];
|
|
1150
|
+
set columns(value: ColumnConfig<T>[] | ColumnConfigMap<T> | undefined);
|
|
1151
|
+
get gridConfig(): GridConfig<T>;
|
|
1152
|
+
set gridConfig(value: GridConfig<T> | undefined);
|
|
1153
|
+
get fitMode(): FitMode;
|
|
1154
|
+
set fitMode(value: FitMode | undefined);
|
|
1155
|
+
get editOn(): string | undefined;
|
|
1156
|
+
set editOn(value: string | undefined);
|
|
1157
|
+
get effectiveConfig(): GridConfig<T>;
|
|
1158
|
+
constructor();
|
|
1159
|
+
/**
|
|
1160
|
+
* Get a plugin instance by its class.
|
|
1161
|
+
* Used by plugins for inter-plugin communication.
|
|
1162
|
+
*/
|
|
1163
|
+
getPlugin<P extends BaseGridPlugin>(PluginClass: new (...args: any[]) => P): P | undefined;
|
|
1164
|
+
/**
|
|
1165
|
+
* Get a plugin instance by its name.
|
|
1166
|
+
* Used for loose coupling between plugins (avoids static imports).
|
|
1167
|
+
*/
|
|
1168
|
+
getPluginByName(name: string): BaseGridPlugin | undefined;
|
|
1169
|
+
/**
|
|
1170
|
+
* Request a full re-render of the grid.
|
|
1171
|
+
* Called by plugins when they need the grid to update.
|
|
1172
|
+
* Note: This does NOT reset plugin state - just re-processes rows/columns and renders.
|
|
1173
|
+
*/
|
|
1174
|
+
requestRender(): void;
|
|
1175
|
+
/**
|
|
1176
|
+
* Request a lightweight style update without rebuilding DOM.
|
|
1177
|
+
* Called by plugins when they only need to update CSS classes/styles.
|
|
1178
|
+
* This runs all plugin afterRender hooks without rebuilding row/column DOM.
|
|
1179
|
+
*/
|
|
1180
|
+
requestAfterRender(): void;
|
|
1181
|
+
connectedCallback(): void;
|
|
1182
|
+
disconnectedCallback(): void;
|
|
1183
|
+
emitCellCommit(detail: CellCommitDetail<T>): void;
|
|
1184
|
+
emitRowCommit(detail: RowCommitDetail<T>): void;
|
|
1185
|
+
emitSortChange(detail: SortChangeDetail): void;
|
|
1186
|
+
emitColumnResize(detail: ColumnResizeDetail): void;
|
|
1187
|
+
emitActivateCell(detail: ActivateCellDetail): void;
|
|
1188
|
+
updateTemplate(): void;
|
|
1189
|
+
findHeaderRow(): HTMLElement;
|
|
1190
|
+
findRenderedRowElement(rowIndex: number): HTMLElement | null;
|
|
1191
|
+
/**
|
|
1192
|
+
* Dispatch a cell click event to the plugin system.
|
|
1193
|
+
* Returns true if any plugin handled the event.
|
|
1194
|
+
*/
|
|
1195
|
+
dispatchCellClick(event: MouseEvent, rowIndex: number, colIndex: number, cellEl: HTMLElement): boolean;
|
|
1196
|
+
/**
|
|
1197
|
+
* Dispatch a header click event to the plugin system.
|
|
1198
|
+
* Returns true if any plugin handled the event.
|
|
1199
|
+
*/
|
|
1200
|
+
dispatchHeaderClick(event: MouseEvent, colIndex: number, headerEl: HTMLElement): boolean;
|
|
1201
|
+
/**
|
|
1202
|
+
* Dispatch a keyboard event to the plugin system.
|
|
1203
|
+
* Returns true if any plugin handled the event.
|
|
1204
|
+
*/
|
|
1205
|
+
dispatchKeyDown(event: KeyboardEvent): boolean;
|
|
1206
|
+
get changedRows(): T[];
|
|
1207
|
+
get changedRowIndices(): number[];
|
|
1208
|
+
resetChangedRows(silent?: boolean): Promise<void>;
|
|
1209
|
+
beginBulkEdit(rowIndex: number): Promise<void>;
|
|
1210
|
+
commitActiveRowEdit(): Promise<void>;
|
|
1211
|
+
ready(): Promise<void>;
|
|
1212
|
+
forceLayout(): Promise<void>;
|
|
1213
|
+
/** Public method: returns a frozen snapshot of the merged effective configuration */
|
|
1214
|
+
getConfig(): Promise<Readonly<GridConfig<T>>>;
|
|
1215
|
+
/**
|
|
1216
|
+
* Set the visibility of a column.
|
|
1217
|
+
* @param field - The field name of the column
|
|
1218
|
+
* @param visible - Whether the column should be visible
|
|
1219
|
+
* @returns True if visibility was changed, false if column not found or locked
|
|
1220
|
+
*/
|
|
1221
|
+
setColumnVisible(field: string, visible: boolean): boolean;
|
|
1222
|
+
/**
|
|
1223
|
+
* Toggle the visibility of a column.
|
|
1224
|
+
* @param field - The field name of the column
|
|
1225
|
+
* @returns True if visibility was toggled, false if column not found or locked
|
|
1226
|
+
*/
|
|
1227
|
+
toggleColumnVisibility(field: string): boolean;
|
|
1228
|
+
/**
|
|
1229
|
+
* Check if a column is currently visible.
|
|
1230
|
+
* @param field - The field name of the column
|
|
1231
|
+
* @returns True if visible, false if hidden or not found
|
|
1232
|
+
*/
|
|
1233
|
+
isColumnVisible(field: string): boolean;
|
|
1234
|
+
/**
|
|
1235
|
+
* Show all columns.
|
|
1236
|
+
*/
|
|
1237
|
+
showAllColumns(): void;
|
|
1238
|
+
/**
|
|
1239
|
+
* Get list of all column fields (including hidden).
|
|
1240
|
+
* Returns columns reflecting current display order (after reordering).
|
|
1241
|
+
* Hidden columns are interleaved at their original relative positions.
|
|
1242
|
+
* @returns Array of all field names with their visibility status
|
|
1243
|
+
*/
|
|
1244
|
+
getAllColumns(): Array<{
|
|
1245
|
+
field: string;
|
|
1246
|
+
header: string;
|
|
1247
|
+
visible: boolean;
|
|
1248
|
+
lockVisible?: boolean;
|
|
1249
|
+
}>;
|
|
1250
|
+
/**
|
|
1251
|
+
* Reorder columns according to the specified field order.
|
|
1252
|
+
* This directly updates _columns in place without going through processColumns.
|
|
1253
|
+
* @param order - Array of field names in the desired order
|
|
1254
|
+
*/
|
|
1255
|
+
setColumnOrder(order: string[]): void;
|
|
1256
|
+
/**
|
|
1257
|
+
* Get the current column order as an array of field names.
|
|
1258
|
+
* @returns Array of field names in display order
|
|
1259
|
+
*/
|
|
1260
|
+
getColumnOrder(): string[];
|
|
1261
|
+
/**
|
|
1262
|
+
* Get the current column state, including order, width, visibility, sort, and plugin state.
|
|
1263
|
+
* Returns a serializable object suitable for localStorage or database storage.
|
|
1264
|
+
*/
|
|
1265
|
+
getColumnState(): GridColumnState;
|
|
1266
|
+
/**
|
|
1267
|
+
* Set the column state, restoring order, width, visibility, sort, and plugin state.
|
|
1268
|
+
* Use this to restore previously saved column state.
|
|
1269
|
+
*/
|
|
1270
|
+
set columnState(state: GridColumnState | undefined);
|
|
1271
|
+
/**
|
|
1272
|
+
* Get the current column state.
|
|
1273
|
+
*/
|
|
1274
|
+
get columnState(): GridColumnState | undefined;
|
|
1275
|
+
/**
|
|
1276
|
+
* Request a state change event to be emitted.
|
|
1277
|
+
* Called internally after resize, reorder, visibility, or sort changes.
|
|
1278
|
+
* Plugins should call this after changing their state.
|
|
1279
|
+
* The event is debounced to avoid excessive events during drag operations.
|
|
1280
|
+
*/
|
|
1281
|
+
requestStateChange(): void;
|
|
1282
|
+
/**
|
|
1283
|
+
* Reset column state to initial configuration.
|
|
1284
|
+
* Clears all user modifications (order, width, visibility, sort).
|
|
1285
|
+
*/
|
|
1286
|
+
resetColumnState(): void;
|
|
1287
|
+
/**
|
|
1288
|
+
* Get the currently active tool panel ID, or null if none is open.
|
|
1289
|
+
*/
|
|
1290
|
+
get activeToolPanel(): string | null;
|
|
1291
|
+
/**
|
|
1292
|
+
* Open a tool panel by ID.
|
|
1293
|
+
* Closes any currently open panel first.
|
|
1294
|
+
*/
|
|
1295
|
+
openToolPanel(panelId: string): void;
|
|
1296
|
+
/**
|
|
1297
|
+
* Close the currently open tool panel.
|
|
1298
|
+
*/
|
|
1299
|
+
closeToolPanel(): void;
|
|
1300
|
+
/**
|
|
1301
|
+
* Toggle a tool panel open/closed.
|
|
1302
|
+
*/
|
|
1303
|
+
toggleToolPanel(panelId: string): void;
|
|
1304
|
+
/**
|
|
1305
|
+
* Get registered tool panel definitions.
|
|
1306
|
+
*/
|
|
1307
|
+
getToolPanels(): ToolPanelDefinition[];
|
|
1308
|
+
/**
|
|
1309
|
+
* Register a custom tool panel (without creating a plugin).
|
|
1310
|
+
*/
|
|
1311
|
+
registerToolPanel(panel: ToolPanelDefinition): void;
|
|
1312
|
+
/**
|
|
1313
|
+
* Unregister a custom tool panel.
|
|
1314
|
+
*/
|
|
1315
|
+
unregisterToolPanel(panelId: string): void;
|
|
1316
|
+
/**
|
|
1317
|
+
* Get registered header content definitions.
|
|
1318
|
+
*/
|
|
1319
|
+
getHeaderContents(): HeaderContentDefinition[];
|
|
1320
|
+
/**
|
|
1321
|
+
* Register custom header content (without creating a plugin).
|
|
1322
|
+
*/
|
|
1323
|
+
registerHeaderContent(content: HeaderContentDefinition): void;
|
|
1324
|
+
/**
|
|
1325
|
+
* Unregister custom header content.
|
|
1326
|
+
*/
|
|
1327
|
+
unregisterHeaderContent(contentId: string): void;
|
|
1328
|
+
/**
|
|
1329
|
+
* Get all registered toolbar buttons.
|
|
1330
|
+
*/
|
|
1331
|
+
getToolbarButtons(): ToolbarButtonInfo[];
|
|
1332
|
+
/**
|
|
1333
|
+
* Register a custom toolbar button programmatically.
|
|
1334
|
+
*/
|
|
1335
|
+
registerToolbarButton(button: ToolbarButtonConfig): void;
|
|
1336
|
+
/**
|
|
1337
|
+
* Unregister a custom toolbar button.
|
|
1338
|
+
*/
|
|
1339
|
+
unregisterToolbarButton(buttonId: string): void;
|
|
1340
|
+
/**
|
|
1341
|
+
* Enable/disable a toolbar button by ID.
|
|
1342
|
+
*/
|
|
1343
|
+
setToolbarButtonDisabled(buttonId: string, disabled: boolean): void;
|
|
1344
|
+
/**
|
|
1345
|
+
* Re-parse light DOM shell elements and refresh shell header.
|
|
1346
|
+
* Call this after dynamically modifying <tbw-grid-header> children.
|
|
1347
|
+
*/
|
|
1348
|
+
refreshShellHeader(): void;
|
|
1349
|
+
/**
|
|
1350
|
+
* Core virtualization routine. Chooses between bypass (small datasets), grouped window rendering,
|
|
1351
|
+
* or standard row window rendering.
|
|
1352
|
+
*/
|
|
1353
|
+
refreshVirtualWindow(force?: boolean): void;
|
|
1354
|
+
}
|
|
1355
|
+
export { DataGridElement }
|
|
1356
|
+
export { DataGridElement as GridElement }
|
|
1357
|
+
|
|
1358
|
+
/**
|
|
1359
|
+
* The compiled webcomponent interface for DataGrid
|
|
1360
|
+
*/
|
|
1361
|
+
export declare interface DataGridElementInterface extends PublicGrid, HTMLElement {
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
export declare interface DataGridEventMap<TRow = any> {
|
|
1365
|
+
'cell-commit': CellCommitDetail<TRow>;
|
|
1366
|
+
'row-commit': RowCommitDetail<TRow>;
|
|
1367
|
+
'changed-rows-reset': ChangedRowsResetDetail<TRow>;
|
|
1368
|
+
'mount-external-view': ExternalMountViewDetail<TRow>;
|
|
1369
|
+
'mount-external-editor': ExternalMountEditorDetail<TRow>;
|
|
1370
|
+
'sort-change': SortChangeDetail;
|
|
1371
|
+
'column-resize': ColumnResizeDetail;
|
|
1372
|
+
'activate-cell': ActivateCellDetail;
|
|
1373
|
+
'column-state-change': GridColumnState;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/** Data row model item */
|
|
1377
|
+
declare interface DataRowModelItem {
|
|
1378
|
+
kind: 'data';
|
|
1379
|
+
row: any;
|
|
1380
|
+
rowIndex: number;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
export declare type DGEventName = (typeof DGEvents)[keyof typeof DGEvents];
|
|
1384
|
+
|
|
1385
|
+
export declare const DGEvents: {
|
|
1386
|
+
readonly CELL_COMMIT: "cell-commit";
|
|
1387
|
+
readonly ROW_COMMIT: "row-commit";
|
|
1388
|
+
readonly CHANGED_ROWS_RESET: "changed-rows-reset";
|
|
1389
|
+
readonly MOUNT_EXTERNAL_VIEW: "mount-external-view";
|
|
1390
|
+
readonly MOUNT_EXTERNAL_EDITOR: "mount-external-editor";
|
|
1391
|
+
readonly SORT_CHANGE: "sort-change";
|
|
1392
|
+
readonly COLUMN_RESIZE: "column-resize";
|
|
1393
|
+
readonly ACTIVATE_CELL: "activate-cell";
|
|
1394
|
+
readonly GROUP_TOGGLE: "group-toggle";
|
|
1395
|
+
readonly COLUMN_STATE_CHANGE: "column-state-change";
|
|
1396
|
+
};
|
|
1397
|
+
|
|
1398
|
+
/** Represents a single edit action that can be undone/redone */
|
|
1399
|
+
export declare interface EditAction {
|
|
1400
|
+
/** Type of action - currently only 'cell-edit' is supported */
|
|
1401
|
+
type: 'cell-edit';
|
|
1402
|
+
/** The row index where the edit occurred */
|
|
1403
|
+
rowIndex: number;
|
|
1404
|
+
/** The field (column key) that was edited */
|
|
1405
|
+
field: string;
|
|
1406
|
+
/** The value before the edit */
|
|
1407
|
+
oldValue: unknown;
|
|
1408
|
+
/** The value after the edit */
|
|
1409
|
+
newValue: unknown;
|
|
1410
|
+
/** Unix timestamp when the edit occurred */
|
|
1411
|
+
timestamp: number;
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
/**
|
|
1415
|
+
* Internal editor execution context extending the generic cell context with commit helpers.
|
|
1416
|
+
*/
|
|
1417
|
+
declare interface EditorExecContext<T = any> extends CellContext<T> {
|
|
1418
|
+
commit: (newValue: any) => void;
|
|
1419
|
+
cancel: () => void;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
/** Configuration options for the export plugin */
|
|
1423
|
+
declare interface ExportConfig {
|
|
1424
|
+
/** Whether export is enabled (default: true) */
|
|
1425
|
+
enabled?: boolean;
|
|
1426
|
+
/** Default file name for exports (default: 'export') */
|
|
1427
|
+
fileName?: string;
|
|
1428
|
+
/** Include column headers in export (default: true) */
|
|
1429
|
+
includeHeaders?: boolean;
|
|
1430
|
+
/** Export only visible columns (default: true) */
|
|
1431
|
+
onlyVisible?: boolean;
|
|
1432
|
+
/** Export only selected rows (default: false) */
|
|
1433
|
+
onlySelected?: boolean;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
/**
|
|
1437
|
+
* Export Plugin Types
|
|
1438
|
+
*
|
|
1439
|
+
* Type definitions for the data export feature.
|
|
1440
|
+
*/
|
|
1441
|
+
/** Supported export formats */
|
|
1442
|
+
export declare type ExportFormat = 'csv' | 'excel' | 'json';
|
|
1443
|
+
|
|
1444
|
+
/** Parameters for a specific export operation */
|
|
1445
|
+
export declare interface ExportParams {
|
|
1446
|
+
/** Export format */
|
|
1447
|
+
format: ExportFormat;
|
|
1448
|
+
/** File name for the export (without extension) */
|
|
1449
|
+
fileName?: string;
|
|
1450
|
+
/** Specific column fields to export */
|
|
1451
|
+
columns?: string[];
|
|
1452
|
+
/** Specific row indices to export */
|
|
1453
|
+
rowIndices?: number[];
|
|
1454
|
+
/** Include column headers in export */
|
|
1455
|
+
includeHeaders?: boolean;
|
|
1456
|
+
/** Custom cell value processor */
|
|
1457
|
+
processCell?: (value: any, field: string, row: any) => any;
|
|
1458
|
+
/** Custom header processor */
|
|
1459
|
+
processHeader?: (header: string, field: string) => string;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/**
|
|
1463
|
+
* Export Plugin for tbw-grid
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```ts
|
|
1467
|
+
* new ExportPlugin({
|
|
1468
|
+
* enabled: true,
|
|
1469
|
+
* fileName: 'my-data',
|
|
1470
|
+
* includeHeaders: true,
|
|
1471
|
+
* onlyVisible: true,
|
|
1472
|
+
* })
|
|
1473
|
+
* ```
|
|
1474
|
+
*/
|
|
1475
|
+
export declare class ExportPlugin extends BaseGridPlugin<ExportConfig> {
|
|
1476
|
+
readonly name = "export";
|
|
1477
|
+
readonly version = "1.0.0";
|
|
1478
|
+
protected get defaultConfig(): Partial<ExportConfig>;
|
|
1479
|
+
private isExportingFlag;
|
|
1480
|
+
private lastExportInfo;
|
|
1481
|
+
private performExport;
|
|
1482
|
+
private getSelectionState;
|
|
1483
|
+
/**
|
|
1484
|
+
* Export data to CSV format.
|
|
1485
|
+
* @param params - Optional export parameters
|
|
1486
|
+
*/
|
|
1487
|
+
exportCsv(params?: Partial<ExportParams>): void;
|
|
1488
|
+
/**
|
|
1489
|
+
* Export data to Excel format (XML Spreadsheet).
|
|
1490
|
+
* @param params - Optional export parameters
|
|
1491
|
+
*/
|
|
1492
|
+
exportExcel(params?: Partial<ExportParams>): void;
|
|
1493
|
+
/**
|
|
1494
|
+
* Export data to JSON format.
|
|
1495
|
+
* @param params - Optional export parameters
|
|
1496
|
+
*/
|
|
1497
|
+
exportJson(params?: Partial<ExportParams>): void;
|
|
1498
|
+
/**
|
|
1499
|
+
* Check if an export is currently in progress.
|
|
1500
|
+
* @returns Whether export is in progress
|
|
1501
|
+
*/
|
|
1502
|
+
isExporting(): boolean;
|
|
1503
|
+
/**
|
|
1504
|
+
* Get information about the last export.
|
|
1505
|
+
* @returns Export info or null if no export has occurred
|
|
1506
|
+
*/
|
|
1507
|
+
getLastExport(): {
|
|
1508
|
+
format: ExportFormat;
|
|
1509
|
+
timestamp: Date;
|
|
1510
|
+
} | null;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
export declare interface ExternalMountEditorDetail<TRow = any> {
|
|
1514
|
+
placeholder: HTMLElement;
|
|
1515
|
+
spec: any;
|
|
1516
|
+
context: {
|
|
1517
|
+
row: TRow;
|
|
1518
|
+
value: any;
|
|
1519
|
+
field: string;
|
|
1520
|
+
column: any;
|
|
1521
|
+
commit: (v: any) => void;
|
|
1522
|
+
cancel: () => void;
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
export declare interface ExternalMountViewDetail<TRow = any> {
|
|
1527
|
+
placeholder: HTMLElement;
|
|
1528
|
+
spec: any;
|
|
1529
|
+
context: {
|
|
1530
|
+
row: TRow;
|
|
1531
|
+
value: any;
|
|
1532
|
+
field: string;
|
|
1533
|
+
column: any;
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
/** Configuration options for the filtering plugin */
|
|
1538
|
+
export declare interface FilterConfig {
|
|
1539
|
+
/** Whether filtering is enabled (default: true) */
|
|
1540
|
+
enabled?: boolean;
|
|
1541
|
+
/** Debounce delay in ms for filter input (default: 300) */
|
|
1542
|
+
debounceMs?: number;
|
|
1543
|
+
/** Whether text filtering is case sensitive (default: false) */
|
|
1544
|
+
caseSensitive?: boolean;
|
|
1545
|
+
/** Whether to trim whitespace from filter input (default: true) */
|
|
1546
|
+
trimInput?: boolean;
|
|
1547
|
+
/** Use Web Worker for filtering large datasets >1000 rows (default: true) */
|
|
1548
|
+
useWorker?: boolean;
|
|
1549
|
+
/** Custom filter panel renderer (replaces default panel content) */
|
|
1550
|
+
filterPanelRenderer?: FilterPanelRenderer;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Filtering Plugin for tbw-grid
|
|
1555
|
+
*
|
|
1556
|
+
* @example
|
|
1557
|
+
* ```ts
|
|
1558
|
+
* new FilteringPlugin({ enabled: true, debounceMs: 300 })
|
|
1559
|
+
* ```
|
|
1560
|
+
*/
|
|
1561
|
+
export declare class FilteringPlugin extends BaseGridPlugin<FilterConfig> {
|
|
1562
|
+
readonly name = "filtering";
|
|
1563
|
+
readonly version = "1.0.0";
|
|
1564
|
+
protected get defaultConfig(): Partial<FilterConfig>;
|
|
1565
|
+
private filters;
|
|
1566
|
+
private cachedResult;
|
|
1567
|
+
private cacheKey;
|
|
1568
|
+
private openPanelField;
|
|
1569
|
+
private panelElement;
|
|
1570
|
+
private searchText;
|
|
1571
|
+
private excludedValues;
|
|
1572
|
+
private documentClickHandler;
|
|
1573
|
+
private globalStylesInjected;
|
|
1574
|
+
private static readonly LIST_ITEM_HEIGHT;
|
|
1575
|
+
private static readonly LIST_OVERSCAN;
|
|
1576
|
+
private static readonly LIST_BYPASS_THRESHOLD;
|
|
1577
|
+
attach(grid: GridElement_2): void;
|
|
1578
|
+
detach(): void;
|
|
1579
|
+
processRows(rows: readonly unknown[]): unknown[];
|
|
1580
|
+
afterRender(): void;
|
|
1581
|
+
/**
|
|
1582
|
+
* Set a filter on a specific field.
|
|
1583
|
+
* Pass null to remove the filter.
|
|
1584
|
+
*/
|
|
1585
|
+
setFilter(field: string, filter: Omit<FilterModel, 'field'> | null): void;
|
|
1586
|
+
/**
|
|
1587
|
+
* Get the current filter for a field.
|
|
1588
|
+
*/
|
|
1589
|
+
getFilter(field: string): FilterModel | undefined;
|
|
1590
|
+
/**
|
|
1591
|
+
* Get all active filters.
|
|
1592
|
+
*/
|
|
1593
|
+
getFilters(): FilterModel[];
|
|
1594
|
+
/**
|
|
1595
|
+
* Alias for getFilters() to match functional API naming.
|
|
1596
|
+
*/
|
|
1597
|
+
getFilterModel(): FilterModel[];
|
|
1598
|
+
/**
|
|
1599
|
+
* Set filters from an array (replaces all existing filters).
|
|
1600
|
+
*/
|
|
1601
|
+
setFilterModel(filters: FilterModel[]): void;
|
|
1602
|
+
/**
|
|
1603
|
+
* Clear all filters.
|
|
1604
|
+
*/
|
|
1605
|
+
clearAllFilters(): void;
|
|
1606
|
+
/**
|
|
1607
|
+
* Clear filter for a specific field.
|
|
1608
|
+
*/
|
|
1609
|
+
clearFieldFilter(field: string): void;
|
|
1610
|
+
/**
|
|
1611
|
+
* Check if a field has an active filter.
|
|
1612
|
+
*/
|
|
1613
|
+
isFieldFiltered(field: string): boolean;
|
|
1614
|
+
/**
|
|
1615
|
+
* Get the count of filtered rows (from cache).
|
|
1616
|
+
*/
|
|
1617
|
+
getFilteredRowCount(): number;
|
|
1618
|
+
/**
|
|
1619
|
+
* Get all active filters (alias for getFilters).
|
|
1620
|
+
*/
|
|
1621
|
+
getActiveFilters(): FilterModel[];
|
|
1622
|
+
/**
|
|
1623
|
+
* Get unique values for a field (for set filter dropdowns).
|
|
1624
|
+
* Uses sourceRows to include all values regardless of current filter.
|
|
1625
|
+
*/
|
|
1626
|
+
getUniqueValues(field: string): unknown[];
|
|
1627
|
+
/**
|
|
1628
|
+
* Inject global styles for filter panel (rendered in document.body)
|
|
1629
|
+
*/
|
|
1630
|
+
private injectGlobalStyles;
|
|
1631
|
+
/**
|
|
1632
|
+
* Toggle the filter panel for a field
|
|
1633
|
+
*/
|
|
1634
|
+
private toggleFilterPanel;
|
|
1635
|
+
/**
|
|
1636
|
+
* Close the filter panel
|
|
1637
|
+
*/
|
|
1638
|
+
private closeFilterPanel;
|
|
1639
|
+
/**
|
|
1640
|
+
* Remove the document click handler
|
|
1641
|
+
*/
|
|
1642
|
+
private removeDocumentClickHandler;
|
|
1643
|
+
/**
|
|
1644
|
+
* Position the panel below the button
|
|
1645
|
+
*/
|
|
1646
|
+
private positionPanel;
|
|
1647
|
+
/**
|
|
1648
|
+
* Render the default filter panel content
|
|
1649
|
+
*/
|
|
1650
|
+
private renderDefaultFilterPanel;
|
|
1651
|
+
/**
|
|
1652
|
+
* Apply a set filter (exclude values)
|
|
1653
|
+
*/
|
|
1654
|
+
private applySetFilter;
|
|
1655
|
+
/**
|
|
1656
|
+
* Apply a text filter
|
|
1657
|
+
*/
|
|
1658
|
+
private applyTextFilter;
|
|
1659
|
+
/**
|
|
1660
|
+
* Return filter state for a column if it has an active filter.
|
|
1661
|
+
*/
|
|
1662
|
+
getColumnState(field: string): Partial<ColumnState> | undefined;
|
|
1663
|
+
/**
|
|
1664
|
+
* Apply filter state from column state.
|
|
1665
|
+
*/
|
|
1666
|
+
applyColumnState(field: string, state: ColumnState): void;
|
|
1667
|
+
readonly styles = "\n .header-cell.filtered::before {\n content: '';\n position: absolute;\n top: 4px;\n right: 4px;\n width: 6px;\n height: 6px;\n background: var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));\n border-radius: 50%;\n }\n .tbw-filter-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 2px;\n margin-left: 4px;\n opacity: 0.4;\n transition: opacity 0.15s;\n color: inherit;\n vertical-align: middle;\n }\n .tbw-filter-btn:hover,\n .tbw-filter-btn.active {\n opacity: 1;\n }\n .tbw-filter-btn.active {\n color: var(--tbw-filter-accent, var(--tbw-color-accent, #3b82f6));\n }\n ";
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
/** Filter model representing a single filter condition */
|
|
1671
|
+
export declare interface FilterModel {
|
|
1672
|
+
/** The field/column to filter on */
|
|
1673
|
+
field: string;
|
|
1674
|
+
/** The type of filter */
|
|
1675
|
+
type: FilterType;
|
|
1676
|
+
/** The filter operator */
|
|
1677
|
+
operator: FilterOperator;
|
|
1678
|
+
/** The filter value (type depends on operator) */
|
|
1679
|
+
value: unknown;
|
|
1680
|
+
/** Secondary value for 'between' operator */
|
|
1681
|
+
valueTo?: unknown;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
/** Filter operators for different filter types */
|
|
1685
|
+
export declare type FilterOperator = 'contains' | 'notContains' | 'equals' | 'notEquals' | 'startsWith' | 'endsWith' | 'blank' | 'notBlank' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'between' | 'in' | 'notIn';
|
|
1686
|
+
|
|
1687
|
+
/** Parameters passed to custom filter panel renderer */
|
|
1688
|
+
declare interface FilterPanelParams {
|
|
1689
|
+
/** The field being filtered */
|
|
1690
|
+
field: string;
|
|
1691
|
+
/** The column configuration */
|
|
1692
|
+
column: ColumnConfig;
|
|
1693
|
+
/** All unique values for this field */
|
|
1694
|
+
uniqueValues: unknown[];
|
|
1695
|
+
/** Currently excluded values (for set filter) */
|
|
1696
|
+
excludedValues: Set<unknown>;
|
|
1697
|
+
/** Current search text */
|
|
1698
|
+
searchText: string;
|
|
1699
|
+
/** Apply a set filter (exclude these values) */
|
|
1700
|
+
applySetFilter: (excludedValues: unknown[]) => void;
|
|
1701
|
+
/** Apply a text filter */
|
|
1702
|
+
applyTextFilter: (operator: FilterOperator, value: string, valueTo?: string) => void;
|
|
1703
|
+
/** Clear the filter for this field */
|
|
1704
|
+
clearFilter: () => void;
|
|
1705
|
+
/** Close the filter panel */
|
|
1706
|
+
closePanel: () => void;
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
/** Custom filter panel renderer function. Return undefined to use default panel for this column. */
|
|
1710
|
+
declare type FilterPanelRenderer = (container: HTMLElement, params: FilterPanelParams) => void | undefined;
|
|
1711
|
+
|
|
1712
|
+
/** Supported filter types */
|
|
1713
|
+
export declare type FilterType = 'text' | 'number' | 'date' | 'set' | 'boolean';
|
|
1714
|
+
|
|
1715
|
+
export declare type FitMode = (typeof FitModeEnum)[keyof typeof FitModeEnum];
|
|
1716
|
+
|
|
1717
|
+
export declare const FitModeEnum: {
|
|
1718
|
+
readonly STRETCH: "stretch";
|
|
1719
|
+
readonly FIXED: "fixed";
|
|
1720
|
+
};
|
|
1721
|
+
|
|
1722
|
+
/** A flattened tree row with hierarchy metadata */
|
|
1723
|
+
declare interface FlattenedTreeRow {
|
|
1724
|
+
/** Unique key identifying this row */
|
|
1725
|
+
key: string;
|
|
1726
|
+
/** Original row data */
|
|
1727
|
+
data: any;
|
|
1728
|
+
/** Depth level in the tree (0 = root) */
|
|
1729
|
+
depth: number;
|
|
1730
|
+
/** Whether this row has children */
|
|
1731
|
+
hasChildren: boolean;
|
|
1732
|
+
/** Whether this row is currently expanded */
|
|
1733
|
+
isExpanded: boolean;
|
|
1734
|
+
/** Key of the parent row, or null for root level */
|
|
1735
|
+
parentKey: string | null;
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
export declare interface GetRowsParams {
|
|
1739
|
+
startRow: number;
|
|
1740
|
+
endRow: number;
|
|
1741
|
+
sortModel?: Array<{
|
|
1742
|
+
field: string;
|
|
1743
|
+
direction: 'asc' | 'desc';
|
|
1744
|
+
}>;
|
|
1745
|
+
filterModel?: Record<string, any>;
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
export declare interface GetRowsResult {
|
|
1749
|
+
rows: any[];
|
|
1750
|
+
totalRowCount: number;
|
|
1751
|
+
lastRow?: number;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
/**
|
|
1755
|
+
* CSS class names used in the grid's shadow DOM.
|
|
1756
|
+
* Use these when adding/removing classes or querying elements.
|
|
1757
|
+
*/
|
|
1758
|
+
export declare const GridClasses: {
|
|
1759
|
+
readonly ROOT: "tbw-grid-root";
|
|
1760
|
+
readonly HEADER: "header";
|
|
1761
|
+
readonly HEADER_ROW: "header-row";
|
|
1762
|
+
readonly HEADER_CELL: "header-cell";
|
|
1763
|
+
readonly ROWS_VIEWPORT: "rows-viewport";
|
|
1764
|
+
readonly ROWS_SPACER: "rows-spacer";
|
|
1765
|
+
readonly ROWS_CONTAINER: "rows";
|
|
1766
|
+
readonly DATA_ROW: "data-row";
|
|
1767
|
+
readonly GROUP_ROW: "group-row";
|
|
1768
|
+
readonly DATA_CELL: "data-cell";
|
|
1769
|
+
readonly SELECTED: "selected";
|
|
1770
|
+
readonly FOCUSED: "focused";
|
|
1771
|
+
readonly EDITING: "editing";
|
|
1772
|
+
readonly EXPANDED: "expanded";
|
|
1773
|
+
readonly COLLAPSED: "collapsed";
|
|
1774
|
+
readonly DRAGGING: "dragging";
|
|
1775
|
+
readonly RESIZING: "resizing";
|
|
1776
|
+
readonly SORTABLE: "sortable";
|
|
1777
|
+
readonly SORTED_ASC: "sorted-asc";
|
|
1778
|
+
readonly SORTED_DESC: "sorted-desc";
|
|
1779
|
+
readonly HIDDEN: "hidden";
|
|
1780
|
+
readonly STICKY_LEFT: "sticky-left";
|
|
1781
|
+
readonly STICKY_RIGHT: "sticky-right";
|
|
1782
|
+
readonly PINNED_TOP: "pinned-top";
|
|
1783
|
+
readonly PINNED_BOTTOM: "pinned-bottom";
|
|
1784
|
+
readonly TREE_TOGGLE: "tree-toggle";
|
|
1785
|
+
readonly TREE_INDENT: "tree-indent";
|
|
1786
|
+
readonly GROUP_TOGGLE: "group-toggle";
|
|
1787
|
+
readonly GROUP_LABEL: "group-label";
|
|
1788
|
+
readonly GROUP_COUNT: "group-count";
|
|
1789
|
+
readonly RANGE_SELECTION: "range-selection";
|
|
1790
|
+
readonly SELECTION_OVERLAY: "selection-overlay";
|
|
1791
|
+
};
|
|
1792
|
+
|
|
1793
|
+
export declare type GridClassName = (typeof GridClasses)[keyof typeof GridClasses];
|
|
1794
|
+
|
|
1795
|
+
/**
|
|
1796
|
+
* Complete grid column state for persistence.
|
|
1797
|
+
* Contains state for all columns, including plugin-contributed properties.
|
|
1798
|
+
*/
|
|
1799
|
+
export declare interface GridColumnState {
|
|
1800
|
+
columns: ColumnState[];
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
/**
|
|
1804
|
+
* Grid configuration object - the **single source of truth** for grid behavior.
|
|
1805
|
+
*
|
|
1806
|
+
* Users can configure the grid via multiple input methods, all of which converge
|
|
1807
|
+
* into an effective `GridConfig` internally:
|
|
1808
|
+
*
|
|
1809
|
+
* **Configuration Input Methods:**
|
|
1810
|
+
* - `gridConfig` property - direct assignment of this object
|
|
1811
|
+
* - `columns` property - shorthand for `gridConfig.columns`
|
|
1812
|
+
* - `fitMode` property - shorthand for `gridConfig.fitMode`
|
|
1813
|
+
* - `editOn` property - shorthand for `gridConfig.editOn`
|
|
1814
|
+
* - Light DOM `<tbw-grid-column>` - declarative columns (merged into `columns`)
|
|
1815
|
+
* - Light DOM `<tbw-grid-header>` - declarative shell header (merged into `shell.header`)
|
|
1816
|
+
*
|
|
1817
|
+
* **Precedence (when same property set multiple ways):**
|
|
1818
|
+
* Individual props (`fitMode`, `editOn`) > `columns` prop > Light DOM > `gridConfig`
|
|
1819
|
+
*
|
|
1820
|
+
* @example
|
|
1821
|
+
* ```ts
|
|
1822
|
+
* // Via gridConfig (recommended for complex setups)
|
|
1823
|
+
* grid.gridConfig = {
|
|
1824
|
+
* columns: [{ field: 'name' }, { field: 'age' }],
|
|
1825
|
+
* fitMode: 'stretch',
|
|
1826
|
+
* plugins: [new SelectionPlugin()],
|
|
1827
|
+
* shell: { header: { title: 'My Grid' } }
|
|
1828
|
+
* };
|
|
1829
|
+
*
|
|
1830
|
+
* // Via individual props (convenience for simple cases)
|
|
1831
|
+
* grid.columns = [{ field: 'name' }, { field: 'age' }];
|
|
1832
|
+
* grid.fitMode = 'stretch';
|
|
1833
|
+
* ```
|
|
1834
|
+
*/
|
|
1835
|
+
export declare interface GridConfig<TRow = any> {
|
|
1836
|
+
/** Column definitions. Can also be set via `columns` prop or `<tbw-grid-column>` light DOM. */
|
|
1837
|
+
columns?: ColumnConfigMap<TRow>;
|
|
1838
|
+
/** Sizing mode for columns. Can also be set via `fitMode` prop. */
|
|
1839
|
+
fitMode?: FitMode;
|
|
1840
|
+
/** Edit activation mode ('click' | 'dblclick'). Can also be set via `editOn` prop. */
|
|
1841
|
+
editOn?: string;
|
|
1842
|
+
/**
|
|
1843
|
+
* Array of plugin instances.
|
|
1844
|
+
* Each plugin is instantiated with its configuration and attached to this grid.
|
|
1845
|
+
*
|
|
1846
|
+
* @example
|
|
1847
|
+
* ```ts
|
|
1848
|
+
* plugins: [
|
|
1849
|
+
* new SelectionPlugin({ mode: 'range' }),
|
|
1850
|
+
* new MultiSortPlugin(),
|
|
1851
|
+
* new FilteringPlugin({ debounceMs: 150 }),
|
|
1852
|
+
* ]
|
|
1853
|
+
* ```
|
|
1854
|
+
*/
|
|
1855
|
+
plugins?: any[];
|
|
1856
|
+
/**
|
|
1857
|
+
* Saved column state to restore on initialization.
|
|
1858
|
+
* Includes order, width, visibility, sort, and plugin-contributed state.
|
|
1859
|
+
*/
|
|
1860
|
+
columnState?: GridColumnState;
|
|
1861
|
+
/**
|
|
1862
|
+
* Shell configuration for header bar and tool panels.
|
|
1863
|
+
* When configured, adds an optional wrapper with title, toolbar, and collapsible side panels.
|
|
1864
|
+
*/
|
|
1865
|
+
shell?: ShellConfig;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
export declare type GridCSSVar = (typeof GridCSSVars)[keyof typeof GridCSSVars];
|
|
1869
|
+
|
|
1870
|
+
/**
|
|
1871
|
+
* CSS custom property names for theming.
|
|
1872
|
+
* Use these when programmatically setting styles.
|
|
1873
|
+
*/
|
|
1874
|
+
export declare const GridCSSVars: {
|
|
1875
|
+
readonly COLOR_BG: "--tbw-color-bg";
|
|
1876
|
+
readonly COLOR_FG: "--tbw-color-fg";
|
|
1877
|
+
readonly COLOR_FG_MUTED: "--tbw-color-fg-muted";
|
|
1878
|
+
readonly COLOR_BORDER: "--tbw-color-border";
|
|
1879
|
+
readonly COLOR_ACCENT: "--tbw-color-accent";
|
|
1880
|
+
readonly COLOR_HEADER_BG: "--tbw-color-header-bg";
|
|
1881
|
+
readonly COLOR_HEADER_FG: "--tbw-color-header-fg";
|
|
1882
|
+
readonly COLOR_SELECTION: "--tbw-color-selection";
|
|
1883
|
+
readonly COLOR_ROW_HOVER: "--tbw-color-row-hover";
|
|
1884
|
+
readonly COLOR_ROW_ALT: "--tbw-color-row-alt";
|
|
1885
|
+
readonly ROW_HEIGHT: "--tbw-row-height";
|
|
1886
|
+
readonly HEADER_HEIGHT: "--tbw-header-height";
|
|
1887
|
+
readonly CELL_PADDING: "--tbw-cell-padding";
|
|
1888
|
+
readonly FONT_FAMILY: "--tbw-font-family";
|
|
1889
|
+
readonly FONT_SIZE: "--tbw-font-size";
|
|
1890
|
+
readonly BORDER_RADIUS: "--tbw-border-radius";
|
|
1891
|
+
readonly FOCUS_OUTLINE: "--tbw-focus-outline";
|
|
1892
|
+
};
|
|
1893
|
+
|
|
1894
|
+
export declare type GridDataAttr = (typeof GridDataAttrs)[keyof typeof GridDataAttrs];
|
|
1895
|
+
|
|
1896
|
+
/**
|
|
1897
|
+
* Data attribute names used on grid elements.
|
|
1898
|
+
* Use these when getting/setting data attributes.
|
|
1899
|
+
*/
|
|
1900
|
+
export declare const GridDataAttrs: {
|
|
1901
|
+
readonly ROW_INDEX: "data-row-index";
|
|
1902
|
+
readonly COL_INDEX: "data-col-index";
|
|
1903
|
+
readonly FIELD: "data-field";
|
|
1904
|
+
readonly GROUP_KEY: "data-group-key";
|
|
1905
|
+
readonly TREE_LEVEL: "data-tree-level";
|
|
1906
|
+
readonly STICKY: "data-sticky";
|
|
1907
|
+
};
|
|
1908
|
+
|
|
1909
|
+
declare interface GridElement_2 {
|
|
1910
|
+
shadowRoot: ShadowRoot | null;
|
|
1911
|
+
rows: any[];
|
|
1912
|
+
columns: ColumnConfig[];
|
|
1913
|
+
gridConfig: any;
|
|
1914
|
+
requestRender(): void;
|
|
1915
|
+
requestAfterRender(): void;
|
|
1916
|
+
forceLayout(): Promise<void>;
|
|
1917
|
+
getPlugin<T extends BaseGridPlugin>(PluginClass: new (...args: any[]) => T): T | undefined;
|
|
1918
|
+
getPluginByName(name: string): BaseGridPlugin | undefined;
|
|
1919
|
+
dispatchEvent(event: Event): boolean;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
/**
|
|
1923
|
+
* Common CSS selectors for querying grid elements.
|
|
1924
|
+
* Built from the class constants for consistency.
|
|
1925
|
+
*/
|
|
1926
|
+
export declare const GridSelectors: {
|
|
1927
|
+
readonly ROOT: ".tbw-grid-root";
|
|
1928
|
+
readonly HEADER: ".header";
|
|
1929
|
+
readonly HEADER_ROW: ".header-row";
|
|
1930
|
+
readonly HEADER_CELL: ".header-cell";
|
|
1931
|
+
readonly ROWS_VIEWPORT: ".rows-viewport";
|
|
1932
|
+
readonly ROWS_CONTAINER: ".rows";
|
|
1933
|
+
readonly DATA_ROW: ".data-row";
|
|
1934
|
+
readonly DATA_CELL: ".data-cell";
|
|
1935
|
+
readonly GROUP_ROW: ".group-row";
|
|
1936
|
+
readonly ROW_BY_INDEX: (index: number) => string;
|
|
1937
|
+
readonly CELL_BY_FIELD: (field: string) => string;
|
|
1938
|
+
readonly CELL_AT: (row: number, col: number) => string;
|
|
1939
|
+
readonly SELECTED_ROWS: ".data-row.selected";
|
|
1940
|
+
readonly EDITING_CELL: ".data-cell.editing";
|
|
1941
|
+
};
|
|
1942
|
+
|
|
1943
|
+
/** Parameters passed to custom group header renderer */
|
|
1944
|
+
declare interface GroupHeaderRenderParams {
|
|
1945
|
+
/** The group ID */
|
|
1946
|
+
id: string;
|
|
1947
|
+
/** The group label (or id if no label) */
|
|
1948
|
+
label: string;
|
|
1949
|
+
/** Columns in this group */
|
|
1950
|
+
columns: ColumnConfig[];
|
|
1951
|
+
/** Starting column index */
|
|
1952
|
+
firstIndex: number;
|
|
1953
|
+
/** Whether this is an implicit (unnamed) group */
|
|
1954
|
+
isImplicit: boolean;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
/** Configuration options for the column groups plugin */
|
|
1958
|
+
declare interface GroupingColumnsConfig {
|
|
1959
|
+
/** Whether the plugin is enabled (default: true) */
|
|
1960
|
+
enabled?: boolean;
|
|
1961
|
+
/** Custom group header renderer */
|
|
1962
|
+
groupHeaderRenderer?: (params: GroupHeaderRenderParams) => HTMLElement | string | void;
|
|
1963
|
+
/** Whether to show group borders (default: true) */
|
|
1964
|
+
showGroupBorders?: boolean;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
/**
|
|
1968
|
+
* Column Groups Plugin for tbw-grid
|
|
1969
|
+
*
|
|
1970
|
+
* @example
|
|
1971
|
+
* ```ts
|
|
1972
|
+
* new GroupingColumnsPlugin({
|
|
1973
|
+
* enabled: true,
|
|
1974
|
+
* showGroupBorders: true,
|
|
1975
|
+
* })
|
|
1976
|
+
* ```
|
|
1977
|
+
*/
|
|
1978
|
+
export declare class GroupingColumnsPlugin extends BaseGridPlugin<GroupingColumnsConfig> {
|
|
1979
|
+
readonly name = "groupingColumns";
|
|
1980
|
+
readonly version = "1.0.0";
|
|
1981
|
+
protected get defaultConfig(): Partial<GroupingColumnsConfig>;
|
|
1982
|
+
private groups;
|
|
1983
|
+
private isActive;
|
|
1984
|
+
detach(): void;
|
|
1985
|
+
/**
|
|
1986
|
+
* Auto-detect column groups from column configuration.
|
|
1987
|
+
*/
|
|
1988
|
+
static detect(rows: readonly any[], config: any): boolean;
|
|
1989
|
+
processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
1990
|
+
afterRender(): void;
|
|
1991
|
+
/**
|
|
1992
|
+
* Check if column groups are active.
|
|
1993
|
+
* @returns Whether grouping is active
|
|
1994
|
+
*/
|
|
1995
|
+
isGroupingActive(): boolean;
|
|
1996
|
+
/**
|
|
1997
|
+
* Get the computed column groups.
|
|
1998
|
+
* @returns Array of column groups
|
|
1999
|
+
*/
|
|
2000
|
+
getGroups(): ColumnGroup[];
|
|
2001
|
+
/**
|
|
2002
|
+
* Get columns in a specific group.
|
|
2003
|
+
* @param groupId - The group ID to find
|
|
2004
|
+
* @returns Array of columns in the group
|
|
2005
|
+
*/
|
|
2006
|
+
getGroupColumns(groupId: string): ColumnConfig[];
|
|
2007
|
+
/**
|
|
2008
|
+
* Refresh column groups (recompute from current columns).
|
|
2009
|
+
*/
|
|
2010
|
+
refresh(): void;
|
|
2011
|
+
readonly styles = "\n .header-group-row {\n display: grid;\n grid-auto-flow: column;\n background: var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));\n border-bottom: 1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border));\n }\n .header-group-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 4px 8px;\n font-weight: 600;\n font-size: 0.9em;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border-right: 1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border));\n }\n .header-group-cell:last-child {\n border-right: none;\n }\n .header-row .cell.grouped {\n border-top: none;\n }\n .header-row .cell.group-end {\n border-right: 2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong));\n }\n ";
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
/** Configuration options for the row grouping plugin */
|
|
2015
|
+
export declare interface GroupingRowsConfig {
|
|
2016
|
+
/** Whether the plugin is enabled (default: true) */
|
|
2017
|
+
enabled?: boolean;
|
|
2018
|
+
/**
|
|
2019
|
+
* Callback to determine group path for a row.
|
|
2020
|
+
* Return an array of group keys, a single key, null/false to skip grouping.
|
|
2021
|
+
*/
|
|
2022
|
+
groupOn?: (row: any) => any[] | any | null | false;
|
|
2023
|
+
/** Whether groups are expanded by default (default: false) */
|
|
2024
|
+
defaultExpanded?: boolean;
|
|
2025
|
+
/** Custom group row renderer */
|
|
2026
|
+
groupRowRenderer?: (params: GroupRowRenderParams) => HTMLElement | string | void;
|
|
2027
|
+
/** Show row count in group headers (default: true) */
|
|
2028
|
+
showRowCount?: boolean;
|
|
2029
|
+
/** Indent width per depth level in pixels (default: 20) */
|
|
2030
|
+
indentWidth?: number;
|
|
2031
|
+
/** Aggregators for group row cells by field name */
|
|
2032
|
+
aggregators?: AggregatorMap;
|
|
2033
|
+
/** Custom format function for group label */
|
|
2034
|
+
formatLabel?: (value: any, depth: number, key: string) => string;
|
|
2035
|
+
/** Whether to render group row as full-width spanning cell (default: true) */
|
|
2036
|
+
fullWidth?: boolean;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/**
|
|
2040
|
+
* Row Grouping Plugin for tbw-grid
|
|
2041
|
+
*
|
|
2042
|
+
* @example
|
|
2043
|
+
* ```ts
|
|
2044
|
+
* new GroupingRowsPlugin({
|
|
2045
|
+
* enabled: true,
|
|
2046
|
+
* groupOn: (row) => row.category,
|
|
2047
|
+
* defaultExpanded: false,
|
|
2048
|
+
* showRowCount: true,
|
|
2049
|
+
* })
|
|
2050
|
+
* ```
|
|
2051
|
+
*/
|
|
2052
|
+
export declare class GroupingRowsPlugin extends BaseGridPlugin<GroupingRowsConfig> {
|
|
2053
|
+
readonly name = "groupingRows";
|
|
2054
|
+
readonly version = "1.0.0";
|
|
2055
|
+
protected get defaultConfig(): Partial<GroupingRowsConfig>;
|
|
2056
|
+
private expandedKeys;
|
|
2057
|
+
private flattenedRows;
|
|
2058
|
+
private isActive;
|
|
2059
|
+
detach(): void;
|
|
2060
|
+
/**
|
|
2061
|
+
* Auto-detect grouping configuration from grid config.
|
|
2062
|
+
* Called by plugin system to determine if plugin should activate.
|
|
2063
|
+
*/
|
|
2064
|
+
static detect(rows: readonly any[], config: any): boolean;
|
|
2065
|
+
processRows(rows: readonly any[]): any[];
|
|
2066
|
+
onCellClick(event: CellClickEvent): boolean | void;
|
|
2067
|
+
/**
|
|
2068
|
+
* Render a row. Returns true if we handled the row (group row), false otherwise.
|
|
2069
|
+
*/
|
|
2070
|
+
renderRow(row: any, rowEl: HTMLElement, _rowIndex: number): boolean;
|
|
2071
|
+
afterRender(): void;
|
|
2072
|
+
private renderFullWidthGroupRow;
|
|
2073
|
+
private renderPerColumnGroupRow;
|
|
2074
|
+
/**
|
|
2075
|
+
* Expand all groups.
|
|
2076
|
+
*/
|
|
2077
|
+
expandAll(): void;
|
|
2078
|
+
/**
|
|
2079
|
+
* Collapse all groups.
|
|
2080
|
+
*/
|
|
2081
|
+
collapseAll(): void;
|
|
2082
|
+
/**
|
|
2083
|
+
* Toggle expansion of a specific group.
|
|
2084
|
+
* @param key - The group key to toggle
|
|
2085
|
+
*/
|
|
2086
|
+
toggle(key: string): void;
|
|
2087
|
+
/**
|
|
2088
|
+
* Check if a specific group is expanded.
|
|
2089
|
+
* @param key - The group key to check
|
|
2090
|
+
* @returns Whether the group is expanded
|
|
2091
|
+
*/
|
|
2092
|
+
isExpanded(key: string): boolean;
|
|
2093
|
+
/**
|
|
2094
|
+
* Expand a specific group.
|
|
2095
|
+
* @param key - The group key to expand
|
|
2096
|
+
*/
|
|
2097
|
+
expand(key: string): void;
|
|
2098
|
+
/**
|
|
2099
|
+
* Collapse a specific group.
|
|
2100
|
+
* @param key - The group key to collapse
|
|
2101
|
+
*/
|
|
2102
|
+
collapse(key: string): void;
|
|
2103
|
+
/**
|
|
2104
|
+
* Get the current group state.
|
|
2105
|
+
* @returns Group state information
|
|
2106
|
+
*/
|
|
2107
|
+
getGroupState(): GroupState;
|
|
2108
|
+
/**
|
|
2109
|
+
* Get the total count of visible rows (including group headers).
|
|
2110
|
+
* @returns Number of visible rows
|
|
2111
|
+
*/
|
|
2112
|
+
getRowCount(): number;
|
|
2113
|
+
/**
|
|
2114
|
+
* Refresh the grouped row model.
|
|
2115
|
+
* Call this after modifying groupOn or other config options.
|
|
2116
|
+
*/
|
|
2117
|
+
refreshGroups(): void;
|
|
2118
|
+
/**
|
|
2119
|
+
* Get current expanded group keys.
|
|
2120
|
+
* @returns Array of expanded group keys
|
|
2121
|
+
*/
|
|
2122
|
+
getExpandedGroups(): string[];
|
|
2123
|
+
/**
|
|
2124
|
+
* Get the flattened row model.
|
|
2125
|
+
* @returns Array of render rows (groups + data rows)
|
|
2126
|
+
*/
|
|
2127
|
+
getFlattenedRows(): RenderRow[];
|
|
2128
|
+
/**
|
|
2129
|
+
* Check if grouping is currently active.
|
|
2130
|
+
* @returns Whether grouping is active
|
|
2131
|
+
*/
|
|
2132
|
+
isGroupingActive(): boolean;
|
|
2133
|
+
/**
|
|
2134
|
+
* Set the groupOn function dynamically.
|
|
2135
|
+
* @param fn - The groupOn function or undefined to disable
|
|
2136
|
+
*/
|
|
2137
|
+
setGroupOn(fn: ((row: any) => any[] | any | null | false) | undefined): void;
|
|
2138
|
+
readonly styles = "\n .group-row {\n background: var(--tbw-grouping-rows-bg, var(--tbw-color-panel-bg));\n font-weight: 500;\n }\n .group-row:hover {\n background: var(--tbw-grouping-rows-bg-hover, var(--tbw-color-row-hover));\n }\n .group-toggle {\n cursor: pointer;\n user-select: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n margin-right: 4px;\n font-size: 10px;\n }\n .group-toggle:hover {\n background: var(--tbw-grouping-rows-toggle-hover, var(--tbw-color-row-hover));\n border-radius: 2px;\n }\n .group-label {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n }\n .group-count {\n color: var(--tbw-grouping-rows-count-color, var(--tbw-color-fg-muted));\n font-size: 0.85em;\n font-weight: normal;\n }\n [data-group-depth=\"0\"] .group-label { padding-left: 0; }\n [data-group-depth=\"1\"] .group-label { padding-left: 20px; }\n [data-group-depth=\"2\"] .group-label { padding-left: 40px; }\n [data-group-depth=\"3\"] .group-label { padding-left: 60px; }\n [data-group-depth=\"4\"] .group-label { padding-left: 80px; }\n ";
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
/** Group row model item */
|
|
2142
|
+
declare interface GroupRowModelItem {
|
|
2143
|
+
kind: 'group';
|
|
2144
|
+
key: string;
|
|
2145
|
+
value: any;
|
|
2146
|
+
depth: number;
|
|
2147
|
+
rows: any[];
|
|
2148
|
+
expanded: boolean;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
/** Parameters passed to custom group row renderer */
|
|
2152
|
+
declare interface GroupRowRenderParams {
|
|
2153
|
+
/** The group key */
|
|
2154
|
+
key: string;
|
|
2155
|
+
/** The group value (last segment of path) */
|
|
2156
|
+
value: any;
|
|
2157
|
+
/** Depth level (0-based) */
|
|
2158
|
+
depth: number;
|
|
2159
|
+
/** All data rows in this group (including nested) */
|
|
2160
|
+
rows: any[];
|
|
2161
|
+
/** Whether the group is expanded */
|
|
2162
|
+
expanded: boolean;
|
|
2163
|
+
/** Toggle expand/collapse */
|
|
2164
|
+
toggleExpand: () => void;
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
/**
|
|
2168
|
+
* Group state information returned by getGroupState()
|
|
2169
|
+
*/
|
|
2170
|
+
declare interface GroupState {
|
|
2171
|
+
/** Whether grouping is currently active */
|
|
2172
|
+
isActive: boolean;
|
|
2173
|
+
/** Number of expanded groups */
|
|
2174
|
+
expandedCount: number;
|
|
2175
|
+
/** Total number of groups */
|
|
2176
|
+
totalGroups: number;
|
|
2177
|
+
/** Array of expanded group keys */
|
|
2178
|
+
expandedKeys: string[];
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
/**
|
|
2182
|
+
* Header click event
|
|
2183
|
+
*/
|
|
2184
|
+
declare interface HeaderClickEvent {
|
|
2185
|
+
colIndex: number;
|
|
2186
|
+
field: string;
|
|
2187
|
+
column: ColumnConfig;
|
|
2188
|
+
headerEl: HTMLElement;
|
|
2189
|
+
originalEvent: MouseEvent;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
/**
|
|
2193
|
+
* Header content definition for plugins contributing to shell header center section.
|
|
2194
|
+
*/
|
|
2195
|
+
export declare interface HeaderContentDefinition {
|
|
2196
|
+
/** Unique content ID */
|
|
2197
|
+
id: string;
|
|
2198
|
+
/** Content factory - called once when shell header renders */
|
|
2199
|
+
render: (container: HTMLElement) => void | (() => void);
|
|
2200
|
+
/** Called when content is removed (for cleanup) */
|
|
2201
|
+
onDestroy?: () => void;
|
|
2202
|
+
/** Order priority (lower = first, default: 100) */
|
|
2203
|
+
order?: number;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
/**
|
|
2207
|
+
* Header renderer function type for plugins.
|
|
2208
|
+
*/
|
|
2209
|
+
declare type HeaderRenderer = (ctx: PluginHeaderRenderContext) => string | HTMLElement;
|
|
2210
|
+
|
|
2211
|
+
/** Result of automatic column inference from sample rows. */
|
|
2212
|
+
export declare interface InferredColumnResult<TRow = any> {
|
|
2213
|
+
columns: ColumnConfigMap<TRow>;
|
|
2214
|
+
typeMap: Record<string, PrimitiveColumnType>;
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
/**
|
|
2218
|
+
* Internal-only augmented interface for DataGrid component
|
|
2219
|
+
*/
|
|
2220
|
+
declare interface InternalGrid<T = any> extends PublicGrid<T>, GridConfig<T> {
|
|
2221
|
+
shadowRoot: ShadowRoot | null;
|
|
2222
|
+
_rows: T[];
|
|
2223
|
+
_columns: ColumnInternal<T>[];
|
|
2224
|
+
/** Visible columns only (excludes hidden). Use for rendering. */
|
|
2225
|
+
visibleColumns: ColumnInternal<T>[];
|
|
2226
|
+
headerRowEl: HTMLElement;
|
|
2227
|
+
bodyEl: HTMLElement;
|
|
2228
|
+
rowPool: HTMLElement[];
|
|
2229
|
+
resizeController: ResizeController;
|
|
2230
|
+
sortState: {
|
|
2231
|
+
field: string;
|
|
2232
|
+
direction: 1 | -1;
|
|
2233
|
+
} | null;
|
|
2234
|
+
__originalOrder: T[];
|
|
2235
|
+
__rowRenderEpoch: number;
|
|
2236
|
+
__didInitialAutoSize?: boolean;
|
|
2237
|
+
__lightDomColumnsCache?: ColumnInternal[];
|
|
2238
|
+
__originalColumnNodes?: HTMLElement[];
|
|
2239
|
+
gridTemplate: string;
|
|
2240
|
+
virtualization: VirtualState;
|
|
2241
|
+
focusRow: number;
|
|
2242
|
+
focusCol: number;
|
|
2243
|
+
activeEditRows: number;
|
|
2244
|
+
rowEditSnapshots: Map<number, any>;
|
|
2245
|
+
_changedRowIndices: Set<number>;
|
|
2246
|
+
changedRows?: T[];
|
|
2247
|
+
changedRowIndices?: number[];
|
|
2248
|
+
effectiveConfig?: GridConfig<T>;
|
|
2249
|
+
findHeaderRow?: () => HTMLElement;
|
|
2250
|
+
refreshVirtualWindow: (full: boolean) => void;
|
|
2251
|
+
updateTemplate?: () => void;
|
|
2252
|
+
findRenderedRowElement?: (rowIndex: number) => HTMLElement | null;
|
|
2253
|
+
beginBulkEdit?: (rowIndex: number) => void;
|
|
2254
|
+
commitActiveRowEdit?: () => void;
|
|
2255
|
+
/** Dispatch cell click to plugin system, returns true if handled */
|
|
2256
|
+
dispatchCellClick?: (event: MouseEvent, rowIndex: number, colIndex: number, cellEl: HTMLElement) => boolean;
|
|
2257
|
+
/** Dispatch header click to plugin system, returns true if handled */
|
|
2258
|
+
dispatchHeaderClick?: (event: MouseEvent, colIndex: number, headerEl: HTMLElement) => boolean;
|
|
2259
|
+
/** Dispatch keydown to plugin system, returns true if handled */
|
|
2260
|
+
dispatchKeyDown?: (event: KeyboardEvent) => boolean;
|
|
2261
|
+
/** Request emission of column-state-change event (debounced) */
|
|
2262
|
+
requestStateChange?: () => void;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
/**
|
|
2266
|
+
* Master/Detail Plugin Types
|
|
2267
|
+
*
|
|
2268
|
+
* Type definitions for expandable detail rows showing additional content.
|
|
2269
|
+
*/
|
|
2270
|
+
/** Configuration options for the master-detail plugin */
|
|
2271
|
+
declare interface MasterDetailConfig {
|
|
2272
|
+
/** Whether master-detail functionality is enabled (default: true) */
|
|
2273
|
+
enabled?: boolean;
|
|
2274
|
+
/** Renderer function that returns detail content for a row */
|
|
2275
|
+
detailRenderer?: (row: any, rowIndex: number) => HTMLElement | string;
|
|
2276
|
+
/** Height of the detail row - number (pixels) or 'auto' (default: 'auto') */
|
|
2277
|
+
detailHeight?: number | 'auto';
|
|
2278
|
+
/** Expand/collapse detail on row click (default: false) */
|
|
2279
|
+
expandOnRowClick?: boolean;
|
|
2280
|
+
/** Collapse expanded detail when clicking outside (default: false) */
|
|
2281
|
+
collapseOnClickOutside?: boolean;
|
|
2282
|
+
/** Show expand/collapse column (default: true) */
|
|
2283
|
+
showExpandColumn?: boolean;
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
/**
|
|
2287
|
+
* Master/Detail Plugin for tbw-grid
|
|
2288
|
+
*
|
|
2289
|
+
* @example
|
|
2290
|
+
* ```ts
|
|
2291
|
+
* new MasterDetailPlugin({
|
|
2292
|
+
* enabled: true,
|
|
2293
|
+
* detailRenderer: (row) => `<div>Details for ${row.name}</div>`,
|
|
2294
|
+
* expandOnRowClick: true,
|
|
2295
|
+
* })
|
|
2296
|
+
* ```
|
|
2297
|
+
*/
|
|
2298
|
+
export declare class MasterDetailPlugin extends BaseGridPlugin<MasterDetailConfig> {
|
|
2299
|
+
readonly name = "masterDetail";
|
|
2300
|
+
readonly version = "1.0.0";
|
|
2301
|
+
protected get defaultConfig(): Partial<MasterDetailConfig>;
|
|
2302
|
+
private expandedRows;
|
|
2303
|
+
private detailElements;
|
|
2304
|
+
detach(): void;
|
|
2305
|
+
processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
2306
|
+
onRowClick(event: RowClickEvent): boolean | void;
|
|
2307
|
+
afterRender(): void;
|
|
2308
|
+
/**
|
|
2309
|
+
* Expand the detail row at the given index.
|
|
2310
|
+
* @param rowIndex - Index of the row to expand
|
|
2311
|
+
*/
|
|
2312
|
+
expand(rowIndex: number): void;
|
|
2313
|
+
/**
|
|
2314
|
+
* Collapse the detail row at the given index.
|
|
2315
|
+
* @param rowIndex - Index of the row to collapse
|
|
2316
|
+
*/
|
|
2317
|
+
collapse(rowIndex: number): void;
|
|
2318
|
+
/**
|
|
2319
|
+
* Toggle the detail row at the given index.
|
|
2320
|
+
* @param rowIndex - Index of the row to toggle
|
|
2321
|
+
*/
|
|
2322
|
+
toggle(rowIndex: number): void;
|
|
2323
|
+
/**
|
|
2324
|
+
* Check if the detail row at the given index is expanded.
|
|
2325
|
+
* @param rowIndex - Index of the row to check
|
|
2326
|
+
* @returns Whether the detail row is expanded
|
|
2327
|
+
*/
|
|
2328
|
+
isExpanded(rowIndex: number): boolean;
|
|
2329
|
+
/**
|
|
2330
|
+
* Expand all detail rows.
|
|
2331
|
+
*/
|
|
2332
|
+
expandAll(): void;
|
|
2333
|
+
/**
|
|
2334
|
+
* Collapse all detail rows.
|
|
2335
|
+
*/
|
|
2336
|
+
collapseAll(): void;
|
|
2337
|
+
/**
|
|
2338
|
+
* Get the indices of all expanded rows.
|
|
2339
|
+
* @returns Array of row indices that are expanded
|
|
2340
|
+
*/
|
|
2341
|
+
getExpandedRows(): number[];
|
|
2342
|
+
/**
|
|
2343
|
+
* Get the detail element for a specific row.
|
|
2344
|
+
* @param rowIndex - Index of the row
|
|
2345
|
+
* @returns The detail HTMLElement or undefined
|
|
2346
|
+
*/
|
|
2347
|
+
getDetailElement(rowIndex: number): HTMLElement | undefined;
|
|
2348
|
+
readonly styles = "\n .master-detail-cell-wrapper {\n display: flex;\n align-items: center;\n gap: 4px;\n }\n .master-detail-toggle {\n cursor: pointer;\n font-size: 10px;\n opacity: 0.7;\n user-select: none;\n }\n .master-detail-toggle:hover {\n opacity: 1;\n }\n .master-detail-row {\n grid-column: 1 / -1;\n display: grid;\n background: var(--tbw-master-detail-bg, var(--tbw-color-row-alt));\n border-bottom: 1px solid var(--tbw-master-detail-border, var(--tbw-color-border));\n }\n .master-detail-cell {\n padding: 16px;\n overflow: auto;\n }\n ";
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
/** Configuration options for the multi-sort plugin */
|
|
2352
|
+
export declare interface MultiSortConfig {
|
|
2353
|
+
/** Whether multi-sort is enabled (default: true) */
|
|
2354
|
+
enabled?: boolean;
|
|
2355
|
+
/** Maximum number of columns to sort by (default: 3) */
|
|
2356
|
+
maxSortColumns?: number;
|
|
2357
|
+
/** Whether to show sort order badges (1, 2, 3) on headers (default: true) */
|
|
2358
|
+
showSortIndex?: boolean;
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
/**
|
|
2362
|
+
* Multi-Sort Plugin for tbw-grid
|
|
2363
|
+
*
|
|
2364
|
+
* @example
|
|
2365
|
+
* ```ts
|
|
2366
|
+
* new MultiSortPlugin({ maxSortColumns: 3, showSortIndex: true })
|
|
2367
|
+
* ```
|
|
2368
|
+
*/
|
|
2369
|
+
export declare class MultiSortPlugin extends BaseGridPlugin<MultiSortConfig> {
|
|
2370
|
+
readonly name = "multiSort";
|
|
2371
|
+
readonly version = "1.0.0";
|
|
2372
|
+
protected get defaultConfig(): Partial<MultiSortConfig>;
|
|
2373
|
+
private sortModel;
|
|
2374
|
+
detach(): void;
|
|
2375
|
+
processRows(rows: readonly unknown[]): unknown[];
|
|
2376
|
+
onHeaderClick(event: HeaderClickEvent): boolean;
|
|
2377
|
+
afterRender(): void;
|
|
2378
|
+
/**
|
|
2379
|
+
* Get the current sort model.
|
|
2380
|
+
* @returns Copy of the current sort model
|
|
2381
|
+
*/
|
|
2382
|
+
getSortModel(): SortModel[];
|
|
2383
|
+
/**
|
|
2384
|
+
* Set the sort model programmatically.
|
|
2385
|
+
* @param model - New sort model to apply
|
|
2386
|
+
*/
|
|
2387
|
+
setSortModel(model: SortModel[]): void;
|
|
2388
|
+
/**
|
|
2389
|
+
* Clear all sorting.
|
|
2390
|
+
*/
|
|
2391
|
+
clearSort(): void;
|
|
2392
|
+
/**
|
|
2393
|
+
* Get the sort index (1-based) for a specific field.
|
|
2394
|
+
* @param field - Field to check
|
|
2395
|
+
* @returns 1-based index or undefined if not sorted
|
|
2396
|
+
*/
|
|
2397
|
+
getSortIndex(field: string): number | undefined;
|
|
2398
|
+
/**
|
|
2399
|
+
* Get the sort direction for a specific field.
|
|
2400
|
+
* @param field - Field to check
|
|
2401
|
+
* @returns Sort direction or undefined if not sorted
|
|
2402
|
+
*/
|
|
2403
|
+
getSortDirection(field: string): 'asc' | 'desc' | undefined;
|
|
2404
|
+
/**
|
|
2405
|
+
* Return sort state for a column if it's in the sort model.
|
|
2406
|
+
*/
|
|
2407
|
+
getColumnState(field: string): Partial<ColumnState> | undefined;
|
|
2408
|
+
/**
|
|
2409
|
+
* Apply sort state from column state.
|
|
2410
|
+
* Rebuilds the sort model from all column states.
|
|
2411
|
+
*/
|
|
2412
|
+
applyColumnState(field: string, state: ColumnState): void;
|
|
2413
|
+
readonly styles = "\n .header-cell[data-sort=\"asc\"]::after {\n content: '\u2191';\n margin-left: 4px;\n opacity: 0.8;\n }\n .header-cell[data-sort=\"desc\"]::after {\n content: '\u2193';\n margin-left: 4px;\n opacity: 0.8;\n }\n .sort-index {\n font-size: 10px;\n background: var(--tbw-multi-sort-badge-bg, var(--tbw-color-panel-bg));\n color: var(--tbw-multi-sort-badge-color, var(--tbw-color-fg));\n border-radius: 50%;\n width: 14px;\n height: 14px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n margin-left: 2px;\n font-weight: 600;\n }\n ";
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
/**
|
|
2417
|
+
* Sticky Columns Plugin Types
|
|
2418
|
+
*
|
|
2419
|
+
* Type definitions for column pinning (sticky left/right columns).
|
|
2420
|
+
*/
|
|
2421
|
+
/** Configuration options for the pinned columns plugin */
|
|
2422
|
+
declare interface PinnedColumnsConfig {
|
|
2423
|
+
/** Whether the plugin is enabled (default: true) */
|
|
2424
|
+
enabled?: boolean;
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
/**
|
|
2428
|
+
* Pinned Columns Plugin for tbw-grid
|
|
2429
|
+
*
|
|
2430
|
+
* @example
|
|
2431
|
+
* ```ts
|
|
2432
|
+
* new PinnedColumnsPlugin({ enabled: true })
|
|
2433
|
+
* ```
|
|
2434
|
+
*/
|
|
2435
|
+
export declare class PinnedColumnsPlugin extends BaseGridPlugin<PinnedColumnsConfig> {
|
|
2436
|
+
readonly name = "pinnedColumns";
|
|
2437
|
+
readonly version = "1.0.0";
|
|
2438
|
+
protected get defaultConfig(): Partial<PinnedColumnsConfig>;
|
|
2439
|
+
private isApplied;
|
|
2440
|
+
private leftOffsets;
|
|
2441
|
+
private rightOffsets;
|
|
2442
|
+
detach(): void;
|
|
2443
|
+
/**
|
|
2444
|
+
* Auto-detect sticky columns from column configuration.
|
|
2445
|
+
*/
|
|
2446
|
+
static detect(rows: readonly unknown[], config: {
|
|
2447
|
+
columns?: ColumnConfig[];
|
|
2448
|
+
}): boolean;
|
|
2449
|
+
processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
2450
|
+
afterRender(): void;
|
|
2451
|
+
/**
|
|
2452
|
+
* Re-apply sticky offsets (e.g., after column resize).
|
|
2453
|
+
*/
|
|
2454
|
+
refreshStickyOffsets(): void;
|
|
2455
|
+
/**
|
|
2456
|
+
* Get columns pinned to the left.
|
|
2457
|
+
*/
|
|
2458
|
+
getLeftPinnedColumns(): ColumnConfig[];
|
|
2459
|
+
/**
|
|
2460
|
+
* Get columns pinned to the right.
|
|
2461
|
+
*/
|
|
2462
|
+
getRightPinnedColumns(): ColumnConfig[];
|
|
2463
|
+
/**
|
|
2464
|
+
* Clear all sticky positioning.
|
|
2465
|
+
*/
|
|
2466
|
+
clearStickyPositions(): void;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
/** Configuration options for the status bar plugin */
|
|
2470
|
+
declare interface PinnedRowsConfig {
|
|
2471
|
+
/** Whether the status bar is enabled (default: false) */
|
|
2472
|
+
enabled?: boolean;
|
|
2473
|
+
/** Position of the info bar (default: 'bottom') */
|
|
2474
|
+
position?: PinnedRowsPosition;
|
|
2475
|
+
/** Show total row count in info bar (default: true) */
|
|
2476
|
+
showRowCount?: boolean;
|
|
2477
|
+
/** Show selected row count in info bar (default: true) */
|
|
2478
|
+
showSelectedCount?: boolean;
|
|
2479
|
+
/** Show filtered row count when filter is active (default: true) */
|
|
2480
|
+
showFilteredCount?: boolean;
|
|
2481
|
+
/** Custom panels to display in the info bar */
|
|
2482
|
+
customPanels?: PinnedRowsPanel[];
|
|
2483
|
+
/** Aggregation rows (footer/header rows with computed values) */
|
|
2484
|
+
aggregationRows?: AggregationRowConfig[];
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
/** Context provided to panel renderers */
|
|
2488
|
+
export declare interface PinnedRowsContext {
|
|
2489
|
+
/** Total number of rows in the grid */
|
|
2490
|
+
totalRows: number;
|
|
2491
|
+
/** Number of rows after filtering */
|
|
2492
|
+
filteredRows: number;
|
|
2493
|
+
/** Number of selected rows */
|
|
2494
|
+
selectedRows: number;
|
|
2495
|
+
/** Current column configuration */
|
|
2496
|
+
columns: ColumnConfig[];
|
|
2497
|
+
/** Current row data */
|
|
2498
|
+
rows: unknown[];
|
|
2499
|
+
/** Reference to the grid element */
|
|
2500
|
+
grid: HTMLElement;
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
/** Custom panel definition for the status bar */
|
|
2504
|
+
export declare interface PinnedRowsPanel {
|
|
2505
|
+
/** Unique identifier for the panel */
|
|
2506
|
+
id: string;
|
|
2507
|
+
/** Position within the status bar */
|
|
2508
|
+
position: 'left' | 'center' | 'right';
|
|
2509
|
+
/** Render function for the panel content */
|
|
2510
|
+
render: (context: PinnedRowsContext) => HTMLElement | string;
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
/**
|
|
2514
|
+
* Pinned Rows Plugin for tbw-grid
|
|
2515
|
+
*
|
|
2516
|
+
* @example
|
|
2517
|
+
* ```ts
|
|
2518
|
+
* new PinnedRowsPlugin({
|
|
2519
|
+
* enabled: true,
|
|
2520
|
+
* position: 'bottom',
|
|
2521
|
+
* showRowCount: true,
|
|
2522
|
+
* showSelectedCount: true,
|
|
2523
|
+
* aggregationRows: [
|
|
2524
|
+
* { id: 'totals', position: 'bottom', values: { amount: 'sum' } },
|
|
2525
|
+
* ],
|
|
2526
|
+
* })
|
|
2527
|
+
* ```
|
|
2528
|
+
*/
|
|
2529
|
+
export declare class PinnedRowsPlugin extends BaseGridPlugin<PinnedRowsConfig> {
|
|
2530
|
+
readonly name = "pinnedRows";
|
|
2531
|
+
readonly version = "1.0.0";
|
|
2532
|
+
protected get defaultConfig(): Partial<PinnedRowsConfig>;
|
|
2533
|
+
private infoBarElement;
|
|
2534
|
+
private topAggregationContainer;
|
|
2535
|
+
private bottomAggregationContainer;
|
|
2536
|
+
private footerWrapper;
|
|
2537
|
+
detach(): void;
|
|
2538
|
+
afterRender(): void;
|
|
2539
|
+
private cleanup;
|
|
2540
|
+
private cleanupFooter;
|
|
2541
|
+
private getSelectionState;
|
|
2542
|
+
private getFilterState;
|
|
2543
|
+
/**
|
|
2544
|
+
* Refresh the status bar to reflect current grid state.
|
|
2545
|
+
*/
|
|
2546
|
+
refresh(): void;
|
|
2547
|
+
/**
|
|
2548
|
+
* Get the current status bar context.
|
|
2549
|
+
* @returns The context with row counts and other info
|
|
2550
|
+
*/
|
|
2551
|
+
getContext(): PinnedRowsContext;
|
|
2552
|
+
/**
|
|
2553
|
+
* Add a custom panel to the info bar.
|
|
2554
|
+
* @param panel - The panel configuration to add
|
|
2555
|
+
*/
|
|
2556
|
+
addPanel(panel: PinnedRowsPanel): void;
|
|
2557
|
+
/**
|
|
2558
|
+
* Remove a custom panel by ID.
|
|
2559
|
+
* @param id - The panel ID to remove
|
|
2560
|
+
*/
|
|
2561
|
+
removePanel(id: string): void;
|
|
2562
|
+
/**
|
|
2563
|
+
* Add an aggregation row.
|
|
2564
|
+
* @param row - The aggregation row configuration
|
|
2565
|
+
*/
|
|
2566
|
+
addAggregationRow(row: AggregationRowConfig): void;
|
|
2567
|
+
/**
|
|
2568
|
+
* Remove an aggregation row by ID.
|
|
2569
|
+
* @param id - The aggregation row ID to remove
|
|
2570
|
+
*/
|
|
2571
|
+
removeAggregationRow(id: string): void;
|
|
2572
|
+
readonly styles = "\n .tbw-footer {\n position: sticky;\n bottom: 0;\n z-index: var(--tbw-z-layer-pinned-rows, 20);\n background: var(--tbw-color-panel-bg);\n }\n\n .tbw-pinned-rows {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n background: var(--tbw-pinned-rows-bg, var(--tbw-color-panel-bg));\n border-top: 1px solid var(--tbw-pinned-rows-border, var(--tbw-color-border));\n font-size: 12px;\n color: var(--tbw-pinned-rows-color, var(--tbw-color-fg-muted));\n min-height: 32px;\n box-sizing: border-box;\n min-width: fit-content;\n }\n .tbw-pinned-rows-left,\n .tbw-pinned-rows-center,\n .tbw-pinned-rows-right {\n display: flex;\n align-items: center;\n gap: 16px;\n }\n .tbw-pinned-rows-left {\n justify-content: flex-start;\n }\n .tbw-pinned-rows-center {\n justify-content: center;\n flex: 1;\n }\n .tbw-pinned-rows-right {\n justify-content: flex-end;\n }\n .tbw-status-panel {\n white-space: nowrap;\n }\n\n .tbw-aggregation-rows {\n min-width: fit-content;\n background: var(--tbw-aggregation-bg, var(--tbw-color-header-bg));\n }\n .tbw-aggregation-rows-top {\n border-bottom: 1px solid var(--tbw-aggregation-border, var(--tbw-color-border));\n }\n .tbw-aggregation-rows-bottom {\n border-top: 1px solid var(--tbw-aggregation-border, var(--tbw-color-border));\n }\n .tbw-aggregation-row {\n display: grid;\n grid-template-columns: var(--tbw-column-template);\n font-weight: var(--tbw-aggregation-font-weight, 600);\n }\n .tbw-aggregation-cell {\n padding: var(--tbw-cell-padding, 2px 8px);\n min-height: var(--tbw-row-height, 28px);\n display: flex;\n align-items: center;\n border-right: 1px solid var(--tbw-color-border-cell);\n }\n .tbw-aggregation-cell:last-child {\n border-right: 0;\n }\n .tbw-aggregation-cell-full {\n grid-column: 1 / -1;\n border-right: 0;\n }\n ";
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
/** Position of the status bar relative to the grid */
|
|
2576
|
+
declare type PinnedRowsPosition = 'top' | 'bottom';
|
|
2577
|
+
|
|
2578
|
+
export declare interface PivotConfig {
|
|
2579
|
+
enabled?: boolean;
|
|
2580
|
+
rowGroupFields?: string[];
|
|
2581
|
+
columnGroupFields?: string[];
|
|
2582
|
+
valueFields?: PivotValueField[];
|
|
2583
|
+
showTotals?: boolean;
|
|
2584
|
+
showGrandTotal?: boolean;
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
declare type PivotDataRow = Record<string, unknown>;
|
|
2588
|
+
|
|
2589
|
+
/**
|
|
2590
|
+
* Pivot Plugin for tbw-grid
|
|
2591
|
+
*
|
|
2592
|
+
* @example
|
|
2593
|
+
* ```ts
|
|
2594
|
+
* new PivotPlugin({
|
|
2595
|
+
* rowGroupFields: ['category'],
|
|
2596
|
+
* columnGroupFields: ['region'],
|
|
2597
|
+
* valueFields: [{ field: 'sales', aggFunc: 'sum' }]
|
|
2598
|
+
* })
|
|
2599
|
+
* ```
|
|
2600
|
+
*/
|
|
2601
|
+
export declare class PivotPlugin extends BaseGridPlugin<PivotConfig> {
|
|
2602
|
+
readonly name = "pivot";
|
|
2603
|
+
readonly version = "1.0.0";
|
|
2604
|
+
protected get defaultConfig(): Partial<PivotConfig>;
|
|
2605
|
+
private isActive;
|
|
2606
|
+
private pivotResult;
|
|
2607
|
+
private columnHeaders;
|
|
2608
|
+
private rowHeaders;
|
|
2609
|
+
detach(): void;
|
|
2610
|
+
processRows(rows: readonly unknown[]): PivotDataRow[];
|
|
2611
|
+
processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
2612
|
+
/**
|
|
2613
|
+
* Enable pivot mode.
|
|
2614
|
+
*/
|
|
2615
|
+
enablePivot(): void;
|
|
2616
|
+
/**
|
|
2617
|
+
* Disable pivot mode and return to normal grid view.
|
|
2618
|
+
*/
|
|
2619
|
+
disablePivot(): void;
|
|
2620
|
+
/**
|
|
2621
|
+
* Check if pivot mode is currently active.
|
|
2622
|
+
*/
|
|
2623
|
+
isPivotActive(): boolean;
|
|
2624
|
+
/**
|
|
2625
|
+
* Get the current pivot result.
|
|
2626
|
+
*/
|
|
2627
|
+
getPivotResult(): PivotResult | null;
|
|
2628
|
+
/**
|
|
2629
|
+
* Set the row group fields for pivoting.
|
|
2630
|
+
* @param fields - Array of field names to group rows by
|
|
2631
|
+
*/
|
|
2632
|
+
setRowGroupFields(fields: string[]): void;
|
|
2633
|
+
/**
|
|
2634
|
+
* Set the column group fields for pivoting.
|
|
2635
|
+
* @param fields - Array of field names to create columns from
|
|
2636
|
+
*/
|
|
2637
|
+
setColumnGroupFields(fields: string[]): void;
|
|
2638
|
+
/**
|
|
2639
|
+
* Set the value fields with aggregation functions.
|
|
2640
|
+
* @param fields - Array of value field configurations
|
|
2641
|
+
*/
|
|
2642
|
+
setValueFields(fields: PivotValueField[]): void;
|
|
2643
|
+
/**
|
|
2644
|
+
* Refresh the pivot by clearing cached results.
|
|
2645
|
+
*/
|
|
2646
|
+
refresh(): void;
|
|
2647
|
+
readonly styles = "\n [data-pivot-depth=\"1\"] { padding-left: 20px; }\n [data-pivot-depth=\"2\"] { padding-left: 40px; }\n [data-pivot-depth=\"3\"] { padding-left: 60px; }\n .pivot-group-row { font-weight: bold; background: var(--tbw-pivot-group-bg, var(--tbw-color-panel-bg)); }\n .pivot-total-row { font-weight: bold; border-top: 2px solid var(--tbw-pivot-border, var(--tbw-color-border-strong)); }\n ";
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
export declare interface PivotResult {
|
|
2651
|
+
rows: PivotRow[];
|
|
2652
|
+
columnKeys: string[];
|
|
2653
|
+
totals: Record<string, number>;
|
|
2654
|
+
grandTotal: number;
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
declare interface PivotRow {
|
|
2658
|
+
rowKey: string;
|
|
2659
|
+
rowLabel: string;
|
|
2660
|
+
depth: number;
|
|
2661
|
+
values: Record<string, number | null>;
|
|
2662
|
+
total?: number;
|
|
2663
|
+
isGroup: boolean;
|
|
2664
|
+
children?: PivotRow[];
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
export declare interface PivotValueField {
|
|
2668
|
+
field: string;
|
|
2669
|
+
aggFunc: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last';
|
|
2670
|
+
header?: string;
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
/**
|
|
2674
|
+
* Cell render context for plugin cell renderers.
|
|
2675
|
+
* Provides full context including position and editing state.
|
|
2676
|
+
*
|
|
2677
|
+
* Note: This differs from the core `CellRenderContext` in types.ts which is
|
|
2678
|
+
* simpler and used for column view renderers. This version provides additional
|
|
2679
|
+
* context needed by plugins that register custom cell renderers.
|
|
2680
|
+
*/
|
|
2681
|
+
declare interface PluginCellRenderContext {
|
|
2682
|
+
/** The cell value */
|
|
2683
|
+
value: any;
|
|
2684
|
+
/** The field/column key */
|
|
2685
|
+
field: string;
|
|
2686
|
+
/** The row data object */
|
|
2687
|
+
row: any;
|
|
2688
|
+
/** Row index in the data array */
|
|
2689
|
+
rowIndex: number;
|
|
2690
|
+
/** Column index */
|
|
2691
|
+
colIndex: number;
|
|
2692
|
+
/** Column configuration */
|
|
2693
|
+
column: ColumnConfig;
|
|
2694
|
+
/** Whether the cell is currently in edit mode */
|
|
2695
|
+
isEditing: boolean;
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
export declare type PluginEventName = (typeof PluginEvents)[keyof typeof PluginEvents];
|
|
2699
|
+
|
|
2700
|
+
export declare const PluginEvents: {
|
|
2701
|
+
readonly SELECTION_CHANGE: "selection-change";
|
|
2702
|
+
readonly TREE_EXPAND: "tree-expand";
|
|
2703
|
+
readonly FILTER_CHANGE: "filter-change";
|
|
2704
|
+
readonly SORT_MODEL_CHANGE: "sort-model-change";
|
|
2705
|
+
readonly EXPORT_START: "export-start";
|
|
2706
|
+
readonly EXPORT_COMPLETE: "export-complete";
|
|
2707
|
+
readonly CLIPBOARD_COPY: "clipboard-copy";
|
|
2708
|
+
readonly CLIPBOARD_PASTE: "clipboard-paste";
|
|
2709
|
+
readonly CONTEXT_MENU_OPEN: "context-menu-open";
|
|
2710
|
+
readonly CONTEXT_MENU_CLOSE: "context-menu-close";
|
|
2711
|
+
readonly HISTORY_CHANGE: "history-change";
|
|
2712
|
+
readonly SERVER_LOADING: "server-loading";
|
|
2713
|
+
readonly SERVER_ERROR: "server-error";
|
|
2714
|
+
readonly COLUMN_VISIBILITY_CHANGE: "column-visibility-change";
|
|
2715
|
+
readonly COLUMN_REORDER: "column-reorder";
|
|
2716
|
+
readonly DETAIL_EXPAND: "detail-expand";
|
|
2717
|
+
readonly GROUP_EXPAND: "group-expand";
|
|
2718
|
+
};
|
|
2719
|
+
|
|
2720
|
+
/**
|
|
2721
|
+
* Header render context for plugin header renderers.
|
|
2722
|
+
*/
|
|
2723
|
+
declare interface PluginHeaderRenderContext {
|
|
2724
|
+
/** Column configuration */
|
|
2725
|
+
column: ColumnConfig;
|
|
2726
|
+
/** Column index */
|
|
2727
|
+
colIndex: number;
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
export declare type PrimitiveColumnType = 'number' | 'string' | 'date' | 'boolean' | 'select' | 'typeahead';
|
|
2731
|
+
|
|
2732
|
+
/**
|
|
2733
|
+
* Public API interface for DataGrid component.
|
|
2734
|
+
*
|
|
2735
|
+
* **Property Getters vs Setters:**
|
|
2736
|
+
*
|
|
2737
|
+
* Property getters return the EFFECTIVE (resolved) value after merging all config sources.
|
|
2738
|
+
* This is the "current situation" - what consumers and plugins need to know.
|
|
2739
|
+
*
|
|
2740
|
+
* Property setters accept input values which are merged into the effective config.
|
|
2741
|
+
* Multiple sources can contribute (gridConfig, columns prop, light DOM, individual props).
|
|
2742
|
+
*
|
|
2743
|
+
* For example:
|
|
2744
|
+
* - `grid.fitMode` returns the resolved fitMode (e.g., 'stretch' even if you set undefined)
|
|
2745
|
+
* - `grid.columns` returns the effective columns after merging
|
|
2746
|
+
* - `grid.gridConfig` returns the full effective config
|
|
2747
|
+
*/
|
|
2748
|
+
export declare interface PublicGrid<T = any> {
|
|
2749
|
+
/**
|
|
2750
|
+
* Full config object. Setter merges with other inputs per precedence rules.
|
|
2751
|
+
* Getter returns the effective (resolved) config.
|
|
2752
|
+
*/
|
|
2753
|
+
gridConfig?: GridConfig<T>;
|
|
2754
|
+
/**
|
|
2755
|
+
* Column definitions.
|
|
2756
|
+
* Getter returns effective columns (after merging config, light DOM, inference).
|
|
2757
|
+
*/
|
|
2758
|
+
columns?: ColumnConfig<T>[];
|
|
2759
|
+
/** Current row data (after plugin processing like grouping, filtering). */
|
|
2760
|
+
rows?: T[];
|
|
2761
|
+
/** Resolves once the component has finished initial work (layout, inference). */
|
|
2762
|
+
ready?: () => Promise<void>;
|
|
2763
|
+
/** Force a layout / measurement pass (e.g. after container resize). */
|
|
2764
|
+
forceLayout?: () => Promise<void>;
|
|
2765
|
+
/** Return effective resolved config (after inference & precedence). */
|
|
2766
|
+
getConfig?: () => Promise<Readonly<GridConfig<T>>>;
|
|
2767
|
+
/** Toggle expansion state of a group row by its generated key. */
|
|
2768
|
+
toggleGroup?: (key: string) => Promise<void>;
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
/** Union type for render rows */
|
|
2772
|
+
declare type RenderRow = GroupRowModelItem | DataRowModelItem;
|
|
2773
|
+
|
|
2774
|
+
/**
|
|
2775
|
+
* Column Reordering Plugin Types
|
|
2776
|
+
*
|
|
2777
|
+
* Type definitions for the column reordering feature.
|
|
2778
|
+
*/
|
|
2779
|
+
/** Configuration options for the reorder plugin */
|
|
2780
|
+
declare interface ReorderConfig {
|
|
2781
|
+
/** Whether column reordering is enabled (default: true) */
|
|
2782
|
+
enabled?: boolean;
|
|
2783
|
+
/** Whether to animate column movement (default: true) */
|
|
2784
|
+
animation?: boolean;
|
|
2785
|
+
/** Animation duration in milliseconds (default: 200) */
|
|
2786
|
+
animationDuration?: number;
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
/**
|
|
2790
|
+
* Column Reordering Plugin for tbw-grid
|
|
2791
|
+
*
|
|
2792
|
+
* @example
|
|
2793
|
+
* ```ts
|
|
2794
|
+
* new ReorderPlugin({
|
|
2795
|
+
* enabled: true,
|
|
2796
|
+
* animation: true,
|
|
2797
|
+
* animationDuration: 200,
|
|
2798
|
+
* })
|
|
2799
|
+
* ```
|
|
2800
|
+
*/
|
|
2801
|
+
export declare class ReorderPlugin extends BaseGridPlugin<ReorderConfig> {
|
|
2802
|
+
readonly name = "reorder";
|
|
2803
|
+
readonly version = "1.0.0";
|
|
2804
|
+
protected get defaultConfig(): Partial<ReorderConfig>;
|
|
2805
|
+
private isDragging;
|
|
2806
|
+
private draggedField;
|
|
2807
|
+
private draggedIndex;
|
|
2808
|
+
private dropIndex;
|
|
2809
|
+
private boundReorderRequestHandler;
|
|
2810
|
+
attach(grid: GridElement_2): void;
|
|
2811
|
+
detach(): void;
|
|
2812
|
+
afterRender(): void;
|
|
2813
|
+
/**
|
|
2814
|
+
* Get the current column order from the grid.
|
|
2815
|
+
* @returns Array of field names in display order
|
|
2816
|
+
*/
|
|
2817
|
+
getColumnOrder(): string[];
|
|
2818
|
+
/**
|
|
2819
|
+
* Move a column to a new position.
|
|
2820
|
+
* @param field - The field name of the column to move
|
|
2821
|
+
* @param toIndex - The target index
|
|
2822
|
+
*/
|
|
2823
|
+
moveColumn(field: string, toIndex: number): void;
|
|
2824
|
+
/**
|
|
2825
|
+
* Set a specific column order.
|
|
2826
|
+
* @param order - Array of field names in desired order
|
|
2827
|
+
*/
|
|
2828
|
+
setColumnOrder(order: string[]): void;
|
|
2829
|
+
/**
|
|
2830
|
+
* Reset column order to the original configuration order.
|
|
2831
|
+
*/
|
|
2832
|
+
resetColumnOrder(): void;
|
|
2833
|
+
readonly styles = "\n .header-row > .cell[draggable=\"true\"] {\n cursor: grab;\n position: relative;\n }\n .header-row > .cell.dragging {\n opacity: 0.5;\n cursor: grabbing;\n }\n .header-row > .cell.drop-before::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--tbw-reorder-indicator, var(--tbw-color-accent));\n z-index: 1;\n }\n .header-row > .cell.drop-after::after {\n content: '';\n position: absolute;\n right: 0;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--tbw-reorder-indicator, var(--tbw-color-accent));\n z-index: 1;\n }\n ";
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
/** Controller managing drag-based column resize lifecycle. */
|
|
2837
|
+
declare interface ResizeController {
|
|
2838
|
+
start: (e: MouseEvent, colIndex: number, cell: HTMLElement) => void;
|
|
2839
|
+
dispose: () => void;
|
|
2840
|
+
/** True while a resize drag is in progress (used to suppress header click/sort). */
|
|
2841
|
+
isResizing: boolean;
|
|
2842
|
+
}
|
|
2843
|
+
|
|
2844
|
+
/**
|
|
2845
|
+
* Row click event
|
|
2846
|
+
*/
|
|
2847
|
+
declare interface RowClickEvent {
|
|
2848
|
+
rowIndex: number;
|
|
2849
|
+
row: any;
|
|
2850
|
+
rowEl: HTMLElement;
|
|
2851
|
+
originalEvent: MouseEvent;
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2854
|
+
/** Detail payload for a committed row edit (may or may not include changes). */
|
|
2855
|
+
export declare interface RowCommitDetail<TRow = any> {
|
|
2856
|
+
/** Row index that lost edit focus. */
|
|
2857
|
+
rowIndex: number;
|
|
2858
|
+
/** Row object reference. */
|
|
2859
|
+
row: TRow;
|
|
2860
|
+
/** Whether any cell changes were actually committed in this row during the session. */
|
|
2861
|
+
changed: boolean;
|
|
2862
|
+
/** Current changed row collection. */
|
|
2863
|
+
changedRows: TRow[];
|
|
2864
|
+
/** Indices of changed rows. */
|
|
2865
|
+
changedRowIndices: number[];
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2868
|
+
/**
|
|
2869
|
+
* Group row rendering customization options.
|
|
2870
|
+
* Used within grouping-rows plugin config for presentation of group rows.
|
|
2871
|
+
*/
|
|
2872
|
+
export declare interface RowGroupRenderConfig {
|
|
2873
|
+
/** If true, group rows span all columns (single full-width cell). Default false. */
|
|
2874
|
+
fullWidth?: boolean;
|
|
2875
|
+
/** Optional label formatter override. Receives raw group value + depth. */
|
|
2876
|
+
formatLabel?: (value: any, depth: number, key: string) => string;
|
|
2877
|
+
/** Optional aggregate overrides per field for group summary cells (only when not fullWidth). */
|
|
2878
|
+
aggregators?: Record<string, AggregatorRef>;
|
|
2879
|
+
/** Additional CSS class applied to each group row root element. */
|
|
2880
|
+
class?: string;
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
/**
|
|
2884
|
+
* Scroll event
|
|
2885
|
+
*/
|
|
2886
|
+
declare interface ScrollEvent {
|
|
2887
|
+
scrollTop: number;
|
|
2888
|
+
scrollLeft: number;
|
|
2889
|
+
scrollHeight: number;
|
|
2890
|
+
scrollWidth: number;
|
|
2891
|
+
clientHeight: number;
|
|
2892
|
+
clientWidth: number;
|
|
2893
|
+
originalEvent?: Event;
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
/**
|
|
2897
|
+
* Unified event detail emitted when selection changes (all modes).
|
|
2898
|
+
* Provides a consistent structure for consumers to handle selection state.
|
|
2899
|
+
*/
|
|
2900
|
+
export declare interface SelectionChangeDetail {
|
|
2901
|
+
/** The selection mode that triggered this event */
|
|
2902
|
+
mode: SelectionMode_2;
|
|
2903
|
+
/** Selected cell ranges. For cell mode, contains a single-cell range. For row mode, contains full-row ranges. */
|
|
2904
|
+
ranges: CellRange[];
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
/** Configuration options for the selection plugin */
|
|
2908
|
+
export declare interface SelectionConfig {
|
|
2909
|
+
/** Selection mode (default: 'cell') */
|
|
2910
|
+
mode: SelectionMode_2;
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
/**
|
|
2914
|
+
* Selection Plugin Types
|
|
2915
|
+
*
|
|
2916
|
+
* Type definitions for the selection feature.
|
|
2917
|
+
*/
|
|
2918
|
+
/**
|
|
2919
|
+
* Selection mode for the grid:
|
|
2920
|
+
* - 'cell': Single cell selection (default). No border, just focus highlight.
|
|
2921
|
+
* - 'row': Row selection. Clicking a cell selects the entire row. Uses focus outline color.
|
|
2922
|
+
* - 'range': Range selection. Shift+click or drag to select rectangular cell ranges. Uses success border color.
|
|
2923
|
+
*/
|
|
2924
|
+
declare type SelectionMode_2 = 'cell' | 'row' | 'range';
|
|
2925
|
+
export { SelectionMode_2 as SelectionMode }
|
|
2926
|
+
|
|
2927
|
+
/**
|
|
2928
|
+
* Selection Plugin for tbw-grid
|
|
2929
|
+
*
|
|
2930
|
+
* @example
|
|
2931
|
+
* ```ts
|
|
2932
|
+
* new SelectionPlugin({ mode: 'range' })
|
|
2933
|
+
* ```
|
|
2934
|
+
*/
|
|
2935
|
+
export declare class SelectionPlugin extends BaseGridPlugin<SelectionConfig> {
|
|
2936
|
+
#private;
|
|
2937
|
+
readonly name = "selection";
|
|
2938
|
+
readonly version = "1.0.0";
|
|
2939
|
+
protected get defaultConfig(): Partial<SelectionConfig>;
|
|
2940
|
+
/** Row selection state (row mode) */
|
|
2941
|
+
private selected;
|
|
2942
|
+
private lastSelected;
|
|
2943
|
+
private anchor;
|
|
2944
|
+
/** Range selection state (range mode) */
|
|
2945
|
+
private ranges;
|
|
2946
|
+
private activeRange;
|
|
2947
|
+
private cellAnchor;
|
|
2948
|
+
private isDragging;
|
|
2949
|
+
/** Cell selection state (cell mode) */
|
|
2950
|
+
private selectedCell;
|
|
2951
|
+
detach(): void;
|
|
2952
|
+
onCellClick(event: CellClickEvent): boolean;
|
|
2953
|
+
onKeyDown(event: KeyboardEvent): boolean;
|
|
2954
|
+
onCellMouseDown(event: CellMouseEvent): boolean | void;
|
|
2955
|
+
onCellMouseMove(event: CellMouseEvent): boolean | void;
|
|
2956
|
+
onCellMouseUp(_event: CellMouseEvent): boolean | void;
|
|
2957
|
+
afterRender(): void;
|
|
2958
|
+
/**
|
|
2959
|
+
* Get the selected cell (cell mode only).
|
|
2960
|
+
*/
|
|
2961
|
+
getSelectedCell(): {
|
|
2962
|
+
row: number;
|
|
2963
|
+
col: number;
|
|
2964
|
+
} | null;
|
|
2965
|
+
/**
|
|
2966
|
+
* Get all selected row indices (row mode).
|
|
2967
|
+
*/
|
|
2968
|
+
getSelectedRows(): number[];
|
|
2969
|
+
/**
|
|
2970
|
+
* Get all selected cell ranges in public format.
|
|
2971
|
+
*/
|
|
2972
|
+
getRanges(): CellRange[];
|
|
2973
|
+
/**
|
|
2974
|
+
* Get all selected cells across all ranges.
|
|
2975
|
+
*/
|
|
2976
|
+
getSelectedCells(): Array<{
|
|
2977
|
+
row: number;
|
|
2978
|
+
col: number;
|
|
2979
|
+
}>;
|
|
2980
|
+
/**
|
|
2981
|
+
* Check if a specific cell is in range selection.
|
|
2982
|
+
*/
|
|
2983
|
+
isCellSelected(row: number, col: number): boolean;
|
|
2984
|
+
/**
|
|
2985
|
+
* Clear all selection.
|
|
2986
|
+
*/
|
|
2987
|
+
clearSelection(): void;
|
|
2988
|
+
/**
|
|
2989
|
+
* Set selected ranges programmatically.
|
|
2990
|
+
*/
|
|
2991
|
+
setRanges(ranges: CellRange[]): void;
|
|
2992
|
+
readonly styles = "\n /* Prevent text selection during range drag */\n :host .selecting .data-grid-row > .cell {\n user-select: none;\n }\n\n /* Row selection - use accent color for row focus */\n :host .data-grid-row.row-focus {\n background-color: var(--tbw-focus-background, rgba(from var(--tbw-color-accent) r g b / 12%));\n }\n\n /* Disable cell-focus outline in row mode - row is the focus unit */\n :host([data-selection-mode=\"row\"]) .cell-focus {\n outline: none;\n }\n\n /* Selection cell styles - for range mode */\n :host .data-grid-row > .cell.selected {\n background-color: var(--tbw-range-selection-bg);\n }\n :host .data-grid-row > .cell.selected.top {\n border-top: 2px solid var(--tbw-range-border-color);\n }\n :host .data-grid-row > .cell.selected.bottom {\n border-bottom: 2px solid var(--tbw-range-border-color);\n }\n :host .data-grid-row > .cell.selected.first {\n border-left: 2px solid var(--tbw-range-border-color);\n }\n :host .data-grid-row > .cell.selected.last {\n border-right: 2px solid var(--tbw-range-border-color);\n }\n ";
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
declare interface ServerSideConfig {
|
|
2996
|
+
enabled?: boolean;
|
|
2997
|
+
pageSize?: number;
|
|
2998
|
+
cacheBlockSize?: number;
|
|
2999
|
+
maxConcurrentRequests?: number;
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
export declare interface ServerSideDataSource {
|
|
3003
|
+
getRows(params: GetRowsParams): Promise<GetRowsResult>;
|
|
3004
|
+
}
|
|
3005
|
+
|
|
3006
|
+
/**
|
|
3007
|
+
* Server-Side Plugin for tbw-grid
|
|
3008
|
+
*
|
|
3009
|
+
* @example
|
|
3010
|
+
* ```ts
|
|
3011
|
+
* const plugin = new ServerSidePlugin({ cacheBlockSize: 100 });
|
|
3012
|
+
* plugin.setDataSource(myDataSource);
|
|
3013
|
+
* ```
|
|
3014
|
+
*/
|
|
3015
|
+
export declare class ServerSidePlugin extends BaseGridPlugin<ServerSideConfig> {
|
|
3016
|
+
readonly name = "serverSide";
|
|
3017
|
+
readonly version = "1.0.0";
|
|
3018
|
+
protected get defaultConfig(): Partial<ServerSideConfig>;
|
|
3019
|
+
private dataSource;
|
|
3020
|
+
private totalRowCount;
|
|
3021
|
+
private loadedBlocks;
|
|
3022
|
+
private loadingBlocks;
|
|
3023
|
+
private lastRequestId;
|
|
3024
|
+
private scrollDebounceTimer?;
|
|
3025
|
+
detach(): void;
|
|
3026
|
+
/**
|
|
3027
|
+
* Check current viewport and load any missing blocks.
|
|
3028
|
+
*/
|
|
3029
|
+
private loadRequiredBlocks;
|
|
3030
|
+
processRows(rows: readonly unknown[]): unknown[];
|
|
3031
|
+
onScroll(event: ScrollEvent): void;
|
|
3032
|
+
/**
|
|
3033
|
+
* Set the data source for server-side loading.
|
|
3034
|
+
* @param dataSource - Data source implementing the getRows method
|
|
3035
|
+
*/
|
|
3036
|
+
setDataSource(dataSource: ServerSideDataSource): void;
|
|
3037
|
+
/**
|
|
3038
|
+
* Refresh all data from the server.
|
|
3039
|
+
*/
|
|
3040
|
+
refresh(): void;
|
|
3041
|
+
/**
|
|
3042
|
+
* Clear all cached data without refreshing.
|
|
3043
|
+
*/
|
|
3044
|
+
purgeCache(): void;
|
|
3045
|
+
/**
|
|
3046
|
+
* Get the total row count from the server.
|
|
3047
|
+
*/
|
|
3048
|
+
getTotalRowCount(): number;
|
|
3049
|
+
/**
|
|
3050
|
+
* Check if a specific row is loaded in the cache.
|
|
3051
|
+
* @param rowIndex - Row index to check
|
|
3052
|
+
*/
|
|
3053
|
+
isRowLoaded(rowIndex: number): boolean;
|
|
3054
|
+
/**
|
|
3055
|
+
* Get the number of loaded cache blocks.
|
|
3056
|
+
*/
|
|
3057
|
+
getLoadedBlockCount(): number;
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
/**
|
|
3061
|
+
* Shell configuration for the grid's optional header bar and tool panels.
|
|
3062
|
+
*/
|
|
3063
|
+
export declare interface ShellConfig {
|
|
3064
|
+
/** Shell header bar configuration */
|
|
3065
|
+
header?: ShellHeaderConfig;
|
|
3066
|
+
/** Tool panel configuration */
|
|
3067
|
+
toolPanel?: ToolPanelConfig;
|
|
3068
|
+
}
|
|
3069
|
+
|
|
3070
|
+
/**
|
|
3071
|
+
* Shell header bar configuration
|
|
3072
|
+
*/
|
|
3073
|
+
export declare interface ShellHeaderConfig {
|
|
3074
|
+
/** Grid title displayed on the left (optional) */
|
|
3075
|
+
title?: string;
|
|
3076
|
+
/** Custom toolbar buttons (rendered before tool panel toggles) */
|
|
3077
|
+
toolbarButtons?: ToolbarButtonConfig[];
|
|
3078
|
+
}
|
|
3079
|
+
|
|
3080
|
+
/** Detail for a sort change (direction 0 indicates cleared sort). */
|
|
3081
|
+
export declare interface SortChangeDetail {
|
|
3082
|
+
/** Sorted field key. */
|
|
3083
|
+
field: string;
|
|
3084
|
+
/** Direction: 1 ascending, -1 descending, 0 cleared. */
|
|
3085
|
+
direction: 1 | -1 | 0;
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3088
|
+
/**
|
|
3089
|
+
* Multi-Sort Plugin Types
|
|
3090
|
+
*
|
|
3091
|
+
* Type definitions for the multi-column sorting feature.
|
|
3092
|
+
*/
|
|
3093
|
+
/** Represents a single column sort configuration */
|
|
3094
|
+
export declare interface SortModel {
|
|
3095
|
+
/** The field key to sort by */
|
|
3096
|
+
field: string;
|
|
3097
|
+
/** Sort direction */
|
|
3098
|
+
direction: 'asc' | 'desc';
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
/**
|
|
3102
|
+
* Toolbar button defined via config (programmatic approach).
|
|
3103
|
+
* Supports three modes:
|
|
3104
|
+
* - Simple: provide `icon` + `action` for grid to create button
|
|
3105
|
+
* - Element: provide `element` for user-created DOM
|
|
3106
|
+
* - Render: provide `render` function for complex widgets
|
|
3107
|
+
*/
|
|
3108
|
+
export declare interface ToolbarButtonConfig {
|
|
3109
|
+
/** Unique button ID */
|
|
3110
|
+
id: string;
|
|
3111
|
+
/** Tooltip / aria-label (required for accessibility) */
|
|
3112
|
+
label: string;
|
|
3113
|
+
/** Order priority (lower = first, default: 100) */
|
|
3114
|
+
order?: number;
|
|
3115
|
+
/** Whether button is disabled (only applies to grid-rendered buttons) */
|
|
3116
|
+
disabled?: boolean;
|
|
3117
|
+
/** Button content: SVG string, emoji, or text. Grid creates <button> with this. */
|
|
3118
|
+
icon?: string;
|
|
3119
|
+
/** Click handler (required when using icon) */
|
|
3120
|
+
action?: () => void;
|
|
3121
|
+
/**
|
|
3122
|
+
* User-provided element. Grid wraps it but doesn't modify it.
|
|
3123
|
+
* User is responsible for event handlers.
|
|
3124
|
+
*/
|
|
3125
|
+
element?: HTMLElement;
|
|
3126
|
+
/**
|
|
3127
|
+
* Render function called once. Receives container, user appends their DOM.
|
|
3128
|
+
* User is responsible for event handlers.
|
|
3129
|
+
* Return a cleanup function (optional).
|
|
3130
|
+
*/
|
|
3131
|
+
render?: (container: HTMLElement) => void | (() => void);
|
|
3132
|
+
}
|
|
3133
|
+
|
|
3134
|
+
/**
|
|
3135
|
+
* Toolbar button info returned by getToolbarButtons().
|
|
3136
|
+
*/
|
|
3137
|
+
declare interface ToolbarButtonInfo {
|
|
3138
|
+
id: string;
|
|
3139
|
+
label: string;
|
|
3140
|
+
disabled: boolean;
|
|
3141
|
+
/** Source of this button: 'config' | 'light-dom' | 'panel-toggle' */
|
|
3142
|
+
source: 'config' | 'light-dom' | 'panel-toggle';
|
|
3143
|
+
/** For panel toggles, the associated panel ID */
|
|
3144
|
+
panelId?: string;
|
|
3145
|
+
}
|
|
3146
|
+
|
|
3147
|
+
/**
|
|
3148
|
+
* Tool panel configuration
|
|
3149
|
+
*/
|
|
3150
|
+
export declare interface ToolPanelConfig {
|
|
3151
|
+
/** Panel position: 'left' | 'right' (default: 'right') */
|
|
3152
|
+
position?: 'left' | 'right';
|
|
3153
|
+
/** Default panel width in pixels (default: 280) */
|
|
3154
|
+
width?: number;
|
|
3155
|
+
/** Panel ID to open by default on load */
|
|
3156
|
+
defaultOpen?: string;
|
|
3157
|
+
/** Whether to persist open/closed state (requires Column State Events) */
|
|
3158
|
+
persistState?: boolean;
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
/**
|
|
3162
|
+
* Tool panel definition registered by plugins or consumers.
|
|
3163
|
+
*/
|
|
3164
|
+
export declare interface ToolPanelDefinition {
|
|
3165
|
+
/** Unique panel ID */
|
|
3166
|
+
id: string;
|
|
3167
|
+
/** Panel title shown in header */
|
|
3168
|
+
title: string;
|
|
3169
|
+
/** Icon for toolbar button (SVG string or emoji) */
|
|
3170
|
+
icon: string;
|
|
3171
|
+
/** Toolbar button tooltip */
|
|
3172
|
+
tooltip?: string;
|
|
3173
|
+
/** Panel content factory - called when panel opens */
|
|
3174
|
+
render: (container: HTMLElement) => void | (() => void);
|
|
3175
|
+
/** Called when panel closes (for cleanup) */
|
|
3176
|
+
onClose?: () => void;
|
|
3177
|
+
/** Panel order priority (lower = first, default: 100) */
|
|
3178
|
+
order?: number;
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
/**
|
|
3182
|
+
* Tree Data Plugin Types
|
|
3183
|
+
*
|
|
3184
|
+
* Type definitions for hierarchical tree data with expand/collapse functionality.
|
|
3185
|
+
*/
|
|
3186
|
+
/** Configuration options for the tree plugin */
|
|
3187
|
+
export declare interface TreeConfig {
|
|
3188
|
+
/** Whether tree functionality is enabled (default: true) */
|
|
3189
|
+
enabled?: boolean;
|
|
3190
|
+
/** Field name containing child rows (default: 'children') */
|
|
3191
|
+
childrenField?: string;
|
|
3192
|
+
/** Auto-detect tree structure from data (default: true) */
|
|
3193
|
+
autoDetect?: boolean;
|
|
3194
|
+
/** Whether nodes are expanded by default (default: false) */
|
|
3195
|
+
defaultExpanded?: boolean;
|
|
3196
|
+
/** Indentation width per level in pixels (default: 20) */
|
|
3197
|
+
indentWidth?: number;
|
|
3198
|
+
/** Show expand/collapse icons (default: true) */
|
|
3199
|
+
showExpandIcons?: boolean;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
/** Event detail emitted when a tree node is expanded or collapsed */
|
|
3203
|
+
export declare interface TreeExpandDetail {
|
|
3204
|
+
/** The row key that was toggled */
|
|
3205
|
+
key: string;
|
|
3206
|
+
/** The original row data */
|
|
3207
|
+
row: any;
|
|
3208
|
+
/** Whether the row is now expanded */
|
|
3209
|
+
expanded: boolean;
|
|
3210
|
+
/** Depth level of the row */
|
|
3211
|
+
depth: number;
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3214
|
+
/**
|
|
3215
|
+
* Tree Data Plugin for tbw-grid
|
|
3216
|
+
*
|
|
3217
|
+
* Provides hierarchical tree data display with expand/collapse functionality.
|
|
3218
|
+
*
|
|
3219
|
+
* @example
|
|
3220
|
+
* ```ts
|
|
3221
|
+
* new TreePlugin({ defaultExpanded: true, indentWidth: 24 })
|
|
3222
|
+
* ```
|
|
3223
|
+
*/
|
|
3224
|
+
export declare class TreePlugin extends BaseGridPlugin<TreeConfig> {
|
|
3225
|
+
readonly name = "tree";
|
|
3226
|
+
readonly version = "1.0.0";
|
|
3227
|
+
protected get defaultConfig(): Partial<TreeConfig>;
|
|
3228
|
+
/** Set of expanded row keys */
|
|
3229
|
+
private expandedKeys;
|
|
3230
|
+
/** Whether initial expansion (based on defaultExpanded config) has been applied */
|
|
3231
|
+
private initialExpansionDone;
|
|
3232
|
+
/** Flattened tree rows for rendering */
|
|
3233
|
+
private flattenedRows;
|
|
3234
|
+
/** Map from key to flattened row for quick lookup */
|
|
3235
|
+
private rowKeyMap;
|
|
3236
|
+
detach(): void;
|
|
3237
|
+
/**
|
|
3238
|
+
* Detects if tree functionality should be enabled based on data structure.
|
|
3239
|
+
* Called by the grid during plugin initialization.
|
|
3240
|
+
*/
|
|
3241
|
+
detect(rows: readonly unknown[]): boolean;
|
|
3242
|
+
processRows(rows: readonly unknown[]): any[];
|
|
3243
|
+
processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
|
|
3244
|
+
onCellClick(event: CellClickEvent): boolean;
|
|
3245
|
+
/**
|
|
3246
|
+
* Expand a specific node by key.
|
|
3247
|
+
*/
|
|
3248
|
+
expand(key: string): void;
|
|
3249
|
+
/**
|
|
3250
|
+
* Collapse a specific node by key.
|
|
3251
|
+
*/
|
|
3252
|
+
collapse(key: string): void;
|
|
3253
|
+
/**
|
|
3254
|
+
* Toggle the expansion state of a node.
|
|
3255
|
+
*/
|
|
3256
|
+
toggle(key: string): void;
|
|
3257
|
+
/**
|
|
3258
|
+
* Expand all nodes in the tree.
|
|
3259
|
+
*/
|
|
3260
|
+
expandAll(): void;
|
|
3261
|
+
/**
|
|
3262
|
+
* Collapse all nodes in the tree.
|
|
3263
|
+
*/
|
|
3264
|
+
collapseAll(): void;
|
|
3265
|
+
/**
|
|
3266
|
+
* Check if a node is currently expanded.
|
|
3267
|
+
*/
|
|
3268
|
+
isExpanded(key: string): boolean;
|
|
3269
|
+
/**
|
|
3270
|
+
* Get all currently expanded keys.
|
|
3271
|
+
*/
|
|
3272
|
+
getExpandedKeys(): string[];
|
|
3273
|
+
/**
|
|
3274
|
+
* Get the flattened tree rows with metadata.
|
|
3275
|
+
*/
|
|
3276
|
+
getFlattenedRows(): FlattenedTreeRow[];
|
|
3277
|
+
/**
|
|
3278
|
+
* Get a row's original data by its key.
|
|
3279
|
+
*/
|
|
3280
|
+
getRowByKey(key: string): any | undefined;
|
|
3281
|
+
/**
|
|
3282
|
+
* Expand all ancestors of a node to make it visible.
|
|
3283
|
+
*/
|
|
3284
|
+
expandToKey(key: string): void;
|
|
3285
|
+
readonly styles = "\n .tree-toggle {\n cursor: pointer;\n user-select: none;\n transition: transform 0.2s;\n }\n .tree-toggle:hover {\n color: var(--tbw-tree-accent, var(--tbw-color-accent));\n }\n ";
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
/**
|
|
3289
|
+
* Undo/Redo Plugin Types
|
|
3290
|
+
*
|
|
3291
|
+
* Type definitions for the undo/redo plugin that tracks
|
|
3292
|
+
* cell edits and provides undo/redo functionality.
|
|
3293
|
+
*/
|
|
3294
|
+
/** Configuration for the undo/redo plugin */
|
|
3295
|
+
declare interface UndoRedoConfig {
|
|
3296
|
+
/** Whether the plugin is enabled. Default: true */
|
|
3297
|
+
enabled?: boolean;
|
|
3298
|
+
/** Maximum number of actions to keep in history. Default: 100 */
|
|
3299
|
+
maxHistorySize?: number;
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
/**
|
|
3303
|
+
* Class-based Undo/Redo plugin for tbw-grid.
|
|
3304
|
+
*
|
|
3305
|
+
* Tracks cell edits and provides undo/redo functionality via keyboard shortcuts
|
|
3306
|
+
* or programmatic API.
|
|
3307
|
+
*/
|
|
3308
|
+
export declare class UndoRedoPlugin extends BaseGridPlugin<UndoRedoConfig> {
|
|
3309
|
+
readonly name = "undoRedo";
|
|
3310
|
+
readonly version = "1.0.0";
|
|
3311
|
+
protected get defaultConfig(): Partial<UndoRedoConfig>;
|
|
3312
|
+
private undoStack;
|
|
3313
|
+
private redoStack;
|
|
3314
|
+
/**
|
|
3315
|
+
* Clean up state when plugin is detached.
|
|
3316
|
+
*/
|
|
3317
|
+
detach(): void;
|
|
3318
|
+
/**
|
|
3319
|
+
* Handle keyboard shortcuts for undo/redo.
|
|
3320
|
+
* - Ctrl+Z / Cmd+Z: Undo
|
|
3321
|
+
* - Ctrl+Y / Cmd+Y / Ctrl+Shift+Z / Cmd+Shift+Z: Redo
|
|
3322
|
+
*/
|
|
3323
|
+
onKeyDown(event: KeyboardEvent): boolean;
|
|
3324
|
+
/**
|
|
3325
|
+
* Record a cell edit for undo/redo tracking.
|
|
3326
|
+
* Call this when a cell value changes.
|
|
3327
|
+
*
|
|
3328
|
+
* @param rowIndex - The row index where the edit occurred
|
|
3329
|
+
* @param field - The field (column key) that was edited
|
|
3330
|
+
* @param oldValue - The value before the edit
|
|
3331
|
+
* @param newValue - The value after the edit
|
|
3332
|
+
*/
|
|
3333
|
+
recordEdit(rowIndex: number, field: string, oldValue: unknown, newValue: unknown): void;
|
|
3334
|
+
/**
|
|
3335
|
+
* Programmatically undo the last action.
|
|
3336
|
+
*
|
|
3337
|
+
* @returns The undone action, or null if nothing to undo
|
|
3338
|
+
*/
|
|
3339
|
+
undo(): EditAction | null;
|
|
3340
|
+
/**
|
|
3341
|
+
* Programmatically redo the last undone action.
|
|
3342
|
+
*
|
|
3343
|
+
* @returns The redone action, or null if nothing to redo
|
|
3344
|
+
*/
|
|
3345
|
+
redo(): EditAction | null;
|
|
3346
|
+
/**
|
|
3347
|
+
* Check if there are any actions that can be undone.
|
|
3348
|
+
*/
|
|
3349
|
+
canUndo(): boolean;
|
|
3350
|
+
/**
|
|
3351
|
+
* Check if there are any actions that can be redone.
|
|
3352
|
+
*/
|
|
3353
|
+
canRedo(): boolean;
|
|
3354
|
+
/**
|
|
3355
|
+
* Clear all undo/redo history.
|
|
3356
|
+
*/
|
|
3357
|
+
clearHistory(): void;
|
|
3358
|
+
/**
|
|
3359
|
+
* Get a copy of the current undo stack.
|
|
3360
|
+
*/
|
|
3361
|
+
getUndoStack(): EditAction[];
|
|
3362
|
+
/**
|
|
3363
|
+
* Get a copy of the current redo stack.
|
|
3364
|
+
*/
|
|
3365
|
+
getRedoStack(): EditAction[];
|
|
3366
|
+
}
|
|
3367
|
+
|
|
3368
|
+
/** Virtual window bookkeeping; modified in-place as scroll position changes. */
|
|
3369
|
+
declare interface VirtualState {
|
|
3370
|
+
enabled: boolean;
|
|
3371
|
+
rowHeight: number;
|
|
3372
|
+
/** Threshold for bypassing virtualization (renders all rows if totalRows <= bypassThreshold) */
|
|
3373
|
+
bypassThreshold: number;
|
|
3374
|
+
start: number;
|
|
3375
|
+
end: number;
|
|
3376
|
+
/** Faux scrollbar element that provides scroll events (AG Grid pattern) */
|
|
3377
|
+
container: HTMLElement | null;
|
|
3378
|
+
/** Rows viewport element for measuring visible area height */
|
|
3379
|
+
viewportEl: HTMLElement | null;
|
|
3380
|
+
/** Spacer element inside faux scrollbar for setting virtual height */
|
|
3381
|
+
totalHeightEl: HTMLElement | null;
|
|
3382
|
+
}
|
|
3383
|
+
|
|
3384
|
+
/**
|
|
3385
|
+
* Column Visibility Plugin Types
|
|
3386
|
+
*
|
|
3387
|
+
* Type definitions for the column visibility feature.
|
|
3388
|
+
*/
|
|
3389
|
+
/** Configuration options for the visibility plugin */
|
|
3390
|
+
declare interface VisibilityConfig {
|
|
3391
|
+
/** Whether visibility control is enabled (default: true) */
|
|
3392
|
+
enabled?: boolean;
|
|
3393
|
+
/** Allow hiding all columns (default: false) */
|
|
3394
|
+
allowHideAll?: boolean;
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3397
|
+
/**
|
|
3398
|
+
* Column Visibility Plugin for tbw-grid
|
|
3399
|
+
*
|
|
3400
|
+
* @example
|
|
3401
|
+
* ```ts
|
|
3402
|
+
* new VisibilityPlugin({ enabled: true, allowHideAll: false })
|
|
3403
|
+
* ```
|
|
3404
|
+
*/
|
|
3405
|
+
export declare class VisibilityPlugin extends BaseGridPlugin<VisibilityConfig> {
|
|
3406
|
+
readonly name = "visibility";
|
|
3407
|
+
readonly version = "1.0.0";
|
|
3408
|
+
/** Tool panel ID for shell integration */
|
|
3409
|
+
static readonly PANEL_ID = "columns";
|
|
3410
|
+
protected get defaultConfig(): Partial<VisibilityConfig>;
|
|
3411
|
+
private columnListElement;
|
|
3412
|
+
private isDragging;
|
|
3413
|
+
private draggedField;
|
|
3414
|
+
private draggedIndex;
|
|
3415
|
+
private dropIndex;
|
|
3416
|
+
detach(): void;
|
|
3417
|
+
/**
|
|
3418
|
+
* Register the column visibility tool panel with the shell.
|
|
3419
|
+
*/
|
|
3420
|
+
getToolPanel(): ToolPanelDefinition | undefined;
|
|
3421
|
+
/**
|
|
3422
|
+
* Show the visibility sidebar panel.
|
|
3423
|
+
*/
|
|
3424
|
+
show(): void;
|
|
3425
|
+
/**
|
|
3426
|
+
* Hide the visibility sidebar panel.
|
|
3427
|
+
*/
|
|
3428
|
+
hide(): void;
|
|
3429
|
+
/**
|
|
3430
|
+
* Toggle the visibility sidebar panel.
|
|
3431
|
+
*/
|
|
3432
|
+
toggle(): void;
|
|
3433
|
+
/**
|
|
3434
|
+
* Check if a specific column is visible.
|
|
3435
|
+
* Delegates to grid.isColumnVisible().
|
|
3436
|
+
* @param field - The field name to check
|
|
3437
|
+
* @returns True if the column is visible
|
|
3438
|
+
*/
|
|
3439
|
+
isColumnVisible(field: string): boolean;
|
|
3440
|
+
/**
|
|
3441
|
+
* Set visibility for a specific column.
|
|
3442
|
+
* Delegates to grid.setColumnVisible().
|
|
3443
|
+
* @param field - The field name of the column
|
|
3444
|
+
* @param visible - Whether the column should be visible
|
|
3445
|
+
*/
|
|
3446
|
+
setColumnVisible(field: string, visible: boolean): void;
|
|
3447
|
+
/**
|
|
3448
|
+
* Get list of all visible column fields.
|
|
3449
|
+
* @returns Array of visible field names
|
|
3450
|
+
*/
|
|
3451
|
+
getVisibleColumns(): string[];
|
|
3452
|
+
/**
|
|
3453
|
+
* Get list of all hidden column fields.
|
|
3454
|
+
* @returns Array of hidden field names
|
|
3455
|
+
*/
|
|
3456
|
+
getHiddenColumns(): string[];
|
|
3457
|
+
/**
|
|
3458
|
+
* Show all columns.
|
|
3459
|
+
* Delegates to grid.showAllColumns().
|
|
3460
|
+
*/
|
|
3461
|
+
showAll(): void;
|
|
3462
|
+
/**
|
|
3463
|
+
* Toggle visibility for a specific column.
|
|
3464
|
+
* Delegates to grid.toggleColumnVisibility().
|
|
3465
|
+
* @param field - The field name of the column
|
|
3466
|
+
*/
|
|
3467
|
+
toggleColumn(field: string): void;
|
|
3468
|
+
/**
|
|
3469
|
+
* Show a specific column.
|
|
3470
|
+
* Delegates to grid.setColumnVisible().
|
|
3471
|
+
* @param field - The field name of the column to show
|
|
3472
|
+
*/
|
|
3473
|
+
showColumn(field: string): void;
|
|
3474
|
+
/**
|
|
3475
|
+
* Hide a specific column.
|
|
3476
|
+
* Delegates to grid.setColumnVisible().
|
|
3477
|
+
* @param field - The field name of the column to hide
|
|
3478
|
+
*/
|
|
3479
|
+
hideColumn(field: string): void;
|
|
3480
|
+
/**
|
|
3481
|
+
* Get all columns with their visibility status.
|
|
3482
|
+
* Useful for building visibility UI.
|
|
3483
|
+
* @returns Array of column info with visibility status
|
|
3484
|
+
*/
|
|
3485
|
+
getAllColumns(): Array<{
|
|
3486
|
+
field: string;
|
|
3487
|
+
header: string;
|
|
3488
|
+
visible: boolean;
|
|
3489
|
+
lockVisible?: boolean;
|
|
3490
|
+
}>;
|
|
3491
|
+
/**
|
|
3492
|
+
* Check if the sidebar panel is currently open.
|
|
3493
|
+
* @returns True if the panel is open
|
|
3494
|
+
*/
|
|
3495
|
+
isPanelVisible(): boolean;
|
|
3496
|
+
/**
|
|
3497
|
+
* Render the panel content into the shell's tool panel container.
|
|
3498
|
+
* Returns a cleanup function.
|
|
3499
|
+
*/
|
|
3500
|
+
private renderPanelContent;
|
|
3501
|
+
/**
|
|
3502
|
+
* Check if a reorder plugin is present (by name to avoid static import).
|
|
3503
|
+
*/
|
|
3504
|
+
private hasReorderPlugin;
|
|
3505
|
+
/**
|
|
3506
|
+
* Build the column toggle checkboxes.
|
|
3507
|
+
* When a reorder plugin is present, adds drag handles for reordering.
|
|
3508
|
+
*/
|
|
3509
|
+
private rebuildToggles;
|
|
3510
|
+
/**
|
|
3511
|
+
* Set up drag-and-drop event listeners for a row.
|
|
3512
|
+
* On drop, emits a 'column-reorder-request' event for other plugins to handle.
|
|
3513
|
+
*/
|
|
3514
|
+
private setupDragListeners;
|
|
3515
|
+
readonly styles = "\n .tbw-visibility-content {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .tbw-visibility-list {\n flex: 1;\n overflow-y: auto;\n padding: 8px;\n }\n\n .tbw-visibility-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 4px;\n cursor: pointer;\n font-size: 13px;\n border-radius: var(--tbw-border-radius, 4px);\n position: relative;\n }\n .tbw-visibility-row:hover {\n background: var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6));\n }\n .tbw-visibility-row input[type=\"checkbox\"] {\n cursor: pointer;\n }\n .tbw-visibility-row.locked span {\n color: var(--tbw-color-fg-muted, #888);\n }\n\n /* Drag handle */\n .tbw-visibility-handle {\n cursor: grab;\n color: var(--tbw-color-fg-muted, #888);\n font-size: 10px;\n letter-spacing: -2px;\n user-select: none;\n flex-shrink: 0;\n }\n .tbw-visibility-row.reorderable:hover .tbw-visibility-handle {\n color: var(--tbw-color-fg, #1f2937);\n }\n\n /* Label wrapper for checkbox and text */\n .tbw-visibility-label {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n cursor: pointer;\n }\n\n /* Drag states */\n .tbw-visibility-row.dragging {\n opacity: 0.5;\n cursor: grabbing;\n }\n .tbw-visibility-row.drop-before::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n height: 2px;\n background: var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6));\n }\n .tbw-visibility-row.drop-after::after {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n height: 2px;\n background: var(--tbw-reorder-indicator, var(--tbw-color-accent, #3b82f6));\n }\n\n .tbw-visibility-show-all {\n margin: 8px;\n padding: 8px 12px;\n border: 1px solid var(--tbw-visibility-border, var(--tbw-color-border, #e5e7eb));\n border-radius: var(--tbw-border-radius, 4px);\n background: var(--tbw-visibility-btn-bg, var(--tbw-color-header-bg, #f9fafb));\n color: var(--tbw-color-fg, #1f2937);\n cursor: pointer;\n font-size: 13px;\n }\n .tbw-visibility-show-all:hover {\n background: var(--tbw-visibility-hover, var(--tbw-color-row-hover, #f3f4f6));\n }\n ";
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3518
|
+
export { }
|