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

@hensley-ui/react-simple-dialog

v0.1.1

Published

> Simple and intuitive Promise-based dialog component

Readme

@hensley-ui/react-simple-dialog

Simple and intuitive Promise-based dialog component

A React dialog library that significantly improves upon ShadCN Dialog's convenience. Implement user confirmation dialogs with simple function calls without complex state management.

🌏 Language

🚀 Key Features

  • Promise-based API: Handle user responses intuitively with await keyword
  • Imperative Approach: Execute dialogs with simple function calls
  • Dynamic Content: Freely configure titles, descriptions, button texts at runtime
  • Automated State Management: All state management handled internally
  • Korean Support: Built-in Korean button labels ("확인", "취소")
  • Full TypeScript Support: Type safety guaranteed

📦 Installation

npm install @hensley-ui/react-simple-dialog
# or
pnpm add @hensley-ui/react-simple-dialog

🎯 Comparison with ShadCN Dialog

❌ Problems with ShadCN Dialog

// Complex declarative structure
const [isOpen, setIsOpen] = useState(false)
const [title, setTitle] = useState("")
const [description, setDescription] = useState("")

const handleDelete = async () => {
  // Need to update states
  setTitle("Delete Confirmation")
  setDescription("Are you sure you want to delete?")
  setIsOpen(true)
  
  // Complex user response handling
  // Separate onConfirm, onCancel handlers needed
}

return (
  <>
    <Button onClick={handleDelete}>Delete</Button>
    
    {/* Must declare entire dialog structure in JSX */}
    <Dialog open={isOpen} onOpenChange={setIsOpen}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <Button variant="secondary" onClick={() => setIsOpen(false)}>
            Cancel
          </Button>
          <Button onClick={() => {
            // Actual delete logic
            setIsOpen(false)
          }}>
            Confirm
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  </>
)

✅ SimpleDialog's Convenience

// Simple and intuitive imperative API
const openDialog = useSimpleDialog()

const handleDelete = async () => {
  const confirmed = await openDialog({
    title: "Delete Confirmation",
    description: "Are you sure you want to delete?",
    confirmButton: "Delete",
    cancelButton: "Cancel",
  })
  
  if (confirmed) {
    // Actual delete logic
    console.log("Deleted!")
  }
}

return <Button onClick={handleDelete}>Delete</Button>

🔄 Convenience Improvements

| Aspect | ShadCN Dialog | SimpleDialog | |--------|---------------|--------------| | State Management | Manual (useState, onOpenChange) | Automatic (handled internally) | | User Response Handling | Complex (separate handlers) | Intuitive (Promise resolve) | | Dynamic Content | Difficult (state updates) | Easy (pass as parameters) | | Code Length | Long and complex | Short and concise | | JSX Structure | Must be pre-declared | Not required | | Async Processing | Callback-based | Promise-based |

🛠 Usage

1. Provider Setup

import { SimpleDialogProvider } from '@hensley-ui/react-simple-dialog'

function App() {
  return (
    <SimpleDialogProvider>
      <YourApp />
    </SimpleDialogProvider>
  )
}

2. Basic Usage

import { useSimpleDialog } from '@hensley-ui/react-simple-dialog'

function DeleteButton() {
  const openDialog = useSimpleDialog()

  const handleClick = async () => {
    const result = await openDialog({
      title: "Delete Confirmation",
      description: "Do you want to delete this item?",
      confirmButton: "Delete",
      cancelButton: "Cancel",
    })

    if (result) {
      console.log("User confirmed")
      // Execute delete logic
    } else {
      console.log("User cancelled")
    }
  }

  return <button onClick={handleClick}>Delete</button>
}

3. Custom Buttons

You can pass React elements instead of strings:

const result = await openDialog({
  title: "Account Deletion",
  description: "This action cannot be undone.",
  confirmButton: <span style={{ color: 'red' }}>Permanently Delete</span>,
  cancelButton: <span>Cancel</span>,
})

📋 API Reference

SimpleDialogType

type SimpleDialogType = {
  title: string | ReactNode           // Dialog title
  description: string | ReactNode     // Dialog description
  confirmButton: string | ReactNode   // Confirm button (default: "확인")
  cancelButton: string | ReactNode    // Cancel button (default: "취소")
  onConfirm?: () => void             // Additional confirm callback (optional)
  onCancel?: () => void              // Additional cancel callback (optional)
}

useSimpleDialog()

Returns a dialog opening function that returns a Promise.

Return value: (props: SimpleDialogType) => Promise<boolean>

  • true: User clicked the confirm button
  • false: User clicked the cancel button or closed the dialog

🌟 Use Cases

Delete Confirmation

const handleDelete = async () => {
  const confirmed = await openDialog({
    title: "Delete Item",
    description: "Do you want to delete the selected item?",
    confirmButton: "Delete",
    cancelButton: "Cancel",
  })

  if (confirmed) {
    await deleteItem(itemId)
    showSuccessMessage("Item deleted successfully")
  }
}

Form Submission Confirmation

const handleSubmit = async () => {
  const confirmed = await openDialog({
    title: "Submit Form",
    description: "Do you want to submit the form with the entered information?",
    confirmButton: "Submit",
    cancelButton: "Continue Editing",
  })

  if (confirmed) {
    await submitForm(formData)
    navigate('/success')
  }
}

Logout Confirmation

const handleLogout = async () => {
  const confirmed = await openDialog({
    title: "Logout",
    description: "Are you sure you want to logout?",
    confirmButton: "Logout",
    cancelButton: "Cancel",
  })

  if (confirmed) {
    await logout()
    navigate('/login')
  }
}

🎨 Styling

This component is built on TailwindCSS and ShadCN design system. You can customize styles by overriding CSS classes as needed.

🤝 Contributing

Feel free to submit issues for improvements or bug reports anytime.

📄 License

MIT License