From 97ed90c992b580ef11212475535409b1ca82e35f Mon Sep 17 00:00:00 2001 From: ryantanrk Date: Tue, 28 May 2024 21:01:09 +0800 Subject: [PATCH 1/6] chore: more keytype replacement --- src/date_utils.ts | 2 ++ src/day.tsx | 2 +- src/index.tsx | 10 +++---- src/month.tsx | 2 +- src/week_number.tsx | 2 +- src/year.tsx | 4 +-- test/timepicker_test.test.tsx | 23 ++++++++-------- test/week_number_test.test.tsx | 8 +++--- test/year_picker_test.test.tsx | 48 ++++++++++++---------------------- 9 files changed, 44 insertions(+), 57 deletions(-) diff --git a/src/date_utils.ts b/src/date_utils.ts index 470cc6a86..7323219b6 100644 --- a/src/date_utils.ts +++ b/src/date_utils.ts @@ -82,6 +82,8 @@ export enum KeyType { Space = " ", Tab = "Tab", Escape = "Escape", + Backspace = "Backspace", + X = "x", } function getLocaleScope() { diff --git a/src/day.tsx b/src/day.tsx index e2a1d5045..155b085ed 100644 --- a/src/day.tsx +++ b/src/day.tsx @@ -170,7 +170,7 @@ export default class Day extends Component { const eventKey = event.key; if (eventKey === KeyType.Space) { event.preventDefault(); - event.key = "Enter"; + event.key = KeyType.Enter; } this.props.handleOnKeyDown(event); diff --git a/src/index.tsx b/src/index.tsx index 3657aa86d..e71079b4a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -877,7 +877,7 @@ export default class DatePicker extends Component< } const copy = newDate(this.state.preSelection); - if (eventKey === "Enter") { + if (eventKey === KeyType.Enter) { event.preventDefault(); if ( this.inputOk() && @@ -888,11 +888,11 @@ export default class DatePicker extends Component< } else { this.setOpen(false); } - } else if (eventKey === "Escape") { + } else if (eventKey === KeyType.Escape) { event.preventDefault(); this.sendFocusBackToInput(); this.setOpen(false); - } else if (eventKey === "Tab") { + } else if (eventKey === KeyType.Tab) { this.setOpen(false); } @@ -904,7 +904,7 @@ export default class DatePicker extends Component< onPortalKeyDown = (event: React.KeyboardEvent): void => { const eventKey = event.key; - if (eventKey === "Escape") { + if (eventKey === KeyType.Escape) { event.preventDefault(); this.setState( { @@ -1095,7 +1095,7 @@ export default class DatePicker extends Component< // ex: while focusing prev and next month buttons onPopperKeyDown = (event: React.KeyboardEvent): void => { const eventKey = event.key; - if (eventKey === "Escape") { + if (eventKey === KeyType.Escape) { event.preventDefault(); this.sendFocusBackToInput(); } diff --git a/src/month.tsx b/src/month.tsx index cdae9b735..f69477d7a 100644 --- a/src/month.tsx +++ b/src/month.tsx @@ -939,7 +939,7 @@ export default class Month extends Component { onKeyDown={(event) => { if (isSpaceKeyDown(event)) { event.preventDefault(); - event.key = "Enter"; + event.key = KeyType.Enter; } this.onMonthKeyDown(event, m); diff --git a/src/week_number.tsx b/src/week_number.tsx index ca3ca2f3b..b5cab9136 100644 --- a/src/week_number.tsx +++ b/src/week_number.tsx @@ -47,7 +47,7 @@ export default class WeekNumber extends Component { const eventKey = event.key; if (eventKey === KeyType.Space) { event.preventDefault(); - event.key = "Enter"; + event.key = KeyType.Enter; } this.props.handleOnKeyDown(event); diff --git a/src/year.tsx b/src/year.tsx index 95a8f4fbc..551e63d53 100644 --- a/src/year.tsx +++ b/src/year.tsx @@ -248,7 +248,7 @@ export default class Year extends Component { const { key } = event; const { date, yearItemNumber, handleOnKeyDown } = this.props; - if (key !== "Tab") { + if (key !== KeyType.Tab) { // preventDefault on tab event blocks focus change event.preventDefault(); } @@ -429,7 +429,7 @@ export default class Year extends Component { onKeyDown={(event) => { if (isSpaceKeyDown(event)) { event.preventDefault(); - event.key = "Enter"; + event.key = KeyType.Enter; } this.onYearKeyDown(event, y); diff --git a/test/timepicker_test.test.tsx b/test/timepicker_test.test.tsx index 7989933fd..c5cc95196 100644 --- a/test/timepicker_test.test.tsx +++ b/test/timepicker_test.test.tsx @@ -1,7 +1,7 @@ import { render, fireEvent, waitFor } from "@testing-library/react"; import React from "react"; -import { newDate, formatDate } from "../src/date_utils"; +import { newDate, formatDate, KeyType } from "../src/date_utils"; import DatePicker from "../src/index"; import { getKey } from "./test_utils"; @@ -152,7 +152,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey("Enter")); + fireEvent.keyDown(lis[1], getKey(KeyType.Enter)); expect(getInputString()).toBe("February 28, 2018 12:30 AM"); }); @@ -163,7 +163,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey(" ")); + fireEvent.keyDown(lis[1], getKey(KeyType.Space)); expect(getInputString()).toBe("February 28, 2018 12:30 AM"); }); @@ -176,7 +176,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey("Enter")); + fireEvent.keyDown(lis[1], getKey(KeyType.Enter)); await waitFor(() => { expect(document.activeElement).toBe(input); @@ -190,7 +190,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey("Escape")); + fireEvent.keyDown(lis[1], getKey(KeyType.Escape)); expect(getInputString()).toBe("February 28, 2018 4:43 PM"); }); @@ -204,7 +204,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey("Escape")); + fireEvent.keyDown(lis[1], getKey(KeyType.Escape)); expect(onKeyDownSpy).toHaveBeenCalledTimes(1); }); @@ -218,7 +218,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey("Enter")); + fireEvent.keyDown(lis[1], getKey(KeyType.Enter)); expect(onKeyDownSpy).toHaveBeenCalledTimes(1); }); @@ -232,7 +232,7 @@ describe("TimePicker", () => { datePicker?.querySelector(".react-datepicker__time-container") ?? new HTMLElement(); const lis = time.querySelectorAll("li"); - fireEvent.keyDown(lis[1], getKey(" ")); + fireEvent.keyDown(lis[1], getKey(KeyType.Space)); expect(onKeyDownSpy).toHaveBeenCalledTimes(1); }); @@ -243,9 +243,10 @@ describe("TimePicker", () => { showTimeSelectOnly: true, }); fireEvent.focus(instance?.input ?? new HTMLElement()); - fireEvent.keyDown(instance?.input ?? new HTMLElement(), { - key: "ArrowDown", - }); + fireEvent.keyDown( + instance?.input ?? new HTMLElement(), + getKey(KeyType.ArrowDown), + ); expect(onKeyDownSpy).toHaveBeenCalledTimes(1); }); diff --git a/test/week_number_test.test.tsx b/test/week_number_test.test.tsx index c7c23da83..533cb5ae6 100644 --- a/test/week_number_test.test.tsx +++ b/test/week_number_test.test.tsx @@ -94,20 +94,20 @@ describe("WeekNumber", () => { describe("handleOnKeyDown", () => { const handleOnKeyDownMock = jest.fn((event) => { - if (event.key === " ") { + if (event.key === utils.KeyType.Space) { event.preventDefault(); - event.key = "Enter"; + event.key = utils.KeyType.Enter; } }); it("should change space key to Enter", () => { const eventSpace = { - key: " ", + key: utils.KeyType.Space, preventDefault: jest.fn(), }; handleOnKeyDownMock(eventSpace); expect(eventSpace.preventDefault).toHaveBeenCalled(); - expect(eventSpace.key).toBe("Enter"); + expect(eventSpace.key).toBe(utils.KeyType.Enter); }); it("should not change any other key", () => { diff --git a/test/year_picker_test.test.tsx b/test/year_picker_test.test.tsx index 1c5e60287..3d8b1d913 100644 --- a/test/year_picker_test.test.tsx +++ b/test/year_picker_test.test.tsx @@ -627,31 +627,13 @@ describe("YearPicker", () => { ).container; const simulateLeft = (target) => - fireEvent.keyDown(target, { - key: "ArrowLeft", - keyCode: 37, - which: 37, - }); + fireEvent.keyDown(target, getKey(utils.KeyType.ArrowLeft)); const simulateRight = (target) => - fireEvent.keyDown(target, { - key: "ArrowRight", - keyCode: 39, - which: 39, - }); - + fireEvent.keyDown(target, getKey(utils.KeyType.ArrowRight)); const simulateUp = (target) => - fireEvent.keyDown(target, { - key: "ArrowUp", - keyCode: 38, - which: 38, - }); - + fireEvent.keyDown(target, getKey(utils.KeyType.ArrowUp)); const simulateDown = (target) => - fireEvent.keyDown(target, { - key: "ArrowDown", - keyCode: 40, - which: 40, - }); + fireEvent.keyDown(target, getKey(utils.KeyType.ArrowDown)); it("should preSelect and set 2020 on left arrow press", () => { const yearPicker = getPicker("2021-01-01"); @@ -780,11 +762,10 @@ describe("YearPicker", () => { ".react-datepicker__year-text--selected", ); - fireEvent.keyDown(target ?? new HTMLElement(), { - key: "Enter", - code: 13, - which: 13, - }); + fireEvent.keyDown( + target ?? new HTMLElement(), + getKey(utils.KeyType.Enter), + ); expect(utils.getYear(selectedDay)).toBe(2021); }); @@ -805,9 +786,10 @@ describe("YearPicker", () => { const year = container.querySelector(".react-datepicker__year-text"); - fireEvent.keyDown(year ?? new HTMLElement(), { - key: "ArrowDown", - }); + fireEvent.keyDown( + year ?? new HTMLElement(), + getKey(utils.KeyType.ArrowDown), + ); expect(onKeyDownSpy).toHaveBeenCalledTimes(1); }); @@ -819,8 +801,10 @@ describe("YearPicker", () => { ".react-datepicker__year-text--selected", ); - const SPACE_KEY = " "; - fireEvent.keyDown(target ?? new HTMLElement(), getKey(SPACE_KEY)); + fireEvent.keyDown( + target ?? new HTMLElement(), + getKey(utils.KeyType.Space), + ); expect(utils.getYear(selectedDay)).toBe(2021); }); From 7e4e71e702f246072e91d41b55e6f530fa2e2183 Mon Sep 17 00:00:00 2001 From: ryantanrk Date: Wed, 29 May 2024 09:06:50 +0800 Subject: [PATCH 2/6] ts: convert test_utils.js to test_utils.ts and add KeyType replacements --- test/datepicker_test.test.js | 2 +- test/test_utils.js | 37 --------------------- test/test_utils.ts | 60 ++++++++++++++++++++++++++++++++++ test/year_picker_test.test.tsx | 2 +- 4 files changed, 62 insertions(+), 39 deletions(-) delete mode 100644 test/test_utils.js create mode 100644 test/test_utils.ts diff --git a/test/datepicker_test.test.js b/test/datepicker_test.test.js index 084b17aff..23b147354 100644 --- a/test/datepicker_test.test.js +++ b/test/datepicker_test.test.js @@ -5,7 +5,7 @@ import DatePicker, { registerLocale } from "../src/index"; import TestWrapper from "./test_wrapper.jsx"; import CustomInput from "./helper_components/custom_input.jsx"; import * as utils from "../src/date_utils.ts"; -import { getKey } from "./test_utils.js"; +import { getKey } from "./test_utils"; function getSelectedDayNode(datePicker) { return ( diff --git a/test/test_utils.js b/test/test_utils.js deleted file mode 100644 index 67b72ba51..000000000 --- a/test/test_utils.js +++ /dev/null @@ -1,37 +0,0 @@ -export function getKey(key, shiftKey = false) { - let event = null; - switch (key) { - case "Backspace": - event = { key, code: 8, which: 8 }; - case "Tab": - event = { key, code: 9, which: 9 }; - case "Enter": - event = { key, code: 13, which: 13 }; - case "Escape": - event = { key, code: 27, which: 27 }; - case " ": - event = { key, code: 32, which: 32 }; - case "PageUp": - event = { key, keyCode: 33, which: 33 }; - case "PageDown": - event = { key, keyCode: 34, which: 34 }; - case "End": - event = { key, keyCode: 35, which: 35 }; - case "Home": - event = { key, keyCode: 36, which: 36 }; - case "ArrowLeft": - event = { key, code: 37, which: 37 }; - case "ArrowRight": - event = { key, code: 39, which: 39 }; - case "ArrowUp": - event = { key, code: 38, which: 38 }; - case "ArrowDown": - event = { key, code: 40, which: 40 }; - case "x": - event = { key, code: 88, which: 88 }; - } - if (!event) { - throw new Error("Unknown key :" + key); - } - return { ...event, shiftKey }; -} diff --git a/test/test_utils.ts b/test/test_utils.ts new file mode 100644 index 000000000..d8cad0dd0 --- /dev/null +++ b/test/test_utils.ts @@ -0,0 +1,60 @@ +import { KeyType } from "../src/date_utils"; + +interface KeyEvent { + key: string; + keyCode?: number; + code?: number; + which: number; +} + +export function getKey(key: KeyType, shiftKey: boolean = false) { + let event: KeyEvent = null as unknown as KeyEvent; + switch (key) { + case KeyType.Backspace: + event = { key, code: 8, which: 8 }; + break; + case KeyType.Tab: + event = { key, code: 9, which: 9 }; + break; + case KeyType.Enter: + event = { key, code: 13, which: 13 }; + break; + case KeyType.Escape: + event = { key, code: 27, which: 27 }; + break; + case KeyType.Space: + event = { key, code: 32, which: 32 }; + break; + case KeyType.PageUp: + event = { key, keyCode: 33, which: 33 }; + break; + case KeyType.PageDown: + event = { key, keyCode: 34, which: 34 }; + break; + case KeyType.End: + event = { key, keyCode: 35, which: 35 }; + break; + case KeyType.Home: + event = { key, keyCode: 36, which: 36 }; + break; + case KeyType.ArrowLeft: + event = { key, code: 37, which: 37 }; + break; + case KeyType.ArrowRight: + event = { key, code: 39, which: 39 }; + break; + case KeyType.ArrowUp: + event = { key, code: 38, which: 38 }; + break; + case KeyType.ArrowDown: + event = { key, code: 40, which: 40 }; + break; + case KeyType.X: + event = { key, code: 88, which: 88 }; + break; + } + if (!event) { + throw new Error("Unknown key :" + key); + } + return { ...event, shiftKey }; +} diff --git a/test/year_picker_test.test.tsx b/test/year_picker_test.test.tsx index 3d8b1d913..94c05e5ac 100644 --- a/test/year_picker_test.test.tsx +++ b/test/year_picker_test.test.tsx @@ -5,7 +5,7 @@ import * as utils from "../src/date_utils"; import DatePicker from "../src/index"; import Year from "../src/year"; -import { getKey } from "./test_utils.js"; +import { getKey } from "./test_utils"; describe("YearPicker", () => { it("should show year picker component when showYearPicker prop is present", () => { From baca8036caa402dccf666ed828c9c40da4a3c540 Mon Sep 17 00:00:00 2001 From: ryantanrk Date: Wed, 29 May 2024 09:18:10 +0800 Subject: [PATCH 3/6] remove X from KeyType enum --- src/date_utils.ts | 1 - test/test_utils.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/date_utils.ts b/src/date_utils.ts index 7323219b6..d066be54b 100644 --- a/src/date_utils.ts +++ b/src/date_utils.ts @@ -83,7 +83,6 @@ export enum KeyType { Tab = "Tab", Escape = "Escape", Backspace = "Backspace", - X = "x", } function getLocaleScope() { diff --git a/test/test_utils.ts b/test/test_utils.ts index d8cad0dd0..8a243f8a3 100644 --- a/test/test_utils.ts +++ b/test/test_utils.ts @@ -49,7 +49,7 @@ export function getKey(key: KeyType, shiftKey: boolean = false) { case KeyType.ArrowDown: event = { key, code: 40, which: 40 }; break; - case KeyType.X: + case "x" as KeyType: event = { key, code: 88, which: 88 }; break; } From c5e3be9693c60a6d15588ad33adc1919b4f5c64d Mon Sep 17 00:00:00 2001 From: ryantanrk Date: Wed, 29 May 2024 09:21:08 +0800 Subject: [PATCH 4/6] chore: rename keyCode to code --- test/test_utils.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/test_utils.ts b/test/test_utils.ts index 8a243f8a3..cf524c3bd 100644 --- a/test/test_utils.ts +++ b/test/test_utils.ts @@ -2,8 +2,7 @@ import { KeyType } from "../src/date_utils"; interface KeyEvent { key: string; - keyCode?: number; - code?: number; + code: number; which: number; } @@ -26,16 +25,16 @@ export function getKey(key: KeyType, shiftKey: boolean = false) { event = { key, code: 32, which: 32 }; break; case KeyType.PageUp: - event = { key, keyCode: 33, which: 33 }; + event = { key, code: 33, which: 33 }; break; case KeyType.PageDown: - event = { key, keyCode: 34, which: 34 }; + event = { key, code: 34, which: 34 }; break; case KeyType.End: - event = { key, keyCode: 35, which: 35 }; + event = { key, code: 35, which: 35 }; break; case KeyType.Home: - event = { key, keyCode: 36, which: 36 }; + event = { key, code: 36, which: 36 }; break; case KeyType.ArrowLeft: event = { key, code: 37, which: 37 }; From 5aaddc1857b40fcc77ba79d1453204a5964ed0a6 Mon Sep 17 00:00:00 2001 From: ryantanrk Date: Wed, 29 May 2024 10:35:17 +0800 Subject: [PATCH 5/6] chore: add unit tests --- test/datepicker_test.test.js | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/test/datepicker_test.test.js b/test/datepicker_test.test.js index 23b147354..ffbbc0d56 100644 --- a/test/datepicker_test.test.js +++ b/test/datepicker_test.test.js @@ -1478,6 +1478,19 @@ describe("DatePicker", () => { utils.formatDate(data.copyM, data.testFormat), ); }); + it("should update the selected date when spacebar is pressed", () => { + const data = getOnInputKeyDownStuff(); + fireEvent.keyDown(data.dateInput, getKey("ArrowDown")); // puts focus on the calendar day + fireEvent.keyDown(getSelectedDayNode(data.instance), getKey("ArrowLeft")); + fireEvent.keyDown(getSelectedDayNode(data.instance), getKey(" ")); + + data.copyM = utils.subDays(data.copyM, 1); + expect(data.callback).toHaveBeenCalled(); + const result = data.callback.mock.calls[0][0]; + expect(utils.formatDate(result, data.testFormat)).toBe( + utils.formatDate(data.copyM, data.testFormat), + ); + }); it("should update the selected date on manual input", () => { const data = getOnInputKeyDownStuff(); fireEvent.change(data.dateInput, { @@ -3344,6 +3357,52 @@ describe("DatePicker", () => { describe("Week picker", () => { describe("Keyboard navigation", () => { + it("should select the week when pressing Enter", () => { + const date = new Date("2021-02-08"); + let selected = date; + const onChange = (d) => { + selected = d; + }; + const data = getOnInputKeyDownStuff({ + showWeekPicker: true, + selected: date, + preSelection: date, + onChange, + }); + + fireEvent.keyDown(data.dateInput, getKey("ArrowDown")); // open + fireEvent.keyDown( + getSelectedDayNode(data.instance), + getKey("ArrowDown"), + ); // navigate to week + fireEvent.keyDown(getSelectedDayNode(data.instance), getKey("Enter")); + expect(utils.formatDate(selected, data.testFormat)).toBe( + utils.formatDate(new Date("2021-02-15"), data.testFormat), + ); + }); + it("should select the week when pressing Space", () => { + const date = new Date("2021-02-08"); + let selected = date; + const onChange = (d) => { + selected = d; + }; + const data = getOnInputKeyDownStuff({ + showWeekPicker: true, + selected: date, + preSelection: date, + onChange, + }); + + fireEvent.keyDown(data.dateInput, getKey("ArrowDown")); // open + fireEvent.keyDown( + getSelectedDayNode(data.instance), + getKey("ArrowDown"), + ); // navigate to week + fireEvent.keyDown(getSelectedDayNode(data.instance), getKey(" ")); + expect(utils.formatDate(selected, data.testFormat)).toBe( + utils.formatDate(new Date("2021-02-15"), data.testFormat), + ); + }); it("should navigate to the previous week when pressing ArrowUp", () => { const date = new Date("2021-02-08"); const data = getOnInputKeyDownStuff({ From d6578b4373f2e0d7a6bf1861954d5f5f581868ab Mon Sep 17 00:00:00 2001 From: ryantanrk Date: Wed, 29 May 2024 10:43:40 +0800 Subject: [PATCH 6/6] chore: remove inferrable type --- test/test_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_utils.ts b/test/test_utils.ts index cf524c3bd..dbc625b59 100644 --- a/test/test_utils.ts +++ b/test/test_utils.ts @@ -6,7 +6,7 @@ interface KeyEvent { which: number; } -export function getKey(key: KeyType, shiftKey: boolean = false) { +export function getKey(key: KeyType, shiftKey = false) { let event: KeyEvent = null as unknown as KeyEvent; switch (key) { case KeyType.Backspace: