Как избежать обертывания ClassNames 【Gutenberg RichText】

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

Как это ниже ..

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

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

Спасибо.

     //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,
        }
    );



person abms    schedule 04.11.2019    source источник


Ответы (1)


Ниже приведена логика, которую я придумал. Допустим, нажата кнопка Средняя:

  1. Переберите активные форматы из текущего значения RichText и удалите Маленький и Большой, если они найдены. Это делается с помощью функции wp.richText.removeFormat. Удаление среднего не позволит нам отслеживать активное и неактивное состояние и, следовательно, помешает переключению.
  2. Назовите wp.richText.toggleFormat, чтобы получить либо средний формат, либо его отсутствие.

Моя функция выглядит так (заметьте, я не очень хорош в именовании: 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 функцию Маленького и Среднего.

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

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

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