general 10. März 2024

Tailwind UI Components

Wiederverwendbare UI-Komponenten: Toast Notifications, Modal, Loading Skeleton, und Dark Mode Toggle.

tailwindcsshtmluicomponents

Toast Notification System

Minimales Toast System mit CSS Animationen.

<div id="toast-container" class="fixed top-4 right-4 z-50 flex flex-col gap-2"></div>

<script>
function showToast(message, type = 'info') {
  const container = document.getElementById('toast-container');
  const colors = {
    success: 'bg-green-500/90 border-green-400',
    error: 'bg-red-500/90 border-red-400',
    info: 'bg-blue-500/90 border-blue-400',
    warning: 'bg-yellow-500/90 border-yellow-400',
  };

  const toast = document.createElement('div');
  toast.className = `px-4 py-3 rounded-lg border text-white text-sm shadow-lg backdrop-blur-sm
    transform translate-x-full animate-slide-in ${colors[type]}`;
  toast.textContent = message;

  container.appendChild(toast);
  setTimeout(() => {
    toast.classList.add('animate-slide-out');
    setTimeout(() => toast.remove(), 300);
  }, 3000);
}
</script>

<style>
@keyframes slide-in { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes slide-out { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } }
.animate-slide-in { animation: slide-in 0.3s ease-out forwards; }
.animate-slide-out { animation: slide-out 0.3s ease-in forwards; }
</style>
<dialog id="modal" class="bg-transparent backdrop:bg-black/60 backdrop:backdrop-blur-sm p-0 max-w-lg w-full">
  <div class="bg-gray-900 border border-gray-700 rounded-xl p-6 text-white">
    <div class="flex justify-between items-center mb-4">
      <h3 class="text-lg font-semibold" id="modal-title">Modal Title</h3>
      <button onclick="document.getElementById('modal').close()" class="text-gray-400 hover:text-white">
        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
        </svg>
      </button>
    </div>
    <div id="modal-content" class="text-gray-300">Content here</div>
    <div class="mt-6 flex gap-3 justify-end">
      <button onclick="document.getElementById('modal').close()" class="px-4 py-2 rounded-lg bg-gray-800 hover:bg-gray-700 text-sm">Abbrechen</button>
      <button class="px-4 py-2 rounded-lg bg-brand-600 hover:bg-brand-500 text-sm font-medium">Bestätigen</button>
    </div>
  </div>
</dialog>

<script>
function openModal(title, content) {
  document.getElementById('modal-title').textContent = title;
  document.getElementById('modal-content').innerHTML = content;
  document.getElementById('modal').showModal();
}
</script>

Loading Skeleton

<div class="animate-pulse space-y-4">
  <div class="h-4 bg-gray-800 rounded w-3/4"></div>
  <div class="h-4 bg-gray-800 rounded w-1/2"></div>
  <div class="h-32 bg-gray-800 rounded"></div>
  <div class="flex gap-2">
    <div class="h-6 w-16 bg-gray-800 rounded-full"></div>
    <div class="h-6 w-20 bg-gray-800 rounded-full"></div>
    <div class="h-6 w-14 bg-gray-800 rounded-full"></div>
  </div>
</div>