Skip to content

Commit 19afe90

Browse files
authored
feat(ui5-date-picker): keyboard handling improvement (#2146)
the following keyboard handling enhancements are implemented: DatePicker [PAGEDOWN] - Decrements the corresponding day of the month by one [SHIFT] + [PAGEDOWN] - Decrements the corresponding month by one [SHIFT] + [CTRL] + [PAGEDOWN] - Decrements the corresponding year by one [PAGEUP] - Increments the corresponding day of the month by one [SHIFT] + [PAGEUP] - Increments the corresponding month by one [SHIFT] + [CTRL] + [PAGEUP] - Increments the corresponding year by one Calendar [F4] - Shows month picker [SHIFT] + [F4] - Shows year picker Day picker [PAGEUP] - Navigate to the previous month [PAGEDOWN] - Navigate to the next month [SHIFT] + [PAGEUP] - Navigate to the previous year [SHIFT] + [PAGEDOWN] - Navigate to the next year [CTRL] + [SHIFT] + [PAGEUP] - Navigate ten years backwards [CTRL] + [SHIFT] + [PAGEDOWN] - Navigate ten years forwards Month picker [PAGEUP] - Navigate to the previous month [PAGEDOWN] - Navigate to the next month Year picker [PAGEUP] - Navigate to the previous year range [PAGEDOWN] - Navigate the next year range Related to: #1534
1 parent 4128216 commit 19afe90

File tree

13 files changed

+843
-163
lines changed

13 files changed

+843
-163
lines changed

packages/base/src/Keys.js

+9
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ const isHome = event => (event.key ? event.key === "Home" : event.keyCode === Ke
119119

120120
const isEnd = event => (event.key ? event.key === "End" : event.keyCode === KeyCodes.END) && !hasModifierKeys(event);
121121

122+
const isHomeCtrl = event => (event.key ? event.key === "Home" : event.keyCode === KeyCodes.HOME) && checkModifierKeys(event, true, false, false);
123+
124+
const isEndCtrl = event => (event.key ? event.key === "End" : event.keyCode === KeyCodes.END) && checkModifierKeys(event, true, false, false);
125+
122126
const isEscape = event => (event.key ? event.key === "Escape" || event.key === "Esc" : event.keyCode === KeyCodes.ESCAPE) && !hasModifierKeys(event);
123127

124128
const isTabNext = event => (event.key ? event.key === "Tab" : event.keyCode === KeyCodes.TAB) && !hasModifierKeys(event);
@@ -153,6 +157,8 @@ const isF4 = event => {
153157
return event.key === "F4" && !hasModifierKeys(event);
154158
};
155159

160+
const isF4Shift = event => (event.key ? event.key === "F4" : event.keyCode === KeyCodes.F4) && checkModifierKeys(event, false, false, true);
161+
156162
const isShowByArrows = event => {
157163
return ((event.key === "ArrowDown" || event.key === "Down") || (event.key === "ArrowUp" || event.key === "Up")) && checkModifierKeys(event, /* Ctrl */ false, /* Alt */ true, /* Shift */ false);
158164
};
@@ -172,13 +178,16 @@ export {
172178
isDown,
173179
isHome,
174180
isEnd,
181+
isHomeCtrl,
182+
isEndCtrl,
175183
isEscape,
176184
isTabNext,
177185
isTabPrevious,
178186
isBackSpace,
179187
isDelete,
180188
isShow,
181189
isF4,
190+
isF4Shift,
182191
isPageUp,
183192
isPageDown,
184193
isPageUpShift,

packages/base/src/delegate/ItemNavigation.js

+45-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
isRight,
77
isHome,
88
isEnd,
9+
isPageUp,
10+
isPageDown,
911
} from "../Keys.js";
1012

1113
import EventProvider from "../EventProvider.js";
@@ -52,9 +54,9 @@ class ItemNavigation extends EventProvider {
5254

5355
async _onKeyPress(event) {
5456
if (this.currentIndex >= this._getItems().length) {
55-
this.onOverflowBottomEdge();
57+
this.onOverflowBottomEdge(event);
5658
} else if (this.currentIndex < 0) {
57-
this.onOverflowTopEdge();
59+
this.onOverflowTopEdge(event);
5860
}
5961

6062
event.preventDefault();
@@ -63,6 +65,7 @@ class ItemNavigation extends EventProvider {
6365

6466
this.update();
6567
this.focusCurrent();
68+
this.fireEvent(ItemNavigation.AFTER_FOCUS);
6669
}
6770

6871
onkeydown(event) {
@@ -89,6 +92,14 @@ class ItemNavigation extends EventProvider {
8992
if (isEnd(event)) {
9093
return this._handleEnd(event);
9194
}
95+
96+
if (isPageUp(event)) {
97+
return this._handlePageUp(event);
98+
}
99+
100+
if (isPageDown(event)) {
101+
return this._handlePageDown(event);
102+
}
92103
}
93104

94105
_handleUp(event) {
@@ -135,6 +146,20 @@ class ItemNavigation extends EventProvider {
135146
}
136147
}
137148

149+
_handlePageUp(event) {
150+
if (this._canNavigate()) {
151+
this.currentIndex -= this.pageSize;
152+
this._onKeyPress(event);
153+
}
154+
}
155+
156+
_handlePageDown(event) {
157+
if (this._canNavigate()) {
158+
this.currentIndex += this.pageSize;
159+
this._onKeyPress(event);
160+
}
161+
}
162+
138163
update(current) {
139164
const origItems = this._getItems();
140165

@@ -217,9 +242,9 @@ class ItemNavigation extends EventProvider {
217242
this.currentIndex = val;
218243
}
219244

220-
onOverflowBottomEdge() {
245+
onOverflowBottomEdge(event) {
221246
const items = this._getItems();
222-
const offset = this.currentIndex - items.length;
247+
const offset = (this.currentIndex - items.length) % this.rowSize;
223248

224249
if (this.behavior === ItemNavigationBehavior.Cyclic) {
225250
this.currentIndex = 0;
@@ -232,12 +257,18 @@ class ItemNavigation extends EventProvider {
232257
this.currentIndex = items.length - 1;
233258
}
234259

235-
this.fireEvent(ItemNavigation.BORDER_REACH, { start: false, end: true, offset });
260+
this.fireEvent(ItemNavigation.BORDER_REACH, {
261+
start: false,
262+
end: true,
263+
originalEvent: event,
264+
offset,
265+
});
236266
}
237267

238-
onOverflowTopEdge() {
268+
onOverflowTopEdge(event) {
239269
const items = this._getItems();
240-
const offset = this.currentIndex + this.rowSize;
270+
const offsetRight = (this.currentIndex + this.rowSize) % this.rowSize;
271+
const offset = offsetRight < 0 ? (this.rowSize + offsetRight) : offsetRight;
241272

242273
if (this.behavior === ItemNavigationBehavior.Cyclic) {
243274
this.currentIndex = items.length - 1;
@@ -250,7 +281,12 @@ class ItemNavigation extends EventProvider {
250281
this.currentIndex = 0;
251282
}
252283

253-
this.fireEvent(ItemNavigation.BORDER_REACH, { start: true, end: false, offset });
284+
this.fireEvent(ItemNavigation.BORDER_REACH, {
285+
start: true,
286+
end: false,
287+
originalEvent: event,
288+
offset,
289+
});
254290
}
255291

256292
_handleNextPage() {
@@ -278,5 +314,6 @@ class ItemNavigation extends EventProvider {
278314
ItemNavigation.PAGE_TOP = "PageTop";
279315
ItemNavigation.PAGE_BOTTOM = "PageBottom";
280316
ItemNavigation.BORDER_REACH = "_borderReach";
317+
ItemNavigation.AFTER_FOCUS = "_afterFocus";
281318

282319
export default ItemNavigation;

packages/localization/src/dates/CalendarDate.js

+22-2
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,29 @@ class CalendarDate {
6464
return this._oUDate.getUTCMonth();
6565
}
6666

67-
setMonth(month) {
67+
/**
68+
* Sets the given month as ordinal month of the year.
69+
* @param {int} month An integer between 0 and 11, representing the months January through December( or their
70+
* equivalent month names for the given calendar).
71+
* If the specified value is is outside of the expected range, this method attempts to update the date information
72+
* accordingly. For example, if 12 is given as a month, the year will be incremented by 1, and 1 will be used for month.
73+
* @param {int} [date] An integer between 1 and 31, representing the day of the month, but other values are allowed.
74+
* 0 will result in the previous month's last day.
75+
* -1 will result in the day before the previous month's last day.
76+
* 32 will result in:
77+
* - first day of the next month if the current month has 31 days.
78+
* - second day of the next month if the current month has 30 days.
79+
* Other value will result in adding or subtracting days according to the given value.
80+
* @returns {sap.ui.unified.calendar.CalendarDate} <code>this</code> for method chaining.
81+
*/
82+
setMonth(month, date) {
6883
checkNumericLike(month, `Invalid month: ${month}`);
69-
this._oUDate.setUTCMonth(month);
84+
if (date || date === 0) {
85+
checkNumericLike(date, `Invalid date: ${date}`);
86+
this._oUDate.setUTCMonth(month, date);
87+
} else {
88+
this._oUDate.setUTCMonth(month);
89+
}
7090
return this;
7191
}
7292

packages/main/src/Calendar.hbs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
<div class="{{classes.main}}" style="{{styles.main}}">
1+
<div
2+
class="{{classes.main}}"
3+
style="{{styles.main}} "
4+
@keydown={{_onkeydown}}
5+
>
26

37
<ui5-calendar-header
48
id="{{_id}}-head"
@@ -39,6 +43,7 @@
3943
.maxDate="{{_oMonth.maxDate}}"
4044
timestamp="{{_monthPicker.timestamp}}"
4145
@ui5-change="{{_monthPicker.onSelectedMonthChange}}"
46+
@ui5-navigate="{{_monthPicker.onNavigate}}"
4247
></ui5-monthpicker>
4348

4449
<ui5-yearpicker
@@ -52,6 +57,7 @@
5257
timestamp="{{_yearPicker.timestamp}}"
5358
._selectedYear="{{_yearPicker._selectedYear}}"
5459
@ui5-change="{{_yearPicker.onSelectedYearChange}}"
60+
@ui5-navigate="{{_yearPicker.onNavigate}}"
5561
></ui5-yearpicker>
5662
</div>
5763
</div>

0 commit comments

Comments
 (0)