-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve accessibility for DatePicker #793
Conversation
🦋 Changeset detectedLatest commit: 7f99fd8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
const calendarAriaLabel = calendarProps["aria-label"]; | ||
|
||
const ariaLabel = | ||
t(texts.calendar) + (calendarAriaLabel ? ` ${calendarAriaLabel}` : ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a slightly better aria-label than just, e.g, "august 2023". The result will be "Calendar august 2023". The August 2023 part comes from the React Aria calendarProps
) { | ||
// Don't submit the form | ||
e.stopPropagation(); | ||
state.setOpen(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I struggled finding that this code is really doing anything, other than creating confusion... I tried using Enter within the input field, but the calendar does not open...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm that's unfortunate. Without this code, there isn't really any way a screen reader can trigger the calendar.
Not much of a difference since it didn't work anyways, but we should probably find a way to trigger the calendar for the simple variant, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The normal way to open stuff when navigating with a screen reader is in fact by using space, not enter - and that works in the simple variant when I focus at the label. But keyboard users will not be able to focus on this element.. I do not know what has been discussed about the simple variant, but maybe rather it should open automatically when receiving focus as there is no actual indication that the user should press either space or enter in the input field to open it.
But I will leave it as is until now and this can be discussed separately 👍
@@ -38,7 +38,6 @@ export const DateTimeSegment = forwardRef<HTMLDivElement, DateTimeSegmentProps>( | |||
...segmentProps.style, | |||
fontVariantNumeric: "tabular-nums", | |||
boxSizing: "content-box", | |||
color: colors.darkGrey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This unfortunately overwrote the focused style as well, so moved it to dateTimeSegment:
instead
{...fieldProps} | ||
/> | ||
</StyledField> | ||
</PopoverAnchor> | ||
{hasTrigger && <CalendarTriggerButton {...buttonProps} />} | ||
{hasTrigger && ( | ||
<PopoverTrigger> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to say that this is really an impressive piece of work and not least the effort you have put in to solve the challenges 💪🌟 Well described and comprehensive summary!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 on what Ana Maria said. Great job here Heidi! 🙌
) { | ||
// Don't submit the form | ||
e.stopPropagation(); | ||
state.setOpen(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm that's unfortunate. Without this code, there isn't really any way a screen reader can trigger the calendar.
Not much of a difference since it didn't work anyways, but we should probably find a way to trigger the calendar for the simple variant, right?
Background
There are some accessibility issues with the DatePicker (and consequently the DateRangePicker):
Other issues:
Solution
Make it possible to navigate with keyboard in the calendar:
First, study React Aria's example to see if there are any props we are missing:
-
hidden={isOutsideVisibleRange}
helps navigate in the calendar with tab.Secondly, study Entur's DatePicker, who also use the same library as us:
- To be able to tab easily inside the DatePicker, we can use a
FocusLock
around theCalendar
, since we here really do not want to end up outside of the calendar unexpectedly.Raise this issue in the
react-spectrum
repo. They made a workaround we await release on, while the original bug is reported to Chrome.Make sure focus is reset to the calendar button when closed. This way, the next focusable element will be the next logical element. The way this is achieved, is wrapping the
CalendarTriggerButton
in aPopoverTrigger
, which handles this for us. When using a PopoverTrigger, the focusable child must have aforwarded ref
. The button then also needs the date pickerref
instead of the input.Add visual focus to today's date in the calendar when it is focused.
Correct the language codes used in React Aria's
useState
so that everything announced by the screen reader is in the same and correct language.For the bugginess around closing the calendar with the button:
This is a little hard nut because we here are using the Popover from Chakra and not from React Aria. If we simply had used the Popover from React Aria, the open-close would handle itself the correct way. We use this Popover because we use the
PopoverAnchor
,PopoverPopoverArrow
, an so on from Chakra, which must be wrapped in the Chakra Popover.Then, we basically have two states, one for the Popover and another for the DatePicker (via
useDatePicker's state
). The Popover listens to outside clicks, escape clicks and so on, and the Popover can fireonOpen
andonClose
callbacks based on this. Here, we update the DatePicker's state to open and closed. If we did not do it this way, the first focusable element within the calendar is not set correctly (the first one should be today's date).The reason why the calendar closes and opens right away when clicking the trigger button while the calendar is open, is then because the Popover notices we press outside the calendar and closes the state, while the trigger button then opens it again since the state just got closed.
This is also fixed by using the PopoverTrigger. The other props,
returnFocusOnClose
etc., specified for the Popover is really then not needed since they did not work as intended anyway.In addition to this:
Since we had problems with portals for the ComboBox, add
withPortal
as an optional prop so that using a Portal or not is optional.Will then also solve #731.