Tiny/Drawer

Integration

React package: tiny-drawer-react

Use tiny-drawer-react when you want a React 18 or 19 wrapper with props, controlled state, refs, hooks, and Next.js-friendly client-side behavior.

What the wrapper adds

tiny-drawer-react wraps the vanilla package and lets you drive the same drawer runtime with React props, children, refs, and the useTinyDrawer()hook. In 1.2.0, it also forwards the object-based scroll-full API from the core package and nests scrollTarget inside onScrollFull.

CSS import

Import the packaged stylesheet once at a global entry point in your app.

app/layout.tsx
import "tiny-drawer-react/styles.css";

Basic uncontrolled usage

Use defaultOpen when the drawer manages its own state after the initial render.

"use client";

import { TinyDrawer } from "tiny-drawer-react";
import "tiny-drawer-react/styles.css";

export default function DrawerDemo() {
  return (
    <TinyDrawer defaultOpen position="right" size="360px" draggable>
      <div>
        <h2>Drawer Title</h2>
        <p>This content is rendered with React children.</p>
      </div>
    </TinyDrawer>
  );
}

Controlled usage

Pass open and onOpenChange when the parent component should own the drawer state.

"use client";

import { useState } from "react";
import { TinyDrawer } from "tiny-drawer-react";
import "tiny-drawer-react/styles.css";

export default function DrawerDemo() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button onClick={() => setOpen(true)}>Open drawer</button>

      <TinyDrawer
        open={open}
        onOpenChange={setOpen}
        position="bottom"
        size="40%"
        minSize="20%"
        maxSize="90%"
        draggable
        appendToBody
      >
        <div>
          <h2>Drawer Title</h2>
          <p>This is rendered with React children.</p>
          <button onClick={() => setOpen(false)}>Close</button>
        </div>
      </TinyDrawer>
    </>
  );
}

Stable onScrollFull config

When you pass onScrollFull as an inline object, React creates a new object on every render. On pages with frequent state updates or layout changes, that can cause the drawer to re-apply scroll-full behavior and appear to flicker.

To avoid that, keep the config reference stable by declaring it outside the component or memoizing it with useMemo(). This is especially helpful when using appendToBody and a custom scrollTarget.

"use client";

import { useState } from "react";
import { TinyDrawer } from "tiny-drawer-react";
import "tiny-drawer-react/styles.css";

const ONSCROLLFULLCONFIGRATION = {
  backDrop: true,
  drawer: false,
  scrollTarget: ".custom-selector",
};

export default function DrawerDemo() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button onClick={() => setOpen(true)}>Open drawer</button>

      <TinyDrawer
        open={open}
        onOpenChange={setOpen}
        position="bottom"
        size="40%"
        minSize="20%"
        maxSize="90%"
        draggable
        appendToBody
        onScrollFull={ONSCROLLFULLCONFIGRATION}
      >
        <div>
          <h2>Drawer Title</h2>
          <p>This is rendered with React children.</p>
          <button onClick={() => setOpen(false)}>Close</button>
        </div>
      </TinyDrawer>
    </>
  );
}

Imperative ref API

The wrapper exposes methods such as open(), close(), toggle(), destroy(), setPosition(), setSize(), getSize(), isOpen(), and getInstance() through the forwarded ref.

"use client";

import { useRef } from "react";
import { TinyDrawer, type TinyDrawerRef } from "tiny-drawer-react";
import "tiny-drawer-react/styles.css";

export default function DrawerWithRef() {
  const drawerRef = useRef<TinyDrawerRef>(null);

  return (
    <>
      <button onClick={() => drawerRef.current?.open()}>Open</button>
      <button onClick={() => drawerRef.current?.close()}>Close</button>

      <TinyDrawer ref={drawerRef} position="left" size="320px">
        <div>Imperative drawer content</div>
      </TinyDrawer>
    </>
  );
}

Hook usage

Use useTinyDrawer() when you want a small hook that returns a container ref plus imperative open and close handlers.

"use client";

import { useTinyDrawer } from "tiny-drawer-react";
import "tiny-drawer-react/styles.css";

export default function HookExample() {
  const drawer = useTinyDrawer({
    position: "bottom",
    size: "40%",
    defaultOpen: false,
    content: "<div>Hook-driven drawer content</div>",
  });

  return (
    <>
      <div ref={drawer.containerRef} />
      <button onClick={drawer.open}>Open</button>
      <button onClick={drawer.close}>Close</button>
    </>
  );
}

Props surface

The wrapper forwards the core drawer options such as position, size, minSize, maxSize, draggable, appendToBody, outSideClickClose, onScrollFull, and fullScreenGap, while also adding React-specific props likechildren, container, containerClassName, destroyOnUnmount, and restoreFocus.

outSideClickClose

Brings the new boundary-aware outside click behavior into the React component API.

onScrollFull

Accepts true or an object like { backDrop: true, drawer: false, scrollTarget: ".custom-selector" } in 1.2.0. Keep the object reference stable in React when the page re-renders often.

fullScreenGap

Preserves space from the opposite edge while the drawer expands to full size.

scrollTarget

Moved into onScrollFull.scrollTarget in 1.2.0 instead of being passed as a top-level prop.

The full prop reference, including controlled state props and lifecycle callbacks, is documented on the Features & Props page.