Skip to content

useDrawer

The unified hook for managing drawers in React. Works in two modes based on whether a drawer key is provided.

Usage

tsx
import { useDrawer } from '@drawerly/react'

// Manager mode - full control over all drawers
const { open, close, closeAll, stack } = useDrawer()

// Instance mode - control a specific drawer
const { isOpen, close, placement, setPlacement } = useDrawer('my-drawer')

Manager Mode

When called without arguments, useDrawer() returns the full manager API:

tsx
function DrawerManager() {
  const { open, close, closeAll, stack, bringToTop } = useDrawer()

  return (
    <div>
      <p>
        Open drawers:
        {stack.length}
      </p>
      <button onClick={() => open({ drawerKey: 'demo', component: Demo })}>
        Open Demo
      </button>
      <button onClick={() => close()}>Close Top</button>
      <button onClick={closeAll}>Close All</button>
    </div>
  )
}

Manager Mode Return Value

PropertyTypeDescription
stackDrawerInstance[]Current drawer stack (last is topmost)
open(options) => DrawerKeyOpens a drawer or moves existing to top
close(key?) => voidCloses top drawer or specific drawer by key
closeAll() => voidCloses all open drawers
bringToTop(key) => voidMoves a drawer to the top of the stack
updateOptions(key, updater) => voidUpdates drawer options
getState() => DrawerStateReturns current state snapshot
getDrawerInstance(key) => DrawerInstance?Returns a drawer by key

Instance Mode

When called with a drawer key, useDrawer(key) returns reactive state and controls for that specific drawer:

tsx
function DrawerControls({ drawerKey }: { drawerKey: string }) {
  const {
    isOpen,
    placement,
    setPlacement,
    close,
    bringToTop,
  } = useDrawer(drawerKey)

  if (!isOpen)
    return <p>Drawer is closed</p>

  return (
    <div>
      <p>
        Placement:
        {placement}
      </p>
      <button onClick={close}>Close</button>
      <button onClick={() => setPlacement('left')}>Move Left</button>
      <button onClick={bringToTop}>Bring to Top</button>
    </div>
  )
}

Instance Mode Return Value

PropertyTypeDescription
isOpenbooleanWhether the drawer is in the stack
placementDrawerPlacementCurrent placement ('right', 'left', 'top', 'bottom')
closeOnEscapeKeybooleanWhether Escape closes the drawer
closeOnBackdropClickbooleanWhether backdrop click closes the drawer
optionsobjectAll current options (excluding component/render)
close() => voidCloses this drawer
bringToTop() => voidMoves this drawer to top
setPlacement(placement) => voidUpdates placement
setCloseOnEscapeKey(value) => voidUpdates escape key behavior
setCloseOnBackdropClick(value) => voidUpdates backdrop click behavior
updateOptions(updater) => voidUpdates any options

Opening Drawers

With a Component

tsx
open({
  drawerKey: 'user-profile',
  component: UserProfile,
  componentProps: {
    userId: '123',
  },
})

The component receives drawerKey and close automatically:

tsx
interface UserProfileProps extends ReactDrawerContentProps {
  userId: string
}

function UserProfile({ userId, drawerKey, close }: UserProfileProps) {
  return (
    <div>
      <h2>
        User
        {userId}
      </h2>
      <button onClick={close}>Close</button>
    </div>
  )
}

With a Render Function

tsx
open({
  drawerKey: 'quick-info',
  render: ({ drawerKey, close }) => (
    <div>
      <p>
        Drawer:
        {drawerKey}
      </p>
      <button onClick={close}>Close</button>
    </div>
  ),
})

Drawer Options

OptionTypeDefaultDescription
drawerKeystringrequiredUnique identifier for the drawer
componentComponentTypeReact component to render
componentPropsobjectProps passed to the component
render(props) => ReactNodeRender function (takes precedence over component)
placement'right' | 'left' | 'top' | 'bottom''right'Drawer position
closeOnEscapeKeybooleantrueClose on Escape key press
closeOnBackdropClickbooleantrueClose on backdrop click
ariaLabelstringAccessibility label
ariaLabelledBystringID of labelling element
ariaDescribedBystringID of describing element

Released under the MIT License.