or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-stores.mdevents.mdindex.mdplugins.mdrevo-grid-component.mdtypes-interfaces.mdutilities.md

events.mddocs/

0

# Events and Handlers

1

2

RevoGrid provides a comprehensive event system covering all grid interactions including data changes, user interactions, lifecycle events, and plugin events. All events follow modern naming conventions and provide detailed event information.

3

4

## Capabilities

5

6

### Data Events

7

8

Events related to data changes and editing operations.

9

10

```typescript { .api }

11

/**

12

* Before cell edit event - fired before cell value changes

13

*/

14

addEventListener(type: 'beforeedit', listener: (e: CustomEvent<BeforeSaveDataDetails>) => void): void;

15

16

/**

17

* Before range edit event - fired before range data changes

18

*/

19

addEventListener(type: 'beforerangeedit', listener: (e: CustomEvent<BeforeRangeSaveDataDetails>) => void): void;

20

21

/**

22

* After edit event - fired after data change is complete

23

*/

24

addEventListener(type: 'afteredit', listener: (e: CustomEvent<AfterEditEvent>) => void): void;

25

26

/**

27

* Before autofill operation

28

*/

29

addEventListener(type: 'beforeautofill', listener: (e: CustomEvent<ChangedRange>) => void): void;

30

31

/**

32

* Before range change operation

33

*/

34

addEventListener(type: 'beforerange', listener: (e: CustomEvent<ChangedRange>) => void): void;

35

36

/**

37

* Before cell edit event detail

38

*/

39

interface BeforeSaveDataDetails {

40

/** New value being set */

41

val: any;

42

/** Previous value */

43

oldVal: any;

44

/** Row data object */

45

row: DataType;

46

/** Column definition */

47

col: ColumnRegular;

48

/** All grid data */

49

models: DataType[];

50

}

51

52

/**

53

* Before range edit event detail

54

*/

55

interface BeforeRangeSaveDataDetails {

56

/** Range being modified */

57

range: RangeArea;

58

/** Data being set */

59

data: any[][];

60

/** Models being affected */

61

models: DataType[];

62

}

63

64

/**

65

* After edit event detail

66

*/

67

interface AfterEditEvent {

68

/** New value that was set */

69

val: any;

70

/** Previous value */

71

oldVal: any;

72

/** Updated row data */

73

row: DataType;

74

/** Column definition */

75

col: ColumnRegular;

76

/** Updated grid data */

77

models: DataType[];

78

}

79

80

/**

81

* Changed range information

82

*/

83

interface ChangedRange {

84

/** Range that changed */

85

range: RangeArea;

86

/** Change type */

87

type: string;

88

/** Source dimension */

89

source: DimensionRows;

90

}

91

```

92

93

**Usage Example:**

94

95

```typescript

96

// Handle cell editing events

97

grid.addEventListener('beforeedit', (e) => {

98

const { val, oldVal, col, row } = e.detail;

99

100

// Validate new value

101

if (col.prop === 'age' && (val < 0 || val > 120)) {

102

e.preventDefault(); // Cancel the edit

103

alert('Age must be between 0 and 120');

104

return;

105

}

106

107

console.log(`Changing ${col.prop} from ${oldVal} to ${val}`);

108

});

109

110

grid.addEventListener('afteredit', (e) => {

111

const { val, col, row } = e.detail;

112

console.log(`Successfully updated ${col.prop} to ${val} in row:`, row);

113

114

// Trigger additional actions

115

if (col.prop === 'status') {

116

// Update related fields or trigger API calls

117

}

118

});

119

120

// Handle range operations

121

grid.addEventListener('beforerangeedit', (e) => {

122

const { range, data } = e.detail;

123

console.log(`Updating range from (${range.x},${range.y}) to (${range.x1},${range.y1})`);

124

console.log('New data:', data);

125

});

126

```

127

128

### Source Events

129

130

Events related to data source management and changes.

131

132

```typescript { .api }

133

/**

134

* Before main source is set

135

*/

136

addEventListener(type: 'beforesourceset', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

137

138

/**

139

* Before any source is set (including pinned)

140

*/

141

addEventListener(type: 'beforeanysource', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

142

143

/**

144

* After main source is set

145

*/

146

addEventListener(type: 'aftersourceset', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

147

148

/**

149

* After any source is set (including pinned)

150

*/

151

addEventListener(type: 'afteranysource', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

152

153

/**

154

* Source set event detail

155

*/

156

interface SourceSetEvent {

157

/** Dimension type being set */

158

type: DimensionRows;

159

/** Data source being set */

160

source: DataType[];

161

}

162

```

163

164

**Usage Example:**

165

166

```typescript

167

// Monitor data source changes

168

grid.addEventListener('beforesourceset', (e) => {

169

const { type, source } = e.detail;

170

console.log(`Setting ${type} data with ${source.length} items`);

171

172

// Perform data validation or transformation

173

if (source.length > 10000) {

174

console.warn('Large dataset detected, performance may be affected');

175

}

176

});

177

178

grid.addEventListener('aftersourceset', (e) => {

179

const { type, source } = e.detail;

180

console.log(`Successfully set ${type} data`);

181

182

// Update UI or trigger related operations

183

updateDataSummary(source);

184

});

185

```

186

187

### Column Events

188

189

Events related to column operations and changes.

190

191

```typescript { .api }

192

/**

193

* Before columns are set

194

*/

195

addEventListener(type: 'beforecolumnsset', listener: (e: CustomEvent<ColumnCollection>) => void): void;

196

197

/**

198

* Before columns are applied to grid

199

*/

200

addEventListener(type: 'beforecolumnapplied', listener: (e: CustomEvent<ColumnCollection>) => void): void;

201

202

/**

203

* After columns are set

204

*/

205

addEventListener(type: 'aftercolumnsset', listener: (e: CustomEvent<AfterColumnsSetEvent>) => void): void;

206

207

/**

208

* After column resize operation

209

*/

210

addEventListener(type: 'aftercolumnresize', listener: (e: CustomEvent<ColumnResizeEvent>) => void): void;

211

212

/**

213

* After columns set event detail

214

*/

215

interface AfterColumnsSetEvent {

216

/** Updated column definitions */

217

columns: ColumnRegular[];

218

/** Column order mapping */

219

order: Record<string, number>;

220

}

221

222

/**

223

* Column resize event detail

224

*/

225

interface ColumnResizeEvent {

226

/** Map of column index to updated column */

227

[index: number]: ColumnRegular;

228

}

229

230

/**

231

* Column collection type

232

*/

233

interface ColumnCollection {

234

/** Column definitions */

235

columns: ColumnRegular[];

236

/** Column grouping information */

237

groups?: ColumnGrouping[];

238

/** Column order */

239

order: Record<string, number>;

240

}

241

```

242

243

**Usage Example:**

244

245

```typescript

246

// Handle column configuration changes

247

grid.addEventListener('beforecolumnsset', (e) => {

248

const { columns } = e.detail;

249

console.log('Setting columns:', columns.map(c => c.name));

250

251

// Validate column configuration

252

const duplicateProps = findDuplicateProps(columns);

253

if (duplicateProps.length > 0) {

254

console.error('Duplicate column properties found:', duplicateProps);

255

e.preventDefault();

256

}

257

});

258

259

grid.addEventListener('aftercolumnsset', (e) => {

260

const { columns, order } = e.detail;

261

console.log('Columns set successfully:', columns.length);

262

263

// Save column configuration

264

saveColumnConfiguration(columns, order);

265

});

266

267

grid.addEventListener('aftercolumnresize', (e) => {

268

const resizedColumns = e.detail;

269

console.log('Columns resized:', Object.keys(resizedColumns));

270

271

// Persist column sizes

272

Object.entries(resizedColumns).forEach(([index, column]) => {

273

saveColumnSize(column.prop, column.size);

274

});

275

});

276

```

277

278

### Selection Events

279

280

Events related to cell focus and selection operations.

281

282

```typescript { .api }

283

/**

284

* Before cell focus changes

285

*/

286

addEventListener(type: 'beforecellfocus', listener: (e: CustomEvent<BeforeSaveDataDetails>) => void): void;

287

288

/**

289

* Before focus is lost

290

*/

291

addEventListener(type: 'beforefocuslost', listener: (e: CustomEvent<FocusedData | null>) => void): void;

292

293

/**

294

* After focus render is complete

295

*/

296

addEventListener(type: 'afterfocus', listener: (e: CustomEvent<FocusAfterRenderEvent>) => void): void;

297

298

/**

299

* Focused data information

300

*/

301

interface FocusedData {

302

/** Focused cell coordinate */

303

cell: Cell;

304

/** Cell value */

305

val: any;

306

/** Row dimension type */

307

rowType: DimensionRows;

308

/** Column dimension type */

309

colType: DimensionCols;

310

}

311

312

/**

313

* After focus render event detail

314

*/

315

interface FocusAfterRenderEvent {

316

/** New focus data */

317

focus: FocusedData;

318

/** Previous focus data */

319

prevFocus?: FocusedData;

320

}

321

```

322

323

**Usage Example:**

324

325

```typescript

326

// Handle focus and selection events

327

grid.addEventListener('beforecellfocus', (e) => {

328

const { row, col } = e.detail;

329

console.log(`Focusing cell ${col.prop} in row:`, row);

330

331

// Custom focus validation

332

if (row.locked) {

333

e.preventDefault();

334

showMessage('Cannot focus on locked row');

335

}

336

});

337

338

grid.addEventListener('afterfocus', (e) => {

339

const { focus, prevFocus } = e.detail;

340

console.log(`Focus moved from (${prevFocus?.cell.x},${prevFocus?.cell.y}) to (${focus.cell.x},${focus.cell.y})`);

341

342

// Update UI elements based on focus

343

updatePropertyPanel(focus.val, focus.rowType, focus.colType);

344

});

345

```

346

347

### Sorting Events

348

349

Events related to sorting operations.

350

351

```typescript { .api }

352

/**

353

* Before sorting operation

354

*/

355

addEventListener(type: 'beforesorting', listener: (e: CustomEvent<BeforeSortingEvent>) => void): void;

356

357

/**

358

* Before source sorting is applied

359

*/

360

addEventListener(type: 'beforesourcesortingapply', listener: (e: CustomEvent<BeforeSourceSortingEvent>) => void): void;

361

362

/**

363

* Before sorting is applied to column

364

*/

365

addEventListener(type: 'beforesortingapply', listener: (e: CustomEvent<BeforeSortingEvent>) => void): void;

366

367

/**

368

* Before sorting event detail

369

*/

370

interface BeforeSortingEvent {

371

/** Column being sorted */

372

column: ColumnRegular;

373

/** Sort order */

374

order: Order;

375

/** Whether this is additive to existing sort */

376

additive: boolean;

377

}

378

379

/**

380

* Before source sorting event detail

381

*/

382

interface BeforeSourceSortingEvent {

383

/** Dimension type being sorted */

384

type: DimensionRows;

385

/** Sorting configuration */

386

sorting: SortingConfig;

387

}

388

389

/**

390

* Sorting configuration

391

*/

392

interface SortingConfig {

393

/** Columns to sort by */

394

sortBy?: ColumnProp[];

395

/** Enable multi-column sorting */

396

multiColumn?: boolean;

397

}

398

```

399

400

**Usage Example:**

401

402

```typescript

403

// Handle sorting events

404

grid.addEventListener('beforesorting', (e) => {

405

const { column, order, additive } = e.detail;

406

console.log(`Sorting column ${column.prop} in ${order} order, additive: ${additive}`);

407

408

// Custom sorting validation

409

if (column.prop === 'id' && order === 'desc') {

410

console.warn('Descending sort on ID may affect performance');

411

}

412

});

413

414

grid.addEventListener('beforesortingapply', (e) => {

415

const { column, order } = e.detail;

416

console.log(`Applying sort to ${column.prop}`);

417

418

// Show loading indicator for large datasets

419

if (grid.source.length > 5000) {

420

showLoadingIndicator('Sorting large dataset...');

421

}

422

});

423

```

424

425

### Filter Events

426

427

Events related to filtering operations.

428

429

```typescript { .api }

430

/**

431

* Before filter is applied

432

*/

433

addEventListener(type: 'beforefilterapply', listener: (e: CustomEvent<BeforeFilterEvent>) => void): void;

434

435

/**

436

* Before filtered items are trimmed

437

*/

438

addEventListener(type: 'beforefiltertrimmed', listener: (e: CustomEvent<BeforeFilterTrimmedEvent>) => void): void;

439

440

/**

441

* Before items are trimmed/hidden

442

*/

443

addEventListener(type: 'beforetrimmed', listener: (e: CustomEvent<BeforeTrimmedEvent>) => void): void;

444

445

/**

446

* After trimmed operation is complete

447

*/

448

addEventListener(type: 'aftertrimmed', listener: (e: CustomEvent<void>) => void): void;

449

450

/**

451

* Before filter event detail

452

*/

453

interface BeforeFilterEvent {

454

/** Filter collection being applied */

455

collection: FilterCollection;

456

}

457

458

/**

459

* Before filter trimmed event detail

460

*/

461

interface BeforeFilterTrimmedEvent {

462

/** Filter collection */

463

collection: FilterCollection;

464

/** Items to be filtered out */

465

itemsToFilter: number[];

466

}

467

468

/**

469

* Before trimmed event detail

470

*/

471

interface BeforeTrimmedEvent {

472

/** Trimmed configuration */

473

trimmed: Record<number, boolean>;

474

/** Type of trimmed operation */

475

trimmedType: string;

476

/** Dimension type */

477

type: DimensionRows;

478

}

479

480

/**

481

* Filter collection type

482

*/

483

interface FilterCollection {

484

[columnProp: string]: FilterData;

485

}

486

487

/**

488

* Filter data for individual column

489

*/

490

interface FilterData {

491

/** Filter type */

492

type: string;

493

/** Filter criteria */

494

criteria: any;

495

/** Filter function */

496

filter?: (value: any, criteria: any) => boolean;

497

}

498

```

499

500

**Usage Example:**

501

502

```typescript

503

// Handle filtering events

504

grid.addEventListener('beforefilterapply', (e) => {

505

const { collection } = e.detail;

506

const activeFilters = Object.keys(collection);

507

console.log('Applying filters to columns:', activeFilters);

508

509

// Validate filter criteria

510

for (const [column, filterData] of Object.entries(collection)) {

511

if (!filterData.criteria) {

512

console.warn(`Empty filter criteria for column ${column}`);

513

}

514

}

515

});

516

517

grid.addEventListener('beforefiltertrimmed', (e) => {

518

const { collection, itemsToFilter } = e.detail;

519

console.log(`Filtering will hide ${itemsToFilter.length} rows`);

520

521

// Show filter summary

522

updateFilterSummary(collection, itemsToFilter.length);

523

});

524

525

grid.addEventListener('aftertrimmed', (e) => {

526

console.log('Filter operation completed');

527

528

// Update UI to reflect filtered state

529

updateRowCountDisplay();

530

hideLoadingIndicator();

531

});

532

```

533

534

### UI Events

535

536

Events related to user interface interactions.

537

538

```typescript { .api }

539

/**

540

* Header click event

541

*/

542

addEventListener(type: 'headerclick', listener: (e: CustomEvent<ColumnRegular>) => void): void;

543

544

/**

545

* Row drag start event

546

*/

547

addEventListener(type: 'rowdragstart', listener: (e: CustomEvent<RowDragStartDetails>) => void): void;

548

549

/**

550

* Row order changed event

551

*/

552

addEventListener(type: 'roworderchanged', listener: (e: CustomEvent<RowOrderChangeEvent>) => void): void;

553

554

/**

555

* Viewport scroll event

556

*/

557

addEventListener(type: 'viewportscroll', listener: (e: CustomEvent<ViewPortScrollEvent>) => void): void;

558

559

/**

560

* Row drag start details

561

*/

562

interface RowDragStartDetails {

563

/** Row being dragged */

564

row: DataType;

565

/** Row index */

566

index: number;

567

/** Dimension type */

568

type: DimensionRows;

569

}

570

571

/**

572

* Row order change event detail

573

*/

574

interface RowOrderChangeEvent {

575

/** Source row index */

576

from: number;

577

/** Target row index */

578

to: number;

579

}

580

581

/**

582

* Viewport scroll event detail

583

*/

584

interface ViewPortScrollEvent {

585

/** Scroll position */

586

coordinate: {

587

x: number;

588

y: number;

589

};

590

/** Dimension type */

591

dimension: DimensionRows | DimensionCols;

592

}

593

```

594

595

**Usage Example:**

596

597

```typescript

598

// Handle UI interaction events

599

grid.addEventListener('headerclick', (e) => {

600

const column = e.detail;

601

console.log(`Header clicked for column: ${column.name}`);

602

603

// Custom header click behavior

604

if (column.prop === 'actions') {

605

showColumnMenu(column);

606

}

607

});

608

609

grid.addEventListener('rowdragstart', (e) => {

610

const { row, index, type } = e.detail;

611

console.log(`Starting to drag row ${index} from ${type}`);

612

613

// Custom drag validation

614

if (row.locked) {

615

e.preventDefault();

616

showMessage('Cannot drag locked row');

617

}

618

});

619

620

grid.addEventListener('roworderchanged', (e) => {

621

const { from, to } = e.detail;

622

console.log(`Row moved from position ${from} to ${to}`);

623

624

// Save new order or trigger API update

625

saveRowOrder(from, to);

626

});

627

628

grid.addEventListener('viewportscroll', (e) => {

629

const { coordinate, dimension } = e.detail;

630

console.log(`Viewport scrolled in ${dimension} to:`, coordinate);

631

632

// Update scroll-based UI elements

633

updateScrollIndicator(coordinate, dimension);

634

});

635

```

636

637

### Lifecycle Events

638

639

Events related to grid lifecycle and initialization.

640

641

```typescript { .api }

642

/**

643

* Before grid render

644

*/

645

addEventListener(type: 'beforegridrender', listener: (e: CustomEvent<void>) => void): void;

646

647

/**

648

* After grid render is complete

649

*/

650

addEventListener(type: 'aftergridrender', listener: (e: CustomEvent<void>) => void): void;

651

652

/**

653

* After grid initialization is complete

654

*/

655

addEventListener(type: 'aftergridinit', listener: (e: CustomEvent<void>) => void): void;

656

657

/**

658

* Grid created event

659

*/

660

addEventListener(type: 'created', listener: (e: CustomEvent<void>) => void): void;

661

662

/**

663

* Content size changed

664

*/

665

addEventListener(type: 'contentsizechanged', listener: (e: CustomEvent<MultiDimensionType>) => void): void;

666

667

/**

668

* Multi-dimension type for size events

669

*/

670

interface MultiDimensionType {

671

[key: string]: number;

672

}

673

```

674

675

**Usage Example:**

676

677

```typescript

678

// Handle grid lifecycle events

679

grid.addEventListener('created', (e) => {

680

console.log('Grid component created');

681

682

// Initialize custom functionality

683

initializeCustomFeatures();

684

});

685

686

grid.addEventListener('aftergridinit', (e) => {

687

console.log('Grid initialization completed');

688

689

// Grid is ready for interaction

690

enableUserInteractions();

691

loadInitialData();

692

});

693

694

grid.addEventListener('contentsizechanged', (e) => {

695

const sizes = e.detail;

696

console.log('Content size changed:', sizes);

697

698

// Update layout or scroll indicators

699

updateLayoutBasedOnSize(sizes);

700

});

701

```

702

703

### Configuration Events

704

705

Events related to configuration changes.

706

707

```typescript { .api }

708

/**

709

* Filter configuration changed

710

*/

711

addEventListener(type: 'filterconfigchanged', listener: (e: CustomEvent<void>) => void): void;

712

713

/**

714

* Sorting configuration changed

715

*/

716

addEventListener(type: 'sortingconfigchanged', listener: (e: CustomEvent<SortingConfig>) => void): void;

717

718

/**

719

* Row headers configuration changed

720

*/

721

addEventListener(type: 'rowheaderschanged', listener: (e: CustomEvent<void>) => void): void;

722

723

/**

724

* Additional data changed

725

*/

726

addEventListener(type: 'additionaldatachanged', listener: (e: CustomEvent<any>) => void): void;

727

728

/**

729

* Theme changed

730

*/

731

addEventListener(type: 'afterthemechanged', listener: (e: CustomEvent<Theme>) => void): void;

732

733

/**

734

* Export events

735

*/

736

addEventListener(type: 'beforeexport', listener: (e: CustomEvent<DataInput>) => void): void;

737

738

/**

739

* Data input for export

740

*/

741

interface DataInput {

742

/** Data to export */

743

data: DataType[];

744

/** Export options */

745

options?: ExportOptions;

746

}

747

748

/**

749

* Export options

750

*/

751

interface ExportOptions {

752

/** Export format */

753

format: 'csv' | 'excel' | 'json';

754

/** Include headers */

755

includeHeaders?: boolean;

756

/** File name */

757

filename?: string;

758

}

759

```

760

761

**Usage Example:**

762

763

```typescript

764

// Handle configuration change events

765

grid.addEventListener('sortingconfigchanged', (e) => {

766

const config = e.detail;

767

console.log('Sorting configuration changed:', config);

768

769

// Save user preferences

770

saveUserPreferences({ sorting: config });

771

});

772

773

grid.addEventListener('afterthemechanged', (e) => {

774

const newTheme = e.detail;

775

console.log(`Theme changed to: ${newTheme}`);

776

777

// Update application theme

778

updateApplicationTheme(newTheme);

779

});

780

781

grid.addEventListener('beforeexport', (e) => {

782

const { data, options } = e.detail;

783

console.log(`Exporting ${data.length} rows in ${options?.format} format`);

784

785

// Add export metadata

786

if (options) {

787

options.filename = options.filename || `grid-export-${Date.now()}`;

788

}

789

});

790

```