Skip to main content

Overview

AG Grid provides a powerful component framework that allows you to customize almost every visual aspect of the grid. You can create custom components for:
  • Cell Renderers - Control how cell values are displayed
  • Cell Editors - Create custom editing interfaces
  • Filters - Build advanced filtering logic
  • Headers - Customize column header appearance and behavior
  • Loading Overlays - Custom loading states
  • Tool Panels - Add custom side panels
All custom components share common lifecycle methods and can be implemented as vanilla JavaScript classes, React components, Angular components, or Vue components.

Component Lifecycle

Every custom component follows a consistent lifecycle:
1

Initialization

The grid creates your component instance and calls the init() method with component-specific parameters.
init(params: IComponentParams): void {
  // Initialize your component
  // Store params for later use
  this.params = params;
}
2

GUI Attachment

After the component is rendered, afterGuiAttached() is called. This is where you should focus elements or perform DOM operations.
afterGuiAttached?(): void {
  // Focus input elements
  // Start animations
  // Measure DOM elements
}
3

Refresh (Optional)

When data changes, the grid calls refresh() to give your component a chance to update without recreating it.
refresh(params: IComponentParams): boolean {
  // Return true if refresh was successful
  // Return false to destroy and recreate
  return true;
}
4

Cleanup

When the component is destroyed, destroy() is called to clean up resources.
destroy?(): void {
  // Remove event listeners
  // Clear timers
  // Release resources
}

Component Types

Cell Renderers

Customize how cell values are displayed without entering edit mode.

Cell Renderers

Learn how to create custom cell renderers for displaying data

Cell Editors

Provide custom editing interfaces when users enter edit mode.

Cell Editors

Build custom cell editors for data input and validation

Filters

Create sophisticated filtering logic beyond the built-in filters.

Filters

Implement custom filter components with advanced logic

Framework-Specific Implementation

AG Grid supports custom components across all major frameworks:
Implement components as ES6 classes:
class CustomComponent {
  init(params) {
    this.params = params;
    this.eGui = document.createElement('div');
    this.eGui.innerHTML = '<span>Custom Content</span>';
  }

  getGui() {
    return this.eGui;
  }

  destroy() {
    // Cleanup
  }
}
Register the component:
const gridOptions = {
  components: {
    customComponent: CustomComponent
  }
};

Common Interfaces

All custom components extend from the base IComponent interface:
interface IComponent<TParams> {
  /** Return the DOM element for your component */
  getGui?(): HTMLElement;
  
  /** Called after the GUI is attached to the DOM */
  afterGuiAttached?(params?: IAfterGuiAttachedParams): void;
  
  /** Called when the component is destroyed */
  destroy?(): void;
}

AgGridCommon Interface

Most component params extend AgGridCommon, which provides access to grid APIs:
interface AgGridCommon<TData, TContext> {
  /** Grid API for programmatic control */
  api: GridApi<TData>;
  
  /** Column API for column operations */
  columnApi: ColumnApi;
  
  /** Custom context object */
  context: TContext;
}

Best Practices

  • Implement refresh() to update components efficiently instead of recreating them
  • Cache DOM elements to avoid repeated queries
  • Debounce expensive operations like API calls
  • Use event delegation for better performance with many cells
  • Always implement destroy() to clean up event listeners
  • Remove timers and intervals in the destroy method
  • Unsubscribe from observables and streams
  • Clear references to DOM elements
  • Add proper ARIA attributes to interactive elements
  • Ensure keyboard navigation works correctly
  • Provide screen reader-friendly labels
  • Test with assistive technologies
  • Use TypeScript generics for type-safe components
  • Define custom parameter interfaces that extend base params
  • Leverage IDE autocomplete with proper typing
  • Avoid any types when possible

Example: Custom Component with All Lifecycle Methods

class FullLifecycleComponent {
  private eGui: HTMLElement;
  private params: ICellRendererParams;
  private eventListener: () => void;

  init(params: ICellRendererParams) {
    this.params = params;
    
    // Create GUI
    this.eGui = document.createElement('div');
    this.eGui.innerHTML = `<span>${params.value}</span>`;
    
    // Add event listener
    this.eventListener = () => {
      console.log('Clicked:', params.value);
    };
    this.eGui.addEventListener('click', this.eventListener);
  }

  getGui() {
    return this.eGui;
  }

  refresh(params: ICellRendererParams): boolean {
    this.params = params;
    this.eGui.querySelector('span').textContent = params.value;
    return true;
  }

  afterGuiAttached() {
    // Focus or measure if needed
    console.log('Component attached to DOM');
  }

  destroy() {
    // Clean up
    if (this.eventListener) {
      this.eGui.removeEventListener('click', this.eventListener);
    }
  }
}

Next Steps

Cell Renderers

Create custom cell renderers

Cell Editors

Build custom editors

Filters

Implement custom filters