EmptyState
비어 있는 이유와 다음 행동을 같은 맥락 안에서 안내합니다.
목적
EmptyState는 화면이나 섹션에 보여줄 데이터가 없을 때 그 이유와 다음 행동을 함께 전달한다. 단순히 빈 공간을 채우는 장식이 아니라 사용자가 멈추지 않고 생성, 조건 변경, 권한 요청 또는 다른 경로로 이동하게 돕는 상태다.
선택 기준
- 최초 생성 전, 검색 결과 없음, 필터 결과 없음처럼 데이터 영역 전체가 비었을 때 사용한다.
- 로딩 중이거나 요청 실패 상태에는 사용하지 않는다.
- 작은 표 셀 하나의 빈 값은
—또는 명시적인 값 없음 표현을 사용한다. - 권한 때문에 데이터를 볼 수 없다면 권한 이유와 요청 경로를 포함한 전용 문구를 사용한다.
실제 패키지 렌더링
기본 사용 예시
아직 등록된 질문이 없어요
첫 질문을 추가하면 학습 흐름을 검토할 수 있어요.
구조
icon: 상태를 빠르게 보조하는 선택적 시각 요소title: 무엇이 비어 있는지 또는 현재 결과를 설명description: 이유, 조건 또는 얻을 수 있는 가치 설명action: 사용자가 이어서 할 수 있는 가장 적절한 행동 하나
변형과 크기
- 별도 variant와 size prop은 없다.
- 기본 표면은 dashed border와 차분한 배경을 사용한다.
- 아이콘이 없어도 구조와 간격이 유지된다.
className으로 컨테이너 높이나 배치를 조정할 수 있지만 주 콘텐츠보다 과도하게 크게 만들지 않는다.
상태와 동작
action이 비동기 작업을 시작하면 버튼이 pending 상태와 진행 레이블을 직접 제공해야 한다.- 검색어 또는 필터로 결과가 없으면 조건을 초기화하는 행동을 우선한다.
- 최초 데이터가 없으면 생성 행동을 우선한다.
- 권한 없음이면 사용할 수 없는 생성 버튼을 보여주기보다 권한 요청 또는 담당자 확인 경로를 제공한다.
- 데이터가 생기면 같은 frame 안에서 실제 콘텐츠로 교체해 위치 변화를 줄인다.
콘텐츠
- 제목은
데이터가 없어요보다등록된 커리큘럼이 없어요처럼 대상을 말한다. - 설명은 이미 제목에 드러난 사실을 반복하지 않는다.
- 검색 결과 없음은 현재 검색어나 필터를 포함할 수 있다.
- 행동 레이블은
시작하기보다첫 커리큘럼 만들기,필터 초기화처럼 결과를 말한다. - 빈 상태가 정상이라면 불안이나 실패처럼 표현하지 않는다.
접근성
- 컨테이너는 기본적으로 일반
div다. 동적으로 결과가 비게 되는 중요한 변화는 소비 제품의 live region이나 결과 개수 안내와 함께 전달한다. - 아이콘은 의미를 중복하지 않도록 장식 처리하거나, 의미가 있다면 자체 접근 가능한 텍스트를 제공한다.
- 행동에는 눈에 보이는 레이블을 우선한다.
- 상태를 아이콘 모양이나 색상만으로 구분하지 않는다.
좁은 화면과 긴 콘텐츠
- 기본적으로 중앙 정렬되고 설명은 읽기 쉬운 폭으로 제한된다.
- action에 여러 버튼을 넣지 않는다. 꼭 필요한 보조 경로는 설명 안의 링크 또는 별도 주변 영역에 둔다.
- 긴 제목과 설명은 자연스럽게 줄바꿈한다. 고유 명칭이 길면 문장 구조를 바꿔 핵심 상태가 먼저 보이게 한다.
- 작은 화면에서 과도한 수직 여백이 생기면
className으로 padding만 조정하되 구조는 유지한다.
공개 API
EmptyStateProps는 React.HTMLAttributes<HTMLDivElement>를 확장한다.
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
title | string | 필수 | 빈 상태의 핵심 메시지 |
description | string | 없음 | 이유 또는 다음 판단을 위한 설명 |
icon | ReactNode | 없음 | 선택적 시각 요소 |
action | ReactNode | 없음 | 주 행동 |
className | string | 없음 | 컨테이너 클래스 |
| 기타 | HTMLAttributes<HTMLDivElement> | 없음 | 표준 div 속성 |
예제
import { Button, EmptyState } from '@classum/dot-design-system/ui';
import { SearchX } from 'lucide-react';
export function NoSearchResults({ reset }: { reset: () => void }) {
return (
<EmptyState
icon={<SearchX aria-hidden />}
title="조건에 맞는 실행 기록이 없어요"
description="검색어를 바꾸거나 적용한 필터를 초기화해보세요."
action={<Button onClick={reset}>필터 초기화</Button>}
/>
);
}피해야 할 사용
- 요청 실패를 빈 데이터처럼 숨기는 사용
- 로딩 중 잠깐 EmptyState를 보여주는 깜박임
- 이유 없이 캐릭터와
아직 없어요만 표시 - 서로 경쟁하는 행동을 여러 개 배치
- 데이터가 비어 있는 정상 상태를 위험 색으로 표현
- 행의 개별 빈 값을 전체 EmptyState로 표현