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

@nobertdev/react-confirm-dialog

v1.1.6

Published

A lightweight async confirmation dialog hook for React that replaces window.confirm() with customizable modals.

Readme

@nobertdev/react-confirm-dialog

A lightweight, fully customizable confirmation dialog hook — useConfirm() — that replaces window.confirm() with beautiful async modals.

Zero runtime dependencies. ~2KB gzipped. Full TypeScript support. Auto dark mode.

📺 Live Demo · 📖 Documentation · 💻 GitHub


Features

  • ✅ Drop-in async replacement for window.confirm()
  • 🎨 Four built-in variants: default, danger, warning, success
  • 🌗 Auto dark mode — adapts to prefers-color-scheme automatically
  • 🧩 Fully customizable via props, classNames, styles, or renderDialog
  • ⌨️ Keyboard accessible (Escape to cancel, auto-focus confirm)
  • 🖱️ Click outside to dismiss
  • 💨 Smooth enter/exit animations
  • 🔒 Zero runtime dependencies
  • 📦 ~2KB gzipped
  • 🏗️ Tree-shakeable ESM + CJS builds
  • 🔷 Full TypeScript types

Installation

npm install @nobertdev/react-confirm-dialog
# or
yarn add @nobertdev/react-confirm-dialog
# or
pnpm add @nobertdev/react-confirm-dialog

Quick Start

1. Wrap your app with the provider:

// main.tsx / _app.tsx
import { ConfirmDialogProvider } from "@nobertdev/react-confirm-dialog";

function App() {
  return (
    <ConfirmDialogProvider>
      <YourApp />
    </ConfirmDialogProvider>
  );
}

2. Use useConfirm() anywhere in your tree:

import { useConfirm } from "@nobertdev/react-confirm-dialog";

function DeleteButton() {
  const confirm = useConfirm();

  const handleDelete = async () => {
    const ok = await confirm({
      title: "Delete this item?",
      message: "This action cannot be undone.",
      variant: "danger",
      confirmText: "Delete",
    });

    if (ok) {
      // user clicked Confirm
      await deleteItem();
    }
  };

  return <button onClick={handleDelete}>Delete</button>;
}

API

<ConfirmDialogProvider>

| Prop | Type | Description | | ---------------- | ----------------------------------------- | --------------------------------------- | | defaultOptions | ConfirmOptions | Default options merged into every call | | classNames | object | Custom CSS class names for each element | | styles | object | Inline style overrides for each element | | renderDialog | (props: RenderDialogProps) => ReactNode | Fully replace the built-in dialog |

useConfirm()

Returns a confirm function:

const confirm = useConfirm();

// Simple string message
const ok = await confirm("Are you sure?");

// Full options object
const ok = await confirm({
  title: "Permanently delete?",
  message: "This cannot be undone.",
  confirmText: "Yes, delete it",
  cancelText: "Never mind",
  variant: "danger",            // "default" | "danger" | "warning" | "success"
  icon: <MyIcon />,             // custom React node
});

Returns Promise<boolean>true if confirmed, false if cancelled.

ConfirmOptions

| Prop | Type | Default | Description | | ------------- | ------------------------------------------------- | ----------------- | -------------------- | | title | string | "Are you sure?" | Dialog heading | | message | string | — | Body text | | confirmText | string | "Confirm" | Confirm button label | | cancelText | string | "Cancel" | Cancel button label | | variant | "default" \| "danger" \| "warning" \| "success" | "default" | Visual variant | | icon | ReactNode | built-in SVG | Custom icon |


Variants

// Default (dark)
await confirm({ title: "Proceed?" });

// Danger (red) — for destructive actions
await confirm({ title: "Delete account?", variant: "danger" });

// Warning (amber) — for cautionary actions
await confirm({ title: "Archive project?", variant: "warning" });

// Success (green) — for confirmatory actions
await confirm({ title: "Publish post?", variant: "success" });

Styling

Via classNames

<ConfirmDialogProvider
  classNames={{
    overlay: "my-overlay",
    dialog: "my-dialog",
    title: "my-title",
    confirmButton: "my-confirm-btn",
    cancelButton: "my-cancel-btn",
  }}
>

Via styles

<ConfirmDialogProvider
  styles={{
    dialog: { borderRadius: "4px", fontFamily: "monospace" },
    confirmButton: { background: "hotpink", borderRadius: "2px" },
  }}
>

Via renderDialog (fully custom)

<ConfirmDialogProvider
  renderDialog={({ isOpen, options, onConfirm, onCancel }) => (
    <MyCustomModal
      open={isOpen}
      title={options.title}
      onConfirm={onConfirm}
      onCancel={onCancel}
    />
  )}
>

Global Defaults

<ConfirmDialogProvider
  defaultOptions={{
    confirmText: "Yes",
    cancelText: "No",
    variant: "danger",
  }}
>

Dark Mode

The built-in dialog automatically adapts to the user's system color scheme via prefers-color-scheme: dark. No configuration needed — it just works.

  • Light mode: White dialog, light icon backgrounds, subtle shadows
  • Dark mode: Dark gray dialog, muted icon backgrounds, deeper shadows

If you use renderDialog or custom styles, you have full control over theming.


SSR / Next.js

Works with SSR out of the box. The portal is only created on the client.


TypeScript

All types are exported:

import type {
  ConfirmOptions,
  ConfirmDialogProviderProps,
  RenderDialogProps,
} from "@nobertdev/react-confirm-dialog";

License

MIT