diff --git a/.jules/palette.md b/.jules/palette.md index 2dcd639e..eba9b02a 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -81,3 +81,6 @@ ## 2024-08-04 - 숫자 입력 필드 빈 문자열 상태 초기화 처리 **학습:** 숫자 입력 필드에서 빈 문자열('')을 입력할 때 브라우저는 이전의 유효하지 않은 상태를 암시적으로 유지하므로, 사용자 정의 검증을 명시적으로 초기화하지 않으면 네이티브 HTML5 유효성 검사가 정상 작동하지 않을 수 있음을 확인했습니다. **실행:** 인라인 검증 스크립트 작성 시 빈 문자열 상태를 별도로 확인하여 this.setCustomValidity('') 및 this.removeAttribute('aria-invalid')를 명시적으로 호출하는 로직을 추가해야 합니다. +## 2024-09-09 - 일괄 업로드 폼 입력 필수 항목 검증 (Validation) 및 인라인 피드백 접근성 개선 +**Learning:** 파일 및 용량(target_bytes) 입력 필드가 비어있을 때 HTML5 툴팁만으로는 오류 상태가 명확하지 않으며, 보조 기기(스크린 리더) 사용자가 입력 누락을 파악하기 어렵다는 점을 확인했습니다. +**Action:** 필수 입력 항목이 비어있을 경우 명시적으로 "This field is required."라는 인라인 에러 메시지를 표시하고, `aria-invalid="true"` 속성 및 시각적 에러 스타일(적색 텍스트 및 별표 아이콘)을 동적으로 적용하여 사용성과 접근성을 향상시켜야 합니다. diff --git a/CHANGELOG.md b/CHANGELOG.md index 9313538b..d2113ecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - 다중 파일 업로드 선택 시 즉각적인 파일 개수 피드백 및 제한 초과 경고 메시지 추가 - 일괄 업로드 폼에 대상 바이트 프리셋 버튼과 총 파일 크기 미리보기를 추가하여 사용성을 개선했습니다. - 클라이언트 측 폼 검증 시 하드코딩된 '5 GiB' 텍스트를 동적으로 변환되도록 수정하고 일괄 업로드 폼에 최대 크기(MAX_UPLOAD_BYTES) 검증 피드백을 추가했습니다. +- 단일 및 일괄 업로드 폼에서 파일 또는 대상 크기 입력이 비어있을 때 명확한 "This field is required." 인라인 메시지와 `aria-invalid=true` 속성을 노출하도록 클라이언트 측 검증 로직을 강화했습니다. ### Changed - 순수 영숫자 토큰은 정규식 호출을 건너뛰되 다국어·문장부호 토큰화 결과는 기존 의미와 동일하게 유지합니다. 근거, 한계, APA 7 참고문헌은 [`docs/doctoring/token-fast-path-equivalence.md`](docs/doctoring/token-fast-path-equivalence.md)에 기록했습니다. diff --git a/saas_web.py b/saas_web.py index 63265e94..4e29b8ba 100644 --- a/saas_web.py +++ b/saas_web.py @@ -153,8 +153,8 @@ async def add_security_headers(request: Request, call_next): button:hover:not(:disabled) { background-color: #004085; } button:disabled { background-color: #6c757d; cursor: not-allowed; } button:focus-visible, input:focus-visible { outline: 2px solid #004085; outline-offset: 2px; } - .required-star { color: #dc3545; } .help-text { color: #6c757d; font-size: 0.85em; display: inline-block; margin-top: 4px; } + .required-star { color: #dc3545; } .spinner { display: inline-block; width: 1em; height: 1em; vertical-align: -0.125em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spinner-border .75s linear infinite; margin-right: 8px; } @keyframes spinner-border { to { transform: rotate(360deg); } } .box { transition: background-color 0.2s, border-color 0.2s; } @@ -190,6 +190,31 @@ async def add_security_headers(request: Request, call_next):
+ +