Skip to content

Commit

Permalink
feat: adding plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
afshinm committed Jul 18, 2020
1 parent cf4aed0 commit 47217ad
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 2 deletions.
99 changes: 99 additions & 0 deletions docs/plugin/advanced-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
id: advanced-plugins
title: Advanced Plugin
---

import { LiveExample } from "../../lib/liveExample.js";

Now that we know how to write a basic plugin, let's take a look at some complex examples.

## Using the pipeline

Grid.js has an internal pipeline which is the brain of Grid.js and takes care of processing, filter and refining the data.
You can always get access to the current pipeline by using `this.config.pipeline` in your plugin component (make sure you have extended `BaseComponent`).

In this example, we have a table of Name (string) and Salary (double) and our custom plugin is in charge of summing salaries
and displaying the total in the footer.

<LiveExample children={
`
class TotalSalaryPlugin extends BaseComponent {
constructor(...props) {
super(...props);

this.state = {
total: 0
};
}

setTotal() {
this.config.pipeline.process().then(data => {
this.setState({
total: data.toArray().reduce((prev, row) => prev + row[1], 0)
});
});
}

componentDidMount() {
// initial setState
this.setTotal();
this.config.pipeline.on('updated', this.setTotal.bind(this));
}

render() {
return h('b', {}, \`Total: $\${this.state.total.toLocaleString()}\`);
}
}

const grid = new Grid({
search: true,
sort: true,
columns: ['Name', 'Salary'],
data: [
['John', Math.round(Math.random() * 100000)],
['Mark', Math.round(Math.random() * 100000)],
['Josh', Math.round(Math.random() * 100000)],
['Sara', Math.round(Math.random() * 100000)],
['Maria', Math.round(Math.random() * 100000)],
]
});

grid.plugin.add({
id: 'salaryplugin',
component: h(TotalSalaryPlugin, {}),
position: PluginPosition.Footer,
});
`
} />

## Using the translation

Likewise, you can get access to the Translator object and localize strings in your custom plugin:

<LiveExample children={
`
class HelloPlugin extends BaseComponent {
render() {
return h('b', {}, this._('hello'));
}
}

const grid = new Grid({
columns: ['Name', 'Salary'],
data: [
['John', Math.round(Math.random() * 100000)],
['Mark', Math.round(Math.random() * 100000)],
['Josh', Math.round(Math.random() * 100000)],
],
language: {
'hello': 'bonjour!!'
}
});

grid.plugin.add({
id: 'bonjour',
component: h(HelloPlugin, {}),
position: PluginPosition.Header,
});
`
} />
83 changes: 83 additions & 0 deletions docs/plugin/basics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
id: basics
title: Plugin basics
---

Grid.js is a modular JavaScript framework which allows you to add custom plugins to it or remove the existing ones.
In this article, we talk about what is a Grid.js plugin and how to develop one.

## Introduction

Grid.js uses [Preact](https://preactjs.com/) under the hood to render the table and other components like search, pagination, etc.
A Grid.js plugin is a `class` or a `function` that render a Virtual Node. This interface is very similar to a React component.

Once you have a component that can render an element, then you can add it to the list of Grid.js plugin and Grid.js will
take care of rendering and calling your plugin.

A [Plugin](https://github.com/grid-js/gridjs/blob/master/src/plugin.ts) has following properties:

```ts
interface Plugin {
id: string;
position: PluginPosition;
component: VNode<any>;
order?: number;
}
```

Where `id` is a unique string, `position` defines where that plugin should be rendered and there is an optional `order`
property to change the ordering of plugins in a specific plugin position (e.g. header).

## Plugin Position

Grid.js can render a plugin in different positions. Simply import `PluginPosition` enum from `gridjs` package and use it
when you are calling the `plugin.add(...)` function:

```js
import { PluginPosition } from "gridjs";
```

:::tip
If you need to render your plugin in a position that doesn't already exist, please open a GitHub issue and we will add
a new PluginPosition!
:::

## Adding a Plugin

Adding a plugin to a Grid.js instance is as easy as calling `gridjs_instance.plugin.add(...)`, for instance:

```js
grid.plugin.add({
id: 'myplugin',
component: h(MyPlugin, {}),
position: PluginPosition.Header,
});
```

Note that `position` and `id` are mandatory fields and `component` is the actual plugin class or function that we want to render.
You can render the same plugin multiple times by calling the `plugin.add()` function and passing an unqiue ID.

## Ordering of plugins

You can pass an optional `order` property to `plugin.add()` to define the ordering of your components:

```js
grid.plugin.add({
id: 'myfirstplugin',
component: h(MyPlugin, {}),
position: PluginPosition.Header,
order: 1,
});

grid.plugin.add({
id: 'mysecondplugin',
component: h(MyPlugin, {}),
position: PluginPosition.Header,
order: 2,
});
```

In above example, `myfirstplugin` renders first and then `mysecondplugin` will be rendered.


Now, let's take a look at writing a simple plugin.
84 changes: 84 additions & 0 deletions docs/plugin/writing-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
id: writing-plugin
title: Writing a Plugin
---

import { LiveExample } from "../../lib/liveExample.js";

In this section, we will explore different ways to write a Grid.js plugin.

## Using a class

Grid.js has a `BaseComponent` class which is used everywhere to ensure that all components are receiving the same set of
internal properties and functions. Simply extend this class and add your own functionality to develop a new plugin.

First of all, import both `BaseComponent` and `BaseProps` from `gridjs`:

```js
import { BaseComponent, BaseProps, h } from "gridjs";
```

Then, create a new class and extend `BaseComponent`:

```js
class MyPlugin extends BaseComponent {
render() {
return h('h1', {}, 'Hello World!');
}
}
```

<LiveExample children={
`
class MyPlugin extends BaseComponent {
render() {
return h('h1', {}, 'Hello World!');
}
}

const grid = new Grid({
columns: ['Name', 'Email', 'Phone Number'],
data: [
['John', '[email protected]', '(353) 01 222 3333'],
['Mark', '[email protected]', '(01) 22 888 4444'],
]
});

grid.plugin.add({
id: 'myplugin',
component: h(MyPlugin, {}),
position: PluginPosition.Header,
});
`
} />

## Using a function

You can also write a simple function that returns a VNode and renders the component:

```js
import { h } from "gridjs";
```

<LiveExample children={
`
function MyPlugin() {
return h('h1', {}, 'Hello world!');
}

const grid = new Grid({
columns: ['Name', 'Email', 'Phone Number'],
data: [
['John', '[email protected]', '(353) 01 222 3333'],
['Mark', '[email protected]', '(01) 22 888 4444'],
]
});

grid.plugin.add({
id: 'myplugin',
component: h(MyPlugin, {}),
position: PluginPosition.Header,
});
`
} />

4 changes: 2 additions & 2 deletions lib/liveExample.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Grid, html, h, createRef as gCreateRef, Component as gComponent } from "gridjs";
import { Grid, html, h, createRef as gCreateRef, Component as gComponent, PluginPosition, BaseComponent, BaseProps } from "gridjs";
import CodeBlock from "@theme/CodeBlock";
import React, {Component, useEffect, useRef} from "react";
import * as faker from 'faker';
Expand All @@ -25,7 +25,7 @@ function () {
<div ref={wrapperRef} />
);
}
` } live={true} scope={{ Grid, html, h, gCreateRef, gComponent, CodeBlock, useEffect, useRef, faker, ...this.props.scope }} />
` } live={true} scope={{ Grid, html, h, gCreateRef, gComponent, PluginPosition, BaseComponent, BaseProps, CodeBlock, useEffect, useRef, faker, ...this.props.scope }} />
)
}
}
5 changes: 5 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ module.exports = {
'config/sort',
'config/pagination',
],
"🧩 Plugin": [
'plugin/basics',
'plugin/writing-plugin',
'plugin/advanced-plugins',
],
"🔌 Integrations": [
'integrations/react',
'integrations/vue',
Expand Down

0 comments on commit 47217ad

Please sign in to comment.