| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Toast Notification Playground</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .toast-container { |
| position: fixed; |
| z-index: 9999; |
| transition: all 0.3s ease; |
| } |
| .toast-container.top-right { |
| top: 20px; |
| right: 20px; |
| } |
| .toast-container.top-left { |
| top: 20px; |
| left: 20px; |
| } |
| .toast-container.bottom-right { |
| bottom: 20px; |
| right: 20px; |
| } |
| .toast-container.bottom-left { |
| bottom: 20px; |
| left: 20px; |
| } |
| .toast-container.center { |
| top: 50%; |
| left: 50%; |
| transform: translate(-50%, -50%); |
| } |
| .toast { |
| position: relative; |
| overflow: hidden; |
| margin-bottom: 10px; |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); |
| transition: all 0.3s ease; |
| opacity: 0; |
| transform: translateY(20px); |
| } |
| .toast.show { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| .toast.hide { |
| opacity: 0; |
| transform: translateY(-20px); |
| } |
| .toast-progress { |
| position: absolute; |
| bottom: 0; |
| left: 0; |
| height: 4px; |
| background-color: rgba(255, 255, 255, 0.7); |
| width: 100%; |
| transform: scaleX(1); |
| transform-origin: left; |
| transition: transform linear; |
| } |
| .custom-font-preview { |
| font-size: 1.2rem; |
| padding: 10px; |
| border: 1px dashed #ccc; |
| margin-top: 5px; |
| } |
| .color-picker-container { |
| display: flex; |
| align-items: center; |
| gap: 10px; |
| } |
| .color-preview { |
| width: 30px; |
| height: 30px; |
| border-radius: 4px; |
| border: 1px solid #ccc; |
| } |
| .export-code { |
| background-color: #f8f9fa; |
| border: 1px solid #dee2e6; |
| border-radius: 4px; |
| padding: 15px; |
| font-family: monospace; |
| white-space: pre-wrap; |
| max-height: 200px; |
| overflow-y: auto; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-100 min-h-screen"> |
| <div class="container mx-auto px-4 py-8"> |
| <h1 class="text-4xl font-bold text-center mb-8 text-indigo-700">Toast Notification Playground</h1> |
| |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> |
| |
| <div class="bg-white rounded-lg shadow-lg p-6 col-span-1"> |
| <h2 class="text-2xl font-semibold mb-6 text-gray-800 border-b pb-2">Configuration</h2> |
| |
| <div class="space-y-6"> |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Message</label> |
| <textarea id="message" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" rows="3">This is a toast notification!</textarea> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Type</label> |
| <div class="grid grid-cols-4 gap-2"> |
| <button data-type="info" class="toast-type-btn py-2 px-3 rounded-md bg-blue-100 text-blue-800 border border-blue-200 hover:bg-blue-200">Info</button> |
| <button data-type="success" class="toast-type-btn py-2 px-3 rounded-md bg-green-100 text-green-800 border border-green-200 hover:bg-green-200">Success</button> |
| <button data-type="warning" class="toast-type-btn py-2 px-3 rounded-md bg-yellow-100 text-yellow-800 border border-yellow-200 hover:bg-yellow-200">Warning</button> |
| <button data-type="error" class="toast-type-btn py-2 px-3 rounded-md bg-red-100 text-red-800 border border-red-200 hover:bg-red-200">Error</button> |
| </div> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Position</label> |
| <div class="grid grid-cols-3 gap-2"> |
| <button data-position="top-left" class="position-btn py-2 px-3 rounded-md bg-gray-100 text-gray-800 border border-gray-200 hover:bg-gray-200">Top Left</button> |
| <button data-position="top-right" class="position-btn py-2 px-3 rounded-md bg-gray-100 text-gray-800 border border-gray-200 hover:bg-gray-200">Top Right</button> |
| <button data-position="center" class="position-btn py-2 px-3 rounded-md bg-gray-100 text-gray-800 border border-gray-200 hover:bg-gray-200">Center</button> |
| <button data-position="bottom-left" class="position-btn py-2 px-3 rounded-md bg-gray-100 text-gray-800 border border-gray-200 hover:bg-gray-200">Bottom Left</button> |
| <button data-position="bottom-right" class="position-btn py-2 px-3 rounded-md bg-gray-100 text-gray-800 border border-gray-200 hover:bg-gray-200">Bottom Right</button> |
| </div> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Duration (ms)</label> |
| <input type="range" id="duration" min="1000" max="10000" step="500" value="5000" class="w-full"> |
| <div class="flex justify-between text-xs text-gray-500"> |
| <span>1s</span> |
| <span>5s</span> |
| <span>10s</span> |
| </div> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Animation</label> |
| <select id="animation" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"> |
| <option value="fade">Fade</option> |
| <option value="slide">Slide</option> |
| <option value="zoom">Zoom</option> |
| </select> |
| </div> |
| |
| |
| <div class="flex items-center"> |
| <input type="checkbox" id="progressBar" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"> |
| <label for="progressBar" class="ml-2 block text-sm text-gray-700">Show Progress Bar</label> |
| </div> |
| |
| |
| <div class="flex items-center"> |
| <input type="checkbox" id="closeButton" checked class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"> |
| <label for="closeButton" class="ml-2 block text-sm text-gray-700">Show Close Button</label> |
| </div> |
| |
| |
| <div class="flex items-center"> |
| <input type="checkbox" id="showIcon" checked class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"> |
| <label for="showIcon" class="ml-2 block text-sm text-gray-700">Show Icon</label> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Custom Colors</label> |
| <div class="space-y-2"> |
| <div class="color-picker-container"> |
| <span class="text-sm">Background:</span> |
| <input type="color" id="bgColor" value="#4f46e5" class="h-8 w-8"> |
| <div id="bgColorPreview" class="color-preview" style="background-color: #4f46e5;"></div> |
| </div> |
| <div class="color-picker-container"> |
| <span class="text-sm">Text:</span> |
| <input type="color" id="textColor" value="#ffffff" class="h-8 w-8"> |
| <div id="textColorPreview" class="color-preview" style="background-color: #ffffff;"></div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Font Family</label> |
| <select id="fontFamily" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500"> |
| <option value="sans-serif">Sans-serif</option> |
| <option value="serif">Serif</option> |
| <option value="monospace">Monospace</option> |
| <option value="cursive">Cursive</option> |
| <option value="fantasy">Fantasy</option> |
| <option value="Arial">Arial</option> |
| <option value="Verdana">Verdana</option> |
| <option value="Georgia">Georgia</option> |
| <option value="Courier New">Courier New</option> |
| </select> |
| <div id="fontPreview" class="custom-font-preview" style="font-family: sans-serif;">Font Preview</div> |
| </div> |
| |
| |
| <div> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Font Size (px)</label> |
| <input type="range" id="fontSize" min="12" max="24" step="1" value="16" class="w-full"> |
| <div class="flex justify-between text-xs text-gray-500"> |
| <span>12px</span> |
| <span>18px</span> |
| <span>24px</span> |
| </div> |
| </div> |
| |
| |
| <button id="showToastBtn" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-md shadow-sm transition duration-150 ease-in-out"> |
| Show Toast |
| </button> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-lg shadow-lg p-6 col-span-1"> |
| <h2 class="text-2xl font-semibold mb-6 text-gray-800 border-b pb-2">Preview</h2> |
| |
| <div id="toastPreview" class="mb-6 p-4 rounded-md bg-indigo-600 text-white flex items-start"> |
| <div class="mr-3"> |
| <i class="fas fa-info-circle text-xl"></i> |
| </div> |
| <div class="flex-1"> |
| <p class="font-medium">This is a toast notification!</p> |
| </div> |
| <button class="ml-3 text-white opacity-70 hover:opacity-100"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <div class="mt-6"> |
| <h3 class="text-lg font-medium text-gray-800 mb-2">Export Code</h3> |
| <div class="mb-4"> |
| <button id="copyCodeBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-1 px-3 rounded-md text-sm shadow-sm transition duration-150 ease-in-out"> |
| Copy Code |
| </button> |
| <button id="downloadCodeBtn" class="ml-2 bg-green-600 hover:bg-green-700 text-white font-medium py-1 px-3 rounded-md text-sm shadow-sm transition duration-150 ease-in-out"> |
| Download |
| </button> |
| </div> |
| <div id="exportCode" class="export-code"> |
| |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="bg-white rounded-lg shadow-lg p-6 col-span-1 relative"> |
| <h2 class="text-2xl font-semibold mb-6 text-gray-800 border-b pb-2">Live Demo</h2> |
| |
| <div class="flex flex-wrap gap-2 mb-6"> |
| <button id="demoInfo" class="py-1 px-3 rounded-md bg-blue-100 text-blue-800 border border-blue-200 hover:bg-blue-200">Info</button> |
| <button id="demoSuccess" class="py-1 px-3 rounded-md bg-green-100 text-green-800 border border-green-200 hover:bg-green-200">Success</button> |
| <button id="demoWarning" class="py-1 px-3 rounded-md bg-yellow-100 text-yellow-800 border border-yellow-200 hover:bg-yellow-200">Warning</button> |
| <button id="demoError" class="py-1 px-3 rounded-md bg-red-100 text-red-800 border border-red-200 hover:bg-red-200">Error</button> |
| <button id="demoCustom" class="py-1 px-3 rounded-md bg-purple-100 text-purple-800 border border-purple-200 hover:bg-purple-200">Custom</button> |
| <button id="clearAll" class="py-1 px-3 rounded-md bg-gray-100 text-gray-800 border border-gray-200 hover:bg-gray-200">Clear All</button> |
| </div> |
| |
| <div id="toastContainer" class="toast-container top-right"></div> |
| |
| <div class="mt-6"> |
| <h3 class="text-lg font-medium text-gray-800 mb-2">Recent Toasts</h3> |
| <div id="toastHistory" class="space-y-2 max-h-60 overflow-y-auto"> |
| |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', function() { |
| // Configuration variables |
| let currentType = 'info'; |
| let currentPosition = 'top-right'; |
| let currentAnimation = 'fade'; |
| let currentBgColor = '#4f46e5'; |
| let currentTextColor = '#ffffff'; |
| let currentFontFamily = 'sans-serif'; |
| let currentFontSize = '16px'; |
| |
| // DOM Elements |
| const toastContainer = document.getElementById('toastContainer'); |
| const toastPreview = document.getElementById('toastPreview'); |
| const exportCode = document.getElementById('exportCode'); |
| |
| // Initialize |
| updatePreview(); |
| generateExportCode(); |
| |
| // Event Listeners |
| document.querySelectorAll('.toast-type-btn').forEach(btn => { |
| btn.addEventListener('click', function() { |
| currentType = this.dataset.type; |
| updateTypeStyles(currentType); |
| updatePreview(); |
| generateExportCode(); |
| }); |
| }); |
| |
| document.querySelectorAll('.position-btn').forEach(btn => { |
| btn.addEventListener('click', function() { |
| currentPosition = this.dataset.position; |
| toastContainer.className = `toast-container ${currentPosition}`; |
| updatePreview(); |
| generateExportCode(); |
| }); |
| }); |
| |
| document.getElementById('message').addEventListener('input', function() { |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('duration').addEventListener('input', function() { |
| generateExportCode(); |
| }); |
| |
| document.getElementById('animation').addEventListener('change', function() { |
| currentAnimation = this.value; |
| generateExportCode(); |
| }); |
| |
| document.getElementById('progressBar').addEventListener('change', function() { |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('closeButton').addEventListener('change', function() { |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('showIcon').addEventListener('change', function() { |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('bgColor').addEventListener('input', function() { |
| currentBgColor = this.value; |
| document.getElementById('bgColorPreview').style.backgroundColor = currentBgColor; |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('textColor').addEventListener('input', function() { |
| currentTextColor = this.value; |
| document.getElementById('textColorPreview').style.backgroundColor = currentTextColor; |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('fontFamily').addEventListener('change', function() { |
| currentFontFamily = this.value; |
| document.getElementById('fontPreview').style.fontFamily = currentFontFamily; |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('fontSize').addEventListener('input', function() { |
| currentFontSize = `${this.value}px`; |
| document.getElementById('fontPreview').style.fontSize = currentFontSize; |
| updatePreview(); |
| generateExportCode(); |
| }); |
| |
| document.getElementById('showToastBtn').addEventListener('click', function() { |
| showToast(); |
| }); |
| |
| // Demo buttons |
| document.getElementById('demoInfo').addEventListener('click', function() { |
| showDemoToast('info', 'Information', 'This is an information toast.'); |
| }); |
| |
| document.getElementById('demoSuccess').addEventListener('click', function() { |
| showDemoToast('success', 'Success', 'Operation completed successfully!'); |
| }); |
| |
| document.getElementById('demoWarning').addEventListener('click', function() { |
| showDemoToast('warning', 'Warning', 'This is a warning message.'); |
| }); |
| |
| document.getElementById('demoError').addEventListener('click', function() { |
| showDemoToast('error', 'Error', 'Something went wrong!'); |
| }); |
| |
| document.getElementById('demoCustom').addEventListener('click', function() { |
| showDemoToast('custom', 'Custom', 'This is a custom styled toast.', { |
| bgColor: '#8b5cf6', |
| textColor: '#ffffff', |
| icon: 'fas fa-star' |
| }); |
| }); |
| |
| document.getElementById('clearAll').addEventListener('click', function() { |
| clearAllToasts(); |
| }); |
| |
| // Copy and Download buttons |
| document.getElementById('copyCodeBtn').addEventListener('click', function() { |
| copyToClipboard(exportCode.textContent); |
| showToast('success', 'Copied to clipboard!'); |
| }); |
| |
| document.getElementById('downloadCodeBtn').addEventListener('click', function() { |
| downloadCode(); |
| }); |
| |
| // Functions |
| function updateTypeStyles(type) { |
| let bgColor, textColor, icon; |
| |
| switch(type) { |
| case 'info': |
| bgColor = '#3b82f6'; |
| textColor = '#ffffff'; |
| icon = 'fas fa-info-circle'; |
| break; |
| case 'success': |
| bgColor = '#10b981'; |
| textColor = '#ffffff'; |
| icon = 'fas fa-check-circle'; |
| break; |
| case 'warning': |
| bgColor = '#f59e0b'; |
| textColor = '#ffffff'; |
| icon = 'fas fa-exclamation-triangle'; |
| break; |
| case 'error': |
| bgColor = '#ef4444'; |
| textColor = '#ffffff'; |
| icon = 'fas fa-times-circle'; |
| break; |
| default: |
| bgColor = currentBgColor; |
| textColor = currentTextColor; |
| icon = 'fas fa-info-circle'; |
| } |
| |
| document.getElementById('bgColor').value = bgColor; |
| document.getElementById('textColor').value = textColor; |
| document.getElementById('bgColorPreview').style.backgroundColor = bgColor; |
| document.getElementById('textColorPreview').style.backgroundColor = textColor; |
| |
| currentBgColor = bgColor; |
| currentTextColor = textColor; |
| |
| return { bgColor, textColor, icon }; |
| } |
| |
| function updatePreview() { |
| const message = document.getElementById('message').value; |
| const showProgressBar = document.getElementById('progressBar').checked; |
| const showCloseButton = document.getElementById('closeButton').checked; |
| const showIcon = document.getElementById('showIcon').checked; |
| |
| const typeStyles = updateTypeStyles(currentType); |
| |
| // Update preview toast |
| toastPreview.style.backgroundColor = typeStyles.bgColor; |
| toastPreview.style.color = typeStyles.textColor; |
| toastPreview.style.fontFamily = currentFontFamily; |
| toastPreview.style.fontSize = currentFontSize; |
| |
| // Update message |
| toastPreview.querySelector('p').textContent = message; |
| |
| // Update icon |
| const iconElement = toastPreview.querySelector('i'); |
| iconElement.className = `${typeStyles.icon} text-xl`; |
| iconElement.style.display = showIcon ? 'block' : 'none'; |
| |
| // Update close button |
| const closeBtn = toastPreview.querySelector('button'); |
| closeBtn.style.display = showCloseButton ? 'block' : 'none'; |
| |
| // Add progress bar if needed |
| let progressBar = toastPreview.querySelector('.toast-progress'); |
| if (showProgressBar) { |
| if (!progressBar) { |
| progressBar = document.createElement('div'); |
| progressBar.className = 'toast-progress'; |
| toastPreview.appendChild(progressBar); |
| } |
| progressBar.style.backgroundColor = `rgba(255, 255, 255, 0.7)`; |
| } else if (progressBar) { |
| progressBar.remove(); |
| } |
| } |
| |
| function showToast(customType, customMessage) { |
| const type = customType || currentType; |
| const message = customMessage || document.getElementById('message').value; |
| const duration = parseInt(document.getElementById('duration').value); |
| const showProgressBar = document.getElementById('progressBar').checked; |
| const showCloseButton = document.getElementById('closeButton').checked; |
| const showIcon = document.getElementById('showIcon').checked; |
| const animation = currentAnimation; |
| |
| const typeStyles = type === 'custom' ? |
| { bgColor: currentBgColor, textColor: currentTextColor, icon: 'fas fa-info-circle' } : |
| updateTypeStyles(type); |
| |
| // Create toast element |
| const toast = document.createElement('div'); |
| toast.className = `toast ${animation}`; |
| toast.style.backgroundColor = typeStyles.bgColor; |
| toast.style.color = typeStyles.textColor; |
| toast.style.fontFamily = currentFontFamily; |
| toast.style.fontSize = currentFontSize; |
| toast.style.borderRadius = '0.375rem'; |
| toast.style.padding = '1rem'; |
| toast.style.display = 'flex'; |
| toast.style.alignItems = 'flex-start'; |
| toast.style.maxWidth = '350px'; |
| |
| // Add icon |
| if (showIcon) { |
| const icon = document.createElement('div'); |
| icon.className = 'mr-3'; |
| const iconElement = document.createElement('i'); |
| iconElement.className = `${typeStyles.icon} text-xl`; |
| icon.appendChild(iconElement); |
| toast.appendChild(icon); |
| } |
| |
| // Add content |
| const content = document.createElement('div'); |
| content.className = 'flex-1'; |
| const messageElement = document.createElement('p'); |
| messageElement.className = 'font-medium'; |
| messageElement.textContent = message; |
| content.appendChild(messageElement); |
| toast.appendChild(content); |
| |
| // Add close button |
| if (showCloseButton) { |
| const closeBtn = document.createElement('button'); |
| closeBtn.className = 'ml-3 opacity-70 hover:opacity-100'; |
| closeBtn.innerHTML = '<i class="fas fa-times"></i>'; |
| closeBtn.addEventListener('click', function() { |
| hideToast(toast); |
| }); |
| toast.appendChild(closeBtn); |
| } |
| |
| // Add progress bar |
| if (showProgressBar) { |
| const progressBar = document.createElement('div'); |
| progressBar.className = 'toast-progress'; |
| progressBar.style.backgroundColor = `rgba(255, 255, 255, 0.7)`; |
| toast.appendChild(progressBar); |
| |
| // Animate progress bar |
| progressBar.style.transform = 'scaleX(1)'; |
| progressBar.style.transition = `transform ${duration}ms linear`; |
| setTimeout(() => { |
| progressBar.style.transform = 'scaleX(0)'; |
| }, 10); |
| } |
| |
| // Add to container |
| toastContainer.appendChild(toast); |
| |
| // Show toast with animation |
| setTimeout(() => { |
| toast.classList.add('show'); |
| }, 10); |
| |
| // Auto hide after duration |
| if (duration > 0) { |
| setTimeout(() => { |
| hideToast(toast); |
| }, duration); |
| } |
| |
| // Add to history |
| addToHistory(type, message); |
| |
| return toast; |
| } |
| |
| function showDemoToast(type, title, message, customStyles = {}) { |
| const toast = showToast(type, message); |
| |
| if (customStyles.bgColor) { |
| toast.style.backgroundColor = customStyles.bgColor; |
| } |
| if (customStyles.textColor) { |
| toast.style.color = customStyles.textColor; |
| } |
| if (customStyles.icon) { |
| const icon = toast.querySelector('i'); |
| if (icon) { |
| icon.className = `${customStyles.icon} text-xl`; |
| } |
| } |
| |
| // Update title if provided |
| const content = toast.querySelector('.flex-1'); |
| if (content && title) { |
| const titleElement = document.createElement('p'); |
| titleElement.className = 'font-bold'; |
| titleElement.textContent = title; |
| content.insertBefore(titleElement, content.firstChild); |
| } |
| } |
| |
| function hideToast(toast) { |
| toast.classList.remove('show'); |
| toast.classList.add('hide'); |
| |
| setTimeout(() => { |
| toast.remove(); |
| }, 300); |
| } |
| |
| function clearAllToasts() { |
| const toasts = toastContainer.querySelectorAll('.toast'); |
| toasts.forEach(toast => { |
| hideToast(toast); |
| }); |
| } |
| |
| function addToHistory(type, message) { |
| const historyContainer = document.getElementById('toastHistory'); |
| const historyItem = document.createElement('div'); |
| historyItem.className = 'flex items-center p-2 bg-gray-50 rounded-md'; |
| |
| // Add type indicator |
| const typeIndicator = document.createElement('div'); |
| typeIndicator.className = `w-3 h-3 rounded-full mr-2 ${ |
| type === 'info' ? 'bg-blue-500' : |
| type === 'success' ? 'bg-green-500' : |
| type === 'warning' ? 'bg-yellow-500' : |
| type === 'error' ? 'bg-red-500' : 'bg-purple-500' |
| }`; |
| historyItem.appendChild(typeIndicator); |
| |
| // Add message |
| const messageElement = document.createElement('span'); |
| messageElement.className = 'text-sm text-gray-700'; |
| messageElement.textContent = message.length > 50 ? message.substring(0, 50) + '...' : message; |
| historyItem.appendChild(messageElement); |
| |
| // Add timestamp |
| const timestamp = document.createElement('span'); |
| timestamp.className = 'ml-auto text-xs text-gray-500'; |
| timestamp.textContent = new Date().toLocaleTimeString(); |
| historyItem.appendChild(timestamp); |
| |
| // Add to history |
| historyContainer.insertBefore(historyItem, historyContainer.firstChild); |
| |
| // Limit history items |
| if (historyContainer.children.length > 10) { |
| historyContainer.removeChild(historyContainer.lastChild); |
| } |
| } |
| |
| function generateExportCode() { |
| const message = document.getElementById('message').value; |
| const duration = document.getElementById('duration').value; |
| const showProgressBar = document.getElementById('progressBar').checked; |
| const showCloseButton = document.getElementById('closeButton').checked; |
| const showIcon = document.getElementById('showIcon').checked; |
| |
| const code = ` |
| // Toast Configuration |
| const toastConfig = { |
| type: '${currentType}', |
| message: '${message.replace(/'/g, "\\'")}', |
| position: '${currentPosition}', |
| duration: ${duration}, |
| animation: '${currentAnimation}', |
| showProgressBar: ${showProgressBar}, |
| showCloseButton: ${showCloseButton}, |
| showIcon: ${showIcon}, |
| backgroundColor: '${currentBgColor}', |
| textColor: '${currentTextColor}', |
| fontFamily: '${currentFontFamily}', |
| fontSize: '${currentFontSize}' |
| }; |
| |
| // Function to show toast |
| function showToast(config) { |
| const toast = document.createElement('div'); |
| toast.className = \`toast \${config.animation}\`; |
| toast.style.backgroundColor = config.backgroundColor; |
| toast.style.color = config.textColor; |
| toast.style.fontFamily = config.fontFamily; |
| toast.style.fontSize = config.fontSize; |
| toast.style.borderRadius = '0.375rem'; |
| toast.style.padding = '1rem'; |
| toast.style.display = 'flex'; |
| toast.style.alignItems = 'flex-start'; |
| toast.style.maxWidth = '350px'; |
| |
| // Add icon |
| if (config.showIcon) { |
| const icon = document.createElement('div'); |
| icon.className = 'mr-3'; |
| const iconElement = document.createElement('i'); |
| iconElement.className = \`\${getIconClass(config.type)} text-xl\`; |
| icon.appendChild(iconElement); |
| toast.appendChild(icon); |
| } |
| |
| // Add content |
| const content = document.createElement('div'); |
| content.className = 'flex-1'; |
| const messageElement = document.createElement('p'); |
| messageElement.className = 'font-medium'; |
| messageElement.textContent = config.message; |
| content.appendChild(messageElement); |
| toast.appendChild(content); |
| |
| // Add close button |
| if (config.showCloseButton) { |
| const closeBtn = document.createElement('button'); |
| closeBtn.className = 'ml-3 opacity-70 hover:opacity-100'; |
| closeBtn.innerHTML = '<i class="fas fa-times"></i>'; |
| closeBtn.addEventListener('click', function() { |
| hideToast(toast); |
| }); |
| toast.appendChild(closeBtn); |
| } |
| |
| // Add progress bar |
| if (config.showProgressBar) { |
| const progressBar = document.createElement('div'); |
| progressBar.className = 'toast-progress'; |
| progressBar.style.backgroundColor = \`rgba(255, 255, 255, 0.7)\`; |
| toast.appendChild(progressBar); |
| |
| // Animate progress bar |
| progressBar.style.transform = 'scaleX(1)'; |
| progressBar.style.transition = \`transform \${config.duration}ms linear\`; |
| setTimeout(() => { |
| progressBar.style.transform = 'scaleX(0)'; |
| }, 10); |
| } |
| |
| // Add to container |
| const container = document.querySelector(\`.toast-container.\${config.position.replace(' ', '-')}\`); |
| container.appendChild(toast); |
| |
| // Show toast with animation |
| setTimeout(() => { |
| toast.classList.add('show'); |
| }, 10); |
| |
| // Auto hide after duration |
| if (config.duration > 0) { |
| setTimeout(() => { |
| hideToast(toast); |
| }, config.duration); |
| } |
| } |
| |
| // Helper function to get icon class |
| function getIconClass(type) { |
| switch(type) { |
| case 'info': return 'fas fa-info-circle'; |
| case 'success': return 'fas fa-check-circle'; |
| case 'warning': return 'fas fa-exclamation-triangle'; |
| case 'error': return 'fas fa-times-circle'; |
| default: return 'fas fa-info-circle'; |
| } |
| } |
| |
| // Function to hide toast |
| function hideToast(toast) { |
| toast.classList.remove('show'); |
| toast.classList.add('hide'); |
| |
| setTimeout(() => { |
| toast.remove(); |
| }, 300); |
| } |
| |
| // Example usage |
| showToast(toastConfig); |
| `; |
| |
| exportCode.textContent = code; |
| } |
| |
| function copyToClipboard(text) { |
| const textarea = document.createElement('textarea'); |
| textarea.value = text; |
| document.body.appendChild(textarea); |
| textarea.select(); |
| document.execCommand('copy'); |
| document.body.removeChild(textarea); |
| } |
| |
| function downloadCode() { |
| const code = exportCode.textContent; |
| const blob = new Blob([code], { type: 'text/javascript' }); |
| const url = URL.createObjectURL(blob); |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = 'toast-notification.js'; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| |
| showToast('success', 'Code downloaded successfully!'); |
| } |
| }); |
| </script> |
| </body> |
| </html> |