В статье "Создание своего Gutenberg-блока для WordPress на основе wordpress-create-block" мы рассматривали, как создать плагин, который будет давать возможность добавить секцию типа ЧаВо (FAQ) на сайт под управлением WordPress с помощью специального Gutenberg-блока.
Здесь хотелось бы расширить этот плагин добавлением настроек в боковой панели для возможности управления цветом и выравниванием заголовка. Основываться будем на файлах с репозитория на Github.
Управление настройками блока в основной области
Итак, настройки блока могут быть видны при редактировании текста (например, жирный или курсив). Для этого используется панель инструментов, которую мы уже видели. Для настройки кнопок в ней в редакторе Гутенберг существует компонент BlockControls. Ниже на скриншоте вы видите стандартный набор настроек для абзаца.
Что касается этих настроек, их имеет смысл добавлять для RichText. В качестве разрешенных форматов к этому компоненту можно добавить такие опции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <RichText tagName="h2" value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" allowedFormats={ [ 'core/bold', 'core/italic', 'core/text-color', 'core/subscript', 'core/superscript', 'core/strikethrough', 'core/link', ] } /> |
Из всего перечисленного у нас уже есть 'core/bold'
и 'core/italic'
. Можем еще добавить 'core/text-color'
в allowedFormats
для возможности цветового выделения, а вот с помощью компонента BlockControls добавим возможность выравнивания:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <div {...blockProps}> <BlockControls> <AlignmentToolbar value={alignment} onChange={(newVal) => setAttributes({ alignment: newVal })} /> </BlockControls> <RichText tagName='h2' allowedFormats={['core/bold', 'core/italic', 'core/text-color']} value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" style={{ textAlign: alignment }} /> </div> |
Тут не весь код: не хватает объявления атрибута alignment
и импорта компонентов BlockControls
и AlignmentToolbar
. Полный код вы найдете ниже.
Те опции, которые мы добавили, дадут нам возможность выбрать такие настройки:
Настройки боковой панели
Боковая панель настроек находится справа от вашего основного контента и изменяется при выборе разных блоков. Предназначена она для настроек на уровне блока и обычно отвечает за форматирование внутри выделенного блока. Может быть разделена на настройки и стили.
Чтобы добавить стили в виде цвета и отступов (margin
, padding
), нужно добавить такой код в блок supports
файла block.json:
1 2 3 4 5 6 7 8 9 10 11 | { . . "supports": { "color": {}, "spacing": { "margin": true, "padding": true } } } |
Все стили будут автоматически применяться для вашего блока при изменении любых значений, но тут нужно учитывать, что block.json описывает стили основного компонента, но никак не вложенного(-ых). Поэтому нам придется воспользоваться настройками, заданными самостоятельно.
Для управления боковой панелью существует специальный компонент InspectorControls
, который должен выводится для того элемента, к которому они относятся. Соответственно, настройки должны быть доступны при выделении соответствующего блока (главного или вложенных).
Также для добавления раздела настроек вам понадобится компонент Panel
и/или PanelBody
, который находится в пакете wp.components
(то есть вам нужно импортировать PanelBody
из wp.components
). Компонент позволяет открыть или свернуть настройки (initialOpen={true}
для открытой панели), а также позволяет задать заголовок. Вы также можете определить собственный класс, иконку и прикрепить функцию события к триггеру открытия-закрытия.
Для размещения в PanelBody
вы можете использовать такие компоненты:
- ToggleControl
- CheckboxControl
- SelectControl
- RadioControl
- ColorPicker
- ColorPalette и др.
Вы найдете больше компонентов в wp.components
репозитории Github.
Цветовая палитра
Поскольку в этой статье мы размещаем прежде всего цветовые настройки, такой код позволит нам вывести цветовую палитру (ColorPalette
) для управления цветом текста и фона для нашего аккордеона.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import { __ } from '@wordpress/i18n'; import { PanelBody} from '@wordpress/components'; import { InnerBlocks, useBlockProps, RichText, BlockControls, AlignmentToolbar, InspectorControls, ColorPalette } from '@wordpress/block-editor'; import './editor.scss'; export default function Edit({ attributes, setAttributes }) { const { heading, alignment, titleTextColor, contentTextColor, titleBgColor, contentBgColor, } = attributes; const accordionStyleVars = { "--tempo-accordion-title-bgcolor": titleBgColor, "--tempo-accordion-title-color": titleTextColor, "--tempo-accordion-font-color": contentTextColor, "--tempo-accordion-panel-background-color": contentBgColor }; const blockProps = useBlockProps({ style: accordionStyleVars }); return ( <div {...blockProps}> <BlockControls> <AlignmentToolbar value={alignment} onChange={(newVal) => setAttributes({ alignment: newVal })} /> </BlockControls> <RichText tagName='h2' allowedFormats={['core/bold', 'core/italic', 'core/text-color']} value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" style={{ textAlign: alignment }} /> <InspectorControls> <PanelBody title={__('Accordion Block Settings', 'accordion-block')} initialOpen={true} > <fieldset> <legend className="blocks-base-control__label"> { __( 'Content Text color', 'accordion-block' ) } </legend> <ColorPalette value={ contentTextColor } onChange={ ( hexColor ) => setAttributes( { contentTextColor: hexColor } ) } /> </fieldset> <fieldset> <legend className="blocks-base-control__label"> { __( 'Content Background color', 'accordion-block' ) } </legend> <ColorPalette value={ contentBgColor } onChange={ ( hexColor ) => setAttributes( { contentBgColor: hexColor } )} /> </fieldset> </PanelBody> </InspectorControls> <InnerBlocks allowedBlocks={['tempo/panel']} template={[ ['tempo/panel', { title: __("Accordion Item Title 1", 'accordion-block') }], ['tempo/panel', { title: __("Accordion Item Title 2", 'accordion-block') }] ]} /> </div> ); } |
Код для save.js вы найдете ниже.
Такой код даст нам настройки вида
Цвета #222222
и transparent
заданы в файле index.js или в block.json в качестве дефолтных.
Учтите, что вам нужно сначала обязательно импортировать используемые компоненты из 2-х пакетов:
1 2 | import { PanelBody} from '@wordpress/components'; import { InspectorControls, ColorPalette } from '@wordpress/block-editor'; |
Ошибка при импорте компонента
Поскольку вы не всегда можете знать, какой пакет содержит какие компоненты, при разработке блока для редактора Гутенберг вы можете увидеть ошибку в консоли типа Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.[missing argument].
Эта ошибка может возникнуть, если вы попытаетесь импортировать несуществующий компонент. Вам нужно посмотреть в репозитории компонентов, из какого пакета берется нужный вам и импортировать его правильно. Например, так:
1 2 3 | import { PanelBody, RangeControl} from '@wordpress/components'; import { InnerBlocks, useBlockProps, RichText, InspectorControls, ColorPalette, PanelColorSettings, ContrastChecker } from '@wordpress/block-editor'; |
Панель цветовых настроек
Вместо таких панелей, которые занимают довольно много места, мы можем вывести компонент PanelColorSettings
, который будет компактней за счет того, что изначально цветовая палитра спрятана, но при этом вы видите цвет текста и фона блока.
В index.js нам нужно добавить атрибут alignment
для BlockControls, о котором речь шла выше + описать атрибуты titleTextColor
, contentTextColor
, titleBgColor
и contentBgColor
, которые мы уже частично использовали в компоненте ColorPalette
для возможности задать цвет текста и фона отдельно для заголовка и основного текста.
Код в файле index.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import { registerBlockType } from '@wordpress/blocks'; registerBlockType(metadata.name, { attributes: { heading: { type: 'string', source: 'html', selector: 'h2', }, alignment: { type: 'string', }, titleTextColor: { type: "string", default: '#222222' }, contentTextColor: { type: "string", default: '#222222' }, titleBgColor: { type: "string", default: 'transparent' }, contentBgColor: { type: "string", default: 'transparent' }, }, edit: Edit, save, }); |
Поскольку изначально мы использовали для блока стили, основанные на CSS-переменных, будем использовать их для того, чтобы изменить цвета всего блока. Все переменные были объявлены для :root
. Однако, если мы перенесем их значение на уровень стиля блока, то это наверняка переопределит цвета по умолчанию. Поэтому нам нужно встроить инлайн-стили в наших файлах edit.js и save.js для основного компонента.
Код в файле edit.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | import { __ } from '@wordpress/i18n'; import { InnerBlocks, useBlockProps, RichText, BlockControls, AlignmentToolbar, InspectorControls, PanelColorSettings, ContrastChecker } from '@wordpress/block-editor'; import './editor.scss'; export default function Edit({ attributes, setAttributes }) { const { heading, alignment, titleTextColor, contentTextColor, titleBgColor, contentBgColor, } = attributes; const accordionStyleVars = { "--tempo-accordion-title-bgcolor": titleBgColor, "--tempo-accordion-title-color": titleTextColor, "--tempo-accordion-font-color": contentTextColor, "--tempo-accordion-panel-background-color": contentBgColor }; const blockProps = useBlockProps({ style: accordionStyleVars }); return ( <div {...blockProps}> <BlockControls> <AlignmentToolbar value={alignment} onChange={(newVal) => setAttributes({ alignment: newVal })} /> </BlockControls> <RichText tagName='h2' allowedFormats={['core/bold', 'core/italic', 'core/text-color']} value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" style={{ textAlign: alignment }} /> <InspectorControls> <PanelColorSettings title={__('Panel Title Color Settings', 'accordion-block')} icon="art" initialOpen={false} colorSettings={[ { value: titleTextColor, onChange: (hexColor) => setAttributes({ titleTextColor: hexColor }), label: __('Title Font Color', 'accordion-block'), }, { value: titleBgColor, onChange: (hexColor) => setAttributes({ titleBgColor: hexColor }), label: __('Title Background Color', 'accordion-block'), } ]}> <ContrastChecker isLargeText="false" textColor={titleTextColor} backgroundColor={titleBgColor} /> </PanelColorSettings> <PanelColorSettings title={__('Panel Content Color Settings', 'accordion-block')} icon="art" initialOpen={false} colorSettings={[ { value: contentTextColor, onChange: (hexColor) => setAttributes({ contentTextColor: hexColor }), label: __('Content Font Color', 'accordion-block'), }, { value: contentBgColor, onChange: (hexColor) => setAttributes({ contentBgColor: hexColor }), label: __('Content Background Color', 'accordion-block'), } ]}> <ContrastChecker isLargeText="false" textColor={contentTextColor} backgroundColor={contentBgColor} /> </PanelColorSettings> </InspectorControls> <InnerBlocks allowedBlocks={['tempo/panel']} template={[ ['tempo/panel', { title: __("Accordion Item Title 1", 'accordion-block') }], ['tempo/panel', { title: __("Accordion Item Title 2", 'accordion-block') }] ]} /> </div> ); } |
Визуально в админке WordPress это выглядит так:
Код в файле save.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import { RichText, InnerBlocks, useBlockProps } from '@wordpress/block-editor'; export default function save({ attributes }) { const { heading, alignment, titleTextColor, contentTextColor, titleBgColor, contentBgColor } = attributes; const accordionStyleVars = { "--tempo-accordion-title-bgcolor": titleBgColor, "--tempo-accordion-title-color": titleTextColor, "--tempo-accordion-font-color": contentTextColor, "--tempo-accordion-panel-background-color": contentBgColor }; const blockProps = useBlockProps.save({ style: accordionStyleVars }); return ( <div {...blockProps}> {heading?.trim().length > 0 && (<RichText.Content tagName="h2" value={heading} style={ { textAlign: alignment } } />)} <InnerBlocks.Content /> </div> ) }; |
После сохранения блока на сайте мы увидим такой аккордеон:
Файлы с настройками вы можете найти на Github.
В нашем плагине мы не передаем настройки блока от родительского блока к дочерним потому, что используем CSS-переменные для изменения цвета. Однако вам может понадобится это сделать в том случае, если вы меняете вид блока в зависимости от какой-то из настроек. Пример такой передачи данных вы найдете в статье Как передавать данные между блоками Gutenberg с помощью контекста блока.