style(design): FINDING-012 — 접근성 통일: 검색 라벨·행 키보드 선택·이모지 숨김 [subagent]

Settings 는 label 연결이 모범인데 Jobs/Products 검색 인풋만 접근
가능한 이름이 없었고, Products 목록(button)과 달리 Jobs 행(tr onClick)
은 키보드로 선택 불가였다. aria-label 2곳, tr tabIndex+Enter/Space
핸들러+focus-visible, 장식 이모지(⚠✓🎉) aria-hidden 처리.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
민헌 2026-07-13 22:58:51 +09:00
parent 645a0362b0
commit 1006ad11ea
4 changed files with 11 additions and 9 deletions

View File

@ -66,11 +66,11 @@ export default function Crawl() {
{ip.data && (
blockCount === 0 ? (
<p className="rounded-lg bg-ok-50 px-3 py-2 text-[13px] font-semibold text-ok-600">
IP 0 ( )
<span aria-hidden> </span> IP 0 ( )
</p>
) : (
<p role="alert" className="rounded-lg border border-dead-600/20 bg-dead-50 px-3 py-2 text-[13px] font-semibold text-dead-600">
{blockCount} {ip.data.block_min_requests} .
<span aria-hidden> </span> {blockCount} {ip.data.block_min_requests} .
( toml [DecodoConfig].ip_request_budget)
</p>
)
@ -139,7 +139,7 @@ export default function Crawl() {
<Card title="차단 발생 추이" hint="시간대별">
{bot.isPending && <Loading />}
{bot.isError && <ErrorNote error={bot.error} />}
{bot.data && bot.data.hourly.length === 0 && <Empty> 🎉</Empty>}
{bot.data && bot.data.hourly.length === 0 && <Empty> <span aria-hidden>🎉</span></Empty>}
{bot.data && bot.data.hourly.length > 0 && (
<ResponsiveContainer width="100%" height={150}>
<BarChart data={bot.data.hourly.map((h) => ({ ...h, x: dateShort(h.bucket) }))} margin={{ top: 6, right: 12, bottom: 0, left: -22 }}>

View File

@ -51,12 +51,12 @@ export default function Dashboard() {
{alerts.map((a) => (
<p key={a.key} role="alert"
className="rounded-lg border border-dead-600/20 bg-dead-50 px-3 py-2 text-[13px] font-semibold text-dead-600">
{a.msg}
<span aria-hidden> </span>{a.msg}
</p>
))}
{d && alerts.length === 0 && (
<p className="rounded-lg bg-ok-50 px-3 py-2 text-[13px] font-semibold text-ok-600">
<span aria-hidden> </span>
</p>
)}

View File

@ -51,7 +51,7 @@ export default function Jobs() {
))}
</div>
<form className="ml-auto flex gap-1.5" onSubmit={(e) => { e.preventDefault(); setQ(qInput.trim()); setPage(0); }}>
<input value={qInput} onChange={(e) => setQInput(e.target.value)} placeholder="상품코드·상품명 검색"
<input value={qInput} onChange={(e) => setQInput(e.target.value)} placeholder="상품코드·상품명 검색" aria-label="상품코드·상품명 검색"
className="w-56 rounded-lg border border-line-200 bg-surface px-3 py-1.5 text-[13px] outline-none focus:border-primary-600" />
<button type="submit" className="rounded-lg bg-primary-600 px-3 py-1.5 text-[12px] font-semibold text-white hover:bg-primary-700"></button>
</form>
@ -77,8 +77,10 @@ export default function Jobs() {
</thead>
<tbody>
{list.data.items.map((j) => (
<tr key={j.job_id} onClick={() => setSelected(j)}
className={`cursor-pointer border-b border-line-100 hover:bg-surface-2 ${selected?.job_id === j.job_id ? "bg-primary-50/60" : ""}`}>
<tr key={j.job_id} onClick={() => setSelected(j)} tabIndex={0}
onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setSelected(j); } }}
aria-selected={selected?.job_id === j.job_id}
className={`cursor-pointer border-b border-line-100 hover:bg-surface-2 focus-visible:bg-primary-50/60 ${selected?.job_id === j.job_id ? "bg-primary-50/60" : ""}`}>
<td className="py-2 pr-3">
<div className="font-semibold">{j.product_name || "—"}</div>
<div className="text-[11px] text-ink-400">{j.product_code}</div>

View File

@ -32,7 +32,7 @@ export default function Products() {
<h1 className="text-[17px] font-bold tracking-tight">·</h1>
<form className="flex gap-1.5" onSubmit={(e) => { e.preventDefault(); setQ(qInput.trim()); }}>
<input value={qInput} onChange={(e) => setQInput(e.target.value)} placeholder="상품코드 검색"
<input value={qInput} onChange={(e) => setQInput(e.target.value)} placeholder="상품코드 검색" aria-label="상품코드 검색"
className="w-64 rounded-lg border border-line-200 bg-surface px-3 py-1.5 text-[13px] outline-none focus:border-primary-600" />
<button type="submit" className="rounded-lg bg-primary-600 px-3 py-1.5 text-[12px] font-semibold text-white hover:bg-primary-700"></button>
</form>