Använd en modal popup för att lägga till ytterligare attribut med registerBlockFormat
Vi har tittat på hur man tillämpar format på ditt inläggsinnehåll med registerFormatType. Men vad händer om vi vill lägga till ytterligare färger till vår överstrykningspenna?
I den här guiden kommer vi att utöka det vi arbetat med tidigare och lägga till en modal popup som gör att vi kan välja en höjdpunktsfärg.
Observera att i denna modala popup kan det innehålla valfritt antal objekt, inklusive anpassade ikoner, bilder eller till och med formulärfält.
All kod som används i denna handledning finns i det kostnadsfria insticksprogrammet ’Highlighter’.
Använda en formattyp med hjälp av Highlighter-plugin.
Videon ovan visar Highlighter-plugin, vår formattyp och popup-fönstret i aktion. Låt oss hoppa till det.
Förutsättningar
- Läs guiden Skapa ett plugin för WordPress Block Editor (Gutenberg) så att du kan få ett försprång med att skapa plugin.
- Följ stegen i artikeln Formatera ditt inläggsinnehåll med registerFormatType.
- Eventuellt ladda ner gratis plugin ’Highlighter’ från GitHub och titta på filen
/src/formats/highlight-colours.js
Skapa Modal
För att skapa den modala popover kommer vi att använda tillstånd för att avgöra om knappen har klickats eller inte. För att göra detta importera useStatefrån '@wordpress/element'.
Inom knappkomponenten, ovanför return-satsen, kommer vi att använda detta för att ställa in ett initialt tillstånd och skapa våra tillståndsinställningsfunktioner.
// State to show popover.
const [ showPopover, setShowPopover ] = useState( false );
Vi kommer sedan att ändra klickhändelsen för knappen för att ställa in tillståndet.
onClick={() => {
setShowPopover( true );
} }
Nu när tillståndet är inställt kan vi använda detta för att utlösa popover. Importera först URLPopoverkomponenten från '@wordpress/block-editor'. Lägg sedan till ett villkor i return-satsen, under knappen, som tar showPopovervariabeln och återger URLPopover.
return (<>
<RichTextToolbarButton
icon='edit'
onClick={() => {
setShowPopover( true );
} }
title={ __( 'Highlight', 'wholesome-highlighter') }
/>
{ showPopover && (<URLPopover
className="components-inline-color-popover"
onClose={ () => setShowPopover( false) }
>
...
</URLPopover>) }
</>)
Observera att vi har lindat de två komponenterna med tomma taggar <></>. Dessa tjänar syftet med <Fragment>taggen och tillåter två JSX-komponenter att rendera utan att mata ut markup på frontend.
Lägg till Modal Popover-innehåll
Eftersom detta är ett highlighter-plugin, kommer vi att importera ColorPalettefrån '@wordpress/block-editor'och placera detta i modal popover.
<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>
Ovanstående kod kommer att använda standardfärgpaletten i popover-fönstret. Mer arbete kommer att behövas för att lägga till våra anpassade färger.
Koden i sin helhet
För att visa hur vi lägger till anpassade färger till paletten är det förmodligen bäst att visa hela koden. Du kan också ladda ner den här filen, tillsammans med de senaste uppdateringarna från 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' ),
}
);
Se till att ställa in färgerna för dina anpassade färger i /src/style.scssfilen, och där har du det, ett överstrykningspennaformat med färgpalett.
.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;
}
}
Markera ikon för vald färg
- Lägg till en blockad sidofält med InspectorControls
- Titta på att använda post-metafält i Gutenberg-block
- Titta på hur du använder alternativ och inställningar i Gutenberg-block
- Titta på att bygga en alternativ- och inställningssida med hjälp av Gutenberg-komponenter