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.88k stars 702 forks source link

Empty inputField with useInput() is not behaving like unselect Date in DayPicker #2058

Closed Tim4497 closed 1 month ago

Tim4497 commented 4 months ago

Description

With the useInput Hook, when I unselect the date, the input field stays empty, when I empty the InputField, the selectedDate is reset to the initialDate.

Expected Behavior

Regardless of unselecting a date or deleting the whole date from the input, no date should be selected as long as the required attribute is not set.

Actual Behavior

After blurring the InputField it gets filled with the initial date again. Even if it looks in the Day Picker that the day was unselected by the InputField

(btw. I love how they play together and update each other on selecting/writing dates, great job!)

Steps to Reproduce

In https://playcode.io/react:

import React from 'react';
import { DayPicker, useInput } from 'react-day-picker';
import 'react-day-picker/dist/style.css';

export function App() {

  const { dayPickerProps, inputProps } = useInput({
    defaultSelected: new Date(),
    format: 'dd/MM/yyyy',
  });

  return (
    <div>
      <input {...inputProps} />
      <DayPicker {...dayPickerProps} />
    </div>
  );
}

Possible Solution

Screenshots

If applicable, add screenshots or GIFs to help explain your problem.

Your Environment

Tim4497 commented 4 months ago

My solution:

import React from 'react';
import { DayPicker, useInput } from 'react-day-picker';
import 'react-day-picker/dist/style.css';

export function App() {

  const { dayPickerProps, inputProps } = useInput({
    defaultSelected: new Date(),
    format: 'dd/MM/yyyy',
  });

const handleEmpty = ( e ) => {
    if ( !e.target.value ) {
      return;
    }
    inputProps.onBlur( e );
};

  return (
    <div>
      <input {...inputProps} onBlur={ handleEmpty } />
      <DayPicker {...dayPickerProps} />
    </div>
  );
}

And this might be the place to add the change to make it happen (useInput.ts:141):

// Special case for _required_ fields: on blur, if the value of the input is not
  // a valid date, reset the calendar and the input value.
  const handleBlur: FocusEventHandler<HTMLInputElement> = (e) => {
    const value = e.target.value;
    if(!required && !value.length) {
      return;
    }
    const day = parseValue(value);
    if (!isValidDate(day)) {
      reset();
    }
  };