Search code examples
reactjswordpressblockwordpress-gutenberg

Gutenberg Block, Change supports with controls


I'm working on my plugin but I'm stuck with block supports. I need to change supports of block with inspector controls. It's like attributes. However, I have not seen anywhere that the supports section can be edited with inspector controls. Let me explain in detail:

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "myplugin/name",
    "supports": {
        "html": false,
        "spacing": {
            "__experimentalSkipSerialization": true,
            "margin": true,
            "padding": true
        }
    },
    "attributes": {
        ...      
    }
}

I want to create a handle function for change supports > spacing > padding true and false. Is there anything like setAttribute({anyAttr: newValue }) for supports? Any help would be perfect.


Solution

  • You could look at using the reapplyBlockTypeFilters action on the core/blocks data store to "re-filter" the blocks types, to run your own blocks.registerBlockType filter.

    Example pseudo-code (no build step):

    function MyBlockEdit() {
      const reapplyBlockTypeFilters = wp.data.useSelect(
        (select) => select('core/blocks').reapplyBlockTypeFilters,
      );
    
      const onChange = (event) => {
        // Remove old hook.
        wp.hooks.removeFilter(
          'blocks.registerBlockType',
          'myplugin/name/filterBlockType',
        );
    
        // Refresh hook.
        wp.hooks.addFilter(
          'blocks.registerBlockType',
          'myplugin/name/filterBlockType',
          (settings, name) =>
            name === 'myplugin/name'
              ? {
                  ...settings,
                  supports: {
                    ...settings.supports,
                    padding: /* true or false */,
                  },
                }
              : settings,
        );
    
        reapplyBlockTypeFilters();
      };
    
      // …
    }
    

    With build step:

    import { useSelect } from '@wordpress/data';
    import { addFilter, removeFilter } from '@wordpress/hooks';
    
    function MyBlockEdit() {
      const reapplyBlockTypeFilters = useSelect(
        (select) => select('core/blocks').reapplyBlockTypeFilters,
      );
    
      const onChange = (event) => {
        // Remove old hook.
        removeFilter('blocks.registerBlockType', 'myplugin/name/filterBlockType');
    
        // Refresh hook.
        addFilter(
          'blocks.registerBlockType',
          'myplugin/name/filterBlockType',
          (settings, name) =>
            name === 'myplugin/name'
              ? {
                  ...settings,
                  supports: {
                    ...settings.supports,
                    padding: /* true or false */,
                  },
                }
              : settings,
        );
    
        reapplyBlockTypeFilters();
      };
    
      // …
    }
    

    The example onChange function would be a prop that would fire on some control value change in the inspector controls. Also be aware that this would affect all blocks of the same type.