-
Notifications
You must be signed in to change notification settings - Fork 0
/
Keyboard.tsx
83 lines (77 loc) · 2.08 KB
/
Keyboard.tsx
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
import {useEffect} from 'react';
import {ENTER_TEXT, DELETE_TEXT} from '../../constants/strings';
import {getStatuses} from '../../lib/statuses';
import {localeAwareUpperCase} from '../../lib/words';
import {Key} from './Key';
export type KeyboardProps = {
onChar: (value: string) => void;
onDelete: () => void;
onEnter: () => void;
guesses: string[];
isRevealing?: boolean;
};
export const Keyboard: React.FC<KeyboardProps> = ({
onChar,
onDelete,
onEnter,
guesses,
isRevealing,
}) => {
const charStatuses = getStatuses(guesses);
const onClick = (value: string) => {
if (value === 'ENTER') {
onEnter();
} else if (value === 'DELETE') {
onDelete();
} else {
onChar(value);
}
};
useEffect(() => {
const listener = (e: KeyboardEvent) => {
if (e.code === 'Enter') {
onEnter();
} else if (e.code === 'Backspace') {
onDelete();
} else {
const key = localeAwareUpperCase(e.key);
// TODO: check this test if the range works with non-english letters
if (key.length === 1 && key >= 'A' && key <= 'Z') {
onChar(key);
}
}
};
window.addEventListener('keyup', listener);
return () => {
window.removeEventListener('keyup', listener);
};
}, [onEnter, onDelete, onChar]);
const mapKey = (key: string) => (
<Key
value={key}
key={key}
onClick={onClick}
status={charStatuses[key]}
isRevealing={isRevealing}
/>
);
return (
<div>
<div className='flex justify-center mb-1'>
{['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'].map(mapKey)}
</div>
<div className='flex justify-center mb-1'>
{['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'].map(mapKey)}
</div>
<div className='flex justify-center'>
<Key width={65.4} value='ENTER' onClick={onClick}>
{ENTER_TEXT}
</Key>
{['Z', 'X', 'C', 'V', 'B', 'N', 'M'].map(mapKey)}
<Key width={65.4} value='DELETE' onClick={onClick}>
{DELETE_TEXT}
</Key>
</div>
</div>
);
};