gpbl / react-day-picker

DayPicker is a customizable date picker component for React. Add date pickers, calendars, and date inputs to your web applications.

Home Page:https://daypicker.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug: Using numberOfMonths >= 2, the dropdowns that are past the toDate should be disabled.

ZakisM opened this issue · comments

commented

Bug description

The dropdowns that are out of range should be disabled if they are after toDate.

To reproduce

https://codesandbox.io/s/react-daypicker-forked-ymyrvh

Steps

  1. On the first calendar, set the month to December and the Year to 2025.

Expected behavior

The dropdown for the month January and dropdown for the year 2026 should be disabled, as this is out of range. The arrow is disabled correctly in this case, but the dropdowns are not.

Screenshots

Screenshot 2023-06-20 at 11 18 38

Additional context

It's possible to fix this currently but it requires duplicating a lof the components and creating a custom Caption component. If we had access to the displayMonth prop inside of the Dropdown component it would make it possible to disable this, which would also be useful:

For example a custom Dropdown Component with our own data-disabled prop.

const DropdownCustom = (props: DropdownCustomPropsType): ReactElement => {
    const { onChange, value, children, caption, className, style } = props;
    const dayPicker = useDayPicker();

    const IconDropdownComponent = dayPicker.components?.IconDropdown ?? IconDropdown;

    return (
        <div className={className} style={style} data-disabled={isAfter(displayMonth, dayPicker.toDate!)}>
            <span className={dayPicker.classNames.vhidden}>{props["aria-label"]}</span>
            <select
                name={props.name}
                aria-label={props["aria-label"]}
                className={dayPicker.classNames.dropdown}
                style={dayPicker.styles.dropdown}
                value={value}
                onChange={onChange}
                disabled={disabled === true ? true : undefined}>
                {children}
            </select>
            <div
                className={dayPicker.classNames.caption_label}
                style={dayPicker.styles.caption_label}
                aria-hidden="true">
                {caption}
                {
                    <IconDropdownComponent
                        className={dayPicker.classNames.dropdown_icon}
                        style={dayPicker.styles.dropdown_icon}
                    />
                }
            </div>
        </div>
    );
};`

Hey @ZakisM thanks for your report, definitely there's space for improvements here. Will check it out better later.

If we had access to the displayMonth prop inside of the Dropdown component it would make it possible to disable this, which would also be useful:

There's a way to know the displayMonths: the useNavigation hook returns that information and it is accessible by a custom component:

https://codesandbox.io/s/react-daypicker-forked-62vjs7?file=/src/App.tsx:213-314

import { useNavigation } from "react-day-picker";

function CustomDropdown(props: DropdownProps) {
  const navigation = useNavigation();
  console.log("Displayed months: ", navigation.displayMonths);
  return <Dropdown {...props} />;
}
commented

Hey, I think I tried this, however when you have multiple months an array is returned. How would I then know which index I need to use for the CustomDropdown?

Hey, I think I tried this, however when you have multiple months an array is returned. How would I then know which index I need to use for the CustomDropdown?

Ah I think this is the reason I chose to not disable these dropdowns. I think this issue doesn't really affect the usability of DayPicker. What's the actual problem when the dropdown are not disabled?

commented

Ah I see, the issue is that when the dropdowns are not disabled, if I pick one of the months from the dropdown, the date picker is now showing dates that are outside of the fromDate/toDate I set:

recording.mov

With #1884 we are adding the displayIndex to the caption components. This could help fixing this issue too 🤔 .