Tips & Tricks

Cara Implement Toast Notifications dengan Claude Code

Pelajari cara implement toast notifications menggunakan Claude Code. Dilengkapi contoh kode praktis dan panduan langkah demi langkah.

設計 toastnotifikasi

toastnotifikasi operasi結果やsistempesan 一時的 tampilan UIpola.modal dan 違いpengguna operasi 妨げ tidak untuk 、フィードバック 最適.Claude Code 使えば、アクセシブル 美しいtoastnotifikasisistem pembangunan bisa dilakukan.

implementasi toastmanajemensistem

> グローバル 使えるtoastnotifikasisistem buatkan.
> success, error, warning, info 4種類 support.
type ToastType = 'success' | 'error' | 'warning' | 'info';

interface Toast {
  id: string;
  type: ToastType;
  message: string;
  duration: number;
  dismissible: boolean;
}

type ToastListener = (toasts: Toast[]) => void;

class ToastManager {
  private toasts: Toast[] = [];
  private listeners: Set<ToastListener> = new Set();
  private counter = 0;

  subscribe(listener: ToastListener) {
    this.listeners.add(listener);
    return () => this.listeners.delete(listener);
  }

  private notify() {
    this.listeners.forEach((fn) => fn([...this.toasts]));
  }

  add(type: ToastType, message: string, options?: Partial<Pick<Toast, 'duration' | 'dismissible'>>) {
    const id = `toast-${++this.counter}`;
    const toast: Toast = {
      id,
      type,
      message,
      duration: options?.duration ?? 5000,
      dismissible: options?.dismissible ?? true,
    };

    this.toasts = [...this.toasts, toast];
    this.notify();

    if (toast.duration > 0) {
      setTimeout(() => this.remove(id), toast.duration);
    }

    return id;
  }

  remove(id: string) {
    this.toasts = this.toasts.filter((t) => t.id !== id);
    this.notify();
  }

  success(message: string) { return this.add('success', message); }
  error(message: string) { return this.add('error', message, { duration: 8000 }); }
  warning(message: string) { return this.add('warning', message); }
  info(message: string) { return this.add('info', message); }
}

export const toast = new ToastManager();

Reactkomponen

import { useState, useEffect } from 'react';

const ICONS: Record<ToastType, string> = {
  success: '✓',
  error: '✕',
  warning: '⚠',
  info: 'ℹ',
};

const STYLES: Record<ToastType, string> = {
  success: 'bg-green-50 border-green-200 text-green-800',
  error: 'bg-red-50 border-red-200 text-red-800',
  warning: 'bg-yellow-50 border-yellow-200 text-yellow-800',
  info: 'bg-blue-50 border-blue-200 text-blue-800',
};

function ToastContainer() {
  const [toasts, setToasts] = useState<Toast[]>([]);

  useEffect(() => {
    return toast.subscribe(setToasts);
  }, []);

  return (
    <div
      aria-live="polite"
      aria-label="notifikasi"
      className="fixed top-4 right-4 z-50 flex flex-col gap-2 max-w-sm w-full"
    >
      {toasts.map((t) => (
        <div
          key={t.id}
          role="status"
          className={`flex items-start gap-3 p-4 rounded-lg border shadow-lg
            animate-slideIn ${STYLES[t.type]}`}
        >
          <span className="text-lg font-bold flex-shrink-0">{ICONS[t.type]}</span>
          <p className="flex-1 text-sm">{t.message}</p>
          {t.dismissible && (
            <button
              onClick={() => toast.remove(t.id)}
              aria-label="notifikasi Close"
              className="text-gray-400 hover:text-gray-600"
            >✕</button>
          )}
        </div>
      ))}
    </div>
  );
}

animasi

@keyframes slideIn {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes slideOut {
  from {
    transform: translateX(0);
    opacity: 1;
  }
  to {
    transform: translateX(100%);
    opacity: 0;
  }
}

.animate-slideIn {
  animation: slideIn 0.3s ease-out;
}

.animate-slideOut {
  animation: slideOut 0.3s ease-in forwards;
}

Pemanfaatan dengan React Hook

export function useToast() {
  return {
    success: (msg: string) => toast.success(msg),
    error: (msg: string) => toast.error(msg),
    warning: (msg: string) => toast.warning(msg),
    info: (msg: string) => toast.info(msg),
  };
}

// Usage example
function SaveButton() {
  const { success, error } = useToast();

  const handleSave = async () => {
    try {
      await saveData();
      success('penyimpananしま');
    } catch (e) {
      error('penyimpanan gagalしま。もう一度お試しください。');
    }
  };

  return <button onClick={handleSave}>保存</button>;
}

Summary

Untuk Claude Codeを使えば、type safetyでアクセシブルなtoastnotifikasisistemをanimasi付きで素早くpembangunanできます。modalとの使い分けはmodal・dialog設計を、animasi全般, lihat アニメーション実装.

WAI-ARIA ライブリージョン mengenai MDN Web Docs - aria-live silakan lihat.

#Claude Code #toast #notifikasi #React #UI