fix: date-pick type error (#4499)

refactor-date
Amour1688 2021-08-12 08:49:30 +08:00 committed by GitHub
parent 70f9b02f51
commit eda5362782
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 218 additions and 256 deletions

View File

@ -7,214 +7,210 @@ import type { GenerateConfig } from '../../vc-picker/generate/index';
import enUS from '../locale/en_US'; import enUS from '../locale/en_US';
import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver'; import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import { getRangePlaceholder } from '../util'; import { getRangePlaceholder } from '../util';
import type { RangePickerProps } from '.';
import { getTimeProps, Components } from '.'; import { getTimeProps, Components } from '.';
import { computed, defineComponent, ref } from 'vue'; import { computed, defineComponent, ref } from 'vue';
import useConfigInject from '../../_util/hooks/useConfigInject'; import useConfigInject from '../../_util/hooks/useConfigInject';
import classNames from '../../_util/classNames'; import classNames from '../../_util/classNames';
import type { ExtraRangePickerProps } from './props';
import { commonProps, rangePickerProps } from './props'; import { commonProps, rangePickerProps } from './props';
import type { PanelMode, RangeValue } from '../../vc-picker/interface'; import type { PanelMode, RangeValue } from '../../vc-picker/interface';
import type { RangePickerSharedProps } from '../../vc-picker/RangePicker'; import type { RangePickerSharedProps } from '../../vc-picker/RangePicker';
import devWarning from '../../vc-util/devWarning'; import devWarning from '../../vc-util/devWarning';
export default function generateRangePicker<DateType>( export default function generateRangePicker<DateType, ExtraProps extends {} = {}>(
generateConfig: GenerateConfig<DateType>, generateConfig: GenerateConfig<DateType>,
extraProps: Record<string, any> = {}, extraProps: ExtraProps,
) { ) {
const RangePicker = defineComponent<RangePickerProps<DateType> & ExtraRangePickerProps<DateType>>( const RangePicker = defineComponent({
{ name: 'ARangePicker',
name: 'ARangePicker', inheritAttrs: false,
inheritAttrs: false, props: {
props: { ...commonProps<DateType>(),
...commonProps<DateType>(), ...rangePickerProps<DateType>(),
...rangePickerProps<DateType>(), ...extraProps,
...extraProps,
} as any,
slots: [
'suffixIcon',
// 'clearIcon',
// 'prevIcon',
// 'nextIcon',
// 'superPrevIcon',
// 'superNextIcon',
// 'panelRender',
'dateRender',
'renderExtraFooter',
// 'separator',
],
emits: [
'change',
'panelChange',
'ok',
'openChange',
'update:value',
'update:open',
'calendarChange',
'focus',
'blur',
],
setup(props, { expose, slots, attrs, emit }) {
devWarning(
!(attrs as any).getCalendarContainer,
'DatePicker',
'`getCalendarContainer` is deprecated. Please use `getPopupContainer"` instead.',
);
const { prefixCls, direction, getPopupContainer, size, rootPrefixCls } = useConfigInject(
'picker',
props,
);
const pickerRef = ref();
expose({
focus: () => {
pickerRef.value?.focus();
},
blur: () => {
pickerRef.value?.blur();
},
});
const maybeToStrings = (dates: DateType[]) => {
return props.valueFormat ? generateConfig.toString(dates, props.valueFormat) : dates;
};
const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => {
const values = maybeToStrings(dates);
emit('update:value', values);
emit('change', values, dateStrings);
};
const onOpenChange = (open: boolean) => {
emit('update:open', open);
emit('openChange', open);
};
const onFoucs = () => {
emit('focus');
};
const onBlur = () => {
emit('blur');
};
const onPanelChange = (dates: RangeValue<DateType>, modes: [PanelMode, PanelMode]) => {
const values = maybeToStrings(dates);
emit('panelChange', values, modes);
};
const onOk = (dates: DateType[]) => {
const value = maybeToStrings(dates);
emit('ok', value);
};
const onCalendarChange: RangePickerSharedProps<DateType>['onCalendarChange'] = (
dates: [DateType, DateType],
dateStrings: [string, string],
info,
) => {
const values = maybeToStrings(dates);
emit('calendarChange', values, dateStrings, info);
};
const [contextLocale] = useLocaleReceiver('DatePicker', enUS);
const value = computed(() => {
if (props.value) {
return props.valueFormat
? generateConfig.toDate(props.value, props.valueFormat)
: props.value;
}
return props.value;
});
const defaultValue = computed(() => {
if (props.defaultValue) {
return props.valueFormat
? generateConfig.toDate(props.defaultValue, props.valueFormat)
: props.defaultValue;
}
return props.defaultValue;
});
const defaultPickerValue = computed(() => {
if (props.defaultPickerValue) {
return props.valueFormat
? generateConfig.toDate(props.defaultPickerValue, props.valueFormat)
: props.defaultPickerValue;
}
return props.defaultPickerValue;
});
return () => {
const locale = { ...contextLocale.value, ...props.locale };
const p = { ...props, ...attrs } as RangePickerProps<DateType>;
const {
prefixCls: customizePrefixCls,
bordered = true,
placeholder,
suffixIcon = slots.suffixIcon?.(),
picker = 'date',
transitionName,
allowClear = true,
dateRender = slots.dateRender,
renderExtraFooter = slots.renderExtraFooter,
separator = slots.separator?.(),
clearIcon = slots.clearIcon?.(),
...restProps
} = p;
const { format, showTime } = p as any;
let additionalOverrideProps: any = {};
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...restProps, picker }) : {}),
};
const pre = prefixCls.value;
return (
<VCRangePicker
dateRender={dateRender}
renderExtraFooter={renderExtraFooter}
separator={
separator || (
<span aria-label="to" class={`${pre}-separator`}>
<SwapRightOutlined />
</span>
)
}
ref={pickerRef}
placeholder={getRangePlaceholder(picker, locale, placeholder)}
suffixIcon={
suffixIcon || (picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />)
}
clearIcon={clearIcon || <CloseCircleFilled />}
allowClear={allowClear}
transitionName={transitionName || `${rootPrefixCls.value}-slide-up`}
{...restProps}
{...additionalOverrideProps}
value={value.value}
defaultValue={defaultValue.value}
defaultPickerValue={defaultPickerValue.value}
picker={picker}
class={classNames(
{
[`${pre}-${size.value}`]: size.value,
[`${pre}-borderless`]: !bordered,
},
attrs.class,
)}
locale={locale!.lang}
prefixCls={pre}
getPopupContainer={attrs.getCalendarContainer || getPopupContainer.value}
generateConfig={generateConfig}
prevIcon={<span class={`${pre}-prev-icon`} />}
nextIcon={<span class={`${pre}-next-icon`} />}
superPrevIcon={<span class={`${pre}-super-prev-icon`} />}
superNextIcon={<span class={`${pre}-super-next-icon`} />}
components={Components}
direction={direction.value}
onChange={onChange}
onOpenChange={onOpenChange}
onFocus={onFoucs}
onBlur={onBlur}
onPanelChange={onPanelChange}
onOk={onOk}
onCalendarChange={onCalendarChange}
/>
);
};
},
}, },
); slots: [
'suffixIcon',
// 'clearIcon',
// 'prevIcon',
// 'nextIcon',
// 'superPrevIcon',
// 'superNextIcon',
// 'panelRender',
'dateRender',
'renderExtraFooter',
// 'separator',
],
emits: [
'change',
'panelChange',
'ok',
'openChange',
'update:value',
'update:open',
'calendarChange',
'focus',
'blur',
],
setup(props, { expose, slots, attrs, emit }) {
devWarning(
!attrs.getCalendarContainer,
'DatePicker',
'`getCalendarContainer` is deprecated. Please use `getPopupContainer"` instead.',
);
const { prefixCls, direction, getPopupContainer, size, rootPrefixCls } = useConfigInject(
'picker',
props,
);
const pickerRef = ref();
expose({
focus: () => {
pickerRef.value?.focus();
},
blur: () => {
pickerRef.value?.blur();
},
});
const maybeToStrings = (dates: DateType[]) => {
return props.valueFormat ? generateConfig.toString(dates, props.valueFormat) : dates;
};
const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => {
const values = maybeToStrings(dates);
emit('update:value', values);
emit('change', values, dateStrings);
};
const onOpenChange = (open: boolean) => {
emit('update:open', open);
emit('openChange', open);
};
const onFocus = () => {
emit('focus');
};
const onBlur = () => {
emit('blur');
};
const onPanelChange = (dates: RangeValue<DateType>, modes: [PanelMode, PanelMode]) => {
const values = maybeToStrings(dates);
emit('panelChange', values, modes);
};
const onOk = (dates: DateType[]) => {
const value = maybeToStrings(dates);
emit('ok', value);
};
const onCalendarChange: RangePickerSharedProps<DateType>['onCalendarChange'] = (
dates: [DateType, DateType],
dateStrings: [string, string],
info,
) => {
const values = maybeToStrings(dates);
emit('calendarChange', values, dateStrings, info);
};
const [contextLocale] = useLocaleReceiver('DatePicker', enUS);
const value = computed(() => {
if (props.value) {
return props.valueFormat
? generateConfig.toDate(props.value, props.valueFormat)
: props.value;
}
return props.value;
});
const defaultValue = computed(() => {
if (props.defaultValue) {
return props.valueFormat
? generateConfig.toDate(props.defaultValue, props.valueFormat)
: props.defaultValue;
}
return props.defaultValue;
});
const defaultPickerValue = computed(() => {
if (props.defaultPickerValue) {
return props.valueFormat
? generateConfig.toDate(props.defaultPickerValue, props.valueFormat)
: props.defaultPickerValue;
}
return props.defaultPickerValue;
});
return () => {
const locale = { ...contextLocale.value, ...props.locale };
const p = { ...props, ...attrs };
const {
prefixCls: customizePrefixCls,
bordered = true,
placeholder,
suffixIcon = slots.suffixIcon?.(),
picker = 'date',
transitionName,
allowClear = true,
dateRender = slots.dateRender,
renderExtraFooter = slots.renderExtraFooter,
separator = slots.separator?.(),
clearIcon = slots.clearIcon?.(),
...restProps
} = p;
const { format, showTime } = p as any;
let additionalOverrideProps: any = {};
additionalOverrideProps = {
...additionalOverrideProps,
...(showTime ? getTimeProps({ format, picker, ...showTime }) : {}),
...(picker === 'time' ? getTimeProps({ format, ...restProps, picker }) : {}),
};
const pre = prefixCls.value;
return (
<VCRangePicker
dateRender={dateRender}
renderExtraFooter={renderExtraFooter}
separator={
separator || (
<span aria-label="to" class={`${pre}-separator`}>
<SwapRightOutlined />
</span>
)
}
ref={pickerRef}
placeholder={getRangePlaceholder(picker, locale, placeholder as [string, string])}
suffixIcon={
suffixIcon || (picker === 'time' ? <ClockCircleOutlined /> : <CalendarOutlined />)
}
clearIcon={clearIcon || <CloseCircleFilled />}
allowClear={allowClear}
transitionName={transitionName || `${rootPrefixCls.value}-slide-up`}
{...restProps}
{...additionalOverrideProps}
value={value.value}
defaultValue={defaultValue.value}
defaultPickerValue={defaultPickerValue.value}
picker={picker}
class={classNames(
{
[`${pre}-${size.value}`]: size.value,
[`${pre}-borderless`]: !bordered,
},
attrs.class,
)}
locale={locale!.lang}
prefixCls={pre}
getPopupContainer={attrs.getCalendarContainer || getPopupContainer.value}
generateConfig={generateConfig}
prevIcon={<span class={`${pre}-prev-icon`} />}
nextIcon={<span class={`${pre}-next-icon`} />}
superPrevIcon={<span class={`${pre}-super-prev-icon`} />}
superNextIcon={<span class={`${pre}-super-next-icon`} />}
components={Components}
direction={direction.value}
onChange={onChange}
onOpenChange={onOpenChange}
onFocus={onFocus}
onBlur={onBlur}
onPanelChange={onPanelChange}
onOk={onOk}
onCalendarChange={onCalendarChange}
/>
);
};
},
});
return RangePicker; return RangePicker;
} }

View File

@ -7,34 +7,26 @@ import type { GenerateConfig } from '../../vc-picker/generate/index';
import enUS from '../locale/en_US'; import enUS from '../locale/en_US';
import { getPlaceholder } from '../util'; import { getPlaceholder } from '../util';
import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver'; import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import type { PickerProps, PickerDateProps, PickerTimeProps } from '.';
import { getTimeProps, Components } from '.'; import { getTimeProps, Components } from '.';
import type { DefineComponent } from 'vue';
import { computed, defineComponent, ref } from 'vue'; import { computed, defineComponent, ref } from 'vue';
import useConfigInject from '../../_util/hooks/useConfigInject'; import useConfigInject from '../../_util/hooks/useConfigInject';
import classNames from '../../_util/classNames'; import classNames from '../../_util/classNames';
import type { ExtraDatePickerProps } from './props';
import { commonProps, datePickerProps } from './props'; import { commonProps, datePickerProps } from './props';
import devWarning from '../../vc-util/devWarning'; import devWarning from '../../vc-util/devWarning';
export default function generateSinglePicker<DateType>( export default function generateSinglePicker<DateType, ExtraProps = {}>(
generateConfig: GenerateConfig<DateType>, generateConfig: GenerateConfig<DateType>,
extraProps: Record<string, any> = {}, extraProps: ExtraProps,
) { ) {
type DatePickerProps = PickerProps<DateType> & ExtraDatePickerProps<DateType>; function getPicker(picker?: PickerMode, displayName?: string) {
return defineComponent({
function getPicker<InnerPickerProps extends DatePickerProps>(
picker?: PickerMode,
displayName?: string,
): DefineComponent<InnerPickerProps> {
return defineComponent<InnerPickerProps>({
name: displayName, name: displayName,
inheritAttrs: false, inheritAttrs: false,
props: { props: {
...commonProps<DateType>(), ...commonProps<DateType>(),
...datePickerProps<DateType>(), ...datePickerProps<DateType>(),
...extraProps, ...extraProps,
} as any, },
slots: [ slots: [
'suffixIcon', 'suffixIcon',
// 'clearIcon', // 'clearIcon',
@ -59,13 +51,13 @@ export default function generateSinglePicker<DateType>(
], ],
setup(props, { slots, expose, attrs, emit }) { setup(props, { slots, expose, attrs, emit }) {
devWarning( devWarning(
!((props as any).monthCellContentRender || slots.monthCellContentRender), !(props.monthCellContentRender || slots.monthCellContentRender),
'DatePicker', 'DatePicker',
'`monthCellContentRender` is deprecated. Please use `monthCellRender"` instead.', '`monthCellContentRender` is deprecated. Please use `monthCellRender"` instead.',
); );
devWarning( devWarning(
!(attrs as any).getCalendarContainer, !attrs.getCalendarContainer,
'DatePicker', 'DatePicker',
'`getCalendarContainer` is deprecated. Please use `getPopupContainer"` instead.', '`getCalendarContainer` is deprecated. Please use `getPopupContainer"` instead.',
); );
@ -94,12 +86,6 @@ export default function generateSinglePicker<DateType>(
emit('update:open', open); emit('update:open', open);
emit('openChange', open); emit('openChange', open);
}; };
const onFoucs = () => {
emit('focus');
};
const onBlur = () => {
emit('blur');
};
const onPanelChange = (date: DateType, mode: PanelMode | null) => { const onPanelChange = (date: DateType, mode: PanelMode | null) => {
const value = maybeToString(date); const value = maybeToString(date);
emit('panelChange', value, mode); emit('panelChange', value, mode);
@ -114,7 +100,7 @@ export default function generateSinglePicker<DateType>(
const value = computed(() => { const value = computed(() => {
if (props.value) { if (props.value) {
return props.valueFormat return props.valueFormat
? generateConfig.toDate(props.value, props.valueFormat) ? generateConfig.toDate(props.value as string | DateType, props.valueFormat)
: props.value; : props.value;
} }
return props.value; return props.value;
@ -122,7 +108,7 @@ export default function generateSinglePicker<DateType>(
const defaultValue = computed(() => { const defaultValue = computed(() => {
if (props.defaultValue) { if (props.defaultValue) {
return props.valueFormat return props.valueFormat
? generateConfig.toDate(props.defaultValue, props.valueFormat) ? generateConfig.toDate(props.defaultValue as string | DateType, props.valueFormat)
: props.defaultValue; : props.defaultValue;
} }
return props.defaultValue; return props.defaultValue;
@ -130,7 +116,10 @@ export default function generateSinglePicker<DateType>(
const defaultPickerValue = computed(() => { const defaultPickerValue = computed(() => {
if (props.defaultPickerValue) { if (props.defaultPickerValue) {
return props.valueFormat return props.valueFormat
? generateConfig.toDate(props.defaultPickerValue, props.valueFormat) ? generateConfig.toDate(
props.defaultPickerValue as string | DateType,
props.valueFormat,
)
: props.defaultPickerValue; : props.defaultPickerValue;
} }
return props.defaultPickerValue; return props.defaultPickerValue;
@ -138,7 +127,7 @@ export default function generateSinglePicker<DateType>(
return () => { return () => {
const locale = { ...contextLocale.value, ...props.locale }; const locale = { ...contextLocale.value, ...props.locale };
const p = { ...props, ...attrs } as InnerPickerProps; const p = { ...props, ...attrs };
const { const {
bordered = true, bordered = true,
placeholder, placeholder,
@ -217,26 +206,23 @@ export default function generateSinglePicker<DateType>(
direction={direction.value} direction={direction.value}
onChange={onChange} onChange={onChange}
onOpenChange={onOpenChange} onOpenChange={onOpenChange}
onFocus={onFoucs} onFocus={props.onFocus}
onBlur={onBlur} onBlur={props.onBlur}
onPanelChange={onPanelChange} onPanelChange={onPanelChange}
onOk={onOk} onOk={onOk}
/> />
); );
}; };
}, },
}) as unknown as DefineComponent<InnerPickerProps>; });
} }
const DatePicker = getPicker<DatePickerProps>(undefined, 'ADatePicker'); const DatePicker = getPicker(undefined, 'ADatePicker');
const WeekPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('week', 'AWeekPicker'); const WeekPicker = getPicker('week', 'AWeekPicker');
const MonthPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('month', 'AMonthPicker'); const MonthPicker = getPicker('month', 'AMonthPicker');
const YearPicker = getPicker<Omit<PickerDateProps<DateType>, 'picker'>>('year', 'AYearPicker'); const YearPicker = getPicker('year', 'AYearPicker');
const TimePicker = getPicker<Omit<PickerTimeProps<DateType>, 'picker'>>('time', 'TimePicker'); // TimePicker 使 const TimePicker = getPicker('time', 'TimePicker'); // TimePicker 使
const QuarterPicker = getPicker<Omit<PickerTimeProps<DateType>, 'picker'>>( const QuarterPicker = getPicker('quarter', 'AQuarterPicker');
'quarter',
'AQuarterPicker',
);
return { return {
DatePicker, DatePicker,
@ -245,12 +231,5 @@ export default function generateSinglePicker<DateType>(
YearPicker, YearPicker,
TimePicker, TimePicker,
QuarterPicker, QuarterPicker,
} as unknown as {
DatePicker: DefineComponent<DatePickerProps>;
WeekPicker: DefineComponent<Omit<PickerDateProps<DateType>, 'picker'>>;
MonthPicker: DefineComponent<Omit<PickerDateProps<DateType>, 'picker'>>;
YearPicker: DefineComponent<Omit<PickerDateProps<DateType>, 'picker'>>;
TimePicker: DefineComponent<Omit<PickerTimeProps<DateType>, 'picker'>>;
QuarterPicker: DefineComponent<Omit<PickerTimeProps<DateType>, 'picker'>>;
}; };
} }

View File

@ -17,8 +17,6 @@ import type { TimePickerLocale } from '../../time-picker';
import generateSinglePicker from './generateSinglePicker'; import generateSinglePicker from './generateSinglePicker';
import generateRangePicker from './generateRangePicker'; import generateRangePicker from './generateRangePicker';
import type { SizeType } from '../../config-provider'; import type { SizeType } from '../../config-provider';
import type { ExtraDatePickerProps, ExtraRangePickerProps } from './props';
import type { DefineComponent } from 'vue';
export const Components = { button: PickerButton, rangeItem: PickerTag }; export const Components = { button: PickerButton, rangeItem: PickerTag };
@ -127,20 +125,17 @@ export type RangePickerProps<DateType> =
| RangePickerDateProps<DateType> | RangePickerDateProps<DateType>
| RangePickerTimeProps<DateType>; | RangePickerTimeProps<DateType>;
function generatePicker<DateType>( function generatePicker<DateType, ExtraProps extends Record<string, any> = {}>(
generateConfig: GenerateConfig<DateType>, generateConfig: GenerateConfig<DateType>,
extraProps: Record<string, any> = {}, extraProps?: ExtraProps,
) { ) {
type DatePickerProps = PickerProps<DateType> & ExtraDatePickerProps<DateType>;
// =========================== Picker =========================== // =========================== Picker ===========================
const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } = const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } =
generateSinglePicker<DateType>(generateConfig, extraProps); generateSinglePicker<DateType, ExtraProps>(generateConfig, extraProps);
// ======================== Range Picker ======================== // ======================== Range Picker ========================
const RangePicker = generateRangePicker<DateType>(generateConfig, extraProps); const RangePicker = generateRangePicker<DateType>(generateConfig, extraProps);
// 使 as TS7056
// error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.
return { return {
DatePicker, DatePicker,
WeekPicker, WeekPicker,
@ -149,14 +144,6 @@ function generatePicker<DateType>(
TimePicker, TimePicker,
QuarterPicker, QuarterPicker,
RangePicker, RangePicker,
} as unknown as {
DatePicker: DefineComponent<DatePickerProps>;
WeekPicker: DefineComponent<Omit<PickerDateProps<DateType>, 'picker'>>;
MonthPicker: DefineComponent<Omit<PickerDateProps<DateType>, 'picker'>>;
YearPicker: DefineComponent<Omit<PickerDateProps<DateType>, 'picker'>>;
TimePicker: DefineComponent<Omit<PickerTimeProps<DateType>, 'picker'>>;
QuarterPicker: DefineComponent<Omit<PickerTimeProps<DateType>, 'picker'>>;
RangePicker: DefineComponent<RangePickerProps<DateType> & ExtraRangePickerProps<DateType>>;
}; };
} }