react-leaflet
react-leaflet copied to clipboard
Support ARIA role for accessibility on Map component
Problem
Following WCAG 1.3.1 rules, for a component to be accessible, it's needed to ensure that elements in the focus order have an appropriate role.
Expected behavior
The leaflet container should have an accessible and meaningful role.
Reproduce steps
Render a map, and check its accessibility with axe/wave;
I'm going to start working on it. Once I have something done, I'll post updates here.
Would also be nice if we can control the tab-index
of MapContainer
and Marker
. Tabbing through all those Marker
can be tedious.
Moreover, if I have a map absolutely positioned and it goes out of the screen for a bit, when I click on it, the document screen moves to show all the map. It occurs because the map container has tabIndex=1, when I remove it - I can click on the map without having my screen moving. Is there any way to remove tabIndex from the container now?
Following WCAG 1.3.1 rules, for a component to be accessible, it's needed to ensure that elements in the focus order have an appropriate role.
I'm not sure the phrasing here is a correct interpretation of WCAG 2.1, 1.3.1: Info and Relationships:
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
Exactly what you need to do to satisfy this criterion will depend on your usage of the map, but it may be valid that you need the map to be "programmatically determined" – which could include setting aria-role
.
Leaflet has an open issue discussing this: leaflet/leaflet#7193.
I do think there is an argument that React-Leaflet should support arbitrary props against the map container element because:
-
Leaflet's accessibility guide recommends adding the inert attribute for decorative maps (although React doesn't properly support
inert
at the moment: facebook/react#24730 🙄) - The Leaflet issue above is anticipating developers needing to add relevant attributes to it (
aria-label
, maybearia-role
, ...)
But this would have to be carefully implemented because Leaflet and React-Leaflet add their own attributes to the map container element (Leaflet: tabindex
, React-Leaflet: id
, style
). Care would need to be taken to make sure arbitrary props do not interfere with any props managed by the libraries.
Would also be nice if we can control the tab-index of MapContainer and Marker. Tabbing through all those Marker can be tedious.
This is Leaflet functionality, and there are open issues discussing this:
- Leaflet/Leaflet#3472
- Leaflet/Leaflet#7479
Moreover, if I have a map absolutely positioned and it goes out of the screen for a bit, when I click on it, the document screen moves to show all the map. It occurs because the map container has tabIndex=1, when I remove it - I can click on the map without having my screen moving. Is there any way to remove tabIndex from the container now?
If your map is not intended to be interactive at all, the inert attribute is probably what you want. You can hack around with a callback ref to work around React not supporting inert, and React-Leaflet not supporting arbitrary props:
import { useCallback } from 'react';
import { MapContainer } from 'react-leaflet/MapContainer';
const SomeMap = () => {
const mapRef = useCallback((node) => {
node && node.getContainer().setAttribute('inert', true);
}, []);
return (
<div inert>
<MapContainer ref={mapRef} {/* ... */}>
{/* ... */}
</MapContainer>
</div>
)
}