All files / src/components/music/piano PianoKeyboard.tsx

0% Statements 0/20
0% Branches 0/10
0% Functions 0/4
0% Lines 0/18

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 54 55 56 57 58 59 60 61 62 63 64 65                                                                                                                                 
import React from "react";
import { StyledPianoKeyboard, StyledPianoKey } from "./style";
import { MAX_OCTAVE, TOTAL_OCTAVES } from "consts";
 
interface PianoKeyboardProps {
  hoverNote: number | null;
  c5Ref: React.RefObject<HTMLDivElement>;
}
 
const octaves = Array.from({ length: TOTAL_OCTAVES }, (_, i) => MAX_OCTAVE - i);
 
const notes = [
  "B",
  "A#",
  "A",
  "G#",
  "G",
  "F#",
  "F",
  "E",
  "D#",
  "D",
  "C#",
  "C",
] as const;
 
const blackNotes = ["A#", "G#", "F#", "D#", "C#"];
const tallNotes = ["A", "G", "D"];
 
export const PianoKeyboard = ({ hoverNote, c5Ref }: PianoKeyboardProps) => {
  return (
    <StyledPianoKeyboard>
      {octaves.map((octave) => {
        const base = (octave - 3) * 12;
 
        return (
          <React.Fragment key={`pianokey_${octave}`}>
            {notes.map((note, index) => {
              const offset = notes.length - 1 - index;
              const noteNumber = base + offset;
              const isBlack = blackNotes.includes(note);
              const isTall = tallNotes.includes(note);
              const isC = note === "C";
              const isC5 = isC && octave === 5;
 
              return (
                <StyledPianoKey
                  key={`${note}${octave}`}
                  $color={isBlack ? "black" : "white"}
                  $highlight={hoverNote === noteNumber}
                  $tall={isTall || undefined}
                  ref={isC5 ? c5Ref : undefined}
                  title={`${note}${octave}`}
                >
                  {isC ? `C${octave}` : undefined}
                </StyledPianoKey>
              );
            })}
          </React.Fragment>
        );
      })}
    </StyledPianoKeyboard>
  );
};