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

plugins.mddocs/

Plugin System

RevoGrid features an extensible plugin architecture that allows you to add custom functionality or extend existing capabilities. The plugin system provides access to all grid providers and enables you to hook into the grid's lifecycle and events.

Capabilities

Base Plugin Class

Foundation class for creating custom plugins with access to grid functionality.

/**
 * Base class for all grid plugins
 */
abstract class BasePlugin {
  /** Grid element reference */
  protected revogrid: HTMLRevoGridElement;
  /** Plugin providers for accessing grid services */
  protected providers: PluginProviders;

  /**
   * Create a new plugin instance
   * @param revogrid - Grid element reference
   * @param providers - Plugin providers
   */
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);

  /**
   * Subscribe to grid events
   * @param eventName - Event name to listen for
   * @param callback - Event callback function
   */
  addEventListener<K extends keyof CustomEventMap>(
    eventName: K, 
    callback: (event: CustomEvent<CustomEventMap[K]>) => void
  ): void;

  /**
   * Watch property changes in grid stores
   * @param prop - Property name to watch
   * @param callback - Change callback function
   * @param config - Watch configuration
   */
  watch<T>(
    prop: string, 
    callback: (newValue: T, oldValue: T) => void, 
    config?: WatchOptions
  ): void;

  /**
   * Remove event listener
   * @param eventName - Event name to remove
   */
  removeEventListener(eventName: string): void;

  /**
   * Emit custom event
   * @param eventName - Event name
   * @param detail - Event detail data
   */
  emit<T>(eventName: string, detail?: T): void;

  /**
   * Clear all subscriptions and watchers
   */
  clearSubscriptions(): void;

  /**
   * Destroy plugin and clean up resources
   */
  destroy(): void;
}

Usage Example:

import { BasePlugin, PluginProviders } from '@revolist/revogrid';

class CustomHighlightPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);
    
    // Listen for cell focus events
    this.addEventListener('afterfocus', this.onCellFocus.bind(this));
    
    // Watch for data changes
    this.watch('source', this.onDataChange.bind(this));
  }

  private onCellFocus(event: CustomEvent) {
    console.log('Cell focused:', event.detail);
    // Add custom highlighting logic
  }

  private onDataChange(newData: any[], oldData: any[]) {
    console.log('Data changed from', oldData.length, 'to', newData.length);
  }
}

// Register plugin
grid.plugins = [CustomHighlightPlugin];

Plugin Providers

Service providers available to plugins for accessing grid functionality.

/**
 * Plugin providers interface - access to all grid services
 */
interface PluginProviders {
  /** Data management provider */
  data: DataProvider;
  /** Column management provider */
  column: ColumnDataProvider;
  /** Dimension calculation provider */
  dimension: DimensionProvider;
  /** Viewport management provider */
  viewport: ViewportProvider;
  /** Selection state provider */
  selection: SelectionStoreConnector;
  /** Plugin service for plugin management */
  plugins: PluginService;
}

/**
 * Data provider interface for plugin access
 */
interface DataProvider {
  setData(source: DataType[], type: DimensionRows, disableVirtual?: boolean): void;
  setCellData(details: SetCellData, refresh?: boolean): void;
  setRangeData(data: RangeUpdateData, type: DimensionRows): void;
  refresh(type?: DimensionRows): void;
  changeOrder(details: RowOrderChangeDetails): void;
  setTrimmed(trimmed: Record<number, boolean>, type: DimensionRows): void;
}

/**
 * Column provider interface for plugin access
 */
interface ColumnDataProvider {
  setColumns(collection: ColumnCollection): void;
  updateColumns(cols: ColumnRegular[]): void;
  getColumns(): ColumnRegular[];
  getColumn(index: number, type: DimensionCols): ColumnRegular | undefined;
  getColumnIndexByProp(prop: ColumnProp, type: DimensionCols): number;
}

Usage Example:

class DataExportPlugin extends BasePlugin {
  exportData() {
    // Access data through provider
    const dataProvider = this.providers.data;
    const columnProvider = this.providers.column;
    
    // Get current data and columns
    const columns = columnProvider.getColumns();
    const sourceStore = this.providers.data.getSourceStore();
    const data = sourceStore.get().source;
    
    // Export logic here
    this.exportToCSV(data, columns);
  }

  private exportToCSV(data: DataType[], columns: ColumnRegular[]) {
    // CSV export implementation
  }
}

Built-in Plugins

Pre-built plugins available for common functionality.

/**
 * Auto-size column plugin for automatic column width adjustment
 */
class AutoSizeColumnPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Filter plugin for column filtering functionality
 */
class FilterPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Sorting plugin for column sorting functionality
 */
class SortingPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Export plugin for data export functionality
 */
class ExportFilePlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Row grouping plugin for hierarchical data display
 */
class GroupingRowPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Column move plugin for drag-and-drop column reordering
 */
class ColumnMovePlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Column stretch plugin for responsive column sizing
 */
class StretchColumn extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Accessibility plugin for WAI-ARIA compliance
 */
class WCAGPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

/**
 * Right-to-left support plugin
 */
class RTLPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders);
}

Usage Example:

import { 
  FilterPlugin, 
  SortingPlugin, 
  AutoSizeColumnPlugin 
} from '@revolist/revogrid';

// Enable built-in plugins
grid.plugins = [
  FilterPlugin,
  SortingPlugin,
  AutoSizeColumnPlugin
];

Plugin Configuration

Configuration options for enabling and customizing plugins.

/**
 * Grid plugin definition - can be class constructor or instance
 */
type GridPlugin = PluginConstructor | PluginInstance;

/**
 * Plugin constructor type
 */
type PluginConstructor = new (
  revogrid: HTMLRevoGridElement, 
  providers: PluginProviders
) => BasePlugin;

/**
 * Plugin instance type
 */
interface PluginInstance extends BasePlugin {
  destroy(): void;
}

/**
 * Watch configuration options
 */
interface WatchOptions {
  /** Execute immediately with current value */
  immediate?: boolean;
  /** Deep watch for object changes */
  deep?: boolean;
}

Usage Example:

// Using constructor
class MyPlugin extends BasePlugin {
  // Plugin implementation
}

// Using instance (for plugins with configuration)
class ConfigurablePlugin extends BasePlugin {
  constructor(
    revogrid: HTMLRevoGridElement, 
    providers: PluginProviders,
    public config: { theme: string; enabled: boolean }
  ) {
    super(revogrid, providers);
  }
}

// Register plugins
grid.plugins = [
  MyPlugin,  // Constructor
  new ConfigurablePlugin(grid, providers, { theme: 'dark', enabled: true })  // Instance
];

Plugin Lifecycle

Managing plugin lifecycle and cleanup.

/**
 * Plugin service for managing plugin lifecycle
 */
interface PluginService {
  /** Register a new plugin */
  register(plugin: GridPlugin): void;
  
  /** Unregister a plugin */
  unregister(plugin: GridPlugin): void;
  
  /** Get all active plugins */
  getPlugins(): PluginBaseComponent[];
  
  /** Destroy all plugins */
  destroyAll(): void;
}

/**
 * Plugin base component interface
 */
interface PluginBaseComponent {
  /** Plugin name/identifier */
  name?: string;
  /** Destroy plugin and clean up */
  destroy(): void;
}

Usage Example:

class LifecyclePlugin extends BasePlugin {
  name = 'lifecycle-plugin';

  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);
    console.log('Plugin initialized');
  }

  destroy() {
    console.log('Plugin destroyed');
    super.destroy();
  }
}

// Register plugin
grid.plugins = [LifecyclePlugin];

// Later, get active plugins
const plugins = await grid.getPlugins();
console.log('Active plugins:', plugins.map(p => p.name));

Custom Event Handling

Advanced event handling and custom event creation in plugins.

/**
 * Custom event map for type-safe event handling
 */
interface CustomEventMap {
  // Data events
  beforeedit: BeforeSaveDataDetails;
  afteredit: AfterEditEvent;
  
  // Selection events
  beforecellfocus: BeforeSaveDataDetails;
  afterfocus: FocusAfterRenderEvent;
  
  // Column events
  beforecolumnsset: ColumnCollection;
  aftercolumnsset: { columns: ColumnRegular[]; order: Record<string, number> };
  
  // Custom plugin events
  [key: string]: any;
}

/**
 * Event detail types
 */
interface BeforeSaveDataDetails {
  val: any;
  oldVal: any;
  row: DataType;
  col: ColumnRegular;
  models: DataType[];
}

interface AfterEditEvent {
  val: any;
  oldVal: any;
  row: DataType;
  col: ColumnRegular;
  models: DataType[];
}

Usage Example:

class EventPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);
    
    // Type-safe event listening
    this.addEventListener('afteredit', this.onAfterEdit);
    this.addEventListener('beforecolumnsset', this.onBeforeColumnsSet);
  }

  private onAfterEdit = (event: CustomEvent<AfterEditEvent>) => {
    const { val, oldVal, row, col } = event.detail;
    console.log(`Cell ${col.prop} changed from ${oldVal} to ${val}`);
    
    // Emit custom event
    this.emit('custom-data-changed', {
      column: col.prop,
      newValue: val,
      row: row
    });
  };

  private onBeforeColumnsSet = (event: CustomEvent<ColumnCollection>) => {
    console.log('Columns will be set:', event.detail);
  };
}

Plugin Communication

Inter-plugin communication and data sharing.

/**
 * Plugin registry for cross-plugin communication
 */
interface PluginRegistry {
  /** Register plugin with name */
  register(name: string, plugin: BasePlugin): void;
  
  /** Get plugin by name */
  get(name: string): BasePlugin | undefined;
  
  /** Check if plugin exists */
  has(name: string): boolean;
  
  /** Send message to plugin */
  sendMessage(targetPlugin: string, message: any): void;
}

Usage Example:

class ProducerPlugin extends BasePlugin {
  name = 'producer';

  shareData() {
    // Share data with other plugins
    this.emit('plugin-data-share', {
      from: this.name,
      data: { status: 'active', count: 100 }
    });
  }
}

class ConsumerPlugin extends BasePlugin {
  name = 'consumer';

  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);
    
    // Listen for shared data
    this.addEventListener('plugin-data-share', this.onDataReceived);
  }

  private onDataReceived = (event: CustomEvent) => {
    const { from, data } = event.detail;
    console.log(`Received data from ${from}:`, data);
  };
}