# Comprehensive Guide to Using RevoGrid Plugins
URL: https://pro.rv-grid.com/guides/plugin/
Source: src/content/docs/guides/plugin.mdx
RevoGrid is a highly flexible and extensible grid component that supports a powerful plugin system. This guide will walk you through everything you need to know about using RevoGrid plugins, from understanding the basics to creating and integrating your custom plugins.

#### 1. **Understanding RevoGrid Plugins**

RevoGrid plugins are modular pieces of code that extend the functionality of the RevoGrid component. These plugins can:
- Add new features.
- Modify existing behavior.
- Integrate with other libraries or frameworks.

All RevoGrid plugins extend from the `BasePlugin` class, which provides a minimal core and utility methods for interacting with the RevoGrid component.

#### 2. **Setting Up Your Development Environment**

Before you can start working with RevoGrid plugins, ensure you have a development environment set up with the following:
- **Node.js** and **npm** (Node Package Manager) installed.
- A code editor (such as **Visual Studio Code**).
- A basic understanding of TypeScript, as RevoGrid and its plugins are TypeScript-based.

To get started, you need to install RevoGrid in your project:

```bash
npm install @revolist/revogrid
```

#### 3. **Creating a Simple Plugin**

Let's start by creating a simple plugin that add class to odd rows.

1. **Create a New Plugin Class**: Your plugin should extend the `BasePlugin` class provided by RevoGrid.

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

export class RowOddPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);

    this.addEventListener(
      'beforerowrender',
      ({
        detail,
      }: CustomEvent<HTMLRevogrDataElementEventMap['beforerowrender']>) => {
        detail.node.$attrs$ = {
          ...detail.node.$attrs$,
          odd: detail.item.itemIndex % 2 !== 0,
        };
      }
    );
  }
}
```

2. **Integrate the Plugin**: Once your plugin is created, integrate it with your RevoGrid instance.

```typescript
const gridElement = document.querySelector('revo-grid');
gridElement.plugins.push(new RowOddPlugin(gridElement, providers));
```

#### 4. **Exploring Core Plugin Methods**

When creating more complex plugins, you'll likely use several core methods provided by the `BasePlugin` class:

- **`addEventListener(eventName: string, callback: (e: CustomEvent) => void): void`**: Subscribes to a RevoGrid event.

  Example:
  ```typescript
  this.addEventListener('beforecellrender', this.handleCellRender);
  ```

- **`watch(prop: string, callback: (arg: T) => boolean | void, config?: Partial): void`**: Watches a property on the RevoGrid component for changes.

  Example:
  ```typescript
  this.watch('rowSelection', (newValue) => {
    console.log('Row selection changed:', newValue);
  });
  ```

- **`emit(eventName: string, detail?: any): CustomEvent`**: Emits a custom event from the RevoGrid component.

  Example:
  ```typescript
  this.emit('customEvent', { data: 'someData' });
  ```

- **`clearSubscriptions(): void`**: Clears all event listeners subscribed by the plugin.

- **`destroy(): void`**: Cleans up the plugin by removing all subscriptions and performing any necessary teardown.

#### 5. **Advanced Plugin Development**

RevoGrid provides a set of providers that you can use to interact with its internal state. These providers include:

- **Data Provider**: Manipulate the grid's data.
- **Dimension Provider**: Manage row and column dimensions.
- **Selection Provider**: Handle cell and row selections.
- **Column Provider**: Manage column data and properties.
- **Viewport Provider**: Handle scrolling and viewport rendering.

Here's how you might use these providers in a more advanced plugin:

```typescript
class HighlightSelectionPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);

    this.addEventListener('afterselectionchange', this.highlightSelectedCells);
  }

  private highlightSelectedCells = () => {
    const selectedCells = this.providers.selection.getSelectedCells();
    selectedCells.forEach(cell => {
      const model = this.providers.data.getModel(cell.rowIndex, cell.type);
      model.cellProperties = {
        style: {
          backgroundColor: 'yellow'
        }
      };
    });
  };
}
```

#### 6. **Styling with Plugins**

Plugins can also be used to dynamically style the grid. For example, using a plugin to flash cells after they are edited:

```typescript
import './cell-flash.style.css';

class CellFlashPlugin extends BasePlugin {
  constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders) {
    super(revogrid, providers);
    this.addEventListener('onEdit', this.handleEdit);
  }

  private handleEdit = (e: CustomEvent) => {
    const { rowIndex, prop } = e.detail;
    const cell = this.revogrid.getCell(rowIndex, prop);
    cell.classList.add('flash');
    setTimeout(() => cell.classList.remove('flash'), 1000);
  };
}

// cell-flash.style.css
.flash {
  animation: flash 1s ease;
}

@keyframes flash {
  from { background-color: yellow; }
  to { background-color: transparent; }
}
```

#### 7. **Best Practices for Plugin Development**

- **Keep Plugins Modular**: Each plugin should have a single responsibility and be as modular as possible.
- **Manage Subscriptions**: Always clear subscriptions when they are no longer needed to avoid memory leaks.
- **Utilize Providers Wisely**: Only use the necessary providers to keep your plugin efficient.
- **Ensure Compatibility**: Test your plugins thoroughly to ensure they work well with other plugins and configurations.

#### 8. **Deploying and Sharing Plugins**

Once you've created a plugin, you can package it as an npm module and share it with the community. Here's a basic setup for packaging your plugin:

1. **Create a `package.json` file**:

```json
{
  "name": "revogrid-cell-logger",
  "version": "1.0.0",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc"
  },
  "dependencies": {
    "@revolist/revogrid": "^4.0.0"
  }
}
```

2. **Build your plugin**:

```bash
npm run build
```

3. **Publish to npm**:

```bash
npm publish
```

#### 9. **Conclusion**

RevoGrid's plugin system is a powerful way to extend its functionality and adapt it to your needs. Whether you're creating simple event listeners or complex data manipulation tools, the flexibility provided by the `BasePlugin` class and the various providers make it easy to build, deploy, and share custom plugins.
By following this guide, you should now be equipped to start creating your own plugins, enhancing the capabilities of RevoGrid, and contributing to a richer ecosystem for all users.
