BottomSheet
화면 하단에서 위로 슬라이드하며 나타나는 모달 인터페이스입니다. 제스처로 드래그하여 닫을 수 있으며, 키보드가 나타나면 자동으로 위치를 조정합니다.
실제 앱에서 확인하세요
웹에서는 시트 열기·닫기와 기본 레이아웃을 확인할 수 있습니다. 네이티브 드래그 감도, 소프트 키보드 회피, SafeArea, Android 하드웨어 뒤로가기와 dismissable 우선순위는 실제 iOS·Android 앱에서 확인하세요.
Interactive exampleBottomSheet 로컬 웹 예제
예제를 선택하면 현재 저장소 소스로 만든 Expo Web 화면을 불러옵니다.
웹 미지원 또는 플랫폼 종속 기능은 실제 iOS·Android 앱에서 확인하세요.
BottomSheetOverlay 렌더러
BottomSheetOverlay는 OverlayProvider 내부에서 시트 상태, 드래그 제스처, 배경 터치, Android back 처리를 연결하는 렌더러입니다. 앱에서 직접 마운트하면 Provider가 관리하는 닫힘 콜백과 우선순위를 우회하게 되므 로 showBottomSheet()로 여세요.
기본 사용법
import { useOverlay } from '@0610studio/zs-ui';
function MyComponent() {
const { showBottomSheet } = useOverlay();
const handleOpenBottomSheet = () => {
showBottomSheet({
component: <MyBottomSheetContent />,
options: {
height: 300,
padding: 20,
},
});
};
return <Button title="BottomSheet 열기" onPress={handleOpenBottomSheet} />;
}
API 참조
showBottomSheet 함수
showBottomSheet(props: ShowBottomSheetProps): void
ShowBottomSheetProps 인터페이스
| Prop | Type | Default | Description |
|---|---|---|---|
component | React.ReactNode | Required | Bottom Sheet 내부에 표시할 컴포넌트 |
headerComponent | React.ReactNode | undefined | 상단에 표시할 헤더 컴포넌트 |
options | BottomSheetOptions | {} | Bottom Sheet 옵션 |
BottomSheetOptions 인터페이스
| Prop | Type | Default | Description |
|---|---|---|---|
dismissable | boolean | true | 배경 터치·아래로 끌기 제스처로 닫을 수 있는지 여부. false여도 hideOverlay('bottomSheet') 호출로는 닫힙니다 |
onClose | () => void | undefined | 시트가 어떤 경로(버튼·배경 터치·드래그·뒤로가기)로 닫히든 정확히 1회 호출되는 콜백 |
isBackgroundTouchClose | boolean | true | Deprecated — dismissable을 사용하세요. dismissable 미지정 시에만 참조되며, 이제 배경 터치뿐 아니라 제스처 닫힘까지 함께 제어합니다 |
marginHorizontal | number | 10 | 시트의 좌우 여백 |
marginBottom | number | 10 | 시트의 하단 여백 |
height | number | 'auto' | 300 | 시트의 높이 ('auto' 지정 시 컨텐츠 크기에 맞춤) |
maxHeight | number | 화면 높이 | 시트의 최대 높이 제한 |
padding | number | 14 | 시트 내부 패딩 |
foldableSingleScreen | boolean | false | 폴더블 디바이스에서 단일 화면 모드 사용 여부 |
type | 'floating' | 'fixed' | 'floating' | 시트 타입 (floating: 떠있는 형태, fixed: 화면 하단에 고정) |
특징
- 제스처 지원: 드래그하여 닫을 수 있습니다
- 키보드 대응: 키보드가 나타나면 자동으로 위치를 조정합니다
- 애니메이션: 부드러운 스프링 애니메이션이 적용됩니다
- 폴더블 디바이스 지원: 폴더블 디바이스에서도 올바르게 동작합니다
예제
기본 사용
import { useOverlay, ZSText, ZSPressable } from '@0610studio/zs-ui';
import { View } from 'react-native';
function MyBottomSheetContent() {
const { hideOverlay } = useOverlay();
return (
<View>
<ZSText typo="heading.2">제목</ZSText>
<ZSText typo="body.2">내용</ZSText>
<ZSPressable onPress={() => hideOverlay('bottomSheet')}>
<ZSText typo="body.2">닫기</ZSText>
</ZSPressable>
</View>
);
}
function MyComponent() {
const { showBottomSheet } = useOverlay();
const handleOpenBottomSheet = () => {
showBottomSheet({
component: <MyBottomSheetContent />,
options: {
height: 300,
},
});
};
return <Button title="BottomSheet 열기" onPress={handleOpenBottomSheet} />;
}
헤더 컴포넌트 사용
import { useOverlay, ZSText } from '@0610studio/zs-ui';
import { View } from 'react-native';
function MyComponent() {
const { showBottomSheet } = useOverlay();
const handleOpenBottomSheet = () => {
showBottomSheet({
headerComponent: (
<View style={{ padding: 20 }}>
<ZSText typo="heading.2">헤더</ZSText>
</View>
),
component: <MyBottomSheetContent />,
options: {
height: 400,
},
});
};
return <Button title="BottomSheet 열기" onPress={handleOpenBottomSheet} />;
}
Fixed 타입 (화면 하단 고정)
import { useOverlay } from '@0610studio/zs-ui';
function MyComponent() {
const { showBottomSheet } = useOverlay();
const handleOpenBottomSheet = () => {
showBottomSheet({
component: <MyBottomSheetContent />,
options: {
height: 500,
type: 'fixed',
padding: 20,
},
});
};
return <Button title="BottomSheet 열기" onPress={handleOpenBottomSheet} />;
}
커스텀 여백
import { useOverlay } from '@0610studio/zs-ui';
function MyComponent() {
const { showBottomSheet } = useOverlay();
const handleOpenBottomSheet = () => {
showBottomSheet({
component: <MyBottomSheetContent />,
options: {
height: 400,
marginHorizontal: 20,
marginBottom: 30,
padding: 30,
},
});
};
return <Button title="BottomSheet 열기" onPress={handleOpenBottomSheet} />;
}
배경 터치·제스처로 닫기 비활성화
dismissable: false를 지정하면 배경 터치와 아래로 끌기 제스처 모두 무시됩니다. 사용자가 반드시 시트 내부 동작(버튼 등)으로만 닫아야 할 때 사용하세요.
import { useOverlay } from '@0610studio/zs-ui';
function MyComponent() {
const { showBottomSheet } = useOverlay();
const handleOpenBottomSheet = () => {
showBottomSheet({
component: <MyBottomSheetContent />,
options: {
height: 300,
dismissable: false,
},
});
};
return <Button title="BottomSheet 열기" onPress={handleOpenBottomSheet} />;
}
BottomSheet 닫기
import { useOverlay, ZSPressable, ZSText } from '@0610studio/zs-ui';
import { View } from 'react-native';
function MyBottomSheetContent() {
const { hideOverlay } = useOverlay();
return (
<View>
<ZSPressable onPress={() => hideOverlay('bottomSheet')}>
<ZSText typo="body.2">닫기</ZSText>
</ZSPressable>
</View>
);
}