All files / src/components/Modal Tutorial.jsx

92.85% Statements 39/42
100% Branches 12/12
84.21% Functions 16/19
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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          16x 16x 16x 16x 16x 16x 16x 16x 5x   16x 32x 4x     16x 16x 16x 16x 5x   16x     16x 16x 16x 15x 10x   5x     16x       16x 16x 16x 16x   16x          
import "./Tutorial.css"
import {useEffect, useState} from "react";
import ReactDom from "react-dom";
 
export default function Tutorial({classNames, audioSourceFolder}) {
    classNames = ["placeholder", ...classNames];
    const [step, setStep] = useState(0);
    const nextStep = () => setStep((prev) => prev + 1);
    const previousStep = () => setStep((prev) => prev - 1);
    const exit = () => setStep(classNames.length);
    useEffect(() => {
        const addHighlight = (className) => {
            Array.from(document.getElementsByClassName(className))
                .forEach(el => el.classList.add('highlighted'));
        };
        const removeHighlight = () => {
            document.querySelectorAll('.highlighted')
                .forEach(el => el.classList.remove('highlighted'));
        };
 
        removeHighlight();
        const className = classNames[step];
        addHighlight(className);
        if (step !== 0 && step < classNames.length) {
            new Audio(`${audioSourceFolder}/${classNames[step]}.mp3`)?.play();
        }
        return removeHighlight;
    }, [audioSourceFolder, classNames, step]);
 
    const HelpButton = () => <button className="help" onClick={() => setStep(0)}>?</button>;
    const NextStepButton = () => <button onClick={nextStep}>{step === classNames.length - 1 ? '✓' : '→'}</button>
    const PreviousStepButton = () => {
        if (step === 0) {
            return <button onClick={exit}>✕</button>
        } else {
            return <button onClick={previousStep}>←</button>
        }
    }
    const Controls = () => <span className="controls">
        {<PreviousStepButton/>}
        {<NextStepButton/>}
    </span>
    const Overlay = ({children}) => <div className="modal-overlay">{children}</div>
    const portal = document.getElementById("portal-game");
    const Banner = () => <div className="banner">How to Play</div>;
    const TutorialModal = () => ReactDom.createPortal(<Overlay><Controls/>{step === 0 && <Banner/>}</Overlay>, portal)
 
    return <>
        <HelpButton/>
        {step < classNames.length && <TutorialModal/>}
    </>
}