Splitter
Splitter (스플리터)
두 패널 사이의 핸들을 드래그해 패널의 크기를 조절할 수 있게 해 주는 컴포넌트예요. 가로·세로·다중 패널·제어·스토어 기반 구성까지 다양하게 지원해요.
출처: 문서
본문
Splitter는 사용자가 패널 사이의 핸들을 드래그해 패널 크기를 재조정할 수 있게 하는 컴포넌트예요. 가로, 세로, 다중 패널, 제어(controlled), 스토어 기반 구성 등을 지원해요. <ExampleTabs name="splitter-basic" />
사용법 (Usage)
import { Splitter } from "@chakra-ui/react"
<Splitter.Root>
<Splitter.Panel />
<Splitter.ResizeTrigger>
<Splitter.ResizeTriggerSeparator />
<Splitter.ResizeTriggerIndicator />
</Splitter.ResizeTrigger>
<Splitter.Panel />
</Splitter.Root>
단축 표현 (Shortcuts)
Splitter 컴포넌트는 흔한 사용 사례를 위한 단축 표현을 제공해요.
SplitterResizeTrigger
Splitter.ResizeTrigger는 기본적으로 그 안에 Splitter.ResizeTriggerSeparator와 Splitter.ResizeTriggerIndicator를 렌더링해 줘요.
이렇게 명시적으로 쓰는 대신,
<Splitter.ResizeTrigger id="a:b" />
시퍼레이터나 인디케이터를 커스터마이즈할 필요가 없다면 이렇게 쓰는 게 단축 표현이에요.
<Splitter.ResizeTrigger id="a:b">
<Splitter.ResizeTriggerSeparator />
<Splitter.ResizeTriggerIndicator />
</Splitter.ResizeTrigger>
예시 (Examples)
제어 (Controlled)
onResize와 size prop을 사용해 패널 크기를 프로그래밍 방식으로 관리할 수 있어요.
<Splitter.Root
panels={[{ id: "a" }, { id: "b" }]}
size={sizes}
onResize={(details) => setSizes(details.size)}
>
{/* ... */}
</Splitter.Root>
스토어 (Store)
스플리터를 제어하는 또 다른 방법은 RootProvider 컴포넌트와 useSplitter 스토어 훅을 사용하는 거예요. 이렇게 하면 스플리터 바깥에서도 상태와 메서드에 접근할 수 있어요.
세로 (Vertical)
Splitter.Root 컴포넌트에 orientation="vertical" prop을 넘기면 패널이 세로로 쌓이며 세로 방향으로 크기가 조절돼요.
반응형 방향 (Responsive Orientation)
useBreakpointValue 훅을 사용해 화면 크기에 따라 스플리터 방향을 바꿀 수 있어요. 모바일에서는 세로, 큰 화면에서는 가로 스플리터를 보여주는 예시예요.
다중 패널 (Multiple Panels)
Splitter.Root 컴포넌트의 panels prop에 배열을 넘기면 두 개보다 많은 크기 조절 가능한 패널을 가진 레이아웃을 만들 수 있어요.
접이식 패널 (Collapsible Panels)
panels 배열의 패널에 collapsible과 collapsedSize 속성을 설정하면 패널을 접거나 특정 크기로 스냅시킬 수 있어요. 이렇게 하면 사용자가 정의된 최소 크기로 패널을 스냅할 수 있어요.
<Splitter.Root
defaultSize={[40, 60]}
panels={[
{ id: "a", collapsible: true, collapsedSize: 5, minSize: 25 },
{ id: "b", minSize: 50 },
]}
>
{/* ... */}
</Splitter.Root>
최소/최대 제약 (Min/Max Constraints)
패널에 minSize와 maxSize를 설정하면 크기 조절 가능한 범위를 제한하고, 이 경계를 넘어서는 재조정을 방지할 수 있어요.
CSS 단위 크기 (CSS Unit Sizes)
퍼센트 외에도 defaultSize, minSize, maxSize는 px, em, rem, vh, vw 같은 CSS 단위를 받아요. 네비게이션 사이드바처럼 고정 너비를 유지해야 하는 패널에 유용해요.
Warning: CSS 단위 크기는 클라이언트에서 측정되므로, 이를 사용하는 패널은 hydration 후에 위치가 바뀔 수 있어요. 안정적인 서버 렌더링 레이아웃을 원한다면 퍼센트 크기를 사용하세요.
크기 조절 동작 (Resize Behavior)
패널에 resizeBehavior를 설정하면 부모 그룹이 크기가 바뀔 때 그 패널이 어떻게 반응할지 제어할 수 있어요. 비례적으로 확대/축소되는 대신 "preserve-pixel-size"를 사용하면 패널의 픽셀 크기를 일정하게 유지해(다른 패널이 변화를 흡수)요.
중첩 패널 (Nested Panels)
패널 안에 스플리터를 중첩해 더 복잡한 레이아웃을 만드는 예시예요. 각 중첩 스플리터는 부모와 독립적으로 자신만의 방향, 크기, 동작을 가질 수 있어요.
저장 (Storage)
defaultSize를 설정하고 useLocalStorage 같은 저장 솔루션과 함께 쓰면 사용자의 패널 크기 선호를 저장할 수 있어요. 이렇게 하면 패널 레이아웃이 세션 간에 유지돼요. 필요에 따라 쿠키나 다른 저장 메커니즘을 써도 돼요.
크기 조절 비활성화 (Disabled Resize)
Splitter.ResizeTrigger에 disabled prop을 넘기면 해당 패널의 크기 조절을 비활성화할 수 있어요. 특정 패널은 고정하고 다른 패널만 조절되게 하려 할 때 유용해요.
<Splitter.ResizeTrigger disabled id="a:b" />
시퍼레이터만 (Separator Only)
리사이즈 트리거를 커스터마이즈해 인디케이터 없이 시퍼레이터만 보여줄 수 있어요. 전체 크기 조절 기능은 유지하면서 미니멀하고 깔끔한 모습을 만들 수 있어요.
<Splitter.ResizeTrigger id="a:b">
<Splitter.ResizeTriggerSeparator />
</Splitter.ResizeTrigger>
더블 클릭 시 리셋 (Reset on Double Click)
Splitter.Context를 사용해 스플리터 컨텍스트에 접근하고 리사이즈 트리거에 더블 클릭 핸들러를 추가할 수 있어요. 이 예시는 리사이즈 핸들을 더블 클릭할 때 패널 크기를 기본값으로 되돌려요.
크기 조절 이벤트 (Resize Events)
onResizeStart, onResize, onResizeEnd props를 사용해 크기 조절 이벤트를 추적할 수 있어요. 이 예시는 타임스탬프와 패널 크기와 함께 모든 크기 조절 이벤트를 기록해, 디버깅이나 커스텀 동작 구현에 유용해요.
키보드 크기 조절 (Keyboard Resize)
Splitter는 접근성과 정밀한 제어를 위해 키보드 기반 크기 조절을 지원해요.
- 리사이즈 핸들이 포커스될 때까지 Tab을 누르세요.
- 화살표 키(Arrow)로 패널 크기를 조절하세요.
- 더 큰 단계로 이동하려면 Shift를 누르세요.
- 최소/최대 크기로 이동하려면 Home / End를 누르세요.
keyboardResizeByprop으로 단계 크기를 제어하세요.
조건부 렌더링 (Conditional Rendering)
이 예시는 패널을 동적으로 보이거나 숨길 수 있는 가로 스플리터를 보여줘요. 스플리터 위의 버튼으로 왼쪽/오른쪽 패널을 토글할 수 있어, 특정 섹션이 항상 필요하지 않은 레이아웃에 적합해요. 패널 하나가 숨겨지면 스플리터가 나머지 패널을 자동으로 조정해 반응형을 유지해요. 초기 패널 크기는 defaultSize로, minSize는 패널이 너무 작아지지 않게 보장해요.
동적 패널 (Dynamic Panels)
상대적 비율을 유지하면서 패널을 동적으로 추가하거나 제거할 수 있어요. 이 예시는 패널을 추가/제거할 때 패널 상태를 관리하고 크기를 재분배하는 방법을 보여줘요.
구성 (Composition)
다양한 방향의 중첩 스플리터, 접이식 패널, 통합된 코드 편집을 보여주는 실제 VS Code 유사 레이아웃이에요.
가이드 (Guides)
스플리터 컨텍스트 (Splitter Context)
스플리터를 프로그래밍 방식으로 제어해야 할 때, 두 가지 방법으로 컨텍스트와 메서드에 접근할 수 있어요.
Splitter.Context렌더 prop 사용useSplitterContext훅 사용
Splitter.Context 렌더 Prop
Splitter.Context를 렌더 prop으로 사용해 컴포넌트 트리 안에서 컨텍스트에 접근할 수 있어요.
<Splitter.Root defaultSize={[50, 50]} panels={[{ id: "a" }, { id: "b" }]}>
<Splitter.Panel id="a">Panel A</Splitter.Panel>
<Splitter.Context>
{(context) => (
<Splitter.ResizeTrigger
id="a:b"
onDoubleClick={() => {
context.resetSizes()
}}
/>
)}
</Splitter.Context>
<Splitter.Panel id="b">Panel B</Splitter.Panel>
</Splitter.Root>
useSplitterContext 훅
대안으로 자식 컴포넌트에서 useSplitterContext 훅을 사용할 수도 있어요.
import { useSplitterContext } from "@chakra-ui/react"
const ResetButton = () => {
const splitter = useSplitterContext()
return <button onClick={() => splitter.resetSizes()}>Reset Sizes</button>
}
const Demo = () => (
<Splitter.Root defaultSize={[50, 50]} panels={[{ id: "a" }, { id: "b" }]}>
<Splitter.Panel id="a">Panel A</Splitter.Panel>
<Splitter.ResizeTrigger id="a:b" />
<Splitter.Panel id="b">
<ResetButton />
</Splitter.Panel>
</Splitter.Root>
)
컨텍스트 객체(어느 방법이든)는 다음을 포함해요.
resetSizes(): 모든 패널을 기본 크기로 리셋해요setSize(sizes): 패널 크기를 프로그래밍 방식으로 설정해요collapsePanel(id): 특정 패널을 접어요expandPanel(id): 접힌 패널을 펴요isPanelCollapsed(id): 패널이 접혔는지 확인해요getItems(): 현재 아이템(패널과 핸들)을 가져와요size: 현재 패널 크기 배열이에요
Props
Splitter 컴포넌트의 Root, Panel, ResizeTrigger 파트 props에 대한 상세 정보는 공식 문서의 PropTable를 참고하세요.