본문으로 건너뛰기
Dot Design System
v0.3.1

목록에서 상세로

목록의 탐색 조건과 선택 맥락을 상세 화면까지 보존합니다.

목표

목록에서 대상을 찾고 상세 내용을 확인한 뒤 다시 목록으로 돌아오는 동안 검색, 필터, 정렬, 페이지, scroll과 선택 위치를 보존한다. 화면 이동을 새로운 시작으로 만들지 않고 하나의 이어진 작업으로 만든다.

선택 기준

  • 여러 record 가운데 하나를 선택해 독립된 상세 route에서 검토하거나 편집할 때 사용한다.
  • 비교가 핵심이면 상세 route를 반복 이동하기보다 table, split view 또는 비교 패턴을 검토한다.
  • 상세 내용이 매우 짧고 현재 목록과 함께 봐야 하면 side panel을 사용할 수 있다.
  • 여러 단계 편집이나 중요한 저장이 포함되면 독립 route가 더 안전하다.

기본 구조

목록

  1. PageHeader: 화면 목적과 주 생성 행동
  2. PageToolbar: 검색·필터·정렬·새로고침
  3. 결과 요약: 결과 개수, 적용 범위, 마지막 갱신
  4. record list 또는 Table
  5. loading, empty, error가 같은 결과 frame 안에서 교체

상세

  1. PageHeader.backAction: 돌아갈 목록의 이름
  2. title: 선택한 record의 사람이 이해할 이름
  3. badge와 meta: 상태, 소유자, 저장 시각
  4. 제한된 주 행동
  5. 세부 section

이동과 맥락 보존

  • 검색어, 필터, 정렬, pagination은 URL search params를 우선 사용한다.
  • 목록을 떠날 때 scroll 위치와 마지막 선택 record를 보존한다.
  • 상세에서 돌아오면 결과를 처음부터 다시 불러오며 빈 화면을 보여주지 말고 기존 결과를 유지한 채 갱신한다.
  • 돌아온 뒤 마지막 record가 남아 있으면 해당 행으로 focus 또는 시각적 위치를 복원한다.
  • record가 삭제되었다면 가장 가까운 안전한 목록 heading 또는 결과 영역으로 focus를 이동한다.
  • 뒤로보다 실행 기록으로 돌아가기처럼 목적지를 눈에 보이는 레이블로 제공한다.

행 행동

  • 행 전체가 정확히 하나의 상세 목적지로 이동하면 행의 주 링크가 넓은 hit area를 가질 수 있다.
  • 실제 table row에 임의 onClick만 추가하지 말고 record 이름에 semantic link를 둔다.
  • 행 안의 menu, checkbox, button은 상세 링크와 독립적으로 동작해야 한다.
  • 행 전체 선택과 상세 이동을 같은 클릭에 묶지 않는다.
  • hover에서만 필수 행동을 드러내지 않는다.
  • 파괴 행동은 row menu에서 바로 완료하지 말고 대상과 결과를 확인한다.

상태와 피드백

Loading

  • column 또는 row 구조를 반영한 skeleton으로 목록 frame을 유지한다.
  • 검색·필터 변경 중에는 이전 결과를 유지하고 갱신 중임을 알린다.

Empty

  • 최초 데이터 없음과 현재 조건의 결과 없음을 구분한다.
  • 최초 없음은 생성 행동, 결과 없음은 조건 초기화를 우선한다.

Error

  • 목록 전체 실패는 같은 frame에 오류와 재시도를 보여준다.
  • 일부 row 실패는 나머지 결과를 유지하고 해당 항목에 상태를 표시한다.

Detail change

  • 저장 성공 뒤 title, status와 목록의 해당 row가 같은 값을 보여야 한다.
  • 삭제 성공 뒤 목록으로 이동하고 삭제된 대상을 다시 focus하려 하지 않는다.
  • 다른 사용자가 record를 변경했다면 덮어쓰기 전에 최신 상태와 충돌을 설명한다.

좁은 화면

  • table의 모든 열을 축소하지 말고 식별자, 상태, 핵심 meta, 주 행동을 record list로 재배치한다.
  • 열려 있는 side panel은 독립 route 또는 full-screen layer로 전환한다.
  • 필터는 sheet에 둘 수 있지만 적용된 조건과 결과 개수는 목록에서 계속 확인 가능해야 한다.
  • 목록으로 돌아왔을 때 이전 scroll과 조건을 모바일에서도 보존한다.

접근성

  • table 데이터는 Table의 header와 cell 관계를 유지한다.
  • 목록에는 고유한 heading 또는 aria-label을 제공한다.
  • row action의 이름에 record 대상을 포함한다. 예: 온보딩 커리큘럼 더보기.
  • route가 바뀌면 상세 h1에 programmatic focus를 보낸다.
  • 목록으로 돌아올 때 삭제되지 않은 마지막 link로 focus를 복원한다.
  • 결과 개수 변경은 짧은 live region으로 알리되 매 keystroke마다 과도하게 낭독하지 않는다.

예제

사용 코드 · TSX
<PageScaffold>
  <PageHeader
    title="커리큘럼"
    description="운영 중인 학습과 검토가 필요한 초안을 관리해요."
    actions={<Button>새 커리큘럼 만들기</Button>}
  />
  <PageToolbar
    title="전체 커리큘럼"
    controls={<Input aria-label="커리큘럼 검색" placeholder="이름 검색" />}
  />
  <CurriculumTable />
</PageScaffold>

상세 header:

사용 코드 · TSX
<PageHeader
  title={curriculum.name}
  backAction={{ label: '커리큘럼 목록', onClick: returnToList }}
  badge={<StatusPill tone="warning">검증 필요</StatusPill>}
/>

피해야 할 사용

  • 상세에서 돌아올 때 검색과 필터 초기화
  • table row에 onClick만 추가하고 link semantics 생략
  • row checkbox, menu와 상세 이동 영역 충돌
  • 상세 title을 내부 ID만으로 표시
  • 검색 갱신마다 결과 전체를 비워 깜박이게 함
  • 모바일에서 중요한 상태 열을 아무 설명 없이 숨김

검토 체크

  • 목록의 목적과 주 생성 행동이 첫 화면에서 보인다.
  • 검색·필터·정렬·페이지가 URL 또는 복원 가능한 state에 있다.
  • 상세로 이동한 record와 돌아갈 위치를 기억한다.
  • row의 link, 선택, menu hit area가 충돌하지 않는다.
  • loading, 최초 empty, 결과 empty, 전체 error, 부분 error가 구분된다.
  • 상세 저장·삭제 결과가 목록과 즉시 일치한다.
  • route 전환과 복귀 focus가 정의돼 있다.
  • 좁은 화면에서도 식별자·상태·핵심 행동이 남는다.

관련 항목