Add number highlight, ESC/ctrl-click deselect, and color theming via spacebar

- Highlight all cells matching a pressed number when no cell is selected (toggle on repeat)
- ESC key and Ctrl+click deselect the active cell
- Spacebar cycles through a random hue that themes the entire UI via CSS custom property --hue
- Theme hue is persisted in localStorage across page reloads

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Eduard Duran
2026-02-17 22:08:17 +01:00
co-authored by Claude Sonnet 4.6
parent 5c07425d1d
commit 2243abbb22
5 changed files with 95 additions and 39 deletions
+6 -4
View File
@@ -2,8 +2,9 @@ import React from 'react'
import Cell from './Cell'
import { checkValue } from '../utils/sudoku'
function Board({ board, puzzle, solution, notes, selected, showErrors, celebrating, selectCell }) {
function Board({ board, puzzle, solution, notes, selected, highlightedNumber, showErrors, celebrating, selectCell, deselect }) {
const selectedValue = selected && board[selected.row][selected.col]
const activeNumber = selected ? selectedValue : highlightedNumber
return (
<div className="board">
@@ -20,9 +21,10 @@ function Board({ board, puzzle, solution, notes, selected, showErrors, celebrati
Math.floor(selected.col / 3) === Math.floor(c / 3)
const isSameNumber =
!isSelected &&
selectedValue !== 0 &&
value !== 0 &&
value === selectedValue
activeNumber !== null &&
activeNumber !== 0 &&
value === activeNumber
const isError =
showErrors &&
!isGiven &&
@@ -43,7 +45,7 @@ function Board({ board, puzzle, solution, notes, selected, showErrors, celebrati
isSameNumber={isSameNumber}
isError={isError}
isCelebrating={isCelebrating}
onClick={() => selectCell(r, c)}
onClick={(e) => e.ctrlKey || e.metaKey ? deselect() : selectCell(r, c)}
/>
)
})
+4 -3
View File
@@ -1,17 +1,18 @@
import React from 'react'
function NumberPad({ onNumber, numberCounts }) {
function NumberPad({ onNumber, numberCounts, highlightedNumber }) {
return (
<div className="number-pad">
<div className="number-buttons">
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map(n => {
const remaining = 9 - numberCounts[n]
const disabled = remaining <= 0
const isHighlighted = highlightedNumber === n
return (
<button
key={n}
className={`num-btn${disabled ? ' disabled' : ''}`}
onClick={() => !disabled && onNumber(n)}
className={`num-btn${disabled ? ' disabled' : ''}${isHighlighted ? ' highlighted' : ''}`}
onClick={() => onNumber(n)}
disabled={disabled}
>
<span className="num-btn-value">{n}</span>