-
Notifications
You must be signed in to change notification settings - Fork 0
/
Keyboard.tsx
72 lines (64 loc) · 1.93 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
import React, { MouseEvent, ChangeEvent } from "react";
import { useReducerState } from "../../context/context";
interface KeyboardProps {}
export const Keyboard: React.FC<KeyboardProps> = ({}) => {
const { state, dispatch } = useReducerState();
const onClick = (event: MouseEvent<HTMLButtonElement>) => {
state.activeElement?.focus();
var setValue = Object?.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
"value"
)?.set;
setValue?.call(state.activeElement, event.currentTarget.getAttribute("data-key"));
state.activeElement?.dispatchEvent(new Event("change", { bubbles: true }));
};
const keys = ["qwertyuiop", "asdfghjkl", "zxcvbnm"];
const rows = [];
for (const str of keys) {
rows.push(
<div className="row" key={"keywrap-" + str}>
{str.split("").map((character) => (
<KeyboardButton
key={"key-" + character}
strikeCount={state.strike.filter((e) => e === character).length}
isBalled={state.ball.has(character)}
character={character}
clickFunc={onClick}
/>
))}
</div>
);
}
return <div className="keyboard_wrap">{rows}</div>;
};
interface KeyboardButtonProps {
strikeCount: number;
isBalled: boolean;
character: string;
clickFunc: (event: MouseEvent<HTMLButtonElement>) => void;
}
export const KeyboardButton: React.FC<KeyboardButtonProps> = ({
strikeCount,
isBalled,
character,
clickFunc,
}) => {
return (
<span>
<button
className={isBalled ? "isBalled" : ""}
onClick={clickFunc}
data-key={character}
>
{character}
</button>
<KeyStrikeCount strikeCount={strikeCount} />
</span>
);
};
interface KeyStrikeCountProps {
strikeCount: number;
}
const KeyStrikeCount: React.FC<KeyStrikeCountProps> = ({ strikeCount }) => {
return <span className={strikeCount > 0 ? "active" : ""}>{strikeCount}</span>;
};