reactjs - Hur lägger man till aria-labels dynamiskt till DayPicker-komponenten i React?
Jag arbetar på ett React-projekt där jag behöver göra DayPicker-komponenten tillgänglig genom att lägga till dynamiska aria-etiketter till enskilda daged element baserat på deras tillstånd (t.ex. valda, inaktiverade, begränsade eller otillgängliga).
Här är koden jag för närvarande använder för DayPicker:
<DayPicker
mode="single"
selected={calendarDates.selected}
onDayClick={setDate}
showOutsideDays
disabled={{ before: startDate, after: endDate }}
modifiers={{
limited: calendarDates.limited,
unavailable: calendarDates.unavailable,
}}
modifiersStyles={{
limited: limitedStyle,
unavailable: unavailableStyle,
}}
/>
Problembeskrivning:
Jag vill:
- Lägg till dynamiska aria-etiketter för varje dag i kalendern baserat på dess status (t.ex. "Valt datum: 1 januari 2024", "Otillgängligt datum: 2 januari 2024").
- Se till att dessa aria-etiketter är åtkomliga för skärmläsare.
Vad jag försökte:
Jag försökte använda en ariaLabelFormatter-prop, men det verkar som att biblioteket inte stöder det (Egenskapen 'ariaLabelFormatter' finns inte på typen 'DayPicker').
Jag tittade på att använda en renderDay-prop, men den är också otillgänglig.
Jag försökte manipulera DOM efter renderingen med useRef och useEffect, så här:
useEffect(() => {
if (calendarRef.current) {
const days = calendarRef.current.querySelectorAll(".rdp-day"); // Adjusted selector
days.forEach((day) => {
const date = day.getAttribute("aria-label");
let ariaLabel = date;
if (day.classList.contains("rdp-day_selected")) {
ariaLabel = `Selected date: ${date}`;
} else if (day.classList.contains("rdp-day_disabled")) {
ariaLabel = `${date} is not available for selection.`;
}
day.setAttribute("aria-label", ariaLabel || date);
});
}
}, [calendarDates]);
Men detta känns som en lösning på problemet och verkar inte pålitligt eftersom det beror på klassnamn och direkt DOM-manipulation. Jag använder följande versioner:
1. "react": "^18.2.0",
2. "react-datepicker": "^6.6.0",
3. "react-day-picker": "^8.10.0",
Svar #1
react-day-picker nyaste versioner erbjuder redan ett API för att anpassa vilka komponenter som ska användas vid rendering. Vi kan dra nytta av det genom att skicka den standard Day-komponenten, eller någon annan du väljer, och lägga till egna props.
Denna Day-nyckel inuti components-prop är en funktion, som tar dagen och en uppsättning modifierare. Granska signaturen för fullständig referens. Inuti den första parametern för den funktionen kan du komma åt de egenskaper du hänvisar till, om dagen är den valda, om det är idag, om den är inaktiverad...
Här är en liten bit om hur du kan uppnå ditt mål. Resten av logiken är upp till dig.
Om du använder 8.x har du bara själva dagen, så du måste hantera alla valideringar själv: avgöra om dagen är vald, inaktiverad, osv.
import { DayPicker, Day } from "react-day-picker";
import "react-day-picker/style.css";
export default function App() {
return (
<DayPicker
mode="single"
components={{
Day: (props) => {
const { disabled, selected, focused, hidden, outside, today } =
props.modifiers;
return (
<Day
{...props}
{...(selected && {
["aria-label"]: "Selected Date: " + props.day.date,
})}
/>
);
},
}}
/>
);
}
Svar #2
Som föreslagits även i kommentarerna
Alternativ 1: Uppgradera till de senaste paketversionerna
Alternativ 2: Håll dig till din useEffect-implementation med klasser eftersom det inte finns någon risk att ändra classNames om du håller dig till en specifik version.
