괄호 안의 항을 2, 3, 4 항으로 설정하는 기능 추가
This commit is contained in:
@@ -4,6 +4,7 @@ import Link from "next/link";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export type PreparationProblemCount = 5 | 10;
|
||||
export type PreparationMaxTermCount = 2 | 3 | 4;
|
||||
|
||||
interface ParenthesesPreparationClientProps {
|
||||
eyebrow: string;
|
||||
@@ -12,11 +13,33 @@ interface ParenthesesPreparationClientProps {
|
||||
notice: string;
|
||||
playHref: string;
|
||||
selectedProblemCount: PreparationProblemCount;
|
||||
selectedMaxTermCount: PreparationMaxTermCount;
|
||||
onProblemCountChange: (count: PreparationProblemCount) => void;
|
||||
onMaxTermCountChange: (count: PreparationMaxTermCount) => void;
|
||||
onStart: () => void;
|
||||
}
|
||||
|
||||
const problemCounts: PreparationProblemCount[] = [5, 10];
|
||||
const maxTermCounts: PreparationMaxTermCount[] = [2, 3, 4];
|
||||
|
||||
const buttonGroupClassName =
|
||||
"inline-flex gap-1 rounded-md border border-slate-300 bg-white p-1 shadow-sm";
|
||||
|
||||
function optionButtonClassName({
|
||||
selected,
|
||||
disabled = false,
|
||||
}: {
|
||||
selected: boolean;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
return `h-10 min-w-16 rounded px-4 text-base font-semibold transition focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2 ${
|
||||
selected ? "bg-emerald-700 text-white" : "text-slate-700 hover:bg-slate-100"
|
||||
} ${
|
||||
disabled
|
||||
? "cursor-not-allowed bg-slate-100 text-slate-400 hover:bg-slate-100"
|
||||
: ""
|
||||
}`;
|
||||
}
|
||||
|
||||
const bracketKinds = [
|
||||
{
|
||||
@@ -46,7 +69,9 @@ export default function ParenthesesPreparationClient({
|
||||
notice,
|
||||
playHref,
|
||||
selectedProblemCount,
|
||||
selectedMaxTermCount,
|
||||
onProblemCountChange,
|
||||
onMaxTermCountChange,
|
||||
onStart,
|
||||
}: ParenthesesPreparationClientProps) {
|
||||
const startLinkRef = useRef<HTMLAnchorElement>(null);
|
||||
@@ -74,7 +99,7 @@ export default function ParenthesesPreparationClient({
|
||||
문제 수
|
||||
</legend>
|
||||
<div
|
||||
className="inline-flex gap-1 rounded-md border border-slate-300 bg-white p-1 shadow-sm"
|
||||
className={buttonGroupClassName}
|
||||
role="group"
|
||||
aria-label="문제 수 선택"
|
||||
>
|
||||
@@ -87,11 +112,7 @@ export default function ParenthesesPreparationClient({
|
||||
type="button"
|
||||
onClick={() => onProblemCountChange(count)}
|
||||
aria-pressed={selected}
|
||||
className={`h-10 min-w-16 rounded px-4 text-base font-semibold transition focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2 ${
|
||||
selected
|
||||
? "bg-emerald-700 text-white"
|
||||
: "text-slate-700 hover:bg-slate-100"
|
||||
}`}
|
||||
className={optionButtonClassName({ selected })}
|
||||
>
|
||||
{count}
|
||||
</button>
|
||||
@@ -100,39 +121,63 @@ export default function ParenthesesPreparationClient({
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset className="space-y-3">
|
||||
<legend className="text-sm font-semibold text-slate-700">
|
||||
괄호 종류
|
||||
</legend>
|
||||
<div
|
||||
className="inline-flex gap-1 rounded-md border border-slate-300 bg-white p-1 shadow-sm"
|
||||
role="group"
|
||||
aria-label="괄호 종류 선택"
|
||||
>
|
||||
{bracketKinds.map((bracketKind) => (
|
||||
<button
|
||||
key={bracketKind.label}
|
||||
type="button"
|
||||
disabled={bracketKind.disabled}
|
||||
aria-pressed={bracketKind.selected}
|
||||
aria-label={`${bracketKind.name} ${
|
||||
bracketKind.disabled ? "준비 중" : "선택됨"
|
||||
}`}
|
||||
className={`h-10 min-w-16 rounded px-4 text-base font-semibold transition focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2 ${
|
||||
bracketKind.selected
|
||||
? "bg-emerald-700 text-white"
|
||||
: "text-slate-700 hover:bg-slate-100"
|
||||
} ${
|
||||
bracketKind.disabled
|
||||
? "cursor-not-allowed bg-slate-100 text-slate-400 hover:bg-slate-100"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{bracketKind.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</fieldset>
|
||||
<div className="flex flex-col gap-6 sm:flex-row sm:items-start">
|
||||
<fieldset className="space-y-3">
|
||||
<legend className="text-sm font-semibold text-slate-700">
|
||||
괄호 종류
|
||||
</legend>
|
||||
<div
|
||||
className={buttonGroupClassName}
|
||||
role="group"
|
||||
aria-label="괄호 종류 선택"
|
||||
>
|
||||
{bracketKinds.map((bracketKind) => (
|
||||
<button
|
||||
key={bracketKind.label}
|
||||
type="button"
|
||||
disabled={bracketKind.disabled}
|
||||
aria-pressed={bracketKind.selected}
|
||||
aria-label={`${bracketKind.name} ${
|
||||
bracketKind.disabled ? "준비 중" : "선택됨"
|
||||
}`}
|
||||
className={optionButtonClassName({
|
||||
selected: bracketKind.selected,
|
||||
disabled: bracketKind.disabled,
|
||||
})}
|
||||
>
|
||||
{bracketKind.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset className="space-y-3">
|
||||
<legend className="text-sm font-semibold text-slate-700">
|
||||
괄호 안 최대 항 수
|
||||
</legend>
|
||||
<div
|
||||
className={buttonGroupClassName}
|
||||
role="group"
|
||||
aria-label="괄호 안 최대 항 수 선택"
|
||||
>
|
||||
{maxTermCounts.map((count) => {
|
||||
const selected = selectedMaxTermCount === count;
|
||||
|
||||
return (
|
||||
<button
|
||||
key={count}
|
||||
type="button"
|
||||
onClick={() => onMaxTermCountChange(count)}
|
||||
aria-pressed={selected}
|
||||
className={optionButtonClassName({ selected })}
|
||||
>
|
||||
{count}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Link
|
||||
|
||||
Reference in New Issue
Block a user