UNPKG

react-typing-test

Version:

A react component typing test, user input and wpm calculations.

96 lines (95 loc) 5.08 kB
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import React, { useState, useRef, useCallback, useMemo, useEffect, } from "react"; import { getRandomWordList, } from "./util/wordListGenerator"; import { BottomBar, ColoredSpan, GlobalStyle } from "./components/style"; import { StyledThemeProvider } from "./themes/ThemeProvider"; import { RedoButton } from "./components/RedoButton"; import { MainContainer } from "./components/MainContainer"; import { Input } from "./components/Input"; import { Word } from "./components/Word"; export var TypingTest = function (_a) { var _b = _a.wordLimit, wordLimit = _b === void 0 ? 50 : _b, _c = _a.language, language = _c === void 0 ? "english" : _c, _d = _a.theme, theme = _d === void 0 ? "Purpleish" : _d, onSetWPM = _a.onSetWPM, customWordList = _a.customWordList, customTheme = _a.customTheme; var inputRef = useRef(null); var _e = useState(""), currentWord = _e[0], setCurrentWord = _e[1]; var _f = useState(0), wordIndex = _f[0], setWordIndex = _f[1]; var _g = useState(null), startTime = _g[0], setStartTime = _g[1]; console.log(customWordList); var _h = useState(getRandomWordList({ wordLimit: wordLimit, language: language, customList: customWordList })), wordsToType = _h[0], setWordsToType = _h[1]; var _j = useState(0), wpm = _j[0], setWpm = _j[1]; var _k = useState(false), hasError = _k[0], setHasError = _k[1]; var _l = useState([]), typedWords = _l[0], setTypedWords = _l[1]; var targetWord = useMemo(function () { return wordsToType[wordIndex]; }, [wordsToType, wordIndex]); var handleOnChange = function (e) { var value = e.target.value; var len = value.length; if (!startTime) { setStartTime(new Date()); } if (value.charAt(len - 1) === " " || (targetWord === wordsToType[wordsToType.length - 1] && len === targetWord.length && value.charAt(len - 1) === targetWord.charAt(len - 1) && typedWords.length === wordsToType.length - 1)) { var nextTypedWords_1 = __spreadArray(__spreadArray([], typedWords, true), [value.replace(" ", "")], false); if (wordIndex + 1 === wordsToType.length) { var endTime = Date.now(); var timeDiffInMinutes = (endTime - startTime.getTime()) / 60000; var correctChars_1 = 0; wordsToType.forEach(function (word, i) { if (nextTypedWords_1[i]) { nextTypedWords_1[i].split("").forEach(function (ntw, j) { if (word[j] === ntw) { correctChars_1 += 1; } }); } }); setWpm(Math.floor(correctChars_1 / 5 / timeDiffInMinutes)); } setCurrentWord(""); setTypedWords(nextTypedWords_1); setWordIndex(wordIndex + 1); } else { setCurrentWord(value); } if (value.charAt(len - 1) !== " ") { setHasError(value.charAt(len - 1) !== targetWord.charAt(len - 1)); } }; useEffect(function () { if (onSetWPM) { onSetWPM(wpm); } }, [wpm, onSetWPM]); var reset = useCallback(function () { var _a; setWordIndex(0); setTypedWords([]); setStartTime(null); setWpm(0); setCurrentWord(""); setWordsToType(getRandomWordList({ wordLimit: wordLimit, language: language, customList: customWordList })); (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, [inputRef]); return (React.createElement(StyledThemeProvider, { themeName: theme, customTheme: customTheme }, React.createElement(MainContainer, null, React.createElement(GlobalStyle, null), React.createElement("div", null, wordsToType.map(function (randWord, i) { return (React.createElement(Word, { word: randWord, wordIndex: wordIndex, index: i, targetWord: targetWord, currentWord: currentWord, typedWords: typedWords })); })), React.createElement(BottomBar, null, React.createElement(Input, { ref: inputRef, type: "text", spellCheck: "false", value: currentWord, onChange: handleOnChange, autoComplete: "off", hasError: hasError, autoFocus: true }), React.createElement(RedoButton, { onClick: reset }, "Redo")), React.createElement(ColoredSpan, null, "WPM: ", wpm, " ")))); }; export default TypingTest;