# Creating custom block controls

*Published:* 2024-10-23
*Author:* Shreya Agarwal

> Learn how to add custom controls to WordPress blocks. Improve the block editor experience with sidebar settings, dynamic options, and more.

# Developing Custom Block Controls

Block controls allow users to customize the appearance, layout, and behavior of blocks in the [WordPress Block Editor](https://wordpress.org/documentation/article/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.

![Developing custom block controls](https://rtcamp.com/wp-content/uploads/sites/2/2024/10/Screenshot-2024-10-23-at-8.00.24 PM.png?resize=720%2C354&quality=100&strip=all)Custom controls for core/cover block to pause/play videoFor 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](https://developer.wordpress.org/block-editor/reference-guides/components/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.

Check out our detailed guide on [creating and customizing block toolbars](https://rtcamp.com/handbook/developing-for-block-editor-and-site-editor/custom-toolbar/).

## 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 <a href="https://developer.wordpress.org/block-editor/reference-guides/components/range-control/" rel="noreferrer noopener" target="_blank">RangeControl</a> 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.

### Categories and Taxonomies

#### Service
[WP Frontend Development](https://rtcamp.com/blog/service/wp-frontend-development.md)

#### Solutions
[WordPress Development](https://rtcamp.com/blog/solution/wordpress-development.md)

#### Topics
[Frontend](https://rtcamp.com/topics/frontend.md), [WordPress](https://rtcamp.com/topics/wordpress.md), [WordPress Development](https://rtcamp.com/topics/wordpress-development.md)

### Related Posts

- [Structural Limits of Accounting-First Software](https://rtcamp.com/handbook/why-migrate-quickbooks-to-erpnext/structural-limits.md)
- [Project structure](https://rtcamp.com/handbook/react-best-practices/project-structure.md)
- [Outgrowing standard hosting](https://rtcamp.com/handbook/enterprise-wordpress-hosting/why-choose-enterprise-wordpress-hosting.md)
- [WordPress vs Kentico](https://rtcamp.com/handbook/enterprise-consolidation/kentico-vs-wordpress.md)
- [rtCamp’s philosophy & principles](https://rtcamp.com/handbook/headless-wordpress/rtcamps-philosophy.md)
