Criar Bloco Gutenberg Personalizado – Parte 5: Configurações do Inspetor
Nas etapas anteriores, aprendemos o básico de como renderizar componentes e atributos em um bloco. Nesta etapa, vamos nos concentrar no que o WordPress (pelo menos em código) chama de Inspetor: a barra lateral do lado direito do editor. Abordaremos alguns novos componentes que fazem sentido colocar na barra lateral e como lidar com eles.
Inspetor/componente da barra lateral
Para inserir suas configurações personalizadas e HTML na barra lateral do Inspetor, você envolverá tudo dentro de um componente chamado InspectorControls. Tudo o que você colocar dentro deste componente será exibido na barra lateral e não dentro do próprio bloco/editor. Você basicamente pode colocar o componente e seu conteúdo em todos os lugares no retorno da editfunção.
Além disso, você lidaria com as configurações dentro da barra lateral como elas estavam dentro do bloco. Cada configuração requer um atributo e você carrega e atualiza os atributos da mesma maneira.
Vamos primeiro dar uma olhada rápida em como a barra lateral do nosso bloco se parece (quando nosso bloco está ativo no editor), com base no código que acabamos na etapa anterior.
Todos os blocos irão, por padrão, mostrar o ícone, nome e descrição do bloco, e a seção Avançado – recolhida. Dentro do Advanced você encontrará uma entrada de texto para fornecer a classe CSS para o bloco.
Adicionando uma seção da barra lateral e algumas configurações
A barra lateral é dividida em seções (referidas como painéis no código) e para um design e funcionalidade ideais (incluindo a funcionalidade de recolhimento aberto), devemos usar os componentes do WordPress para gerar painéis corretamente.
Use o componente PanelBodypara adicionar uma seção (aquelas que você pode abrir ou recolher), encontrada no wp.componentspacote. O componente aceita alguns adereços, por exemplo, para o título e se o painel deve ou não ser aberto ou fechado como padrão. Você também pode fornecer classe personalizada, ícone e anexar uma função de evento ao gatilho abrir-fechar.
Dentro PanelBodydo WordPress, recomenda-se usar o PanelRowcomponente que atua como contêineres genéricos dentro do painel – para garantir a racionalização do design. Este componente aplica automaticamente alguns estilos de margem e linha flexível para o seu conteúdo. Por causa do flex-direction: rowestilo " " você deve envolver cada configuração dentro de um PanelRow. Ou você pode ignorá-lo completamente e assumir a responsabilidade de estilizá-lo você mesmo com divs e tal.
Adicionando um painel e configurações
Vamos adicionar um painel de barra lateral para o nosso bloco com algumas configurações dentro, só para ver na prática. Adicionaremos um controle de alternância, uma entrada de seleção, um seletor de cores e uma caixa de seleção – apenas para obter alguma experiência com diferentes tipos de componentes de entrada. Deixei o conteúdo do bloco (com os dois RichTexts) e a savefunção como antes.
const { registerBlockType } = wp.blocks;
const { RichText, InspectorControls } = wp.blockEditor;
const { ToggleControl, PanelBody, PanelRow, CheckboxControl, SelectControl, ColorPicker } = wp.components;
registerBlockType('awp/firstblock', {
title: 'My first block',
category: 'common',
icon: 'smiley',
description: 'Learning in progress',
keywords: ['example', 'test'],
attributes: {
myRichHeading: {
type: 'string',
},
myRichText: {
type: 'string',
source: 'html',
selector: 'p'
},
toggle: {
type: 'boolean',
default: true
},
favoriteAnimal: {
type: 'string',
default: 'dogs'
},
favoriteColor: {
type: 'string',
default: '#DDDDDD'
},
activateLasers: {
type: 'boolean',
default: false
}
},
edit: (props) => {
const { attributes, setAttributes } = props;
return (<div>
<InspectorControls>
<PanelBody
title="Most awesome settings ever"
initialOpen={true}
>
<PanelRow>
<ToggleControl
label="Toggle me"
checked={attributes.toggle}
onChange={(newval) => setAttributes({ toggle: newval })}
/>
</PanelRow>
<PanelRow>
<SelectControl
label="What's your favorite animal?"
value={attributes.favoriteAnimal}
options={[
{label: "Dogs", value: 'dogs'},
{label: "Cats", value: 'cats'},
{label: "Something else", value: 'weird_one'},
]}
onChange={(newval) => setAttributes({ favoriteAnimal: newval })}
/>
</PanelRow>
<PanelRow>
<ColorPicker
color={attributes.favoriteColor}
onChangeComplete={(newval) => setAttributes({ favoriteColor: newval.hex })}
disableAlpha
/>
</PanelRow>
<PanelRow>
<CheckboxControl
label="Activate lasers?"
checked={attributes.activateLasers}
onChange={(newval) => setAttributes({ activateLasers: newval })}
/>
</PanelRow>
</PanelBody>
</InspectorControls>
<RichText
tagName="h2"
placeholder="Write your heading here"
value={attributes.myRichHeading}
onChange={(newtext) => setAttributes({ myRichHeading: newtext })}
/>
<RichText
tagName="p"
placeholder="Write your paragraph here"
value={attributes.myRichText}
onChange={(newtext) => setAttributes({ myRichText: newtext })}
/>
</div>
);
},
save: (props) => {
const { attributes } = props;
return (<div>
<RichText.Content
tagName="h2"
value={attributes.myRichHeading}
/>
<RichText.Content
tagName="p"
value={attributes.myRichText}
/>
</div>
);
}
});
Como sempre, começamos desestruturando os componentes e funções que queremos usar. No attributesinterior registerBlockType(), definimos um atributo por entrada e correspondemos ao tipo – por exemplo, o controle de alternância espera um booleano e, como os valores do menu suspenso são strings, esse atributo também deve ser um tipo string.
Na linha #41iniciamos o InspectorControlscomponente, e tudo a partir desse ponto até a linha #80aparecerá na barra lateral. O resto aparecerá dentro do próprio editor, e não fiz nenhuma alteração lá.
Dentro, primeiro criamos um painel com PanelBodye com o prop initialOpendefinido como true, dizemos ao Gutenberg que este painel deve ser aberto por padrão. E então cabe a nós o que adicionar dentro de cada arquivo PanelRow.
Para o componente ToggleControl, usamos as mesmas props que fizemos antes com entradas de texto, exceto que, em vez da prop value, fornecemos o valor do atributo dentro da prop checked. Isso se aplica a qualquer entrada que espere um atributo marcado em HTML simples, por exemplo, caixas de seleção. Para botões de opção, você usaria o prop selected, pois isso é o que você usaria em HTML simples também. Tenha em mente que o atributo para esta entrada deve ser do tipo boolean.
Quanto CheckboxControlao manuseio de uma caixa de seleção singular, funciona exatamente da mesma forma que ToggleControl– retorna um booleano, esteja ou não marcado.
O SelectControlgera uma lista suspensa de seleção e espera as opções possíveis como uma matriz no prop options. Cada elemento deve ser um objeto com as propriedades labele value. O mesmo se aplica a caixas de seleção e botões de opção (RadioControl). Em circunstâncias normais, você provavelmente geraria as opções como uma variável fora da saída HTML.
Você pode notar que ColorPickerfunciona um pouco diferente dos outros, pois este é um componente mais complexo e não uma entrada HTML padrão. Forneça o prop colorpara a cor salva e, em vez de onChange(dispara uma vez ao clicar, mas também toda vez que o valor é alterado ao arrastar – o que pode resultar em muitos incêndios) use onChangeComplete. A prop retornada neste evento também é um objeto onde precisamos decidir qual parte queremos salvar em nosso atributo. Neste exemplo queremos salvar o valor hexadecimal (sem alfa/opacidade), então dentro setAttributes()extraímos a hexpropriedade do colorobjeto retornado. É também por isso que adicionamos a propriedadedisableAlphacomo remover a interface do usuário do canal alfa (para controlar a opacidade), pois não faz sentido oferecer isso ao usuário quando nunca salvamos o valor da opacidade.
Cada um dos componentes tem um labelprop disponível, exceto o colorpicker. Se você quiser produzir um rótulo ou texto antes dele, precisará mexer no HTML ou no estilo para garantir que fique bom.
Obviamente, você pode adicionar quantos painéis quiser, basta adicionar outro PanelBodycomponente após o anterior.
Se você estiver interessado em aprender mais sobre como adicionar configurações de bloco, tenho tutoriais separados para configurações e componentes mais complexos para o Inspector; Como adicionar uma seleção de imagem e como adicionar um painel de configurações de cores.
Manipulaçãosave
Deixei a savefunção como estava antes. Depende de você e tudo depende do que as configurações controlam na saída. Você já sabe como obter os valores de cada configuração. Como exemplo, vamos supor que o atributo booleano activateLaserscontrole se um elemento HTML personalizado é renderizado ou não. Se o atributo for trueum div deve ser gerado, caso contrário não. Você pode fazer isso com o if-check tradicional ou usar o inline ife o &&operador do JSX. Leia mais sobre isso no guia do React para renderização condicional.
save: (props) => {
const { attributes } = props;
return (<div>
<RichText.Content
tagName="h2"
value={attributes.myRichHeading}
/>
<RichText.Content
tagName="p"
value={attributes.myRichText}
/>
{attributes.activateLasers &&
<div className="lasers">Lasers activated</div>
}
</div>
);
}
Como usamos RichTextessa saída não seria visível no editor, mas aparecerá no frontend.
Você encontrará mais componentes no repositório do wp.components Github. A maioria dessas pastas deve fornecer um leia-me com alguma documentação sobre como usá-lo. Eu aprendi a maior parte disso olhando neste repositório e também nos principais componentes do WordPress como eles fizeram isso.
Na próxima etapa da série, vamos nos concentrar em como controlar a barra de ferramentas do bloco. Aprenderemos como lidar, por exemplo, com o alinhamento de um bloco e adicionar botões personalizados à barra de ferramentas.

