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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@choice-ui/bells

v0.0.5

Published

A notification bell component with animated indicators for displaying alerts and messages

Readme

Bells

A customizable notification component built on top of Sonner, featuring progress indicators, multiple variants, and flexible action support. Perfect for displaying toast-style notifications with enhanced visual feedback.

Import

import { bells, Bell } from "@choice-ui/react"

Features

  • Multiple visual variants for different notification types (default, accent, success, warning, danger, assistive)
  • Optional progress bar with pause-on-hover functionality
  • Support for custom actions and close buttons
  • HTML content support for rich notifications
  • Customizable duration with support for persistent notifications
  • Icon support for visual enhancement
  • Compound slots for granular style customization
  • Smooth animations powered by Framer Motion

Usage

Basic

bells({
  text: "Your changes have been saved",
})

With icon and variant

import { CheckCircleFilled } from "@choiceform/icons-react"

bells({
  text: "Task completed successfully",
  icon: <CheckCircleFilled />,
  variant: "success",
})

With progress indicator

bells({
  text: "Upload in progress...",
  progress: true,
  duration: 5000,
})

With custom action

bells({
  text: "New message received",
  action: (id) => (
    <Button
      size="small"
      variant="ghost"
      onClick={() => console.log("View", id)}
    >
      View
    </Button>
  ),
})

Persistent notification

bells({
  text: "System update available",
  duration: Infinity,
  onClose: (id) => {
    console.log("Closed notification", id)
    toast.dismiss(id)
  },
})

With HTML content

bells({
  html: "Task <strong>deployment</strong> completed",
  variant: "success",
})

Props

interface BellsProps extends Omit<ToasterProps, "id"> {
  /** Custom action renderer function */
  action?: (id: string | number) => React.ReactNode

  /** Additional CSS class name */
  className?: string

  /** Object of class names for each slot */
  classNames?: {
    button?: string
    close?: string
    content?: string
    icon?: string
    progress?: string
    root?: string
    text?: string
  }

  /** HTML content (alternative to text) */
  html?: string

  /** Icon element to display */
  icon?: React.ReactNode

  /** Unique notification identifier */
  id: string | number

  /** Callback when notification is closed */
  onClose?: (id: string | number) => void

  /** Whether to show progress indicator */
  progress?: boolean

  /** Plain text content */
  text?: string

  /** Visual style variant */
  variant?: "default" | "accent" | "success" | "warning" | "danger" | "assistive" | "reset"
}
  • Defaults:

    • duration: 4000 (ms)
    • variant: "default"
    • progress: false
  • Notes:

    • Either text or html prop is required
    • Use duration: Infinity for persistent notifications
    • Progress bar automatically pauses on hover

Styling

  • Uses Tailwind CSS via tailwind-variants with multiple customizable slots
  • Slots available: root, content, icon, text, close, button, progress
  • Each variant has distinct color schemes matching semantic meaning
  • Dark mode compatible with appropriate contrast ratios

Best practices

  • Choose variants that match the notification's semantic meaning
  • Keep messages concise and actionable
  • Use progress indicators for long-running operations
  • Provide clear actions when user interaction is needed
  • Consider using icons to enhance visual recognition
  • Set appropriate durations based on content complexity

Examples

Error notification with action

bells({
  text: "Failed to save changes",
  variant: "danger",
  action: (id) => (
    <Button
      size="small"
      variant="ghost"
      onClick={() => {
        retryOperation()
        toast.dismiss(id)
      }}
    >
      Retry
    </Button>
  ),
})

Upload progress

bells({
  text: "Uploading file...",
  progress: true,
  duration: 10000,
  icon: <Upload />,
  variant: "accent",
})

Warning with custom close handler

bells({
  text: "Your session will expire in 5 minutes",
  variant: "warning",
  onClose: (id) => {
    trackEvent("warning_dismissed")
    toast.dismiss(id)
  },
})

Notes

  • The component uses Sonner under the hood for toast management
  • Progress bars pause on hover to give users time to read/interact
  • Custom actions are memoized to prevent unnecessary re-renders
  • The notification system supports queueing and positioning through Sonner's API
  • Use the bells() function for programmatic notifications, or <Bell> component for custom implementations