From 0988ff3ebfcdef150ec75d0749c376d1a66b4544 Mon Sep 17 00:00:00 2001 From: Boyan Rakilovski Date: Mon, 7 Dec 2020 02:24:08 +0200 Subject: [PATCH] fix(ui5-datepicker): keyboard navigation works properly 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 4e94d6ecf3be..cf011e5744ab 100644 --- a/packages/main/src/Calendar.js +++ b/packages/main/src/Calendar.js @@ -623,9 +623,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 43169167ab6f..51e5f47d12e4 100644 --- a/packages/main/src/DayPicker.js +++ b/packages/main/src/DayPicker.js @@ -568,7 +568,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(); @@ -660,7 +660,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); } @@ -676,7 +676,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) { @@ -841,7 +844,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 29180c7653ea..8abc3ec96fea 100644 --- a/packages/main/src/MonthPicker.js +++ b/packages/main/src/MonthPicker.js @@ -240,7 +240,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 a01efa790cdb..e1421799da5d 100644 --- a/packages/main/src/YearPicker.js +++ b/packages/main/src/YearPicker.js @@ -265,7 +265,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 366690641b7f..8b9c8d6f21a5 100644 --- a/packages/main/test/specs/DatePicker.spec.js +++ b/packages/main/test/specs/DatePicker.spec.js @@ -909,4 +909,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"); + }); });