From 8c87f2a321e0e57495ed2e653ad0aebcd9700b55 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 14 Aug 2020 08:08:03 +0300 Subject: [PATCH 1/9] feat(ui5-time-picker): Keyboard handling improvement --- packages/base/src/Keys.js | 18 +++++++++++ packages/main/src/TimePicker.js | 43 +++++++++++++++++++++++++ packages/main/src/TimePickerPopover.hbs | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/packages/base/src/Keys.js b/packages/base/src/Keys.js index 53c8a1b92b3a..30b03a7b9ffe 100644 --- a/packages/base/src/Keys.js +++ b/packages/base/src/Keys.js @@ -129,6 +129,18 @@ const isBackSpace = event => (event.key ? event.key === "Backspace" : event.keyC const isDelete = event => (event.key ? event.key === "Delete" : event.keyCode === KeyCodes.DELETE) && !hasModifierKeys(event); +const isPageUp = event => (event.key ? event.key === "PageUp" : event.keyCode === KeyCodes.PAGE_UP) && !hasModifierKeys(event); + +const isPageDown = event => (event.key ? event.key === "PageDown" : event.keyCode === KeyCodes.PAGE_DOWN) && !hasModifierKeys(event); + +const isPageUpShift = event => (event.key ? event.key === "PageUp" : event.keyCode === KeyCodes.PAGE_UP) && checkModifierKeys(event, false, false, true); + +const isPageDownShift = event => (event.key ? event.key === "PageDown" : event.keyCode === KeyCodes.PAGE_DOWN) && checkModifierKeys(event, false, false, true); + +const isPageUpShiftCtrl = event => (event.key ? event.key === "PageUp" : event.keyCode === KeyCodes.PAGE_UP) && checkModifierKeys(event, true, false, true); + +const isPageDownShiftCtrl = event => (event.key ? event.key === "PageDown" : event.keyCode === KeyCodes.PAGE_DOWN) && checkModifierKeys(event, true, false, true); + const isShow = event => { if (event.key) { return isF4(event) || isShowByArrows(event); @@ -167,4 +179,10 @@ export { isDelete, isShow, isF4, + isPageUp, + isPageDown, + isPageUpShift, + isPageDownShift, + isPageUpShiftCtrl, + isPageDownShiftCtrl }; diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index b24e8440af29..bad5e6be4416 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -14,6 +14,12 @@ import { isTabNext, isTabPrevious, isShow, + isPageUp, + isPageDown, + isPageUpShift, + isPageDownShift, + isPageUpShiftCtrl, + isPageDownShiftCtrl } from "@ui5/webcomponents-base/src/Keys.js"; import "@ui5/webcomponents-icons/dist/icons/time-entry-request.js"; import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; @@ -674,6 +680,43 @@ class TimePicker extends UI5Element { e.preventDefault(); this.togglePicker(); } + + if (isPageUpShiftCtrl(e)) { + e.preventDefault(); + this._incrementValue(true, false, false, true); + } else if (isPageUpShift(e)) { + e.preventDefault(); + this._incrementValue(true, false, true, false); + } else if (isPageUp(e)) { + e.preventDefault(); + this._incrementValue(true, true, false, false); + } + + if (isPageDownShiftCtrl(e)) { + e.preventDefault(); + this._incrementValue(false, false, false, true); + } else if (isPageDownShift(e)) { + e.preventDefault(); + this._incrementValue(false, false, true, false); + } else if (isPageDown(e)) { + e.preventDefault(); + this._incrementValue(false, true, false, false); + } + } + + _incrementValue(increment, hours, minutes, seconds) { + const date = this.dateValue; + const incrementStep = increment ? 1 : -1; + + if (hours) { + date.setHours(date.getHours() + incrementStep); + } else if (minutes) { + date.setMinutes(date.getMinutes() + incrementStep); + } else if (seconds) { + date.setSeconds(date.getSeconds() + incrementStep); + } + + this.setValue(this.formatValue(date)); } _handleWheel(e) { diff --git a/packages/main/src/TimePickerPopover.hbs b/packages/main/src/TimePickerPopover.hbs index 54487cd3fb4b..04043c292940 100644 --- a/packages/main/src/TimePickerPopover.hbs +++ b/packages/main/src/TimePickerPopover.hbs @@ -13,7 +13,7 @@ @keydown="{{_ontimepickerpopoverkeydown}}" @wheel="{{_handleWheel}}" > -
+
{{#if shouldBuildHoursSlider}} Date: Fri, 14 Aug 2020 08:17:30 +0300 Subject: [PATCH 2/9] lint fix --- packages/base/src/Keys.js | 2 +- packages/main/src/TimePicker.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/base/src/Keys.js b/packages/base/src/Keys.js index 30b03a7b9ffe..73810145440d 100644 --- a/packages/base/src/Keys.js +++ b/packages/base/src/Keys.js @@ -184,5 +184,5 @@ export { isPageUpShift, isPageDownShift, isPageUpShiftCtrl, - isPageDownShiftCtrl + isPageDownShiftCtrl, }; diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 42a77fc6d1fe..e0688ea9dc94 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -19,7 +19,7 @@ import { isPageUpShift, isPageDownShift, isPageUpShiftCtrl, - isPageDownShiftCtrl + isPageDownShiftCtrl, } from "@ui5/webcomponents-base/src/Keys.js"; import "@ui5/webcomponents-icons/dist/icons/time-entry-request.js"; import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js"; From ff1730694d2011b14ee3bfec4ad6d9d30607c8fa Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 14 Aug 2020 09:49:45 +0300 Subject: [PATCH 3/9] Added tests --- packages/main/test/specs/TimePicker.spec.js | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/main/test/specs/TimePicker.spec.js b/packages/main/test/specs/TimePicker.spec.js index 92dd07c7b2b9..dd5a219f8d08 100644 --- a/packages/main/test/specs/TimePicker.spec.js +++ b/packages/main/test/specs/TimePicker.spec.js @@ -123,4 +123,52 @@ describe("TimePicker general interaction", () => { // assert assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("valueState"), "None", "The value state is None"); }); + + it("tests input keyboard handling", () => { + const timepicker = browser.$("#timepicker5"); + + // act + timepicker.click(); + timepicker.keys(['Shift', 'PageUp']); + timepicker.keys('Shift'); + + // assert + assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("value"), "12:01:01", "The value of minutes is +1"); + // act + timepicker.click(); + timepicker.keys(['Shift', 'PageDown']); + timepicker.keys('Shift'); + + // assert + assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("value"), "12:00:01", "The value of minutes is -1"); + + // act + timepicker.click(); + timepicker.keys('PageUp'); + + // assert + assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("value"), "01:00:01", "The value of hours is +1"); + // act + timepicker.click(); + timepicker.keys('PageDown'); + + // assert + assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("value"), "12:00:01", "The value of hours is -1"); + + // act + timepicker.click(); + timepicker.keys(['Shift', 'Control', 'PageUp']); + timepicker.keys('Control'); + + // assert + assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("value"), "12:00:02", "The value of seconds is +1"); + // act + timepicker.click(); + timepicker.keys(['Shift', 'Control', 'PageDown']); + timepicker.keys('Shift'); + timepicker.keys('Control'); + + // assert + assert.strictEqual(timepicker.shadow$("ui5-input").getProperty("value"), "12:00:01", "The value of seconds is -1"); + }); }); \ No newline at end of file From 90c16a05c30fe0b0f900a4d1b167ac6e763508f7 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 14 Aug 2020 13:51:52 +0300 Subject: [PATCH 4/9] fixes and change event added --- packages/main/src/TimePicker.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index e0688ea9dc94..0ed86a69fab1 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -708,15 +708,18 @@ class TimePicker extends UI5Element { const date = this.dateValue; const incrementStep = increment ? 1 : -1; - if (hours) { + if (hours && this.shouldBuildHoursSlider) { date.setHours(date.getHours() + incrementStep); - } else if (minutes) { + } else if (minutes && this.shouldBuildMinutesSlider) { date.setMinutes(date.getMinutes() + incrementStep); - } else if (seconds) { + } else if (seconds && this.shouldBuildSecondsSlider) { date.setSeconds(date.getSeconds() + incrementStep); + } else { + return; } this.setValue(this.formatValue(date)); + this.fireEvent("change", { value: this.value, valid: true }); } _handleWheel(e) { From 552e389680bad5e2c594b7bcebb9728fa775b8f8 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Fri, 14 Aug 2020 16:31:35 +0300 Subject: [PATCH 5/9] added unpress function of button in test --- packages/main/test/specs/TimePicker.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/main/test/specs/TimePicker.spec.js b/packages/main/test/specs/TimePicker.spec.js index dd5a219f8d08..c491b6bd39e6 100644 --- a/packages/main/test/specs/TimePicker.spec.js +++ b/packages/main/test/specs/TimePicker.spec.js @@ -158,6 +158,7 @@ describe("TimePicker general interaction", () => { // act timepicker.click(); timepicker.keys(['Shift', 'Control', 'PageUp']); + timepicker.keys('Shift'); timepicker.keys('Control'); // assert From 9a0896e0833ff5bf3e55fe6174f7ffe790a85fd1 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 17 Aug 2020 11:27:56 +0300 Subject: [PATCH 6/9] implementing comments --- packages/main/src/TimePicker.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 0ed86a69fab1..4906c71d12e0 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -653,6 +653,28 @@ class TimePicker extends UI5Element { e.preventDefault(); responsivePopover.querySelector(`.ui5-time-picker-footer`).lastElementChild.focus(); } + + if (isPageDown(e)) { + this._selectLimitCell(e, false); + } else if (isPageUp(e)) { + this._selectLimitCell(e, true); + } + } + + _selectLimitCell (e, isMax) { + e.preventDefault(); + if (e.target === this.hoursSlider) { + const hoursArray = this.hoursArray; + e.target.value = isMax ? hoursArray[hoursArray.length - 1] : hoursArray[0]; + } else if (e.target === this.minutesSlider) { + const minutesArray = this.minutesArray; + e.target.value = isMax ? minutesArray[minutesArray.length - 1] : minutesArray[0]; + } else if (e.target === this.secondsSlider) { + const secondsArray = this.secondsArray; + e.target.value = isMax ? secondsArray[secondsArray.length - 1] : secondsArray[0]; + } else { + return; + } } _onfooterkeydown(e) { @@ -681,6 +703,10 @@ class TimePicker extends UI5Element { this.togglePicker(); } + if (this.isOpen()) { + return; + } + if (isPageUpShiftCtrl(e)) { e.preventDefault(); this._incrementValue(true, false, false, true); From 9f360c33a27efe90406b7afc52a9226af0f0024e Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 17 Aug 2020 11:43:29 +0300 Subject: [PATCH 7/9] lint fixes --- packages/main/src/TimePicker.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 4906c71d12e0..3e2e73fd63d9 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -661,7 +661,7 @@ class TimePicker extends UI5Element { } } - _selectLimitCell (e, isMax) { + _selectLimitCell(e, isMax) { e.preventDefault(); if (e.target === this.hoursSlider) { const hoursArray = this.hoursArray; @@ -672,8 +672,6 @@ class TimePicker extends UI5Element { } else if (e.target === this.secondsSlider) { const secondsArray = this.secondsArray; e.target.value = isMax ? secondsArray[secondsArray.length - 1] : secondsArray[0]; - } else { - return; } } From 372cea32d3f97f168ad491bcf1d701f1b8ec4d8e Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Mon, 17 Aug 2020 17:06:55 +0300 Subject: [PATCH 8/9] added documentation --- packages/main/src/TimePicker.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index 3e2e73fd63d9..bfde404d0f02 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -236,7 +236,23 @@ const metadata = { *

* For example, if the format-pattern is "HH:mm:ss", * a valid value string is "11:42:35" and the same is displayed in the input. - * + * + *

Keyboard handling

+ * [F4], [ALT]+[UP], [ALT]+[DOWN] Open/Close picker dialog and move focus to it. + * When closed: + * [PAGEUP] - Increments hours by 1. If 12 am is reached, increment hours to 1 pm and vice versa. + * [PAGEDOWN] - Decrements the corresponding field by 1. If 1 pm is reached, decrement hours to 12 am and vice versa. + * [SHIFT]+[PAGEUP] Increments minutes by 1. + * [SHIFT]+ [PAGEDOWN] Decrements minutes by 1. + * [SHIFT]+[CTRL]+[PAGEUP] Increments seconds by 1. + * [SHIFT]+[CTRL]+ [PAGEDOWN] Decrements seconds by 1. + * When opened: + * [UP] If focus is on one of the selection lists: Select the value which is above the current value. If the first value is selected, select the last value in the list. Exception: AM/ PM List: stay on the first item. + * [DOWN] If focus is on one of the selection lists: Select the value which is below the current value. If the last value is selected, select the first value in the list. Exception: AM/ PM List: stay on the last item. + * [LEFT] If focus is on one of the selection lists: Move focus to the selection list which is left of the current selection list. If focus is at the first selection list, move focus to the last selection list. + * [RIGHT] If focus is on one of the selection lists: Move focus to the selection list which is right of the current selection list. When focus is at the last selection list, move focus to the first selection list. + * [PAGEUP] If focus is on one of the selection lists: Move focus to the first entry of this list. + * [PAGEDOWN] If focus is on one of the selection lists: Move focus to the last entry of this list. *

ES6 Module Import

* * import @ui5/webcomponents/dist/TimePicker.js"; From 8d1507f050a6134ec1aace3b8853903fc2ad49e1 Mon Sep 17 00:00:00 2001 From: Tsanislav Gatev Date: Tue, 18 Aug 2020 08:03:23 +0300 Subject: [PATCH 9/9] lint fixes --- packages/main/src/TimePicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/main/src/TimePicker.js b/packages/main/src/TimePicker.js index bfde404d0f02..b46c6ba7076f 100644 --- a/packages/main/src/TimePicker.js +++ b/packages/main/src/TimePicker.js @@ -236,14 +236,14 @@ const metadata = { *

* For example, if the format-pattern is "HH:mm:ss", * a valid value string is "11:42:35" and the same is displayed in the input. - * + * *

Keyboard handling

* [F4], [ALT]+[UP], [ALT]+[DOWN] Open/Close picker dialog and move focus to it. * When closed: * [PAGEUP] - Increments hours by 1. If 12 am is reached, increment hours to 1 pm and vice versa. * [PAGEDOWN] - Decrements the corresponding field by 1. If 1 pm is reached, decrement hours to 12 am and vice versa. * [SHIFT]+[PAGEUP] Increments minutes by 1. - * [SHIFT]+ [PAGEDOWN] Decrements minutes by 1. + * [SHIFT]+ [PAGEDOWN] Decrements minutes by 1. * [SHIFT]+[CTRL]+[PAGEUP] Increments seconds by 1. * [SHIFT]+[CTRL]+ [PAGEDOWN] Decrements seconds by 1. * When opened: