Splitter
Splitter
크기 조절 가능한 분할 창 레이아웃 컴포넌트예요. use-splitter 훅 위에 구축되어 선언형 API와 Styles API 통합을 제공해요.
출처: 문서
본문
사용법 (Usage)
Splitter 컴포넌트는 크기 조절 가능한 분할 창 레이아웃을 제공해요. use-splitter 훅 위에 구축되어 선언형 API와 Styles API 통합을 제공해요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter>
<Splitter.Pane defaultSize="50%">First pane</Splitter.Pane>
<Splitter.Pane defaultSize="50%">Second pane</Splitter.Pane>
</Splitter>
);
}
orientation prop으로 분할 방향을 설정할 수 있어요.
CSS 단위 (CSS units)
Splitter.Pane의 defaultSize, min, max prop은 일반 숫자 외에 CSS 단위를 받아요.
- 일반
number또는%문자열('30%')은 유연한 크기예요. 패널이 다른 유연한 패널과 남은 공간을 나눠 가져요. px또는rem문자열('240px','15rem')은 고정 크기예요. 컨테이너가 리사이즈되어도 패널은 픽셀 크기를 유지하고, 자기 핸들을 드래그할 때만 변경돼요.
이로써 고정 너비 사이드바와 나머지 공간을 흡수하는 유동 콘텐츠 패널을 섞을 수 있어요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter>
<Splitter.Pane defaultSize="240px">Fixed 240px sidebar</Splitter.Pane>
<Splitter.Pane>Flexible content</Splitter.Pane>
</Splitter>
);
}
크기는 선언된 단위 그대로 보고돼요. '240px' 패널은 sizes/onSizeChange에서 계속 '240px'로 유지되고, 유연한 패널은 해석된 백분율을 보고해요. 컨테이너가 고정 패널 합보다 작아지면 고정 패널은 비례적으로 줄어들어요.
세로 방향 (Vertical orientation)
orientation="vertical"로 설정하면 패널을 세로로 분할해요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter orientation="vertical">
<Splitter.Pane defaultSize="50%">Top pane</Splitter.Pane>
<Splitter.Pane defaultSize="50%">Bottom pane</Splitter.Pane>
</Splitter>
);
}
접을 수 있는 패널 (Collapsible panes)
Splitter.Pane에 collapsible prop을 설정하면 패널을 최소 크기 너머로 드래그해 접을 수 있어요. splitterRef로 프로그램 방식의 접기/펼치기를 위한 명령형 API에 접근할 수 있어요.
import { useRef } from 'react';
import { Button, Group, Splitter } from '@mantine/core';
import { UseSplitterReturnValue } from '@mantine/hooks';
function Demo() {
const splitterRef = useRef<UseSplitterReturnValue>(null);
return (
<>
<Splitter size="md">
<Splitter.Pane collapsible defaultSize="30%">Collapsible sidebar</Splitter.Pane>
<Splitter.Pane defaultSize="70%">Main content</Splitter.Pane>
</Splitter>
<Group mt="md">
<Button onClick={() => splitterRef.current?.toggleCollapse(0)}>Toggle sidebar</Button>
</Group>
</>
);
}
제어 방식 (Controlled)
패널 크기를 제어하려면 sizes와 onSizeChange prop을 사용해요.
import { useState } from 'react';
import { Button, Group, Splitter, Text } from '@mantine/core';
function Demo() {
const [sizes, setSizes] = useState([50, 50]);
return (
<>
<Splitter
sizes={sizes}
onSizeChange={setSizes}
>
<Splitter.Pane>Panel A ({Math.round(sizes[0])}%)</Splitter.Pane>
<Splitter.Pane>Panel B ({Math.round(sizes[1])}%)</Splitter.Pane>
</Splitter>
<Text>Current sizes: [{sizes.map((s) => Math.round(s)).join(', ')}]</Text>
<Group mt="md">
<Button onClick={() => setSizes([30, 70])}>30 / 70</Button>
<Button onClick={() => setSizes([50, 50])}>50 / 50</Button>
<Button onClick={() => setSizes([70, 30])}>70 / 30</Button>
</Group>
</>
);
}
여러 패널 (Multiple panes)
Splitter은 어떤 수의 패널이든 지원해요. 핸들은 패널 사이에 자동으로 렌더링돼요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter>
<Splitter.Pane>First</Splitter.Pane>
<Splitter.Pane>Second</Splitter.Pane>
<Splitter.Pane>Third</Splitter.Pane>
</Splitter>
);
}
중첩 스플리터 (Nested splitters)
복잡한 레이아웃을 만들기 위해 Splitter 컴포넌트를 중첩할 수 있어요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter>
<Splitter.Pane>Sidebar</Splitter.Pane>
<Splitter.Pane>
<Splitter orientation="vertical">
<Splitter.Pane>Editor</Splitter.Pane>
<Splitter.Pane>Terminal</Splitter.Pane>
</Splitter>
</Splitter.Pane>
</Splitter>
);
}
재분배 (Redistribute)
여러 패널을 사용할 때 redistribute prop을 설정하면 인접 패널이 min/max에 도달했을 때 비인접 패널에서 공간을 어떻게 빌려올지 제어할 수 있어요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter redistribute>
<Splitter.Pane>Panel A</Splitter.Pane>
<Splitter.Pane>Panel B</Splitter.Pane>
<Splitter.Pane>Panel C</Splitter.Pane>
<Splitter.Pane>Panel D</Splitter.Pane>
</Splitter>
);
}
선 크기 (Line size)
lineSize prop으로 패널 사이의 구분선 두께를 제어할 수 있어요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter lineSize={4}>
<Splitter.Pane>First pane</Splitter.Pane>
<Splitter.Pane>Second pane</Splitter.Pane>
</Splitter>
);
}
핸들 없이 (Without handle)
withHandle={false}로 설정하면 그립 아이콘이 있는 썸을 숨길 수 있어요. 패널 사이의 구분선은 여전히 보이고 드래그할 수 있어요.
import { Splitter } from '@mantine/core';
function Demo() {
return (
<Splitter withHandle={false}>
<Splitter.Pane>First pane</Splitter.Pane>
<Splitter.Pane>Second pane</Splitter.Pane>
</Splitter>
);
}
명령형 API (Imperative API)
splitterRef prop으로 명령형 스플리터 API에 접근할 수 있어요.
import { useRef } from 'react';
import { Splitter } from '@mantine/core';
import { UseSplitterReturnValue } from '@mantine/hooks';
function Demo() {
const splitterRef = useRef<UseSplitterReturnValue>(null);
return (
<>
<Button onClick={() => splitterRef.current?.collapse(0)}>Collapse first pane</Button>
<Splitter splitterRef={splitterRef}>
<Splitter.Pane>First pane</Splitter.Pane>
<Splitter.Pane>Second pane</Splitter.Pane>
</Splitter>
</>
);
}
Splitter.Pane 감싸기 (Wrap Splitter.Pane)
Splitter 컴포넌트는 Splitter.Pane의 순서에 의존해요. Splitter.Pane을 감싸는 것은 지원되지 않아요. Splitter.Pane은 반드시 Splitter의 직접 자식이어야 해요.
import { Splitter } from '@mantine/core';
// This will not work – wrapped pane will not be recognized
function WillNotWork() {
return (
<Splitter>
<PaneWrapper>This part will not render correctly</PaneWrapper>
</Splitter>
);
}
// Create a separate component for pane content instead
function PaneContent() {
return <div>This will work as expected!</div>;
}
function Demo() {
return (
<Splitter>
<Splitter.Pane>
{/* Do not wrap Splitter.Pane in another component */}
<PaneContent />
</Splitter.Pane>
<Splitter.Pane>First pane</Splitter.Pane>
</Splitter>
);
}
use-splitter 훅
Splitter 컴포넌트는 use-splitter 훅 위에 구축돼요. 레이아웃과 스타일링을 더 제어해야 한다면 훅을 직접 사용할 수 있어요.