0
# Utilities and Services
1
2
RevoGrid provides comprehensive utility functions and service classes for common operations including data manipulation, column management, dimension calculations, viewport handling, and observable state management.
3
4
## Capabilities
5
6
### Data Utilities
7
8
Utility functions for data manipulation and array operations.
9
10
```typescript { .api }
11
/**
12
* Generate array of numbers in range
13
* @param size - Number of elements to generate
14
* @param startAt - Starting number (default: 0)
15
* @returns Array of sequential numbers
16
*/
17
function range(size: number, startAt?: number): number[];
18
19
/**
20
* Find element position using binary search algorithm
21
* @param el - Element to find
22
* @param compareFn - Comparison function
23
* @returns Index of element or insertion point
24
*/
25
function findPositionInArray<T>(
26
el: T,
27
compareFn: (a: T, b: T) => number
28
): number;
29
30
/**
31
* Insert element in sorted array maintaining order
32
* @param arr - Sorted array
33
* @param el - Element to insert
34
* @param fn - Comparison function
35
* @returns Updated array
36
*/
37
function pushSorted<T>(
38
arr: T[],
39
el: T,
40
fn: (a: T, b: T) => number
41
): T[];
42
43
/**
44
* Merge two sorted arrays into one sorted array
45
* @param arr1 - First sorted array
46
* @param arr2 - Second sorted array
47
* @param compareFn - Comparison function (optional)
48
* @returns Merged sorted array
49
*/
50
function mergeSortedArray<T>(
51
arr1: T[],
52
arr2: T[],
53
compareFn?: (a: T, b: T) => number
54
): T[];
55
56
/**
57
* Scale value from one range to another
58
* @param value - Value to scale
59
* @param from - Source range [min, max]
60
* @param to - Target range [min, max]
61
* @returns Scaled value
62
*/
63
function scaleValue(
64
value: number,
65
from: [number, number],
66
to: [number, number]
67
): number;
68
69
/**
70
* Async timeout utility function
71
* @param delay - Delay in milliseconds (default: 0)
72
* @returns Promise that resolves after delay
73
*/
74
function timeout(delay?: number): Promise<void>;
75
76
/**
77
* Calculate system scrollbar size
78
* @param document - Document object
79
* @returns Scrollbar width in pixels
80
*/
81
function getScrollbarSize(document: Document): number;
82
83
/**
84
* TypeScript mixin utility function
85
* @param derivedCtor - Target constructor
86
* @param constructors - Source constructors to mix in
87
*/
88
function applyMixins(derivedCtor: any, constructors: any[]): void;
89
```
90
91
**Usage Example:**
92
93
```typescript
94
import { range, findPositionInArray, pushSorted, scaleValue } from '@revolist/revogrid';
95
96
// Generate array of numbers
97
const indices = range(10, 1); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
98
99
// Binary search in sorted array
100
const sortedNumbers = [1, 3, 5, 7, 9, 11];
101
const position = findPositionInArray(6, (a, b) => a - b); // Returns 3 (insertion point)
102
103
// Insert maintaining sort order
104
const newArray = pushSorted([1, 3, 7, 9], 5, (a, b) => a - b); // [1, 3, 5, 7, 9]
105
106
// Scale values between ranges
107
const scaled = scaleValue(5, [0, 10], [0, 100]); // 50 (5 is halfway between 0-10, so 50 is halfway between 0-100)
108
109
// Async delay
110
async function delayedOperation() {
111
console.log('Starting...');
112
await timeout(1000); // Wait 1 second
113
console.log('Completed!');
114
}
115
```
116
117
### Column Utilities
118
119
Utilities for processing and managing column definitions.
120
121
```typescript { .api }
122
/**
123
* Process column definitions and groupings into flat collection
124
* @param columns - Column definitions (can include groups)
125
* @param level - Current nesting level for groups
126
* @param columnTypes - Reusable column type definitions
127
* @returns Processed column collection
128
*/
129
function getColumns(
130
columns: (ColumnRegular | ColumnGrouping)[],
131
level?: number,
132
columnTypes?: {[name: string]: ColumnType}
133
): ColumnCollection;
134
135
/**
136
* Find column definition by property name
137
* @param columns - Array of column definitions
138
* @param prop - Column property to find
139
* @returns Column definition or undefined
140
*/
141
function getColumnByProp(
142
columns: ColumnRegular[],
143
prop: ColumnProp
144
): ColumnRegular | undefined;
145
146
/**
147
* Column collection result from processing
148
*/
149
interface ColumnCollection {
150
/** Flattened column definitions */
151
columns: ColumnRegular[];
152
/** Column grouping information */
153
groups: ColumnGrouping[];
154
/** Column order mapping */
155
order: Record<string, number>;
156
/** Maximum group depth */
157
maxLevel: number;
158
}
159
```
160
161
**Usage Example:**
162
163
```typescript
164
import { getColumns, getColumnByProp, ColumnRegular, ColumnGrouping } from '@revolist/revogrid';
165
166
// Define columns with grouping
167
const columnDefs: (ColumnRegular | ColumnGrouping)[] = [
168
{ prop: 'id', name: 'ID' },
169
{
170
name: 'Personal Info',
171
children: [
172
{ prop: 'firstName', name: 'First Name' },
173
{ prop: 'lastName', name: 'Last Name' }
174
]
175
},
176
{ prop: 'email', name: 'Email' }
177
];
178
179
// Process columns
180
const processed = getColumns(columnDefs, 0);
181
console.log('Processed columns:', processed.columns.length); // 4 (flattened)
182
console.log('Groups:', processed.groups); // Grouping information
183
console.log('Max level:', processed.maxLevel); // 1 (one level of grouping)
184
185
// Find specific column
186
const emailColumn = getColumnByProp(processed.columns, 'email');
187
console.log('Email column:', emailColumn?.name);
188
```
189
190
### Event Utilities
191
192
Utilities for handling DOM events across different input types.
193
194
```typescript { .api }
195
/**
196
* Get property value from event (handles touch/mouse events)
197
* @param event - DOM event (mouse or touch)
198
* @param property - Property to extract ('clientX', 'clientY', etc.)
199
* @returns Property value from event
200
*/
201
function getPropertyFromEvent(event: Event, property: string): any;
202
203
/**
204
* Keyboard key code constants
205
*/
206
const KEY_CODES: {
207
readonly ARROW_LEFT: number;
208
readonly ARROW_UP: number;
209
readonly ARROW_RIGHT: number;
210
readonly ARROW_DOWN: number;
211
readonly ENTER: number;
212
readonly ESCAPE: number;
213
readonly TAB: number;
214
readonly SPACE: number;
215
readonly DELETE: number;
216
readonly BACKSPACE: number;
217
readonly HOME: number;
218
readonly END: number;
219
readonly PAGE_UP: number;
220
readonly PAGE_DOWN: number;
221
readonly F2: number;
222
};
223
```
224
225
**Usage Example:**
226
227
```typescript
228
import { getPropertyFromEvent, KEY_CODES } from '@revolist/revogrid';
229
230
// Handle mouse and touch events uniformly
231
function handlePointerEvent(event: MouseEvent | TouchEvent) {
232
const x = getPropertyFromEvent(event, 'clientX');
233
const y = getPropertyFromEvent(event, 'clientY');
234
console.log('Pointer position:', { x, y });
235
}
236
237
// Handle keyboard navigation
238
function handleKeyDown(event: KeyboardEvent) {
239
switch (event.keyCode) {
240
case KEY_CODES.ARROW_LEFT:
241
moveLeft();
242
break;
243
case KEY_CODES.ARROW_RIGHT:
244
moveRight();
245
break;
246
case KEY_CODES.ENTER:
247
startEdit();
248
break;
249
case KEY_CODES.ESCAPE:
250
cancelEdit();
251
break;
252
case KEY_CODES.F2:
253
toggleEdit();
254
break;
255
}
256
}
257
```
258
259
### Browser Utilities
260
261
Utilities for browser feature detection and measurements.
262
263
```typescript { .api }
264
/**
265
* Calculate system scrollbar size for current browser
266
* @param document - Document object
267
* @returns Scrollbar width in pixels
268
*/
269
function getScrollbarSize(document: Document): number;
270
```
271
272
**Usage Example:**
273
274
```typescript
275
import { getScrollbarSize } from '@revolist/revogrid';
276
277
// Get scrollbar size for layout calculations
278
const scrollbarWidth = getScrollbarSize(document);
279
console.log('System scrollbar width:', scrollbarWidth); // Usually 15-17px
280
281
// Use for layout adjustments
282
function adjustGridLayout() {
283
const containerWidth = container.clientWidth;
284
const contentWidth = containerWidth - scrollbarWidth;
285
grid.style.width = `${contentWidth}px`;
286
}
287
```
288
289
### Observable System
290
291
Reactive state management system used internally by RevoGrid.
292
293
```typescript { .api }
294
/**
295
* Observable interface for reactive state management
296
*/
297
interface Observable<T> {
298
/** Subscribe to state changes */
299
onChange(callback: (newState: T, oldState?: T) => void): () => void;
300
301
/** Get current state value */
302
get(): T;
303
304
/** Set new state value */
305
set(state: T): void;
306
307
/** Update state using function */
308
update(updater: (currentState: T) => T): void;
309
}
310
311
/**
312
* Store types for different grid stores
313
*/
314
interface StoreTypes {
315
/** Data source store */
316
DataSourceStore: Observable<DataSourceState>;
317
/** Column store */
318
ColumnStore: Observable<ColumnCollection>;
319
/** Dimension store */
320
DimensionStore: Observable<DimensionSettingsState>;
321
/** Viewport store */
322
ViewportStore: Observable<ViewportState>;
323
/** Selection store */
324
SelectionStore: Observable<SelectionStoreState>;
325
}
326
```
327
328
**Usage Example:**
329
330
```typescript
331
// Access grid stores through providers
332
const providers = await grid.getProviders();
333
334
// Subscribe to data changes
335
const dataStore = await grid.getSourceStore('rgRow');
336
const unsubscribe = dataStore.onChange((newState, oldState) => {
337
console.log('Data changed:', {
338
oldCount: oldState?.source.length || 0,
339
newCount: newState.source.length
340
});
341
342
// React to data changes
343
updateDataSummary(newState.source);
344
});
345
346
// Get current state
347
const currentData = dataStore.get();
348
console.log('Current data:', currentData.source);
349
350
// Clean up subscription when done
351
// unsubscribe();
352
```
353
354
### Data Provider Service
355
356
Service class for managing grid data sources and operations.
357
358
```typescript { .api }
359
/**
360
* Data provider service for managing grid data
361
*/
362
class DataProvider {
363
/**
364
* Set data source for specific dimension
365
* @param source - Data array
366
* @param type - Dimension type
367
* @param disableVirtual - Disable virtualization for this data
368
*/
369
setData(source: DataType[], type: DimensionRows, disableVirtual?: boolean): void;
370
371
/**
372
* Update specific cell data
373
* @param details - Cell update details
374
* @param refresh - Whether to refresh grid view
375
*/
376
setCellData(details: SetCellData, refresh?: boolean): void;
377
378
/**
379
* Update range of data
380
* @param data - Range update data
381
* @param type - Dimension type
382
*/
383
setRangeData(data: RangeUpdateData, type: DimensionRows): void;
384
385
/**
386
* Refresh data for specific dimension type
387
* @param type - Dimension type to refresh
388
*/
389
refresh(type?: DimensionRows): void;
390
391
/**
392
* Change row order (for drag and drop)
393
* @param details - Order change details
394
*/
395
changeOrder(details: RowOrderChangeDetails): void;
396
397
/**
398
* Set trimmed/hidden rows
399
* @param trimmed - Trimmed row configuration
400
* @param type - Dimension type
401
*/
402
setTrimmed(trimmed: Record<number, boolean>, type: DimensionRows): void;
403
}
404
```
405
406
### Column Data Provider Service
407
408
Service class for managing column definitions and operations.
409
410
```typescript { .api }
411
/**
412
* Column data provider service
413
*/
414
class ColumnDataProvider {
415
/**
416
* Set processed column collection
417
* @param collection - Processed column collection
418
*/
419
setColumns(collection: ColumnCollection): void;
420
421
/**
422
* Update existing columns
423
* @param cols - Updated column definitions
424
*/
425
updateColumns(cols: ColumnRegular[]): void;
426
427
/**
428
* Get all column definitions
429
* @returns Array of column definitions
430
*/
431
getColumns(): ColumnRegular[];
432
433
/**
434
* Get column by index for specific dimension
435
* @param index - Column index
436
* @param type - Column dimension type
437
* @returns Column definition or undefined
438
*/
439
getColumn(index: number, type: DimensionCols): ColumnRegular | undefined;
440
441
/**
442
* Get column index by property name
443
* @param prop - Column property
444
* @param type - Column dimension type
445
* @returns Column index or -1 if not found
446
*/
447
getColumnIndexByProp(prop: ColumnProp, type: DimensionCols): number;
448
}
449
```
450
451
### Dimension Provider Service
452
453
Service class for managing dimension calculations and viewport sizing.
454
455
```typescript { .api }
456
/**
457
* Dimension provider service for calculations
458
*/
459
class DimensionProvider {
460
/**
461
* Update dimension settings
462
* @param settings - New dimension settings
463
* @param type - Dimension type
464
*/
465
setSettings(settings: DimensionSettingsState, type: DimensionRows | DimensionCols): void;
466
467
/**
468
* Apply new column configuration
469
* @param columns - Column definitions
470
* @param disableVirtual - Disable virtualization
471
* @param init - Is initialization
472
*/
473
applyNewColumns(columns: ColumnRegular[], disableVirtual?: boolean, init?: boolean): void;
474
475
/**
476
* Set custom sizes for items
477
* @param type - Dimension type
478
* @param sizes - Custom size mapping
479
*/
480
setCustomSizes(type: DimensionRows | DimensionCols, sizes: ViewSettingSizeProp): void;
481
482
/**
483
* Clear size data
484
* @param type - Dimension type
485
* @param length - New length
486
*/
487
clearSize(type: DimensionRows | DimensionCols, length: number): void;
488
489
/**
490
* Get viewport position information
491
* @param params - Position parameters
492
* @returns Position details
493
*/
494
getViewPortPos(params: ViewportPositionParams): PositionItem;
495
496
/**
497
* Get full content size
498
* @returns Content size for all dimensions
499
*/
500
getFullSize(): MultiDimensionType;
501
}
502
503
/**
504
* Viewport position parameters
505
*/
506
interface ViewportPositionParams {
507
/** Coordinate to find */
508
coordinate: number;
509
/** Dimension type */
510
type: DimensionRows | DimensionCols;
511
}
512
513
/**
514
* Position item information
515
*/
516
interface PositionItem {
517
/** Item index */
518
index: number;
519
/** Item position */
520
position: number;
521
/** Item size */
522
size: number;
523
}
524
525
/**
526
* View setting size properties
527
*/
528
interface ViewSettingSizeProp {
529
[index: number]: number;
530
}
531
```
532
533
**Usage Example:**
534
535
```typescript
536
// Access providers through grid
537
const providers = await grid.getProviders();
538
539
// Use data provider
540
const dataProvider = providers.data;
541
dataProvider.setCellData({
542
row: 0,
543
col: 'name',
544
val: 'Updated Name',
545
rowSource: 'rgRow'
546
});
547
548
// Use column provider
549
const columnProvider = providers.column;
550
const columns = columnProvider.getColumns();
551
console.log('Current columns:', columns.length);
552
553
// Find column index
554
const nameColumnIndex = columnProvider.getColumnIndexByProp('name', 'rgCol');
555
556
// Use dimension provider
557
const dimensionProvider = providers.dimension;
558
const contentSize = dimensionProvider.getFullSize();
559
console.log('Content size:', contentSize);
560
561
// Set custom column sizes
562
dimensionProvider.setCustomSizes('rgCol', {
563
0: 150, // First column 150px
564
1: 200, // Second column 200px
565
2: 100 // Third column 100px
566
});
567
```
568
569
### Selection Store Connector
570
571
Service class for managing selection state across grid components.
572
573
```typescript { .api }
574
/**
575
* Selection store connector service
576
*/
577
class SelectionStoreConnector {
578
/**
579
* Set edit state for cell
580
* @param val - Edit state value or null to clear
581
*/
582
setEdit(val: EditCellStore | null): void;
583
584
/**
585
* Select all cells in grid
586
*/
587
selectAll(): void;
588
589
/**
590
* Clear all selections and focus
591
*/
592
clearAll(): void;
593
594
/**
595
* Handle focus navigation to next cell
596
* @param event - Navigation event details
597
*/
598
beforeNextFocusCell(event: BeforeNextFocusCellEvent): void;
599
}
600
601
/**
602
* Before next focus cell event
603
*/
604
interface BeforeNextFocusCellEvent {
605
/** Current focused cell */
606
currentCell: Cell;
607
/** Direction of navigation */
608
direction: 'up' | 'down' | 'left' | 'right';
609
/** Whether to wrap around edges */
610
wrap: boolean;
611
}
612
```
613
614
**Usage Example:**
615
616
```typescript
617
// Access selection connector
618
const providers = await grid.getProviders();
619
const selection = providers.selection;
620
621
// Select all cells
622
selection.selectAll();
623
624
// Clear selections
625
selection.clearAll();
626
627
// Set edit mode for specific cell
628
selection.setEdit({
629
row: 2,
630
col: 'email',
631
val: 'editing...',
632
rowType: 'rgRow'
633
});
634
635
// Clear edit mode
636
selection.setEdit(null);
637
```