Inspector Controls & Block Toolbar
InspectorControls (Sidebar)
InspectorControls adds settings to the block sidebar panel:
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody, RangeControl, SelectControl } from '@wordpress/components';
export default function Edit( { attributes, setAttributes } ) {
return (
<>
<InspectorControls>
<PanelBody title="Layout Settings" initialOpen={ true }>
<RangeControl
label="Columns"
value={ attributes.columns }
onChange={ ( columns ) => setAttributes( { columns } ) }
min={ 1 }
max={ 4 }
/>
</PanelBody>
<PanelBody title="Style Options" initialOpen={ false }>
<SelectControl
label="Style"
value={ attributes.style }
options={ [
{ label: 'Default', value: 'default' },
{ label: 'Bordered', value: 'bordered' },
] }
onChange={ ( style ) => setAttributes( { style } ) }
/>
</PanelBody>
</InspectorControls>
<div { ...useBlockProps() }>
{/* Block content */}
</div>
</>
);
}Available Control Components
| Component | Use For |
|---|---|
TextControl | Single line text |
TextareaControl | Multi-line text |
RangeControl | Number slider |
SelectControl | Dropdown menu |
ToggleControl | On/off switch |
CheckboxControl | Checkbox |
RadioControl | Radio buttons |
ColorPicker | Color selection |
DateTimePicker | Date/time |
FormTokenField | Tag-style input |
Color Settings
Use ColorPaletteControl for theme-aware colors:
import { InspectorControls, PanelColorSettings } from '@wordpress/block-editor';
<InspectorControls>
<PanelColorSettings
title="Colors"
colorSettings={ [
{
value: attributes.backgroundColor,
onChange: ( backgroundColor ) => setAttributes( { backgroundColor } ),
label: 'Background Color',
},
{
value: attributes.textColor,
onChange: ( textColor ) => setAttributes( { textColor } ),
label: 'Text Color',
},
] }
/>
</InspectorControls>This automatically uses your theme's color palette!
BlockControls (Toolbar)
BlockControls adds buttons to the block toolbar:
import { BlockControls, AlignmentToolbar } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { formatBold, link } from '@wordpress/icons';
export default function Edit( { attributes, setAttributes } ) {
return (
<>
<BlockControls>
<AlignmentToolbar
value={ attributes.alignment }
onChange={ ( alignment ) => setAttributes( { alignment } ) }
/>
<ToolbarGroup>
<ToolbarButton
icon={ formatBold }
label="Bold"
onClick={ () => {/* handle click */} }
isPressed={ attributes.isBold }
/>
<ToolbarButton
icon={ link }
label="Add Link"
onClick={ () => setAttributes( { showLink: true } ) }
/>
</ToolbarGroup>
</BlockControls>
<div { ...useBlockProps() }>
{/* Block content */}
</div>
</>
);
}ToolbarDropdownMenu
For grouped options:
import { ToolbarDropdownMenu } from '@wordpress/components';
import { chevronDown, grid, list } from '@wordpress/icons';
<BlockControls>
<ToolbarDropdownMenu
icon={ attributes.layout === 'grid' ? grid : list }
label="Layout"
controls={ [
{
icon: grid,
title: 'Grid',
onClick: () => setAttributes( { layout: 'grid' } ),
isActive: attributes.layout === 'grid',
},
{
icon: list,
title: 'List',
onClick: () => setAttributes( { layout: 'list' } ),
isActive: attributes.layout === 'list',
},
] }
/>
</BlockControls>Complete Example with Full Controls
import { __ } from '@wordpress/i18n';
import {
useBlockProps,
RichText,
InspectorControls,
BlockControls,
AlignmentToolbar,
PanelColorSettings
} from '@wordpress/block-editor';
import {
PanelBody,
RangeControl,
ToggleControl,
SelectControl,
ToolbarGroup,
ToolbarButton
} from '@wordpress/components';
import { edit, trash } from '@wordpress/icons';
export default function Edit( { attributes, setAttributes } ) {
const {
content,
alignment,
columns,
showBorder,
borderStyle,
backgroundColor,
textColor
} = attributes;
const blockProps = useBlockProps( {
className: `align-${ alignment } columns-${ columns }`,
style: {
backgroundColor,
color: textColor,
...(showBorder && { border: `2px ${ borderStyle } currentColor` })
}
} );
return (
<>
{/* Toolbar */}
<BlockControls>
<AlignmentToolbar
value={ alignment }
onChange={ ( newAlign ) => setAttributes( { alignment: newAlign } ) }
/>
<ToolbarGroup>
<ToolbarButton
icon={ edit }
label={ __( 'Edit', 'my-block' ) }
onClick={ () => console.log( 'Edit clicked' ) }
/>
</ToolbarGroup>
</BlockControls>
{/* Sidebar */}
<InspectorControls>
<PanelBody title={ __( 'Layout', 'my-block' ) }>
<RangeControl
label={ __( 'Columns', 'my-block' ) }
value={ columns }
onChange={ ( val ) => setAttributes( { columns: val } ) }
min={ 1 }
max={ 4 }
/>
</PanelBody>
<PanelBody title={ __( 'Border', 'my-block' ) } initialOpen={ false }>
<ToggleControl
label={ __( 'Show Border', 'my-block' ) }
checked={ showBorder }
onChange={ ( val ) => setAttributes( { showBorder: val } ) }
/>
{ showBorder && (
<SelectControl
label={ __( 'Border Style', 'my-block' ) }
value={ borderStyle }
options={ [
{ label: 'Solid', value: 'solid' },
{ label: 'Dashed', value: 'dashed' },
{ label: 'Dotted', value: 'dotted' },
] }
onChange={ ( val ) => setAttributes( { borderStyle: val } ) }
/>
) }
</PanelBody>
<PanelColorSettings
title={ __( 'Colors', 'my-block' ) }
colorSettings={ [
{
value: backgroundColor,
onChange: ( val ) => setAttributes( { backgroundColor: val } ),
label: __( 'Background', 'my-block' ),
},
{
value: textColor,
onChange: ( val ) => setAttributes( { textColor: val } ),
label: __( 'Text', 'my-block' ),
},
] }
/>
</InspectorControls>
{/* Block Content */}
<div { ...blockProps }>
<RichText
tagName="p"
value={ content }
onChange={ ( val ) => setAttributes( { content: val } ) }
placeholder={ __( 'Enter text...', 'my-block' ) }
/>
</div>
</>
);
}
Control Grouping: Use
PanelBody to organize settings logically. Set initialOpen={false} for secondary settings.
Next Steps
In the next lesson, we'll create dynamic blocks that render with PHP on the server.
๐ฏ Lesson Complete! You can now add comprehensive controls to your blocks.