-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Global Styles: Fix incorrect usage of ItemGroup in the Background image panel #68631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Hey @afercia, Whenever you have a moment, could you please review my PR? It addresses another instance of incorrect usage of the ItemGroup component in the Background Image panel. I’d really appreciate your feedback! |
@@ -125,7 +125,12 @@ function InspectorImagePreviewItem( { | |||
} | |||
}, [ toggleProps?.isOpen, onToggleCallback ] ); | |||
return ( | |||
<ItemGroup as={ as } className={ className } { ...toggleProps }> | |||
<ItemGroup | |||
role="none" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the background image is set, ItemGroup is rendered as a button element. The role=none would override the native button role, which isn't okay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can solve this with imgUrl ? "none" : "button"
. I'll try it out and update you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe based on the as
prop. However, this would be just a temporary workaround.
This component is still used incorrectly and against its documentation. We can implement a temporary fix but the long term goal is to not allow this kind of incorrect usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@im3dabasia thanks for your PR. As mentioned in #67425 (comment) when the background image is set, this ItemGroup becomes a button element. Setting role=none
on the button would override the native button role and assistive technology would not communicate this as a button.
One option could be setting the role conditionally but it wouldn't be great having a button element with role=button.
I'd rather remove the ItemGroup entirely and explore a design change.
Thank you for your feedback @afercia . I agree that this is happening, but the button has As a temporary fix, I’d like to propose two possible solutions. Let me know which one you think works best:
<ItemGroup
role={ as === 'span' ? 'none' : 'button' }
as={as}
className={className}
{...toggleProps}
/> This would add role="none" by default when a span is rendered and otherwise apply role="button".
<ItemGroup
{...(as === 'span' ? { role: 'none' } : {})}
as={as}
className={className}
{...toggleProps}
/> This approach adds the role prop only when a span is rendered; otherwise, it allows the default behavior to prevail (i.e., a button with role="list"). Personally, I believe the first approach is better as it improves accessibility overall for this issue. Looking forward to here your thoughts @afercia |
We should avoid that so the first approach is better. However, this can only be acceptable as a temporary solution. |
c763ce2
to
fcbb2a9
Compare
Hi @afercia, Sorry for the delay. I have updated the PR with the relevant changes as discussed. I have also added a TODO message for future reference. Please review my PR once again and provide any feedback. Thank you for your time. I appreciate it. |
fcbb2a9
to
839cd48
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to explore a temporary fix here, but I don't think simply changing the role
attribute is enough.
Here are what I consider to be the problems.
The focus outline style is slightly different than that of the Button
component:
The focus outline color is black:
These issues seem to be caused by customizing the ItemGroup
component.
I would suggest, similar to #68633, to remove the ItemGroup
component completely and use the Button
component. We'll probably need to adjust the implementation of the InspectorImagePreviewItem
component. What do you think?
Correct! I have adjusted the code in I have replaced This approach solves our problem and also eliminates the |
When you get a chance. Please review this PR. I feel we are close to shipping this 🚢 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update!
Can you fix the button when the background image panel is open? It seems that the button elements are nested:
Additionally, we might be able to extract FlexItem
:
function InspectorImagePreviewItem( {} ) {
// ...
const renderLabelContent = () => (
<FlexItem>
<Truncate>{ label }</Truncate>
{/* ... */}
</FlexItem>
);
return imgUrl ? (
<Button>
<HStack className="block-editor-global-styles-background-panel__inspector-preview-inner">
{ imgUrl && {/* ... */} }
{ renderLabelContent() }
</HStack>
</Button>
) : (
renderLabelContent()
);
}
Thank you @t-hamano for correctly pointing out these improvements. I appreciate your feedback. I have implemented the changes and added them to the PR. Please take a look when you have a chance. Video reference: Screen.Recording.2025-03-28.at.2.16.34.PM.mov |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@im3dabasia Can you investigate and fix the browser console error occurring when adding a background image? This error doesn't occur on trunk:
6d2b8da786d27d867d85b56e45454a29.mp4
@t-hamano , The console error was occurring because the Please check once again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Finally, can we do a small refactor like this?
const { isOpen, ...restToggleProps } = toggleProps;
useEffect( () => {
if ( typeof isOpen !== 'undefined' ) {
onToggleCallback( isOpen );
}
}, [ isOpen, onToggleCallback ] );
@t-hamano . Thanks for the continuous iterations of feedback. Please check when you have a moment |
…ge panel (WordPress#68631) * : a11y issue in background image panel * fix: Role of button when rendered in span/button * revert: Fix unwanted storybook change * fix: Replace ItemGroup with Button * fix: Breading button nesting in popover * chore: Change render function name * fix: Error related to isOpen prop in button * chore: Code refactor Co-authored-by: im3dabasia <im3dabasia1@git.wordpress.org> Co-authored-by: afercia <afercia@git.wordpress.org> Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Part of: #67425
What?
Improved the
ItemGroup
component to handle role attributes correctly based on its rendered HTML element. When rendered as a span, it now appliesrole="none"
to prevent incorrect semantic meaning, and when rendered as a button, it correctly appliesrole="button"
.Why?
The previous implementation incorrectly applied
role="list"
in scenarios where a semantic list wasn't appropriate, causing accessibility issues. This change ensures we maintain proper accessibility standards by applying the correct ARIA roles based on the actual HTML element being rendered.How?
Updated the component to conditionally set the role attribute based on the as prop:
role="none"
to remove any implied semantic meaningrole="button
" for proper accessibilityTesting Instructions
role="list"
when unnecessary.|