Не работает средство выбора вариантов блоков Гутенберга

#reactjs #wordpress-gutenberg #gutenberg-blocks

Вопрос:

Я пытаюсь добавить средство выбора вариантов блоков, как в примере WordPress Github:

 import { useSelect } from '@wordpress/data';
import {
    __experimentalBlockVariationPicker as BlockVariationPicker,
    store as blockEditorStore,
} from '@wordpress/block-editor';

const MyBlockVariationPicker = ( { blockName } ) => {
    const variations = useSelect(
        ( select ) => {
            const { getBlockVariations } = select( blocksStore );
            return getBlockVariations( blockName, 'block' );
        },
        [ blockName ]
    );
    return <BlockVariationPicker variations={ variations } />;
};
 

В моей функции редактирования я добавляю:

 { MyBlockVariationPicker }
 

Средство выбора вариантов блоков не отображается.

Я уже зарегистрировал свои варианты блоков с помощью блока scope:

 registerBlockVariation(
   'my/testimonial',
   [
     {
       name: 'testimonial-1',
       title: 'Testimonial 1',
       scope: ['block'],
       attributes: {
         example: 'testimonial-1'
       },
   },
   {
       name: 'testimonial-2',
       title: 'Testimonial 2',
       scope: ['block'],
       attributes: {
         example: 'testimonial-2'
       },
     }
   ]
 );
 

Варианты блоков должны отображаться, { MyBlockVariationPicker } но не отображаются. К сожалению, документации по этому поводу не так много. Как мы можем отобразить варианты блока с помощью средства выбора вариантов блоков, как показано в примере Github?

Ответ №1:

Используются как столбцы, так и блок запросов __experimentalBlockVariationPicker , и это действительно хороший компонент / пользовательский интерфейс, и я согласен, что примеров его использования не так много, скорее всего, поскольку он все еще «экспериментальный» и все еще может измениться.

Я обнаружил, что как столбцы, так и блоки запросов отображают BlockVariationPicker , проверяя, содержит ли текущий блок (по идентификатору клиента) какие-либо внутренние блоки; если их нет, BlockVariationPicker отображается. При использовании этого компонента в вашем собственном блоке вам понадобится некоторый атрибут или свойство, чтобы проверить, был ли выбран вариант.

Я собрал базовый / рабочий пример, используя структуру вашего my/testimonial блока variations и основываясь на том, как BlockVariationPicker реализован в блоке Columns:

 import { get } from 'lodash';
import { useSelect } from '@wordpress/data';
import { registerBlockType, registerBlockVariation, store as blocksStore } from '@wordpress/blocks';
import { useBlockProps, __experimentalBlockVariationPicker as BlockVariationPicker } from '@wordpress/block-editor';


// Create our own BlockVariationPicker
const MyBlockVariationPicker = ({ name, setAttributes }) => { // Note: We need "name" and "setAttributes" from edit() props
    const { blockType, variations, defaultVariation } = useSelect(
        (select) => {
            const { getBlockVariations, getBlockType, getDefaultBlockVariation } = select(blocksStore);
            return {
                blockType: getBlockType(name),
                defaultVariation: getDefaultBlockVariation(name, 'block'),
                variations: getBlockVariations(name, 'block')
            };
        },
        [name]
    );
    return <BlockVariationPicker
        variations={variations}
        icon={get(blockType, ['icon', 'src'])}
        label={get(blockType, ['title'])}
        onSelect={(nextVariation = defaultVariation) => {
            if (nextVariation.attributes) {
                setAttributes(nextVariation.attributes); // Use setAttributes to set the selected variation attributes
            }
        }}
    />;
};

// Register the Block Variations
registerBlockVariation(
    'my/testimonial',
    [
        {
            name: 'testimonial-1',
            title: 'Testimonial 1',
            icon: 'admin-comments', // Added icon so the variation is visibly different (optional)
            scope: ['block'],
            attributes: {
                example: 'testimonial-1'
            },
            isDefault: true
        },
        {
            name: 'testimonial-2',
            title: 'Testimonial 2',
            icon: 'admin-links',
            scope: ['block'],
            attributes: {
                example: 'testimonial-2'
            },
        }
    ]
);

registerBlockType('my/testimonial', {
    title: 'My Testimonial',
    keywords: ['testimonial'],
    icon: 'admin-post',
    attributes: {
        example: {
            type: "string", // no default set, example is "undefined"
        }
    },
    edit(props) {
        const { attributes, setAttributes } = props;

        // If example is undefined, show Variation Picker
        if (attributes.example === undefined) {
            return (
                <MyBlockVariationPicker {...props} />
            );
        }
        // Otherwise show the Editor
        return (<div {...useBlockProps()}><h2>{attributes.example}</h2></div>);
    },
    save: ({ attributes }) => {
        return <div {...useBlockProps.save()}><h2>{attributes.example}</h2></div>;
    }
})
 

Если вы создадите приведенный выше javascript, результирующий блок позволит вам выбрать один из двух вариантов вставки:
мой / отзыв