JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 5
  • Score
    100M100P100Q66221F
  • License MIT

A comprehensive React component library featuring toast notifications, customizable buttons, and typography components built with TypeScript and Tailwind CSS.

Package Exports

  • @cibobu/react-toast-popup
  • @cibobu/react-toast-popup/components/Button/Button.css
  • @cibobu/react-toast-popup/styles/tailwind-fallback.css

Readme

@cibobu/react-toast-popup

A comprehensive React component library featuring toast notifications, customizable buttons, and typography components built with TypeScript and Tailwind CSS.

React Toast Popup License TypeScript

✨ Features

  • 🍞 Toast Notifications - Beautiful, accessible toast notifications with multiple types and animations
  • 🎨 Button Component - Highly customizable button with multiple variants, styles, and sizes
  • 📝 Typography Component - Comprehensive typography system with semantic variants
  • 🎯 TypeScript Support - Fully typed components with excellent IntelliSense
  • 🎨 Tailwind CSS - Built with Tailwind CSS for easy customization
  • 📱 Responsive - Mobile-first design that works on all screen sizes
  • Accessible - WCAG compliant with proper ARIA attributes
  • 🚀 Tree Shakeable - Import only what you need

📦 Installation

npm install @cibobu/react-toast-popup
# or
yarn add @cibobu/react-toast-popup
# or
pnpm add @cibobu/react-toast-popup

🚀 Quick Start

1. Setup (Choose One Option)

# Install Tailwind CSS first
npm install -D tailwindcss postcss autoprefixer

# Then initialize Tailwind
npx tailwindcss init -p

tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
    "./node_modules/@cibobu/react-toast-popup/**/*.{js,ts,jsx,tsx}"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

src/index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

If you don't want to setup Tailwind CSS, simply import the fallback CSS:

src/index.css or src/main.jsx:

@import '@cibobu/react-toast-popup/dist/styles/tailwind-fallback.css';

Or in your main JS file:

import '@cibobu/react-toast-popup/dist/styles/tailwind-fallback.css';

This is the easiest way to get started! No configuration needed.

2. Basic Usage

import React from 'react';
import useNotification, { Button, Typography, Notification } from '@cibobu/react-toast-popup';

function App() {
  const { showNotification, notifications, removeNotification } = useNotification();

  return (
    <div className="p-8">
      <Typography variant="title-h1">Welcome!</Typography>
      
      <Button 
        variant="primary" 
        style="filled" 
        onClick={() => showNotification({
          type: 'success',
          message: 'Hello World!',
          duration: 3000
        })}
      >
        Show Toast
      </Button>

      {/* Notification Container */}
      <div className="fixed top-4 right-4 space-y-2">
        {notifications.map((notification) => (
          <Notification
            key={notification.id}
            type={notification.type}
            message={notification.message}
            onClose={() => removeNotification(notification.id)}
          />
        ))}
      </div>
    </div>
  );
}

export default App;

📚 Components

🍞 Toast Notifications

useNotification Hook

import useNotification from '@cibobu/react-toast-popup';

const { showNotification, notifications, removeNotification } = useNotification();

API:

  • showNotification(options) - Show a new notification
  • notifications - Array of current notifications
  • removeNotification(id) - Remove a specific notification

Options:

interface NotificationOptions {
  type: 'success' | 'info' | 'warning' | 'error';
  message: string;
  duration?: number; // in milliseconds
  animation?: 'fade' | 'pop' | 'slide';
}

Notification Component

import { Notification } from '@cibobu/react-toast-popup';

<Notification
  type="success"
  message="Operation completed successfully!"
  onClose={() => console.log('closed')}
/>

🎨 Button Component

import { Button } from '@cibobu/react-toast-popup';

// Basic usage
<Button variant="primary" style="filled" size="medium">
  Click me
</Button>

// With loading state
<Button variant="primary" style="filled" loading>
  Loading...
</Button>

// With icons
<Button 
  variant="primary" 
  style="filled" 
  leftIcon={<span>📧</span>}
  rightIcon={<span></span>}
>
  Send Email
</Button>

// Icon only
<Button variant="primary" style="filled" iconOnly>
  ⚙️
</Button>

Props:

interface ButtonProps {
  variant?: 'primary' | 'neutral' | 'error';
  style?: 'filled' | 'stroke' | 'lighter' | 'ghost';
  size?: 'x-small' | 'small' | 'medium';
  loading?: boolean;
  disabled?: boolean;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  iconOnly?: boolean;
  children: React.ReactNode;
  className?: string;
}

Variants & Styles:

  • Primary: Blue color scheme
  • Neutral: Gray color scheme
  • Error: Red color scheme

Each variant supports 4 styles:

  • Filled: Solid background
  • Stroke: Outlined border
  • Lighter: Light background
  • Ghost: Transparent background

📝 Typography Component

import { Typography } from '@cibobu/react-toast-popup';

// Display variants
<Typography variant="display-d1">Large Display</Typography>
<Typography variant="display-d2">Medium Display</Typography>

// Title variants
<Typography variant="title-h1">Main Title</Typography>
<Typography variant="title-h2">Section Title</Typography>
<Typography variant="title-h3">Subsection Title</Typography>
<Typography variant="title-h4">Card Title</Typography>

// Subheading variants
<Typography variant="subheading-medium">Medium Subheading</Typography>
<Typography variant="subheading-small">Small Subheading</Typography>

// Label variants
<Typography variant="label-large">Large Label</Typography>
<Typography variant="label-medium">Medium Label</Typography>
<Typography variant="label-small">Small Label</Typography>

// Paragraph variants
<Typography variant="paragraph-medium">Regular paragraph text</Typography>
<Typography variant="paragraph-small">Small paragraph text</Typography>

// Custom element
<Typography variant="title-h1" as="h2">
  Custom HTML element
</Typography>

Props:

interface TypographyProps {
  variant?: 
    | 'display-d1' | 'display-d2'
    | 'title-h1' | 'title-h2' | 'title-h3' | 'title-h4'
    | 'subheading-medium' | 'subheading-small' | 'subheading-x-small'
    | 'label-large' | 'label-medium' | 'label-small' | 'label-x-small'
    | 'paragraph-medium' | 'paragraph-small' | 'paragraph-x-small';
  as?: keyof JSX.IntrinsicElements;
  children: React.ReactNode;
  className?: string;
}

🎯 Complete Example

import React, { useState } from 'react';
import useNotification, { Button, Typography, Notification } from '@cibobu/react-toast-popup';

function ContactForm() {
  const [formData, setFormData] = useState({ name: '', email: '' });
  const [isSubmitting, setIsSubmitting] = useState(false);
  const { showNotification, notifications, removeNotification } = useNotification();

  const handleSubmit = async (e) => {
    e.preventDefault();
    setIsSubmitting(true);
    
    try {
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      showNotification({
        type: 'success',
        message: 'Form submitted successfully!',
        duration: 3000
      });
      
      setFormData({ name: '', email: '' });
    } catch (error) {
      showNotification({
        type: 'error',
        message: 'Failed to submit form. Please try again.',
        duration: 5000
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-lg">
      <Typography variant="title-h2" className="mb-6 text-center">
        Contact Us
      </Typography>
      
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <Typography variant="label-medium" className="block mb-2">
            Name
          </Typography>
          <input
            type="text"
            value={formData.name}
            onChange={(e) => setFormData({...formData, name: e.target.value})}
            className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
            required
          />
        </div>
        
        <div>
          <Typography variant="label-medium" className="block mb-2">
            Email
          </Typography>
          <input
            type="email"
            value={formData.email}
            onChange={(e) => setFormData({...formData, email: e.target.value})}
            className="w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
            required
          />
        </div>
        
        <Button
          type="submit"
          variant="primary"
          style="filled"
          size="medium"
          loading={isSubmitting}
          disabled={isSubmitting}
          className="w-full"
        >
          {isSubmitting ? 'Submitting...' : 'Submit Form'}
        </Button>
      </form>

      {/* Toast Notifications */}
      <div className="fixed top-4 right-4 space-y-2 z-50">
        {notifications.map((notification) => (
          <Notification
            key={notification.id}
            type={notification.type}
            message={notification.message}
            onClose={() => removeNotification(notification.id)}
          />
        ))}
      </div>
    </div>
  );
}

export default ContactForm;

🎨 Customization

Custom Styling

All components accept a className prop for custom styling:

<Button 
  variant="primary" 
  style="filled" 
  className="shadow-lg hover:shadow-xl transform hover:scale-105"
>
  Custom Button
</Button>

<Typography 
  variant="title-h1" 
  className="text-gradient bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent"
>
  Gradient Title
</Typography>

Theme Customization

You can customize the appearance by extending your Tailwind config:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          50: '#eff6ff',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
        }
      }
    }
  }
}

🔧 TypeScript Support

This library is built with TypeScript and provides full type definitions:

import { Button, Typography, Notification } from '@cibobu/react-toast-popup';
import type { ButtonProps, TypographyProps } from '@cibobu/react-toast-popup';

// Fully typed props
const MyButton: React.FC<ButtonProps> = (props) => {
  return <Button {...props} />;
};

📱 Browser Support

  • Chrome >= 60
  • Firefox >= 60
  • Safari >= 12
  • Edge >= 79

🔧 Troubleshooting

Button Styles Not Appearing?

Problem: Button appears without styles (no colors, padding, etc.)

Solution: You need to import the CSS. Choose one:

  1. Easy way (Recommended):

    import '@cibobu/react-toast-popup/dist/styles/tailwind-fallback.css';
  2. With Tailwind CSS:

    npm install -D tailwindcss postcss autoprefixer
    npx tailwindcss init -p

    Then add to your tailwind.config.js:

    content: [
      "./src/**/*.{js,jsx,ts,tsx}",
      "./node_modules/@cibobu/react-toast-popup/**/*.{js,ts,jsx,tsx}"
    ]

Error: "could not determine executable to run"

Problem: npx tailwindcss init -p fails

Solution: Install Tailwind CSS first:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

React Context Error

Problem: "Cannot read properties of undefined (reading 'ReactCurrentDispatcher')"

Solution: Make sure React is installed in your project:

npm install react react-dom

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments


Made with ❤️ by @cibobu