import cx from 'classnames'; import { useCallback, useMemo, useRef, useState } from 'react'; import PickerPopover from './PickerPopover'; import { CombinedInputTrigger } from './PickerTrigger'; import PanelContext from '../context/PanelContext'; import useTimeValue, { parseSelectedToRangeDate } from '../hooks/useTimeValue'; import { useEventCallbackRef } from '../../utils/hooks/useEventCallbackRef'; import pick from '../../utils/pick'; import useRangeDisabledTime from '../hooks/useRangeDisabledTime'; import { startOfToday } from 'date-fns'; import { triggerCommonProps, timePanelProps, defaultTimePickerProps, emptyTimeRange, } from '../constants'; import { ICombinedTimeRangePickerPropsWithDefault, ICombinedTimePanelProps, RangeTime, } from '../types'; import useSinglePopoverVisible from '../hooks/useSinglePopoverVisible'; const prefixCls = 'zent-datepicker-combined'; const PanelContextProvider = PanelContext.Provider; interface ITimePickerBaseProps extends ICombinedTimeRangePickerPropsWithDefault { ContentComponent: React.ComponentType; seperator?: string; } const CombinedTimePicker: React.FC = ({ onChange, disabledTime, onOpen, onClose, value, ContentComponent, defaultTime, selectedDate, disabled, ...restProps }) => { const restPropsRef = useRef(restProps); restPropsRef.current = restProps; const { format, className, openPanel } = restPropsRef.current; const onChangeRef = useEventCallbackRef(onChange); const { selected, setSelected } = useTimeValue( emptyTimeRange, value ); const [visibleChange, setVisibleChange] = useState(true); const { panelVisible, setPanelVisible, onVisibleChange } = useSinglePopoverVisible( value ?? emptyTimeRange, setSelected, onOpen, onClose, disabled, openPanel ); const onSelected = useCallback( (val: RangeTime, finished = false) => { setVisibleChange(false); setSelected(val); if (finished) { setPanelVisible(!finished); setVisibleChange(true); onChangeRef.current?.(val); } }, [onChangeRef, setSelected, setPanelVisible] ); const onClearInput = useCallback( evt => { evt.stopPropagation(); onChangeRef.current?.(emptyTimeRange); }, [onChangeRef] ); const selectedDates = parseSelectedToRangeDate(selected, format, new Date()); // disabledTimeOption const { disabledStartTimes, disabledConfirm, disabledEndTimes } = useRangeDisabledTime({ selected: selectedDates, disabledTime, }); const disabledTimeOptionStart = useMemo( () => disabledStartTimes?.(selectedDates[0] ?? startOfToday()), [disabledStartTimes, selectedDates] ); const disabledTimeOptionEnd = useMemo( () => disabledEndTimes?.(selectedDates[1] ?? startOfToday()), [disabledEndTimes, selectedDates] ); const trigger = useMemo(() => { const triggerProps = pick(restPropsRef.current, triggerCommonProps); return (
); }, [ value, selected, selectedDates, panelVisible, restPropsRef, disabled, onClearInput, ]); const content = useMemo(() => { const commonPanelProps = pick(restPropsRef.current, timePanelProps); return (
); }, [ selected, defaultTime, restPropsRef, onSelected, disabledTimeOptionStart, disabledTimeOptionEnd, ContentComponent, ]); return (
); }; CombinedTimePicker.defaultProps = defaultTimePickerProps; export default CombinedTimePicker;