So, you’re diving into custom Gutenberg blocks and you’ve hit a point where you want to add a bit more flair, a touch more control, directly to your block’s toolbar. That familiar little row of icons that pops up when you select your block – yeah, that one! It’s a common next step for many, and thankfully, it’s more accessible than you might think.
The short answer? You create a custom Gutenberg block toolbar control by defining a new component that renders within the BlockControls slot. This involves understanding React components, Gutenberg’s data store, and a little bit about how WordPress renders these interface elements. It’s about extending the existing interface, not reinventing the wheel, and the tools are already there for you.
The Building Blocks: What You Need to Know
Before we get our hands dirty, let’s make sure we’re on the same page with a few key concepts. You don’t need to be a seasoned React ninja, but a basic understanding will smooth out the learning curve significantly.
Understanding Gutenberg’s Architecture
Gutenberg, now the default WordPress editor, is built using React. This means its interface, including blocks, toolbars, and inspector panels, is composed of React components. Each block registers its own set of components, and the editor orchestrates how they’re displayed.
- InnerBlocks vs. Reusable Blocks: It’s worth noting the difference.
InnerBlocksallows creating blocks that can contain other blocks, building complex nested structures. Reusable blocks are saved entities that can be inserted multiple times across posts. We’re focusing on custom toolbar controls for your own unique blocks.
React Fundamentals (A Quick Refresher)
If you’ve dipped your toes into React, you’ll be familiar with concepts like components, props, and state. For building custom controls, you’ll primarily be working with components.
- Components: Think of these as the LEGO bricks of your user interface. You create a function or class that returns JSX (JavaScript XML), which describes what should be rendered.
- Props: These are like arguments passed to components, allowing you to customize their behavior and appearance from their parent.
- State: This refers to data that a component manages and can change over time. While less critical for simple toolbar controls, it becomes important if your control needs to maintain some sort of internal state.
Gutenberg’s Data Store
WordPress uses a Redux-like data store to manage the editor’s state. Block attributes, selected blocks, and other crucial information are stored here. You’ll interact with this store to read data and dispatch actions to update it.
useSelectanduseDispatchHooks: These are your primary tools for interacting with the data store in modern Gutenberg development.useSelectlets you grab data, anduseDispatchallows you to send commands.
If you’re looking to enhance your WordPress development skills, particularly in creating custom Gutenberg block toolbar controls, you might find it beneficial to explore related resources. One such article that provides valuable insights into payment integration for WordPress is available at this link. It offers a comprehensive guide on implementing payment solutions, which can complement your understanding of custom block development by showcasing how to integrate various functionalities within the WordPress ecosystem.
The Toolbar Blueprint: Where Your Control Lives
The block toolbar isn’t just some arbitrary space; it’s a deliberate part of Gutenberg’s UI structure. Understanding where your custom control fits in is crucial.
BlockControls and InspectorControls
When you’re developing a custom block, you’ll often come across two key components for adding UI elements: BlockControls and InspectorControls.
BlockControls: This is where the magic for the block toolbar happens. Anything rendered within theBlockControlscomponent will appear in the floating toolbar that accompanies your block when it’s selected. This is the target for our custom controls.InspectorControls: This component renders controls in the block settings sidebar (the panel that appears on the right when you click the gear icon). These are for more complex settings that don’t need to be in the immediate toolbar.
The Principle of SlotFills
Gutenberg employs a powerful pattern called “SlotFills.” This is how different parts of the editor can contribute UI elements to specific areas. BlockControls is a “slot,” and when you render a component within it, you’re essentially “filling” that slot.
- The
nameProp: When usingBlockControls, you’ll often see anameprop. This helps WordPress identify and organize different types of controls within the toolbar. For custom controls, you’ll define your own specific areas.
Crafting Your Custom Control: The Code Walkthrough
Now, let’s get to the practical part. We’ll build a simple example to illustrate the process. Imagine we want to add a button to our block’s toolbar that toggles a highlight attribute for the block.
Step 1: Registering Your Block
This is the foundational step. Assuming you have a block.json file and a registration script, you’ll have a basic block set up.
“`javascript
// src/index.js or similar file where your block is registered
import { registerBlockType } from ‘@wordpress/blocks’;
import ‘./style.scss’; // For block styles
import ‘./editor.scss’; // For editor-specific styles
import Edit from ‘./edit’; // Your block’s edit component
import save from ‘./save’; // Your block’s save component
registerBlockType(‘my-plugin/my-custom-block’, {
edit: Edit,
save: save,
// … other block settings
});
“`
Step 2: Defining the Edit Component
This Edit component is where you’ll house your toolbar control. It receives block attributes, setAttributes, and className as props.
“`javascript
// src/edit.js
import { __ } from ‘@wordpress/i18n’;
import { useBlockProps, BlockControls } from ‘@wordpress/block-editor’;
import { ToolbarGroup, ToolbarButton, Tooltip } from ‘@wordpress/components’;
import { formatBold } from ‘@wordpress/icons’; // Example icon
function Edit({ attributes, setAttributes }) {
const blockProps = useBlockProps();
const { isHighlighted } = attributes; // Assuming you have a ‘isHighlighted’ attribute
const toggleHighlight = () => {
setAttributes({ isHighlighted: !isHighlighted });
};
return (
<>
icon={formatBold} // Use an available icon label={__(‘Toggle Highlight’, ‘my-plugin’)} onClick={toggleHighlight} isActive={isHighlighted} // Highlight the button if active /> {/ Your block’s content goes here /} This is my custom block. {isHighlighted && Highlighted!} > ); } export default Edit; “` Your “`json // block.json { “apiVersion”: 2, “name”: “my-plugin/my-custom-block”, “version”: “0.1.0”, “title”: “My Custom Block”, “category”: “text”, “attributes”: { “isHighlighted”: { “type”: “boolean”, “default”: false } }, “editorScript”: “file:./index.asset.php”, “editorStyle”: “file:./index.css”, “style”: “file:./style-index.css” } “` You’ll need styles to visually indicate the highlighted state. “`scss // src/editor.scss .wp-block-my-plugin-my-custom-block.is-highlighted { border: 2px solid yellow; background-color: rgba(255, 255, 0, 0.2); } // src/style.scss (for frontend) .wp-block-my-plugin-my-custom-block.is-highlighted { border: 2px solid yellow; background-color: rgba(255, 255, 0, 0.2); } “` The example above touches on several important components from As mentioned, this is the wrapper. It tells Gutenberg, “Everything inside here belongs in the block toolbar.” This component groups related toolbar items. It can help declutter the toolbar, especially if you have many controls. This is the star of your custom control. It renders an icon, a label (for tooltips and accessibility), and an Although not directly used in the If you’re looking to enhance your custom Gutenberg block by adding a toolbar control, you might find it helpful to explore related topics that can improve your overall site performance. For instance, optimizing your website’s speed can significantly impact user experience and SEO. A great resource for this is an article on Google PageSpeed Insights, which provides valuable insights on how to improve your site’s loading time. You can read more about it here. This knowledge can complement your efforts in creating a more efficient and user-friendly block editor experience. Once you’ve got the basics down, you might want to explore more complex scenarios or refine your controls. You can add as many The “`javascript // src/components/MyCustomIcon.js import React from ‘react’; const MyCustomIcon = (props) => ( ); export default MyCustomIcon; “` Then, import and use it: “`javascript import MyCustomIcon from ‘./components/MyCustomIcon’; // … inside your Edit component “` You might want a toolbar button to only appear under certain conditions. “`javascript // Example: Show button only if another attribute is set function Edit({ attributes, setAttributes }) { const { someOtherSetting, isHighlighted } = attributes; return ( <> {someOtherSetting && ( // Conditional rendering icon={formatBold} label={__(‘Toggle Highlight’, ‘my-plugin’)} onClick={() => setAttributes({ isHighlighted: !isHighlighted })} isActive={isHighlighted} /> )} {/ … rest of your block /} > ); } “` Sometimes, your toolbar control might need to read or modify attributes of other blocks. This is where This is more advanced and requires careful consideration of how your block interacts with the rest of the content. For simple controls on your own block, stick to To make your custom controls effective and user-friendly, keep these tips in mind: The block toolbar has limited space. Aim for controls that perform discrete, useful actions. Avoid cluttering it with too many options. The Choose icons that intuitively represent the action. For togglable features, the While generally not a major concern for simple toolbar controls, be mindful if your control involves complex logic or data fetching. Before you ship your custom block with its new toolbar control, run through this quick checklist: Creating custom Gutenberg block toolbar controls is a fantastic way to enhance the user experience for your blocks. By understanding the underlying React structure, Gutenberg’s component system, and the role of Step 3: Adding Block Attributes
block.json needs to define the attribute that your toolbar control will manage.Step 4: Handling Styles (Editor and Frontend)
Deep Dive: The Components You’ll Use
@wordpress/components and @wordpress/block-editor. Let’s unpack them.BlockControls
ToolbarGroup components for better organization. Blocks can have multiple ToolbarGroups to separate related controls.ToolbarGroup
ToolbarButtononClick handler.
icon Prop: Accepts a React element, typically an SVG icon imported from @wordpress/icons (like formatBold, alignLeft, image, etc.). You can also create your own SVG icons.label Prop: This is crucial for accessibility and for the tooltip that appears when a user hovers over the button. Use speak strings from @wordpress/i18n for translation.onClick Prop: This is where you define the action that happens when the button is clicked. This is where you’ll use setAttributes to update your block’s state.isActive Prop: A boolean that, when true, visually indicates that the button’s associated action is currently active (e.g., the bold button is active if the text is bold). This is perfect for toggling states.TooltipToolbarButton itself in this example, Tooltip is often used in conjunction with ToolbarButton to provide explanatory text when hovering. The label prop on ToolbarButton essentially handles this functionality for you.Advanced Scenarios and Further Customization
Multiple Controls in One Group
ToolbarButton components as you need within a single ToolbarGroup.
ToolbarButtons: one for “primary,” one for “secondary,” and one for “outline” styles, each triggering a different setAttributes call.Using Different Icons
@wordpress/icons package is a treasure trove of common icons.
import { IconName } from '@wordpress/icons';.js or .jsx file.Conditional Rendering of Controls
useSelect to check the globally selected block can also influence visibility, though this is less common for your block’s specific toolbar.Interacting with Other Block Data
useSelect and useDispatch come in handy.
const { getBlockAttributes } = useSelect('core/block-editor');const { updateBlockAttributes } = useDispatch('core/block-editor');setAttributes.Best Practices for Toolbar Controls
Keep it Concise
Clear and Actionable Labels
label prop is vital.
__( 'Your Label', 'your-text-domain' ): Always internationalize your labels for translation.Appropriate Icons
@wordpress/icons when available.State Indication (
isActive)isActive prop on ToolbarButton is a must. It provides immediate visual feedback to the user.
Performance Considerations
onClick handler if it can be avoided.useMemo and useCallback hooks.Putting It All Together: A Checklist
index.js?block.json Attributes: Is the necessary attribute defined with the correct type and default?Edit Component: Is the Edit component set up to receive props like attributes and setAttributes?BlockControls: Is your custom UI wrapped within BlockControls?ToolbarGroup & ToolbarButton: Are you using these components correctly?icon: Is an appropriate icon provided?label: Is the label clear, translatable, and descriptive?onClick: Does the onClick handler correctly call setAttributes to toggle or change the relevant attribute?isActive (if applicable): Is isActive used to reflect the current state of the control?BlockControls, you can add powerful and intuitive options directly into the editing workflow, making your custom blocks shine.