Przyjrzeliśmy się Stosowanie formatów do treści posta za pomocą registerFormatType. Ale co, jeśli chcemy dodać dodatkowe kolory do naszego zakreślacza?
W tym przewodniku zamierzamy rozszerzyć to, nad czym pracowaliśmy wcześniej, i dodać modalne wyskakujące okienko, które pozwoli nam wybrać kolor podświetlenia.
Zauważ, że w tym wyskakującym okienku modalnym może zawierać dowolną liczbę elementów, w tym niestandardowe ikony, obrazy, a nawet pola formularzy.
Cały kod użyty w tym samouczku można znaleźć w bezpłatnej wtyczce „Highlighter".
Stosowanie typu formatu za pomocą wtyczki Highlighter.
Powyższy film pokazuje wtyczkę Highlighter, nasz typ formatu i wyskakujące okienko w akcji. Przejdźmy do tego.
Warunki wstępne
- Przeczytaj przewodnik Tworzenie wtyczki do edytora bloków WordPress (Gutenberg), aby rozpocząć tworzenie wtyczki.
- Wykonaj czynności opisane w artykule Formatowanie treści posta za pomocą registerFormatType.
- Opcjonalnie pobierz darmową wtyczkę „Highlighter” z GitHub i spójrz na plik
/src/formats/highlight-colours.js
Utwórz modalny
Aby utworzyć modalny popover, użyjemy stanu, aby określić, czy przycisk został kliknięty, czy nie. Aby to zrobić, zaimportuj useStatez '@wordpress/element'.
W komponencie przycisku, nad instrukcją return, użyjemy tego do ustawienia stanu początkowego i utworzenia naszych funkcji ustawiających stan.
// State to show popover.
const [ showPopover, setShowPopover ] = useState( false );
Następnie zmienimy zdarzenie kliknięcia przycisku, aby ustawić stan.
onClick={() => {
setShowPopover( true );
} }
Teraz, gdy stan jest ustawiony, możemy użyć tego do wywołania popover. Najpierw zaimportuj URLPopoverkomponent z '@wordpress/block-editor'. Następnie w instrukcji return pod przyciskiem dodaj warunek, który pobiera showPopoverzmienną i renderuje URLPopover.
return (<>
<RichTextToolbarButton
icon='edit'
onClick={() => {
setShowPopover( true );
} }
title={ __( 'Highlight', 'wholesome-highlighter') }
/>
{ showPopover && (<URLPopover
className="components-inline-color-popover"
onClose={ () => setShowPopover( false) }
>
...
</URLPopover>) }
</>)
Zauważ, że otoczyliśmy oba komponenty pustymi znacznikami <></>. Służą one celowi <Fragment>tagu i umożliwiają dwóm komponentom JSX renderowanie bez wyprowadzania znaczników na interfejsie.
Dodaj modalną zawartość popover
Ponieważ jest to wtyczka do zakreślania, zaimportujemy ColorPaletteją '@wordpress/block-editor'i umieścimy w modalnym popoverze.
<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>
Powyższy kod użyje domyślnej palety kolorów w popoverze. Potrzeba więcej pracy, aby dodać nasze niestandardowe kolory.
Kodeks w całości
Aby zademonstrować, w jaki sposób dodajemy niestandardowe kolory do palety, najlepiej jest pokazać pełny kod. Możesz również pobrać ten plik wraz z najnowszymi aktualizacjami z 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' ),
}
);
Pamiętaj, aby ustawić kolory dla niestandardowych kolorów w /src/style.scsspliku, i masz to, format pisaka z zakreślaczem z paletą kolorów.
.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;
}
}
Ikona wybranego koloru wyróżnienia
- Dodaj blokowy pasek boczny za pomocą InspectorControls
- Spójrz na używanie post meta pól w blokach Gutenberga
- Spójrz na użycie opcji i ustawień w blokach Gutenberg
- Spójrz na tworzenie strony opcji i ustawień za pomocą komponentów Gutenberg