diff --git a/submissions/examples/toast/README.md b/submissions/examples/toast/README.md new file mode 100644 index 00000000..363b0945 --- /dev/null +++ b/submissions/examples/toast/README.md @@ -0,0 +1,39 @@ +# Toast Notification Component + +A fixed-position toast notification system with slide-in/slide-out animations, 4 color variants (success, danger, warning, info), dismiss close button, and 4 position options (top-right, top-left, bottom-right, bottom-left). Includes inline JavaScript for dynamic show/dismiss. + +## Classes + +| Class | Description | +|---|---| +| `ease-toast-container` | Fixed container for stacking toasts | +| `ease-toast-container--top-left` | Top-left position | +| `ease-toast-container--bottom-right` | Bottom-right position | +| `ease-toast-container--bottom-left` | Bottom-left position | +| `ease-toast` | Individual toast notification | +| `ease-toast--success` | Green accent (success) | +| `ease-toast--danger` | Red accent (error/danger) | +| `ease-toast--warning` | Amber accent (warning) | +| `ease-toast--info` | Blue accent (info) | +| `ease-toast-icon` | Icon circle | +| `ease-toast-msg` | Notification message | +| `ease-toast-close` | Dismiss button | +| `ease-toast--exit` | Exit animation state (added via JS) | + +## Usage + +```html +
+ +
+``` + +See `demo.html` for the full JS setup (dynamic creation, auto-dismiss after 4s, close button handler). + +## Why it fits EaseMotion CSS + +Smooth slide-in entrance animation (`ease-kf-toast-in`) and fade-out exit animation, 4 color variants with accent borders and icon backgrounds, position modifiers for all 4 corners, and stacking container. Respects `prefers-reduced-motion`. diff --git a/submissions/examples/toast/demo.html b/submissions/examples/toast/demo.html new file mode 100644 index 00000000..e89624ad --- /dev/null +++ b/submissions/examples/toast/demo.html @@ -0,0 +1,86 @@ + + + + + + Toast Notifications — EaseMotion CSS + + + + +
+ + + + +
+ +
+ + + + +
+ + + + + diff --git a/submissions/examples/toast/style.css b/submissions/examples/toast/style.css new file mode 100644 index 00000000..d084064d --- /dev/null +++ b/submissions/examples/toast/style.css @@ -0,0 +1,195 @@ +/* ============================================================ + EaseMotion CSS — Toast Notification Component + Issue #1184 + ============================================================ */ + +/* ── Container ────────────────────────────────────────────── */ + +.ease-toast-container { + position: fixed; + top: var(--ease-space-4, 1rem); + right: var(--ease-space-4, 1rem); + z-index: 9999; + display: flex; + flex-direction: column; + gap: var(--ease-space-3, 0.75rem); + pointer-events: none; + max-width: 420px; + width: calc(100% - 2rem); +} + +/* ── Position variants ───────────────────────────────────── */ + +.ease-toast-container--top-left { + top: var(--ease-space-4, 1rem); + left: var(--ease-space-4, 1rem); + right: auto; +} + +.ease-toast-container--bottom-right { + top: auto; + bottom: var(--ease-space-4, 1rem); + right: var(--ease-space-4, 1rem); +} + +.ease-toast-container--bottom-left { + top: auto; + bottom: var(--ease-space-4, 1rem); + left: var(--ease-space-4, 1rem); + right: auto; +} + +/* ── Individual toast ────────────────────────────────────── */ + +.ease-toast { + display: flex; + align-items: center; + gap: var(--ease-space-3, 0.75rem); + padding: 14px 18px; + background: #1a1a24; + border: 1.5px solid rgba(255, 255, 255, 0.08); + border-radius: var(--ease-radius-md, 0.625rem); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + pointer-events: auto; + min-width: 260px; + animation: ease-kf-toast-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) both; + transition: opacity 0.3s ease, transform 0.3s ease; +} + +/* ── Color variant: left accent border ────────────────────── */ + +.ease-toast--success { + border-left: 4px solid #22c55e; +} + +.ease-toast--danger { + border-left: 4px solid #ef4444; +} + +.ease-toast--warning { + border-left: 4px solid #f59e0b; +} + +.ease-toast--info { + border-left: 4px solid #3b82f6; +} + +/* ── Icon ─────────────────────────────────────────────────── */ + +.ease-toast-icon { + flex-shrink: 0; + width: 22px; + height: 22px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + font-size: var(--ease-text-xs, 0.75rem); + font-weight: 700; + line-height: 1; +} + +.ease-toast--success .ease-toast-icon { + background: rgba(34, 197, 94, 0.15); + color: #22c55e; +} + +.ease-toast--danger .ease-toast-icon { + background: rgba(239, 68, 68, 0.15); + color: #ef4444; +} + +.ease-toast--warning .ease-toast-icon { + background: rgba(245, 158, 11, 0.15); + color: #f59e0b; +} + +.ease-toast--info .ease-toast-icon { + background: rgba(59, 130, 246, 0.15); + color: #3b82f6; +} + +/* ── Message ──────────────────────────────────────────────── */ + +.ease-toast-msg { + flex: 1; + font-size: var(--ease-text-sm, 0.875rem); + color: rgba(255, 255, 255, 0.85); + line-height: 1.4; +} + +/* ── Close button ─────────────────────────────────────────── */ + +.ease-toast-close { + margin-left: auto; + flex-shrink: 0; + background: none; + border: none; + cursor: pointer; + padding: 2px 6px; + font-size: 1.25rem; + line-height: 1; + color: rgba(255, 255, 255, 0.3); + border-radius: var(--ease-radius-sm, 4px); + transition: + color var(--ease-speed-fast, 150ms) cubic-bezier(0.4, 0, 0.2, 1), + background var(--ease-speed-fast, 150ms) cubic-bezier(0.4, 0, 0.2, 1); +} + +.ease-toast-close:hover { + background: rgba(255, 255, 255, 0.08); + color: rgba(255, 255, 255, 0.7); +} + +/* ── Exit animation ──────────────────────────────────────── */ + +.ease-toast--exit { + opacity: 0; + transform: translateX(100%); +} + +.ease-toast-container--top-left .ease-toast--exit, +.ease-toast-container--bottom-left .ease-toast--exit { + transform: translateX(-100%); +} + +/* ── Keyframes ────────────────────────────────────────────── */ + +@keyframes ease-kf-toast-in { + from { + opacity: 0; + transform: translateX(100%); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.ease-toast-container--top-left .ease-toast, +.ease-toast-container--bottom-left .ease-toast { + animation-name: ease-kf-toast-in-left; +} + +@keyframes ease-kf-toast-in-left { + from { + opacity: 0; + transform: translateX(-100%); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +/* ── Reduced motion ──────────────────────────────────────── */ + +@media (prefers-reduced-motion: reduce) { + .ease-toast { + animation: none; + } + .ease-toast--exit { + opacity: 1; + transform: none; + } +}