diff --git a/src/components/DatePicker/DatePickerFieldTypeDate/DatePickerFieldTypeDate.tsx b/src/components/DatePicker/DatePickerFieldTypeDate/DatePickerFieldTypeDate.tsx index 271f397ab..d7a28b86b 100644 --- a/src/components/DatePicker/DatePickerFieldTypeDate/DatePickerFieldTypeDate.tsx +++ b/src/components/DatePicker/DatePickerFieldTypeDate/DatePickerFieldTypeDate.tsx @@ -29,7 +29,7 @@ export const DatePickerFieldTypeDate = React.forwardRef< ...otherProps } = props; - const inputRef = usePicker({ + const [inputRef, onClear] = usePicker({ format, separator, onChange, @@ -46,6 +46,7 @@ export const DatePickerFieldTypeDate = React.forwardRef< inputContainerRef={ref} inputRef={useForkRef([inputRef, inputRefProp])} placeholder={placeholder} + onClear={onClear} /> ); }); diff --git a/src/components/DatePicker/DatePickerFieldTypeDate/helpers.ts b/src/components/DatePicker/DatePickerFieldTypeDate/helpers.ts index 895402663..65c441c94 100644 --- a/src/components/DatePicker/DatePickerFieldTypeDate/helpers.ts +++ b/src/components/DatePicker/DatePickerFieldTypeDate/helpers.ts @@ -164,11 +164,7 @@ export const usePicker = (props: UsePickerProps) => { [minDate?.getTime(), maxDate?.getTime(), formatProp, separator], ); - const { - ref, - setValue: setStringValue, - value: stringValue, - } = useIMask( + const imaskProps = useIMask( { mask: Date as unknown as MaskedDate, pattern: formatProp, @@ -237,7 +233,13 @@ export const usePicker = (props: UsePickerProps) => { { onAccept }, ); - useStringValue(value, stringValue, formatProp, separator, setStringValue); + const handleClear = useStringValue( + value, + formatProp, + separator, + onChangeRef, + imaskProps, + ); - return ref; + return [imaskProps.ref, handleClear] as const; }; diff --git a/src/components/DatePicker/DatePickerFieldTypeDateTime/DatePickerFieldTypeDateTime.tsx b/src/components/DatePicker/DatePickerFieldTypeDateTime/DatePickerFieldTypeDateTime.tsx index eaa2a1660..10af72d09 100644 --- a/src/components/DatePicker/DatePickerFieldTypeDateTime/DatePickerFieldTypeDateTime.tsx +++ b/src/components/DatePicker/DatePickerFieldTypeDateTime/DatePickerFieldTypeDateTime.tsx @@ -32,7 +32,7 @@ export const DatePickerFieldTypeDateTime = React.forwardRef< ...otherProps } = props; - const inputRef = usePicker({ + const [inputRef, onClear] = usePicker({ onChange, value, onError, @@ -52,6 +52,7 @@ export const DatePickerFieldTypeDateTime = React.forwardRef< inputContainerRef={ref} inputRef={useForkRef([inputRef, inputRefProp])} placeholder={placeholder} + onClear={onClear} /> ); }); diff --git a/src/components/DatePicker/DatePickerFieldTypeDateTime/helpers.ts b/src/components/DatePicker/DatePickerFieldTypeDateTime/helpers.ts index a9347ee3e..d6f7599a1 100644 --- a/src/components/DatePicker/DatePickerFieldTypeDateTime/helpers.ts +++ b/src/components/DatePicker/DatePickerFieldTypeDateTime/helpers.ts @@ -193,11 +193,7 @@ export const usePicker = (props: UsePickerProps) => { [minDate?.getTime(), maxDate?.getTime(), formatProp, separator], ); - const { - ref, - setValue: setStringValue, - value: stringValue, - } = useIMask( + const imaskProps = useIMask( { mask: Date as unknown as MaskedDate, pattern: formatProp, @@ -319,7 +315,13 @@ export const usePicker = (props: UsePickerProps) => { { onAccept }, ); - useStringValue(value, stringValue, formatProp, separator, setStringValue); + const handleClear = useStringValue( + value, + formatProp, + separator, + onChangeRef, + imaskProps, + ); - return ref; + return [imaskProps.ref, handleClear] as const; }; diff --git a/src/components/DatePicker/DatePickerFieldTypeMonth/DatePickerFieldTypeMonth.tsx b/src/components/DatePicker/DatePickerFieldTypeMonth/DatePickerFieldTypeMonth.tsx index d16ea218f..4d928f146 100644 --- a/src/components/DatePicker/DatePickerFieldTypeMonth/DatePickerFieldTypeMonth.tsx +++ b/src/components/DatePicker/DatePickerFieldTypeMonth/DatePickerFieldTypeMonth.tsx @@ -29,7 +29,7 @@ export const DatePickerFieldTypeMonth = React.forwardRef< ...otherProps } = props; - const inputRef = usePicker({ + const [inputRef, onClear] = usePicker({ value, format, separator, @@ -46,6 +46,7 @@ export const DatePickerFieldTypeMonth = React.forwardRef< inputContainerRef={ref} inputRef={useForkRef([inputRef, inputRefProp])} placeholder={placeholder} + onClear={onClear} /> ); }); diff --git a/src/components/DatePicker/DatePickerFieldTypeMonth/helpers.ts b/src/components/DatePicker/DatePickerFieldTypeMonth/helpers.ts index de2d27c42..ffec7007c 100644 --- a/src/components/DatePicker/DatePickerFieldTypeMonth/helpers.ts +++ b/src/components/DatePicker/DatePickerFieldTypeMonth/helpers.ts @@ -160,11 +160,7 @@ export const usePicker = (props: UsePickerProps) => { [minDate?.getTime(), maxDate?.getTime(), formatProp, separator], ); - const { - ref, - setValue: setStringValue, - value: stringValue, - } = useIMask( + const imaskProps = useIMask( { mask: Date as unknown as MaskedDate, pattern: formatProp, @@ -224,7 +220,13 @@ export const usePicker = (props: UsePickerProps) => { { onAccept }, ); - useStringValue(value, stringValue, formatProp, separator, setStringValue); + const handleClear = useStringValue( + value, + formatProp, + separator, + onChangeRef, + imaskProps, + ); - return ref; + return [imaskProps.ref, handleClear] as const; }; diff --git a/src/components/DatePicker/DatePickerFieldTypeTime/DatePickerFieldTypeTime.tsx b/src/components/DatePicker/DatePickerFieldTypeTime/DatePickerFieldTypeTime.tsx index a3f404ee0..07e272052 100644 --- a/src/components/DatePicker/DatePickerFieldTypeTime/DatePickerFieldTypeTime.tsx +++ b/src/components/DatePicker/DatePickerFieldTypeTime/DatePickerFieldTypeTime.tsx @@ -32,7 +32,7 @@ export const DatePickerFieldTypeTime = React.forwardRef< ...otherProps } = props; - const inputRef = usePicker({ + const [inputRef, onClear] = usePicker({ value, onChange, onError, @@ -52,6 +52,7 @@ export const DatePickerFieldTypeTime = React.forwardRef< inputContainerRef={ref} inputRef={useForkRef([inputRef, inputRefProp])} placeholder={placeholder} + onClear={onClear} /> ); }); diff --git a/src/components/DatePicker/DatePickerFieldTypeTime/helpers.ts b/src/components/DatePicker/DatePickerFieldTypeTime/helpers.ts index c31dcc655..ab20e75d5 100644 --- a/src/components/DatePicker/DatePickerFieldTypeTime/helpers.ts +++ b/src/components/DatePicker/DatePickerFieldTypeTime/helpers.ts @@ -189,11 +189,7 @@ export const usePicker = (props: UsePickerProps) => { [minDate?.getTime(), maxDate?.getTime(), formatProp, separator], ); - const { - ref, - setValue: setStringValue, - value: stringValue, - } = useIMask( + const imaskProps = useIMask( { mask: Date as unknown as MaskedDate, pattern: formatProp, @@ -289,7 +285,13 @@ export const usePicker = (props: UsePickerProps) => { { onAccept }, ); - useStringValue(value, stringValue, formatProp, separator, setStringValue); + const handleClear = useStringValue( + value, + formatProp, + separator, + onChangeRef, + imaskProps, + ); - return ref; + return [imaskProps.ref, handleClear] as const; }; diff --git a/src/components/DatePicker/DatePickerFieldTypeYear/DatePickerFieldTypeYear.tsx b/src/components/DatePicker/DatePickerFieldTypeYear/DatePickerFieldTypeYear.tsx index 9f43538b4..6c73af86f 100644 --- a/src/components/DatePicker/DatePickerFieldTypeYear/DatePickerFieldTypeYear.tsx +++ b/src/components/DatePicker/DatePickerFieldTypeYear/DatePickerFieldTypeYear.tsx @@ -29,7 +29,7 @@ export const DatePickerFieldTypeYear = React.forwardRef< ...otherProps } = props; - const inputRef = usePicker({ + const [inputRef, onClear] = usePicker({ value, minDate, maxDate, @@ -46,6 +46,7 @@ export const DatePickerFieldTypeYear = React.forwardRef< inputContainerRef={ref} inputRef={useForkRef([inputRef, inputRefProp])} placeholder={placeholder} + onClear={onClear} /> ); }); diff --git a/src/components/DatePicker/DatePickerFieldTypeYear/helpers.ts b/src/components/DatePicker/DatePickerFieldTypeYear/helpers.ts index c827e442a..e58065195 100644 --- a/src/components/DatePicker/DatePickerFieldTypeYear/helpers.ts +++ b/src/components/DatePicker/DatePickerFieldTypeYear/helpers.ts @@ -161,11 +161,7 @@ export const usePicker = (props: UsePickerProps) => { [minDate?.getTime(), maxDate?.getTime(), formatProp, separator], ); - const { - ref, - setValue: setStringValue, - value: stringValue, - } = useIMask( + const imaskProps = useIMask( { mask: Date as unknown as MaskedDate, pattern: formatProp, @@ -215,7 +211,13 @@ export const usePicker = (props: UsePickerProps) => { { onAccept }, ); - useStringValue(value, stringValue, formatProp, separator, setStringValue); + const handleClear = useStringValue( + value, + formatProp, + separator, + onChangeRef, + imaskProps, + ); - return ref; + return [imaskProps.ref, handleClear] as const; }; diff --git a/src/components/DatePicker/helpers.ts b/src/components/DatePicker/helpers.ts index d17bd8984..49b3e06be 100644 --- a/src/components/DatePicker/helpers.ts +++ b/src/components/DatePicker/helpers.ts @@ -1,5 +1,8 @@ import { format, isValid, parse, startOfToday } from 'date-fns'; -import { useEffect } from 'react'; +import { useCallback, useEffect } from 'react'; +import { useIMask } from 'react-imask'; + +import { useMutableRef } from '##/hooks/useMutableRef'; import { range } from '../../utils/array'; import { DateRange } from '../../utils/types/Date'; @@ -147,16 +150,39 @@ export const getFieldName = ( export const getDropdownZIndex = (style?: React.CSSProperties) => typeof style?.zIndex === 'number' ? style.zIndex + 1 : undefined; +type DatePickerFieldTypeDatePropOnChange = ( + value: Date | null, + props: { + e: Event; + }, +) => void; + export const useStringValue = ( value: Date | undefined | null, - stringValue: string, formatProp: string, separator: string, - setStringValue: React.Dispatch, + onChangeRef: React.MutableRefObject< + DatePickerFieldTypeDatePropOnChange | undefined + >, + imaskProps: ReturnType, ) => { + const stringValue = imaskProps.value; + + const refs = useMutableRef([imaskProps.setValue, value] as const); + + const handleClear: React.MouseEventHandler = useCallback( + (e) => { + refs.current[0](''); + if (refs.current[1]) { + onChangeRef.current?.(null, { e: e as unknown as Event }); + } + }, + [], + ); + useEffect(() => { if (value && isValid(value)) { - setStringValue(format(value, formatProp)); + refs.current[0](format(value, formatProp)); } if (!value && stringValue) { @@ -176,8 +202,10 @@ export const useStringValue = ( : undefined; if (isValid(date)) { - setStringValue(''); + refs.current[0](''); } } }, [value?.getTime()]); + + return handleClear; };