Accessibility: Default Icon to aria-hidden (#84362)

* Icon: aria hide icon, unless a label is set

* Update doc

* Remove weird auto import

* Fix fialing tests

* Add recommendation for Tooltip

* Consider more aria attributes to support Tooltip

* Handle tabIndex and aria-hidden case

* Add comment about aria-label
pull/85531/head^2
Tobias Skarhed 1 year ago committed by GitHub
parent 01afca9d99
commit f387cff836
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 8
      packages/grafana-ui/src/components/Icon/Icon.mdx
  2. 10
      packages/grafana-ui/src/components/Icon/Icon.tsx
  3. 9
      public/app/features/alerting/unified/components/rules/RulesFilter.tsx
  4. 1
      public/app/plugins/datasource/cloud-monitoring/components/__snapshots__/VariableQueryEditor.test.tsx.snap

@ -7,6 +7,14 @@ import { Icon } from './Icon';
Grafana's wrapper component over [Font Awesome](https://fontawesome.com/) and Unicons icons
## Accessibility
`Icon` is aria-hidden by default. If your icon has semantic meaning, please provide a `title` or wrap it in a `Tooltip`.
### Usage with Tooltip
If you decide to use a `Tooltip` to wrap `Icon`, you need to set a `title` or `aria-label` on the `Icon` component in order for it to appear in the accessibility tree. `Tooltip` only provides `aria-describedby` on interaction.
### Changing icon size
By default `Icon` has width and height of `16px` and font-size of `14px`. Pass `className` to control icon's size:

@ -13,6 +13,9 @@ export interface IconProps extends Omit<React.SVGProps<SVGElement>, 'onLoad' | '
name: IconName;
size?: IconSize;
type?: IconType;
/**
* Give your icon a semantic meaning. The icon will be hidden from screen readers, unless this prop or an aria-label is provided.
*/
title?: string;
}
@ -60,6 +63,13 @@ export const Icon = React.forwardRef<SVGElement, IconProps>(
return (
<SVG
aria-hidden={
rest.tabIndex === undefined &&
!title &&
!rest['aria-label'] &&
!rest['aria-labelledby'] &&
!rest['aria-describedby']
}
innerRef={ref}
src={svgPath}
width={svgWid}

@ -162,7 +162,12 @@ const RulesFilter = ({ onFilterCleared = () => undefined }: RulesFilerProps) =>
</div>
}
>
<Icon id="data-source-picker-inline-help" name="info-circle" size="sm" />
<Icon
id="data-source-picker-inline-help"
name="info-circle"
size="sm"
title="Search by data sources help"
/>
</Tooltip>
</Stack>
</Label>
@ -232,7 +237,7 @@ const RulesFilter = ({ onFilterCleared = () => undefined }: RulesFilerProps) =>
<Stack gap={0.5}>
<span>Search</span>
<HoverCard content={<SearchQueryHelp />}>
<Icon name="info-circle" size="sm" tabIndex={0} />
<Icon name="info-circle" size="sm" tabIndex={0} title="Search help" />
</HoverCard>
</Stack>
</Label>

@ -91,6 +91,7 @@ exports[`VariableQueryEditor renders correctly 1`] = `
className="css-zyjsuv-input-suffix"
>
<svg
aria-hidden={true}
className="css-1d3xu67-Icon"
height={16}
id="public/img/icons/unicons/angle-down.svg"

Loading…
Cancel
Save