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

@buildkitgg/react-modals

v1.0.1

Published

React modal management with typed state and results, external calls, and pluggable UI adapters.

Readme

@buildkitgg/react-modals

React subscriptions, typed modal definitions, and shared confirm/alert helpers.

pnpm add @buildkitgg/react-modals react
import { createModalManager, ModalRenderer } from "@buildkitgg/react-modals"

export const modals = createModalManager({ adapter: { Surface: YourSurface } })
// Mount once: <ModalRenderer manager={modals} />
const confirmed = await modals.confirm({ title: "Delete draft?" })
// Use a UI adapter unless you need a custom renderer.

Mount one renderer per manager. Calls can originate outside React. Components receive data, controls, isPending and error. Custom result types require a defaultResult for cancellation. The host clears pending modals on actual unmount and tolerates StrictMode reconnects. A custom surface owns accessibility and calls finishExit. The adapter is selected once per manager. A headless manager may omit it, but rendering requires one. The shadcn and Fluent packages provide defaults; they share this manager and renderer implementation.

API

  • createModalManager({ labels?, adapter? }): open, alert, confirm and createModal.
  • createModal({ initialState, body, defaultResult, ...options }): inferred state, partial opening overrides and typed results.
  • controls.update(patch | updater): update presentation and custom state together, with state patches under data. Functional updaters receive the current presentation and current.data.
  • controls.submit(action): one pending action, typed success result and retryable errors.
  • beforeDismiss(data): optional asynchronous cancellation guard.
  • useModals(manager): reactive snapshot without a context provider.
  • ModalRenderer: one host, nested rendering and unmount cleanup.
  • ModalAdapter<TSurface>: a surface component receiving entry, title, body, footer and nested children.
  • ModalManagerOptions<TSurface> and ModalSurfaceOptions: shared defaults for UI adapters. Surface options contain className and style; custom React surfaces may supply their own generic type.

Update an open modal

Keep the handle before awaiting its result. Standard modals patch their opening options:

const modal = modals.open({ title: "Loading" })
modal.update({ title: "Ready", body: "Your results are available." })
await modal

Custom definitions use the same method, with custom state under data:

const modal = editProfile.open()
modal.update({ title: "Edit Grace's profile", data: { name: "Grace" } })
modal.update(({ data }) => ({ data: { step: data.step + 1 } }))

Here editProfile is a definition with name and step in its initial state. The component's controls.update() works identically. Presentation and data each merge shallowly, together in one notification. Each opening has independent values. Closed handles ignore updates; IDs are fixed. All slots accept nodes or { component: Component }. Custom footers own their buttons. onClose({ id, result, reason }) observes settlement and can be replaced with update().

See update examples, lifecycle and architecture and package guide.