-
Notifications
You must be signed in to change notification settings - Fork 0
Home
When working on https://github.com/woocommerce/woocommerce-free-shipping-progress-bar-block/pull/14, I needed to add color settings to the custom block. Initially, I implemented the PR in a way, that I would add the hex code of the color to the corresponding block. Nadir pointed out that colors should be implemented based on class names, to remain compatible to theme changes. After checking color setting the implementation of Gutenberg and WooCommerce Blocks and reading various tutorials, I was able to implement the color settings as expected. The following steps demonstrate how to add color settings to a custom block.
In this tutorial, I’m going to create a block that simply prints Hello World. Both the font color and the background colour of the block can be adjusted. On a high-level, these are the steps required to add color settings to the custom block:
- Bootstrap custom block
- Add attributes to block.json
- Add attributes to src/block.js
- Add color settings to src/edit.js
First, we’re going to bootstrap a custom block with the following commands:
$ npx @wordpress/create-block gutenberg-color-settings
$ cd gutenberg-color-settings
$ npm start
If we look up block.json, we see the following code:
{
"apiVersion": 2,
"name": "create-block/gutenberg-color-settings",
"version": "0.1.0",
"title": "Gutenberg Color Settings",
"category": "widgets",
"icon": "smiley",
"description": "Example block written with ESNext standard and JSX support – build step required.",
"supports": {
"html": false
},
"textdomain": "gutenberg-color-settings",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}Let’s add the attributes we need for the color settings. Our block.json now looks like this:
{
"apiVersion": 2,
"name": "create-block/gutenberg-color-settings",
"version": "0.1.0",
"title": "Gutenberg Color Settings",
"category": "widgets",
"icon": "smiley",
"description": "Example block written with ESNext standard and JSX support – build step required.",
"supports": {
"html": false
},
"attributes": {
"textColor": {
"type": "string"
},
"backgroundColor": {
"type": "string"
}
},
"textdomain": "gutenberg-color-settings",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}Running npx @wordpress/create-block gutenberg-color-settings sets up a fresh Gutenberg block with the following files in the src folder:
edit.js
editor.scss
index.js
save.js
style.scss
To make the functionality of our block reusable, let’s create a new file called block.js. Within this file, we need to import the following dependencies:
/**
* External dependencies
*/
import { getColorClassName } from "@wordpress/block-editor";
import classnames from "classnames";getColorClassName creates a color class name such as has-text-color and has-black-color and classnames merges multiple CSS classes together.
Next, let's create our Edit component:
export default function Edit({ color, textColor, backgroundColor }) {
const textColorClass = getColorClassName("color", textColor);
const backgroundColorClass = getColorClassName(
"background-color",
backgroundColor
);
const divClasses = classnames({
"has-text-color": color || textColor,
"has-background": color || backgroundColor,
[textColorClass]: textColorClass,
[backgroundColorClass]: backgroundColorClass,
});
return <div className={divClasses}>Hello World!</div>;
}The final block.js looks like this:
/**
* External dependencies
*/
import { getColorClassName } from "@wordpress/block-editor";
import classnames from "classnames";
export default function Edit({ color, textColor, backgroundColor }) {
const textColorClass = getColorClassName("color", textColor);
const backgroundColorClass = getColorClassName(
"background-color",
backgroundColor
);
const divClasses = classnames({
"has-text-color": color || textColor,
"has-background": color || backgroundColor,
[textColorClass]: textColorClass,
[backgroundColorClass]: backgroundColorClass,
});
return <div className={divClasses}>Hello World!</div>;
}In src/edit.js, let’s first imports all needed dependencies:
/**
* External dependencies
*/
import {
useBlockProps,
InspectorControls,
withColors,
PanelColorSettings,
} from "@wordpress/block-editor";
import { PanelBody, TextControl } from "@wordpress/components";
import { __ } from "@wordpress/i18n";
/**
* Internal dependencies
*/
import "./editor.scss";
import Block from "./block";Next, let’s create the ColorEdit component:
function ColorEdit({
attributes,
setAttributes,
textColor,
setTextColor,
backgroundColor,
setBackgroundColor,
}) {
return (
<div {...useBlockProps()}>
<InspectorControls>
<PanelBody title="Settings" initialOpen={true}>
<PanelColorSettings
title={__("Color Settings", "free-shipping-progress-bar")}
colorSettings={[
{
label: __("Message Color", "free-shipping-progress-bar"),
value: textColor.color,
onChange: setTextColor,
},
{
label: __("Progress Bar Color", "free-shipping-progress-bar"),
value: backgroundColor.color,
onChange: setBackgroundColor,
},
]}
></PanelColorSettings>
</PanelBody>
</InspectorControls>
<Block {...attributes} />
</div>
);
}Now, we need to run the ColorEdit component through the HOC component withColors(). We can do that by adding the following code:
const Edit = withColors("color", {
textColor: "color",
backgroundColor: "color",
})(ColorEdit);Finally, we export the Edit component:
export default Edit;The final edit.js looks like this:
/**
* External dependencies
*/
import {
useBlockProps,
InspectorControls,
withColors,
PanelColorSettings,
} from "@wordpress/block-editor";
import { PanelBody, TextControl } from "@wordpress/components";
import { __ } from "@wordpress/i18n";
/**
* Internal dependencies
*/
import "./editor.scss";
import Block from "./block";
function ColorEdit({
attributes,
setAttributes,
textColor,
setTextColor,
backgroundColor,
setBackgroundColor,
}) {
return (
<div {...useBlockProps()}>
<InspectorControls>
<PanelBody title="Settings" initialOpen={true}>
<PanelColorSettings
title={__("Color Settings", "free-shipping-progress-bar")}
colorSettings={[
{
label: __("Message Color", "free-shipping-progress-bar"),
value: textColor.color,
onChange: setTextColor,
},
{
label: __("Progress Bar Color", "free-shipping-progress-bar"),
value: backgroundColor.color,
onChange: setBackgroundColor,
},
]}
></PanelColorSettings>
</PanelBody>
</InspectorControls>
<Block {...attributes} />
</div>
);
}
const Edit = withColors("color", {
textColor: "color",
backgroundColor: "color",
})(ColorEdit);
export default Edit;