Skip to content

useDrawer

useDrawer(drawerly, key) binds a component to a single drawer. Where useDrawerly exposes the whole stack, useDrawer binds to one key and gives you its state and controls directly:

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

export function SettingsStatus() {
  const { isOpen, isTop, close } = useDrawer(drawerly, 'settings')

  if (!isOpen)
    return null

  return (
    <span className={isTop ? 'top' : ''}>
      Settings is open
      <button onClick={close}>Close</button>
    </span>
  )
}

Drawers are created with drawerly.open(). Reach for useDrawer once you have a key and want to read or adjust that specific drawer, most commonly from inside the drawer's own content component.

Reactive Values

isOpen tracks whether the drawer is in the stack, and isTop whether it is the topmost one. Both update automatically:

tsx
export function FocusSettingsButton() {
  const { isOpen, isTop, bringToTop } = useDrawer(drawerly, 'settings')

  if (!isOpen || isTop)
    return null

  return (
    <button onClick={bringToTop}>
      Focus Settings
    </button>
  )
}

instance exposes the full drawer instance, including any custom fields, and is undefined while the drawer is closed:

ts
const { instance } = useDrawer(drawerly, 'product-detail')

console.log(instance?.placement)

Updating Options

updateOptions merges a patch into the drawer:

ts
const { updateOptions } = useDrawer(drawerly, 'form')

updateOptions({ closeOnEscapeKey: false })

To compute a patch from the current value, read it off instance first:

ts
const { instance, updateOptions } = useDrawer(drawerly, 'product-detail')

updateOptions({ price: (instance?.price ?? 0) * 0.9 })

Closing Yourself

The most common use of useDrawer is inside the drawer's own content component, closing itself with the drawerKey prop the container passes in:

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

interface UserProfileProps {
  drawerKey: string
  userId: string
}

export function UserProfile({ drawerKey, userId }: UserProfileProps) {
  const { close } = useDrawer(drawerly, drawerKey)

  return (
    <div>
      <button onClick={close}>Close</button>
      <p>{`User ID: ${userId}`}</p>
    </div>
  )
}

Dynamic Keys

The key is an ordinary argument, so a computed key rebinds everything on the next render:

ts
const { isOpen, close } = useDrawer(drawerly, `user-profile-${userId}`)
// changing userId rebinds everything to the new key

Typed Drawer Options

Like useDrawerly, a generic types the custom fields:

ts
const { instance, updateOptions } = useDrawer<ProductDrawerOptions>(drawerly, 'product-drawer')

console.log(instance?.price)
updateOptions({ price: 899.99 })

Released under the MIT License.