react-leaflet icon indicating copy to clipboard operation
react-leaflet copied to clipboard

Support ARIA role for accessibility on Map component

Open Scaralu opened this issue 1 year ago • 4 comments

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;

Scaralu avatar Jul 22 '22 15:07 Scaralu

I'm going to start working on it. Once I have something done, I'll post updates here.

Scaralu avatar Jul 22 '22 16:07 Scaralu

Would also be nice if we can control the tab-index of MapContainer and Marker. Tabbing through all those Marker can be tedious.

gitkumi avatar Aug 16 '22 00:08 gitkumi

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?

Leningram avatar Aug 17 '22 07:08 Leningram

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, maybe aria-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>
    )
}

rjackson avatar Aug 17 '22 12:08 rjackson