1.2.0 • Published 1 year ago

@ws-serenity/react-datepicker v1.2.0

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
1 year ago

DatePicker

Repository

About

Кастомный datepicker, основаный на react-datepicker \ В зависимости от значения пропса use может использоваться без дополнительной обертки в виде Controller вместе с react-hook-form \ Сообщение об ошибке всегда располагается под инпутом дейтпикера. Чтобы разметка "не прыгала", используется флаг reserveSpaceForError.

type DatePickerBaseProps = {
    // подпись к дейтпикеру
    label?: string;
    // флаг для расположения подписи сверху
    topLabel?: boolean;
    // отображать поле, как обязательное (красная звездочка)
    showRequired?: boolean;
    // сообщение об ошибке
    error?: string;
    // класс для всего компонента
    className?: string;
    // зарезервировать место для ошибки
    reserveSpaceForError?: boolean;
}

use={'on-change'}

export type DatePickerProps = {
    use: 'on-change';
} & DatePickerBaseProps & Omit<ReactDatePickerProps, 'className' | 'required'>
Пример использования
function SimpleDatePicker() {
    const [ isDatePickerOpened, setIsDatePickerOpened ] = useState(false);
    const [ date, setDate ] = useState<Date>(new Date);

    const onDatePickerChange = (date: Date | null) => {
        if (date) setDate(date);
        setIsDatePickerOpened(false);
    };

    return (
        <DatePicker
          onInputClick={() => setIsDatePickerOpened(!isDatePickerOpened)}
          selected={date}
          use={'on-change'}
          onChange={onDatePickerChange}
          open={isDatePickerOpened}
          onClickOutside={() => setIsDatePickerOpened(false)}
        />
    );
}

use={'hook-form'}

Компонент с пропсом use={'hook-form'} не нуждается в обертке контроллером

export type ControllableDatePickerProps<TType extends FieldValues> = {
    use: 'hook-form';
} & DatePickerBaseProps & Controllable<TType> & Omit<ReactDatePickerProps, 'onChange' | 'className' | 'required'>
Пример использования
type SimpleForm = {
    name: string;
    date: Date;
}

function SimpleForm() {
    const [ isDatePickerOpened, setIsDatePickerOpened ] = useState(false);
    const {
        control,
        register,
        formState: { isValid },
        handleSubmit,
    } = useForm<SimpleForm>();

    const onSubmit = (data: SimpleForm) => {
        alert(`${data.name} ${format(data.date, 'dd.MM.yyyy')}`);
    };

    return (
        <section className={'simple-form'}>
            <form className={'simple-form__form'}>
                <input
                  type={'text'}
                  {...register('name')}
                />
                <DatePicker
                  onInputClick={() => setIsDatePickerOpened(!isDatePickerOpened)}
                  use={'hook-form'}
                  open={isDatePickerOpened}
                  onClickOutside={() => setIsDatePickerOpened(false)}
                  onSelect={() => setIsDatePickerOpened(false)}
                  control={control}
                  name={'date'}
                />
                <button
                  disabled={!isValid}
                  onClick={handleSubmit(onSubmit)}
                  className={'simple-form__button'}
                  type={'submit'}
                >
                    Add
                </button>
            </form>
        </section>
    );
}

Оптимизация зависимостей

Из библиотеки была удалена дефолтная ru-локаль, потому что далеко не факт, что библиотека будет использоваться под приложение с русской локалью.

Если все же понадобится русская локаль:

Зависимости date-fns и date-fns/locale/ru считаются бандлером как разные. Поэтому необходимо явно указать, что это тоже peer-зависимость:

// inside vite.config
packageJson.peerDependencies['date-fns/locale/ru'] = '*'

TS будет жаловаться на такую 👆🏻 наглость. Стоит написать типы для package.json модуля. В крайнем случае // @ts-ignore вам в помощь