Description
<ItemGroup> is supposed to 'display a list of Items grouped and styled together.
The items are supposed to be visually and semantically grouped because the <ItemGroup> renders a div element with an ARIA role=list. This is basically equivalent to an <ul> element. As such, it is supposed to only contain <Item> sub-components that render a div element with role=listitem. This is basically equivalent to <li> elements.
As such, <ItemGroup> is the ARIA equivalent of an unordered list with list items.
The documentation clearly states that ItemGroup should be used in combination with the Item sub-component. The documentation example is pretty clear as well.
However, in practice, ItemGroup accepts any children. There are several examples in the codebase where children other than <Item> are used within an <ItemGroup>. This is semantically incorrect and not accessible. It's basically the equivalent of an <ul> element that contains elements other than <li> elements.
Unfortunately, contributors to this project seem to not read the documentation and misuse this component only to get the 'visual aspect' of the <ItemGroup> not realizing they're going to render unsemantic and not accessible markup.
On the other hand, the <ItemGroup> component doesn't enforce its children to be <Item> sub-components. I would argue that it should, given its intended usage and its documentation.
One example of this misuse is in the block bindings UI:

|
<ItemGroup> |
|
<Text variant="muted"> |
|
{ __( |
|
'Attributes connected to custom fields or other dynamic data.' |
|
) } |
|
</Text> |
|
</ItemGroup> |
where the text highlighted in the screenshot is a <span> element inside a <div> element with role=list. The equivalent in HTML would be something like the following:
<ul>
<span>Some text</span>
</ul>
For the case in the screenshot above, that text should not use an <ItemGroup> in the first place. There are other usage cases in the editor that need to be investigated though.
Still, this component is intended and documented to render a semantic list, while in practice it allows to be misused.
About the parent where <ItemGroup> is used into
Similar concerns raise when the <ItemGroup> is used within elements that can't contain a list.
Again, the <ItemGroup> is the equivalent of an <ul> unordered list. For example, an <ul> can't be used within a <button> element (or any element with role=button). If that was a HTML <ul>, it would be invalid HTML. Even if it's a div with role=list it's still semantically invalid.
One example of this is the 'Add background image' control in the global Styles > Background:

In this case, there is a <button> element rendered by Dropdown, that contains an InspectorImagePreviewItem component which is an <ItemGroup> that contains span elements. In terms of equivalent HTML this would be:
<button>
<ul> <-- Element ul not allowed as child of element button
<span> <-- Element span not allowed as child of element ul
Some content
</span>
</ul>
</button>
Step-by-step reproduction instructions
- Go to Site Editor > Styles > Background
- Inspect the source of the 'Add background image' control.
- Observe it's a button element that contains an ItemGroup with
role="list" which in turns contains only <span> elements.
Screenshots, screen recording, code snippet
No response
Environment info
No response
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Please confirm which theme type you used for testing.
Description
<ItemGroup>is supposed to 'display a list ofItems grouped and styled together.The items are supposed to be visually and semantically grouped because the
<ItemGroup>renders adivelement with an ARIArole=list. This is basically equivalent to an<ul>element. As such, it is supposed to only contain<Item>sub-components that render adivelement withrole=listitem. This is basically equivalent to<li>elements.As such,
<ItemGroup>is the ARIA equivalent of an unordered list with list items.The documentation clearly states that ItemGroup should be used in combination with the Item sub-component. The documentation example is pretty clear as well.
However, in practice, ItemGroup accepts any children. There are several examples in the codebase where children other than
<Item>are used within an<ItemGroup>. This is semantically incorrect and not accessible. It's basically the equivalent of an<ul>element that contains elements other than<li>elements.Unfortunately, contributors to this project seem to not read the documentation and misuse this component only to get the 'visual aspect' of the
<ItemGroup>not realizing they're going to render unsemantic and not accessible markup.On the other hand, the
<ItemGroup>component doesn't enforce its children to be<Item>sub-components. I would argue that it should, given its intended usage and its documentation.One example of this misuse is in the block bindings UI:
gutenberg/packages/block-editor/src/hooks/block-bindings.js
Lines 303 to 309 in 9ec5998
where the text highlighted in the screenshot is a
<span>element inside a<div>element withrole=list. The equivalent in HTML would be something like the following:For the case in the screenshot above, that text should not use an
<ItemGroup>in the first place. There are other usage cases in the editor that need to be investigated though.Still, this component is intended and documented to render a semantic list, while in practice it allows to be misused.
About the parent where
<ItemGroup>is used intoSimilar concerns raise when the
<ItemGroup>is used within elements that can't contain a list.Again, the
<ItemGroup>is the equivalent of an<ul>unordered list. For example, an<ul>can't be used within a<button>element (or any element with role=button). If that was a HTML<ul>, it would be invalid HTML. Even if it's adivwithrole=listit's still semantically invalid.One example of this is the 'Add background image' control in the global Styles > Background:
In this case, there is a
<button>element rendered byDropdown, that contains an InspectorImagePreviewItem component which is an<ItemGroup>that contains span elements. In terms of equivalent HTML this would be:Step-by-step reproduction instructions
role="list"which in turns contains only<span>elements.Screenshots, screen recording, code snippet
No response
Environment info
No response
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Please confirm which theme type you used for testing.