Skip to content

roldanjr/popup-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

2 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽฏ Simple Popup Queue Manager

A lightweight React solution for managing multiple popups without chaos. Prevents popup race conditions by automatically queuing and showing popups one at a time, sorted by priority.

โœจ Core Features

  • ๐Ÿšซ No More Popup Chaos: Only one popup shows at a time
  • ๐ŸŽฏ Priority-Based Queuing: Higher priority popups show first
  • ๐ŸŽจ Complete Design Freedom: Each popup is a self-contained React component
  • ๐Ÿ”’ Non-Escapable Modals: Critical popups that require user action
  • โฐ Frequency Control: Prevent spam with "once", "session", or "always" rules
  • ๐Ÿ’พ Smart State Tracking: Respects user dismissals and prevents repeated annoyance
  • โšก Simple API: Easy integration with minimal configuration

๐Ÿš€ Quick Start

# Install dependencies
npm install

# Start development server
npm run dev

๐Ÿ“– Simple Usage

Basic Popup

import { usePopupQueue } from "./hooks/usePopupQueue";

function App() {
  const { addPopup } = usePopupQueue();

  const showWelcome = () => {
    addPopup({
      id: "welcome",
      content: <MyWelcomeComponent />,
      priority: 5,
    });
  };

  return <button onClick={showWelcome}>Show Popup</button>;
}

Custom Popup Component

import { usePopupActions } from "./hooks/usePopupActions";

function MyWelcomeComponent() {
  const { close } = usePopupActions();

  return (
    <div className="bg-white rounded-lg shadow-xl max-w-md p-6">
      <h2 className="text-xl font-bold mb-4">Welcome!</h2>
      <p className="mb-4">Thanks for joining us.</p>
      <button
        onClick={close}
        className="bg-blue-600 text-white px-4 py-2 rounded"
      >
        Get Started
      </button>
    </div>
  );
}

Non-Escapable Modal

// Critical popup that cannot be dismissed with ESC or backdrop click
addPopup({
  id: "terms-update",
  content: <TermsAcceptance />,
  priority: 10,
  escapable: false, // Must complete action to continue
});

Frequency Control

Control how often popups can be shown to prevent spam:

// Show only once (default behavior)
addPopup({
  id: "welcome",
  content: <Welcome />,
  frequency: "once", // Won't show again after dismissal
});

// Show once per browser session
addPopup({
  id: "session-tip",
  content: <QuickTip />,
  frequency: "session", // Shows again after page refresh
});

// Always show (ignore dismissal)
addPopup({
  id: "critical-alert",
  content: <SecurityAlert />,
  frequency: "always", // Shows every time (use sparingly)
});

๐ŸŽ›๏ธ API Reference

usePopupQueue Hook

const {
  // State
  queue, // Array of queued popups
  currentPopup, // Currently displayed popup
  queueLength, // Number of popups in queue

  // Actions
  addPopup, // Add popup to queue
  showNextPopup, // Manually show next popup
  clearQueue, // Clear all queued popups
  resetAllStates, // Reset all popup states for testing

  // Status
  isQueueEmpty, // Boolean: is queue empty?
  hasCurrentPopup, // Boolean: is popup currently showing?
} = usePopupQueue();

usePopupActions Hook

// Use inside popup components
const {
  close, // Close current popup and show next
  closeAll, // Close current popup and clear queue
  showNext, // Show next popup (for multi-step flows)
} = usePopupActions();

PopupConfig Interface

interface PopupConfig {
  id: string; // Unique identifier
  content: ReactNode; // Your custom React component
  priority?: number; // Higher = more important (default: 5)
  type?: string; // Optional categorization
  frequency?: PopupFrequency; // Show frequency rules (default: "once")
  escapable?: boolean; // Can be closed with ESC/backdrop (default: true)
  expiresAt?: Date; // Auto-expire date
}

type PopupFrequency = "once" | "session" | "always";

Frequency Options Explained

Frequency Behavior Use Case
"once" Shows once, never again after dismissal Welcome messages, terms updates
"session" Shows once per browser session Session tips, temporary notifications
"always" Shows every time, ignores dismissal Critical alerts, testing

๐Ÿ—๏ธ Architecture

Simple & Clean

  • No Templates: Each popup defines its own complete layout
  • Modal Only: All popups are modal dialogs (no banners, toasts, etc.)
  • Self-Contained: Popup components handle their own styling and actions
  • Minimal State: Essential state tracking without complexity

Priority System

Popups are automatically sorted by priority (highest first):

  • 10: Critical system alerts
  • 8-9: Important warnings
  • 5-7: General notifications
  • 2-4: Promotions and optional content
  • 1: Low priority background items

State Management

  • Dismissal Tracking: Dismissed popups won't show again (respects frequency)
  • Session Storage: Persisted across browser sessions
  • Reset Capability: Clear all states for testing/demos

๐ŸŽฎ Demo Features

The included demo showcases:

  • Main Demo: Adds 5 different popups by priority
  • Individual Controls: Payment (once), Tour (once), Rating (session), Upgrade (always)
  • Non-Escapable Modal: Critical popup that requires action
  • Frequency Testing: Different frequency behaviors you can test interactively
  • Queue Visualization: Real-time queue status
  • Reset Functions: Clear states for repeated testing

Testing Frequency Behaviors

  1. "Once" Frequency: Payment/Tour buttons - dismiss once, won't show again
  2. "Session" Frequency: Rating button - shows again after page refresh
  3. "Always" Frequency: Upgrade button - shows every time, even after dismissal

๐Ÿ”ง Tech Stack

  • React 19 with TypeScript
  • Vite for development
  • Tailwind CSS for styling
  • Zustand for state management
  • ShadCN UI for components

๐Ÿ’ก Key Concepts

1. Self-Contained Popups

Each popup is a complete React component with its own styling:

function PaymentForm() {
  const { close } = usePopupActions();

  return (
    <div className="bg-white rounded-lg shadow-xl max-w-md p-6">
      {/* Your complete popup design here */}
      <button onClick={close}>Done</button>
    </div>
  );
}

2. Automatic Queue Management

// Add multiple popups - they'll show one at a time by priority
addPopup({ id: "terms", content: <Terms />, priority: 9 });
addPopup({ id: "payment", content: <Payment />, priority: 8 });
addPopup({ id: "welcome", content: <Welcome />, priority: 5 });
// Shows: Terms โ†’ Payment โ†’ Welcome

3. Non-Escapable Modals for Critical Actions

addPopup({
  id: "critical-update",
  content: <SecurityAlert />,
  priority: 10,
  escapable: false, // User must complete the action
});

4. Smart Frequency Management

// Welcome message - show once per user, ever
addPopup({
  id: "welcome",
  content: <Welcome />,
  frequency: "once", // Default: won't show again after dismissal
});

// Quick tip - show once per session
addPopup({
  id: "productivity-tip",
  content: <ProductivityTip />,
  frequency: "session", // Shows again after browser restart
});

// Critical system alert - always show
addPopup({
  id: "system-maintenance",
  content: <MaintenanceAlert />,
  frequency: "always", // Ignores dismissal, shows every time
  priority: 10,
});

๐ŸŽฏ Perfect For

  • Login Flows: Queue multiple popups without overwhelming users
  • Onboarding: Sequential user guidance
  • Critical Alerts: Non-dismissible security warnings
  • Terms Updates: Mandatory acceptance flows
  • Payment Issues: Important account notifications

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Submit a pull request

๐Ÿ“„ License

MIT License - feel free to use in your projects!


Simple, focused popup management for better user experiences โœจ

About

One popup at a time with priority-based ordering. No more popup chaos!

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors