Skip to content

Commit 238ce34

Browse files
committed
refactor: Unify keydown events
1 parent 9432c7f commit 238ce34

File tree

13 files changed

+145
-65
lines changed

13 files changed

+145
-65
lines changed

src/VueDatePicker/components/ActionRow.vue

+4-7
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@
3636
type="button"
3737
class="dp__action_button dp__action_cancel"
3838
@click="$emit('close-picker')"
39-
@keydown.enter="$emit('close-picker')"
40-
@keydown.space="$emit('close-picker')"
39+
@keydown="checkKeyDown($event, () => $emit('close-picker'))"
4140
>
4241
{{ cancelText }}
4342
</button>
@@ -46,8 +45,7 @@
4645
type="button"
4746
class="dp__action_button dp__action_cancel"
4847
@click="$emit('select-now')"
49-
@keydown.enter="$emit('select-now')"
50-
@keydown.space="$emit('select-now')"
48+
@keydown="checkKeyDown($event, () => $emit('select-now'))"
5149
>
5250
{{ nowButtonLabel }}
5351
</button>
@@ -58,8 +56,7 @@
5856
class="dp__action_button dp__action_select"
5957
:disabled="disabled"
6058
data-test="select-button"
61-
@keydown.enter="selectDate"
62-
@keydown.space="selectDate"
59+
@keydown="checkKeyDown($event, () => selectDate())"
6360
@click="selectDate"
6461
>
6562
{{ selectText }}
@@ -73,7 +70,7 @@
7370
<script lang="ts" setup>
7471
import { computed, onMounted, onUnmounted, ref } from 'vue';
7572
76-
import { convertType, unrefElement } from '@/utils/util';
73+
import { checkKeyDown, convertType, unrefElement } from '@/utils/util';
7774
import { useArrowNavigation, useDefaults, useValidation } from '@/composables';
7875
import { PickerBaseProps } from '@/props';
7976
import { formatDate } from '@/utils/date-utils';

src/VueDatePicker/components/Common/ArrowBtn.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
:aria-label="ariaLabel"
88
:aria-disabled="disabled || undefined"
99
@click="$emit('activate')"
10-
@keydown.enter.prevent="$emit('activate')"
11-
@keydown.space.prevent="$emit('activate')"
10+
@keydown="checkKeyDown($event, () => $emit('activate'), true)"
1211
>
1312
<span class="dp__inner_nav" :class="{ dp__inner_nav_disabled: disabled }">
1413
<slot />
@@ -18,6 +17,7 @@
1817

1918
<script lang="ts" setup>
2019
import { onMounted, ref } from 'vue';
20+
import { checkKeyDown } from '@/utils/util';
2121
2222
defineOptions({
2323
compatConfig: {

src/VueDatePicker/components/Common/SelectionOverlay.vue

+34-10
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@
55
:style="dpOverlayStyle"
66
role="dialog"
77
tabindex="0"
8-
@keydown.esc.prevent="handleEsc"
9-
@keydown.left.prevent="handleArrowKey($event)"
10-
@keydown.up.prevent="handleArrowKey($event)"
11-
@keydown.down.prevent="handleArrowKey($event)"
12-
@keydown.right.prevent="handleArrowKey($event)"
8+
@keydown="onKeyDown"
139
>
1410
<div
1511
ref="containerRef"
@@ -40,8 +36,7 @@
4036
tabindex="0"
4137
:data-test="col.text"
4238
@click="onClick(col)"
43-
@keydown.enter.prevent="onClick(col)"
44-
@keydown.space.prevent="onClick(col)"
39+
@keydown="checkKeyDown($event, () => onClick(col), true)"
4540
@mouseover="setHoverValue(col.value)"
4641
>
4742
<div :class="col.className">
@@ -61,8 +56,7 @@
6156
:class="actionButtonClass"
6257
tabindex="0"
6358
@click="toggle"
64-
@keydown.enter="toggle"
65-
@keydown.tab="onTab"
59+
@keydown="onBtnKeyDown"
6660
>
6761
<slot name="button-icon" />
6862
</button>
@@ -72,11 +66,19 @@
7266
<script lang="ts" setup>
7367
import { computed, nextTick, onBeforeUpdate, onMounted, onUnmounted, ref, watch } from 'vue';
7468
75-
import { checkStopPropagation, convertType, findFocusableEl, getElWithin, unrefElement } from '@/utils/util';
69+
import {
70+
checkKeyDown,
71+
checkStopPropagation,
72+
convertType,
73+
findFocusableEl,
74+
getElWithin,
75+
unrefElement,
76+
} from '@/utils/util';
7677
import { useArrowNavigation, useCommon, useDefaults } from '@/composables';
7778
7879
import type { AriaLabels, Config, DynamicClass, Flow, OverlayGridItem, TextInputProp } from '@/interfaces';
7980
import type { PickerBasePropsType } from '@/props';
81+
import { EventKey } from '@/constants';
8082
8183
const { setSelectionGrid, buildMultiLevelMatrix, setMonthPicker } = useArrowNavigation();
8284
@@ -290,5 +292,27 @@
290292
}
291293
};
292294
295+
const onKeyDown = (ev: KeyboardEvent) => {
296+
switch (ev.key) {
297+
case EventKey.esc:
298+
return handleEsc();
299+
case EventKey.arrowLeft:
300+
return handleArrowKey(ev);
301+
case EventKey.arrowRight:
302+
return handleArrowKey(ev);
303+
case EventKey.arrowUp:
304+
return handleArrowKey(ev);
305+
case EventKey.arrowDown:
306+
return handleArrowKey(ev);
307+
default:
308+
return;
309+
}
310+
};
311+
312+
const onBtnKeyDown = (ev: KeyboardEvent) => {
313+
if (ev.key === EventKey.enter) return toggle();
314+
if (ev.key === EventKey.tab) return onTab();
315+
};
316+
293317
defineExpose({ focusGrid });
294318
</script>

src/VueDatePicker/components/DatePicker/DpCalendar.vue

+2-3
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@
5757
tabindex="0"
5858
:data-test="dayVal.value"
5959
@click.prevent="onDateSelect($event, dayVal)"
60-
@keydown.enter="$emit('select-date', dayVal)"
61-
@keydown.space="$emit('handle-space', dayVal)"
60+
@keydown="checkKeyDown($event, () => $emit('select-date', dayVal))"
6261
@mouseenter="onMouseOver(dayVal, weekInd, dayInd)"
6362
@mouseleave="onMouseLeave(dayVal)"
6463
@mousedown="onMouseDown(dayVal)"
@@ -128,7 +127,7 @@
128127
import { computed, nextTick, onMounted, ref } from 'vue';
129128
import { format, getISOWeek, getWeek } from 'date-fns';
130129
131-
import { checkStopPropagation, getDayNames, getDefaultMarker, unrefElement } from '@/utils/util';
130+
import { checkKeyDown, checkStopPropagation, getDayNames, getDefaultMarker, unrefElement } from '@/utils/util';
132131
import { useArrowNavigation, useDefaults } from '@/composables';
133132
import { PickerBaseProps } from '@/props';
134133
import { getDate, isDateAfter, isDateEqual, resetDateTime, setDateMonthOrYear } from '@/utils/date-utils';

src/VueDatePicker/components/DatePicker/DpHeader.vue

+2-3
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
:aria-label="type.ariaLabel"
3939
:data-test="`${type.type}-toggle-overlay-${instance}`"
4040
@click="type.toggle"
41-
@keydown.enter.prevent="type.toggle"
42-
@keydown.space.prevent="type.toggle"
41+
@keydown="checkKeyDown($event, () => type.toggle(), true)"
4342
>
4443
<slot
4544
v-if="$slots[type.type]"
@@ -139,7 +138,7 @@
139138
getMinMaxYear,
140139
getMinMonth,
141140
} from '@/utils/date-utils';
142-
import { checkMinMaxValue, formatNumber, groupListAndMap, unrefElement } from '@/utils/util';
141+
import { checkKeyDown, checkMinMaxValue, formatNumber, groupListAndMap, unrefElement } from '@/utils/util';
143142
import { FlowStep, HeaderPicker } from '@/constants';
144143
145144
import type { HeaderSelectionBtn, IDefaultSelect, MaybeElementRef, OverlayGridItem } from '@/interfaces';

src/VueDatePicker/components/DatepickerInput.vue

+6-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
:aria-disabled="disabled || undefined"
4141
:aria-invalid="state === false ? true : undefined"
4242
@input="handleInput"
43-
@keydown.enter="handleEnter"
44-
@keydown.tab="handleTab"
4543
@blur="handleBlur"
4644
@focus="handleFocus"
4745
@keypress="handleKeyPress"
@@ -290,6 +288,12 @@
290288
};
291289
292290
const handleKeyPress = (ev: KeyboardEvent): void => {
291+
if (ev.key === 'Tab') {
292+
handleTab(ev);
293+
}
294+
if (ev.key === 'Enter') {
295+
handleEnter(ev);
296+
}
293297
if (!defaultedTextInput.value.enabled) {
294298
if (ev.code === 'Tab') return;
295299
ev.preventDefault();

src/VueDatePicker/components/DatepickerMenu.vue

+39-22
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@
99
:style="{ '--dp-arrow-left': arrowPos }"
1010
@mouseleave="clearHoverDate"
1111
@click="handleDpMenuClick"
12-
@keydown.esc="handleEsc"
13-
@keydown.left.prevent="handleArrowKey('left')"
14-
@keydown.up.prevent="handleArrowKey('up')"
15-
@keydown.down.prevent="handleArrowKey('down')"
16-
@keydown.right.prevent="handleArrowKey('right')"
1712
@keydown="onKeyDown"
1813
>
1914
<div v-if="((disabled || readonly) && defaultedInline.enabled) || loading" :class="disabledReadonlyOverlay">
@@ -55,8 +50,7 @@
5550
:class="{ 'dp--preset-range-collapsed': collapse }"
5651
:data-test="preset.testId ?? undefined"
5752
@click.prevent="presetDate(preset.value, preset.noTz)"
58-
@keydown.enter.prevent="presetDate(preset.value, preset.noTz)"
59-
@keydown.space.prevent="presetDate(preset.value, preset.noTz)"
53+
@keydown="checkKeyDown($event, () => presetDate(preset.value, preset.noTz), true)"
6054
>
6155
{{ preset.label }}
6256
</button>
@@ -127,7 +121,7 @@
127121
import ActionRow from '@/components/ActionRow.vue';
128122
129123
import { mapSlots, useArrowNavigation, useState, useFlow, useDefaults } from '@/composables';
130-
import { checkStopPropagation, unrefElement } from '@/utils/util';
124+
import { checkKeyDown, checkStopPropagation, unrefElement } from '@/utils/util';
131125
import { AllProps } from '@/props';
132126
133127
import MonthPicker from '@/components/MonthPicker/MonthPicker.vue';
@@ -138,6 +132,7 @@
138132
139133
import type { DynamicClass, MenuView, InternalModuleValue, MenuExposedFn, MonthModel } from '@/interfaces';
140134
import type { PropType } from 'vue';
135+
import { ArrowDirection, EventKey } from '@/constants';
141136
142137
defineOptions({
143138
compatConfig: {
@@ -309,22 +304,22 @@
309304
}
310305
};
311306
312-
const handleArrowKey = (arrow: 'up' | 'down' | 'left' | 'right'): void => {
307+
const handleArrowKey = (arrow: ArrowDirection): void => {
313308
if (props.arrowNavigation) {
314-
if (arrow === 'up') return arrowUp();
315-
if (arrow === 'down') return arrowDown();
316-
if (arrow === 'left') return arrowLeft();
317-
if (arrow === 'right') return arrowRight();
318-
} else if (arrow === 'left' || arrow === 'up') {
319-
callChildFn('handleArrow', 'left', 0, arrow === 'up');
309+
if (arrow === ArrowDirection.up) return arrowUp();
310+
if (arrow === ArrowDirection.down) return arrowDown();
311+
if (arrow === ArrowDirection.left) return arrowLeft();
312+
if (arrow === ArrowDirection.right) return arrowRight();
313+
} else if (arrow === ArrowDirection.right || arrow === ArrowDirection.up) {
314+
callChildFn('handleArrow', ArrowDirection.left, 0, arrow === ArrowDirection.up);
320315
} else {
321-
callChildFn('handleArrow', 'right', 0, arrow === 'down');
316+
callChildFn('handleArrow', ArrowDirection.right, 0, arrow === ArrowDirection.down);
322317
}
323318
};
324319
325320
const checkShiftKey = (ev: KeyboardEvent) => {
326321
setShiftKey(ev.shiftKey);
327-
if (!props.disableMonthYearSelect && ev.code === 'Tab') {
322+
if (!props.disableMonthYearSelect && ev.code === EventKey.tab) {
328323
if ((ev.target as HTMLElement).classList.contains('dp__menu') && control.value.shiftKeyInMenu) {
329324
ev.preventDefault();
330325
checkStopPropagation(ev, defaultedConfig.value, true);
@@ -373,16 +368,38 @@
373368
callChildFn('updateMonthYear', instance, value);
374369
};
375370
371+
const onArrowKey = (ev: KeyboardEvent, arrow: ArrowDirection) => {
372+
ev.preventDefault();
373+
handleArrowKey(arrow);
374+
};
375+
376376
const onKeyDown = (ev: KeyboardEvent) => {
377377
checkShiftKey(ev);
378-
if (ev.key === 'Home' || ev.key === 'End') {
379-
return callChildFn('selectWeekDate', ev.key === 'Home');
378+
379+
if (ev.key === EventKey.home || ev.key === EventKey.end) {
380+
return callChildFn('selectWeekDate', ev.key === EventKey.home);
380381
}
381-
if (ev.key === 'PageUp' || ev.key === 'PageDown') {
382+
if (ev.key === EventKey.pageUp || ev.key === EventKey.pageDown) {
382383
if (ev.shiftKey) {
383-
return callChildFn('changeYear', ev.key === 'PageUp');
384+
return callChildFn('changeYear', ev.key === EventKey.pageUp);
384385
}
385-
return callChildFn('changeMonth', ev.key === 'PageUp');
386+
return callChildFn('changeMonth', ev.key === EventKey.pageUp);
387+
}
388+
389+
// ev.preventDefault();
390+
switch (ev.key) {
391+
case EventKey.esc:
392+
return handleEsc();
393+
case EventKey.arrowLeft:
394+
return onArrowKey(ev, ArrowDirection.left);
395+
case EventKey.arrowRight:
396+
return onArrowKey(ev, ArrowDirection.right);
397+
case EventKey.arrowUp:
398+
return onArrowKey(ev, ArrowDirection.up);
399+
case EventKey.arrowDown:
400+
return onArrowKey(ev, ArrowDirection.down);
401+
default:
402+
return;
386403
}
387404
};
388405

src/VueDatePicker/components/TimePicker/TimeInput.vue

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
:data-test="`${timeInput.type}-time-inc-btn-${props.order}`"
1717
:aria-label="defaultedAriaLabels?.incrementValue(timeInput.type)"
1818
tabindex="0"
19-
@keydown.enter.prevent="handleTimeValue(timeInput.type, true, { keyboard: true })"
20-
@keydown.space.prevent="handleTimeValue(timeInput.type, true, { keyboard: true })"
19+
@keydown="
20+
checkKeyDown($event, () => handleTimeValue(timeInput.type, true, { keyboard: true }), true)
21+
"
2122
@click="defaultedConfig.timeArrowHoldThreshold ? undefined : handleTimeValue(timeInput.type, true)"
2223
@mousedown="
2324
defaultedConfig.timeArrowHoldThreshold ? handleTimeValue(timeInput.type, true) : undefined
@@ -47,8 +48,7 @@
4748
:disabled="checkOverlayDisabled(timeInput.type)"
4849
tabindex="0"
4950
:data-test="`${timeInput.type}-toggle-overlay-btn-${props.order}`"
50-
@keydown.enter.prevent="toggleOverlay(timeInput.type)"
51-
@keydown.space.prevent="toggleOverlay(timeInput.type)"
51+
@keydown="checkKeyDown($event, () => toggleOverlay(timeInput.type), true)"
5252
@click="toggleOverlay(timeInput.type)"
5353
>
5454
<slot
@@ -72,8 +72,9 @@
7272
:data-test="`${timeInput.type}-time-dec-btn-${props.order}`"
7373
:aria-label="defaultedAriaLabels?.decrementValue(timeInput.type)"
7474
tabindex="0"
75-
@keydown.enter.prevent="handleTimeValue(timeInput.type, false, { keyboard: true })"
76-
@keydown.space.prevent="handleTimeValue(timeInput.type, false, { keyboard: true })"
75+
@keydown="
76+
checkKeyDown($event, () => handleTimeValue(timeInput.type, false, { keyboard: true }), true)
77+
"
7778
@click="defaultedConfig.timeArrowHoldThreshold ? undefined : handleTimeValue(timeInput.type, false)"
7879
@mousedown="
7980
defaultedConfig.timeArrowHoldThreshold ? handleTimeValue(timeInput.type, false) : undefined
@@ -102,8 +103,7 @@
102103
:aria-label="defaultedAriaLabels?.amPmButton"
103104
tabindex="0"
104105
@click="setAmPm"
105-
@keydown.enter.prevent="setAmPm"
106-
@keydown.space.prevent="setAmPm"
106+
@keydown="checkKeyDown($event, () => setAmPm(), true)"
107107
>
108108
{{ amPm }}
109109
</button>
@@ -152,7 +152,7 @@
152152
153153
import { useTransitions, useArrowNavigation, useDefaults } from '@/composables';
154154
import { PickerBaseProps } from '@/props';
155-
import { groupListAndMap, hoursToAmPmHours } from '@/utils/util';
155+
import { checkKeyDown, groupListAndMap, hoursToAmPmHours } from '@/utils/util';
156156
import { getDate, sanitizeTime } from '@/utils/date-utils';
157157
158158
import type { PropType } from 'vue';

src/VueDatePicker/components/TimePicker/TimePicker.vue

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
:aria-label="defaultedAriaLabels?.openTimePicker"
1010
:tabindex="noOverlayFocus ? undefined : 0"
1111
data-test="open-time-picker-btn"
12-
@keydown.enter="toggleTimePicker(true)"
13-
@keydown.space="toggleTimePicker(true)"
12+
@keydown="checkKeyDown($event, () => toggleTimePicker(true))"
1413
@click="toggleTimePicker(true)"
1514
>
1615
<slot v-if="$slots['clock-icon']" name="clock-icon" />
@@ -88,8 +87,7 @@
8887
:class="toggleButtonClass"
8988
:aria-label="defaultedAriaLabels?.closeTimePicker"
9089
tabindex="0"
91-
@keydown.enter="toggleTimePicker(false)"
92-
@keydown.space="toggleTimePicker(false)"
90+
@keydown="checkKeyDown($event, () => toggleTimePicker(false))"
9391
@click="toggleTimePicker(false)"
9492
>
9593
<slot v-if="$slots['calendar-icon']" name="calendar-icon" />
@@ -107,7 +105,7 @@
107105
import { ClockIcon, CalendarIcon } from '@/components/Icons';
108106
import TimeInput from '@/components/TimePicker/TimeInput.vue';
109107
110-
import { findFocusableEl, isModelAuto, unrefElement } from '@/utils/util';
108+
import { checkKeyDown, findFocusableEl, isModelAuto, unrefElement } from '@/utils/util';
111109
import { mapSlots, useTransitions, useArrowNavigation, useDefaults, useCommon } from '@/composables';
112110
import { PickerBaseProps } from '@/props';
113111

0 commit comments

Comments
 (0)