diff --git a/example/src/GameOverlay.tsx b/example/src/GameOverlay.tsx
deleted file mode 100755
index d9d8c59..0000000
--- a/example/src/GameOverlay.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import type { GameStatus } from "@vimazing/vim-maze";
-import type { UseScoreType } from "@vimazing/vim-maze";
-import { useIsMobile } from "./useIsMobile";
-import { MobileGameOverlay } from "./MobileGameOverlay";
-
-type GameOverlayProps = {
- gameStatus: GameStatus;
- scoreManager: UseScoreType;
-};
-
-export const GameOverlay = ({ gameStatus, scoreManager }: GameOverlayProps) => {
- const isMobile = useIsMobile();
- if (isMobile) return
-
- // 🧠Only show overlay when the game has ended
- if (['started', 'hasKey'].includes(gameStatus)) return null;
- // console.log('gameStatus:', gameStatus)
-
- return (
-
- {gameStatus === "waiting" && }
- {gameStatus === "game-over" && }
- {gameStatus === "game-won" && }
-
- );
-};
-
-export const GameWaitingContent = () => {
- return (
-
-
-
Press i to play...
-
h,j,k,l to move around
-
try other vim motions
you're familiar with
-
- $,^,0,G,gg only valid if
- the edges are reachable
-
-
-
- );
-};
-
-export const GameWonContent = ({ scoreManager }: { scoreManager: UseScoreType }) => {
- const finalScore = scoreManager.finalScore ?? 0;
-
- return (
-
-
Congratulations!
-
Final Score:
-
{finalScore.toLocaleString()}
-
- min
- (
- 100000
- , (
- optimalTime
- /
- actualTime
- ) *
- 100000
- )
-
-
Press i to play again
-
- );
-};
-
-export const GameOverContent = () => {
- return (
-
-
Game Over
-
Press i to play again
-
- );
-};
-
-export const GameOverlayContainer = ({
- children,
-}: {
- children: React.ReactNode;
-}) => {
- return (
-
- {children}
-
- );
-};
-
-
-
diff --git a/example/src/MobileGameOverlay.tsx b/example/src/MobileGameOverlay.tsx
deleted file mode 100755
index f804e3f..0000000
--- a/example/src/MobileGameOverlay.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import type { GameStatus } from "@vimazing/vim-maze";
-import type { UseScoreType } from "@vimazing/vim-maze";
-
-type MobileGameOverlayProps = {
- gameStatus: GameStatus;
- scoreManager: UseScoreType;
-};
-
-export const MobileGameOverlay = ({ gameStatus, scoreManager }: MobileGameOverlayProps) => {
- // 🧠Only show overlay when the game has ended
- if (['started', 'hasKey'].includes(gameStatus)) return null;
- // console.log('gameStatus:', gameStatus)
-
- return (
-
- {gameStatus === "waiting" && }
- {gameStatus === "game-over" && }
- {gameStatus === "game-won" && }
-
- );
-};
-
-export const GameWaitingContent = () => {
- return (
-
-
-
Press here to play
-
all the vim motions
available on desktop
-
-
- );
-};
-
-export const GameWonContent = ({ scoreManager }: { scoreManager: UseScoreType }) => {
- const finalScore = scoreManager.finalScore ?? 0;
-
- return (
-
-
Congratulations!
-
Final Score:
-
{finalScore.toLocaleString()}
-
- min
- (
- 100000
- , (
- optimalTime
- /
- actualTime
- ) *
- 100000
- )
-
-
Press to play again
-
- );
-};
-
-export const GameOverContent = () => {
- return (
-
- Game Over
-
- );
-};
-
-export const GameOverlayContainer = ({
- children,
-}: {
- children: React.ReactNode;
-}) => {
- return (
-
- {children}
-
- );
-};
-
-
diff --git a/example/src/testStateMachines.ts b/example/src/testStateMachines.ts
deleted file mode 100644
index 7edbd77..0000000
--- a/example/src/testStateMachines.ts
+++ /dev/null
@@ -1,167 +0,0 @@
-import type { GameMode } from '@vimazing/typing-chud';
-
-export type ModeTransition = {
- fromMode: GameMode;
- threshold: number;
- targetMode: GameMode;
- description: string;
-};
-
-export type ScoreTransition = {
- scoreThreshold: number;
- targetMode: GameMode;
- description: string;
-};
-
-export type TestScenario = {
- id: string;
- name: string;
- description: string;
- initialMode: GameMode;
- transitions?: ModeTransition[];
- scoreTransitions?: ScoreTransition[];
-};
-
-export const testScenarios: Record = {
- scoreBasedProgression: {
- id: 'scoreBasedProgression',
- name: 'Score-Based Progression',
- description: 'Change modes based on score: score 10 → words, score 50 → sentences, score 100 → paragraphs. Tests delayed application until current item completes.',
- initialMode: 'letters',
- scoreTransitions: [
- {
- scoreThreshold: 10,
- targetMode: 'words',
- description: 'At score 10, request switch to words',
- },
- {
- scoreThreshold: 50,
- targetMode: 'sentences',
- description: 'At score 50, request switch to sentences',
- },
- {
- scoreThreshold: 100,
- targetMode: 'paragraphs',
- description: 'At score 100, request switch to paragraphs',
- },
- ],
- },
-
- progressive: {
- id: 'progressive',
- name: 'Progressive Mode Ladder',
- description: 'Automatically progress through all modes: 10 letters → 10 words → 5 sentences → 3 paragraphs',
- initialMode: 'letters',
- transitions: [
- {
- fromMode: 'letters',
- threshold: 10,
- targetMode: 'words',
- description: 'After 10 letters, switch to words',
- },
- {
- fromMode: 'words',
- threshold: 10,
- targetMode: 'sentences',
- description: 'After 10 words, switch to sentences',
- },
- {
- fromMode: 'sentences',
- threshold: 5,
- targetMode: 'paragraphs',
- description: 'After 5 sentences, switch to paragraphs',
- },
- ],
- },
-
- lettersOnly: {
- id: 'lettersOnly',
- name: 'Letters Only',
- description: 'Stay in letters mode (baseline)',
- initialMode: 'letters',
- transitions: [],
- },
-
- wordsOnly: {
- id: 'wordsOnly',
- name: 'Words Only',
- description: 'Start in words mode (baseline)',
- initialMode: 'words',
- transitions: [],
- },
-
- sentencesOnly: {
- id: 'sentencesOnly',
- name: 'Sentences Only',
- description: 'Start in sentences mode (baseline)',
- initialMode: 'sentences',
- transitions: [],
- },
-
- paragraphsOnly: {
- id: 'paragraphsOnly',
- name: 'Paragraphs Only',
- description: 'Start in paragraphs mode (baseline)',
- initialMode: 'paragraphs',
- transitions: [],
- },
-
- rapidTransitions: {
- id: 'rapidTransitions',
- name: 'Rapid Transitions',
- description: 'Quick transitions: 3 letters → 3 words → 2 sentences → 1 paragraph',
- initialMode: 'letters',
- transitions: [
- {
- fromMode: 'letters',
- threshold: 3,
- targetMode: 'words',
- description: 'After 3 letters, switch to words',
- },
- {
- fromMode: 'words',
- threshold: 3,
- targetMode: 'sentences',
- description: 'After 3 words, switch to sentences',
- },
- {
- fromMode: 'sentences',
- threshold: 2,
- targetMode: 'paragraphs',
- description: 'After 2 sentences, switch to paragraphs',
- },
- ],
- },
-
- backAndForth: {
- id: 'backAndForth',
- name: 'Back and Forth',
- description: 'Oscillate between modes: 5 letters ↔ 5 words ↔ 5 letters',
- initialMode: 'letters',
- transitions: [
- {
- fromMode: 'letters',
- threshold: 5,
- targetMode: 'words',
- description: 'After 5 letters, switch to words',
- },
- {
- fromMode: 'words',
- threshold: 5,
- targetMode: 'letters',
- description: 'After 5 words, switch back to letters',
- },
- ],
- },
-};
-
-export function getScenario(id: string): TestScenario {
- return testScenarios[id] || testScenarios.progressive;
-}
-
-export function getScenarioNames(): { id: string; name: string }[] {
- return Object.entries(testScenarios).map(([id, scenario]) => ({
- id,
- name: scenario.name,
- }));
-}
diff --git a/example/src/useIsMobile.ts b/example/src/useIsMobile.ts
deleted file mode 100755
index 6b77170..0000000
--- a/example/src/useIsMobile.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as React from "react";
-
-const MOBILE_BREAKPOINT = 768;
-
-export function useIsMobile() {
- const [isMobile, setIsMobile] = React.useState(
- typeof window !== "undefined"
- ? window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`).matches
- : false
- );
-
- React.useEffect(() => {
- const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
-
- const onChange = (event: MediaQueryListEvent) => {
- setIsMobile(event.matches);
- };
-
- // Set initial value
- setIsMobile(mql.matches);
-
- // Add listener
- mql.addEventListener("change", onChange);
-
- // Cleanup
- return () => mql.removeEventListener("change", onChange);
- }, []);
-
- return isMobile;
-}
diff --git a/example/src/useKeyBindings.ts b/example/src/useKeyBindings.ts
deleted file mode 100755
index 641ebf1..0000000
--- a/example/src/useKeyBindings.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { useEffect } from "react";
-import type { GameManager } from "../../src";
-
-export const useKeyBindings = (gameManager: GameManager) => {
- useEffect(() => {
- const handler = (ev: KeyboardEvent) => {
- // start game
- if (ev.code === "Space") {
- ev.preventDefault(); // Prevent button activation
- if (["waiting", "game-over", "game-won"].includes(gameManager.gameStatus)) {
- gameManager.clearKeyLog();
- gameManager.renderBoard();
- if (gameManager.gameStatus === "game-over" || gameManager.gameStatus === "game-won") {
- gameManager.quitGame();
- setTimeout(() => gameManager.startGame(), 0);
- } else {
- gameManager.startGame();
- }
- return;
- }
- }
-
- // ignore other keys while waiting
- if (gameManager.gameStatus === "waiting") return;
-
- // quit
- if (ev.key === "Escape") {
- ev.preventDefault();
- gameManager.quitGame();
- return;
- }
-
- // handle letter and punctuation typing during game
- if (gameManager.gameStatus === "started") {
- if (ev.key.length === 1 && /[a-zA-Z.,!? ]/.test(ev.key)) {
- gameManager.handleTypedLetter(ev.key);
- }
- }
- };
-
- window.addEventListener("keydown", handler);
- return () => window.removeEventListener("keydown", handler);
- }, [gameManager.gameStatus]);
-};
-
diff --git a/example/src/useMounted.ts b/example/src/useMounted.ts
deleted file mode 100755
index 7da354e..0000000
--- a/example/src/useMounted.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { useState, useEffect } from 'react';
-
-export const useMounted = () => {
- const [mounted, setMounted] = useState(false);
-
- useEffect(() => {
- setMounted(true);
- }, []);
-
- return mounted;
-};