Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(DatePicker): optimize range picker panel header click logic #3207

Merged
merged 2 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 41 additions & 38 deletions src/date-picker/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from '../_common/js/date-picker/format';
import { subtractMonth, addMonth, extractTimeObj } from '../_common/js/date-picker/utils';
import useFormDisabled from '../hooks/useFormDisabled';
import { dateCorrection } from './utils';

export default defineComponent({
name: 'TDateRangePicker',
Expand Down Expand Up @@ -132,7 +133,7 @@ export default defineComponent({
}

// 日期点击
function onCellClick(nextDate: Date, { e, partial }: { e: MouseEvent; partial: DateRangePickerPartial }) {
function onCellClick(nextDate: Date, { e }: { e: MouseEvent; partial: DateRangePickerPartial }) {
const date = nextDate;
// 不开启时间选择时 结束时间默认重置为 23:59:59
if (activeIndex.value && !props.enableTimePicker) date.setHours(23, 59, 59);
Expand All @@ -150,18 +151,6 @@ export default defineComponent({
cacheValue.value = nextValue;
inputValue.value = nextValue;

// date 模式自动切换年月
if (props.mode === 'date') {
// 选择了不属于面板中展示月份的日期
const partialIndex = partial === 'start' ? 0 : 1;
const isAdditional = dayjs(date).month() !== month.value[partialIndex];
if (isAdditional) {
// 保证左侧时间小于右侧
if (activeIndex.value === 0) month.value = [dayjs(date).month(), Math.min(dayjs(date).month() + 1, 11)];
if (activeIndex.value === 1) month.value = [Math.max(dayjs(date).month() - 1, 0), dayjs(date).month()];
}
}

// 有时间选择器走 confirm 逻辑
if (props.enableTimePicker) return;

Expand Down Expand Up @@ -227,28 +216,16 @@ export default defineComponent({
next = addMonth(current, monthCount);
}

const nextYear = [...year.value];
let nextYear = [...year.value];
nextYear[partialIndex] = next.getFullYear();
const nextMonth = [...month.value];
let nextMonth = [...month.value];
nextMonth[partialIndex] = next.getMonth();
const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode);

// 保证左侧时间不大于右侧
if (partialIndex === 0) {
nextYear[1] = Math.max(nextYear[0], nextYear[1]);

if (nextYear[0] === nextYear[1]) {
nextMonth[1] = Math.max(nextMonth[0], nextMonth[1]);
}
}

// 保证左侧时间不大于右侧
if (partialIndex === 1) {
nextYear[0] = Math.min(nextYear[0], nextYear[1]);

if (nextYear[0] === nextYear[1]) {
nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]);
}
}
// 头部日期切换修正
const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect);
nextYear = correctedDate.nextYear;
nextMonth = correctedDate.nextMonth;

year.value = nextYear;
month.value = nextMonth;
Expand Down Expand Up @@ -364,13 +341,18 @@ export default defineComponent({
let partialIndex = partial === 'start' ? 0 : 1;
if (props.enableTimePicker) partialIndex = activeIndex.value;

const nextYear = [...year.value];
let nextYear = [...year.value];
let nextMonth = [...month.value];
nextYear[partialIndex] = nextVal;
// 保证左侧时间不大于右侧
if (partialIndex === 0) nextYear[1] = Math.max(nextYear[0], nextYear[1]);
if (partialIndex === 1) nextYear[0] = Math.min(nextYear[0], nextYear[1]);
const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode);

// 头部日期切换修正
const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect);
nextYear = correctedDate.nextYear;
nextMonth = correctedDate.nextMonth;

year.value = nextYear;
if (!onlyYearSelect) month.value = nextMonth;
}

function onMonthChange(nextVal: number, { partial }: { partial: DateRangePickerPartial }) {
Expand All @@ -381,8 +363,29 @@ export default defineComponent({
nextMonth[partialIndex] = nextVal;
// 保证左侧时间不大于右侧
if (year.value[0] === year.value[1]) {
if (partialIndex === 0) nextMonth[1] = Math.max(nextMonth[0], nextMonth[1]);
if (partialIndex === 1) nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]);
if (partialIndex === 0) {
// 操作了左侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错右侧比左侧大 1
if (nextMonth[1] <= nextMonth[0]) {
nextMonth[1] = nextMonth[0] + 1;
if (nextMonth[1] === 12) {
// 处理跨年的边界场景
nextMonth[1] = 0;
year.value = [year.value?.[0], year.value?.[1] + 1];
}
}
}
if (partialIndex === 1) {
// 操作了右侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错左侧比右侧小 1
nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]);
if (nextMonth[0] >= nextMonth[1]) {
nextMonth[0] -= 1;
if (nextMonth[0] === -1) {
// 处理跨年的边界场景
nextMonth[0] = 11;
year.value = [year.value?.[0] - 1, year.value?.[1]];
}
}
}
}

month.value = nextMonth;
Expand Down
66 changes: 41 additions & 25 deletions src/date-picker/DateRangePickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import TRangePanel from './panel/RangePanel';
import useRangeValue from './hooks/useRangeValue';
import { formatDate, getDefaultFormat, parseToDayjs } from '../_common/js/date-picker/format';
import { subtractMonth, addMonth, extractTimeObj } from '../_common/js/date-picker/utils';
import { dateCorrection } from './utils';

export default defineComponent({
name: 'TDateRangePickerPanel',
Expand Down Expand Up @@ -147,28 +148,16 @@ export default defineComponent({
next = addMonth(current, monthCount);
}

const nextYear = [...year.value];
let nextYear = [...year.value];
nextYear[partialIndex] = next.getFullYear();
const nextMonth = [...month.value];
let nextMonth = [...month.value];
nextMonth[partialIndex] = next.getMonth();
const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode);

// 保证左侧时间不大于右侧
if (partialIndex === 0) {
nextYear[1] = Math.max(nextYear[0], nextYear[1]);

if (nextYear[0] === nextYear[1]) {
nextMonth[1] = Math.max(nextMonth[0], nextMonth[1]);
}
}

// 保证左侧时间不大于右侧
if (partialIndex === 1) {
nextYear[0] = Math.min(nextYear[0], nextYear[1]);

if (nextYear[0] === nextYear[1]) {
nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]);
}
}
// 头部日期切换修正
const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect);
nextYear = correctedDate.nextYear;
nextMonth = correctedDate.nextMonth;

if (year.value.some((y) => !nextYear.includes(y))) {
props.onYearChange?.({
Expand Down Expand Up @@ -301,13 +290,19 @@ export default defineComponent({
let partialIndex = partial === 'start' ? 0 : 1;
if (props.enableTimePicker) partialIndex = activeIndex.value;

const nextYear = [...year.value];
let nextYear = [...year.value];
nextYear[partialIndex] = nextVal;
// 保证左侧时间不大于右侧
if (partialIndex === 0) nextYear[1] = Math.max(nextYear[0], nextYear[1]);
if (partialIndex === 1) nextYear[0] = Math.min(nextYear[0], nextYear[1]);
let nextMonth = [...month.value];
// 年/季度/月份场景下,头部只有年选择器
const onlyYearSelect = ['year', 'quarter', 'month'].includes(props.mode);

// 头部日期切换修正
const correctedDate = dateCorrection(partialIndex, nextYear, nextMonth, onlyYearSelect);
nextYear = correctedDate.nextYear;
nextMonth = correctedDate.nextMonth;

year.value = nextYear;
if (!onlyYearSelect) month.value = nextMonth;

props.onYearChange?.({
partial,
Expand All @@ -331,8 +326,29 @@ export default defineComponent({
nextMonth[partialIndex] = nextVal;
// 保证左侧时间不大于右侧
if (year[0] === year[1]) {
if (partialIndex === 0) nextMonth[1] = Math.max(nextMonth[0], nextMonth[1]);
if (partialIndex === 1) nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]);
if (partialIndex === 0) {
// 操作了左侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错右侧比左侧大 1
if (nextMonth[1] <= nextMonth[0]) {
nextMonth[1] = nextMonth[0] + 1;
if (nextMonth[1] === 12) {
// 处理跨年的边界场景
nextMonth[1] = 0;
year.value = [year.value?.[0], year.value?.[1] + 1];
}
}
}
if (partialIndex === 1) {
// 操作了右侧区间, 处理右侧区间小于或等于左侧区间的场景,交互上始终报错左侧比右侧小 1
nextMonth[0] = Math.min(nextMonth[0], nextMonth[1]);
if (nextMonth[0] >= nextMonth[1]) {
nextMonth[0] -= 1;
if (nextMonth[0] === -1) {
// 处理跨年的边界场景
nextMonth[0] = 11;
year.value = [year.value?.[0] - 1, year.value?.[1]];
}
}
}
}

month.value = nextMonth;
Expand Down
49 changes: 49 additions & 0 deletions src/date-picker/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 用于头部日期切换修正
// eslint-disable-next-line import/prefer-default-export
export function dateCorrection(
partialIndex: number,
preYear: Array<number>,
preMonth: Array<number>,
onlyYearSelect: boolean,
) {
let nextYear = preYear;
const nextMonth = preMonth;
if (partialIndex === 0) {
if (nextYear[1] <= nextYear[0]) {
if (onlyYearSelect) nextYear[1] = nextYear[0] + 1;
else {
// eslint-disable-next-line prefer-destructuring
nextYear[1] = nextYear[0];
if (nextMonth[1] <= nextMonth[0]) {
nextMonth[1] = nextMonth[0] + 1;
if (nextMonth[1] === 12) {
// 处理跨年的边界场景
nextMonth[1] = 0;
nextYear = [nextYear[0], nextYear[1] + 1];
}
}
}
}
}

// 保证左侧时间不大于右侧
if (partialIndex === 1) {
if (nextYear[0] >= nextYear[1]) {
// 年/季度/月份场景下,头部只有年选择器,直接 - 1
if (onlyYearSelect) nextYear[0] = nextYear[1] - 1;
else {
// eslint-disable-next-line prefer-destructuring
nextYear[0] = nextYear[1];
if (nextMonth[0] >= nextMonth[1]) {
nextMonth[0] = nextMonth[1] - 1;
if (nextMonth[0] === -1) {
// 处理跨年的边界场景
nextMonth[0] = 11;
nextYear = [nextYear[0] - 1, nextYear[1]];
}
}
}
}
}
return { nextYear, nextMonth };
}
Loading