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

revrag-universal-widget

v3.0.0

Published

Universal floating support widget with React components - works on all platforms including React, Next.js, Angular, Vue.js, and vanilla JavaScript. Features expandable interface with call and chat functionality. Zero configuration required!

Readme

🚀 Revrag Universal Widget

A powerful, universal floating support widget that works across all platforms - React, Next.js, Angular, and vanilla JavaScript. Features expandable interface with call and chat functionality. Zero configuration required!

✨ Features

  • 🌐 Universal Compatibility: Works on all platforms (React, Next.js, Angular, vanilla JS)
  • ⚛️ React Components: Dedicated React components with hooks and TypeScript support
  • 📱 Zero Setup: Just include the script tag and it works automatically
  • 💬 Interactive Tooltip: Beautiful hover tooltip with "Do you need any help?" message
  • 🔄 Expandable Interface: Smooth expand/collapse with modern animations
  • 📞 Professional Call Interface:
    • Live call duration timer with monospace font
    • Mute/Unmute toggle with visual feedback
    • End call functionality
    • Support agent avatar with animated ring
    • Professional call status indicators
  • 💬 Complete Chat System:
    • Real-time message rendering with animations
    • User and agent message bubbles
    • Message timestamps and avatars
    • Auto-scroll to latest messages
    • Input validation and sanitization
  • 🎨 Beautiful Modern Design:
    • CSS variables for consistent theming
    • Gradient backgrounds and smooth shadows
    • Hover effects and micro-interactions
    • Modern border-radius and spacing
    • Glass-morphism effects with backdrop blur
  • 📞 Enhanced Button: Gradient background with ripple effects
  • 🔧 Production Ready: Multiple script loads, CSP compliance, responsive design
  • Fully Accessible: ARIA labels, keyboard navigation, high contrast support
  • 🌙 Dark Mode: Automatic dark mode and reduced motion support
  • 📱 Mobile Optimized: Touch-friendly with safe area support
  • Optimized: ~17KB JS + ~13KB CSS for full functionality

🚀 Quick Start

React Usage (New!)

npm install revrag-universal-widget
import React from 'react';
import { RevragReactWidget } from 'revrag-universal-widget/src/react';

function App() {
  const handleCall = () => {
    console.log('Call started!');
    // Your call logic here
  };

  const handleChat = () => {
    console.log('Chat opened!');
    // Your chat logic here
  };

  return (
    <div>
      <h1>My App</h1>
      
      <RevragReactWidget
        position="bottom-right"
        backgroundColor="#007bff"
        phoneNumber="+1234567890"
        helpText="Need help? Click here!"
        size="medium"
        onCall={handleCall}
        onChat={handleChat}
      />
    </div>
  );
}

export default App;

React Props

interface RevragReactWidgetProps {
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
  backgroundColor?: string;        // Hex color for button background
  iconColor?: string;             // Hex color for button icon
  size?: 'small' | 'medium' | 'large';
  phoneNumber?: string;           // Phone number for calls
  helpText?: string;              // Tooltip text on hover
  bottomOffset?: number;          // Distance from bottom (px)
  rightOffset?: number;           // Distance from right (px)
  avatarUrl?: string;             // Custom avatar image URL
  onCall?: () => void;            // Custom call handler
  onChat?: () => void;            // Custom chat handler
  className?: string;             // Additional CSS classes
  style?: React.CSSProperties;    // Inline styles
}

Basic Usage (Works Everywhere!)

Simply add this script tag to your HTML:

<script src="https://unpkg.com/revrag-universal-widget@latest/dist/revrag-widget.min.js" 
        data-phone="+1234567890"></script>

That's it! The floating phone button will automatically appear in the bottom-right corner.

🛠 Installation & Usage

Via CDN (Recommended)

<script src="https://unpkg.com/revrag-universal-widget@latest/dist/revrag-widget.min.js" 
        data-phone="+1234567890"></script>

Via npm

npm install revrag-universal-widget

Then include in your project:

<script src="node_modules/revrag-universal-widget/dist/revrag-widget.min.js"
        data-phone="+1234567890"></script>

Development Build

git clone https://github.com/revrag/revrag-universal-widget.git
cd revrag-universal-widget
npm install
npm run build

⚙️ Configuration

Using Data Attributes (Recommended)

Configure the widget using data attributes on the script tag:

<script src="https://unpkg.com/revrag-universal-widget@latest/dist/revrag-widget.min.js"
        data-phone="+1234567890"
        data-position="bottom-left"
        data-bg-color="#28a745"
        data-icon-color="#ffffff"
        data-size="large"></script>

Available Data Attributes:

  • data-phone: Phone number to call
  • data-position: bottom-right, bottom-left, top-right, top-left
  • data-bg-color: Background color (hex, rgb, or named colors)
  • data-icon-color: Icon color
  • data-size: small, medium, large
  • data-help-text: Custom tooltip text (default: "Do you need any help?")
  • data-avatar-url: Avatar image URL for call interface

Using JavaScript API

For more advanced control:

// Manual initialization
RevragWidget.init({
  phoneNumber: '+1234567890',
  position: 'bottom-right',
  backgroundColor: '#007bff',
  iconColor: '#ffffff',
  size: 'medium',
  bottomOffset: 20,
  rightOffset: 20,
  helpText: 'Need assistance?',
  avatarUrl: 'https://example.com/avatar.jpg',
  onCall: () => {
    // Custom call handler
    console.log('Call started!');
    // Example: integrate with your WebRTC service
  },
  onChat: () => {
    // Custom chat handler
    console.log('Chat message sent!');
    // Example: integrate with your chat API
  }
});

// Control the widget
const widget = RevragWidget.getInstance();
widget.hide();           // Hide the widget
widget.show();           // Show the widget
RevragWidget.destroy();  // Remove the widget completely

// Update configuration dynamically
widget.updateConfig({
  backgroundColor: '#28a745',
  avatarUrl: 'https://example.com/new-avatar.jpg'
});

🌐 Platform Integration

Vanilla HTML/JavaScript

<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
</head>
<body>
    <h1>Welcome to My Site</h1>
    
    <!-- Widget automatically loads -->
    <script src="revrag-widget.min.js" data-phone="+1234567890"></script>
</body>
</html>

React.js

Add to your public/index.html:

<script src="revrag-widget.min.js" 
        data-phone="+1234567890"
        data-bg-color="#007bff"></script>

Or use the JavaScript API in a component:

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    if (window.RevragWidget) {
      window.RevragWidget.init({
        phoneNumber: '+1234567890',
        onCall: () => {
          // Custom React handler
          setShowSupportModal(true);
        }
      });
    }

    return () => {
      window.RevragWidget?.destroy();
    };
  }, []);

  return <div>Your React App</div>;
}

Next.js

Add to pages/_document.js:

import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html>
      <Head>
        <script 
          src="revrag-widget.min.js"
          data-phone="+1234567890"
          data-bg-color="#000000"
        />
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Or in pages/_app.js:

import Head from 'next/head';

export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <Head>
        <script 
          src="revrag-widget.min.js"
          data-phone="+1234567890"
        />
      </Head>
      <Component {...pageProps} />
    </>
  );
}

Angular

Add to src/index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MyAngularApp</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
  
  <!-- Revrag Widget -->
  <script src="revrag-widget.min.js" data-phone="+1234567890"></script>
</body>
</html>

Or use in a component:

import { Component, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-root',
  template: '<h1>My App</h1>'
})
export class AppComponent implements OnDestroy {
  ngAfterViewInit() {
    if (window.RevragWidget) {
      window.RevragWidget.init({
        phoneNumber: '+1234567890',
        backgroundColor: '#673ab7'
      });
    }
  }

  ngOnDestroy() {
    if (window.RevragWidget) {
      window.RevragWidget.destroy();
    }
  }
}

Vue.js

Add to public/index.html:

<script src="revrag-widget.min.js" data-phone="+1234567890"></script>

Or in a component:

<template>
  <div>Your Vue App</div>
</template>

<script>
export default {
  mounted() {
    if (window.RevragWidget) {
      window.RevragWidget.init({
        phoneNumber: '+1234567890',
        backgroundColor: '#42b883'
      });
    }
  },
  
  beforeUnmount() {
    if (window.RevragWidget) {
      window.RevragWidget.destroy();
    }
  }
}
</script>

🎨 Customization Examples

Different Positions

<!-- Bottom Left -->
<script src="revrag-widget.min.js" 
        data-phone="+1234567890" 
        data-position="bottom-left"></script>

<!-- Top Right -->
<script src="revrag-widget.min.js" 
        data-phone="+1234567890" 
        data-position="top-right"></script>

Custom Colors

<!-- Green theme -->
<script src="revrag-widget.min.js" 
        data-phone="+1234567890" 
        data-bg-color="#28a745" 
        data-icon-color="#ffffff"></script>

<!-- Custom brand colors -->
<script src="revrag-widget.min.js" 
        data-phone="+1234567890" 
        data-bg-color="#6f42c1" 
        data-icon-color="#ffffff"></script>

Different Sizes

<!-- Large widget -->
<script src="revrag-widget.min.js" 
        data-phone="+1234567890" 
        data-size="large"></script>

<!-- Small widget -->
<script src="revrag-widget.min.js" 
        data-phone="+1234567890" 
        data-size="small"></script>

🔧 Advanced Usage

Custom Click Handlers

Instead of direct phone calls, you can provide custom logic:

RevragWidget.init({
  onCall: () => {
    // Open your custom support interface
    openChatWidget();
    // Or show a modal with contact options
    showContactModal();
    // Or trigger analytics
    gtag('event', 'support_clicked');
  }
});

Dynamic Configuration

Change widget properties at runtime:

const widget = RevragWidget.getInstance();

// Update colors
widget.updateConfig({
  backgroundColor: '#dc3545',
  iconColor: '#ffffff'
});

// Change position
widget.updateConfig({
  position: 'top-left',
  bottomOffset: 10,
  rightOffset: 10
});

Programmatic Control

// Hide widget on certain pages
if (window.location.pathname === '/contact') {
  RevragWidget.getInstance().hide();
}

// Show widget with delay
setTimeout(() => {
  RevragWidget.getInstance().show();
}, 3000);

// Destroy widget conditionally
if (userHasSupport) {
  RevragWidget.destroy();
}

🛡️ Edge Cases Handled

  • Multiple Script Loads: Prevents duplicate widgets
  • DOM Not Ready: Waits for DOM before initializing
  • Mobile Safari: Handles iOS-specific touch behaviors
  • High Contrast Mode: Adds borders for accessibility
  • Reduced Motion: Disables animations when preferred
  • Print Styles: Hides widget when printing
  • CSS Framework Conflicts: Resets styles to prevent conflicts
  • Safe Area: Respects mobile safe areas (notches)
  • Z-Index Issues: Uses maximum z-index to stay on top

📱 Responsive Design

The widget automatically adapts to different screen sizes:

  • Desktop: Full-size button with hover effects
  • Tablet: Slightly smaller with touch-optimized interactions
  • Mobile: Respects safe areas and provides adequate touch targets
  • Small Screens: Automatically reduces size to save space

♿ Accessibility

  • ARIA Labels: Proper labeling for screen readers
  • Keyboard Navigation: Can be focused and activated via keyboard
  • High Contrast: Automatic border in high contrast mode
  • Reduced Motion: Respects user's motion preferences
  • Touch Targets: Minimum 44px touch targets on mobile

🎯 Browser Support

  • Chrome 60+
  • Firefox 60+
  • Safari 12+
  • Edge 79+
  • Internet Explorer 11+
  • Mobile browsers (iOS Safari, Android Chrome)

📦 CDN Usage

You can use the widget directly from a CDN:

<!-- unpkg CDN -->
<script src="https://unpkg.com/revrag-universal-widget@latest/dist/revrag-widget.min.js"
        data-phone="+1234567890"></script>

<!-- jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/npm/revrag-universal-widget@latest/dist/revrag-widget.min.js"
        data-phone="+1234567890"></script>

🔍 Development

# Install dependencies
npm install

# Development mode with hot reload
npm run dev

# Build for production
npm run build

# Serve example page
npm run serve

📄 License

MIT License - feel free to use in personal and commercial projects.

🤝 Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

📞 Support

Need help? Contact us or open an issue on GitHub.