♻️(react) refactor DatePicker component

Refactor the original DatePicker component to utilize the newly created shared
common DatePickerAux component. This modification enhances code consistency,
and promotes the reuse of the DatePickerAux across date inputs variants.
This commit is contained in:
Lebaud Antoine
2023-06-16 17:00:14 +02:00
committed by aleb_the_flash
parent 0d6b98ee1f
commit 114d0b5f2e
5 changed files with 137 additions and 204 deletions

View File

@@ -0,0 +1,86 @@
import React, { useMemo, useRef, useState } from "react";
import {
DatePickerStateOptions,
useDatePickerState,
} from "@react-stately/datepicker";
import { DateValue } from "@internationalized/date";
import { useDatePicker } from "@react-aria/datepicker";
import DatePickerAux, {
DatePickerAuxSubProps,
} from ":/components/Forms/DatePicker/DatePickerAux";
import { Calendar } from ":/components/Forms/DatePicker/Calendar";
import DateFieldBox from ":/components/Forms/DatePicker/DateField";
import { StringOrDate } from ":/components/Forms/DatePicker/types";
import {
getDefaultPickerOptions,
parseCalendarDate,
} from ":/components/Forms/DatePicker/utils";
export type DatePickerProps = DatePickerAuxSubProps & {
value?: null | StringOrDate;
label: string;
defaultValue?: StringOrDate;
onChange?: (value: string | null) => void | undefined;
};
const DatePicker = (props: DatePickerProps) => {
if (props.defaultValue && props.value) {
throw new Error(
"You cannot use both defaultValue and value props on DatePicker component"
);
}
const ref = useRef<HTMLDivElement>(null);
const [isFocused, setIsFocused] = useState(false);
const options: DatePickerStateOptions<DateValue> = {
...getDefaultPickerOptions(props),
value:
// Force clear the component's value when passing null or an empty string.
props.value === "" || props.value === null
? null
: parseCalendarDate(props.value),
defaultValue: parseCalendarDate(props.defaultValue),
onChange: (value: DateValue | null) => {
props.onChange?.(value?.toString() || "");
},
};
const pickerState = useDatePickerState(options);
const { fieldProps, calendarProps, ...pickerProps } = useDatePicker(
options,
pickerState,
ref
);
const labelAsPlaceholder = useMemo(
() => !isFocused && !pickerState.isOpen && !pickerState.value,
[pickerState.value, pickerState.isOpen, isFocused]
);
const calendar = <Calendar {...calendarProps} />;
return (
<DatePickerAux
{...{
...props,
labelAsPlaceholder,
isFocused,
pickerState,
pickerProps,
calendar,
onClear: () => pickerState.setValue(null as unknown as DateValue),
}}
ref={ref}
>
<DateFieldBox
{...{
...fieldProps,
label: props.label,
labelAsPlaceholder,
onFocusChange: setIsFocused,
}}
/>
</DatePickerAux>
);
};
export default DatePicker;