Components

Drawer

사용 예시

좁은 화면의 메뉴

항목을 DrawerClose로 감싸면 고를 때 Drawer가 닫혀요. 동작 줄이기를 켠 기기에서는 옆으로 움직이지 않고 제자리에서 나타나요.

tsx
<Drawer>  <DrawerTrigger render={<Button color="neutral" emphasis="outline" />}>    <Menu />    메뉴  </DrawerTrigger>  <DrawerContent>    <DrawerHeader closable>      <DrawerTitle>메뉴</DrawerTitle>    </DrawerHeader>    <div className="flex flex-col gap-tight">      {items.map(item => (        <DrawerClose key={item} render={<Button color="neutral" emphasis="ghost" className="justify-start" />}>          {item}        </DrawerClose>      ))}    </div>  </DrawerContent></Drawer>

오른쪽에서 여는 장바구니

장바구니 같은 보조 내용은 오른쪽에서 열어요. 왼쪽에서 여는 메뉴와 구분돼요.

tsx
<Drawer side="right">  <DrawerTrigger render={<Button color="neutral" emphasis="outline" />}>    <ShoppingCart />    장바구니  </DrawerTrigger>  <DrawerContent>    <DrawerHeader closable>      <DrawerTitle>장바구니</DrawerTitle>      <DrawerDescription>사기 전에 담아 둔 상품이에요.</DrawerDescription>    </DrawerHeader>    <Table label="장바구니에 담은 상품">      <TableHeader>        <TableHeadCell>품목</TableHeadCell>        <TableHeadCell>고른 치수</TableHeadCell>      </TableHeader>      <TableBody>        {cart.map(row => (          <TableRow key={row.name}>            <TableCell>{row.name}</TableCell>            <TableCell>{row.size}</TableCell>          </TableRow>        ))}      </TableBody>    </Table>  </DrawerContent></Drawer>

본문만 스크롤

항목을 DrawerBody에 담으면 제목과 닫기 버튼은 그대로 있고 목록만 스크롤돼요. DrawerBody가 없으면 DrawerContent 전체가 스크롤돼요.

tsx
<Drawer>  <DrawerTrigger render={<Button color="neutral" emphasis="outline" />}>    <Menu />    전체 메뉴  </DrawerTrigger>  <DrawerContent>    <DrawerHeader closable>      <DrawerTitle>전체 메뉴</DrawerTitle>    </DrawerHeader>    <DrawerBody>      <div className="flex flex-col gap-tight">        {items.map(item => (          <DrawerClose key={item} render={<Button color="neutral" emphasis="ghost" className="justify-start" />}>            {item}          </DrawerClose>        ))}      </div>    </DrawerBody>  </DrawerContent></Drawer>

푸터 버튼과 코드로 닫기

DrawerFooter는 Drawer의 아래 끝에 있어요. layout fill이면 버튼이 같은 폭으로 나뉘어요. 적용처럼 누른 뒤 닫아야 하면 open을 넘기고 호출하는 쪽에서 닫아요.

검색어: 없음

tsx
<Drawer open={open} onOpenChange={setOpen} side="right">  <DrawerTrigger render={<Button color="neutral" emphasis="outline" />}>    <Funnel />    필터  </DrawerTrigger>  <DrawerContent>    <DrawerHeader closable>      <DrawerTitle>필터</DrawerTitle>    </DrawerHeader>    <Field>      <FieldLabel>검색어</FieldLabel>      <Input value={keyword} onChange={e => setKeyword(e.target.value)} placeholder="가방" />    </Field>    <DrawerFooter layout="fill">      <Button color="neutral" emphasis="outline" onClick={() => setKeyword('')}>        초기화      </Button>      <Button color="brand" emphasis="solid" onClick={applyFilter}>        적용      </Button>    </DrawerFooter>  </DrawerContent></Drawer><p className="text-caption text-fg-muted">검색어: {applied || '없음'}</p>

겹쳐 열기

Drawer 안에서 다른 Drawer를 열면 뒤의 Drawer가 붙은 쪽으로 조금 작아지고 overlay로 어두워져요. 안쪽 Drawer는 바깥 DrawerContent 안에 둬요. 좁은 화면에서는 안쪽 Drawer가 화면 전체를 덮어요.

tsx
<Drawer>  <DrawerTrigger render={<Button color="neutral" emphasis="outline" />}>    <Menu />    메뉴  </DrawerTrigger>  <DrawerContent>    <DrawerHeader closable>      <DrawerTitle>메뉴</DrawerTitle>    </DrawerHeader>    <Drawer side="right">      <DrawerTrigger render={<Button color="neutral" emphasis="ghost" className="justify-start" />}>        <ShoppingCart />        장바구니      </DrawerTrigger>      <DrawerContent>        <DrawerHeader closable>          <DrawerTitle>장바구니</DrawerTitle>          <DrawerDescription>사기 전에 담아 둔 상품이에요.</DrawerDescription>        </DrawerHeader>      </DrawerContent>    </Drawer>  </DrawerContent></Drawer>

컨트롤

tsx
<Drawer>  <DrawerTrigger render={<Button color="neutral" emphasis="outline" />}>    <Menu />    메뉴  </DrawerTrigger>  <DrawerContent>    <DrawerHeader closable>      <DrawerTitle>메뉴</DrawerTitle>      <DrawerDescription>둘러볼 곳을 모았어요.</DrawerDescription>    </DrawerHeader>  </DrawerContent></Drawer>

명세

이름
이름값기본
Drawer
openboolean-
호출하는 쪽에서 열림 상태를 관리해요.
defaultOpenbooleanfalse
처음에 열어 둘지 정해요.
onOpenChange(open: boolean, eventDetails) => void-
열리거나 닫히면 호출돼요. 스와이프로 닫으면 eventDetails.reason이 swipe예요.
sideleft, rightleft
열리는 쪽이에요. 닫을 때도 같은 쪽으로 스와이프해요.
renderReactElement-
기본 요소 대신 그릴 요소예요. DrawerTrigger와 DrawerClose에 Button을 넘길 때 써요.
classNamestring-
모든 하위 컴포넌트에 쓸 수 있어요. 640px 이상에서 DrawerContent의 너비를 바꾸려면 sm:w-96처럼 sm:을 붙여요.
DrawerHeader
leadReactNode-
제목 앞에 보여요.
trailReactNode-
헤더 오른쪽 끝에 보여요.
closablebooleanfalse
헤더 오른쪽 끝에 닫기 버튼을 보여요. trail이 있으면 trail 다음에 와요.
closeLabelstring닫기
닫기 버튼의 접근성 이름이에요.
DrawerBody
childrenReactNode-
본문이에요. 길면 헤더와 DrawerFooter는 그대로 두고 이 안에서만 스크롤돼요.
DrawerFooter
layoutend, between, fill, grow-last, { narrow, wide }end
버튼 배치예요. end는 오른쪽에 모으고, between은 첫 버튼만 왼쪽 끝에 두고, fill은 모든 버튼을 같은 폭으로, grow-last는 마지막 버튼만 남은 폭만큼 늘려요. 640px 아래와 위를 다르게 하려면 narrow와 wide를 넘겨요.