Как избежать упаковки ClassNames 【Gutenberg RichText】 - PullRequest
0 голосов
/ 04 ноября 2019

Я добавил кнопки для текста большого, среднего и малого размера в блоке Gutenberg RichText с помощью блоков create-guten. Эти кнопки добавляют ClassName к выделенному тексту при нажатии. Они работают, но когда я нажимаю кнопку, которая уже имеет ClassName, она оборачивает другое ClassName. Я имею в виду, что они имеют двойные или тройные ClassNames ..

Как показано ниже ..

<span class="text-small"><span class="text-large">text<span><span>

Как я могу удалить предыдущее ClassName, когда я щелкаю по тому, которое уже имеет ClassName?

Спасибо.

     //Large Text
    var TextLarge = function( props ) {
        return wp.element.createElement(
            wp.editor.RichTextToolbarButton, {
            icon: <svg xmlns="svg".../></svg>,
                title: 'Large Text,
                onClick: function() {
                    props.onChange( wp.richText.toggleFormat(
                        props.value,
                        { type: 'my-blocks/text-large' }
                    ) );
                },
                isActive: props.isActive,
            }
        );
    }
    var LButton = compose(
        withSelect( function( select ) {
            return {
                selectedBlock: select( 'core/editor' ).getSelectedBlock()
            }
        } ),
        ifCondition( function( props ) {
            return (
                props.selectedBlock &&
                props.selectedBlock.name !== 'core/heading'
            );
        } )
    )( TextLarge );

    wp.richText.registerFormatType(
        'my-blocks/text-large', {
            title: 'Large Text',
            tagName: 'span',
            className: 'text-large',
            edit: LButton,
        }
    );

    //Medium Text
    var TextMedium = function( props ) {
        return wp.element.createElement(
            wp.editor.RichTextToolbarButton, {
            icon: <svg xmlns="svg".../></svg>,
                title: 'Medium Text',
                onClick: function() {
                    props.onChange( wp.richText.toggleFormat(
                        props.value,
                        { type: 'my-blocks/text-medium' }
                    ) );
                },
                isActive: props.isActive,
            }
        );
    }
    var MButton = compose(
        withSelect( function( select ) {
            return {
                selectedBlock: select( 'core/editor' ).getSelectedBlock()
            }
        } ),
        ifCondition( function( props ) {
            return (
                props.selectedBlock &&
                props.selectedBlock.name !== 'core/heading'
            );
        } )
    )( TextMedium );

    wp.richText.registerFormatType(
        'my-blocks/text-medium', {
            title: 'Medium Text',
            tagName: 'span',
            className: 'text-medium',
            edit: MButton,
        }
    );

    //Small Text
    var TextSmall = function( props ) {
        return wp.element.createElement(
            wp.editor.RichTextToolbarButton, {
            icon: <svg xmlns="svg".../></svg>,
                title: 'Small Text',
                onClick: function() {
                    props.onChange( wp.richText.toggleFormat(
                        props.value,
                        { type: 'my-blocks/text-small' }
                    ) );
                },
                isActive: props.isActive,
            }
        );
    }
    var SButton = compose(
        withSelect( function( select ) {
            return {
                selectedBlock: select( 'core/editor' ).getSelectedBlock()
            }
        } ),
        ifCondition( function( props ) {
            return (
                props.selectedBlock &&
                props.selectedBlock.name !== 'core/heading'
            );
        } )
    )( TextSmall );

    wp.richText.registerFormatType(
        'my-blocks/text-small', {
            title: 'Small Text',
            tagName: 'span',
            className: 'text-small',
            edit: SButton,
        }
    );


1 Ответ

1 голос
/ 04 ноября 2019

Ниже приведена логика, которую я придумал. Предположим, что нажата кнопка Medium :

  1. Зацикливание активных форматов из текущего значения RichText и удаление Small и Large если найденЭто делается с помощью функции wp.richText.removeFormat. Удаление Medium не позволит нам отслеживать активное и неактивное состояние и, следовательно, препятствует функциональности переключения.
  2. Вызовите wp.richText.toggleFormat, поэтому мы можем получить либо Medium формат или нет.

Моя функция выглядит так (заметьте, я не так хорош в названии: D):

function removeActiveFormatsAndToggleSpecific(props, formatNameToSkip) {
   var propVal = props.value;
    var formattedItem = propVal;
    if (propVal.activeFormats.length) {
        for (var i = 0; i < propVal.activeFormats.length; i++) {
            var typeOfFormat = propVal.activeFormats[i].type;
            if (typeOfFormat !== formatNameToSkip) {
                formattedItem = wp.richText.removeFormat(formattedItem, typeOfFormat);
            }
        }
    }
    formattedItem = wp.richText.toggleFormat(
        formattedItem,
        { type: formatNameToSkip });
    return formattedItem;
}

Эта функция будет вызываться в каждом отдельном props.onChange из 3 кнопок, поэтому вам придется изменить свой код следующим образом:

var TextLarge = function( props ) {
    return wp.element.createElement(
        wp.editor.RichTextToolbarButton, {
        icon: <svg xmlns="svg".../></svg>,
            title: 'Large Text',
            onClick: function() {
                props.onChange(removeActiveFormatsAndToggleSpecific(props, 'my-blocks/text-large'));
            },
            isActive: props.isActive,
        }
    );
}

Вам придется изменить функцию onClick Small и Medium также.

props.onChange вызывается только один раз за внутренний цикл, с которым я не знаком, но я подозреваю, что он устанавливается по реакции или абстракции WordPress. В любом случае, мне не удалось внести изменения с помощью нескольких вызовов onChange. В итоге он выполнил только последний вызов, поэтому мне пришлось поместить все в одну функцию.

Несколько рекомендаций:

  • Я написал код в ES5, как код, который вынаписал выше, но я бы предложил использовать @ wordpress / scripts , что позволяет легко настроить сборку веб-пакета и использовать синтаксис ESNext.
  • Я бы также порекомендовал установить и импортировать всепакеты, такие как @wordpress/rich-text и @wordpress/editor, так что вы можете искать отдельные функции. Импорт невозможен без этапа сборки, поэтому, пожалуйста, сначала реализуйте первый.
  • У меня установлен плагин Gutenberg , который предоставляет последний код React, который должен быть реализован в будущих итерациях. WordPress. Это дает полезные советы, и многие ошибки консоли из основного кода очищаются. Это также дает подсказки об устаревшей функциональности. Рано или поздно вы придете к этим сообщениям, поэтому я бы предложил использовать их сегодня :) Вот что сказано о вашем коде: Gutenberg warnings
...