Skip to content

Commit f7468e1

Browse files
authored
fix(ui5-calendar): next and previous header buttons are triggered by Space and Enter (#13435)
Next and Previous buttons are triggered by pressing Space and Enter buttons.
1 parent d1574a8 commit f7468e1

3 files changed

Lines changed: 85 additions & 3 deletions

File tree

packages/main/cypress/specs/Calendar.cy.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,38 @@ describe("Calendar general interaction", () => {
753753
.should("have.class", "ui5-calheader-arrowbtn-disabled");
754754
});
755755

756+
it("Should navigate when pressing Space/Enter on prev/next buttons", () => {
757+
const date = new Date(Date.UTC(2024, 5, 15, 0, 0, 0)); // June 15, 2024
758+
cy.mount(getDefaultCalendar(date));
759+
760+
// Focus and press Enter on next button
761+
cy.get<Calendar>("#calendar1")
762+
.shadow()
763+
.find("[data-ui5-cal-header-btn-next]")
764+
.focus()
765+
.realPress("Enter");
766+
767+
// Verify navigation to July
768+
cy.get<Calendar>("#calendar1")
769+
.shadow()
770+
.find("[data-ui5-cal-header-btn-month]")
771+
.should("contain.text", "July");
772+
773+
// Focus and press Space on prev button
774+
cy.get<Calendar>("#calendar1")
775+
.shadow()
776+
.find("[data-ui5-cal-header-btn-prev]")
777+
.focus()
778+
.realPress("Space");
779+
780+
// Verify navigation back to June
781+
cy.get<Calendar>("#calendar1")
782+
.shadow()
783+
.find("[data-ui5-cal-header-btn-month]")
784+
.should("contain.text", "June");
785+
});
786+
787+
756788
it("Second month and year are rendered in the header", () => {
757789
cy.mount(<Calendar id="calendar1" primaryCalendarType="Islamic" secondaryCalendarType="Gregorian"></Calendar>);
758790
const timestamp = new Date(Date.UTC(2000, 9, 10, 0, 0, 0)).valueOf() / 1000;

packages/main/src/Calendar.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,7 @@ class Calendar extends CalendarPart {
10821082

10831083
onYearButtonKeyUp(e: KeyboardEvent) {
10841084
if (isSpace(e)) {
1085+
e.preventDefault();
10851086
this.switchToYearPicker();
10861087
this.fireDecoratorEvent("show-year-view");
10871088
}
@@ -1100,12 +1101,13 @@ class Calendar extends CalendarPart {
11001101

11011102
onYearRangeButtonKeyUp(e: KeyboardEvent) {
11021103
if (isSpace(e)) {
1104+
e.preventDefault();
11031105
this.switchToYearRangePicker();
11041106
this.fireDecoratorEvent("show-year-range-view");
11051107
}
11061108
}
11071109

1108-
_handleNavigationButtonKeyDown(e: MouseEvent, isDisabled: boolean, action: () => void) {
1110+
_handleNavigationButtonClick(e: MouseEvent, isDisabled: boolean, action: () => void) {
11091111
if (isDisabled) {
11101112
e.preventDefault();
11111113
return;
@@ -1119,12 +1121,56 @@ class Calendar extends CalendarPart {
11191121
e.preventDefault();
11201122
}
11211123

1124+
_handlePrevNextButtonKeyDown(e: KeyboardEvent, isDisabled: boolean, action: () => void) {
1125+
if (isDisabled) {
1126+
e.preventDefault();
1127+
return;
1128+
}
1129+
1130+
if (isSpace(e)) {
1131+
e.preventDefault();
1132+
}
1133+
1134+
if (isEnter(e)) {
1135+
action();
1136+
e.preventDefault();
1137+
}
1138+
}
1139+
1140+
_handlePrevNextButtonKeyUp(e: KeyboardEvent, isDisabled: boolean, action: () => void) {
1141+
if (isDisabled) {
1142+
e.preventDefault();
1143+
return;
1144+
}
1145+
1146+
if (isSpace(e)) {
1147+
e.preventDefault();
1148+
action();
1149+
}
1150+
}
1151+
11221152
onPrevButtonClick(e: MouseEvent) {
1123-
this._handleNavigationButtonKeyDown(e, this._previousButtonDisabled, () => this.onHeaderPreviousPress());
1153+
this._handleNavigationButtonClick(e, this._previousButtonDisabled, () => this.onHeaderPreviousPress());
11241154
}
11251155

11261156
onNextButtonClick(e: MouseEvent) {
1127-
this._handleNavigationButtonKeyDown(e, this._nextButtonDisabled, () => this.onHeaderNextPress());
1157+
this._handleNavigationButtonClick(e, this._nextButtonDisabled, () => this.onHeaderNextPress());
1158+
}
1159+
1160+
onPrevButtonKeyDown(e: KeyboardEvent) {
1161+
this._handlePrevNextButtonKeyDown(e, this._previousButtonDisabled, () => this.onHeaderPreviousPress());
1162+
}
1163+
1164+
onPrevButtonKeyUp(e: KeyboardEvent) {
1165+
this._handlePrevNextButtonKeyUp(e, this._previousButtonDisabled, () => this.onHeaderPreviousPress());
1166+
}
1167+
1168+
onNextButtonKeyDown(e: KeyboardEvent) {
1169+
this._handlePrevNextButtonKeyDown(e, this._nextButtonDisabled, () => this.onHeaderNextPress());
1170+
}
1171+
1172+
onNextButtonKeyUp(e: KeyboardEvent) {
1173+
this._handlePrevNextButtonKeyUp(e, this._nextButtonDisabled, () => this.onHeaderNextPress());
11281174
}
11291175

11301176
/**

packages/main/src/CalendarHeaderTemplate.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ function renderPrevButton(this: Calendar, isFirst: boolean, isMultiple: boolean)
5656
part="calendar-header-arrow-button"
5757
role="button"
5858
onMouseDown={this.onPrevButtonClick}
59+
onKeyDown={this.onPrevButtonKeyDown}
60+
onKeyUp={this.onPrevButtonKeyUp}
5961
tabindex={this._previousButtonDisabled ? -1 : 0}
6062
title={this.accInfo.tooltipPrevButton}
6163
aria-label={this.accInfo.ariaLabelPrevButton}
@@ -162,6 +164,8 @@ function renderNextButton(this: Calendar, isFirst: boolean, isLast: boolean, isM
162164
part="calendar-header-arrow-button"
163165
role="button"
164166
onMouseDown={this.onNextButtonClick}
167+
onKeyDown={this.onNextButtonKeyDown}
168+
onKeyUp={this.onNextButtonKeyUp}
165169
tabindex={this._nextButtonDisabled ? -1 : 0}
166170
title={this.accInfo.tooltipNextButton}
167171
aria-label={this.accInfo.ariaLabelNextButton}

0 commit comments

Comments
 (0)