Search code examples
javascriptreactjswordpresswordpress-gutenberggutenberg-blocks

How to use :hover in Gutenberg custom blocks?


So I have a problem with building block that has background-color attribute and the user can change it using ColorPalette component. When creating a custom block in gutenberg we need 2 functions inside of registerBlockType: save and edit.

I'm using inline CSS to generate correct styles for each block. Here is my edit() function:

edit: ( { attributes, setAttributes } ) => {
   /*
    some code
   */

    const [ isHover, setIsHover ] = useState( false );

    const handleMouseEnter = () => {
        setIsHover( true );
    };
    
    const handleMouseLeave = () => {
        setIsHover( false );
    };

    return <div { ...blockProps }>
        <InspectorControls key="settings" group="styles">
            // controls are here
        </InspectorControls>
        <InnerBlocks />
        <button style={ { 
            backgroundColor: isHover ? attributes.btnBgColorHover : attributes.btnBgColor,
            color: isHover ? attributes.btnTextColorHover : attributes.btnTextColor } }
            onMouseEnter={ handleMouseEnter } onMouseLeave={ handleMouseLeave }>
            <span class="material-symbols-outlined">
                expand_more
            </span>
        </button>
    </div>
}

as you can see I'm using isHover state and onMouseEnter and onMouseLeave to set the correct color selected by the user. And now I can't use it in save function because content rendered by save function does not support things like onClick, onMouseEnter, onMouseLeave etc (even if I define these inside of save, gutenberg just renders the element using content returned by save).

    save: ( { attributes } ) => {
        return <div { ...blockProps }>
            <InnerBlocks.Content />
            <button style={ { 
                backgroundColor: isHover ? attributes.btnBgColorHover : attributes.btnBgColor,
                color: isHover ? attributes.btnTextColorHover : attributes.btnTextColor } }
                onMouseEnter={ handleMouseEnter } onMouseLeave={ handleMouseLeave }>
                <span class="material-symbols-outlined">
                    expand_more
                </span>
            </button>
        </div>
    }

How to build a block with background color on hover (or just a color on hover) so the user will be able to change it?


Solution

  • So! If you want to allow users to choose the color on hover state you do not need any onMouseEnter & onMouseLeave events.

    All I had to do was to declare CSS variables in inline styles and use these variables in external CSS sheets.

    save: ( { attributes } ) => {
        return <div { ...blockProps }>
            <InnerBlocks.Content />
            <button style={ "--ebl-btn-bg-hover": attributes.btnBgColorHover }>
                <span class="material-symbols-outlined">
                    expand_more
                </span>
            </button>
        </div>
    }
    

    and then in external CSS (scss used here):

    .ebl_card {
        &__read-more {
            &-btn {
                &:hover {
                    background-color: var( --ebl-btn-bg-hover );
                }
            }
        }
    }