Files
CipherStreamWeb/src/components/input/SquareNumberArray.tsx
2026-08-15 17:28:19 -04:00

95 lines
2.6 KiB
TypeScript

import clsx from "clsx";
import { PrimaryButton, SuccessButton } from "mattrixwv-components";
import { useCallback } from "react";
import { BsDashLg, BsPlusLg } from "react-icons/bs";
export default function SquareNumberArray({
value,
onChange
}:{
value: number[][];
onChange: (value: number[][]) => void;
}){
//TODO: Check for a square array
const decreaseArraySize = useCallback(() => {
if(value.length <= 2){
throw new Error("Cannot decrease grid size below 2");
}
const newValue = value.slice(0, -1);
newValue.forEach((row) => {
row.pop();
});
onChange(newValue);
}, [ onChange, value ]);
const increaseArraySize = useCallback(() => {
if(value.length >= 10){
throw new Error("Cannot increase grid size above 10");
}
const newValue = [...value];
newValue.forEach((row) => {
row.push(0);
});
newValue.push(new Array(value.length + 1).fill(0) as number[]);
onChange(newValue);
}, [ onChange, value ]);
const updateValue = useCallback((rowIndex: number, cellIndex: number, newCellValue: number) => {
const newValue = [...value];
newValue[rowIndex][cellIndex] = newCellValue;
onChange(newValue);
}, [ onChange, value ]);
return (
<div
className="flex flex-col items-center justify-center gap-y-4"
>
<div
className="flex flex-row items-center justify-center gap-x-8"
>
<SuccessButton size="sm" shape="square" onClick={decreaseArraySize} disabled={value.length <= 2}><BsDashLg className="text-3xl text-white"/></SuccessButton>
<PrimaryButton size="sm" shape="square" onClick={increaseArraySize} disabled={value.length >= 10}><BsPlusLg className="text-3xl text-white"/></PrimaryButton>
</div>
<table>
<tbody>
{
value.map((row, rowIndex) => (
<tr
// eslint-disable-next-line @eslint-react/no-array-index-key
key={`squareNumberArrayRow${rowIndex}`}
className=""
>
{
row.map((cell, cellIndex) => (
<td
// eslint-disable-next-line @eslint-react/no-array-index-key
key={`squareNumberArrayCell${rowIndex}${cellIndex}`}
className="w-8 h-8 border"
>
<input
type="number"
className={clsx(
"text-center spinbox-hide text-xl w-12 h-10",
"[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
)}
value={cell}
onChange={(e) => updateValue(rowIndex, cellIndex, parseInt(e.target.value))}
/>
</td>
))
}
</tr>
))
}
</tbody>
</table>
</div>
);
}