Skip to Content
HooksuseDisclosure

useDisclosure

useDisclosure manages boolean open state for UI such as dialogs, popovers, accordions, and details panels.

Live Example

Disclosure controls

This demo shows one uncontrolled disclosure and one controlled panel using the same action API.

Disclosure state

Account controls

Panel Closed

Uncontrolled section

Billing details

Annual plan, card ending in 4242, renewal on May 18.

Controlled panel

Security review

Parent state: false

Import

import { useDisclosure } from "react-rsc-kit/client";

Signature

const { isOpen, open, close, toggle, setOpen } = useDisclosure({ open, defaultOpen, onOpen, onClose, onChange, });

Parameters

NameTypeDefaultDescription
openbooleanundefinedControlled open state. The hook is controlled when this is not undefined.
defaultOpenbooleanfalseInitial uncontrolled open state. Later changes to defaultOpen are ignored.
onOpen() => voidundefinedCalled when the disclosure transitions from closed to open.
onClose() => voidundefinedCalled when the disclosure transitions from open to closed.
onChange(open: boolean) => voidundefinedCalled when the disclosure open state changes.

Returns

KeyDescription
isOpenControlled open when controlled, otherwise internal state.
openOpens the disclosure.
closeCloses the disclosure.
toggleFlips the disclosure state.
setOpenSets the disclosure state to a specific boolean value.

Controlled Dialog

"use client"; import { useDisclosure } from "react-rsc-kit/client"; interface DialogProps { open: boolean; onOpenChange: (open: boolean) => void; } export function Dialog({ open, onOpenChange }: DialogProps) { const disclosure = useDisclosure({ open, onChange: onOpenChange, }); return ( <section hidden={!disclosure.isOpen}> <button type="button" onClick={disclosure.close}> Close </button> </section> ); }

Uncontrolled Details

"use client"; import { useDisclosure } from "react-rsc-kit/client"; export function DetailsPanel() { const disclosure = useDisclosure({ defaultOpen: true, }); return ( <section> <button type="button" aria-expanded={disclosure.isOpen} onClick={disclosure.toggle}> {disclosure.isOpen ? "Hide details" : "Show details"} </button> {disclosure.isOpen ? <p>Plan details and account limits.</p> : null} </section> ); }

Notes

  • The hook is controlled when open !== undefined; undefined intentionally means “uncontrolled”.
  • defaultOpen is read only for uncontrolled initialization.
  • open, close, toggle, and setOpen are stable callbacks.
  • onOpen, onClose, and onChange run only when the requested state differs from the current state.
Last updated on