or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

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

events.mddocs/

Events and Handlers

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.

Capabilities

Data Events

Events related to data changes and editing operations.

/**
 * Before cell edit event - fired before cell value changes
 */
addEventListener(type: 'beforeedit', listener: (e: CustomEvent<BeforeSaveDataDetails>) => void): void;

/**
 * Before range edit event - fired before range data changes
 */
addEventListener(type: 'beforerangeedit', listener: (e: CustomEvent<BeforeRangeSaveDataDetails>) => void): void;

/**
 * After edit event - fired after data change is complete
 */
addEventListener(type: 'afteredit', listener: (e: CustomEvent<AfterEditEvent>) => void): void;

/**
 * Before autofill operation
 */
addEventListener(type: 'beforeautofill', listener: (e: CustomEvent<ChangedRange>) => void): void;

/**
 * Before range change operation
 */
addEventListener(type: 'beforerange', listener: (e: CustomEvent<ChangedRange>) => void): void;

/**
 * Before cell edit event detail
 */
interface BeforeSaveDataDetails {
  /** New value being set */
  val: any;
  /** Previous value */
  oldVal: any;
  /** Row data object */
  row: DataType;
  /** Column definition */
  col: ColumnRegular;
  /** All grid data */
  models: DataType[];
}

/**
 * Before range edit event detail
 */
interface BeforeRangeSaveDataDetails {
  /** Range being modified */
  range: RangeArea;
  /** Data being set */
  data: any[][];
  /** Models being affected */
  models: DataType[];
}

/**
 * After edit event detail
 */
interface AfterEditEvent {
  /** New value that was set */
  val: any;
  /** Previous value */
  oldVal: any;
  /** Updated row data */
  row: DataType;
  /** Column definition */
  col: ColumnRegular;
  /** Updated grid data */
  models: DataType[];
}

/**
 * Changed range information
 */
interface ChangedRange {
  /** Range that changed */
  range: RangeArea;
  /** Change type */
  type: string;
  /** Source dimension */
  source: DimensionRows;
}

Usage Example:

// Handle cell editing events
grid.addEventListener('beforeedit', (e) => {
  const { val, oldVal, col, row } = e.detail;
  
  // Validate new value
  if (col.prop === 'age' && (val < 0 || val > 120)) {
    e.preventDefault(); // Cancel the edit
    alert('Age must be between 0 and 120');
    return;
  }
  
  console.log(`Changing ${col.prop} from ${oldVal} to ${val}`);
});

grid.addEventListener('afteredit', (e) => {
  const { val, col, row } = e.detail;
  console.log(`Successfully updated ${col.prop} to ${val} in row:`, row);
  
  // Trigger additional actions
  if (col.prop === 'status') {
    // Update related fields or trigger API calls
  }
});

// Handle range operations
grid.addEventListener('beforerangeedit', (e) => {
  const { range, data } = e.detail;
  console.log(`Updating range from (${range.x},${range.y}) to (${range.x1},${range.y1})`);
  console.log('New data:', data);
});

Source Events

Events related to data source management and changes.

/**
 * Before main source is set
 */
addEventListener(type: 'beforesourceset', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

/**
 * Before any source is set (including pinned)
 */
addEventListener(type: 'beforeanysource', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

/**
 * After main source is set
 */
addEventListener(type: 'aftersourceset', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

/**
 * After any source is set (including pinned)
 */
addEventListener(type: 'afteranysource', listener: (e: CustomEvent<SourceSetEvent>) => void): void;

/**
 * Source set event detail
 */
interface SourceSetEvent {
  /** Dimension type being set */
  type: DimensionRows;
  /** Data source being set */
  source: DataType[];
}

Usage Example:

// Monitor data source changes
grid.addEventListener('beforesourceset', (e) => {
  const { type, source } = e.detail;
  console.log(`Setting ${type} data with ${source.length} items`);
  
  // Perform data validation or transformation
  if (source.length > 10000) {
    console.warn('Large dataset detected, performance may be affected');
  }
});

grid.addEventListener('aftersourceset', (e) => {
  const { type, source } = e.detail;
  console.log(`Successfully set ${type} data`);
  
  // Update UI or trigger related operations
  updateDataSummary(source);
});

Column Events

Events related to column operations and changes.

/**
 * Before columns are set
 */
addEventListener(type: 'beforecolumnsset', listener: (e: CustomEvent<ColumnCollection>) => void): void;

/**
 * Before columns are applied to grid
 */
addEventListener(type: 'beforecolumnapplied', listener: (e: CustomEvent<ColumnCollection>) => void): void;

/**
 * After columns are set
 */
addEventListener(type: 'aftercolumnsset', listener: (e: CustomEvent<AfterColumnsSetEvent>) => void): void;

/**
 * After column resize operation
 */
addEventListener(type: 'aftercolumnresize', listener: (e: CustomEvent<ColumnResizeEvent>) => void): void;

/**
 * After columns set event detail
 */
interface AfterColumnsSetEvent {
  /** Updated column definitions */
  columns: ColumnRegular[];
  /** Column order mapping */
  order: Record<string, number>;
}

/**
 * Column resize event detail
 */
interface ColumnResizeEvent {
  /** Map of column index to updated column */
  [index: number]: ColumnRegular;
}

/**
 * Column collection type
 */
interface ColumnCollection {
  /** Column definitions */
  columns: ColumnRegular[];
  /** Column grouping information */
  groups?: ColumnGrouping[];
  /** Column order */
  order: Record<string, number>;
}

Usage Example:

// Handle column configuration changes
grid.addEventListener('beforecolumnsset', (e) => {
  const { columns } = e.detail;
  console.log('Setting columns:', columns.map(c => c.name));
  
  // Validate column configuration
  const duplicateProps = findDuplicateProps(columns);
  if (duplicateProps.length > 0) {
    console.error('Duplicate column properties found:', duplicateProps);
    e.preventDefault();
  }
});

grid.addEventListener('aftercolumnsset', (e) => {
  const { columns, order } = e.detail;
  console.log('Columns set successfully:', columns.length);
  
  // Save column configuration
  saveColumnConfiguration(columns, order);
});

grid.addEventListener('aftercolumnresize', (e) => {
  const resizedColumns = e.detail;
  console.log('Columns resized:', Object.keys(resizedColumns));
  
  // Persist column sizes
  Object.entries(resizedColumns).forEach(([index, column]) => {
    saveColumnSize(column.prop, column.size);
  });
});

Selection Events

Events related to cell focus and selection operations.

/**
 * Before cell focus changes
 */
addEventListener(type: 'beforecellfocus', listener: (e: CustomEvent<BeforeSaveDataDetails>) => void): void;

/**
 * Before focus is lost
 */
addEventListener(type: 'beforefocuslost', listener: (e: CustomEvent<FocusedData | null>) => void): void;

/**
 * After focus render is complete
 */
addEventListener(type: 'afterfocus', listener: (e: CustomEvent<FocusAfterRenderEvent>) => void): void;

/**
 * Focused data information
 */
interface FocusedData {
  /** Focused cell coordinate */
  cell: Cell;
  /** Cell value */
  val: any;
  /** Row dimension type */
  rowType: DimensionRows;
  /** Column dimension type */
  colType: DimensionCols;
}

/**
 * After focus render event detail
 */
interface FocusAfterRenderEvent {
  /** New focus data */
  focus: FocusedData;
  /** Previous focus data */
  prevFocus?: FocusedData;
}

Usage Example:

// Handle focus and selection events
grid.addEventListener('beforecellfocus', (e) => {
  const { row, col } = e.detail;
  console.log(`Focusing cell ${col.prop} in row:`, row);
  
  // Custom focus validation
  if (row.locked) {
    e.preventDefault();
    showMessage('Cannot focus on locked row');
  }
});

grid.addEventListener('afterfocus', (e) => {
  const { focus, prevFocus } = e.detail;
  console.log(`Focus moved from (${prevFocus?.cell.x},${prevFocus?.cell.y}) to (${focus.cell.x},${focus.cell.y})`);
  
  // Update UI elements based on focus
  updatePropertyPanel(focus.val, focus.rowType, focus.colType);
});

Sorting Events

Events related to sorting operations.

/**
 * Before sorting operation
 */
addEventListener(type: 'beforesorting', listener: (e: CustomEvent<BeforeSortingEvent>) => void): void;

/**
 * Before source sorting is applied
 */
addEventListener(type: 'beforesourcesortingapply', listener: (e: CustomEvent<BeforeSourceSortingEvent>) => void): void;

/**
 * Before sorting is applied to column
 */
addEventListener(type: 'beforesortingapply', listener: (e: CustomEvent<BeforeSortingEvent>) => void): void;

/**
 * Before sorting event detail
 */
interface BeforeSortingEvent {
  /** Column being sorted */
  column: ColumnRegular;
  /** Sort order */
  order: Order;
  /** Whether this is additive to existing sort */
  additive: boolean;
}

/**
 * Before source sorting event detail
 */
interface BeforeSourceSortingEvent {
  /** Dimension type being sorted */
  type: DimensionRows;
  /** Sorting configuration */
  sorting: SortingConfig;
}

/**
 * Sorting configuration
 */
interface SortingConfig {
  /** Columns to sort by */
  sortBy?: ColumnProp[];
  /** Enable multi-column sorting */
  multiColumn?: boolean;
}

Usage Example:

// Handle sorting events
grid.addEventListener('beforesorting', (e) => {
  const { column, order, additive } = e.detail;
  console.log(`Sorting column ${column.prop} in ${order} order, additive: ${additive}`);
  
  // Custom sorting validation
  if (column.prop === 'id' && order === 'desc') {
    console.warn('Descending sort on ID may affect performance');
  }
});

grid.addEventListener('beforesortingapply', (e) => {
  const { column, order } = e.detail;
  console.log(`Applying sort to ${column.prop}`);
  
  // Show loading indicator for large datasets
  if (grid.source.length > 5000) {
    showLoadingIndicator('Sorting large dataset...');
  }
});

Filter Events

Events related to filtering operations.

/**
 * Before filter is applied
 */
addEventListener(type: 'beforefilterapply', listener: (e: CustomEvent<BeforeFilterEvent>) => void): void;

/**
 * Before filtered items are trimmed
 */
addEventListener(type: 'beforefiltertrimmed', listener: (e: CustomEvent<BeforeFilterTrimmedEvent>) => void): void;

/**
 * Before items are trimmed/hidden
 */
addEventListener(type: 'beforetrimmed', listener: (e: CustomEvent<BeforeTrimmedEvent>) => void): void;

/**
 * After trimmed operation is complete
 */
addEventListener(type: 'aftertrimmed', listener: (e: CustomEvent<void>) => void): void;

/**
 * Before filter event detail
 */
interface BeforeFilterEvent {
  /** Filter collection being applied */
  collection: FilterCollection;
}

/**
 * Before filter trimmed event detail  
 */
interface BeforeFilterTrimmedEvent {
  /** Filter collection */
  collection: FilterCollection;
  /** Items to be filtered out */
  itemsToFilter: number[];
}

/**
 * Before trimmed event detail
 */
interface BeforeTrimmedEvent {
  /** Trimmed configuration */
  trimmed: Record<number, boolean>;
  /** Type of trimmed operation */
  trimmedType: string;
  /** Dimension type */
  type: DimensionRows;
}

/**
 * Filter collection type
 */
interface FilterCollection {
  [columnProp: string]: FilterData;
}

/**
 * Filter data for individual column
 */
interface FilterData {
  /** Filter type */
  type: string;
  /** Filter criteria */
  criteria: any;
  /** Filter function */
  filter?: (value: any, criteria: any) => boolean;
}

Usage Example:

// Handle filtering events
grid.addEventListener('beforefilterapply', (e) => {
  const { collection } = e.detail;
  const activeFilters = Object.keys(collection);
  console.log('Applying filters to columns:', activeFilters);
  
  // Validate filter criteria
  for (const [column, filterData] of Object.entries(collection)) {
    if (!filterData.criteria) {
      console.warn(`Empty filter criteria for column ${column}`);
    }
  }
});

grid.addEventListener('beforefiltertrimmed', (e) => {
  const { collection, itemsToFilter } = e.detail;
  console.log(`Filtering will hide ${itemsToFilter.length} rows`);
  
  // Show filter summary
  updateFilterSummary(collection, itemsToFilter.length);
});

grid.addEventListener('aftertrimmed', (e) => {
  console.log('Filter operation completed');
  
  // Update UI to reflect filtered state
  updateRowCountDisplay();
  hideLoadingIndicator();
});

UI Events

Events related to user interface interactions.

/**
 * Header click event
 */
addEventListener(type: 'headerclick', listener: (e: CustomEvent<ColumnRegular>) => void): void;

/**
 * Row drag start event
 */
addEventListener(type: 'rowdragstart', listener: (e: CustomEvent<RowDragStartDetails>) => void): void;

/**
 * Row order changed event
 */
addEventListener(type: 'roworderchanged', listener: (e: CustomEvent<RowOrderChangeEvent>) => void): void;

/**
 * Viewport scroll event
 */
addEventListener(type: 'viewportscroll', listener: (e: CustomEvent<ViewPortScrollEvent>) => void): void;

/**
 * Row drag start details
 */
interface RowDragStartDetails {
  /** Row being dragged */
  row: DataType;
  /** Row index */
  index: number;
  /** Dimension type */
  type: DimensionRows;
}

/**
 * Row order change event detail
 */
interface RowOrderChangeEvent {
  /** Source row index */
  from: number;
  /** Target row index */
  to: number;
}

/**
 * Viewport scroll event detail
 */
interface ViewPortScrollEvent {
  /** Scroll position */
  coordinate: {
    x: number;
    y: number;
  };
  /** Dimension type */
  dimension: DimensionRows | DimensionCols;
}

Usage Example:

// Handle UI interaction events
grid.addEventListener('headerclick', (e) => {
  const column = e.detail;
  console.log(`Header clicked for column: ${column.name}`);
  
  // Custom header click behavior
  if (column.prop === 'actions') {
    showColumnMenu(column);
  }
});

grid.addEventListener('rowdragstart', (e) => {
  const { row, index, type } = e.detail;
  console.log(`Starting to drag row ${index} from ${type}`);
  
  // Custom drag validation
  if (row.locked) {
    e.preventDefault();
    showMessage('Cannot drag locked row');
  }
});

grid.addEventListener('roworderchanged', (e) => {
  const { from, to } = e.detail;
  console.log(`Row moved from position ${from} to ${to}`);
  
  // Save new order or trigger API update
  saveRowOrder(from, to);
});

grid.addEventListener('viewportscroll', (e) => {
  const { coordinate, dimension } = e.detail;
  console.log(`Viewport scrolled in ${dimension} to:`, coordinate);
  
  // Update scroll-based UI elements
  updateScrollIndicator(coordinate, dimension);
});

Lifecycle Events

Events related to grid lifecycle and initialization.

/**
 * Before grid render
 */
addEventListener(type: 'beforegridrender', listener: (e: CustomEvent<void>) => void): void;

/**
 * After grid render is complete
 */
addEventListener(type: 'aftergridrender', listener: (e: CustomEvent<void>) => void): void;

/**
 * After grid initialization is complete
 */
addEventListener(type: 'aftergridinit', listener: (e: CustomEvent<void>) => void): void;

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

/**
 * Content size changed
 */
addEventListener(type: 'contentsizechanged', listener: (e: CustomEvent<MultiDimensionType>) => void): void;

/**
 * Multi-dimension type for size events
 */
interface MultiDimensionType {
  [key: string]: number;
}

Usage Example:

// Handle grid lifecycle events
grid.addEventListener('created', (e) => {
  console.log('Grid component created');
  
  // Initialize custom functionality
  initializeCustomFeatures();
});

grid.addEventListener('aftergridinit', (e) => {
  console.log('Grid initialization completed');
  
  // Grid is ready for interaction
  enableUserInteractions();
  loadInitialData();
});

grid.addEventListener('contentsizechanged', (e) => {
  const sizes = e.detail;
  console.log('Content size changed:', sizes);
  
  // Update layout or scroll indicators
  updateLayoutBasedOnSize(sizes);
});

Configuration Events

Events related to configuration changes.

/**
 * Filter configuration changed
 */
addEventListener(type: 'filterconfigchanged', listener: (e: CustomEvent<void>) => void): void;

/**
 * Sorting configuration changed
 */
addEventListener(type: 'sortingconfigchanged', listener: (e: CustomEvent<SortingConfig>) => void): void;

/**
 * Row headers configuration changed
 */
addEventListener(type: 'rowheaderschanged', listener: (e: CustomEvent<void>) => void): void;

/**
 * Additional data changed
 */
addEventListener(type: 'additionaldatachanged', listener: (e: CustomEvent<any>) => void): void;

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

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

/**
 * Data input for export
 */
interface DataInput {
  /** Data to export */
  data: DataType[];
  /** Export options */
  options?: ExportOptions;
}

/**
 * Export options
 */
interface ExportOptions {
  /** Export format */
  format: 'csv' | 'excel' | 'json';
  /** Include headers */
  includeHeaders?: boolean;
  /** File name */
  filename?: string;
}

Usage Example:

// Handle configuration change events
grid.addEventListener('sortingconfigchanged', (e) => {
  const config = e.detail;
  console.log('Sorting configuration changed:', config);
  
  // Save user preferences
  saveUserPreferences({ sorting: config });
});

grid.addEventListener('afterthemechanged', (e) => {
  const newTheme = e.detail;
  console.log(`Theme changed to: ${newTheme}`);
  
  // Update application theme
  updateApplicationTheme(newTheme);
});

grid.addEventListener('beforeexport', (e) => {
  const { data, options } = e.detail;
  console.log(`Exporting ${data.length} rows in ${options?.format} format`);
  
  // Add export metadata
  if (options) {
    options.filename = options.filename || `grid-export-${Date.now()}`;
  }
});