-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[UI Framework] Improve minor accessibility issues in ui_framework #14073
Conversation
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.
🌋 This is epic! Thanks for doing this, Tim! There's so much good stuff documented here which I hadn't known about previously. I just had a few suggestions.
id={idGen('collapsable')} | ||
style={{ display: isExpanded ? 'block' : 'none' }} | ||
> | ||
Here is some collapsable content. |
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.
Typo: I think this should be "collapsible". We should probably update the generated IDs with this spelling too.
</GuideText> | ||
|
||
<GuideText> | ||
For the sake of simplicity we haven’t labeled the element on this page |
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.
Is this meant to refer to the <label>
example or to all of the different input examples on the page?
You can use this button to reveal and hide content. | ||
You can use this button to reveal and hide content. For a complete example | ||
on how to make an collapsable panel proper accessible, read | ||
the <a href="#/collapsebutton">CollapseButton</a> documentation. |
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.
Instead of using <a>
directly here, let's use react-router's Link:
import {
Link,
} from 'react-router';
<Link
className="guideLink"
to="collapsebutton"
>
CollapseButton
</Link>
@@ -71,6 +71,9 @@ const KuiButton = ({ | |||
children, | |||
...rest | |||
}) => { | |||
if (!children && !rest['aria-label'] && !rest['aria-labelledby']) { | |||
console.error('Specify aria-label or aria-labelledby on <KuiButton/> if it does not have children.'); | |||
} |
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.
What would you say to replacing this with a custom prop-type checker?
const accessibleIconButton = (props, propName, componentName) => {
if (props.children) {
return;
}
if (props['aria-label']) {
return;
}
if (props['aria-labelledby']) {
return;
}
throw new Error(
`${componentName} requires aria-label or aria-labelledby to be specified if it does not have children. ` +
`This is because we're assuming you're creating an icon-only button, which is screen-reader-inaccessible.`
);
};
const KuiButton = ({
isLoading,
iconPosition = DEFAULT_ICON_POSITION,
className,
buttonType,
icon,
children,
...rest
}) => {
return (
<button
className={getClassName({
className,
buttonType,
hasIcon: icon || isLoading,
})}
{...rest}
>
<ContentWithIcon
icon={icon}
iconPosition={iconPosition}
isLoading={isLoading}
>
{children}
</ContentWithIcon>
</button>
);
};
KuiButton.propTypes = {
icon: PropTypes.node,
iconPosition: PropTypes.oneOf(ICON_POSITIONS),
children: PropTypes.node,
isLoading: PropTypes.bool,
buttonType: PropTypes.oneOf(BUTTON_TYPES),
className: PropTypes.string,
'aria-label': accessibleIconButton,
};
This will give us an error like 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.
That is of course the way better option. Sorry I never thought about using propTypes
for checking conditions between multiple properties.
@@ -116,6 +119,10 @@ const KuiLinkButton = ({ | |||
} | |||
}; | |||
|
|||
if (!children && !rest['aria-label'] && !rest['aria-labelledby']) { | |||
console.error('Specify aria-label or aria-labelledby on <KuiLinkButton/> if it does not have children.'); | |||
} |
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 can reuse the same custom prop type checker here.
@@ -6,14 +6,16 @@ import classNames from 'classnames'; | |||
const KuiInfoButton = props => { | |||
const iconClasses = classNames('kuiInfoButton', props.className); | |||
|
|||
const ariaLabel = props['aria-label'] || 'Info'; |
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.
Instead of doing this we can create a defaultProps
definition after the propTypes
on line 17:
KuiInfoButton.defaultProps = {
'aria-label': 'Info',
};
I improved the PR with all your suggestions. |
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.
Looks great!
Jenkins, test this |
1 similar comment
Jenkins, test this |
Jenkins, test this ... more and more weird errors that seem unrelated to this PR |
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.
👍
* Use proper labels in bar example * Make aria-label on icon buttons mandatory * Add role=group to KuiButtonGroup * Add roles to card component * Fix alphabetical ordering in menu * Add accessibility example for KuiCollapseButton * Improve accessibility of Event examples * Add note about labeling to Form docs * Update broken snapshots * Fix icon in HeaderBar example * Add default aria-label to InfoButton if not specified * Fix wrong HTML entities * Fix icon names in Event example * Add icon labels in InfoPanel example * Improve accessibility of Micro and MenuButton examples * Add labels to StatusText example * Apply proper ARIA roles for tabs * Make ToggleButton example accessible * Fix icon names in events sandbox * Also allow aria-labelledby for icon buttons * Fix spelling of collapsible * Make statement about labels more clear * Use proper Link element for linking * Use propTypes to check for icon only buttons * Use defaultProps in KuiInfoButton
Backports:
|
This PR fixes some minor accessibility issues in the UI framework. I have excluded the following components, from this PR, since they are either rather large and I would like to open separate PRs for each of them or they still need some discussion:
ColorPicker
Expression
Gallery
LocalNav
Menu
Modal
Pager
Popover
Table
And unrelated, but I considered it too small for it's own PR, I fixed the alphabetical order in the UI framework docs menu.
Beside some ARIA attributes and roles, this also introduces a function change:
If you use an
KuiButton
(orKuiLinkButton
) without any children, an error will be logged if noaria-label
andaria-labelledby
property was specified, to prevent the common mistake of icon only buttons.Fixes some parts of #14080