Skip to content
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

add an example of a controlled date range picker #14

Closed
SSmJaE opened this issue Mar 1, 2023 · 3 comments
Closed

add an example of a controlled date range picker #14

SSmJaE opened this issue Mar 1, 2023 · 3 comments

Comments

@SSmJaE
Copy link

SSmJaE commented Mar 1, 2023

great repo 👍

i have found #4
but this doesn't provide a complete example
so with some struggle, i finally got this

maybe we could add this example to the readme? for someone like controlled style component like me

export function DateRangePicker({
    value,
    onChange,
}: {
    value: [Dayjs, Dayjs];
    onChange: (value: [Dayjs, Dayjs]) => void;
}) {
    const [selectedDates, onDatesChange] = useState([
        value[0].startOf("day").toDate(),
        value[1].endOf("day").toDate(),
    ]);

    const {
        data: { weekDays, calendars, selectedDates: currentSelectedDates },
        propGetters: { dayButton, previousMonthButton, nextMonthButton },
    } = useDatePicker({
        dates: {
            mode: "range",
        },
        selectedDates,
        onDatesChange,
    });

    // The local state needs to be updated when the parent component's state changes
    useEffect(() => {
        onDatesChange([value[0].startOf("day").toDate(), value[1].endOf("day").toDate()]);
    }, [value]);

    useEffect(() => {
        if (currentSelectedDates.length === 2) {
            onChange([
                dayjs(currentSelectedDates[0]).startOf("day"),
                dayjs(currentSelectedDates[1]).endOf("day"),
            ]);
        }
    }, [currentSelectedDates]);
@Feshchenko
Copy link
Contributor

Feshchenko commented Mar 1, 2023

@SSmJaE , hi, thanks for the issue.
I think I do not get it at all. The date picker is controlled by the design 🤷‍♂️
In all examples from README you can see these lines 👇

  const [selectedDates, onDatesChange] = useState<Date[]>([]);
  const dpState = useDatePickerState({
    selectedDates,
    onDatesChange,
    dates: { toggle: true, mode: 'multiple' },
  });

You don't need to create a local state and then call onChange
Just make sure that the value is an array of dates and that onChange accepts an array of dates.
If you need to make a date transformation to the dayjs you can make it in the parent component before submission.
The example above should look like this:

export function DateRangePicker({
    value,
    onChange,
}: {
    value: Date[];
    onChange: (value: Date[]) => void;
}) {
    const {
        data: { weekDays, calendars },
        propGetters: { dayButton, previousMonthButton, nextMonthButton },
    } = useDatePicker({
        dates: {
            mode: "range",
        },
        selectedDates: value,
        onDatesChange: onChange,
  });

  return (COMPONENT GOES HERE);
}

Everything else in your code is redundant! 😉

@SSmJaE
Copy link
Author

SSmJaE commented Mar 2, 2023

@Feshchenko thanks for quick response

actually, i have tried what you mentioned earlier
onDatesChange has a problem that, whenever a dayButton is click, it will trigger this callback

so if I log like this

onDatesChange : (value) => {
    console.log({
        valueInPicker: value,
    });
}

it will output

{
    valueInPicker : [ Date() ] // not [ Date(), Date() ]
}

what i want is, the prop onChange callback to only fire when the range selection is done
I haven't found a related explantion in the readme, maybe there is a better way to achieve this?

@Feshchenko
Copy link
Contributor

Feshchenko commented Mar 2, 2023

@SSmJaE yes, you are right.
You need to check it manually, for example inside onDateChange which you are passing as a prop.
Actually, this is an implementation detail.

const [selectedDates, setDates] = useState<Date[]>([]);

const onChange = () => {
  console.log('Send me to the BE');
}

const onDateChange = (dates: Date[]) => {
  setDates(dates);
  if(dates.length === 2) onChange(dates);
}

We have the Discord for live help. I'm trying to answer and help as soon as I can :)

@SSmJaE SSmJaE changed the title add controlled component example to readme add an example of a controlled date range picker Mar 2, 2023
@SSmJaE SSmJaE closed this as completed Mar 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants