Files
sudoku-tools/src/components/NumberPad.tsx
T

77 lines
2.2 KiB
TypeScript

import type { EntryMode } from "../state/session";
import { symbolFor } from "../state/session";
import { colorMarkDescription } from "../state/uiPreferences";
const modes: Array<{ mode: EntryMode; label: string; key: string }> = [
{ mode: "value", label: "Value", key: "Z" },
{ mode: "corner", label: "Corner", key: "X" },
{ mode: "center", label: "Centre", key: "C" },
{ mode: "color", label: "Colour", key: "V" },
];
export function NumberPad({
size,
mode,
onMode,
onValue,
onErase,
}: {
size: number;
mode: EntryMode;
onMode: (mode: EntryMode) => void;
onValue: (value: number) => void;
onErase: () => void;
}) {
return (
<div className="number-pad">
<div className="mode-switcher" role="group" aria-label="Entry mode">
{modes.map((item) => (
<button
key={item.mode}
type="button"
className={mode === item.mode ? "is-active" : ""}
aria-pressed={mode === item.mode}
title={`${item.label} mode (${item.key})`}
onClick={() => onMode(item.mode)}
>
{item.label}
</button>
))}
</div>
<div
className={`digit-pad${size > 9 ? " digit-pad--wide" : ""}`}
role="group"
aria-label={mode === "color" ? "Colours" : "Digits"}
>
{Array.from({ length: mode === "color" ? 8 : size }, (_, index) => {
const value = index + 1;
return (
<button
key={value}
type="button"
className={
mode === "color" ? `color-choice color-${String(value)}` : ""
}
onClick={() => onValue(value)}
>
{mode === "color" ? (
<>
<span aria-hidden="true" />{" "}
<span className="sr-only">
Colour {value}: {colorMarkDescription(value)}
</span>
</>
) : (
symbolFor(value, size)
)}
</button>
);
})}
<button type="button" className="erase-key" onClick={onErase}>
Erase
</button>
</div>
</div>
);
}