Code — how this page is built

Under the hood

The actual source of the components on this page, read straight from the repo. Copy it, read it, or open it on GitHub.


CalculatorGameview on GitHub ↗

A keypad + keyboard handler that builds an expression string and evaluates it live with math.js. Equals commits the result; no eval is used.

'use client';

import { evaluate } from 'mathjs';
import * as React from 'react';

const KEYS = [
  ['C', '(', ')', '/'],
  ['7', '8', '9', '*'],
  ['4', '5', '6', '-'],
  ['1', '2', '3', '+'],
  ['0', '.', '⌫', '='],
];

export function CalculatorGame() {
  const [expr, setExpr] = React.useState('');
  const [out, setOut] = React.useState('');

  const compute = React.useCallback((e: string) => {
    if (!e.trim()) {
      setOut('');
      return;
    }
    try {
      const r = evaluate(e);
      setOut(typeof r === 'number' || typeof r === 'string' ? String(r) : r?.toString?.() ?? '');
    } catch {
      setOut('…');
    }
  }, []);

  const press = React.useCallback(
    (k: string) => {
      if (k === 'C') {
        setExpr('');
        setOut('');
      } else if (k === '⌫') {
        setExpr((e) => {
          const n = e.slice(0, -1);
          compute(n);
          return n;
        });
      } else if (k === '=') {
        setExpr((e) => {
          try {
            const r = evaluate(e);
            const s = String(r);
            setOut('');
            return s;
          } catch {
            return e;
          }
        });
      } else {
        setExpr((e) => {
          const n = e + k;
          compute(n);
          return n;
        });
      }
    },
    [compute],
  );

  React.useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (/[-0-9+*/().%]/.test(e.key)) press(e.key);
      else if (e.key === 'Enter' || e.key === '=') press('=');
      else if (e.key === 'Backspace') press('⌫');
      else if (e.key === 'Escape') press('C');
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [press]);

  return (
    <div className="w-full max-w-sm select-none">
      <div className="mb-3 rounded-md border border-foreground/20 bg-[#faf7ef] px-4 py-3 text-right">
        <div className="min-h-[1.2em] break-all font-mono text-sm opacity-60">{expr || '0'}</div>
        <div className="min-h-[1.4em] break-all font-mono text-2xl font-bold">{out}</div>
      </div>
      <div className="grid grid-cols-4 gap-2">
        {KEYS.flat().map((k) => (
          <button
            key={k}
            type="button"
            onClick={() => press(k)}
            className={`h-14 rounded-md border border-foreground/15 font-mono text-lg transition-transform active:scale-95 ${
              k === '=' ? 'bg-foreground text-background' : 'bg-[var(--tile)]'
            }`}
          >
            {k}
          </button>
        ))}
      </div>
    </div>
  );
}
↖ kaspirius