fix(dayjs): cannot handle week and quarter String + Format (#6385)

* fix(generateRangePicker): onChange type

* fix(dayjs): cannot handle week's String + Format

* test(date-picker): update snap

* test(date-picker): add WeekPicker valueFormat case

* refactor(dayjs): todate support week and quarter

* test(QuarterPicker): test QuarterPicker valueFormat

* chore(QuarterPicker): findTargetStr rename

* test(DatePicker): update demo snap
pull/6445/head
Cherry7 2023-04-05 09:47:51 +08:00 committed by GitHub
parent 72508d864b
commit 1977074a7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 7 deletions

View File

@ -14,4 +14,20 @@ describe('QuarterPicker', () => {
});
expect(wrapper.html()).toMatchSnapshot();
});
it('test QuarterPicker valueFormat', async () => {
const case1 = '2023-1';
const wrapper = mount(DatePicker, {
props: {
picker: 'quarter',
format: 'YYYY-Q',
valueFormat: 'YYYY-Q',
value: case1,
},
sync: false,
attachTo: 'body',
});
const input = wrapper.find('input');
expect(input.element.value).toBe(case1);
});
});

View File

@ -69,4 +69,25 @@ describe('RangePicker', () => {
await sleep();
expect(wrapper.html()).toMatchSnapshot();
});
fit('test WeekPicker valueFormat', async () => {
const case1 = ['2023-22', '2023-24'];
const case2 = ['2023-27', '2023-28'];
const wrapper = mount(RangePicker, {
props: {
picker: 'week',
format: 'YYYY-ww',
valueFormat: 'YYYY-ww',
value: case1,
},
sync: false,
attachTo: 'body',
});
const inputs = wrapper.findAll('input');
expect((inputs[0].element.value, inputs[1].element.value)).toBe((case1[0], case1[1]));
await asyncExpect(() => {
wrapper.setProps({ value: case2 });
});
expect((inputs[0].element.value, inputs[1].element.value)).toBe((case2[0], case2[1]));
});
});

View File

@ -68,7 +68,7 @@ export default function generateRangePicker<DateType, ExtraProps = {}>(
const maybeToStrings = (dates: DateType[]) => {
return props.valueFormat ? generateConfig.toString(dates, props.valueFormat) : dates;
};
const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => {
const onChange = (dates: RangeValue<DateType>, dateStrings: [string, string]) => {
const values = maybeToStrings(dates);
emit('update:value', values);
emit('change', values, dateStrings);

View File

@ -4,6 +4,7 @@ import weekday from 'dayjs/plugin/weekday';
import localeData from 'dayjs/plugin/localeData';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import weekYear from 'dayjs/plugin/weekYear';
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import type { GenerateConfig } from '.';
@ -15,6 +16,7 @@ dayjs.extend(weekday);
dayjs.extend(localeData);
dayjs.extend(weekOfYear);
dayjs.extend(weekYear);
dayjs.extend(quarterOfYear);
dayjs.extend((_o, c) => {
// todo support Wo (ISO week)
@ -105,6 +107,58 @@ const parseNoMatchNotice = () => {
noteOnce(false, 'Not match any format. Please help to fire a issue about this.');
};
const advancedFormatRegex = /\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|k{1,2}|S/g;
function findTargetStr(val: string, index: number, segmentation: string) {
const items = [...new Set(val.split(segmentation))];
let idx = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
idx += item.length;
if (idx > index) {
return item;
}
idx += segmentation.length;
}
}
const toDateWithValueFormat = (val: string | Dayjs, valueFormat: string) => {
if (dayjs.isDayjs(val)) {
return val;
}
const matchs = valueFormat.matchAll(advancedFormatRegex);
let baseDate = dayjs(val, valueFormat);
if (matchs === null) {
return baseDate;
}
for (const match of matchs) {
const origin = match[0];
const index = match['index'];
if (origin === 'Q') {
const segmentation = val.slice(index - 1, index);
const quarterStr = findTargetStr(val, index, segmentation).match(/\d+/)[0];
baseDate = baseDate.quarter(parseInt(quarterStr));
}
if (origin.toLowerCase() === 'wo') {
const segmentation = val.slice(index - 1, index);
const weekStr = findTargetStr(val, index, segmentation).match(/\d+/)[0];
baseDate = baseDate.week(parseInt(weekStr));
}
if (origin.toLowerCase() === 'ww') {
baseDate = baseDate.week(parseInt(val.slice(index, index + origin.length)));
}
if (origin.toLowerCase() === 'w') {
baseDate = baseDate.week(parseInt(val.slice(index, index + origin.length + 1)));
}
}
return baseDate;
};
const generateConfig: GenerateConfig<Dayjs> = {
// get
getNow: () => dayjs(),
@ -177,13 +231,9 @@ const generateConfig: GenerateConfig<Dayjs> = {
toDate: (value, valueFormat) => {
if (Array.isArray(value)) {
return value.map((val: any) =>
typeof val === 'string' && val ? dayjs(val, valueFormat) : val || null,
) as Dayjs[];
return value.map((val: any) => toDateWithValueFormat(val, valueFormat)) as Dayjs[];
} else {
return (
typeof value === 'string' && value ? dayjs(value, valueFormat) : value || null
) as Dayjs;
return toDateWithValueFormat(value, valueFormat) as Dayjs;
}
},
toString: (value, valueFormat) => {