ComponentsP3 본문

SideSheet

BottomSheet의 적응형 확장 짝 — 좁은 화면은 하단 시트, 넓은 화면은 측면 패널로 자동 전환합니다. 두 표면을 합성한 ADR-012 Track C 컴포넌트입니다.

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

한눈에#

같은 콘텐츠를 뷰포트 폭에 따라 하단 시트 ↔ 측면 패널로 자동 전환하는 적응형 래퍼입니다 — BottomSheet와 Drawer를 합성합니다.

상세 편집넓은 화면은 측면 패널, 좁은 화면은 하단 시트로 같은 콘텐츠를 렌더합니다.
  • 적응형: 시트 ↔ 측면
  • compact → BottomSheet
  • expanded → 측면 패널
  • 동작 계약 일관
열린 상태 재현(넓은 화면=측면 패널) — 좁은 화면에서는 하단 시트로 전환됩니다(실제 동작은 아래에서)

같은 콘텐츠를 뷰포트 폭에 따라 두 표면으로 갈아끼우는 얇은 적응형 래퍼입니다 — compact(< 600px)면 BottomSheet, 그 이상이면 측면 패널 (Drawer 어휘)로 렌더합니다. 다이얼로그·포커스 트랩·Escape·배경 클릭 닫기·스크롤 잠금은 두 표면이 그대로 책임지므로 동작 계약이 일관됩니다.

트리거를 눌러 직접 확인하세요(창 폭을 바꿔 표면 전환도):

사용 시점#

같은 콘텐츠를 폭에 따라 시트↔측면으로 자동 전환하면 SideSheet — 한 표면으로 고정하려면 다른 컴포넌트입니다.

권장 — 이렇게 쓰세요

지양 — 이러지 마세요

쓴다모바일·데스크톱을 한 컴포넌트로 — 좁으면 하단 시트, 넓으면 측면 패널로 자동 전환

대신 BottomSheet뷰포트와 무관하게 항상 하단 시트로 고정할 때

대신 Drawer적응 없이 측면 패널로 고정할 때

플레이그라운드#

컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.

SideSheet를 직접 조작해 보세요

속성·테마·토큰을 바꾸고 React·Flutter 코드를 확인하는 풀스크린 빌더로 엽니다.

빌더 열기

플레이그라운드는 넓은 작업 영역이 필요해 웹·태블릿에서 편집할 수 있어요.

변형#

side확장(넓은 화면) 표면의 슬라이드 인 방향을 정합니다 — 'right'(기본)·'left'. compact 뷰포트에서는 항상 하단 시트라 side는 무시됩니다.

side — right(기본) · left (넓은 화면에서 확인)

크기#

표면이 폭에 따라 갈리므로 별도 size 축은 없습니다 — compact는 하단 시트(상한 85dvh), expanded는 측면 패널입니다. 강제 전환이 필요하면 responsive로 표면을 고정합니다.

상태#

제어 컴포넌트입니다 — 열림/닫힘은 소비자의 open prop이 결정하고, 닫힘 요청 (Escape·배경·닫기 버튼)은 onClose 콜백으로 전달됩니다. responsive로 적응을 재정의할 수 있습니다 — 'auto'(기본)는 폭에 따라, 'mobile'은 항상 시트, 'desktop'은 항상 측면 패널입니다.

모바일 표면에서는 BottomSheet 규칙이 우선합니다. 표면 공통 class는 className에, 시트 전용 보정은 sheetClassName에, 측면 패널 전용 보정은 drawerClassName에 나눠 넣습니다. Drawer 전용 border·shadow·폭 보정 class를 className에 섞어 모바일 시트로 전달하지 않습니다.

Props#

Prop타입기본값설명
openboolean표시 여부 — 제어 prop
onClose() => voidEscape·배경·닫기 버튼의 닫힘 요청 콜백
titleReactNode시트/패널 제목 — 두 표면의 aria-labelledby 대상이라 필수
side'right' | 'left'rightexpanded(측면 패널) 표면의 슬라이드 인 방향 (기본 right). compact 시트에선 무시
footerReactNode하단 액션 영역 (취소/확인 등)
closeLabelstring닫기닫기 버튼 aria-label
classNamestring활성 표면 패널에 전달 — 표면 공통/중립 class만 사용
sheetClassNamestringcompact BottomSheet 표면에만 전달 — 모바일 시트 규칙에 맞는 class만 사용
drawerClassNamestringexpanded Drawer 표면에만 전달
responsive'auto' | 'mobile' | 'desktop'auto적응형 표시 (기본 'auto') — 'auto': compact→BottomSheet, 그 외→측면 패널. 'mobile': 폭과 무관하게 시트 강제 / 'desktop': 폭과 무관하게 측면 패널 강제.
refRef<HTMLDivElement>패널(role=dialog)로 병합 전달되는 ref — 닫힘(미마운트) 동안 null (React 19 ref-as-prop). compact 표면(BottomSheet) 또는 expanded 표면(Drawer) 중 활성 표면의 패널 노드를 가리킨다.

접근성#

표면 선택만 담당하고 a11y 계약은 합성 대상(BottomSheet/Drawer)이 이행합니다.

계약구현
역할role="dialog" + aria-modal="true" (두 표면 공통)
이름titlearia-labelledby로 연결
포커스열리면 패널로 진입, 트랩(Tab 순환), 닫히면 이전 포커스 복원
닫기Escape · 배경 클릭 · 닫기 버튼
스크롤열림 동안 배경 body 스크롤 잠금
적응 SSR서버 기본 expanded → mount 후 동기화(hydration mismatch 없음)

토큰#

자체 토큰 없이 합성 대상의 표면 어휘를 그대로 따릅니다 — BottomSheet·Drawer의 토큰 표를 참고하세요.