Use um pop-up modal para adicionar atributos adicionais com registerBlockFormat
Demos uma olhada em Aplicar formatos ao seu conteúdo de postagem com registerFormatType. Mas e se quisermos adicionar cores adicionais à nossa caneta marcadora?
Neste guia, vamos expandir o que trabalhamos anteriormente e adicionar um pop-up modal que nos permitirá selecionar uma cor de destaque.
Observe que neste pop-up modal pode conter qualquer número de itens, incluindo ícones personalizados, imagens ou até mesmo campos de formulário.
Todo o código usado neste tutorial pode ser encontrado no plugin ‘Highlighter’ gratuito.
Aplicando um tipo de formato usando o plugin Highlighter.
O vídeo acima mostra o plugin Highlighter, nosso tipo de formato e o pop-up em ação. Vamos pular para ele.
Pré-requisitos
- Leia o guia Criando um Plugin para o Editor de Blocos do WordPress (Gutenberg) para que você possa ter uma vantagem inicial na criação do plugin.
- Siga as etapas no artigo Formatar seu conteúdo de postagem com registerFormatType.
- Opcionalmente , baixe o plug-in ‘Highlighter’ gratuito do GitHub e veja o arquivo
/src/formats/highlight-colours.js
Crie o Modal
Para criar o popover modal, vamos usar state, para determinar se o botão foi clicado ou não. Para fazer essa importação useStatede '@wordpress/element'.
Dentro do componente de botão, acima da instrução de retorno, vamos usar isso para definir um estado inicial e criar nossas funções de configuração de estado.
// State to show popover.
const [ showPopover, setShowPopover ] = useState( false );
Vamos então alterar o evento click do botão para definir o estado.
onClick={() => {
setShowPopover( true );
} }
Agora que o estado está definido, podemos usar isso para acionar o popover. Primeiro importe o URLPopovercomponente do '@wordpress/block-editor'. Em seguida, dentro da instrução return, sob o botão, adicione uma condicional que receba a showPopovervariável e renderize o arquivo URLPopover.
return (<>
<RichTextToolbarButton
icon='edit'
onClick={() => {
setShowPopover( true );
} }
title={ __( 'Highlight', 'wholesome-highlighter') }
/>
{ showPopover && (<URLPopover
className="components-inline-color-popover"
onClose={ () => setShowPopover( false) }
>
...
</URLPopover>) }
</>)
Observe que envolvemos os dois componentes com tags vazias <></>. Eles servem ao propósito da <Fragment>tag e permitem que dois componentes JSX sejam renderizados sem gerar marcação no frontend.
Adicione o conteúdo popover modal
ColorPaletteComo este é um plugin de destaque, vamos importar '@wordpress/block-editor'e colocar isso no popover modal.
<URLPopover
className="components-inline-color-popover"
onClose={ () => setShowPopover( false) }
>
<ColorPalette
onChange={ (color) => {
setShowPopover( false );
if (color) {
onChange(
applyFormat( value, {
type: name,
attributes: { style: `background-color: ${color};` },
}
));
} else {
onChange( toggleFormat( value, { type: name }) );
}
} }
/>
</URLPopover>
O código acima usará a paleta de cores padrão no popover. Mais trabalho será necessário para adicionar nossas cores personalizadas.
O código completo
Para demonstrar como adicionamos cores personalizadas à paleta, provavelmente é melhor mostrar o código completo. Você também pode baixar este arquivo, juntamente com as atualizações mais recentes do Github.
import { ColorPalette, RichTextToolbarButton, URLPopover } from '@wordpress/block-editor';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Icon } from '@wordpress/icons';
import { applyFormat, registerFormatType, toggleFormat, useAnchorRef } from '@wordpress/rich-text';
import '../style.scss';
const name = 'wholesome/highlighter';
const cssClass = 'wholesome-highlight';
const HighlighterButton = (props) => {
const { contentRef, isActive, onChange, value } = props;
const { activeFormats } = value;
const anchorRef = useAnchorRef( { ref: contentRef, value } );
const highlighterIcon = <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.2186 3.31061C13.7838 2.89252 13.0834 2.89708 12.6543 3.32078L9.22512 6.70711C9.17494 6.75668 9.13068 6.80978 9.09236 6.86558L7.36613 8.57021L11.393 12.4419L16.362 7.50771L16.6812 7.1925C17.1103 6.76879 17.1056 6.08638 16.6708 5.66828L14.2186 3.31061Z" fill="black"/>
<path d="M6.81914 9.10588L10.8041 12.9457L9.79592 13.9391C9.42424 14.3053 8.84982 14.3575 8.42039 14.0938L7.83675 13.8883L7.01822 14.6819L5.03321 12.7381L5.86163 11.9349L5.67624 11.454C5.39121 11.0373 5.43547 10.4692 5.811 10.0992L6.81914 9.10588Z" fill="black"/>
<path d="M5.11329 13.6189L6.13911 14.5945L5.70907 15L4 14.592L5.11329 13.6189Z" fill="black"/>
</svg>;
const [ showPopover, setShowPopover ] = useState( false );
const [ activeColor, setActiveColor ] = useState( false );
const colors = [
{ name: 'Yellow', color: '#fff300' },
{ name: 'Green', color: '#79fe0c' },
{ name: 'Blue', color: '#4af1f2' },
{ name: 'Purple', color: '#df00ff' },
{ name: 'Red', color: '#ff2226' },
{ name: 'Orange', color: '#ff7b19' },
{ name: 'Pink', color: '#ff70c5' },
];
const getActiveColor = () => {
const formats = activeFormats.filter( format => name === format['type'] );
if (formats.length > 0) {
const format = formats[0];
const { attributes, unregisteredAttributes } = format;
let atts = unregisteredAttributes;
if (attributes && attributes.length) {
atts = attributes;
}
if (! atts) {
if (activeColor) {
return { backgroundColor: activeColor };
}
return;
}
if (atts.hasOwnProperty('class')) {
const parts = atts.class.split( '--' );
const colorName = parts[ parts.length - 1 ];
const selectedColor = colors.filter( item => colorName === item.name.toLowerCase() )[0];
return { backgroundColor: selectedColor.color };
} else if (atts.hasOwnProperty('style')) {
const { style } = atts;
const parts = style.split( ': ' );
const selectedColor = parts[ parts.length - 1 ].replace( ';', '' );
return { backgroundColor: selectedColor };
}
}
};
return (<>
<RichTextToolbarButton
icon={
<>
<Icon icon={ highlighterIcon } />
{ isActive && (<span
className="format-library-text-color-button__indicator"
style={ getActiveColor() }
/>) }
</>
}
key={ isActive? 'text-color': 'text-color-not-active' }
name={ isActive? 'text-color': undefined }
onClick={ () => {
setShowPopover( true );
} }
title={ __( 'Highlight', 'wholesome-highlighter') }
/>
{ showPopover && (<URLPopover
anchorRef={ anchorRef }
className="components-inline-color-popover"
onClose={ () => setShowPopover( false) }
>
<ColorPalette
colors={ colors }
onChange={ (color) => {
setShowPopover( false );
setActiveColor( color );
if (color) {
const selectedColor = colors.filter( item => color === item.color );
const attributes = {};
if (selectedColor.length) {
attributes.class = `${cssClass}--${selectedColor[0].name.toLowerCase()}`;
} else {
attributes.style = `background-color: ${color};`;
}
onChange(
applyFormat( value, {
type: name,
attributes,
}
));
} else {
onChange( toggleFormat( value, { type: name }) );
}
} }
/>
</URLPopover>) }
</>) };
registerFormatType(
name, {
className: cssClass,
edit: HighlighterButton,
tagName: 'mark',
title: __( 'Highlight', 'wholesome-highlighter' ),
}
);
Certifique-se de definir as cores para suas cores personalizadas no /src/style.scssarquivo, e aí está, um formato de caneta marca-texto com paleta de cores.
.wholesome-highlight {
&.wholesome-highlight--yellow {
background-color: #fff300;
}
&.wholesome-highlight--green {
background-color: #79fe0c;
}
&.wholesome-highlight--blue {
background-color: #4af1f2;
}
&.wholesome-highlight--purple {
background-color: #df00ff;
}
&.wholesome-highlight--red {
background-color: #ff2226;
}
&.wholesome-highlight--orange {
background-color: #ff7b19;
}
&.wholesome-highlight--pink {
background-color: #ff70c5;
}
}
Ícone de cor selecionada do marca-texto
- Adicione uma barra lateral de bloco com InspectorControls
- Veja o uso de meta campos post em blocos Gutenberg
- Veja como usar opções e configurações em blocos Gutenberg
- Veja como criar uma página de opções e configurações usando componentes do Gutenberg