import { useMemo, useCallback, useRef, useState } from 'react'; import cx from 'classnames'; import formatFn from 'date-fns/format'; import parse from 'date-fns/parse'; import PickerPopover from './PickerPopover'; import { SingleInputTrigger } from './PickerTrigger'; import PanelContext from '../context/PanelContext'; import useTimeValue from '../hooks/useTimeValue'; import useConfirmStatus from '../hooks/useConfirmStatus'; import { useEventCallbackRef } from '../../utils/hooks/useEventCallbackRef'; import pick from '../../utils/pick'; import { triggerCommonProps, timePanelProps, defaultTimePickerProps, } from '../constants'; import { ISingleTimePickerPropsWithDefault, ITimePanelProps, SingleTime, } from '../types'; import useSinglePopoverVisible from '../hooks/useSinglePopoverVisible'; const emptyTime: SingleTime = ''; const PanelContextProvider = PanelContext.Provider; interface ITimePickerBaseProps extends ISingleTimePickerPropsWithDefault { ContentComponent: React.ComponentType; seperator?: string; } const TimePickerBase: React.FC = ({ onChange, disabledTime, onOpen, onClose, value, className, ContentComponent, defaultTime, selectedDate, autoComplete, disabled, ...restProps }) => { const restPropsRef = useRef(restProps); restPropsRef.current = restProps; const { format, openPanel } = restPropsRef.current; const onChangeRef = useEventCallbackRef(onChange); const [visibleChange, setVisibleChange] = useState(true); const { selected, setSelected } = useTimeValue(emptyTime, value); const { panelVisible, setPanelVisible, onVisibleChange } = useSinglePopoverVisible( value ?? emptyTime, setSelected, onOpen, onClose, disabled, openPanel ); const disabledTimeOption = useMemo( () => disabledTime?.(selectedDate) || {}, [disabledTime, selectedDate] ); const confirmStatus = useConfirmStatus({ selected, disabledTimeOption, format, }); const currentTime = useMemo(() => formatFn(new Date(), format), [format]); const selectCurrentDate = useMemo( () => parse(currentTime, format, selectedDate), [currentTime, format, selectedDate] ); const isDisabledCurrent = useConfirmStatus({ selected: currentTime, disabledTimeOption: disabledTime?.(selectCurrentDate) || {}, format, }); const onSelected = useCallback( (val, finished = false) => { setVisibleChange(false); setSelected(val); if (finished || autoComplete) { onChangeRef.current?.(val); finished && setVisibleChange(true); finished && setPanelVisible(openPanel ?? false); } }, [openPanel, onChangeRef, setSelected, setPanelVisible, autoComplete] ); const onClearInput = useCallback( evt => { evt.stopPropagation(); onChangeRef.current?.(emptyTime); }, [onChangeRef] ); const trigger = useMemo(() => { const { hiddenIcon } = restPropsRef.current; const triggerProps = pick(restPropsRef.current, triggerCommonProps); return (
); }, [value, selected, panelVisible, restPropsRef, disabled, onClearInput]); const content = useMemo(() => { const commonPanelProps = pick(restPropsRef.current, timePanelProps); return (
); }, [ selected, restPropsRef, defaultTime, disabledTimeOption, onSelected, ContentComponent, ]); return (
); }; TimePickerBase.defaultProps = defaultTimePickerProps; export default TimePickerBase;