PatternsP4 본문

Loading Feedback

Spinner·Skeleton·Progress·FormMessage·Alert·Toast를 대기 성격과 피드백 범위에 따라 선택하는 상태 전달 패턴입니다.

마지막 업데이트 2026-06-29

쓰는 곳#

저장, 검색, 목록 페치, 차트 로딩, 파일 업로드, AI 생성, 백그라운드 동기화처럼 사용자가 기다리거나 결과를 확인해야 하는 모든 흐름에 씁니다. 핵심은 무엇이 기다리는 대상인지피드백이 어디까지 영향을 주는지를 먼저 정하는 것입니다.

Feedback state model

먼저 상태와 소유 표면을 정합니다

같은 로딩이라도 버튼, 콘텐츠, 장기 작업, 결과 복구는 서로 다른 표면이 상태를 소유합니다.

짧은 대기누른 컨트롤Button loading · Spinner사용자가 누른 바로 그 곳에서 대기 상태를 소유합니다.
콘텐츠 로딩들어올 자리SkeletonList · Skeleton첫 화면에 보이는 밀도만 예약해 레이아웃 점프를 줄입니다.
진행 작업작업 표면Progress · Task status수치를 알면 결정 진행률, 모르면 상태 라벨을 함께 둡니다.
결과·복구영향 범위FormMessage · Alert · Toast실패와 재시도는 화면에 남기고, 완료 보조만 Toast로 보냅니다.
Form action

제출 피드백은 CTA가 소유합니다

저장 중에는 주 버튼이 로딩을 표시하고, 실패는 버튼 위 메시지로 남깁니다.

Content loading

콘텐츠 자리는 Skeleton이 지킵니다

목록·카드·차트는 전체 Spinner 대신 들어올 구조와 같은 밀도로 먼저 자리를 잡습니다.

Background task

긴 작업은 진행 상태와 복귀점을 보존합니다

내보내기·AI 생성·동기화는 페이지를 떠나도 사용자가 다시 확인할 수 있어야 합니다.

보고서 생성64% · 백그라운드에서 계속 진행
진행 중
64%
권한 동기화진행률을 계산할 수 없는 작업
진행 중
Result scope

결과는 사라져도 되는지로 나눕니다

복구 행동이 필요한 실패는 화면 안에 남기고, 이미 반영된 완료만 Toast로 보조합니다.

일부 항목만 반영됨

3건은 저장됐지만 권한이 없는 1건은 보류했습니다. 보류 항목을 확인하세요.

저장 완료

변경사항이 화면에 반영되었습니다.

모바일 기준

모바일에서는 대기 표시를 늘리지 않습니다. CTA·목록·작업 큐처럼 사용자가 기다리는 대상 가까이에 상태를 모으고, 실패·재시도는 Toast가 사라진 뒤에도 화면에 남깁니다.
Loading Feedback — 대기 성격과 결과 범위별 컴포넌트 선택

적용 현황#

기준서
완료
이 문서에서 Spinner·Skeleton·Progress·Message 선택 기준을 정의합니다.
포털 적용
Settings·Login·Dashboard·Admin Console·Chart Data States·Background Task Monitor와 이 문서의 조합 데모에 적용
재사용 구현
개별 컴포넌트는 @wds/ui-web에 있음 — FeedbackState 조합 API는 아직 후보
배포 패키지
Spinner·Skeleton·Progress·Button loading·FormMessage·Alert·Toast 포함
다음 조치
반복 적용처가 늘어나면 FeedbackState·LoadableRegion recipe 또는 registry 후보로 분리

상태 모델#

Loading Feedback은 컴포넌트 이름으로 고르지 않습니다. 먼저 상태가 얼마나 오래 가는지, 어떤 표면이 소유하는지, 사용자가 복구 행동을 해야 하는지를 정합니다.

짧은 인라인 대기

버튼·아이콘·텍스트 옆의 짧은 대기는 Button loading 또는 작은 Spinner가 소유합니다. 화면 중앙 Spinner로 키우지 않습니다.

콘텐츠 로딩

목록·카드·차트처럼 들어올 자리가 정해져 있으면 Skeleton이 소유합니다. 첫 화면에 보이는 행 수·높이·밀도만 예약합니다.

진행 작업

업로드·내보내기·AI 생성처럼 사용자가 진행을 추적해야 하면 Progress 또는 작업 큐가 소유합니다. 모르는 수치는 만들지 않고 상태 라벨을 둡니다.

성공

결과가 이미 화면에 반영됐고 사용자가 놓쳐도 되는 완료만 Toast로 보조합니다. 다음 행동이 필요하면 표면 안에 남깁니다.

실패·부분·권한

실패, 부분 완료, 권한 없음, 오래된 데이터처럼 복구나 판단이 필요한 상태는 FormMessage, Alert, 해당 결과 표면 안에 남깁니다.

선택 매트릭스#

버튼·인라인 대기

사용자가 누른 바로 그 행동이 짧게 대기하면 Button loading을 씁니다. 독립 Spinner를 화면 중앙에 키우지 않습니다.

콘텐츠 페치

곧 들어올 콘텐츠 구조를 알고 있으면 Skeleton 또는 프리셋(SkeletonList, SkeletonCard, SkeletonTable)을 씁니다. 실제 콘텐츠와 같은 크기·밀도로 잡아 레이아웃 점프를 막습니다.

진행률 작업

업로드·내보내기·동기화처럼 작업 진행 상태가 주 관심사면 Progress를 씁니다. 수치를 알면 결정 모드, 모르면 indeterminate와 상태 라벨을 씁니다.

폼 결과

제출 실패·계정 잠금·레이트리밋처럼 폼 안에서 해결해야 하는 결과는 FormMessage를 CTA 위 또는 모바일 액션 메시지 행에 둡니다.

페이지 공지

사용자가 읽고 유지해야 하는 페이지 범위 공지·오류 요약은 Alert입니다. 자동으로 사라지는 Toast로 대체하지 않습니다.

일시 결과

저장 완료처럼 이미 화면 상태가 반영됐고 지나가도 되는 결과만 Toast로 알립니다. 실패 원인·재시도는 Toast만으로 끝내지 않습니다.

웹 규칙#

상태 소유

상태는 사용자가 기다리는 대상이 소유합니다. 버튼 제출은 버튼, 목록 로딩은 목록 자리, 장기 작업은 작업 큐나 진행 영역이 소유합니다.

스켈레톤 동형성

Skeleton은 실제 UI와 같은 행 수·카드 수·차트 영역 비율을 사용합니다. 예쁜 회색 블록이 아니라 레이아웃 안정 장치입니다.

가짜 진행률 금지

수치를 모르면 퍼센트를 만들지 않고 indeterminate Progress 또는 상태 문구를 씁니다.

결과 보존

완료·실패가 이후 행동을 요구하면 Toast만 띄우지 않고 해당 화면·큐·폼 안에 상태를 남깁니다.

동일 높이

대기·결과 표면을 같은 행에 나란히 놓으면 세로 높이를 맞춥니다. 한쪽 카드만 짧거나 긴 상태로 방치하지 않습니다.

모바일 규칙#

좁은 화면에서는 작은 피드백을 여러 곳에 흩뿌리면 사용자가 무엇을 기다리는지 놓칩니다. 모바일은 피드백을 줄이는 것이 아니라 기다리는 대상 가까이에 모으는 것이 기준입니다.

CTA

제출 중에는 주 버튼이 로딩을 소유하고, 보조 버튼은 비활성화하거나 같은 폭을 유지합니다. 버튼 행 위 메시지 규칙은 모바일 폼 액션 규칙을 따릅니다.

목록·카드

모바일 목록은 전체 화면 Spinner보다 SkeletonListSkeletonCard를 우선합니다. 첫 화면에 보이는 행 수만 보여 주고 아래쪽까지 과도하게 채우지 않습니다.

장기 작업

오래 걸리는 작업은 하단 compact status 또는 알림 복귀점으로 유지하고, 상세는 BottomSheet로 엽니다. 관련 규칙은 Background Task Monitor를 따릅니다.

Toast

모바일 Toast는 결과 확인 보조 수단입니다. 실패·재시도·입력 수정처럼 행동이 필요한 정보는 화면 안 메시지로 남깁니다.

표면 절제

모바일에서는 데스크탑 카드·패널 테두리를 반복하지 않습니다. 필요한 구분선과 섹션 흐름만 남겨 상태와 CTA가 폭을 확보하게 합니다.

모션 감소

reduced-motion에서는 Spinner 회전·Progress 왕복·Skeleton shimmer가 멈추거나 약해져도 상태 라벨은 남아야 합니다.

조합 레시피#

FormActionFeedback

폼 제출 실패는 FormMessage를 CTA 바로 위에 두고, 모바일 버튼은 취소·저장 2등분 또는 세로 전체폭으로 유지합니다.

LoadableRegion

검색 결과·목록·차트는 aria-busy를 대상 컨테이너에 한 번만 주고, 반복 Skeleton 도형 자체는 장식으로 둡니다.

TaskProgress

장기 작업은 Progress와 상태 태그를 함께 두고, 실패·재시도·완료 결과는 Background Task Monitor 규칙으로 보존합니다.

ResultScope

필드 오류는 FormField, 폼 오류는 FormMessage, 페이지 공지는 Alert, 일시 완료는 Toast로 범위를 분리합니다.

접근성#

  • 로딩 상태는 컨테이너 aria-busy 또는 컴포넌트 역할(status, progressbar)로 한 번만 전달합니다.
  • Skeleton 도형 자체는 장식입니다. 반복 행마다 낭독하지 않고 SkeletonLoadable 같은 컨테이너에서 알립니다.
  • 오류는 범위가 중요합니다. 필드 오류는 FormField, 폼 오류는 FormMessage, 페이지 오류는 Alert로 올립니다.
  • Progress indeterminate는 aria-valuenow를 생략합니다. 수치를 모르는 작업에 가짜 값을 주지 않습니다.
  • Toast는 자동 해제되므로, 반드시 읽어야 하는 정보나 재시도 행동을 Toast에만 두지 않습니다.

참고 기준#

사용 컴포넌트#

Button(loading) · Spinner · Skeleton · Progress · FormMessage · Alert · Toast · EmptyState

검수 기준#

대상

사용자가 무엇을 기다리는지 첫 화면에서 바로 알 수 있음

점프

Skeleton이 실제 콘텐츠와 다른 높이·밀도로 잡혀 로드 후 레이아웃이 튀지 않음

범위

필드·폼·페이지·전역 피드백이 서로 중복되지 않음

모바일

320px에서 메시지와 CTA가 서로 폭을 빼앗지 않고, 페이지 전체 가로 스크롤이 없음

복구

실패 상태에는 원인·재시도·수정 위치가 남아 Toast 소멸 뒤에도 복구 가능함