setForm({ ...form, title: e.target.value })}
className="w-full bg-surface-overlay border border-slate-700/50 rounded-lg px-3 py-2 text-[11px] text-heading placeholder:text-hint focus:outline-none focus:border-blue-500/50"
@@ -282,6 +283,7 @@ export function NoticeManagement() {
diff --git a/frontend/src/features/auth/LoginPage.tsx b/frontend/src/features/auth/LoginPage.tsx
index e9d80a6..6f488fe 100644
--- a/frontend/src/features/auth/LoginPage.tsx
+++ b/frontend/src/features/auth/LoginPage.tsx
@@ -142,6 +142,7 @@ export function LoginPage() {
setUserId(e.target.value)}
@@ -157,6 +158,7 @@ export function LoginPage() {
setPassword(e.target.value)}
diff --git a/frontend/src/features/detection/ChinaFishing.tsx b/frontend/src/features/detection/ChinaFishing.tsx
index 46ec976..2ea7e8f 100644
--- a/frontend/src/features/detection/ChinaFishing.tsx
+++ b/frontend/src/features/detection/ChinaFishing.tsx
@@ -345,7 +345,7 @@ export function ChinaFishing() {
-
@@ -664,10 +664,10 @@ export function ChinaFishing() {
))}
-
diff --git a/frontend/src/features/detection/GearIdentification.tsx b/frontend/src/features/detection/GearIdentification.tsx
index 1710d74..cf24e90 100644
--- a/frontend/src/features/detection/GearIdentification.tsx
+++ b/frontend/src/features/detection/GearIdentification.tsx
@@ -436,15 +436,17 @@ function FormField({ label, children, hint }: { label: string; children: React.R
);
}
-function InputField({ value, onChange, placeholder, type = 'text', className = '' }: {
+function InputField({ value, onChange, placeholder, type = 'text', className = '', label }: {
value: string | number | null;
onChange: (v: string) => void;
placeholder: string;
type?: string;
className?: string;
+ label?: string;
}) {
return (
onChange(e.target.value)}
diff --git a/frontend/src/features/parent-inference/LabelSession.tsx b/frontend/src/features/parent-inference/LabelSession.tsx
index dca7f28..dc72a2e 100644
--- a/frontend/src/features/parent-inference/LabelSession.tsx
+++ b/frontend/src/features/parent-inference/LabelSession.tsx
@@ -122,11 +122,11 @@ export function LabelSession() {
{!canCreate &&
권한 없음}
- setGroupKey(e.target.value)} placeholder="group_key"
+ setGroupKey(e.target.value)} placeholder="group_key"
className="flex-1 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreate} />
- setSubCluster(e.target.value)} placeholder="sub"
+ setSubCluster(e.target.value)} placeholder="sub"
className="w-24 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreate} />
- setLabelMmsi(e.target.value)} placeholder="정답 parent MMSI"
+ setLabelMmsi(e.target.value)} placeholder="정답 parent MMSI"
className="w-48 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreate} />
권한 없음}
- setGrpKey(e.target.value)} placeholder="group_key"
+ setGrpKey(e.target.value)} placeholder="group_key"
className="flex-1 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreateGroup} />
- setGrpSub(e.target.value)} placeholder="sub"
+ setGrpSub(e.target.value)} placeholder="sub"
className="w-24 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreateGroup} />
- setGrpMmsi(e.target.value)} placeholder="excluded MMSI"
+ setGrpMmsi(e.target.value)} placeholder="excluded MMSI"
className="w-40 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreateGroup} />
- setGrpReason(e.target.value)} placeholder="사유"
+ setGrpReason(e.target.value)} placeholder="사유"
className="flex-1 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreateGroup} />
권한 없음}
- setGlbMmsi(e.target.value)} placeholder="excluded MMSI"
+ setGlbMmsi(e.target.value)} placeholder="excluded MMSI"
className="w-40 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreateGlobal} />
- setGlbReason(e.target.value)} placeholder="사유"
+ setGlbReason(e.target.value)} placeholder="사유"
className="flex-1 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs" disabled={!canCreateGlobal} />
신규 모선 확정 등록 (테스트)
setNewGroupKey(e.target.value)}
@@ -135,6 +136,7 @@ export function ParentReview() {
className="flex-1 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs"
/>
setNewSubCluster(e.target.value)}
@@ -142,6 +144,7 @@ export function ParentReview() {
className="w-32 bg-surface-overlay border border-border rounded px-3 py-1.5 text-xs"
/>
setNewMmsi(e.target.value)}
diff --git a/frontend/src/features/vessel/VesselDetail.tsx b/frontend/src/features/vessel/VesselDetail.tsx
index 1e65326..b97d198 100644
--- a/frontend/src/features/vessel/VesselDetail.tsx
+++ b/frontend/src/features/vessel/VesselDetail.tsx
@@ -167,17 +167,17 @@ export function VesselDetail() {
선박 상세 조회
시작/종료
- setStartDate(e.target.value)}
+ setStartDate(e.target.value)}
className="flex-1 bg-surface-overlay border border-slate-700/50 rounded px-2 py-1 text-[10px] text-label focus:outline-none focus:border-blue-500/50"
placeholder="YYYY-MM-DD HH:mm" />
~
- setEndDate(e.target.value)}
+ setEndDate(e.target.value)}
className="flex-1 bg-surface-overlay border border-slate-700/50 rounded px-2 py-1 text-[10px] text-label focus:outline-none focus:border-blue-500/50"
placeholder="YYYY-MM-DD HH:mm" />
MMSI
- setSearchMmsi(e.target.value)}
+ setSearchMmsi(e.target.value)}
placeholder="MMSI 입력"
className="flex-1 bg-surface-overlay border border-slate-700/50 rounded px-2 py-1 text-[10px] text-label focus:outline-none" />
diff --git a/frontend/src/flow/components/FilterBar.tsx b/frontend/src/flow/components/FilterBar.tsx
index 73a478e..a950951 100644
--- a/frontend/src/flow/components/FilterBar.tsx
+++ b/frontend/src/flow/components/FilterBar.tsx
@@ -74,7 +74,7 @@ export function FilterBar({ filter, onChange, groupBy, onGroupByChange, meta }:
v{meta.version} · {meta.releaseDate} · 노드 {meta.nodeCount} · 엣지 {meta.edgeCount}
-
diff --git a/frontend/src/shared/components/common/SaveButton.tsx b/frontend/src/shared/components/common/SaveButton.tsx
index 98be3d1..fb5d3ad 100644
--- a/frontend/src/shared/components/common/SaveButton.tsx
+++ b/frontend/src/shared/components/common/SaveButton.tsx
@@ -29,6 +29,7 @@ export function SaveButton({ onClick, label = '저장', disabled = false, classN
return (
{
* variant: primary / secondary / ghost / outline / destructive
* size: sm / md / lg
* className override는 cn()으로 안전하게 허용됨.
+ *
+ * **접근성 정책**:
+ * - 텍스트 children이 있는 버튼: 그 텍스트가 접근 이름
+ * - 아이콘 전용 버튼 (children 없이 icon만): 반드시 aria-label 또는 title 필수
+ * 예) } />
+ * - 위반 시 스크린 리더가 용도를 인지할 수 없어 WCAG 2.1 Level A 위반
*/
export const Button = forwardRef(
({ className, variant, size, icon, trailingIcon, children, ...props }, ref) => {