import { defineComponent, ref } from 'vue'; import type { RangePickerTimeProps } from '../date-picker/generatePicker'; import generatePicker from '../date-picker/generatePicker'; import { commonProps, datePickerProps, rangePickerProps, } from '../date-picker/generatePicker/props'; import type { CommonProps, DatePickerProps } from '../date-picker/generatePicker/props'; import type { GenerateConfig } from '../vc-picker/generate'; import type { PanelMode, RangeValue } from '../vc-picker/interface'; import type { RangePickerSharedProps } from '../vc-picker/RangePicker'; import devWarning from '../vc-util/devWarning'; import { useInjectFormItemContext } from '../form/FormItemContext'; import omit from '../_util/omit'; export interface TimePickerLocale { placeholder?: string; rangePlaceholder?: [string, string]; } export const timePickerProps = () => ({ format: String, showNow: { type: Boolean, default: undefined }, showHour: { type: Boolean, default: undefined }, showMinute: { type: Boolean, default: undefined }, showSecond: { type: Boolean, default: undefined }, use12Hours: { type: Boolean, default: undefined }, hourStep: Number, minuteStep: Number, secondStep: Number, hideDisabledOptions: { type: Boolean, default: undefined }, popupClassName: String, }); export interface CommonTimePickerProps { format?: string; showNow?: boolean; showHour?: boolean; showMinute?: boolean; showSecond?: boolean; use12Hours?: boolean; hourStep?: number; minuteStep?: number; secondStep?: number; hideDisabledOptions?: boolean; popupClassName?: string; } export type TimeRangePickerProps = Omit< RangePickerTimeProps, 'picker' | 'defaultPickerValue' | 'defaultValue' | 'value' | 'onChange' | 'onPanelChange' | 'onOk' > & { popupClassName?: string; valueFormat?: string; defaultPickerValue?: RangeValue | RangeValue; defaultValue?: RangeValue | RangeValue; value?: RangeValue | RangeValue; onChange?: ( value: RangeValue | RangeValue | null, dateString: [string, string], ) => void; 'onUpdate:value'?: (value: RangeValue | RangeValue | null) => void; onPanelChange?: ( values: RangeValue | RangeValue, modes: [PanelMode, PanelMode], ) => void; onOk?: (dates: RangeValue | RangeValue) => void; }; export type TimePickerProps = CommonProps & DatePickerProps & CommonTimePickerProps & { addon?: () => void; }; function createTimePicker< DateType, DTimePickerProps extends TimePickerProps = TimePickerProps, DTimeRangePickerProps extends TimeRangePickerProps = TimeRangePickerProps, >(generateConfig: GenerateConfig) { const DatePicker = generatePicker(generateConfig, { ...timePickerProps(), order: { type: Boolean, default: true }, }); const { TimePicker: InternalTimePicker, RangePicker: InternalRangePicker } = DatePicker as any; const TimePicker = defineComponent({ name: 'ATimePicker', inheritAttrs: false, props: { ...commonProps(), ...datePickerProps(), ...timePickerProps(), addon: { type: Function }, } as any, slot: ['addon', 'renderExtraFooter', 'suffixIcon', 'clearIcon'], setup(props, { slots, expose, emit, attrs }) { const formItemContext = useInjectFormItemContext(); devWarning( !(slots.addon || props.addon), 'TimePicker', '`addon` is deprecated. Please use `v-slot:renderExtraFooter` instead.', ); const pickerRef = ref(); expose({ focus: () => { pickerRef.value?.focus(); }, blur: () => { pickerRef.value?.blur(); }, }); const onChange = (value: DateType | string, dateString: string) => { emit('update:value', value); emit('change', value, dateString); formItemContext.onFieldChange(); }; const onOpenChange = (open: boolean) => { emit('update:open', open); emit('openChange', open); }; const onFocus = (e: FocusEvent) => { emit('focus', e); }; const onBlur = (e: FocusEvent) => { emit('blur', e); formItemContext.onFieldBlur(); }; const onOk = (value: DateType) => { emit('ok', value); }; return () => { const { id = formItemContext.id.value, ...restProps } = props; return ( ); }; }, }); const TimeRangePicker = defineComponent({ name: 'ATimeRangePicker', inheritAttrs: false, props: { ...commonProps(), ...rangePickerProps(), ...timePickerProps(), order: { type: Boolean, default: true }, } as any, slot: ['renderExtraFooter', 'suffixIcon', 'clearIcon'], setup(props, { slots, expose, emit, attrs }) { const pickerRef = ref(); const formItemContext = useInjectFormItemContext(); expose({ focus: () => { pickerRef.value?.focus(); }, blur: () => { pickerRef.value?.blur(); }, }); const onChange = ( values: RangeValue | RangeValue, dateStrings: [string, string], ) => { emit('update:value', values); emit('change', values, dateStrings); formItemContext.onFieldChange(); }; const onOpenChange = (open: boolean) => { emit('update:open', open); emit('openChange', open); }; const onFocus = (e: FocusEvent) => { emit('focus', e); }; const onBlur = (e: FocusEvent) => { emit('blur', e); formItemContext.onFieldBlur(); }; const onPanelChange = ( values: RangeValue | RangeValue, modes: [PanelMode, PanelMode], ) => { emit('panelChange', values, modes); }; const onOk = (values: RangeValue) => { emit('ok', values); }; const onCalendarChange: RangePickerSharedProps['onCalendarChange'] = ( values: RangeValue | RangeValue, dateStrings: [string, string], info, ) => { emit('calendarChange', values, dateStrings, info); }; return () => { const { id = formItemContext.id.value, ...restProps } = props; return ( ); }; }, }); return { TimePicker, TimeRangePicker, }; } export default createTimePicker;