From 66cd1d7b79964aeb8b0bddaf2aa1950990a36494 Mon Sep 17 00:00:00 2001 From: Boyan Rakilovski Date: Wed, 16 Dec 2020 14:40:45 +0200 Subject: [PATCH] fix(ui5-datepicker): keyboard navigation works properly (#2549) Keyboard navigation now works properly, when ui5-datepicker component popover is opened and there are disabled dates in the corresponding ui5-calendar component due to min/max set. --- packages/main/src/Calendar.js | 8 +++++--- packages/main/src/DayPicker.js | 11 +++++++---- packages/main/src/MonthPicker.js | 5 ++++- packages/main/src/YearPicker.js | 5 ++++- packages/main/test/specs/DatePicker.spec.js | 17 +++++++++++++++++ 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/main/src/Calendar.js b/packages/main/src/Calendar.js index 69b89e98e296..ff087a2a2c59 100644 --- a/packages/main/src/Calendar.js +++ b/packages/main/src/Calendar.js @@ -631,9 +631,11 @@ class Calendar extends UI5Element { async _setDayPickerCurrentIndex(calDate, applyFocus) { await RenderScheduler.whenFinished(); - const currentDate = new CalendarDate(calDate); - const currentDateIndex = this.dayPicker._getVisibleDays(currentDate).findIndex(date => date.valueOf() === currentDate.valueOf()); - this.dayPicker._itemNav.currentIndex = currentDateIndex; + const currentDate = new CalendarDate(calDate, this._primaryCalendarType); + const currentIndex = this.dayPicker.focusableDays.findIndex(item => { + return CalendarDate.fromLocalJSDate(new Date(item.timestamp * 1000), this._primaryCalendarType).isSame(currentDate); + }); + this.dayPicker._itemNav.currentIndex = currentIndex; if (applyFocus) { this.dayPicker._itemNav.focusCurrent(); } else { diff --git a/packages/main/src/DayPicker.js b/packages/main/src/DayPicker.js index 77d7e203e4a1..0d608f37f827 100644 --- a/packages/main/src/DayPicker.js +++ b/packages/main/src/DayPicker.js @@ -564,7 +564,7 @@ class DayPicker extends UI5Element { } currentTimestamp = calDate.valueOf() / 1000; - const newItemIndex = this._itemNav._getItems().findIndex(item => parseInt(item.timestamp) === currentTimestamp); + const newItemIndex = this.focusableDays.findIndex(item => parseInt(item.timestamp) === currentTimestamp); this._itemNav.currentIndex = newItemIndex; this._itemNav.focusCurrent(); @@ -656,7 +656,7 @@ class DayPicker extends UI5Element { const focusableDays = []; for (let i = 0; i < this._weeks.length; i++) { - const week = this._weeks[i].slice(1).filter(x => !x.disabled); + const week = this._weeks[i].slice(1).filter(dayItem => !dayItem.disabled); focusableDays.push(week); } @@ -672,7 +672,10 @@ class DayPicker extends UI5Element { } _setCurrentItemTabIndex(index) { - this._itemNav._getCurrentItem().setAttribute("tabindex", index.toString()); + const currentItem = this._itemNav._getCurrentItem(); + if (currentItem) { + currentItem.setAttribute("tabindex", index.toString()); + } } _modifySelectionAndNotifySubscribers(timestamp) { @@ -837,7 +840,7 @@ class DayPicker extends UI5Element { this.fireEvent("navigate", { timestamp }); await RenderScheduler.whenFinished(); - const newItemIndex = this._itemNav._getItems().findIndex(item => parseInt(item.timestamp) === timestamp); + const newItemIndex = this.focusableDays.findIndex(item => parseInt(item.timestamp) === timestamp); this._itemNav.currentIndex = newItemIndex; this._itemNav.focusCurrent(); } diff --git a/packages/main/src/MonthPicker.js b/packages/main/src/MonthPicker.js index 89cc8c503a36..50380b36a859 100644 --- a/packages/main/src/MonthPicker.js +++ b/packages/main/src/MonthPicker.js @@ -237,7 +237,10 @@ class MonthPicker extends UI5Element { } _setCurrentItemTabIndex(index) { - this._itemNav._getCurrentItem().setAttribute("tabindex", index.toString()); + const currentItem = this._itemNav._getCurrentItem(); + if (currentItem) { + currentItem.setAttribute("tabindex", index.toString()); + } } _onmousedown(event) { diff --git a/packages/main/src/YearPicker.js b/packages/main/src/YearPicker.js index e51d2613f4ed..49217295e4b8 100644 --- a/packages/main/src/YearPicker.js +++ b/packages/main/src/YearPicker.js @@ -266,7 +266,10 @@ class YearPicker extends UI5Element { } _setCurrentItemTabIndex(index) { - this._itemNav._getCurrentItem().setAttribute("tabindex", index.toString()); + const currentItem = this._itemNav._getCurrentItem(); + if (currentItem) { + currentItem.setAttribute("tabindex", index.toString()); + } } _onmousedown(event) { diff --git a/packages/main/test/specs/DatePicker.spec.js b/packages/main/test/specs/DatePicker.spec.js index 4940580cce86..55543276a1ba 100644 --- a/packages/main/test/specs/DatePicker.spec.js +++ b/packages/main/test/specs/DatePicker.spec.js @@ -921,4 +921,21 @@ describe("Date Picker Tests", () => { assert.strictEqual(date.getMonth(), 0, "Correct month value"); assert.strictEqual(date.getFullYear(), 2000, "Correct year value"); }); + + it("Keyboard navigation works when there are disabled dates in the calendar grid", () => { + datepicker.id = "#dp33"; + datepicker.innerInput.click(); + browser.keys("Jan 1, 2000"); + + datepicker.valueHelpIcon.click(); + + browser.keys("ArrowDown"); + + assert.ok(datepicker.getDisplayedDay(13).isFocusedDeep(), "Successfully navigated"); + + browser.keys("Escape"); + datepicker.innerInput.click(); + browser.keys(["Control", "A"]); + browser.keys("Backspace"); + }); });