From f2e9d6e049b3c52eef4ea7d9cb080b4dca23c7a1 Mon Sep 17 00:00:00 2001 From: Evan Johnson Date: Tue, 2 Jul 2024 14:18:23 -0400 Subject: [PATCH] Fix end time selection before selecting date (#6858) --- .../changelog/@unreleased/pr-6858.v2.yml | 5 ++++ .../date-range-picker3/dateRangePicker3.tsx | 25 +++++++++++++++-- .../test/components/dateRangePicker3Tests.tsx | 28 +++++++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 packages/datetime2/changelog/@unreleased/pr-6858.v2.yml diff --git a/packages/datetime2/changelog/@unreleased/pr-6858.v2.yml b/packages/datetime2/changelog/@unreleased/pr-6858.v2.yml new file mode 100644 index 0000000000..842d070d25 --- /dev/null +++ b/packages/datetime2/changelog/@unreleased/pr-6858.v2.yml @@ -0,0 +1,5 @@ +type: fix +fix: + description: Fix `DateRangePicker` end time selection before selecting end date + links: + - https://github.com/palantir/blueprint/pull/6858 diff --git a/packages/datetime2/src/components/date-range-picker3/dateRangePicker3.tsx b/packages/datetime2/src/components/date-range-picker3/dateRangePicker3.tsx index 5cd0ed9679..50b4ad94b3 100644 --- a/packages/datetime2/src/components/date-range-picker3/dateRangePicker3.tsx +++ b/packages/datetime2/src/components/date-range-picker3/dateRangePicker3.tsx @@ -15,7 +15,7 @@ */ import classNames from "classnames"; -import { format } from "date-fns"; +import { addDays, format } from "date-fns"; import * as React from "react"; import type { DateFormatter, DayModifiers, DayMouseEventHandler, ModifiersClassNames } from "react-day-picker"; @@ -265,17 +265,38 @@ export class DateRangePicker3 extends DateFnsLocalizedComponent { + const { value } = this.state; + const otherIndex = dateIndex === 0 ? 1 : 0; + const otherDate = value[otherIndex]; + if (otherDate == null) { + return new Date(); + } + + const { allowSingleDayRange } = this.props; + if (!allowSingleDayRange) { + const dateDiff = dateIndex === 0 ? -1 : 1; + return addDays(otherDate, dateDiff); + } + + return otherDate; + }; + private handleTimeChangeLeftCalendar = (time: Date) => { this.handleTimeChange(time, 0); }; diff --git a/packages/datetime2/test/components/dateRangePicker3Tests.tsx b/packages/datetime2/test/components/dateRangePicker3Tests.tsx index b50761f229..2430a6b37f 100644 --- a/packages/datetime2/test/components/dateRangePicker3Tests.tsx +++ b/packages/datetime2/test/components/dateRangePicker3Tests.tsx @@ -15,7 +15,7 @@ */ import { assert } from "chai"; -import { format, parse } from "date-fns"; +import { addDays, format, parse } from "date-fns"; import enUSLocale from "date-fns/locale/en-US"; import { mount, type ReactWrapper } from "enzyme"; import * as React from "react"; @@ -1293,11 +1293,35 @@ describe("", () => { assert.equal(parseInt(minuteInputText, 10), newLeftMinute); }); - it("changing time without date uses today", () => { + it("changing time without date uses today, when other date not selected", () => { render({ timePrecision: "minute" }).setTimeInput("minute", "left", 45); assert.isTrue(DateUtils.isSameDay(onChangeSpy.firstCall.args[0][0] as Date, new Date())); }); + it("changing time without date uses other date if selected and `allowSingleDayRange` is true", () => { + const dateRange = render({ timePrecision: "minute", allowSingleDayRange: true }); + + dateRange.left.clickDay(10); + dateRange.setTimeInput("minute", "right", 45); + const [start, end] = dateRange.wrapper.state("value"); + + assert.isNotNull(start); + assert.isNotNull(end); + assert.isTrue(DateUtils.isSameDay(start!, end!)); + }); + + it("changing time without date uses 1 day offset from other date if selected and `allowSingleDayRange` is false", () => { + const dateRange = render({ timePrecision: "minute", allowSingleDayRange: false }); + + dateRange.left.clickDay(10); + dateRange.setTimeInput("minute", "right", 45); + const [start, end] = dateRange.wrapper.state("value"); + + assert.isNotNull(start); + assert.isNotNull(end); + assert.isTrue(DateUtils.isSameDay(end!, addDays(start!, 1))); + }); + it("clicking a shortcut with includeTime=false doesn't change time", () => { render({ timePrecision: "minute", defaultValue: defaultRange }).clickShortcut(); assert.isTrue(DateUtils.isSameTime(onChangeSpy.firstCall.args[0][0] as Date, defaultRange[0]));