diff --git a/components/date-picker/__tests__/QuarterPicker.test.js b/components/date-picker/__tests__/QuarterPicker.test.js index 6be242612..d9e72a988 100644 --- a/components/date-picker/__tests__/QuarterPicker.test.js +++ b/components/date-picker/__tests__/QuarterPicker.test.js @@ -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); + }); }); diff --git a/components/date-picker/__tests__/RangePicker.test.js b/components/date-picker/__tests__/RangePicker.test.js index 8ff8b9a52..c277035f4 100644 --- a/components/date-picker/__tests__/RangePicker.test.js +++ b/components/date-picker/__tests__/RangePicker.test.js @@ -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])); + }); }); diff --git a/components/date-picker/generatePicker/generateRangePicker.tsx b/components/date-picker/generatePicker/generateRangePicker.tsx index 4f9f4b10d..13e6f2a61 100644 --- a/components/date-picker/generatePicker/generateRangePicker.tsx +++ b/components/date-picker/generatePicker/generateRangePicker.tsx @@ -68,7 +68,7 @@ export default function generateRangePicker( 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, dateStrings: [string, string]) => { const values = maybeToStrings(dates); emit('update:value', values); emit('change', values, dateStrings); diff --git a/components/vc-picker/generate/dayjs.ts b/components/vc-picker/generate/dayjs.ts index ab817fda2..80266ff02 100644 --- a/components/vc-picker/generate/dayjs.ts +++ b/components/vc-picker/generate/dayjs.ts @@ -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 = { // get getNow: () => dayjs(), @@ -177,13 +231,9 @@ const generateConfig: GenerateConfig = { 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) => {