웹 앱 디자인
웹 앱은 사람들이 매일 돌아와서 레코드를 찾고, 변경하고, 작업을 전달하는 곳입니다. 사람들이 항상 자신이 어디에 있는지, 무엇을 보고 있는지, 무엇을 할 수 있는지, 방금 무슨 일이 일어났는지 알 수 있고, 내일도 URL로 동일한 뷰로 돌아올 수 있을 때 성공합니다. 가장 흔한 모델 실패는 아름다운 해피패스 화면에 설 자리가 없는 경우입니다. 즉, 빈 상태, 로딩 상태, 오류 상태, 권한 없음 상태가 없고, 필터가 새로고침 시 사라지고, 개수 표시와 실행 취소가 없는 일괄 작업, 서버가 나중에 거부하는 낙관적 업데이트에서 실행되는 "삭제", 그리고 에이전트가 구분할 수 없는 동일한 "편집" 버튼 행이 있는 경우입니다.
interface-guidelines의 우선순위 원칙(모두가 사용할 수 있어야 한다 > 진실을 말해야 한다 > 의미를 명확히 해야 한다 > 답이 먼저 나와야 한다 > 실수는 회복 가능해야 한다 > 제자리에 있어야 한다 > 가능한 것이 보여야 한다 > 관례를 따라야 한다 > 다듬어야 한다)을 적용하세요. 해당 스킬이 설치되어 있다면 먼저 SKILL.md를 읽으세요. 그 참조는 피드백 타이밍, 오류 문구, 데이터로서의 테이블, 에이전트 지향 시맨틱을 다룹니다. 이 스킬은 애플리케이션 UI에 특화된 패턴을 추가합니다.
개요
- 객체와 동사. 명사(주문, 고객, 송장)와 각 역할이 각각에 대해 무엇을 할 수 있는지 나열하세요. 네비게이션과 권한이 이 테이블에서 도출됩니다.
- 역할과 테넌트. 누가 무엇을 보고 변경할 수 있습니까? 한 사람이 속할 수 있는 작업 공간, 조직 또는 환경(스테이징, 프로덕션)이 두 개 이상 있습니까?
- 일일 업무 빈도와 각 역할이 가장 먼저 여는 하나의 뷰.
- 컬렉션 크기: 일반적인 경우와 최악의 경우(10행 또는 200만 행). 페이지네이션, 검색 및 서버 측 필터링을 결정합니다.
- 각 변경 동사에 대한 오류 비용과 서버 측에서 실행 취소할 수 있는지 여부.
- 동시성: 두 사람 또는 사람과 에이전트가 동일한 레코드를 편집할 수 있습니까?
- 누가 표시 텍스트를 작성합니까? 고객 이름, 티켓 본문, 가져온 파일: 모두 외부인이 작성합니다.
- 에이전트 리더: UI의 브라우저 에이전트, API, 또는 둘 다? UI와 API는 작업당 하나의 서비스를 공유해야 합니다.
규칙
셸과 네비게이션
- 네비게이션은 조직도가 아닌 객체를 반영합니다. 최상위 항목은 사람들이 작업하는 명사이며, 사용 빈도 순서대로, 사람들이 사용하는 단어로 레이블이 지정됩니다. [S: Mac HIG 1992 pp. 54-61 (논리별, 빈도별 그룹화); J]
- 데스크톱에서는 기본 네비게이션을 계속 표시하세요. 숨겨진 네비게이션은 발견성을 떨어뜨리고 NN/g의 연구에서 작업 속도를 늦췄습니다. 햄버거 메뉴는 전화기의 타협입니다. [E: NN/g, 기초]
- 사용자가 어디에 있는지 세 가지 방법으로 표시:
aria-current="page"와 시각적 상태로 표시된 현재 네비게이션 항목, 객체 또는 목록의 이름을 지정하는 페이지h1, 그리고 경로에 따라 변경되는 문서 제목. [S: WCAG 2.4.2, 2.4.8; J] - 이동 경로는 깊은 객체 트리에서만 기록이 아닌 계층 구조를 보여줍니다. 현재 페이지는 링크가 아닙니다. [P: NN/g 이동 경로]
- 현재 작업 공간, 조직 또는 환경은 항상 셸에 단어로 표시되며, 프로덕션은 스테이징과 시각적으로 구별됩니다. 테넌트 전환은 명시적인 행위이며, 해당 테넌트의 동등한 페이지나 홈으로 이동하며, 선택 또는 초안을 절대 넘기지 않습니다. [J]
- 모든 뷰에는 URL이 있습니다. 필터, 정렬, 검색, 페이지, 선택된 탭 및 열린 레코드는 URL에 있습니다. 새로고침과 공유 시 복원됩니다. [S: 기초 에이전트-표면 3]
- 뒤로 가기는 목록을 그대로 복원합니다: 동일한 필터, 스크롤 위치 및 사용자가 열었던 행에 초점이 맞춰집니다. [S: Mac HIG 1992 p. 140 (재활성화된 창은 그대로 반환됨); J]
목록과 테이블
- 테이블은 레코드를 비교하기 위한 것이고, 목록은 하나의 속성을 스캔하기 위한 것입니다. 표 형식 데이터에는 실제
<table>을 사용하세요. [S: 기초; NN/g 데이터 테이블] - 네 가지 테이블 작업을 지원: 레코드 찾기, 행 간 비교, 한 행 보기 또는 편집, 하나 또는 여러 행에 대한 작업 수행. [P: NN/g 데이터 테이블]
- 첫 번째 열은 안정적이고 사람이 읽을 수 있는 키(이름 + ID)로 행을 식별합니다. 스크롤 시 열과 헤더를 고정하세요. [P: NN/g 데이터 테이블]
- 헤더에서 정렬:
<th>내부의<button>, 정렬된 열에만aria-sort, 그리고 보이는 화살표. 기본 정렬이 명시됩니다("최신순"). [S: APG 정렬 가능 테이블; P: Carbon] - 필터는 표시되고, 제거 가능하며, 개수가 표시됩니다. 적용된 필터를 칩으로 표시하고 "모두 지우기", 결과 개수("1,204개 주문 중 38개"), 필터를 명명하는 빈 결과 메시지를 포함하세요. 필터 이름에는 사용자의 단어를 사용하세요. [P: NN/g 필터; S: 기초]
- 컬렉션이 큰 경우 서버 측 검색, 필터 및 정렬을 사용하세요. 로드된 페이지의 데이터만 정렬하거나 개수를 세어 전체인 것처럼 제시하지 마세요. [J; 기초 진실 규칙]
- 목표 지향적인 작업은 페이지네이션하고, 무한 스크롤은 피드용으로 남겨두세요. 페이지네이션은 위치, 돌아갈 안정적인 장소, 도달 가능한 푸터를 제공합니다. 범위와 총 개수, 그리고 "목록 끝"을 명시하세요. [P: NN/g 무한 스크롤; S: Smith and Mosier 4.2/7]
- 행 작업은 표시되거나 키보드 포커스로 도달 가능해야 하며, 호버 전용이어서는 안 되며, 행별로 이름이 지정됩니다("INV-2041 보관"). 작업이 3개 미만이면 인라인으로 표시하세요. [S: 기초 에이전트-표면 3; P: Carbon]
- 밀도는 사용 방식에 따릅니다. 매일 사용하는 전문가를 위해 조밀한 밀도를 제공하고, 최소 24px의 터치 대상을 유지하세요. [S: WCAG 2.5.8; P: Carbon 행 크기]
선택 및 일괄 작업
- 일괄 모드는 명시적입니다: 행 체크박스, 불확정 상태의 헤더 체크박스, 개수를 표시하는 도구 모음("3개 선택됨"). [P: Carbon; S: Mac HIG 1992 pp. 64-66 (혼합 상태)]
- "모두 선택"은 그 범위를 명시합니다: 이 페이지의 50개, 또는 필터와 일치하는 1,204개 모두. 사용자가 다른 것을 기대할 때 조용히 하나를 의미하지 마세요. [J]
- 일괄 작업은 실행 전에 객체, 개수 및 범위를 명시하고, 실행 후에 항목별 결과를 보고하며("1,198개 보관됨, 6개 실패: 보기"), 실행 취소 가능하거나 미리 볼 수 있어야 합니다. [S: 기초 섹션 1; J]
- 선택은 도구 모음이 그렇다고 표시하는 경우에만 페이지 매김 및 필터링에서 유지됩니다. 그렇지 않으면 시각적으로 지우세요. [J]
상세 및 편집
- 컨텍스트가 유지되는 곳에서 레코드를 여세요. 측면 패널은 편집하면서 참조하기 좋고, 전체 페이지는 깊은 레코드에 적합합니다. 편집을 위해 모달은 인접 레코드를 숨기므로 피하세요. [P: NN/g 데이터 테이블]
- 상세 뷰는 정체성과 상태를 단어로 먼저 보여주고, 그 다음 사람들이 작업하는 필드, 그 다음 기록을 보여줍니다. [S: 기초; J]
- 표면당 하나의 저장 모델. 토글은 즉시 적용되고, 텍스트 및 다중 필드 편집은 명시적으로 저장됩니다. 한 양식에서 둘 다를 절대 사용하지 마세요. [S: Primer 저장; 기초]
- 저장되지 않은 변경 사항을 남기기 전에 경고하고, 손실이 심할 경우 초안을 자동 저장하세요. [S: Primer 저장]
- 공유 레코드에서 누가, 언제 무엇을 변경했는지 절대 타임스탬프와 함께 표시하고, 자동으로 덮어쓰지 않고 오래된 쓰기를 감지하세요(버전 또는 ETag). [S: Mac HIG 1992 pp. 27-31; 기초의 AIP-154]
- 앱 내부의 양식은
form-design을 따릅니다.
낙관적 UI, 실행 취소 및 확인
- 서버가 거의 거부하지 않고 작업이 되돌릴 수 있을 때만 낙관적으로 수행: 읽음 표시, 즐겨찾기, 순서 변경. 보류 상태를 확인된 상태와 구별하여 표시하고, 실패 시 이유와 함께 시각적으로 롤백하며, 돈 이동, 메시지 전송, 또는 완료된 레코드 삭제를 낙관적으로 표시하지 마세요. [S: Mac HIG 1992 p. 182 (입력됨, 확인됨, 적용됨); P: React useOptimistic]
- 되돌릴 수 있는 작업에는 확인보다 실행 취소를 선호: 보관, 이동, 휴지통으로 삭제. 토스트가 사라진 후에도 실행 취소가 가능하도록 유지하세요(항목 기록의 실행 취소, 휴지통 보기, 편집 메뉴 단축키). [P: Raskin 2007; NN/g 사용자 제어]
- 심각하거나, 되돌릴 수 없거나, 예상치 못한 작업에 대해서만 확인하고, 대상과 효과를 명명하세요. 드물게 발생하는 치명적인 작업(작업 공간 삭제)에 대해서는 입력하여 확인하세요. [S: 기초 섹션 1; E: Bravo-Lillo 2013 (기초를 통해)]
- 서버 측에서 소프트 삭제를 수행하고, 명시된 보존 기간을 제공하여 실행 취소가 실제로 작동하고 클라이언트 환상에 불과하지 않도록 하세요. [S: 기초의 AIP-164]
빈 상태, 로딩 상태, 오류 상태 및 권한 없음 상태
- 네 가지 빈 상태를 구분: 첫 사용(객체를 설명하고 생성 작업 제공), 결과 없음(필터를 명명하고 지우기 제공), 모두 완료됨(완료), 오류(무엇이 실패했는지, 무엇을 해야 하는지). 데이터가 로드되기 전에 "레코드 없음"을 절대 표시하지 마세요. [P: NN/g 빈 상태; S: Primer 빈 상태]
- 로딩은 무엇이 로드되고 있는지 텍스트로 명명하고, 대체하는 영역 내부에 표시하며, 셸과 네비게이션은 사용 가능하게 유지하세요. [S: 기초]
- 권한 없음은 숨겨진 기능이 아닌 상태입니다. 이유와 부여할 수 있는 사람을 설명하면서 비활성화된 작업을 표시하거나("워크스페이스 관리자만 내보낼 수 있습니다. Maya Chen에게 문의하세요."), 액세스 권한과 요청 방법을 설명하는 페이지를 표시하세요. 사용자가 존재를 몰라야 하는 것만 숨기세요. [S: Mac HIG 1992 pp. 318-321 (비활성화된 항목은 스스로를 설명함); J]
- 권한 검사는 서버에서 수행됩니다. 버튼을 숨기는 것은 프레젠테이션이지 권한이 아닙니다. [S: 기초]
- 응답에서 존재 여부보다 먼저 권한을 확인하여 404 대 403이 데이터를 유출하지 않도록 하세요. [S: 기초의 AIP-193]
설정
- 작업 중에 변경되는 설정(뷰 밀도, 열 선택, 필터)은 영향을 주는 항목 옆에 배치하고, 설정 영역은 거의 변경되지 않는 앱 전체 옵션을 보관합니다. [S: Apple HIG 설정]
- 개인 설정과 워크스페이스 설정을 분리하고, 각각이 누구의 것이며 누구에게 영향을 미치는지 레이블을 지정하세요("Acme의 모든 사람에게 적용됨"). [J]
- 데이터베이스 테이블이 아닌 사용자의 작업별로 그룹화하고, 설정이 한두 화면을 초과하면 검색 기능을 제공하세요. [J]
- 더 적은 설정. 세션당 여러 번 변경되는 기본 설정은 설정이 아니라 누락된 컨트롤입니다. [S: Mac HIG 1992 p. 38; Apple HIG 설정]
- 위험한 설정은 별도의 레이블이 지정된 영역에 결과 텍스트와 확인(소유권 이전, 작업 공간 삭제)과 함께 배치하세요. [P: GitHub; J]
온보딩
- 투어가 아닌 맥락에서 가르치세요. NN/g는 카드 덱 튜토리얼이 작업 성능을 향상시키지 않는다는 것을 발견했습니다. 맥락에 맞는 팁과 좋은 빈 상태가 교육을 수행합니다. 투어가 있다면 짧게 유지하고 건너뛸 수 있게 하세요. [P: NN/g 온보딩]
- 사람들이 첫 번째 실제 결과를 빨리 얻을 수 있게 하세요. 샘플 데이터는 나타나는 모든 곳에서 샘플로 표시되고 한 번의 작업으로 제거 가능해야 합니다. [J; 기초 진실 규칙]
- 설정 체크리스트는 지속적이고 정직해야 합니다: 실제 상태를 반영하고, 해제될 수 있으며, 나중에 다시 접근할 수 있어야 합니다. [J]
키보드 및 명령 팔레트
- 명령 팔레트는 메뉴가 아닌 액셀러레이터입니다. 그 안의 모든 명령은 보이는 UI에도 존재합니다. 명령 옆에 단축키를 나열하여 가르칩니다. [S: Windows 메뉴 지침(단축키를 유일한 방법으로 만들지 마십시오); P: VS Code UX 지침]
- 단일 키 단축키는 끄거나 다시 매핑할 수 있어야 하며(WCAG 2.1.4), 텍스트 필드 내에서 절대 실행되지 않고, 브라우저 또는 OS 단축키를 재정의하지 않아야 합니다. [S: WCAG 2.1.4; Apple 키보드]
- 단축키 도움말 시트(종종
?) 는 현재 범위의 모든 단축키를 나열합니다. [J]
에이전트 리더를 위해
- 버튼, 팔레트, API 및 모든 도구에서 공유되는 작업당 하나의 서비스 함수. [S: 기초 에이전트-표면 7]
- 행 컨트롤은 시스템 ID에서 이름을 지정하고, 외부인 텍스트는 그렇지 않습니다. 셀의 외부인 텍스트는 데이터입니다. [J]
- 컬렉션은 실제 크기와 범위를 보이는 텍스트로 명시하며, 필터와 정렬은 URL에 있습니다. [J]
- 결과는 토스트보다 오래 지속됩니다: 변경된 행, 활동 로그, 실행 취소 항목. [J]
- 테넌시와 환경은 모든 페이지에서 텍스트로 읽을 수 있어야 하므로, 에이전트가 스테이징인데 프로덕션에서 행동하지 않습니다. [J]
구축 순서
- 역할별 동사별 객체 테이블; 모든 뷰에 대한 경로 및 URL.
- 셸: 네비게이션, 테넌트 및 환경 표시기, 제목,
h1. - 실제 데이터 형태를 가진 목록 뷰: 서버 측 페이지 매김, 정렬, 필터, 모두 URL에.
- 상세 뷰, 저장 모델, 동시성 처리.
- 모든 변경 작업을 하나의 서비스를 통해: 보류 중, 성공, 실패, 오류 비용 사다리에 따른 실행 취소 또는 확인.
- 각 뷰에 대한 빈 상태, 로딩 상태, 오류 상태, 권한 없음 상태.
- 일괄 작업, 키보드 단축키, 팔레트.
- 설정 및 온보딩은 마지막에; 이 독자를 위한 스타일(
brand-identity가 룩을 소유).
검증
node <interface-guidelines>/scripts/audit.mjs <url|dist> --canary "<샘플 외부인 텍스트>"각 주요 경로에서, 필터가 적용된 목록과 상세 뷰를 포함하여 실행.- 앱 내부 양식:
node <form-design>/scripts/form-check.mjs <url>. - 새로고침 테스트: 필터 적용, 정렬, 3페이지, 레코드 열기; 새로고침하고 URL을 새 세션에 붙여넣기. 모든 것이 복원됨.
- 역할 테스트: 각 역할로 로그인. 숨겨지거나 비활성화된 모든 작업에는 이유가 있음; 서버는 직접 호출된 금지된 요청을 거부함.
- 크기 테스트: 0, 1, 25, 10,000+ 행; 가장 긴 이름; 일치하는 항목이 없는 필터.
- 실패 테스트: 서버가 낙관적 작업과 일괄 작업을 부분적으로 거부하도록 함; UI가 롤백되고 항목별로 보고함.
- 에이전트 테스트: 접근성 스냅샷만 사용하여, 필터로 특정 레코드를 찾고, 변경하고, 새 스냅샷에서 결과를 확인하고, 실행 취소함.
함정
- 컴포넌트 상태에만 보관되는 필터 및 정렬.
- 도구 모음이 모든 것을 암시하는 동안 페이지를 선택하는 "모두 선택".
- 롤백 및 실행 취소가 없는 낙관적 삭제.
- 관리자 테이블의 무한 스크롤; 로드된 행에서 계산된 총계.
- 호버 전용 행 작업; 다섯 개의 동일한 "편집" 버튼.
- 로드 전에 깜빡이는 "데이터 없음"; 모든 원인에 대한 하나의 일반 빈 상태.
- 설명 없이 역할의 기능을 숨기거나, 표시하고 클릭 시 "금지됨"과 함께 실패.
- 이전 테넌트의 선택을 유지하는 테넌트 전환기, 또는 보이는 테넌트가 전혀 없음.
- 사용 가능한 빈 상태 대신 제품 둘러보기.
- 데이터베이스 테이블을 반영하는 설정 페이지.
참조
| 파일 | 읽을 경우 |
|---|---|
references/patterns.md | 네비게이션 모델, 테이블 해부학, 일괄 작업 흐름, 권한 상태, 테넌시, 낙관적 및 실행 취소 메커니즘, 팔레트 디자인 및 이 스킬의 출처에 대한 세부 정보가 필요할 때 |