Developing Custom Block Controls
Block controls allow users to customize the appearance, layout, and behavior of blocks in the WordPress Block Editor. These controls provide an interface for users to make adjustments without needing to code, offering flexibility for users while keeping the editing experience simple.
For developers, understanding how to create these controls enables you to build powerful, user-friendly blocks that offer customization options directly in the editor.
Understanding Sidebar (InspectorControls) vs Inline (Block-Level Controls)
In the WordPress Block Editor, controls can be added either in the sidebar or directly within the block itself. Both types of controls serve different purposes and enhance the editing experience in their ways.
InspectorControls (Sidebar Controls)
InspectorControls
appear in the right-hand sidebar when editing a block. These controls are used for settings that affect a block’s layout, style, or behavior without directly changing the block’s content. The sidebar is the best place for inputs like color pickers, text inputs, and toggles.
Example: Adding a TextControl
and ColorPicker
import { __ } from "@wordpress/i18n";
import { useBlockProps, InspectorControls } from "@wordpress/block-editor";
import { PanelBody, TextControl, ColorPicker } from "@wordpress/components";
const Edit = (props) => {
const { attributes, setAttributes } = props;
const { text, backgroundColor } = attributes;
return (
<div {...useBlockProps()} style={{ backgroundColor }}>
<InspectorControls>
<PanelBody title={__("Block Settings")}>
<TextControl
label={__("Heading Text")}
value={text}
onChange={(newText) => setAttributes({ text: newText })}
/>
<ColorPicker
label={__("Background Color")}
color={backgroundColor}
onChange={(colorValue) =>
setAttributes({ backgroundColor: colorValue })
}
/>
</PanelBody>
</InspectorControls>
<h2>{text}</h2>
</div>
);
};
export default Edit;
- InspectorControls adds block settings to the sidebar, offering customization options without cluttering the main content area.
- TextControl provides a field for users to input the heading text.
- ColorPicker allows users to select a background color.
Inline (Block-Level Controls)
Also known as the block toolbar, these controls appear directly within or above the block when it is selected. They are designed to give users quick access to essential settings, such as text formatting, alignment, or other immediate adjustments. The block toolbar is all about making fast, in-context changes without navigating away from the block you’re working on.
For a detailed guide on creating and customizing block toolbars, check out the full blog post here.
Dynamic Block Controls: Conditional Controls
Dynamic block controls change based on user input, making blocks more interactive and intuitive. For example, you might show a RangeControl
for adjusting font size only if the user has enabled the option for custom font sizes.
Example: Conditionally Showing a Font Size Slider
import { ToggleControl, RangeControl } from "@wordpress/components";
const Edit = (props) => {
const { attributes, setAttributes } = props;
const { enableCustomFontSize, fontSize } = attributes;
return (
<div>
<ToggleControl
label="Enable Custom Font Size"
checked={enableCustomFontSize}
onChange={(value) => setAttributes({ enableCustomFontSize: value })}
/>
{enableCustomFontSize && (
<RangeControl
label="Font Size"
value={fontSize}
onChange={(value) => setAttributes({ fontSize: value })}
min={12}
max={100}
/>
)}
</div>
);
};
- The ToggleControl allows users to enable or disable custom font size settings.
- The RangeControl slider appears only if the toggle is enabled, keeping the interface clean and context-aware.
Saving, Validating, and Rendering Block Controls
When users interact with block controls, their input is saved as block attributes. These attributes are then rendered on the front end to reflect the user’s choices.
Saving Block Controls
Example: Saving and Rendering Block Attributes
const Save = (props) => {
const { attributes } = props;
const { text, backgroundColor } = attributes;
return (
<div style={{ backgroundColor }}>
<h2>{text}</h2>
</div>
);
};
Save function: This example renders the text and background color chosen by the user. When the content is saved, these attributes ensure the user’s customization appears both in the editor and on the live page.
Validating User Input in Block Controls
Validation ensures that users provide correct and appropriate input in block controls. For instance, you might validate the length of a text field or check if a URL is properly formatted.
Example: Validating Text Input Length
const validateInput = ( value ) => {
if ( value.length < 5 ) {
setError( 'Input must be at least 5 characters.' );
}
};
This function ensures the user provides text input with at least 5 characters, helping avoid invalid or incomplete data.
Optimizing Performance for Block Controls
Reducing Unnecessary Re-Renders
When a block re-renders too often, especially with complex controls, it can degrade performance. To improve performance, ensure that block attributes are only updated when necessary, and avoid expensive state updates.
Example: Using useCallback
and useMemo
to Optimize Re-Renders
import { useMemo, useCallback } from "react";
import { RangeControl } from "@wordpress/components";
const Edit = (props) => {
const { attributes, setAttributes } = props;
const { fontSize } = attributes; // Using useMemo to optimize fontSize range initialization
const fontSizeRange = useMemo(() => {
return { min: 12, max: 100 };
}, []); // Using useCallback to prevent re-creation of the handleFontSizeChange function
const handleFontSizeChange = useCallback(
(value) => {
setAttributes({ fontSize: value });
},
[setAttributes]
);
return (
<div>
<RangeControl
label="Font Size"
value={fontSize}
onChange={handleFontSizeChange}
min={fontSizeRange.min}
max={fontSizeRange.max}
/>
</div>
);
};
useMemo
: Precomputes the font size range and prevents recalculation on every render.useCallback
: Ensures that the handleFontSizeChange function isn’t recreated unnecessarily, avoiding extra processing and improving performance.
Styling and Accessibility in Block Controls
Using WordPress’s Built-in Component Library
WordPress provides components like TextControl
, Button
, and ColorPicker
to help you maintain a consistent design across blocks. This ensures your custom controls fit naturally into the editor.
.custom-block-control {
margin: 10px 0;
padding: 5px;
}
Accessibility Considerations
Make sure your controls are accessible by:
- Using descriptive labels and tooltips.
- Adding ARIA attributes for screen readers.
- Ensuring keyboard navigation works seamlessly.
Example: Accessible Toggle Button
<ToggleControl
label="Enable Feature"
aria-label="Enable or disable custom feature"
checked={ isEnabled }
onChange={ ( value ) => setEnabled( value ) }
/>
By leveraging the power of InspectorControls
, dynamic features like conditional controls, validation, and performance optimizations, you can create custom block controls that enhance both the user experience and the flexibility of the WordPress Block Editor. Focusing on performance and accessibility ensures that your blocks not only function well but also offer a seamless experience for all users.