0

I've seen a few Gutenberg blocks, consistent between developers, where the user can define different data for different views, as this user references:

Kadence Blocks example

However their build files are, of course, minified, so I'm not sure how they are achieving this and haven't been able to find any documentation on it.

It doesn't seem to be part of the native supports config. Is this something I would have to build myself? If so, any pointers or references?

Update

This tutorial helped me add an InspectorControls element:

import { RichText, BlockControls, AlignmentToolbar, useBlockProps, InspectorControls, PanelBody} from '@wordpress/block-editor';
...
const { TextControl, ToggleControl, Panel, PanelBody, PanelRow } = wp.components;

const onChangeTest = ( value ) => {
    setAttributes( { doubleoptin: value } );
};

return (
...
            <InspectorControls>
                <PanelBody
                title='Additional Settings'
                    initialOpen="true">
                    <PanelRow>
                        <ToggleControl
                            label='Test Toggle'
                            onChange={onChangeTest}
                            checked={props.attributes.doubleoptin}
                    />
                    </PanelRow>
                </PanelBody>
            </InspectorControls>

And also identified, in Kadence blocks, the exact feature I'd like my custom block to have:

Advanced Text from Kadence Blocks

I'd love to avoid building this from scratch.

Update 2

Looks like "from scratch" it is, at this time. Perhaps eventually this functionality will be included in WP Core.

Thankfully WPDevelopers, notificationx codebase is published on Github, from which I was able to extract:

import { dispatch } from "@wordpress/data";
export default function Edit( props ) {
    const {
        attributes: {previewmode},
        setAttributes,
    } = props;

const handleDesktopBtnClick = ({
        setPreviewDeviceType,
        setAttributes,
    }) => {
        setAttributes({
            previewmode: "Desktop",
        });
        setPreviewDeviceType("Desktop");
    };

    const handleTabBtnClick = ({ setPreviewDeviceType, setAttributes }) => {
        setAttributes({
            previewmode: "Tablet",
        });
        setPreviewDeviceType("Tablet");
    };

    const handleMobileBtnClick = ({
        setPreviewDeviceType,
        setAttributes,
    }) => {
        setAttributes({
            previewmode: "Mobile",
        });
        setPreviewDeviceType("Mobile");
    };

A bunch of the styleName's I am just keeping the Kadence Blocks styles, since will be using that plugin at the moment anyway, and the JSX is deduced from the HTML that plugin utilizes:

<div className="kadence-title-bar">
        <span className="kadence-control-title">Font Size (em)</span>
        <ButtonGroup className="kb-measure-responsive-options" aria-label="Device">
            <Button className="kb-responsive-btn kb-desk-tab is-active is-small">
            <span
            onClick={() =>
                handleDesktopBtnClick({
                    setAttributes,
                    setPreviewDeviceType:
                        dispatch("core/edit-post")
                            .__experimentalSetPreviewDeviceType,
                })
            }
            className={`typoResButton dashicons dashicons-desktop ${
                previewmode === "Desktop" ? "active" : " "
            }`}></span>
            </Button>
            <Button className="kb-responsive-btn kb-tablet-tab is-small">
            <span
                onClick={() =>
                    handleTabBtnClick({
                        setAttributes,
                        setPreviewDeviceType:
                            dispatch("core/edit-post")
                                .__experimentalSetPreviewDeviceType,
                    })
                }
                className={`typoResButton dashicons dashicons-tablet ${
                    previewmode === "Tablet" ? "active" : " "
                }`}></span>
            </Button>
            <Button className="kb-responsive-btn kb-mobile-tab is-small">
            <span
                onClick={() =>
                    handleMobileBtnClick({
                        setAttributes,
                        setPreviewDeviceType:
                            dispatch("core/edit-post")
                                .__experimentalSetPreviewDeviceType,
                    })
                }
                className={`typoResButton dashicons dashicons-smartphone ${
                    previewmode === "Mobile" ? "active" : " "
                }`}></span>
            </Button>
        </ButtonGroup>
    </div>
<PanelRow>
    <BaseControl className="width-100">
        <RangeControl
            label=" "
            min={0.5}
            max={10}
            step={0.1}
            value={props.attributes.fontsize}
            onChange={ value => setAttributes( {fontsize: value}) }
        />
    </BaseControl>
</PanelRow>
// HARDCODING for EM in this case.

Now I just need to figure out:

  • Save multiple sizes, with default if 0, 1 or 2 are set.
  • Generate the @media queries for the front end.

1 Answer 1

0

Would love to know a recommended way to insert the CSS into the page, but I'm adding a <script> block with a couple of levels of javascript string interpolation directly into the JSX in both edit and save:

<style>{
`.wp-block-create-block-population-count {
    font-size: ${DesktopFontSize}em;
}
@media (max-width: 767px) {
        .wp-block-create-block-population-count {
            font-size: ${MobileFontSize}em;
        }
    }
    @media (min-width: 768px) and (max-width: 1050px) {
        .wp-block-create-block-population-count {
            font-size: ${TabletFontSize}em;
        }
    }`
}
</style>

As for saving the three different type sizes, add them to the attributes, which are in block.json (could also be in index.js):

    "attributes": {
        "alignment": {
            "type": "string"
        },
        "preamble": {
            "type": "string",
            "source": "html",
            "selector": ".preamble"
        },
        "closing": {
            "type": "string",
            "source": "html",
            "selector": ".closing"
        },
        "DesktopFontSize": {
            "type": "number"
        },
        "TabletFontSize": {
            "type": "number"
        },
        "MobileFontSize": {
            "type": "number"
        }
    }

Add them to our props deconstruction:

const {
        attributes: {etc, previewmode = "Desktop", DesktopFontSize, MobileFontSize, TabletFontSize},
        className, focus,
        setAttributes,
    } = props;

And update the setAttributes calls (x3):

<RangeControl
    label=" "
    min={0.5}
    max={8}
    step={0.1}
    value={props.attributes[previewmode + "FontSize"] || 3}
    onChange={ value => setAttributes( {[previewmode + "FontSize"]: value}) }
/>
</BaseControl>

Not sure quiet what's happening in

dispatch("core/edit-post").__experimentalSetPreviewDeviceType

Hoping to accept a more informed solution. Perhaps eventually this feature will be added as a WP core component.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.