Skip to content

Commit 051361b

Browse files
authored
[DateRangePicker] Allow date picker popover to be closed by esc key press (#7033)
1 parent aa64811 commit 051361b

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

packages/datetime/src/components/date-range-input/dateRangeInput.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,18 @@ export class DateRangeInput extends AbstractPureComponent<DateRangeInputProps, D
630630
private handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
631631
const isTabPressed = e.key === "Tab";
632632
const isEnterPressed = e.key === "Enter";
633+
const isEscapeKeyPressed = e.key === "Escape";
633634
const isShiftPressed = e.shiftKey;
634635

635636
const { selectedStart, selectedEnd } = this.state;
636637

638+
if (isEscapeKeyPressed) {
639+
this.startInputElement?.blur();
640+
this.endInputElement?.blur();
641+
this.setState({ isOpen: false, isStartInputFocused: false, isEndInputFocused: false });
642+
return;
643+
}
644+
637645
// order of JS events is our enemy here. when tabbing between fields,
638646
// this handler will fire in the middle of a focus exchange when no
639647
// field is currently focused. we work around this by referring to the

packages/datetime/test/components/dateRangeInputTests.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,21 @@ describe("<DateRangeInput>", () => {
602602
expect(root.state("isOpen"), "popover closed at end").to.be.false;
603603
});
604604

605+
it("pressing Escape closes the popover", () => {
606+
const { root } = wrap(<DateRangeInput {...DATE_FORMAT} value={[null, null]} />);
607+
root.setState({ isOpen: true });
608+
609+
const startInput = getStartInput(root);
610+
startInput.simulate("focus");
611+
612+
expect(root.state("isOpen")).to.be.true;
613+
614+
startInput.simulate("keydown", { key: "Escape" });
615+
616+
expect(root.state("isOpen")).to.be.false;
617+
expect(isStartInputFocused(root)).to.be.false;
618+
});
619+
605620
it("Clicking a date invokes onChange with the new date range and updates the input fields", () => {
606621
const defaultValue = [START_DATE, null] as DateRange;
607622

packages/datetime2/src/components/date-range-input3/dateRangeInput3.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,18 @@ export class DateRangeInput3 extends DateFnsLocalizedComponent<DateRangeInput3Pr
484484
private handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
485485
const isTabPressed = e.key === "Tab";
486486
const isEnterPressed = e.key === "Enter";
487+
const isEscapeKeyPressed = e.key === "Escape";
487488
const isShiftPressed = e.shiftKey;
488489

489490
const { selectedStart, selectedEnd } = this.state;
490491

492+
if (isEscapeKeyPressed) {
493+
this.startInputElement?.blur();
494+
this.endInputElement?.blur();
495+
this.setState({ isOpen: false, isStartInputFocused: false, isEndInputFocused: false });
496+
return;
497+
}
498+
491499
// order of JS events is our enemy here. when tabbing between fields,
492500
// this handler will fire in the middle of a focus exchange when no
493501
// field is currently focused. we work around this by referring to the

packages/datetime2/test/components/dateRangeInput3Tests.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,6 +2343,21 @@ describe("<DateRangeInput3>", () => {
23432343
assertDateRangesEqual(onChange.args[1][0], [START_STR, null]);
23442344
});
23452345

2346+
it("pressing Escape closes the popover", () => {
2347+
const { root } = wrap(<DateRangeInput3 {...DATE_FORMAT} value={[null, null]} />);
2348+
root.setState({ isOpen: true });
2349+
2350+
const startInput = getStartInput(root);
2351+
startInput.simulate("focus");
2352+
2353+
expect(root.state("isOpen")).to.be.true;
2354+
2355+
startInput.simulate("keydown", { key: "Escape" });
2356+
2357+
expect(root.state("isOpen")).to.be.false;
2358+
expect(isStartInputFocused(root)).to.be.false;
2359+
});
2360+
23462361
it("Clicking a date invokes onChange with the new date range and updates the input field text", () => {
23472362
const onChange = sinon.spy();
23482363
const { root, getDayElement } = wrap(

0 commit comments

Comments
 (0)