React Components to Gutenberg Blocks
The @faustwp/block-editor-utils package provides helper functions for converting existing React components into Gutenberg blocks. This is very useful for when you already have some components and you want to test them in Gutenberg without needing to write any code to port them. You will also be able to re-use the same React component in both places; the Headless side and the Editor side.
Make sure you have completed the initial setup for Faust at Getting Started and the Get started with Gutenberg Blocks Provider and Viewer.
Quick Start
The @faust/cli
package includes a helpful command to detect, compile and upload your custom blocks into WordPress all within the Headless project!
In this guide we provide the steps required to create a new block using this workflow. We are creating a new block named my-first-block
.
First, from your root folder, install the required dependencies:
$ npm install @wordpress/scripts @faustwp/block-editor-utils --save-dev
You should see the following file and folder structure now:
❯ tree -L 2 .
.
├── README.md
├── faust.config.js
├── globalStylesheet.css
├── next.config.js
├── package.json
├── pages
│ ├── [...wordpressNode].js
│ ├── _app.js
│ ├── api
│ ├── index.js
│ └── preview.js
├── possibleTypes.json
├── styles
│ └── blocks.scss
├── wp-blocks
│ └── index.js
└── wp-templates
├── front-page.js
└── index.js
Code language: CSS (css)
Now we’re ready to explore the process of using this package’s helpers to convert a React component to blocks.
Porting A Simple Component
For the purposes of this tutorial we are using the a simple React component. Add a folder called my-first-block
to the wp-blocks
folder, then add the following into a jsx file called MyFirstBlock.jsx
:
// MyFirstBlock.jsx
function MyFirstBlock({ style, className, attributes, children, ...props }) {
const styles = {
...style,
};
const cssClassName = 'create-block-my-first-block';
return (
<div
style={styles}
className={cssClassName}
dangerouslySetInnerHTML={{ __html: attributes.message }}
/>
);
}
export default MyFirstBlock
Code language: JavaScript (javascript)
This pure React component consists of div
element with three attributes that controls the content and the style of the box. Let’s describe them briefly:
- message: is a text message that gets displayed.
- bg_color: controls the background color.
- text_color: controls the text color.
We would like to use this React component in WordPress using the Block editor. Traditionally, this step would require us (the developers) to register a block within WordPress, provide a block.json
and write code for the Edit and Save functions for the editor. Once those steps are done, then the block would be usable in the block editor list.
That is a lot of know-how and development effort for simply trying to use the React component in the editor side. What if we just provided the React component and let the framework handle all the block registration and creating the editor form fields for changing the content?
This is what @faustwp/block-editor-utils
package tries to do. It provides a registerFaustBlock
helper function, that handles all the necessary configuration, registration and generation of Editor Form fields and Inspector controls for you. From the perspective of the Headless Developer, they provide the React component and are able to review this within the WordPress block editor and re-use it in both places.
Within your
folder replace the wp-blocks/my-first-block
index.js
contents with the following code:
// index.js
import './style.scss';
// import block.json
import metadata from './block.json';
// import our React component
import MyFirstBlock from './MyFirstBlock';
import { registerFaustBlock } from '@faustwp/block-editor-utils';
// Register the React component in Gutenberg
registerFaustBlock(MyFirstBlock, {blockJson: metadata})
Code language: JavaScript (javascript)
The registerFaustBlock
helper takes the following arguments:
- component: the actual React component to convert into a Gutenberg block. (Required).
- metadata: a metadata object that contains several fields:
- blockJson: the
block.json
object that describes the component attributes. (Required). - edit: provides a custom Edit function that describes the structure of your block in the context of the editor. (Optional).
- save: provides a custom Save function that defines the way in which the different attributes should be combined into the final markup. (Optional).
- blockJson: the
Now let’s take a look at the block.json
. Since we declared three configurable attributes for our component, we need to declare them as attributes here.
Here is the final block.json
with the assigned attributes object:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/my-first-block",
"version": "0.1.0",
"title": "My First Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"supports": {
"html": false
},
"attributes": {
"message": {
"type": "string",
"default": "My First Block"
},
"bg_color": { "type": "string", "default": "#000000" },
"text_color": { "type": "string", "default": "#ffffff" }
},
"textdomain": "my-first-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
Code language: JSON / JSON with Comments (json)
Syncing the block with WordPress
Add the following command in your package.json
scripts and run it afterwards:
"scripts": {
...
"blockset": "faust blockset"
},
Code language: JavaScript (javascript)
$ npm run blockset
If everything goes OK the cli tool will compile the blocks within the wp-blocks
folder and upload them to your WordPress site in a special location that Faust uses to detect and register the blocks.
Trying out the Component in the Block Editor
We can now try to use the component straight in the editor side. This is what it will look like at first glance in Edit mode:
You can interact with the form fields, and then click outside the block contents where you will see the component rendered in Preview mode.
Configuring the Form Controls
So far we’ve been able to render the React component in the Block Editor, change some of the attributes, and reflect the changes in the page.
However, a few of the attributes that control the color are using text field controls, which may prove problematic since they allow invalid values. What if we wanted to use a proper color picker component?
Since the block.json
attribute types do not allow color
as a value, we will have to provide a different configuration to allow that option.
When registering the React component using registerFaustBlock
, it allows extra configuration to be used in case you want to declare which kinds of controls to use on each attribute.
Add the following config object as a property to the MyFirstBlock
function:
// MyFirstBlock.jsx
...
MyFirstBlock.config = {
name: "MyFirstBlock",
editorFields: {
bg_color: {
location: "inspector",
control: "color",
},
text_color: {
location: "inspector",
control: "color",
},
},
};
Code language: JavaScript (javascript)
Here we included an object with the following properties:
name
: the name of the block.editorFields
: the list of Editor metadata configuration. This consists of two attributes that we want to specify: the type of control to use and the location within the editor. For example, by usinglocation: "inspector",
we are telling this control to appear in the Block Sidebar section. By usingcontrol: "color"
, we are indicating that we want to use a ColorPicker component instead of the regularTextControl
.
Once you update the component, you can refresh the page and create a new block. Now instead of having two text fields inside the block, we have two ColorPicker
fields in the sidebar section:
Form Control Reference List
So far we’ve seen examples of two controls: The ColorPicker
handled by the control: "color"
and the TextControl
, which is set as default for every type: "string"
in the block.json
attributes list.
The corresponding table represents the mapping logic between the block.json
attributes and their associated fields:
type | field | comment |
---|---|---|
string | TextControl | Renders a TextControl field of type text |
boolean | RadioControl | Renders a RadioControl field |
integer | TextControl | Renders a TextControl field of type number |
number | TextControl | Renders a TextControl field of type number |
object | TextAreaControl | Renders a TextAreaControl field |
block.json
attributes types to Editor ControlsThe following control types will also be available when using the editorFields
metadata when specifying a control
property:
control | field | comment |
---|---|---|
color | ColorPicker | Renders a ColorPicker field |
text | TextControl | Renders a TextControl field of type text |
textarea | TextAreaControl | Renders a TextAreaControl field |
radio | RadioControl | Renders a RadioControl field |
select | SelectControl | Renders a SelectControl field |
range | RangeControl | Renders a RangeControl field |
number | TextControl | Renders a TextControl field of type number |
checkbox | CheckBoxControl | Renders a CheckBoxControl field |
NOTE:
The editorFields
configuration provides necessary hints for the helper to render the specified controls. It always overrides any configuration that is declared in the block.json
attributes section. If you are not seeing the appropriate control used, check that your editorFields
contain the correct attribute name and the correct control
property.
Reference
The following RFC document explains in detail the different options and configurations regarding the usage of the @faustwp/block-editor-utils
.