npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tiny-drawer-react

v1.2.0

Published

React and Next.js wrapper for tiny-drawer.

Readme

tiny-drawer-react

tiny-drawer-react is a React 18/19 and Next.js-friendly wrapper around tiny-drawer. It keeps the original drawer behavior and API surface, while letting you drive it with React props, refs, and hooks.

tiny-drawer is installed internally as a runtime dependency, so app developers only need to add tiny-drawer-react.

This 1.2.0 release adds support for the latest tiny-drawer scroll-full options object API.

Install Dependencies

npm

npm install tiny-drawer-react

yarn

yarn add tiny-drawer-react

pnpm

pnpm add tiny-drawer-react

CSS Import

Import the packaged CSS once in your app:

import "tiny-drawer-react/styles.css";

For Next.js App Router, import it in app/layout.tsx or another client-side entry that is loaded globally.

Basic Uncontrolled Example

"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 Example

"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>
    </>
  );
}

Next.js App Router

Use the wrapper from a client component:

"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>
    </>
  );
}

Imperative Ref Example

"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>
    </>
  );
}

useTinyDrawer Hook Example

"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

| Prop | Type | Default | Notes | | -------------------- | ------------------------------- | --------------- | ------------------------------------------------------------------------------------- | | open | boolean | undefined | Controlled open state. | | defaultOpen | boolean | false | Initial uncontrolled open state. | | onOpenChange | (open: boolean) => void | undefined | Called when the drawer opens or closes through user interaction or imperative APIs. | | position | DrawerPosition | vanilla default | Calls instance.setPosition() after mount when changed. | | size | DrawerSizeValue | vanilla default | Calls instance.setSize() after mount when changed. | | minSize | DrawerSizeValue | vanilla default | Passed through to tiny-drawer. | | maxSize | DrawerSizeValue | vanilla default | Passed through to tiny-drawer. | | parentContainer | string \| HTMLElement \| null | null | Optional parent mount target passed to the vanilla instance. | | themePrefix | string | undefined | Passed through. | | backdrop | boolean | undefined | Passed through. | | closeButton | boolean | undefined | Passed through. | | closeOnBackdrop | boolean | undefined | Passed through. | | outSideClickClose | boolean | undefined | Closes the drawer when clicking outside its boundary. | | closeOnEscape | boolean | undefined | Passed through. | | draggable | boolean | undefined | Passed through. | | onScrollFull | boolean \| DrawerScrollFullOptions | undefined | Enables scroll-to-full behavior and supports nested backDrop, drawer, and scrollTarget options in tiny-drawer 1.2.0. | | fullScreenGap | DrawerSizeValue | undefined | Controls the gap when the drawer expands to its full scroll state. | | animation | boolean | undefined | Passed through. | | appendToBody | boolean | undefined | Passed through. | | lastDragLocation | boolean | undefined | Passed through. | | className | string | undefined | Drawer class passed through to the vanilla instance. | | zIndex | number | undefined | Passed through. | | ariaLabel | string | undefined | Passed through. | | children | React.ReactNode | undefined | Rendered inside an internal portal-backed content element. | | container | string \| HTMLElement \| null | null | External host container. If omitted, an internal zero-footprint host div is rendered. | | containerClassName | string | undefined | Applied to the internal host div when container is omitted. | | containerStyle | React.CSSProperties | undefined | Applied to the internal host div when container is omitted. | | destroyOnUnmount | boolean | true | Controls whether the wrapper destroys the drawer during normal unmount. | | restoreFocus | boolean | true | Restores focus to the previously active element after close when possible. | | onOpen | (instance) => void | undefined | Vanilla open callback. | | onClose | (instance) => void | undefined | Vanilla close callback. | | onDragStart | (instance) => void | undefined | Vanilla drag start callback. | | onDrag | (size, instance) => void | undefined | Vanilla drag callback. | | onDragEnd | (size, instance) => void | undefined | Vanilla drag end callback. | | onDestroy | (instance) => void | undefined | Vanilla destroy callback. |

Ref API

| Method | Description | | ----------------------- | ------------------------------------------------- | | open() | Opens the drawer. | | close() | Closes the drawer. | | toggle() | Toggles the drawer. | | destroy() | Destroys the underlying vanilla instance. | | setPosition(position) | Calls instance.setPosition(position). | | setSize(size) | Calls instance.setSize(size). | | getSize() | Returns instance.getSize(). | | isOpen() | Returns instance.isOpen(). | | getInstance() | Returns the raw tiny-drawer instance or null. |

SSR and Hydration Notes

  • Importing the package is SSR-safe because it does not touch window or document during render.
  • The actual tiny-drawer instance is created only inside effects on the client.
  • For Next.js App Router, add "use client"; to components that render TinyDrawer or call useTinyDrawer.
  • React children are portaled into an internal DOM node that is handed off to tiny-drawer, so you keep React rendering without duplicating the drawer implementation.

Events and Vanilla Behavior

The wrapper uses the original TinyDrawer class from tiny-drawer, so vanilla callbacks and custom events such as tiny-drawer:open, tiny-drawer:close, and drag events are preserved.

Link Back

This package is a thin React wrapper around tiny-drawer.