괄호 안의 항을 2, 3, 4 항으로 설정하는 기능 추가

This commit is contained in:
2026-05-31 13:40:45 +09:00
parent e148a957ea
commit ac3c939051
21 changed files with 708 additions and 344 deletions
+24 -43
View File
@@ -14,7 +14,7 @@ import type { FocusEvent, FormEvent } from "react";
import { DESKTOP_INPUT_DEVICE_QUERY } from "@/lib/input-device";
import KatexRenderer from "@/components/math/KatexRenderer";
export type ActiveAnswerInput = 0 | 1;
export type ActiveAnswerInput = number;
const ANSWER_INPUT_PATTERN = /^-?\d*(?:\.\d*)?$/;
const KEYPAD_KEYS = [
@@ -36,13 +36,11 @@ export interface NumberAnswerFormHandle {
}
interface NumberAnswerFormProps {
answerA: string;
answerB: string;
answers: string[];
activeInput: ActiveAnswerInput;
error: string;
pendingAnswerLabels: [string, string];
onAnswerAChange: (value: string) => void;
onAnswerBChange: (value: string) => void;
pendingAnswerLabels: string[];
onAnswerChange: (index: ActiveAnswerInput, value: string) => void;
onActiveInputChange: (input: ActiveAnswerInput) => void;
onInputBlur?: () => void;
onInputFocus?: () => void;
@@ -54,13 +52,11 @@ const NumberAnswerForm = forwardRef<
NumberAnswerFormProps
>(function NumberAnswerForm(
{
answerA,
answerB,
answers,
activeInput,
error,
pendingAnswerLabels,
onAnswerAChange,
onAnswerBChange,
onAnswerChange,
onActiveInputChange,
onInputBlur,
onInputFocus,
@@ -75,17 +71,16 @@ const NumberAnswerForm = forwardRef<
const [keypadOpen, setKeypadOpen] = useState(false);
const [desktopInputDevice, setDesktopInputDevice] = useState(false);
const activeAnswer = activeInput === 0 ? answerA : answerB;
const activeLabel = activeInput === 0 ? "첫째 항" : "둘째 항";
const activeAnswer = answers[activeInput] ?? "";
const activeLabel = `${activeInput + 1}`;
const activeDescription = `${activeLabel}의 답을 입력하세요.`;
const activeEnterKeyHint = activeInput === 0 ? "next" : "done";
const activeAnswerChange =
activeInput === 0 ? onAnswerAChange : onAnswerBChange;
const lastInputIndex = answers.length - 1;
const activeEnterKeyHint = activeInput < lastInputIndex ? "next" : "done";
function updateAnswer(value: string) {
if (!ANSWER_INPUT_PATTERN.test(value)) return;
activeAnswerChange(value);
onAnswerChange(activeInput, value);
}
function handleInputFocus() {
@@ -154,16 +149,9 @@ const NumberAnswerForm = forwardRef<
};
}, []);
function setAnswer(input: ActiveAnswerInput, value: string) {
if (input === 0) {
onAnswerAChange(value);
} else {
onAnswerBChange(value);
}
}
function toggleMinus() {
activeAnswerChange(
onAnswerChange(
activeInput,
activeAnswer.startsWith("-") ? activeAnswer.slice(1) : `-${activeAnswer}`,
);
focusInput();
@@ -182,14 +170,14 @@ const NumberAnswerForm = forwardRef<
function moveToInput(input: ActiveAnswerInput, reset = false) {
onActiveInputChange(input);
if (reset) {
setAnswer(input, "");
onAnswerChange(input, "");
}
focusInput();
}
function handleEnter() {
if (activeInput === 0) {
moveToInput(1);
if (activeInput < lastInputIndex) {
moveToInput(activeInput + 1);
return;
}
@@ -197,18 +185,11 @@ const NumberAnswerForm = forwardRef<
focusInput();
}
const answerButtons = [
{
index: 0 as const,
label: "첫째 항",
value: answerA,
},
{
index: 1 as const,
label: "둘째 항",
value: answerB,
},
];
const answerButtons = answers.map((value, index) => ({
index,
label: `${index + 1}`,
value,
}));
return (
<form
@@ -334,9 +315,9 @@ const NumberAnswerForm = forwardRef<
onPointerDown={(event) => event.preventDefault()}
onClick={handleEnter}
aria-label={
activeInput === 0
? "첫째 항 입력 완료 후 둘째 항으로 이동"
: "둘째 항 입력 완료 후 제출"
activeInput < lastInputIndex
? "현재 항 입력 완료 후 다음 항으로 이동"
: "마지막 항 입력 완료 후 제출"
}
className="col-span-2 inline-flex h-12 items-center justify-center rounded-md bg-emerald-700 text-base font-semibold text-white shadow-sm transition hover:bg-emerald-800 focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2"
>