Dropdown
Dropdown
은 뷰포트에 따라 PC에서는 드롭다운, 모바일에서는 바텀 시트로 등장하는 컴포넌트입니다.
How to use
import { Dropdown } from '@vibrant-ui/components';
Properties
Prop | Type | Default | Description |
---|---|---|---|
open | boolean | 열림 상태를 제어합니다. | |
defaultOpen | boolean | false | 초기 열림 상태를 설정합니다. |
renderOpener | (_: { open: () => void; isOpen: boolean, ref: RefObject }) => ReactElementChild | open 함수를 이용하여 오프너 요소를 설정합니다. | |
position | bottom | left | right | top | bottom-end | bottom-start | left-end | left-start | right-end | right-start | top-end | top-start | bottom | 드랍다운이 열리는 위치를 설정합니다. |
spacing | number | 8 | 드랍다운과 오프너 요소 사이의 간격을 설정합니다. |
renderContents | (_: { close: () => void }) => ReactElementChild | 내부 컨텐츠를 설정합니다. | |
onClose | () => void | 컨텐츠 바깥 영역이 클릭되거나 닫기 버튼이 클릭됐을 때 호출됩니다. |
Usage
제어
open
속성을 통해 열림 상태를 제어합니다.
const Controlled = () => {
const [open, setOpen] = useState(false);
return (
<>
<Pressable onClick={() => setOpen(true)}>
열기
</Pressable>
<Dropdown
open={open}
onClose={() => setOpen(false)}
renderContents={() => (
<VStack spacing={20}>
<Body level={2} px={20}>
메뉴 1
</Body>
<Body level={2} px={20}>
메뉴 2
</Body>
</VStack>
)}
/>
</>
);
};
비제어
defaultOpen
속성을 통해 초기 열림 상태만 지정하고 이후의 상태는 Dropdown
컴포넌트 내부에서 관리됩니다.
render prop인 renderOpener
속성으로 Dropdown
을 열리게 하는 요소를 지정할 수 있으며 전달인자로 Dropdown
을 열린 상태로 변경하는 함수 open
와 현재 열림 상태를 나타내는 isOpen
프로퍼티를 가진 객체를 제공합니다.
const Uncontrolled = () => (
<Dropdown
defaultOpen={false}
renderOpener={({ open }) => (
<Pressable onClick={open}>열기</Pressable>
)}
renderContents={() => (
<VStack spacing={20}>
<Body level={2} px={20}>
메뉴 1
</Body>
<Body level={2} px={20}>
메뉴 2
</Body>
</VStack>
)}
/>
);
오프너
renderOpener
렌더 속성을 통해 드랍다운을 열기 위한 오프너 요소를 설정할 수 있습니다. 인자로 전달 받은 open
함수를 사용해서 원하는 요소의 이벤트 핸들러로 등록하여 드랍다운을 열도록 설정할 수 있으며, 드랍다운은 오프너 요소를 감싸는 컨테이너를 기준으로 위치가 설정됩니다.
만약 오프너를 감싸는 컨테이너가 아닌 특정 요소를 기준으로 드랍다운이 위치하길 원하는 경우에는 인자로 전달받은 ref
로 원하는 요소에 등록합니다.
<HStack mx="auto" spacing={24}>
<Dropdown
position="top-end"
renderOpener={({ ref, open }) => (
// 드랍다운은 Pressable을 감싸는 컨테이너 기준으로 위치하게 됩니다
<Pressable onClick={open}>열기</Pressable>
)}
renderContents={() => (
<Body level={2} px={20}>
컨텐츠
</Body>
)}
/>
<Dropdown
position="top-end"
renderOpener={({ ref, open }) => (
<>
<Pressable onClick={open}>열기</Pressable>
<Box
// ref를 사용한 경우 드랍다운은 이 Box를 기준으로 위치하게 됩니다
ref={ref}
position="fixed"
bottom={0}
width={50}
height={50}
borderRadius={25}
backgroundColor="surface2"
elevationLevel={1}
/>
</>
)}
renderContents={() => (
<Body level={2} px={20}>
컨텐츠
</Body>
)}
/>
</HStack>
위치
드랍다운의 위치는 position
속성을 통해 bottom
, left
,right
, top
, bottom-end
, bottom-start
, left-end
, left-start
, right-end
, right-start
, top-end
, top-start
로 설정할 수 있습니다.
컨텐츠
다양한 콘텐츠가 담길 수 있으며, 콘텐츠의 깊이(depth)가 변하는 경우에도 닫히지 않고 동일한 컨테이너를 유지한 채 높이가 변화합니다. 메뉴나 필터의 옵션으로 사용될 수 있으며 이 외에도 다양한 패턴으로 사용될 수 있습니다.
BackHandler (Android only)
뷰포트에 따라 모바일에서는 바텀 시트로 동작하여, Android 에선 바텀 시트와 같은 방식으로
뒤로 가기
시스템 버튼을 클릭 시에 모달이 닫히게 됩니다.