如何通过Inspector Controls修改Gutenberg Block的supports配置?
解决Gutenberg区块通过Inspector Controls动态修改supports的问题
首先明确:区块的supports是静态配置,属于区块类型定义,无法像attributes那样在单个区块实例运行时直接修改。要实现通过Inspector开关控制padding支持的需求,需要通过「属性+逻辑控制」的方式模拟动态开关效果,具体步骤如下:
1. 在block.json中添加控制属性
给区块新增一个enablePadding属性,用于标记是否启用padding控制:
{ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "myplugin/name", "supports": { "html": false, "spacing": { "__experimentalSkipSerialization": true, "margin": true, "padding": true } }, "attributes": { "enablePadding": { "type": "boolean", "default": true }, // 其他原有属性... } }
2. 在编辑组件中添加Inspector开关控件
引入WordPress的UI组件,在Inspector Controls中添加开关并绑定enablePadding属性,切换时可同步清空padding样式:
import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; import { PanelBody, ToggleControl } from '@wordpress/components'; export default function Edit({ attributes, setAttributes }) { const { enablePadding, style } = attributes; const handlePaddingToggle = (value) => { let updatedStyle = { ...style }; // 禁用时清空padding样式 if (!value && updatedStyle?.spacing?.padding) { delete updatedStyle.spacing.padding; if (Object.keys(updatedStyle.spacing).length === 0) { delete updatedStyle.spacing; } } setAttributes({ enablePadding: value, style: updatedStyle }); }; return ( <> <InspectorControls> <PanelBody title="区块样式设置"> <ToggleControl label="启用内边距控制" checked={ enablePadding } onChange={ handlePaddingToggle } /> </PanelBody> </InspectorControls> <div { ...useBlockProps() }> {/* 区块内容 */} 我的自定义区块 </div> </> ); }
3. 控制前端渲染时的padding输出
在save函数中,根据enablePadding属性决定是否保留padding样式:
import { useBlockProps } from '@wordpress/block-editor'; export default function save({ attributes }) { const { enablePadding, style } = attributes; // 禁用时移除padding相关样式 const finalStyle = enablePadding ? style : { ...style, spacing: style?.spacing ? { ...style.spacing, padding: undefined } : undefined }; // 清理空对象避免无效输出 const cleanedStyle = Object.fromEntries( Object.entries(finalStyle).filter(([_, value]) => value !== undefined && Object.keys(value).length > 0) ); const blockProps = useBlockProps.save({ style: Object.keys(cleanedStyle).length > 0 ? cleanedStyle : undefined }); return ( <div { ...blockProps }> 我的自定义区块 </div> ); }
4. 隐藏禁用状态下的padding编辑器控件(可选)
如果需要在禁用padding时隐藏侧边栏的padding控制项,可通过过滤器实现:
import { addFilter } from '@wordpress/hooks'; import { InspectorControls } from '@wordpress/block-editor'; import React from 'react'; addFilter( 'editor.BlockEdit', 'myplugin/hide-padding-control', (OriginalEdit, props) => { if (props.name !== 'myplugin/name') return OriginalEdit; return (props) => { const { attributes } = props; const originalOutput = <OriginalEdit { ...props } />; if (!attributes.enablePadding) { return ( <> {originalOutput.props.children.filter(child => { if (child.type === InspectorControls) { return React.cloneElement(child, { children: child.props.children.map(panel => { if (panel.props.title === 'Spacing') { return React.cloneElement(panel, { children: panel.props.children.filter(control => control.props.label !== 'Padding' ) }); } return panel; }) }); } return child; })} </> ); } return originalOutput; }; } );
核心逻辑说明
supports是区块类型的静态配置,无法针对单个实例动态修改。我们通过新增属性作为开关,在编辑时控制UI显示和样式修改,在保存时控制样式输出,以此模拟动态切换supports的效果。
内容的提问来源于stack exchange,提问作者kront
相关产品推荐
相关产品推荐

