티스토리 뷰

잡담

여전히 사이드 프로젝트를 진행 중이다! 현재는 Bottom Sheet에 대한 요구사항이 생겨서 구현해야 하는 상황이다. 그러나 Bottom Sheet을 깡으로 구현하는 것 보다는 라이브러리가 있고, 커스텀이 가능하다면 해당 라이브러리를 가져와도 좋지 않을까? 라는 생각을 하였고, React Spring Bottom Sheet이라는 훌륭한 라이브러리가 존재한다는 것을 알게 되었다.

생각보다 해당 라이브러리 사용에 대한 설명이 부족한 것 같아 추가적으로 필요한 정보들을 기록하고자 한다.

 

+ 이 글이 아니어도 공식 문서나 아래의 Github 저장소 링크를 참조할 수 있다.

react-spring-bottom-sheet/GET_STARTED.md at main · stipsan/react-spring-bottom-sheet

 

react-spring-bottom-sheet/GET_STARTED.md at main · stipsan/react-spring-bottom-sheet

Accessible ♿️, Delightful ✨, & Fast 🚀. Contribute to stipsan/react-spring-bottom-sheet development by creating an account on GitHub.

github.com


설치

현재 사용하고 있는 패키지 매니저에 따라서 해당 라이브러리를 설치해주자.

npm install react-spring-bottom-sheet
yarn add react-spring-bottom-sheet

사용 설명

인터페이스 확인해보기

children과 boolean 타입의 프로퍼티는 필수적으로 요구로 한다. 그 외 나머지 프로퍼티는 옵셔널하게 허용하고 있는데, 하나씩 살펴보도록 하자.

import React from 'react';
import type { RefHandles, SpringEvent } from './types';
export type { RefHandles as BottomSheetRef, Props as BottomSheetProps, } from './types';
export declare const BottomSheet: React.ForwardRefExoticComponent<{
    children: React.ReactNode;
    sibling?: React.ReactNode;
    onSpringStart?: (event: SpringEvent) => void;
    onSpringCancel?: (event: SpringEvent) => void;
    onSpringEnd?: (event: SpringEvent) => void;
    open: boolean;
    className?: string;
    footer?: React.ReactNode;
    header?: React.ReactNode;
    initialFocusRef?: false | React.RefObject<HTMLElement>;
    onDismiss?: () => void;
    blocking?: boolean;
    maxHeight?: number;
    scrollLocking?: boolean;
    snapPoints?: import("./types").snapPoints;
    defaultSnap?: number | ((props: import("./types").defaultSnapProps) => number);
    reserveScrollBarGap?: boolean;
    skipInitialTransition?: boolean;
    expandOnContentDrag?: boolean;
} & Omit<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>>, "children"> & React.RefAttributes<RefHandles>>;

기본 코드

import { useState } from 'react'
import { BottomSheet } from 'react-spring-bottom-sheet'
import 'react-spring-bottom-sheet/dist/style.css'

export default function Example() {
  const [open, setOpen] = useState(false)
  return (
    <>
      <button onClick={() => setOpen(true)}>Open</button>
      <BottomSheet open={open}>My awesome content here</BottomSheet>
    </>
  )
}

 

해당 예제 코드를 통해 기초적인 사용방법을 익혀보자.

우선, 설치된 패키지에서 BottomSheet를 import 해온다. 그리고 BottomSheet에 open에 true/false의 값을 내려주어 Bottom Sheet의 열리고 닫힘을 제어할 수 있다.

 

onDismiss

ESC 키를 누르거나, 배경을 탭하거나, 바텀시트를 아래로 스와이프 했을 경우 할당한 콜백함수가 호출된다. 이를 통해 바텀시트를 닫히도록 제어할 수 있다. (위 코드에서는 setOpen(false)를 넘겨주는 코드를 추가하면 된다.)

snapPoints

'snapPoints는 BottomSheet의 최소 높이, 최대 높이를 정할 수 있는 기능이다.' 고 설명을 많이 하시는데, 구체적으로는 바텀 시트가 멈출 높이를 설정하는 것이다. 아래 코드와 같이 배열 안에 스탑 포인트를 삼을 값을 하나씩 넣어주면 된다.

<BottomSheet 
  open={open} 
  snapPoints={({ maxHeight }) => [maxHeight * 0.3, maxHeight * 0.6, maxHeight]}
>
  <p>다양한 높이 설정 가능</p>
</BottomSheet>

maxHeight은 스크롤 할 수 있는 박스 높이에 해당하고, maxHeight는 기본 값이 100dvh이므로 이를 참고해서 조정해주면 된다.

위와 같이 배열 안에 최소 높이와 최대 높이를 순차적으로 넣어주면 된다.

defaultSnap

defualtSnap은 기본적인 박스 높이를 지정하는 속성이다.

<BottomSheet 
  open={open} 
  defaultSnap={({ maxHeight }) => maxHeight * 0.6}
>
  <p>기본 높이를 60%로 설정</p>
</BottomSheet>

blocking

blocking은 외부로 탭 이동을 차단하여 배경 밖으로 나가지 못 하도록 만든다.

<BottomSheet open={open} blocking={false}>
  <p>외부 클릭 시 닫히지 않음</p>
</BottomSheet>

expandOnContentDrag

위로 드래그 했을 경우 바텀시트가 확장 될 수 있게끔 한다.

<BottomSheet open={open} expandOnContentDrag>
  <p>내용을 위로 드래그하면 확장됨</p>
</BottomSheet>

skipInitialTransition

초기에 등장하는 애니메이션의 동작을 비활성화 하는 속성이다.

<BottomSheet open={open} skipInitialTransition>
  <p>애니메이션 없이 등장</p>
</BottomSheet>

 

initialFocusRef

바텀 시트가 열릴 때 포커스를 받을 요소를 설정할 수 있다.

const inputRef = React.useRef(null);

<BottomSheet open={open} initialFocusRef={inputRef}>
  <input ref={inputRef} placeholder="자동 포커스" />
</BottomSheet>

적용 결과

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31