diff --git a/components/calendar/dayjs.tsx b/components/calendar/dayjs.tsx index f64dce83e..fc1e128b9 100644 --- a/components/calendar/dayjs.tsx +++ b/components/calendar/dayjs.tsx @@ -1,10 +1,9 @@ -import type { Dayjs } from 'dayjs'; import generateConfig from '../vc-picker/generate/dayjs'; import { withInstall } from '../_util/type'; import type { CalendarProps } from './generateCalendar'; import generateCalendar from './generateCalendar'; -const Calendar = generateCalendar(generateConfig); +const Calendar = generateCalendar(generateConfig); export type { CalendarProps }; export default withInstall(Calendar); diff --git a/components/calendar/generateCalendar.tsx b/components/calendar/generateCalendar.tsx index 32ad27f0a..fc9916629 100644 --- a/components/calendar/generateCalendar.tsx +++ b/components/calendar/generateCalendar.tsx @@ -65,7 +65,10 @@ export interface CalendarProps { valueFormat?: string; } -function generateCalendar(generateConfig: GenerateConfig) { +function generateCalendar< + DateType, + Props extends CalendarProps = CalendarProps, +>(generateConfig: GenerateConfig) { function isSameYear(date1: DateType, date2: DateType) { return date1 && date2 && generateConfig.getYear(date1) === generateConfig.getYear(date2); } @@ -82,28 +85,9 @@ function generateCalendar(generateConfig: GenerateConfig) { ); } - const Calendar = defineComponent>({ + const Calendar = defineComponent({ name: 'ACalendar', inheritAttrs: false, - props: [ - 'prefixCls', - 'locale', - 'validRange', - 'disabledDate', - 'dateFullCellRender', - 'dateCellRender', - 'monthFullCellRender', - 'monthCellRender', - 'headerRender', - 'value', - 'defaultValue', - 'mode', - 'fullscreen', - 'onChange', - 'onPanelChange', - 'onSelect', - 'valueFormat', - ] as any, emits: ['change', 'panelChange', 'select', 'update:value'], slots: [ 'dateFullCellRender', @@ -303,7 +287,6 @@ function generateCalendar(generateConfig: GenerateConfig) { onModeChange={triggerModeChange} /> )} - (generateConfig: GenerateConfig) { }; }, }); + + Calendar.props = [ + 'prefixCls', + 'locale', + 'validRange', + 'disabledDate', + 'dateFullCellRender', + 'dateCellRender', + 'monthFullCellRender', + 'monthCellRender', + 'headerRender', + 'value', + 'defaultValue', + 'mode', + 'fullscreen', + 'onChange', + 'onPanelChange', + 'onSelect', + 'valueFormat', + ]; + Calendar.install = function (app: App) { app.component(Calendar.name, Calendar); return app; }; - return Calendar; + + return Calendar as unknown as (props: CalendarProps) => JSX.Element; } export default generateCalendar; diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index 58dbee679..a4a3280db 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -16,18 +16,18 @@ import type { PanelMode, RangeValue } from '../../vc-picker/interface'; import type { RangePickerSharedProps } from '../../vc-picker/RangePicker'; import devWarning from '../../vc-util/devWarning'; -export default function generateRangePicker( +export default function generateRangePicker( generateConfig: GenerateConfig, extraProps: ExtraProps, ) { const RangePicker = defineComponent({ name: 'ARangePicker', - inheritAttrs: false, props: { ...commonProps(), ...rangePickerProps(), ...extraProps, }, + inheritAttrs: false, slots: [ 'suffixIcon', // 'clearIcon', diff --git a/components/date-picker/generatePicker/generateSinglePicker.tsx b/components/date-picker/generatePicker/generateSinglePicker.tsx index 9dd3a2ee1..a3abddbc6 100644 --- a/components/date-picker/generatePicker/generateSinglePicker.tsx +++ b/components/date-picker/generatePicker/generateSinglePicker.tsx @@ -12,6 +12,7 @@ import { computed, defineComponent, nextTick, onMounted, ref } from 'vue'; import useConfigInject from '../../_util/hooks/useConfigInject'; import classNames from '../../_util/classNames'; import { commonProps, datePickerProps } from './props'; + import devWarning from '../../vc-util/devWarning'; export default function generateSinglePicker( diff --git a/components/date-picker/generatePicker/index.tsx b/components/date-picker/generatePicker/index.tsx index 43f168631..68fa3d7db 100644 --- a/components/date-picker/generatePicker/index.tsx +++ b/components/date-picker/generatePicker/index.tsx @@ -1,22 +1,12 @@ -import type { GenerateConfig } from '../../vc-picker/generate/index'; -import type { - PickerBaseProps as RCPickerBaseProps, - PickerDateProps as RCPickerDateProps, - PickerTimeProps as RCPickerTimeProps, -} from '../../vc-picker/Picker'; +import type { GenerateConfig } from '../../vc-picker/generate'; import type { SharedTimeProps } from '../../vc-picker/panels/TimePanel'; -import type { - RangePickerBaseProps as RCRangePickerBaseProps, - RangePickerDateProps as RCRangePickerDateProps, - RangePickerTimeProps as RCRangePickerTimeProps, -} from '../../vc-picker/RangePicker'; -import type { PickerMode, Locale as RcPickerLocale } from '../../vc-picker/interface'; +import type { PickerMode } from '../../vc-picker/interface'; import PickerButton from '../PickerButton'; import PickerTag from '../PickerTag'; -import type { TimePickerLocale } from '../../time-picker'; import generateSinglePicker from './generateSinglePicker'; import generateRangePicker from './generateRangePicker'; -import type { SizeType } from '../../config-provider'; + +export * from './interface'; export const Components = { button: PickerButton, rangeItem: PickerTag }; @@ -65,67 +55,7 @@ export function getTimeProps( }; } -type InjectDefaultProps = Omit< - Props, - | 'locale' - | 'generateConfig' - | 'prevIcon' - | 'nextIcon' - | 'superPrevIcon' - | 'superNextIcon' - | 'hideHeader' - | 'components' -> & { - locale?: PickerLocale; - size?: SizeType; - bordered?: boolean; -}; - -export type PickerLocale = { - lang: RcPickerLocale & AdditionalPickerLocaleLangProps; - timePickerLocale: TimePickerLocale; -} & AdditionalPickerLocaleProps; - -export type AdditionalPickerLocaleProps = { - dateFormat?: string; - dateTimeFormat?: string; - weekFormat?: string; - monthFormat?: string; -}; - -export type AdditionalPickerLocaleLangProps = { - placeholder: string; - yearPlaceholder?: string; - quarterPlaceholder?: string; - monthPlaceholder?: string; - weekPlaceholder?: string; - rangeYearPlaceholder?: [string, string]; - rangeMonthPlaceholder?: [string, string]; - rangeWeekPlaceholder?: [string, string]; - rangePlaceholder?: [string, string]; -}; - -// Picker Props -export type PickerBaseProps = InjectDefaultProps>; -export type PickerDateProps = InjectDefaultProps>; -export type PickerTimeProps = InjectDefaultProps>; - -export type PickerProps = - | PickerBaseProps - | PickerDateProps - | PickerTimeProps; - -// Range Picker Props -export type RangePickerBaseProps = InjectDefaultProps>; -export type RangePickerDateProps = InjectDefaultProps>; -export type RangePickerTimeProps = InjectDefaultProps>; - -export type RangePickerProps = - | RangePickerBaseProps - | RangePickerDateProps - | RangePickerTimeProps; - -function generatePicker = {}>( +function generatePicker( generateConfig: GenerateConfig, extraProps?: ExtraProps, ) { @@ -134,7 +64,7 @@ function generatePicker = {}>( generateSinglePicker(generateConfig, extraProps); // ======================== Range Picker ======================== - const RangePicker = generateRangePicker(generateConfig, extraProps); + const RangePicker = generateRangePicker(generateConfig, extraProps); return { DatePicker, diff --git a/components/date-picker/generatePicker/interface.ts b/components/date-picker/generatePicker/interface.ts new file mode 100644 index 000000000..426d32fa1 --- /dev/null +++ b/components/date-picker/generatePicker/interface.ts @@ -0,0 +1,73 @@ +import type { + PickerBaseProps as RCPickerBaseProps, + PickerDateProps as RCPickerDateProps, + PickerTimeProps as RCPickerTimeProps, +} from '../../vc-picker/Picker'; +import type { + RangePickerBaseProps as RCRangePickerBaseProps, + RangePickerDateProps as RCRangePickerDateProps, + RangePickerTimeProps as RCRangePickerTimeProps, +} from '../../vc-picker/RangePicker'; +import type { Locale as RcPickerLocale } from '../../vc-picker/interface'; +import type { TimePickerLocale } from '../../time-picker'; +import type { SizeType } from '../../config-provider'; + +type InjectDefaultProps = Omit< + Props, + | 'locale' + | 'generateConfig' + | 'prevIcon' + | 'nextIcon' + | 'superPrevIcon' + | 'superNextIcon' + | 'hideHeader' + | 'components' +> & { + locale?: PickerLocale; + size?: SizeType; + bordered?: boolean; +}; + +export type PickerLocale = { + lang: RcPickerLocale & AdditionalPickerLocaleLangProps; + timePickerLocale: TimePickerLocale; +} & AdditionalPickerLocaleProps; + +export type AdditionalPickerLocaleProps = { + dateFormat?: string; + dateTimeFormat?: string; + weekFormat?: string; + monthFormat?: string; +}; + +export type AdditionalPickerLocaleLangProps = { + placeholder: string; + yearPlaceholder?: string; + quarterPlaceholder?: string; + monthPlaceholder?: string; + weekPlaceholder?: string; + rangeYearPlaceholder?: [string, string]; + rangeMonthPlaceholder?: [string, string]; + rangeWeekPlaceholder?: [string, string]; + rangePlaceholder?: [string, string]; +}; + +// Picker Props +export type PickerBaseProps = InjectDefaultProps>; +export type PickerDateProps = InjectDefaultProps>; +export type PickerTimeProps = InjectDefaultProps>; + +export type PickerProps = + | PickerBaseProps + | PickerDateProps + | PickerTimeProps; + +// Range Picker Props +export type RangePickerBaseProps = InjectDefaultProps>; +export type RangePickerDateProps = InjectDefaultProps>; +export type RangePickerTimeProps = InjectDefaultProps>; + +export type RangePickerProps = + | RangePickerBaseProps + | RangePickerDateProps + | RangePickerTimeProps; diff --git a/components/date-picker/generatePicker/props.ts b/components/date-picker/generatePicker/props.ts index b233ac193..5da209fc6 100644 --- a/components/date-picker/generatePicker/props.ts +++ b/components/date-picker/generatePicker/props.ts @@ -76,6 +76,44 @@ function commonProps() { }; } +export interface CommonProps { + prefixCls?: string; + dropdownClassName?: string; + dropdownAlign?: AlignType; + popupStyle?: CSSProperties; + transitionName?: string; + placeholder?: string; + allowClear?: boolean; + autofocus?: boolean; + disabled?: boolean; + tabindex?: number; + open?: boolean; + defaultOpen?: boolean; + inputReadOnly?: boolean; + suffixIcon?: VueNode; + clearIcon?: VueNode; + prevIcon?: VueNode; + nextIcon?: VueNode; + superPrevIcon?: VueNode; + superNextIcon?: VueNode; + getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement; + panelRender?: (originPanel: VueNode) => VueNode; + role?: string; + name?: string; + autocomplete?: string; + direction?: 'ltr' | 'rtl'; + showToday?: boolean; + showTime?: boolean | SharedTimeProps; + locale?: PickerLocale; + size?: SizeType; + bordered?: boolean; + dateRender?: DateRender; + disabledDate?: (date: DateType) => boolean; + mode?: PanelMode; + picker?: PickerMode; + valueFormat?: string; +} + function datePickerProps() { return { defaultPickerValue: { type: [String, Object] as PropType }, @@ -95,6 +133,19 @@ function datePickerProps() { }; } +export interface DatePickerProps { + defaultPickerValue?: DateType | string; + defaultValue?: DateType | string; + value?: DateType | string; + disabledTime?: DisabledTime; + format?: string | CustomFormat | (string | CustomFormat)[]; + renderExtraFooter?: (mode: PanelMode) => VueNode; + showNow?: boolean; + monthCellRender?: MonthCellRender; + // deprecated Please use `monthCellRender"` instead.', + monthCellContentRender?: MonthCellRender; +} + function rangePickerProps() { return { allowEmpty: { type: Array as unknown as PropType<[boolean, boolean]> }, @@ -124,6 +175,25 @@ function rangePickerProps() { }; } +export interface RangePickerProps { + allowEmpty?: [boolean, boolean]; + dateRender?: RangeDateRender; + defaultPickerValue?: [DateType, DateType] | [string, string]; + defaultValue?: [DateType, DateType] | [string, string]; + value?: [DateType, DateType]; + disabledTime?: (date: EventValue, type: RangeType) => DisabledTimes; + disabled?: [boolean, boolean]; + format?: string; + renderExtraFooter?: () => VueNode; + separator?: string; + ranges?: Record< + string, + Exclude, null> | (() => Exclude, null>) + >; + placeholder?: [string, string]; + mode?: [PanelMode, PanelMode]; +} + export type ExtraDatePickerProps = { valueFormat?: string; defaultPickerValue?: DateType | string; diff --git a/components/time-picker/time-picker.tsx b/components/time-picker/time-picker.tsx index 8cc650a60..309950ff8 100644 --- a/components/time-picker/time-picker.tsx +++ b/components/time-picker/time-picker.tsx @@ -6,6 +6,7 @@ import { 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'; @@ -16,7 +17,7 @@ export interface TimePickerLocale { rangePlaceholder?: [string, string]; } -const timpePickerProps = { +const timePickerProps = { format: String, showNow: { type: Boolean, default: undefined }, showHour: { type: Boolean, default: undefined }, @@ -30,29 +31,46 @@ const timpePickerProps = { popupClassName: String, }; -function createTimePicker(generateConfig: GenerateConfig) { +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, 'picker'> & { + popupClassName?: string; + valueFormat?: string; +}; + +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, { - ...timpePickerProps, + ...timePickerProps, order: { type: Boolean, default: true }, }); + const { TimePicker: InternalTimePicker, RangePicker: InternalRangePicker } = DatePicker as any; - type TimeRangePickerProps = Omit, 'picker'> & { - popupClassName?: string; - valueFormat?: string; - }; - // type TimePickerProps = Omit, 'picker'> & { - // popupClassName?: string; - // valueFormat?: string; - // }; - const TimePicker = defineComponent({ + + const TimePicker = defineComponent({ name: 'ATimePicker', inheritAttrs: false, - props: { - ...commonProps(), - ...datePickerProps(), - ...timpePickerProps, - addon: { type: Function }, - } as any, slot: ['addon', 'renderExtraFooter', 'suffixIcon', 'clearIcon'], emits: ['change', 'openChange', 'focus', 'blur', 'ok', 'update:value', 'update:open'], setup(props, { slots, expose, emit, attrs }) { @@ -78,7 +96,7 @@ function createTimePicker(generateConfig: GenerateConfig) { emit('update:open', open); emit('openChange', open); }; - const onFoucs = () => { + const onFocus = () => { emit('focus'); }; const onBlur = () => { @@ -100,7 +118,7 @@ function createTimePicker(generateConfig: GenerateConfig) { } onChange={onChange} onOpenChange={onOpenChange} - onFocus={onFoucs} + onFocus={onFocus} onBlur={onBlur} onOk={onOk} v-slots={slots} @@ -110,15 +128,16 @@ function createTimePicker(generateConfig: GenerateConfig) { }, }); - const TimeRangePicker = defineComponent({ + TimePicker.props = { + ...commonProps(), + ...datePickerProps(), + ...timePickerProps, + addon: { type: Function }, + }; + + const TimeRangePicker = defineComponent({ name: 'ATimeRangePicker', inheritAttrs: false, - props: { - ...commonProps(), - ...rangePickerProps(), - ...timpePickerProps, - order: { type: Boolean, default: true }, - } as any, slot: ['renderExtraFooter', 'suffixIcon', 'clearIcon'], emits: [ 'change', @@ -152,7 +171,7 @@ function createTimePicker(generateConfig: GenerateConfig) { emit('update:open', open); emit('openChange', open); }; - const onFoucs = () => { + const onFocus = () => { emit('focus'); }; const onBlur = () => { @@ -164,7 +183,7 @@ function createTimePicker(generateConfig: GenerateConfig) { ) => { emit('panelChange', values, modes); }; - const onOk = (values: RangeValue | RangeValue) => { + const onOk = (values: RangeValue) => { emit('ok', values); }; const onCalendarChange: RangePickerSharedProps['onCalendarChange'] = ( @@ -185,7 +204,7 @@ function createTimePicker(generateConfig: GenerateConfig) { ref={pickerRef} onChange={onChange} onOpenChange={onOpenChange} - onFocus={onFoucs} + onFocus={onFocus} onBlur={onBlur} onPanelChange={onPanelChange} onOk={onOk} @@ -197,6 +216,13 @@ function createTimePicker(generateConfig: GenerateConfig) { }, }); + TimeRangePicker.props = { + ...commonProps(), + ...rangePickerProps(), + ...timePickerProps, + order: { type: Boolean, default: true }, + }; + return { TimePicker, TimeRangePicker,