|
<!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> |