feat: support valueFormat

pull/4499/head
tangjinzhou 2021-08-03 16:21:17 +08:00
parent 0dcae5b62a
commit d8c8bc4156
13 changed files with 429 additions and 192 deletions

View File

@ -0,0 +1,35 @@
import type { App } from 'vue';
import dataFnsGenerateConfig from '../vc-picker/generate/dataFns';
import type {
PickerProps,
PickerDateProps,
RangePickerProps as BaseRangePickerProps,
} from './generatePicker';
import generatePicker from './generatePicker';
import { ExtraDatePickerProps, ExtraRangePickerProps } from './generatePicker/props';
export type DatePickerProps = PickerProps<Date> & ExtraDatePickerProps<Date>;
export type MonthPickerProps = Omit<PickerDateProps<Date>, 'picker'> & ExtraDatePickerProps<Date>;
export type WeekPickerProps = Omit<PickerDateProps<Date>, 'picker'> & ExtraDatePickerProps<Date>;
export type RangePickerProps = BaseRangePickerProps<Date> & ExtraRangePickerProps<Date>;
const DatePicker = generatePicker<Date>(dataFnsGenerateConfig);
const RangePicker = DatePicker.RangePicker;
const MonthPicker = DatePicker.MonthPicker;
const WeekPicker = DatePicker.WeekPicker;
const QuarterPicker = DatePicker.QuarterPicker;
/* istanbul ignore next */
DatePicker.install = function (app: App) {
app.component(DatePicker.name, DatePicker);
app.component(RangePicker.name, RangePicker);
app.component(MonthPicker.name, MonthPicker);
app.component(WeekPicker.name, WeekPicker);
app.component(QuarterPicker.name, QuarterPicker);
return app;
};
export { RangePicker, WeekPicker, MonthPicker, QuarterPicker };
export default DatePicker as typeof DatePicker & Plugin;

View File

@ -0,0 +1,36 @@
import type { Dayjs } from 'dayjs';
import type { App } from 'vue';
import dayjsGenerateConfig from '../vc-picker/generate/dayjs';
import type {
PickerProps,
PickerDateProps,
RangePickerProps as BaseRangePickerProps,
} from './generatePicker';
import generatePicker from './generatePicker';
import { ExtraDatePickerProps, ExtraRangePickerProps } from './generatePicker/props';
export type DatePickerProps = PickerProps<Dayjs> & ExtraDatePickerProps<Dayjs>;
export type MonthPickerProps = Omit<PickerDateProps<Dayjs>, 'picker'> & ExtraDatePickerProps<Dayjs>;
export type WeekPickerProps = Omit<PickerDateProps<Dayjs>, 'picker'> & ExtraDatePickerProps<Dayjs>;
export type RangePickerProps = BaseRangePickerProps<Dayjs> & ExtraRangePickerProps<Dayjs>;
const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig);
const RangePicker = DatePicker.RangePicker;
const MonthPicker = DatePicker.MonthPicker;
const WeekPicker = DatePicker.WeekPicker;
const QuarterPicker = DatePicker.QuarterPicker;
/* istanbul ignore next */
DatePicker.install = function (app: App) {
app.component(DatePicker.name, DatePicker);
app.component(RangePicker.name, RangePicker);
app.component(MonthPicker.name, MonthPicker);
app.component(WeekPicker.name, WeekPicker);
app.component(QuarterPicker.name, QuarterPicker);
return app;
};
export { RangePicker, WeekPicker, MonthPicker, QuarterPicker };
export default DatePicker as typeof DatePicker & Plugin;

View File

@ -9,16 +9,17 @@ import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import { getRangePlaceholder } from '../util'; import { getRangePlaceholder } from '../util';
import type { RangePickerProps } from '.'; import type { RangePickerProps } from '.';
import { getTimeProps, Components } from '.'; import { getTimeProps, Components } from '.';
import { 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 { commonProps, rangePickerProps } from './props'; import { commonProps, ExtraRangePickerProps, rangePickerProps } from './props';
import { PanelMode, RangeValue } from '../../vc-picker/interface'; import { PanelMode, RangeValue } from '../../vc-picker/interface';
import { RangePickerSharedProps } from '../../vc-picker/RangePicker'; import { RangePickerSharedProps } from '../../vc-picker/RangePicker';
import devWarning from '../../vc-util/devWarning'; import devWarning from '../../vc-util/devWarning';
export default function generateRangePicker<DateType>(generateConfig: GenerateConfig<DateType>) { export default function generateRangePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
const RangePicker = defineComponent<RangePickerProps<DateType>>({ const RangePicker = defineComponent<RangePickerProps<DateType> & ExtraRangePickerProps<DateType>>(
{
name: 'ARangePicker', name: 'ARangePicker',
inheritAttrs: false, inheritAttrs: false,
props: { props: {
@ -67,8 +68,11 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
}, },
}); });
const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => { const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => {
emit('update:value', dates); const values = props.valueFormat
emit('change', dates, dateStrings); ? generateConfig.toString(dates, props.valueFormat)
: dates;
emit('update:value', values);
emit('change', values, dateStrings);
}; };
const onOpenChange = (open: boolean) => { const onOpenChange = (open: boolean) => {
emit('openChange', open); emit('openChange', open);
@ -79,16 +83,51 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
const onBlur = () => { const onBlur = () => {
emit('blur'); emit('blur');
}; };
const onPanelChange = (values: RangeValue<DateType>, modes: [PanelMode, PanelMode]) => { const onPanelChange = (dates: RangeValue<DateType>, modes: [PanelMode, PanelMode]) => {
const values = props.valueFormat
? generateConfig.toString(dates, props.valueFormat)
: dates;
emit('panelChange', values, modes); emit('panelChange', values, modes);
}; };
const onOk = (value: DateType) => { const onOk = (value: DateType) => {
emit('ok', value); emit('ok', value);
}; };
const onCalendarChange: RangePickerSharedProps<DateType>['onCalendarChange'] = (...args) => { const onCalendarChange: RangePickerSharedProps<DateType>['onCalendarChange'] = (
emit('calendarChange', ...args); dates: [DateType, DateType],
dateStrings: [string, string],
info,
) => {
const values = props.valueFormat
? generateConfig.toString(dates, props.valueFormat)
: dates;
emit('calendarChange', values, dateStrings, info);
}; };
const [contextLocale] = useLocaleReceiver('DatePicker', enUS); 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 () => { return () => {
const locale = { ...contextLocale.value, ...props.locale }; const locale = { ...contextLocale.value, ...props.locale };
const p = { ...props, ...attrs } as RangePickerProps<DateType>; const p = { ...props, ...attrs } as RangePickerProps<DateType>;
@ -133,6 +172,9 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
transitionName={transitionName || `${rootPrefixCls.value}-slide-up`} transitionName={transitionName || `${rootPrefixCls.value}-slide-up`}
{...restProps} {...restProps}
{...additionalOverrideProps} {...additionalOverrideProps}
value={value.value}
defaultValue={defaultValue.value}
defaultPickerValue={defaultPickerValue.value}
picker={picker} picker={picker}
class={classNames( class={classNames(
{ {
@ -162,7 +204,8 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
); );
}; };
}, },
}); },
);
return RangePicker; return RangePicker;
} }

View File

@ -9,14 +9,14 @@ import { getPlaceholder } from '../util';
import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver'; import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import type { PickerProps, PickerDateProps, PickerTimeProps } from '.'; import type { PickerProps, PickerDateProps, PickerTimeProps } from '.';
import { getTimeProps, Components } from '.'; import { getTimeProps, Components } from '.';
import { 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 { commonProps, datePickerProps } from './props'; import { commonProps, datePickerProps, ExtraDatePickerProps } from './props';
import devWarning from '../../vc-util/devWarning'; import devWarning from '../../vc-util/devWarning';
export default function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) { export default function generatePicker<DateType>(generateConfig: GenerateConfig<DateType>) {
type DatePickerProps = PickerProps<DateType>; type DatePickerProps = PickerProps<DateType> & ExtraDatePickerProps<DateType>;
function getPicker<InnerPickerProps extends DatePickerProps>( function getPicker<InnerPickerProps extends DatePickerProps>(
picker?: PickerMode, picker?: PickerMode,
@ -68,8 +68,9 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
}, },
}); });
const onChange = (date: DateType, dateString: string) => { const onChange = (date: DateType, dateString: string) => {
emit('update:value', date); const value = props.valueFormat ? generateConfig.toString(date, props.valueFormat) : date;
emit('change', date, dateString); emit('update:value', value);
emit('change', value, dateString);
}; };
const onOpenChange = (open: boolean) => { const onOpenChange = (open: boolean) => {
emit('openChange', open); emit('openChange', open);
@ -80,7 +81,8 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
const onBlur = () => { const onBlur = () => {
emit('blur'); emit('blur');
}; };
const onPanelChange = (value: DateType, mode: PanelMode | null) => { const onPanelChange = (date: DateType, mode: PanelMode | null) => {
const value = props.valueFormat ? generateConfig.toString(date, props.valueFormat) : date;
emit('panelChange', value, mode); emit('panelChange', value, mode);
}; };
const onOk = (value: DateType) => { const onOk = (value: DateType) => {
@ -88,6 +90,32 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
}; };
const [contextLocale] = useLocaleReceiver('DatePicker', enUS); 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 () => { return () => {
const locale = { ...contextLocale.value, ...props.locale }; const locale = { ...contextLocale.value, ...props.locale };
const p = { ...props, ...attrs } as InnerPickerProps; const p = { ...props, ...attrs } as InnerPickerProps;
@ -144,6 +172,9 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
transitionName={transitionName || `${rootPrefixCls.value}-slide-up`} transitionName={transitionName || `${rootPrefixCls.value}-slide-up`}
{...restProps} {...restProps}
{...additionalOverrideProps} {...additionalOverrideProps}
value={value.value}
defaultValue={defaultValue.value}
defaultPickerValue={defaultPickerValue.value}
showToday={showToday} showToday={showToday}
locale={locale!.lang} locale={locale!.lang}
class={classNames( class={classNames(

View File

@ -72,14 +72,15 @@ function commonProps<DateType>() {
disabledDate: { type: Function as PropType<(date: DateType) => boolean> }, disabledDate: { type: Function as PropType<(date: DateType) => boolean> },
mode: { type: String as PropType<PanelMode> }, mode: { type: String as PropType<PanelMode> },
picker: { type: String as PropType<PickerMode> }, picker: { type: String as PropType<PickerMode> },
valueFormat: String,
}; };
} }
function datePickerProps<DateType>() { function datePickerProps<DateType>() {
return { return {
defaultPickerValue: { type: [String, Object] as PropType<DateType> }, defaultPickerValue: { type: [String, Object] as PropType<DateType | string> },
defaultValue: { type: [String, Object] as PropType<DateType> }, defaultValue: { type: [String, Object] as PropType<DateType | string> },
value: { type: [String, Object] as PropType<DateType> }, value: { type: [String, Object] as PropType<DateType | string> },
disabledTime: { type: Function as PropType<DisabledTime<DateType>> }, disabledTime: { type: Function as PropType<DisabledTime<DateType>> },
format: { format: {
type: [String, Function, Array] as PropType< type: [String, Function, Array] as PropType<
@ -98,8 +99,10 @@ function rangePickerProps<DateType>() {
return { return {
allowEmpty: { type: Array as unknown as PropType<[boolean, boolean]> }, allowEmpty: { type: Array as unknown as PropType<[boolean, boolean]> },
dateRender: { type: Function as PropType<RangeDateRender<DateType>> }, dateRender: { type: Function as PropType<RangeDateRender<DateType>> },
defaultPickerValue: { type: Array as unknown as PropType<[DateType, DateType]> }, defaultPickerValue: {
defaultValue: { type: Array as unknown as PropType<[DateType, DateType]> }, type: Array as unknown as PropType<[DateType, DateType] | [string, string]>,
},
defaultValue: { type: Array as unknown as PropType<[DateType, DateType] | [string, string]> },
value: { type: Array as unknown as PropType<[DateType, DateType]> }, value: { type: Array as unknown as PropType<[DateType, DateType]> },
disabledTime: { disabledTime: {
type: Function as PropType<(date: EventValue<DateType>, type: RangeType) => DisabledTimes>, type: Function as PropType<(date: EventValue<DateType>, type: RangeType) => DisabledTimes>,
@ -121,4 +124,18 @@ function rangePickerProps<DateType>() {
}; };
} }
export type ExtraDatePickerProps<DateType> = {
valueFormat?: string;
defaultPickerValue?: DateType | string;
defaultValue?: DateType | string;
value?: DateType | string;
};
export type ExtraRangePickerProps<DateType> = {
valueFormat?: string;
defaultPickerValue?: [DateType, DateType] | [string, string];
defaultValue?: [DateType, DateType] | [string, string];
value?: [DateType, DateType] | [string, string];
};
export { commonProps, datePickerProps, rangePickerProps }; export { commonProps, datePickerProps, rangePickerProps };

View File

@ -1,35 +1,4 @@
import type { Moment } from 'moment'; import DatePicker from './moment';
import type { App } from 'vue'; export * from './moment';
import momentGenerateConfig from '../vc-picker/generate/moment';
import type {
PickerProps,
PickerDateProps,
RangePickerProps as BaseRangePickerProps,
} from './generatePicker';
import generatePicker from './generatePicker';
export type DatePickerProps = PickerProps<Moment>; export default DatePicker;
export type MonthPickerProps = Omit<PickerDateProps<Moment>, 'picker'>;
export type WeekPickerProps = Omit<PickerDateProps<Moment>, 'picker'>;
export type RangePickerProps = BaseRangePickerProps<Moment>;
const DatePicker = generatePicker<Moment>(momentGenerateConfig);
const RangePicker = DatePicker.RangePicker;
const MonthPicker = DatePicker.MonthPicker;
const WeekPicker = DatePicker.WeekPicker;
const QuarterPicker = DatePicker.QuarterPicker;
/* istanbul ignore next */
DatePicker.install = function (app: App) {
app.component(DatePicker.name, DatePicker);
app.component(RangePicker.name, RangePicker);
app.component(MonthPicker.name, MonthPicker);
app.component(WeekPicker.name, WeekPicker);
app.component(QuarterPicker.name, QuarterPicker);
return app;
};
export { RangePicker, WeekPicker, MonthPicker, QuarterPicker };
export default DatePicker as typeof DatePicker & Plugin;

View File

@ -0,0 +1,38 @@
import type { Moment } from 'moment';
import type { App } from 'vue';
import momentGenerateConfig from '../vc-picker/generate/moment';
import type {
PickerProps,
PickerDateProps,
RangePickerProps as BaseRangePickerProps,
} from './generatePicker';
import generatePicker from './generatePicker';
import { ExtraDatePickerProps, ExtraRangePickerProps } from './generatePicker/props';
export type DatePickerProps = PickerProps<Moment> & ExtraDatePickerProps<Moment>;
export type MonthPickerProps = Omit<PickerDateProps<Moment>, 'picker'> &
ExtraDatePickerProps<Moment>;
export type WeekPickerProps = Omit<PickerDateProps<Moment>, 'picker'> &
ExtraDatePickerProps<Moment>;
export type RangePickerProps = BaseRangePickerProps<Moment> & ExtraRangePickerProps<Moment>;
const DatePicker = generatePicker<Moment>(momentGenerateConfig);
const RangePicker = DatePicker.RangePicker;
const MonthPicker = DatePicker.MonthPicker;
const WeekPicker = DatePicker.WeekPicker;
const QuarterPicker = DatePicker.QuarterPicker;
/* istanbul ignore next */
DatePicker.install = function (app: App) {
app.component(DatePicker.name, DatePicker);
app.component(RangePicker.name, RangePicker);
app.component(MonthPicker.name, MonthPicker);
app.component(WeekPicker.name, WeekPicker);
app.component(QuarterPicker.name, QuarterPicker);
return app;
};
export { RangePicker, WeekPicker, MonthPicker, QuarterPicker };
export default DatePicker as typeof DatePicker & Plugin;

View File

@ -29,7 +29,7 @@ import useTextValueMapping from './hooks/useTextValueMapping';
import useValueTexts from './hooks/useValueTexts'; import useValueTexts from './hooks/useValueTexts';
import useHoverValue from './hooks/useHoverValue'; import useHoverValue from './hooks/useHoverValue';
import type { CSSProperties, HtmlHTMLAttributes, Ref } from 'vue'; import type { CSSProperties, HtmlHTMLAttributes, Ref } from 'vue';
import { computed, createVNode, defineComponent, ref, toRef, watch } from 'vue'; import { computed, defineComponent, ref, toRef, watch } from 'vue';
import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface'; import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface';
import type { VueNode } from '../_util/type'; import type { VueNode } from '../_util/type';
import type { AlignType } from '../vc-align/interface'; import type { AlignType } from '../vc-align/interface';

View File

@ -31,7 +31,7 @@ import useHoverValue from './hooks/useHoverValue';
import type { VueNode } from '../_util/type'; import type { VueNode } from '../_util/type';
import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface'; import type { ChangeEvent, FocusEventHandler, MouseEventHandler } from '../_util/EventInterface';
import type { HTMLAttributes } from 'vue'; import type { HTMLAttributes } from 'vue';
import { computed, createVNode, defineComponent, ref, toRef, watch, watchEffect } from 'vue'; import { computed, defineComponent, ref, toRef, watch, watchEffect } from 'vue';
import useMergedState from '../_util/hooks/useMergedState'; import useMergedState from '../_util/hooks/useMergedState';
import { warning } from '../vc-util/warning'; import { warning } from '../vc-util/warning';
import useState from '../_util/hooks/useState'; import useState from '../_util/hooks/useState';

View File

@ -22,6 +22,7 @@ import {
startOfWeek, startOfWeek,
format as formatDate, format as formatDate,
parse as parseDate, parse as parseDate,
isDate,
} from 'date-fns'; } from 'date-fns';
import * as Locale from 'date-fns/locale'; import * as Locale from 'date-fns/locale';
import type { GenerateConfig } from '.'; import type { GenerateConfig } from '.';
@ -110,6 +111,28 @@ const generateConfig: GenerateConfig<Date> = {
return null; return null;
}, },
}, },
toDate: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) =>
typeof val === 'string' && val ? parseDate(val, valueFormat, new Date()) : val || null,
) as Date[];
} else {
return (
typeof value === 'string' && value
? parseDate(value, valueFormat, new Date())
: value || null
) as Date;
}
},
toString: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) =>
isDate(val) ? formatDate(val as Date, valueFormat) : val,
) as string[];
} else {
return (isDate(value) ? formatDate(value as Date, valueFormat) : value) as string;
}
},
}; };
export default generateConfig; export default generateConfig;

View File

@ -113,6 +113,25 @@ const generateConfig: GenerateConfig<Dayjs> = {
return null; return null;
}, },
}, },
toDate: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) =>
typeof val === 'string' && val ? dayjs(val, valueFormat) : val || null,
) as Dayjs[];
} else {
return (
typeof value === 'string' && value ? dayjs(value, valueFormat) : value || null
) as Dayjs;
}
},
toString: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) => (dayjs.isDayjs(val) ? val.format(valueFormat) : val));
} else {
return dayjs.isDayjs(value) ? value.format(valueFormat) : value;
}
},
}; };
export default generateConfig; export default generateConfig;

View File

@ -26,6 +26,14 @@ export type GenerateConfig<DateType> = {
isAfter: (date1: DateType, date2: DateType) => boolean; isAfter: (date1: DateType, date2: DateType) => boolean;
isValidate: (date: DateType) => boolean; isValidate: (date: DateType) => boolean;
toDate: (
value: string | string[] | DateType | DateType[],
valueFormat: string,
) => DateType | DateType[];
toString: (
value: string | string[] | DateType | DateType[],
valueFormat: string,
) => string | string[];
locale: { locale: {
getWeekFirstDay: (locale: string) => number; getWeekFirstDay: (locale: string) => number;
getWeekFirstDate: (locale: string, value: DateType) => DateType; getWeekFirstDate: (locale: string, value: DateType) => DateType;

View File

@ -135,6 +135,24 @@ const generateConfig: GenerateConfig<Moment> = {
return null; return null;
}, },
}, },
toDate: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) =>
typeof val === 'string' && val ? moment(val, valueFormat) : val || null,
) as Moment[];
} else {
return (
typeof value === 'string' && value ? moment(value, valueFormat) : value || null
) as Moment;
}
},
toString: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) => (moment.isMoment(val) ? val.format(valueFormat) : val));
} else {
return moment.isMoment(value) ? value.format(valueFormat) : value;
}
},
}; };
export default generateConfig; export default generateConfig;