import React, { useState, useEffect, useCallback } from "react"; import classNames from "classnames"; import moment, { Moment } from "moment"; import CalendarPart from "../calendar/CalendarPart"; import { useDefaultValue } from "../form/controlled"; import { Input } from "../input"; import { TimeTable } from "./TimeTable"; import { Button } from "../button"; import { useTranslation } from "../i18n"; import { DropdownBox } from "../dropdown"; import { TimePickerProps } from "./TimeProps"; import { genShowHourMinuteSecond, isValidTimeValue } from "./util"; import { TimeRangePicker } from "./TimeRangePicker"; import { useDefault } from "../_util/use-default"; import { Popover } from "../popover/Popover"; import { DatePickerTrigger } from "../datepicker/util"; import { useConfig } from "../_util/config-context"; import { noop } from "../_util/noop"; import { KeyMap } from "../_util/key-map"; import { forwardRefWithStatics } from "../_util/forward-ref-with-statics"; import { mergeEventProps } from "../_util/merge-event-props"; import { Icon } from "../icon"; export const TimePicker = forwardRefWithStatics( function TimePicker(props: TimePickerProps, ref: React.Ref) { const { classPrefix } = useConfig(); const t = useTranslation(moment); const { value, onChange, format = "HH:mm:ss", placeholder = t.selectTime, disabled = false, defaultOpen = false, open, onOpenChange = noop, onInputValueChange = noop, placement = "bottom-start", placementOffset = 5, closeOnScroll = true, escapeWithReference, popupContainer, clearable, overlayClassName, overlayStyle, className, style, } = useDefaultValue(props); const [hover, setHover] = useState(false); const [curValue, setCurValue] = useState(value); const [active, setActive] = useDefault(open, defaultOpen, onOpenChange); const { showMilliseconds } = genShowHourMinuteSecond(format); useEffect(() => { setCurValue(value); // eslint-disable-next-line react-hooks/exhaustive-deps }, [active]); const getInputValue = useCallback( value => { return moment.isMoment(value) ? value.locale(t.locale).format(format) : ""; }, [t.locale, format] ); const [inputValue, setInputValue] = useState( getInputValue(curValue) ); const syncInputValue = useCallback( (value: Moment) => { const inputValue = getInputValue(value); setInputValue(inputValue); onInputValueChange(inputValue, { valid: true }); }, // eslint-disable-next-line react-hooks/exhaustive-deps [getInputValue] ); useEffect(() => { setCurValue(value); syncInputValue(value); }, [format, getInputValue, syncInputValue, value]); function handleInputChange(content: string) { setInputValue(content); // 格式校验 const value = moment(content, format, true); if (!value.isValid()) { onInputValueChange(content, { valid: false }); return; } const valid = isValidTimeValue(value, props); if (valid) { setCurValue(value); } onInputValueChange(content, { valid }); } function handleKeyDown(event: React.KeyboardEvent) { if (!active) { handleOpen(); return; } switch (event.key) { case KeyMap.Enter: handleOk(event); break; case KeyMap.Esc: handleClose(); break; } } function handleSelectChange(value: Moment) { syncInputValue(value); setCurValue(value); } function handleOk(event: React.SyntheticEvent) { if (!curValue) { return; } onChange(curValue, { event }); handleClose(); } function handleOpen() { if (disabled) { return; } setActive(true); } function handleClose() { syncInputValue(value); setActive(false); } return ( { if (!visible) { handleClose(); } else { setActive(visible); } }} placement={placement} placementOffset={placementOffset} closeOnScroll={closeOnScroll} escapeWithReference={escapeWithReference} popupContainer={popupContainer} overlayClassName={overlayClassName} overlayStyle={overlayStyle} overlay={ } /> } >
setHover(true)} onMouseLeave={() => setHover(false)} > { if (active) { event.stopPropagation(); } }} /> {clearable && !disabled && ( { event.stopPropagation(); onChange(null, { event }); }} /> )}
); }, { defaultLabelAlign: "middle", RangePicker: TimeRangePicker, } ); TimePicker.displayName = "TimePicker";