Agent skill
block-editor-components
React editor components for WordPress blocks in Oh My Brand! theme. useBlockProps, InspectorControls, MediaUpload, and attributes. Use when writing edit.tsx files.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/block-editor-components
Metadata
Additional technical details for this skill
- author
- Wesley Smits
- version
- 1.0.0
SKILL.md
Block Editor Components
React editor components for WordPress blocks in the Oh My Brand! FSE theme.
When to Use
- Creating editor UI for WordPress blocks
- Adding sidebar controls (InspectorControls)
- Implementing media selection (MediaUpload)
- Handling block attributes and state
Reference Files
| File | Purpose |
|---|---|
| edit-gallery-example.tsx | Full gallery edit component (~155 lines) |
| edit.tsx | Edit component scaffold |
Basic Edit Component
import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, RangeControl, ToggleControl } from '@wordpress/components';
import type { BlockEditProps } from '@wordpress/blocks';
interface BlockAttributes {
count: number;
isEnabled: boolean;
}
export default function Edit({
attributes,
setAttributes,
}: BlockEditProps<BlockAttributes>): JSX.Element {
const { count, isEnabled } = attributes;
const blockProps = useBlockProps();
return (
<>
<InspectorControls>
<PanelBody title={__('Settings', 'theme-oh-my-brand')}>
<RangeControl
label={__('Count', 'theme-oh-my-brand')}
value={count}
onChange={(value) => value !== undefined && setAttributes({ count: value })}
min={1}
max={10}
/>
<ToggleControl
label={__('Enable Feature', 'theme-oh-my-brand')}
checked={isEnabled}
onChange={(value) => setAttributes({ isEnabled: value })}
/>
</PanelBody>
</InspectorControls>
<div {...blockProps}>
{/* Block content */}
</div>
</>
);
}
See edit-gallery-example.tsx for a complete implementation with MediaUpload.
useBlockProps
// Basic usage
const blockProps = useBlockProps();
// With additional classes
const blockProps = useBlockProps({ className: 'custom-class' });
// With data attributes
const blockProps = useBlockProps({
className: 'wp-block-theme-oh-my-brand-gallery',
'data-visible': visibleImages,
});
// Apply to wrapper
return <div {...blockProps}>Content</div>;
InspectorControls
Add sidebar panel controls:
<InspectorControls>
<PanelBody title={__('Settings', 'theme-oh-my-brand')} initialOpen={true}>
<RangeControl
label={__('Visible Items', 'theme-oh-my-brand')}
value={visibleItems}
onChange={(value) => setAttributes({ visibleItems: value })}
min={1}
max={6}
/>
<ToggleControl
label={__('Enable Feature', 'theme-oh-my-brand')}
checked={enableFeature}
onChange={(value) => setAttributes({ enableFeature: value })}
/>
<SelectControl
label={__('Layout', 'theme-oh-my-brand')}
value={layout}
onChange={(value) => setAttributes({ layout: value })}
options={[
{ label: __('Grid', 'theme-oh-my-brand'), value: 'grid' },
{ label: __('Carousel', 'theme-oh-my-brand'), value: 'carousel' },
]}
/>
<TextControl
label={__('Caption', 'theme-oh-my-brand')}
value={caption}
onChange={(value) => setAttributes({ caption: value })}
/>
</PanelBody>
</InspectorControls>
MediaUpload
Single Image
<MediaUploadCheck>
<MediaUpload
onSelect={(media) => setAttributes({
imageId: media.id,
imageUrl: media.sizes?.large?.url || media.url,
imageAlt: media.alt || '',
})}
allowedTypes={['image']}
value={imageId}
render={({ open }) => (
<Button variant="primary" onClick={open}>
{imageUrl ? __('Replace', 'theme-oh-my-brand') : __('Select', 'theme-oh-my-brand')}
</Button>
)}
/>
</MediaUploadCheck>
Multiple Images (Gallery)
<MediaUploadCheck>
<MediaUpload
onSelect={(media) => {
const selected = media.map((item) => ({
id: item.id,
url: item.sizes?.large?.url || item.url,
alt: item.alt || '',
}));
setAttributes({ images: selected });
}}
allowedTypes={['image']}
multiple={true}
gallery={true}
value={images.map((img) => img.id)}
render={({ open }) => (
<Button variant="primary" onClick={open}>
{hasImages ? __('Edit Gallery', 'theme-oh-my-brand') : __('Select', 'theme-oh-my-brand')}
</Button>
)}
/>
</MediaUploadCheck>
Block Attributes
Type Definitions
interface BlockAttributes {
title: string;
count: number;
isEnabled: boolean;
images: ImageData[];
}
interface ImageData {
id: number;
url: string;
alt: string;
}
Setting Attributes
// Single attribute
setAttributes({ title: 'New Title' });
// Multiple attributes
setAttributes({ title: 'New Title', count: 5 });
// Array attribute
setAttributes({ images: [...images, newImage] });
Attribute Defaults (block.json)
"attributes": {
"title": { "type": "string", "default": "" },
"count": { "type": "number", "default": 3 },
"isEnabled": { "type": "boolean", "default": true },
"images": { "type": "array", "default": [] }
}
Common Patterns
Placeholder State
import { Placeholder } from '@wordpress/components';
import { gallery as blockIcon } from '@wordpress/icons';
{!hasContent && (
<Placeholder
icon={blockIcon}
label={__('Block Name', 'theme-oh-my-brand')}
instructions={__('Instructions for the user.', 'theme-oh-my-brand')}
>
<Button variant="primary" onClick={handleAdd}>
{__('Add Content', 'theme-oh-my-brand')}
</Button>
</Placeholder>
)}
Toolbar Controls
import { BlockControls } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
<BlockControls>
<ToolbarGroup>
<ToolbarButton icon={edit} label={__('Edit', 'theme-oh-my-brand')} onClick={handleEdit} />
<ToolbarButton icon={trash} label={__('Remove', 'theme-oh-my-brand')} onClick={handleRemove} />
</ToolbarGroup>
</BlockControls>
Related Skills
- typescript-standards - TypeScript conventions
- native-block-development - Block structure
- block-scaffolds - Edit component template
References
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?