diff --git a/docs/plugins/advanced-plugins.md b/docs/plugins/advanced-plugins.md index 96483f25..fe960e6b 100644 --- a/docs/plugins/advanced-plugins.md +++ b/docs/plugins/advanced-plugins.md @@ -4,46 +4,34 @@ title: Advanced Plugins 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. +Now that we know how to write a basic Grid.js 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`). +Grid.js has an internal pipeline which takes care of processing, filter and refining the raw data. You can get access to the current pipeline by using `config.pipeline` (via the `useConfig` hook) or you can use the `useSelector` hook to subscribe to a specific part of +Grid.js state. 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. +```js +import { useSelector } from "gridjs"; +``` + state.data); - 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)); - } + useEffect(() => { + if (!data) return; + + setTotal(data.toArray().reduce((prev, row) => prev + row[1], 0)); + }, [data]); - render() { - return h('b', {}, \`Total: $\${this.state.total.toLocaleString()}\`); - } + return h('b', {}, \`Total: $\${total.toLocaleString()}\`); } - const grid = new Grid({ search: true, sort: true, @@ -67,15 +55,18 @@ grid.plugin.add({ ## Using the translation -Likewise, you can get access to the Translator object and localize strings in your custom plugin. `_` is a method of `BaseComponent` -and since you've extended `BaseComponent`, you will have access to `this._` throughout your custom plugin: +Likewise, you can get access to the Translator function using the `useTranslator` hook to localize strings in your Grid.js plugin: + +```js +import { useTranslator } from "gridjs"; +``` + +## Hooks + +Grid.js provides the following hooks. You can use them to build and customize the behavior of your plugin: + + - `useConfig`: Retrieve the current Grid.js config object + - `useSelector`: Subscribe to a specific part of the Grid.js state (e.g. `useSelector(state => state.data)`) + - `useTranslator`: Get the Grid.js Translator function + - `useStore`: Retrieve the Grid.js internal Store object diff --git a/docs/plugins/basics.md b/docs/plugins/basics.md index 3cfb464c..40a9cee7 100644 --- a/docs/plugins/basics.md +++ b/docs/plugins/basics.md @@ -8,18 +8,18 @@ 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. +A Grid.js plugin is a [Preact Functional Component](https://preactjs.com/guide/v10/components/#functional-components) 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. +take care of rendering your plugin. A [Plugin](https://github.com/grid-js/gridjs/blob/master/src/plugin.ts) has following properties: ```ts -interface Plugin { +interface Plugin { id: string; position: PluginPosition; - component: VNode; + component: T; order?: number; } ``` @@ -53,11 +53,12 @@ grid.plugin.add({ }); ``` -Note that `position` and `id` are mandatory fields and `component` is the actual plugin class or function that we want to render. +Note that `position` and `id` are mandatory fields and `component` is the actual plugin 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. ## Adding a Plugin using React Wrapper -Just use ```plugins``` property to add all plugin that you want. +Just use the ```plugins``` property to add all plugin that you want. + ```js ``` - ## Ordering of plugins You can pass an optional `order` property to `plugin.add()` to define the ordering of your components: diff --git a/docs/plugins/writing-plugin.md b/docs/plugins/writing-plugin.md index 4410c44f..07830882 100644 --- a/docs/plugins/writing-plugin.md +++ b/docs/plugins/writing-plugin.md @@ -4,65 +4,34 @@ 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`: +Grid.js Plugins are Preact Functional Components. Simply create a new functional component to render a plugin: ```js -import { BaseComponent, BaseProps, h } from "gridjs"; +import { h } from "gridjs"; ``` -Then, create a new class and extend `BaseComponent`: - ```js -class MyPlugin extends BaseComponent { - render() { - return h('h1', {}, 'Hello World!'); - } +function MyPlugin () { + return h('h1', {}, 'Hello World!'); } ``` - - -## Using a function - -You can also write a simple function that returns a VNode and renders the component: +:::tip +You don't have to use the `h` function to render elements if your bundler is set up to understand Preact JSX renderer: ```js -import { h } from "gridjs"; +function MyPlugin () { + return

Hello World!

; +} ``` +See this guide for more details https://preactjs.com/guide/v10/getting-started#setting-up-jsx +::: + - diff --git a/lib/liveExample.js b/lib/liveExample.js index e9b6985b..4ed35c5d 100644 --- a/lib/liveExample.js +++ b/lib/liveExample.js @@ -1,7 +1,7 @@ -import { Grid, html, h, createRef as gCreateRef, Component as gComponent, PluginPosition, BaseComponent } from "gridjs"; +import { Grid, html, h, createRef as gCreateRef, Component as gComponent, PluginPosition, BaseComponent, useConfig, useTranslator, useSelector, useState, useEffect } from "gridjs"; import { esES, frFR } from "gridjs/l10n"; import CodeBlock from "@theme/CodeBlock"; -import React, {Component, useEffect, useRef} from "react"; +import React, {Component, useRef, useEffect as reactUseEffect} from "react"; import * as faker from 'faker'; export class LiveExample extends Component { @@ -16,7 +16,7 @@ function () { const wrapperRef = useRef(null); - useEffect(() => { + reactUseEffect(() => { if (typeof (grid) == 'object' && wrapperRef && wrapperRef.current && wrapperRef.current.childNodes.length === 0) { grid.render(wrapperRef.current); } @@ -26,7 +26,27 @@ function () {
); } -` } live={true} scope={{ Grid, html, h, gCreateRef, gComponent, PluginPosition, BaseComponent, CodeBlock, useEffect, useRef, faker, esES, frFR, ...this.props.scope }} /> +` } live={true} scope={{ + Grid, + html, + h, + reactUseEffect, + gCreateRef, + gComponent, + PluginPosition, + BaseComponent, + CodeBlock, + useEffect, + useRef, + faker, + esES, + frFR, + useState, + useConfig, + useSelector, + useTranslator, + ...this.props.scope + }} /> ) } } diff --git a/package-lock.json b/package-lock.json index ff40306e..9c8a3cb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "chartist": "^0.11.4", "classnames": "^2.3.1", "faker": "^5.5.3", - "gridjs": "^6.0.5", + "gridjs": "^6.0.6", "gridjs-react": "^6.0.1", "postcss-scss": "^3.0.5", "react": "^17.0.2", @@ -7040,9 +7040,9 @@ } }, "node_modules/gridjs": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/gridjs/-/gridjs-6.0.5.tgz", - "integrity": "sha512-dpGi1eK27tnplumOOrYOIQEJJaPZcx6kzexQTqtNN0CBKEVJBpFvbCJgk7xZyRMF42RoCT6BYRcQjzXCpQXbvQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/gridjs/-/gridjs-6.0.6.tgz", + "integrity": "sha512-TZ20nY+weE/wlyXOd3A9FJyJlsJ/MrHr6frMgUHFN29RmWZCYtnyfF0zuspXC81oePwSJeSZ8HY651aeyX8+rQ==", "dependencies": { "preact": "^10.11.3" } diff --git a/package.json b/package.json index a77b816d..8cf75d43 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "chartist": "^0.11.4", "classnames": "^2.3.1", "faker": "^5.5.3", - "gridjs": "^6.0.5", + "gridjs": "^6.0.6", "gridjs-react": "^6.0.1", "postcss-scss": "^3.0.5", "react": "^17.0.2",