Skip to content

Commit 1977074

Browse files
authored
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
1 parent 72508d8 commit 1977074

File tree

4 files changed

+94
-7
lines changed

4 files changed

+94
-7
lines changed

components/date-picker/__tests__/QuarterPicker.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,20 @@ describe('QuarterPicker', () => {
1414
});
1515
expect(wrapper.html()).toMatchSnapshot();
1616
});
17+
18+
it('test QuarterPicker valueFormat', async () => {
19+
const case1 = '2023-1';
20+
const wrapper = mount(DatePicker, {
21+
props: {
22+
picker: 'quarter',
23+
format: 'YYYY-Q',
24+
valueFormat: 'YYYY-Q',
25+
value: case1,
26+
},
27+
sync: false,
28+
attachTo: 'body',
29+
});
30+
const input = wrapper.find('input');
31+
expect(input.element.value).toBe(case1);
32+
});
1733
});

components/date-picker/__tests__/RangePicker.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,25 @@ describe('RangePicker', () => {
6969
await sleep();
7070
expect(wrapper.html()).toMatchSnapshot();
7171
});
72+
73+
fit('test WeekPicker valueFormat', async () => {
74+
const case1 = ['2023-22', '2023-24'];
75+
const case2 = ['2023-27', '2023-28'];
76+
const wrapper = mount(RangePicker, {
77+
props: {
78+
picker: 'week',
79+
format: 'YYYY-ww',
80+
valueFormat: 'YYYY-ww',
81+
value: case1,
82+
},
83+
sync: false,
84+
attachTo: 'body',
85+
});
86+
const inputs = wrapper.findAll('input');
87+
expect((inputs[0].element.value, inputs[1].element.value)).toBe((case1[0], case1[1]));
88+
await asyncExpect(() => {
89+
wrapper.setProps({ value: case2 });
90+
});
91+
expect((inputs[0].element.value, inputs[1].element.value)).toBe((case2[0], case2[1]));
92+
});
7293
});

components/date-picker/generatePicker/generateRangePicker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default function generateRangePicker<DateType, ExtraProps = {}>(
6868
const maybeToStrings = (dates: DateType[]) => {
6969
return props.valueFormat ? generateConfig.toString(dates, props.valueFormat) : dates;
7070
};
71-
const onChange = (dates: [DateType, DateType], dateStrings: [string, string]) => {
71+
const onChange = (dates: RangeValue<DateType>, dateStrings: [string, string]) => {
7272
const values = maybeToStrings(dates);
7373
emit('update:value', values);
7474
emit('change', values, dateStrings);

components/vc-picker/generate/dayjs.ts

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import weekday from 'dayjs/plugin/weekday';
44
import localeData from 'dayjs/plugin/localeData';
55
import weekOfYear from 'dayjs/plugin/weekOfYear';
66
import weekYear from 'dayjs/plugin/weekYear';
7+
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
78
import advancedFormat from 'dayjs/plugin/advancedFormat';
89
import customParseFormat from 'dayjs/plugin/customParseFormat';
910
import type { GenerateConfig } from '.';
@@ -15,6 +16,7 @@ dayjs.extend(weekday);
1516
dayjs.extend(localeData);
1617
dayjs.extend(weekOfYear);
1718
dayjs.extend(weekYear);
19+
dayjs.extend(quarterOfYear);
1820

1921
dayjs.extend((_o, c) => {
2022
// todo support Wo (ISO week)
@@ -105,6 +107,58 @@ const parseNoMatchNotice = () => {
105107
noteOnce(false, 'Not match any format. Please help to fire a issue about this.');
106108
};
107109

110+
const advancedFormatRegex = /\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|k{1,2}|S/g;
111+
112+
function findTargetStr(val: string, index: number, segmentation: string) {
113+
const items = [...new Set(val.split(segmentation))];
114+
let idx = 0;
115+
for (let i = 0; i < items.length; i++) {
116+
const item = items[i];
117+
idx += item.length;
118+
if (idx > index) {
119+
return item;
120+
}
121+
idx += segmentation.length;
122+
}
123+
}
124+
125+
const toDateWithValueFormat = (val: string | Dayjs, valueFormat: string) => {
126+
if (dayjs.isDayjs(val)) {
127+
return val;
128+
}
129+
const matchs = valueFormat.matchAll(advancedFormatRegex);
130+
let baseDate = dayjs(val, valueFormat);
131+
if (matchs === null) {
132+
return baseDate;
133+
}
134+
for (const match of matchs) {
135+
const origin = match[0];
136+
const index = match['index'];
137+
138+
if (origin === 'Q') {
139+
const segmentation = val.slice(index - 1, index);
140+
const quarterStr = findTargetStr(val, index, segmentation).match(/\d+/)[0];
141+
baseDate = baseDate.quarter(parseInt(quarterStr));
142+
}
143+
144+
if (origin.toLowerCase() === 'wo') {
145+
const segmentation = val.slice(index - 1, index);
146+
const weekStr = findTargetStr(val, index, segmentation).match(/\d+/)[0];
147+
baseDate = baseDate.week(parseInt(weekStr));
148+
}
149+
150+
if (origin.toLowerCase() === 'ww') {
151+
baseDate = baseDate.week(parseInt(val.slice(index, index + origin.length)));
152+
}
153+
154+
if (origin.toLowerCase() === 'w') {
155+
baseDate = baseDate.week(parseInt(val.slice(index, index + origin.length + 1)));
156+
}
157+
}
158+
159+
return baseDate;
160+
};
161+
108162
const generateConfig: GenerateConfig<Dayjs> = {
109163
// get
110164
getNow: () => dayjs(),
@@ -177,13 +231,9 @@ const generateConfig: GenerateConfig<Dayjs> = {
177231

178232
toDate: (value, valueFormat) => {
179233
if (Array.isArray(value)) {
180-
return value.map((val: any) =>
181-
typeof val === 'string' && val ? dayjs(val, valueFormat) : val || null,
182-
) as Dayjs[];
234+
return value.map((val: any) => toDateWithValueFormat(val, valueFormat)) as Dayjs[];
183235
} else {
184-
return (
185-
typeof value === 'string' && value ? dayjs(value, valueFormat) : value || null
186-
) as Dayjs;
236+
return toDateWithValueFormat(value, valueFormat) as Dayjs;
187237
}
188238
},
189239
toString: (value, valueFormat) => {

0 commit comments

Comments
 (0)