Site icon Hip-Hop Website Design and Development

When setting styles to an extended block that was saved as a pattern, it doesn’t remove the style that was there

I’m extending the button block, adding extra options such adding theme colors (a color picker) and icons (radio group). This adds class names for each of the options. has-icon, has-icon-{icon}, is-theme-{color}, and also is-style classes.

When saving the block as a pattern with the classes, and inserting this pattern into a post, the classes that were saved as the pattern can no longer be changable, and any changes added to the button is prepended, which breaks the block and clashes with the other class names.

Pattern html (Just the button markup)

      <div class="wp-block-buttons is-content-justification-right cta-buttons">
         <!-- wp:button {"className":"is-style-solid is-theme-yellow has-icon has-icon-arrow-diagonal"} -->
         <div class="wp-block-button is-style-solid is-theme-yellow has-icon has-icon-arrow-diagonal is-theme-blue"><a class="wp-block-button__link" href="#form">Request</a></div>
         <!-- /wp:button -->
      </div>

The output class names when trying to change button settings:

wp-block is-theme-red has-icon has-icon-download is-selected wp-block-button is-style-solid is-theme-yellow has-icon has-icon-arrow-diagonal

With

is-style-solid is-theme-yellow has-icon has-icon-arrow-diagonal

Being the styles that aren’t being removed.

The fix to this is by removing the classes that’s there in the class names box, but that isn’t really a solution.

Here’s a snippet that’s extending the button block:

const addInspectorControl = createHigherOrderComponent(
  (BlockEdit) => (props) => {
    const {
      attributes: { color, icon, className },
      setAttributes,
      name,
    } = props;
    if (!enabledBlocks.includes(name)) return <BlockEdit {...props} />;
    const isStandaloneStyle =
      className?.includes("is-style-standalone") ?? false;

    if (isStandaloneStyle) {
      setAttributes({
        color: getObjByKey(buttonColorOptions, "name", "link-blue"),
      });
    }

    return (
      <Fragment>
        <InspectorControls>
          <PanelBody
            title={__("Button Style Settings", "button/style-settings")}
          >
            <BaseControl>
              <BaseControl.VisualLabel>Button Color</BaseControl.VisualLabel>
              <ColorPalette
                colors={
                  !isStandaloneStyle
                    ? buttonColorOptions
                    : [getObjByKey(buttonColorOptions, "name", "link-blue")]
                }
                value={color.color}
                style={{ width: "400px" }}
                clearable={false}
                disableCustomColors={true}
                onChange={(selectedColor) => {
                  console.log(props, selectedColor);
                  return setAttributes({
                    color: getObjByKey(
                      buttonColorOptions,
                      "color",
                      selectedColor
                    ),
                  });
                }}
              />
            </BaseControl>

            <BaseControl help={`Selected Icon: ${icon.title}`}>
              <BaseControl.VisualLabel>Button Icon</BaseControl.VisualLabel>
              <RadioGroup
                id="button-icon-selector"
                onChange={(selectedIcon) =>
                  setAttributes({
                    icon: getObjByKey(buttonIconOptions, "slug", selectedIcon),
                  })
                }
                defaultChecked="none"
                label="Button Icon Selection" //aria-label - not label really
                checked={icon.slug}
              >
                {buttonIconOptions.map((iconObj) => {
                  return (
                    <Radio value={iconObj.slug}>
                      <Icon icon={iconObj.icon} />
                    </Radio>
                  );
                })}
              </RadioGroup>
            </BaseControl>
          </PanelBody>
        </InspectorControls>
        <BlockEdit {...props} />
      </Fragment>
    );
  },
  "withInspectorControl"
);

const addClassEditor = createHigherOrderComponent((BlockListBlock) => {
  return (props) => {
    const {
      attributes: { color, icon },
      className,
      name,
    } = props;
    if (!enabledBlocks.includes(name)) return <BlockListBlock {...props} />;
    console.log(typeof color, typeof icon);
    console.log(props);
    return (
      <BlockListBlock
        {...props}
        className={classnames(
          className,
          !isEmpty(color) ? `is-theme-${color.name}` : "",
          !isEmpty(icon) && icon.slug !== "none"
            ? `has-icon has-icon-${icon.slug}`
            : ""
        )}
      />
    );
  };
}, "withEditorColorClass");

const addClassFrontend = (props, block, attributes) => {
  if (!enabledBlocks.includes(block.name)) return props;
  const { className } = props;
  const { color, icon } = attributes;
  return assign({}, props, {
    className: classnames(
      className,
      !isEmpty(color) ? `is-theme-${color.name}` : "",
      !isEmpty(icon) && icon.slug !== "none"
        ? `has-icon has-icon-${icon.slug}`
        : ""
    ),
  });
};

Registering the pattern snippet

register_block_pattern(
    'cta/standard-reversed',
    array(
        'title'       => __( 'Standard CTA - Reversed', 'standard-cta-reversed' ),
        'description' => _x( 'Standard CTA - Reversed', 'Block pattern description', 'ux' ),
        'categories'    => array( 'ctas' ),
        'content'     => "<!-- wp:generateblocks/container {"uniqueId":"6ec90db7","paddingTop":"1","paddingRight":"5","paddingBottom":"1","paddingLeft":"5","paddingUnit":"em","paddingRightTablet":"3","paddingLeftTablet":"3","paddingRightMobile":"2","paddingLeftMobile":"2","backgroundColor":"#283139","gradientColorOne":"#3c4042","gradientColorOneOpacity":1,"gradientColorStopOne":3,"gradientColorTwo":"#cf2e2e","gradientColorTwoOpacity":1,"gradientSelector":"pseudo-element","textColor":"#ffffff","linkColor":"#0693e3","bgImage":{"id":11904,"image":{"url":"/funky-lines.png","height":400,"width":400,"orientation":"landscape"}},"bgOptions":{"selector":"element","opacity":0.3,"overlay":false,"position":"center center","size":"actual","repeat":"repeat","attachment":""},"align":"full","shapeDividers":[],"isDynamic":true,"blockVersion":2,"className":"bg-bm-cb cta-container cta-standard-inverse cta-standard","opacities":[],"transitions":[],"boxShadows":[],"transforms":[],"textShadows":[],"filters":[],"advBackgrounds":[]} --><!-- wp:columns --><div class="wp-block-columns"><!-- wp:column {"width":"35%","className":"cta-col-image"} --><div class="wp-block-column cta-col-image" style="flex-basis:35%"><!-- wp:image {"id":12548,"sizeSlug":"large","linkDestination":"media","className":"cta-image"} --><figure class="wp-block-image size-large cta-image"><a href="/Product_Wheel_Full2000px-e1639176460709.png"><img src="/Product_Wheel_Full2000px-e1639176460709-1024x718.png" alt="" class="wp-image-12548"/></a></figure><!-- /wp:image --></div><!-- /wp:column --><!-- wp:column {"width":"55%","className":"cta-col-content"} --><div class="wp-block-column cta-col-content" style="flex-basis:55%"><!-- wp:heading {"style":{"typography":{"fontSize":"30px"}},"textColor":"white","className":"cta-heading"} --><h2 class="cta-heading has-white-color has-text-color" style="font-size:30px">Get Started with the Industry’s Best Strategic Portfolio Management Platform</h2><!-- /wp:heading --><!-- wp:buttons {"contentJustification":"right","className":"cta-buttons"} --><div class="wp-block-buttons is-content-justification-right cta-buttons"><!-- wp:button {"className":"is-style-solid is-theme-yellow has-icon has-icon-arrow-diagonal"} --><div class="wp-block-button is-style-solid is-theme-yellow has-icon has-icon-arrow-diagonal is-theme-blue"><a class="wp-block-button__link" href="#form">Request a Demo</a></div><!-- /wp:button --></div><!-- /wp:buttons --></div><!-- /wp:column --></div><!-- /wp:columns --><!-- /wp:generateblocks/container -->"
    )
);