Layout
AppShell
애플리케이션 골격. 네비게이션 배치를 매번 명시적으로 고르게 한다.
상단 네비 / 사이드 네비 / 네비 없음을 nav prop 하나로 전환합니다. AppShell.Nav는 부모의 nav 값에 따라 가로 바 또는 세로 사이드바로 알아서 배치되므로, 네비 내용을 바꾸지 않고 골격만 갈아탈 수 있습니다.
왜 nav에 기본값이 없는가 — 골격을 고르는 프리미티브가 없으면 화면을 만들 때마다 즉흥으로 짜게 되고, 결국 가장 익숙한 형태(좌측 사이드바 + 카드 그리드)로 매번 수렴합니다. nav를 필수로 둔 건 그 선택을 의식하게 만들려는 장치입니다.
import { AppShell } from "@nxtgen-org/react";
어느 배치를 고를 것인가
목적지 개수와 콘텐츠 폭이 결정한다. 취향이 아니라 구조의 문제.
| nav | 고르는 조건 | 이유 |
|---|---|---|
| top | 목적지 5개 이하 · 넓은 테이블이나 차트가 주인공 | 사이드바가 가로 240px를 상시 점유하지 않는다. 데이터 화면에서 그 폭이 아깝다. |
| side | 목적지 8개 이상 · 중첩 메뉴가 있는 관리 화면 | 세로 목록은 길이 제한이 없다. 톱네브는 5~7개를 넘으면 줄바꿈되거나 "더보기"에 숨겨야 한다. |
| none | 단일 화면 · 로그인 · 온보딩 · 마케팅 페이지 | 이동할 곳이 없으면 네비는 소음이다. |
6~7개 구간은 어느 쪽도 정답이 아닙니다. 메뉴가 늘어날 예정이면 side, 고정이면 top으로 갑니다.
Variants
같은 자식 구조로 배치만 바뀐다.
Top navigation
가로 공간을 지키고 싶을 때. 데이터 밀도가 높은 화면에 유리하다.
TopNav
Content
tsx
<AppShell nav="top"><AppShell.Nav><Logo /><HStack gap="x1">{links}</HStack></AppShell.Nav><AppShell.Main><AppShell.Content width="wide">{children}</AppShell.Content></AppShell.Main></AppShell>
Side navigation
목적지가 많고 중첩될 때. 접으면 64px로 줄어든다.
SideNav
Content
tsx
<AppShell nav="side"><AppShell.Nav collapsed={collapsed}><VStack gap="x1">{links}</VStack></AppShell.Nav><AppShell.Main><AppShell.Content>{children}</AppShell.Content></AppShell.Main></AppShell>
No navigation
로그인·온보딩처럼 이동할 곳이 없는 화면.
Content
tsx
<AppShell nav="none"><AppShell.Main><AppShell.Content width="prose">{children}</AppShell.Content></AppShell.Main></AppShell>
Content width
max-w-6xl 같은 임의 값 대신 의도를 남긴다.
폭 고르기
prose720pxcontent1152pxwide1440pxtsx
<AppShell.Content width="prose"> {/* 읽기 화면 */}<AppShell.Content> {/* 기본 = content */}<AppShell.Content width="wide"> {/* 테이블·차트 */}
Props
| Name | Type | Default | Description |
|---|---|---|---|
| nav* | "top" | "side" | "none" | — | 네비게이션 배치. 기본값 없음 — 매번 명시적으로 고른다. |
AppShell.Nav
| Name | Type | Default | Description |
|---|---|---|---|
| collapsed | boolean | false | 사이드 배치일 때만 유효. 폭이 navSize.sideWidth(240px) → sideWidthCollapsed(64px)로 줄어든다. |
AppShell.Content
| Name | Type | Default | Description |
|---|---|---|---|
| width | "prose" | "content" | "wide" | "content" | 콘텐츠 최대 폭. contentWidth 토큰을 참조한다. |