diff --git a/packages/main/cypress/specs/Calendar.cy.tsx b/packages/main/cypress/specs/Calendar.cy.tsx index f53b10890dcb..9ed1429585ac 100644 --- a/packages/main/cypress/specs/Calendar.cy.tsx +++ b/packages/main/cypress/specs/Calendar.cy.tsx @@ -1760,6 +1760,36 @@ describe("Day Picker Tests", () => { expect(todayFromTimestamp.getFullYear()).to.equal(actualToday.getFullYear()); }); }); + + it("mousedown + arrow navigation + click keeps focus at navigated cell, selection on clicked cell", () => { + const date = new Date(Date.UTC(2000, 9, 10, 0, 0, 0)); + cy.mount(getDefaultCalendar(date)); + + const day15Timestamp = new Date(Date.UTC(2000, 9, 15, 0, 0, 0)).valueOf() / 1000; + const day12Timestamp = new Date(Date.UTC(2000, 9, 12, 0, 0, 0)).valueOf() / 1000; + + // mousedown on 15th — focus moves to 15th + cy.ui5CalendarGetDay("#calendar1", day15Timestamp.toString()) + .realMouseDown(); + + // press arrow left three times — focus moves to 12th + cy.realPress("ArrowLeft"); + cy.realPress("ArrowLeft"); + cy.realPress("ArrowLeft"); + + cy.ui5CalendarGetDay("#calendar1", day12Timestamp.toString()) + .should("have.focus"); + + // mouseup on 15th — selection goes to 15th, focus stays on 12th + cy.ui5CalendarGetDay("#calendar1", day15Timestamp.toString()) + .realMouseUp(); + + cy.ui5CalendarGetDay("#calendar1", day12Timestamp.toString()) + .should("have.focus"); + + cy.ui5CalendarGetDay("#calendar1", day15Timestamp.toString()) + .should("have.class", "ui5-dp-item--selected"); + }); }); describe("Calendar Global Configuration", () => { diff --git a/packages/main/src/DayPicker.ts b/packages/main/src/DayPicker.ts index 7b813b3223b6..f47dc63d4c6f 100644 --- a/packages/main/src/DayPicker.ts +++ b/packages/main/src/DayPicker.ts @@ -503,9 +503,10 @@ class DayPicker extends CalendarPart implements ICalendarPicker { * Selects/deselects a day. * @param e * @param isShift true if the user did Click+Shift or Enter+Shift (but not Space+Shift) + * @param setTimestamp whether to move focus (timestamp) to the selected day; false for mouse clicks where focus is independent * @private */ - _selectDate(e: Event, isShift: boolean) { + _selectDate(e: Event, isShift: boolean, setTimestamp = true) { let target = e.target as HTMLElement; if (!target.hasAttribute("data-sap-timestamp")) { @@ -518,7 +519,9 @@ class DayPicker extends CalendarPart implements ICalendarPicker { const timestamp = this._getTimestampFromDom(target); - this._safelySetTimestamp(timestamp); + if (setTimestamp) { + this._safelySetTimestamp(timestamp); + } this._updateSecondTimestamp(); this._updateSelectedDates(timestamp, isShift); @@ -597,6 +600,21 @@ class DayPicker extends CalendarPart implements ICalendarPicker { this.selectedDates = this.selectedDates.filter(value => value !== timestamp); } + _onmousedown(e: MouseEvent) { + let target = e.target as HTMLElement; + + if (!target.hasAttribute("data-sap-timestamp")) { + target = target.parentNode as HTMLElement; + } + + if (!this._isDayPressed(target)) { + return; + } + + this._safelySetTimestamp(this._getTimestampFromDom(target)); + this.fireDecoratorEvent("navigate", { timestamp: this.timestamp! }); + } + /** * Called when at least one day is selected and the user presses "Shift". * @param timestamp @@ -714,7 +732,7 @@ class DayPicker extends CalendarPart implements ICalendarPicker { * @private */ _onclick(e: MouseEvent) { - this._selectDate(e, e.shiftKey); + this._selectDate(e, e.shiftKey, false); } /** diff --git a/packages/main/src/DayPickerTemplate.tsx b/packages/main/src/DayPickerTemplate.tsx index 40be6e05d6ad..dcb22972dee1 100644 --- a/packages/main/src/DayPickerTemplate.tsx +++ b/packages/main/src/DayPickerTemplate.tsx @@ -13,6 +13,7 @@ export default function DayPickerTemplate(this: DayPicker) { }} onKeyDown={this._onkeydown} onKeyUp={this._onkeyup} + onMouseDown={this._onmousedown} onClick={this._onclick} onMouseOver={this._onmouseover} >