-
Notifications
You must be signed in to change notification settings - Fork 252
/
Copy pathkeydown.ts
126 lines (123 loc) Β· 3.3 KB
/
keydown.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import {getUIValue, setUISelection, getValueOrTextContent} from '../../document'
import {
getTabDestination,
hasOwnSelection,
isContentEditable,
isEditable,
isElementType,
} from '../../utils'
import {focusElement} from '../focus'
import {input} from '../input'
import {moveSelection, selectAll, setSelectionRange} from '../selection'
import {walkRadio} from '../radio'
import {BehaviorPlugin} from '.'
import {behavior} from './registry'
behavior.keydown = (event, target, instance) => {
return (
keydownBehavior[event.key]?.(event, target, instance) ??
combinationBehavior(event, target, instance)
)
}
const keydownBehavior: {
[key: string]: BehaviorPlugin<'keydown'> | undefined
} = {
ArrowDown: (event, target, instance) => {
/* istanbul ignore else */
if (isElementType(target, 'input', {type: 'radio'} as const)) {
return () => walkRadio(instance, target, 1)
}
},
ArrowLeft: (event, target, instance) => {
if (isElementType(target, 'input', {type: 'radio'} as const)) {
return () => walkRadio(instance, target, -1)
}
return () => moveSelection(target, -1)
},
ArrowRight: (event, target, instance) => {
if (isElementType(target, 'input', {type: 'radio'} as const)) {
return () => walkRadio(instance, target, 1)
}
return () => moveSelection(target, 1)
},
ArrowUp: (event, target, instance) => {
/* istanbul ignore else */
if (isElementType(target, 'input', {type: 'radio'} as const)) {
return () => walkRadio(instance, target, -1)
}
},
Backspace: (event, target, instance) => {
if (isEditable(target)) {
return () => {
input(instance, target, '', 'deleteContentBackward')
}
}
},
Delete: (event, target, instance) => {
if (isEditable(target)) {
return () => {
input(instance, target, '', 'deleteContentForward')
}
}
},
End: (event, target) => {
if (
isElementType(target, ['input', 'textarea']) ||
isContentEditable(target)
) {
return () => {
const newPos =
getValueOrTextContent(target)?.length ?? /* istanbul ignore next */ 0
setSelectionRange(target, newPos, newPos)
}
}
},
Home: (event, target) => {
if (
isElementType(target, ['input', 'textarea']) ||
isContentEditable(target)
) {
return () => {
setSelectionRange(target, 0, 0)
}
}
},
PageDown: (event, target) => {
if (isElementType(target, ['input'])) {
return () => {
const newPos = getUIValue(target).length
setSelectionRange(target, newPos, newPos)
}
}
},
PageUp: (event, target) => {
if (isElementType(target, ['input'])) {
return () => {
setSelectionRange(target, 0, 0)
}
}
},
Tab: (event, target, instance) => {
return () => {
const dest = getTabDestination(
target,
instance.system.keyboard.modifiers.Shift,
)
focusElement(dest)
if (hasOwnSelection(dest)) {
setUISelection(dest, {
anchorOffset: 0,
focusOffset: dest.value.length,
})
}
}
},
}
const combinationBehavior: BehaviorPlugin<'keydown'> = (
event,
target,
instance,
) => {
if (event.code === 'KeyA' && instance.system.keyboard.modifiers.Control) {
return () => selectAll(target)
}
}