gpbl / react-day-picker

DayPicker is a customizable date picker component for React. Add date pickers, calendars, and date inputs to your web applications.
https://daypicker.dev
MIT License
5.86k stars 700 forks source link

Wrong type for DayProps[rootProps] #2223

Open ArthurGoupil opened 6 days ago

ArthurGoupil commented 6 days ago

Description

Hello!

In DayProps, the provided rootProps are supposed to be applied on a div.

export declare function Day(props: {
    day: CalendarDay;
    modifiers: DayModifiers;
    children?: ReactNode;
    rootProps: Pick<JSX.IntrinsicElements["div"], "className" | "style" | "tabIndex" | "aria-colindex" | "aria-disabled" | "aria-hidden" | "aria-label" | "aria-selected" | "onClick" | "onBlur" | "onFocus" | "onKeyDown" | "onKeyPress" | "onKeyUp" | "onMouseEnter" | "onMouseLeave" | "onPointerEnter" | "onPointerLeave" | "onTouchCancel" | "onTouchEnd" | "onTouchMove" | "onTouchStart" | "ref" | "role">;
}): React.JSX.Element;
export type DayProps = Parameters<typeof Day>[0];

If I'm not wrong this is not great for accessibility:

gpbl commented 6 days ago

Hi @ArthurGoupil thanks for your feedback - in this case I believe the linter warning is a false positive, as the interactive element is marked as a grid cell and reacts to user interactions - such as click or focus.

ArthurGoupil commented 5 days ago

Not sure to understand, even with the gridcell role, the div is not supposed to be interactive right?

Actually, I wanted to implement the following behaviour: for a vertical 6 months calendar, display directly the selected date even if it's 3 months later (so automatic scroll if needed). The only way I found to handle this is with an autofocus. The autofocus doesn't work with the gridcell div, while it does with a button.

Benrajalu commented 5 days ago

Hello @gpbl, I don't understand the correlation between the role="gridcell" and interactivity 🤔 If anything the current output is <div role="gridcell" onClick="..." tabIndex="...."> but gridcell is not parsed as interactive by screen readers 🤔

Running Voiceover on this https://codesandbox.io/p/sandbox/rendering-test-react-day-picker-v9-3kwpm8?file=/src/index.tsx I never get prompted to click, only the day's number is being read.

gpbl commented 5 days ago

@Benrajalu thanks for the feedback, yeah I agree we should consider again the button there.

What is your suggestion here? What is the correct ARIA tree?

I'll try with a grid cell wrapping a Button element, hopefully will make VoiceOver happier.

<div role="gridcell" aria-selected={true}>
  <button tabIndex={1}> 
    {date}
  </button>
</div>
Benrajalu commented 4 days ago

That does seem better yes, gridCell for the layout, button for the interaction!