본문으로 건너뛰기
레이아웃 / master-detail

MasterDetailLayout

반응형 2컬럼 master/detail 패턴(모바일에서 스택 + back).
레이아웃master-detailStatic specimenmaster detail마스터 디테일list detail목록 상세
01 · Specimen

먼저 보고, 그다음 계약을 읽습니다

반응형 2컬럼 master/detail 패턴(모바일에서 스택 + back).

Workbench 불러오는 중…
Component intent의도와 경계 읽기

좌측 목록(list/tree)과 우측 상세(detail)를 데스크톱에서는 가로로, 모바일(< breakpoint)에서는 한 컬럼씩 스택으로 보여준다. Cortex MemoryBrowser 의 list+detail 모바일 토글 패턴을 SSOT 로 흡수했다. 모바일 detail 화면 상단에 back 버튼이 자동으로 붙고, master↔detail 전이 시 포커스를 기억·복원한다. mobileShowDetail + onMobileBack 을 주면 controlled, 안 주면 detail !== null 여부로 자동 전환하는 uncontrolled 로 동작한다.

02 · Use

예제

SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.

01uncontrolled (자동 전환)tsxfragment
uncontrolled (자동 전환)
import { MasterDetailLayout } from "@axe/ui";import { useState } from "react";function Browser() {  const [id, setId] = useState<string | null>(null);  return (    <MasterDetailLayout      master={<List onSelect={setId} />}      detail={id ? <Detail id={id} /> : null}      masterWidth="320px"    />  );}
02controlled (모바일 화면 소유)tsxfragment
controlled (모바일 화면 소유)
import { MasterDetailLayout } from "@axe/ui";<MasterDetailLayout  master={<List onSelect={open} />}  detail={selected ? <Detail item={selected} /> : null}  breakpoint={768}  mobileBackLabel="목록으로"  mobileShowDetail={showDetail}  onMobileBack={() => setShowDetail(false)}/>
03 · React

Props

TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.

이름타입필수기본값설명
masterReact.ReactNode필수좌측 컬럼 내용(list/tree).
detailReact.ReactNode | null필수우측 detail 내용. null 이면 emptyState(또는 기본 placeholder) 표시.
masterWidthnumber | string"320px"데스크톱 master 컬럼 폭(--axe-md-master-width). number=px.
breakpointnumber768모바일 전환 임계 px(< breakpoint = 스택 모드).
mobileBackLabelstring"목록으로"모바일 detail 상단 back 버튼 텍스트.
mobileShowDetailbooleancontrolled — true 면 모바일에서 detail 화면. onMobileBack 와 함께 사용.
onMobileBack() => voidcontrolled back 핸들러. mobileShowDetail 와 함께 주면 controlled 모드로 전환.
emptyStateReact.ReactNodedetail === null 일 때 표시할 빈 자리 노드(미지정 시 기본 placeholder).
...restOmit<React.HTMLAttributes<HTMLDivElement>, "children">className 은 병합, style 은 내부 CSS 변수와 병합, 나머지는 루트 div 로 전파.
04 · Any stack

.axe-* 클래스 계약

React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.

클래스안정성용도
.axe-master-detailstable루트 flex row(데스크톱 2컬럼, gap --space-4).
.axe-master-detail--mobilestableJS 측정 후 부여 — flex column(스택), gap 0.
.axe-master-detail__masterstable좌측 <aside> — 폭 --axe-md-master-width(기본 320px), overflow auto.
.axe-master-detail__master--hiddenstable모바일 detail 화면에서 master 숨김(display:none).
.axe-master-detail__detailstable우측 <section> — flex:1 로 남는 공간 차지, overflow auto.
.axe-master-detail__detail--hiddenstable모바일 master 화면에서 detail 숨김(display:none).
.axe-master-detail__backstable모바일 detail 상단 back 버튼(hover/focus 트림).
.axe-master-detail__back-arrowstableback 버튼 ← 화살표 span(aria-hidden).
.axe-master-detail__emptystabledetail 미지정 + emptyState 없을 때의 기본 placeholder("항목을 선택하세요").
비-React 소비 노트
데스크톱 2컬럼 정적 레이아웃은 `.axe-master-detail` 마크업으로 재현 가능하나, 모바일 토글·back·포커스 이동은 JS(matchMedia + 상태)에 의존 — CSS-only 로는 반응형 단일 컬럼 전환까지만. master 폭은 --axe-md-master-width 로 제어. (컴포넌트가 부여하는 `--show-detail` modifier 는 상태 훅일 뿐 대응 CSS 규칙이 없다.)
05 · Inclusive

접근성

키보드, ARIA, 구현 노트를 함께 검토합니다.

Keyboard
  • back 버튼은 네이티브 <button> — Enter/Space 로 목록 복귀
ARIA

master=<aside>, detail=<section>. 모바일에서 숨는 컬럼에 aria-hidden 을 부여해 AX 트리에서 제외한다. back 버튼 aria-label = "<mobileBackLabel> 돌아가기", 화살표 span 은 aria-hidden.

Notes

모바일 전이 시 포커스 관리: master→detail 진입 때 직전 master 내 포커스를 기억하고 back 버튼으로 이동(rAF 다음 프레임), detail→master 복귀 때 기억한 element 로 복원. 이 포커스 관리는 모바일(isMobile)에서만 동작한다. 뷰포트 감지는 matchMedia 기반 SSR-safe — 초기엔 데스크톱(false)으로 렌더 후 mount 시 보정한다.

06 · Judgment

권장 · 지양

권장
  • detail 이 비었을 때의 안내는 emptyState 로 명시적으로 준다.
  • controlled 모드에서는 라우팅 상태(URL)와 mobileShowDetail 를 동기화한다.
지양
  • mobileShowDetail 만 주고 onMobileBack 을 빼먹지 말 것(back 이 무동작).
  • master 폭을 지나치게 좁혀 목록이 조작 불가능하게 만들지 말 것.
검색창을 열면 컴포넌트 인덱스를 불러옵니다.