I'm developing a Gutenberg block, and am trying to create some InspectorControls. I would like to create a buttongroup to control the alignment of a specific element within the block (I would add that I'm using ServerSideRender to render the block). There isn't much information in the handbook about ButtonGroup, it doesn't seem to take a "label". My javascript code right now is:
createElement(PanelRow, {},
createElement(ButtonGroup, { title: __('N Element Alignment','bibleget-io') },
createElement(IconButton, {
icon: 'editor-alignleft',
isDefault: true
}),
createElement(IconButton, {
icon: 'editor-aligncenter',
isDefault: true
}),
createElement(IconButton, {
icon: 'editor-alignright',
isDefault: true
})
)
),
I would also like to know if the ButtonGroup has an onChange event, or only the single Buttons in the group? Or perhaps an onClick event? How would I set the value of the ButtonGroup? Would I have to set the state of each button based on an attribute's value?
UPDATE: I saw the "deprecated" notices in the chrome inspector tools as regards "IconButton" (so I'm just using "Button" now) and as regards the "isDefault" property so I'm using "isSecondary" now. I found that I can actually set a value property on each button. And so far the only way I can find to set the state of each button in a significant manner based on the value of a single attribute is in this manner:
createElement(PanelRow, {},
createElement(ButtonGroup, { title: __('N Element Alignment','bibleget-io') },
createElement(Button, {
icon: 'editor-alignleft',
value: 'left',
isPrimary: (attributes.nalignment === 'left'),
isSecondary: (attributes.nalignment !== 'left'),
onClick: changeNAlignmentValue
}),
createElement(Button, {
icon: 'editor-aligncenter',
value: 'center',
isPrimary: (attributes.nalignment === 'center'),
isSecondary: (attributes.nalignment !== 'center'),
onClick: changeNAlignmentValue
}),
createElement(Button, {
icon: 'editor-alignright',
value: 'right',
isPrimary: (attributes.nalignment === 'right'),
isSecondary: (attributes.nalignment !== 'right'),
onClick: changeNAlignmentValue
})
)
),
The button states are now showing in a more significant manner based on the value of my nalignment attribute. When I click on a button in the group I see that the click event is being passed to the changeNAlignmentValue function. I am able to read the value of the button that was clicked like this:
function changNAlignmentValue(ev){
let nalignment = ev.currentTarget.value;
setAttributes({nalignment});
}
In this manner I see that my nalignment attribute is updating correctly and state is being set on the buttons in the ButtonGroup based on the value of the nalignment attribute. Is this the correct approach to using the ButtonGroup? I would have expected it to have more of a radio functionality, seeing that the documentation says that only one button can be toggled at a time (when used in the exclusive radio like manner: how would you set a ButtonGroup as exclusive rather than multiple, which would act more like a checkbox buttongroup?) And I still have the question of how to put a label on the ButtonGroup. If it's not possible, I would even just create a Text component immediately before creating the ButtonGroup component, but I can't find any documentation on how to create a Text componenent in javascript. I have tried a couple things but I get errors like "was expecting string and found expression"...
I'm developing a Gutenberg block, and am trying to create some InspectorControls. I would like to create a buttongroup to control the alignment of a specific element within the block (I would add that I'm using ServerSideRender to render the block). There isn't much information in the handbook about ButtonGroup, it doesn't seem to take a "label". My javascript code right now is:
createElement(PanelRow, {},
createElement(ButtonGroup, { title: __('N Element Alignment','bibleget-io') },
createElement(IconButton, {
icon: 'editor-alignleft',
isDefault: true
}),
createElement(IconButton, {
icon: 'editor-aligncenter',
isDefault: true
}),
createElement(IconButton, {
icon: 'editor-alignright',
isDefault: true
})
)
),
I would also like to know if the ButtonGroup has an onChange event, or only the single Buttons in the group? Or perhaps an onClick event? How would I set the value of the ButtonGroup? Would I have to set the state of each button based on an attribute's value?
UPDATE: I saw the "deprecated" notices in the chrome inspector tools as regards "IconButton" (so I'm just using "Button" now) and as regards the "isDefault" property so I'm using "isSecondary" now. I found that I can actually set a value property on each button. And so far the only way I can find to set the state of each button in a significant manner based on the value of a single attribute is in this manner:
createElement(PanelRow, {},
createElement(ButtonGroup, { title: __('N Element Alignment','bibleget-io') },
createElement(Button, {
icon: 'editor-alignleft',
value: 'left',
isPrimary: (attributes.nalignment === 'left'),
isSecondary: (attributes.nalignment !== 'left'),
onClick: changeNAlignmentValue
}),
createElement(Button, {
icon: 'editor-aligncenter',
value: 'center',
isPrimary: (attributes.nalignment === 'center'),
isSecondary: (attributes.nalignment !== 'center'),
onClick: changeNAlignmentValue
}),
createElement(Button, {
icon: 'editor-alignright',
value: 'right',
isPrimary: (attributes.nalignment === 'right'),
isSecondary: (attributes.nalignment !== 'right'),
onClick: changeNAlignmentValue
})
)
),
The button states are now showing in a more significant manner based on the value of my nalignment attribute. When I click on a button in the group I see that the click event is being passed to the changeNAlignmentValue function. I am able to read the value of the button that was clicked like this:
function changNAlignmentValue(ev){
let nalignment = ev.currentTarget.value;
setAttributes({nalignment});
}
In this manner I see that my nalignment attribute is updating correctly and state is being set on the buttons in the ButtonGroup based on the value of the nalignment attribute. Is this the correct approach to using the ButtonGroup? I would have expected it to have more of a radio functionality, seeing that the documentation says that only one button can be toggled at a time (when used in the exclusive radio like manner: how would you set a ButtonGroup as exclusive rather than multiple, which would act more like a checkbox buttongroup?) And I still have the question of how to put a label on the ButtonGroup. If it's not possible, I would even just create a Text component immediately before creating the ButtonGroup component, but I can't find any documentation on how to create a Text componenent in javascript. I have tried a couple things but I get errors like "was expecting string and found expression"...
Share Improve this question edited May 14, 2020 at 7:46 JohnRDOrazio asked May 13, 2020 at 18:13 JohnRDOrazioJohnRDOrazio 1517 bronze badges1 Answer
Reset to default 1I have discovered a way of creating a label and a help property for a component that doesn't have it's own label or help properties, by wrapping that component in a BaseControl component. Here is my working solution:
createElement(PanelRow, {},
createElement(BaseControl, {
label: __('N element alignment', 'my-textdomain'),
help: __('Set the alignment for n element in this block','my-textdomain')
},
createElement(ButtonGroup, {},
createElement(Button, {
icon: 'editor-alignleft',
value: 'left',
isPrimary: (attributes.nelementalign === 'left'),
isSecondary: (attributes.nelementalign !== 'left'),
onClick: changeNElementAlign,
title: __('N element align left', 'my-textdomain')
}),
createElement(Button, {
icon: 'editor-aligncenter',
value: 'center',
isPrimary: (attributes.nelementalign === 'center'),
isSecondary: (attributes.nelementalign !== 'center'),
onClick: changeNElementAlign,
title: __('N element align center', 'my-textdomain')
}),
createElement(Button, {
icon: 'editor-alignright',
value: 'right',
isPrimary: (attributes.nelementalign === 'right'),
isSecondary: (attributes.nelementalign !== 'right'),
onClick: changeNElementAlign,
title: __('N element align right', 'my-textdomain')
})
)
)
),