Skip to content

Commit 4cef15f

Browse files
committed
improve map accessibility
1 parent 51c6543 commit 4cef15f

9 files changed

Lines changed: 55 additions & 6 deletions

File tree

messages/de.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@
500500
"Map": {
501501
"drawerTitle": "Eintragsdetails",
502502
"drawerDescription": "Details zum ausgewählten Eintrag.",
503+
"mapRegionLabel": "Kompostkarte",
504+
"controlsLabel": "Kartensteuerung",
505+
"zoomControlsLabel": "Zoomsteuerung der Karte",
506+
"markerLabel": "Kartenmarkierung",
503507
"emptyTitle": "Nichts gefunden",
504508
"emptyBody": "Der Eintrag, den du suchst, existiert nicht oder wurde entfernt. Tut uns leid.",
505509
"searchPlaceholder": "Strasse oder Ort suchen",

messages/en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@
500500
"Map": {
501501
"drawerTitle": "Listing details",
502502
"drawerDescription": "Selected listing details.",
503+
"mapRegionLabel": "Composting map",
504+
"controlsLabel": "Map controls",
505+
"zoomControlsLabel": "Map zoom controls",
506+
"markerLabel": "Map marker",
503507
"emptyTitle": "Coming up empty",
504508
"emptyBody": "The listing you’re looking for doesn’t exist or has been removed. Sorry to disappoint.",
505509
"searchPlaceholder": "Search for a street or place",

messages/es.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@
500500
"Map": {
501501
"drawerTitle": "Detalles del anuncio",
502502
"drawerDescription": "Detalles del anuncio seleccionado.",
503+
"mapRegionLabel": "Mapa de compostaje",
504+
"controlsLabel": "Controles del mapa",
505+
"zoomControlsLabel": "Controles de zoom del mapa",
506+
"markerLabel": "Marcador del mapa",
503507
"emptyTitle": "No encontramos nada",
504508
"emptyBody": "El anuncio que buscas no existe o fue eliminado.",
505509
"searchPlaceholder": "Busca una calle o un lugar",

messages/fr.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@
500500
"Map": {
501501
"drawerTitle": "Détails de l’annonce",
502502
"drawerDescription": "Détails de l’annonce sélectionnée.",
503+
"mapRegionLabel": "Carte du compostage",
504+
"controlsLabel": "Commandes de la carte",
505+
"zoomControlsLabel": "Commandes de zoom de la carte",
506+
"markerLabel": "Repère de carte",
503507
"emptyTitle": "Rien à l’horizon",
504508
"emptyBody": "L’annonce que vous cherchez n’existe pas ou a été supprimée. Désolé pour la déception.",
505509
"searchPlaceholder": "Rechercher une rue ou un lieu",

messages/pt-BR.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@
500500
"Map": {
501501
"drawerTitle": "Detalhes do anúncio",
502502
"drawerDescription": "Detalhes do anúncio selecionado.",
503+
"mapRegionLabel": "Mapa de compostagem",
504+
"controlsLabel": "Controles do mapa",
505+
"zoomControlsLabel": "Controles de zoom do mapa",
506+
"markerLabel": "Marcador do mapa",
503507
"emptyTitle": "Nada por aqui",
504508
"emptyBody": "O anúncio que você procura não existe ou foi removido. Desculpe a decepção.",
505509
"searchPlaceholder": "Busque uma rua ou um lugar",

src/components/LocationSelect/LocationSelect.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ export default function LocationSelect({
375375
<MapPin type={listingType} selected={true} />
376376
</Marker>
377377
<MapZoomControls
378+
controlsLabel={t("Map.zoomControlsLabel")}
378379
onZoomIn={() => mapRef.current?.getMap().zoomIn()}
379380
onZoomOut={() => mapRef.current?.getMap().zoomOut()}
380381
zoomInLabel={t("Map.zoomInControl")}

src/features/map/components/MapControls.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { theme } from "@/styles/theme.yak";
1212

1313
type MapControlClusterProps = {
14+
controlsLabel: string;
1415
locateActive?: boolean;
1516
locateLabel?: string;
1617
onLocate?: () => void;
@@ -21,9 +22,11 @@ type MapControlClusterProps = {
2122
zoomInDisabled?: boolean;
2223
zoomInLabel: string;
2324
zoomOutLabel: string;
25+
zoomControlsLabel: string;
2426
};
2527

2628
type MapZoomControlsProps = {
29+
controlsLabel: string;
2730
onZoomIn: () => void;
2831
onZoomOut: () => void;
2932
zoomInDisabled?: boolean;
@@ -139,6 +142,7 @@ const ZoomButton = styled.button`
139142
`;
140143

141144
export function MapZoomControls({
145+
controlsLabel,
142146
onZoomIn,
143147
onZoomOut,
144148
zoomInDisabled = false,
@@ -148,6 +152,7 @@ export function MapZoomControls({
148152
return (
149153
<ControlAnchor>
150154
<ZoomControlGroup
155+
controlsLabel={controlsLabel}
151156
onZoomIn={onZoomIn}
152157
onZoomOut={onZoomOut}
153158
zoomInDisabled={zoomInDisabled}
@@ -159,14 +164,15 @@ export function MapZoomControls({
159164
}
160165

161166
function ZoomControlGroup({
167+
controlsLabel,
162168
onZoomIn,
163169
onZoomOut,
164170
zoomInDisabled = false,
165171
zoomInLabel,
166172
zoomOutLabel,
167173
}: MapZoomControlsProps) {
168174
return (
169-
<ZoomGroup>
175+
<ZoomGroup role="group" aria-label={controlsLabel}>
170176
<ZoomButton
171177
type="button"
172178
aria-label={zoomInLabel}
@@ -191,6 +197,7 @@ function ZoomControlGroup({
191197
}
192198

193199
export default function MapControls({
200+
controlsLabel,
194201
locateActive = false,
195202
locateLabel,
196203
onLocate,
@@ -200,10 +207,11 @@ export default function MapControls({
200207
searchLabel,
201208
zoomInDisabled = false,
202209
zoomInLabel,
210+
zoomControlsLabel,
203211
zoomOutLabel,
204212
}: MapControlClusterProps) {
205213
return (
206-
<ControlAnchor $gap>
214+
<ControlAnchor $gap role="group" aria-label={controlsLabel}>
207215
{onSearch && searchLabel ? (
208216
<ControlButton
209217
type="button"
@@ -228,6 +236,7 @@ export default function MapControls({
228236
</ControlButton>
229237
) : null}
230238
<ZoomControlGroup
239+
controlsLabel={zoomControlsLabel}
231240
onZoomIn={onZoomIn}
232241
onZoomOut={onZoomOut}
233242
zoomInDisabled={zoomInDisabled}

src/features/map/components/MapPinLayer.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { hasValidCoordinates } from "../lib/mapUtils";
1515

1616
type MapPinLayerProps = {
1717
listings: ListingMarker[];
18+
markerLabel: string;
1819
selectedListingId: number | null;
1920
onMarkerClick: (listing: ListingMarker) => void;
2021
};
@@ -23,6 +24,7 @@ type ListingMapPinMarkerProps = {
2324
listing: ListingMarker;
2425
coords: ListingCoordinates;
2526
isSelected: boolean;
27+
markerLabel: string;
2628
onMarkerClick: MapPinLayerProps["onMarkerClick"];
2729
};
2830

@@ -36,6 +38,7 @@ function ListingMapPinMarker({
3638
listing,
3739
coords,
3840
isSelected,
41+
markerLabel,
3942
onMarkerClick,
4043
}: ListingMapPinMarkerProps) {
4144
const markerRef = useRef<MarkerInstance | null>(null);
@@ -51,6 +54,8 @@ function ListingMapPinMarker({
5154
if (!markerElement) return;
5255

5356
markerElement.tabIndex = 0;
57+
markerElement.setAttribute("role", "button");
58+
markerElement.setAttribute("aria-label", markerLabel);
5459

5560
const activateFromKeyboard = (event: KeyboardEvent) => {
5661
lastKeyboardActivationRef.current = event.timeStamp;
@@ -86,10 +91,13 @@ function ListingMapPinMarker({
8691

8792
return () => {
8893
isSpaceActivationPendingRef.current = false;
94+
markerElement.removeAttribute("aria-label");
95+
markerElement.removeAttribute("role");
96+
markerElement.removeAttribute("tabindex");
8997
markerElement.removeEventListener("keydown", handleMarkerKeyDown);
9098
markerElement.removeEventListener("keyup", handleMarkerKeyUp);
9199
};
92-
}, [listing, onMarkerClick]);
100+
}, [listing, markerLabel, onMarkerClick]);
93101

94102
const handlePinClick = (event: ReactMouseEvent<HTMLDivElement>) => {
95103
event.preventDefault();
@@ -146,6 +154,7 @@ function ListingMapPinMarker({
146154

147155
export default function MapPinLayer({
148156
listings,
157+
markerLabel,
149158
selectedListingId,
150159
onMarkerClick,
151160
}: MapPinLayerProps) {
@@ -163,6 +172,7 @@ export default function MapPinLayer({
163172
listing={listing}
164173
coords={coords}
165174
isSelected={isSelected}
175+
markerLabel={markerLabel}
166176
onMarkerClick={onMarkerClick}
167177
/>
168178
);

src/features/map/components/MapView.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,8 @@ export default function MapView({
493493
return (
494494
<MapContainer
495495
ref={mapContainerRef}
496+
role="region"
497+
aria-label={t("mapRegionLabel")}
496498
data-testid="map-view"
497499
style={initialMapPinZoomStyleRef.current ?? undefined}
498500
>
@@ -524,6 +526,7 @@ export default function MapView({
524526

525527
<MapPinLayer
526528
listings={listings}
529+
markerLabel={t("markerLabel")}
527530
selectedListingId={selectedListingId}
528531
onMarkerClick={onMarkerClick}
529532
/>
@@ -533,12 +536,13 @@ export default function MapView({
533536
latitude={userCoordinates.latitude}
534537
anchor="center"
535538
>
536-
<UserLocationDot />
539+
<UserLocationDot aria-hidden="true" />
537540
</Marker>
538541
) : null}
539542
</Map>
540543

541544
<MapControls
545+
controlsLabel={t("controlsLabel")}
542546
locateActive={Boolean(userCoordinates)}
543547
locateLabel={t("locateControl")}
544548
onLocate={handleLocate}
@@ -548,6 +552,7 @@ export default function MapView({
548552
searchLabel={t("searchLabel")}
549553
zoomInDisabled={isZoomInDisabled}
550554
zoomInLabel={t("zoomInControl")}
555+
zoomControlsLabel={t("zoomControlsLabel")}
551556
zoomOutLabel={t("zoomOutControl")}
552557
/>
553558
<MapSearch
@@ -558,11 +563,15 @@ export default function MapView({
558563
/>
559564
</>
560565
) : (
561-
<LoadingChip>{t("loadingPins")}</LoadingChip>
566+
<LoadingChip role="status" aria-live="polite">
567+
{t("loadingPins")}
568+
</LoadingChip>
562569
)}
563570

564571
{hasInitialPosition && isFetching && (
565-
<LoadingChip>{t("loadingPins")}</LoadingChip>
572+
<LoadingChip role="status" aria-live="polite">
573+
{t("loadingPins")}
574+
</LoadingChip>
566575
)}
567576

568577
{showReturnButton && (

0 commit comments

Comments
 (0)