Skip to content

Commit 7323f9d

Browse files
committed
docs: update accessibility notes for input fields
Signed-off-by: gpbl <io@gpbl.dev>
1 parent 67792b7 commit 7323f9d

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

examples/Dialog.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export function Dialog() {
2121

2222
// Function to toggle the dialog visibility
2323
const toggleDialog = () => setIsDialogOpen(!isDialogOpen);
24+
const calendarLabel = `Calendar, ${format(month, "MMMM yyyy")}`;
2425

2526
// Hook to handle the body scroll behavior and focus trapping. You may want to
2627
// use your own trapping library as the body.style overflow will break the
@@ -82,7 +83,7 @@ export function Dialog() {
8283
type="button"
8384
style={{ fontSize: "inherit" }}
8485
onClick={toggleDialog}
85-
aria-controls="dialog"
86+
aria-controls={dialogId}
8687
aria-haspopup="dialog"
8788
aria-expanded={isDialogOpen}
8889
aria-label="Open calendar to choose booking date"
@@ -102,19 +103,24 @@ export function Dialog() {
102103
onClose={() => setIsDialogOpen(false)}
103104
>
104105
{isDialogOpen && (
105-
<DayPicker
106-
defaultMonth={selectedDate || month}
107-
onMonthChange={setMonth}
108-
autoFocus
109-
mode="single"
110-
selected={selectedDate}
111-
onSelect={handleDayPickerSelect}
112-
footer={
113-
selectedDate !== undefined && (
114-
<>Selected: {selectedDate.toDateString()}</>
115-
)
116-
}
117-
/>
106+
<>
107+
<h2 id={headerId}>Choose a date</h2>
108+
<DayPicker
109+
defaultMonth={selectedDate || month}
110+
onMonthChange={setMonth}
111+
autoFocus
112+
role="application"
113+
aria-label={calendarLabel}
114+
mode="single"
115+
selected={selectedDate}
116+
onSelect={handleDayPickerSelect}
117+
footer={
118+
selectedDate !== undefined && (
119+
<>Selected: {selectedDate.toDateString()}</>
120+
)
121+
}
122+
/>
123+
</>
118124
)}
119125
</dialog>
120126
</div>

website/docs/guides/input-fields.mdx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ Implementing the date picker as a dialog requires careful consideration of acces
9797

9898
In this example, we use the native HTML `<dialog>` element, which provides a built-in way to create a modal dialog. You can replace the native `<dialog>` element with a custom dialog component or a modal library that fits your application's design and accessibility requirements.
9999

100+
If a screen reader keeps the arrow keys for browse mode (for example, NVDA), set `role="application"` on the calendar root and make sure it has an accessible name that includes the current month (for example, "Calendar, September 2025"). This prompts focus mode so arrow-key navigation works inside the calendar.
101+
100102
<BrowserWindow>
101103
<Examples.Dialog />
102104
</BrowserWindow>
@@ -126,6 +128,7 @@ export function Dialog() {
126128

127129
// Function to toggle the dialog visibility
128130
const toggleDialog = () => setIsDialogOpen(!isDialogOpen);
131+
const calendarLabel = `Calendar, ${format(month, "MMMM yyyy")}`;
129132

130133
// Hook to handle the body scroll behavior and focus trapping
131134
useEffect(() => {
@@ -185,7 +188,7 @@ export function Dialog() {
185188
<button
186189
style={{ fontSize: "inherit" }}
187190
onClick={toggleDialog}
188-
aria-controls="dialog"
191+
aria-controls={dialogId}
189192
aria-haspopup="dialog"
190193
aria-expanded={isDialogOpen}
191194
aria-label="Open calendar to choose booking date"
@@ -205,10 +208,13 @@ export function Dialog() {
205208
aria-labelledby={headerId}
206209
onClose={() => setIsDialogOpen(false)}
207210
>
211+
<h2 id={headerId}>Choose a date</h2>
208212
<DayPicker
209213
month={month}
210214
onMonthChange={setMonth}
211215
autoFocus
216+
role="application"
217+
aria-label={calendarLabel}
212218
mode="single"
213219
selected={selectedDate}
214220
onSelect={handleDayPickerSelect}

0 commit comments

Comments
 (0)