Listless/Helpers/KeyboardNavigationModifier.swift (1603B)
1import SwiftUI
2
3struct ShortcutKey: Hashable {
4 let key: KeyEquivalent
5 let modifiers: EventModifiers
6
7 init(key: KeyEquivalent, modifiers: EventModifiers = []) {
8 self.key = key
9 self.modifiers = modifiers
10 }
11
12 static func == (lhs: ShortcutKey, rhs: ShortcutKey) -> Bool {
13 lhs.key == rhs.key && lhs.modifiers == rhs.modifiers
14 }
15
16 func hash(into hasher: inout Hasher) {
17 hasher.combine(key)
18 hasher.combine(modifiers.rawValue)
19 }
20}
21
22extension View {
23 func keyboardNavigation(_ bindings: [ShortcutKey: () -> KeyPress.Result]) -> some View {
24 self.onKeyPress { press in
25 let key = normalizeKey(press)
26 let modifiers = normalizeModifiers(press.modifiers)
27 let shortcut = ShortcutKey(key: key, modifiers: modifiers)
28
29 if let action = bindings[shortcut] {
30 return action()
31 }
32 return .ignored
33 }
34 }
35
36 private func normalizeKey(_ press: KeyPress) -> KeyEquivalent {
37
38 if press.characters == "\u{7F}" {
39 return .delete
40 }
41 return press.key
42 }
43
44 private func normalizeModifiers(_ modifiers: EventModifiers) -> EventModifiers {
45
46
47 let shortcutModifierMask: EventModifiers = [.command, .shift, .option, .control]
48 return EventModifiers(rawValue: modifiers.rawValue & shortcutModifierMask.rawValue)
49 }
50}