0

I made my custom block button. I want wrap it in and align a button horizontally. How could you wrap it? Below code has two problems

  1. It doesn't allow to edit a text in a button
  2. It doesn't allow a button to align center
(function (element, blocks, blockEditor) {
  var el = element.createElement;
  var RichText = blockEditor.RichText;
  blocks.registerBlockType(
    'custome-namespace/button',
    {
      title: 'nice button',
      icon: 'button',
      category: 'layout',
      example: {},
      attributes: {
        text: {
          type: 'string',
          default: '',
          source: 'html',
          selector: 'button'
        },
        align: {
          type: 'string',
          default: 'center',
        }
      },
      supports: {
        align: true,
        justifyContent: true,
        alignItems: true
      },
      edit: function (props) {
        var blockProps = blockEditor.useBlockProps();
        var buttonBlock = el(
          RichText, Object.assign(blockProps, {
            onChange: function handleChange(text) {
              props.setAttributes({ text: text })
            },
            value: props.attributes.text,
            placeholder: 'Input button label',
            tagName: 'button',
            className: props.className,
          })
        );
        return el('div', blockProps, buttonBlock)
      },
      save: function (props) {
        var blockProps = blockEditor.useBlockProps.save();
        var buttonBlock = el(
          RichText.Content,
          Object.assign(blockProps, {
            value: props.attributes.text,
            tagName: 'button',
          })
        );
        return el('div', blockProps, buttonBlock)
      },
    }
  );

})(window.wp.element, window.wp.blocks, window.wp.blockEditor)

Thank you so much!

4
  • 1
    Sorry if my previous comment sounded silly... I actually thought nothing major was changed in your code (I didn't check thoroughly on your code).. anyway, let me know if my answer helped?
    – Sally CJ
    Jan 21, 2022 at 13:17
  • Yeah! it fixed like a charm! Thank you so much. Next time I'll write in JSX :)
    – Watanabe.N
    Jan 21, 2022 at 14:47
  • Glad it helped, but sorry! You could actually use the blockProps with RichText.. but nonetheless, see my revised anwer for more details :)
    – Sally CJ
    Jan 21, 2022 at 16:09
  • 1
    Thank you so much! You made many things clear!
    – Watanabe.N
    Jan 22, 2022 at 5:19

1 Answer 1

1

If you turned on script debugging or the SCRIPT_DEBUG constant in WordPress, then you would've noticed that your block type causes React to throw this warning: "Warning: React does not recognize the tagName prop on a DOM element.", so when developing block types, you should enable script debugging — at least, you'll know your code causes a warning or an error, even if the message didn't make sense.. i.e. it doesn't tell something like, "hey, remove tagName from your blockProps object!".. :)

So as for the problems in question, or the above warning, it's because the block (wrapper) props, i.e. your blockProps variable, contained an invalid property/attribute (which is tagName) for the <div> tag that your edit() and save() functions return.

That property is added to the blockProps when you do Object.assign(blockProps, { your props }) which modifies the original blockProps object — Object.assign() works like array_merge() in PHP, but PHP doesn't modify the first array passed to the function and simply returns a new array; Object.assign(), on the other hand, modifies the first object. So you should have used Object.assign({}, blockProps, { your props }) instead (note the {}), i.e. clone the existing blockProps object instead of modifying it, e.g. in edit():

var buttonBlock = el(
//  RichText, Object.assign(blockProps, {   // bad
// and it's bad because it adds the tagName property to the blockProps.

  RichText, Object.assign({}, blockProps, { // good
    ... your props.
  })
);
return el('div', blockProps, buttonBlock)

However, despite using the blockProps (or useBlockProps) on other elements would not result in any error/warning, I don't think it's needed above, hence I'd use the blockProps only on the div element. :)

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.