Promote classifier's local toast (classifier/css/base.css + showToast
in classifier/js/excel.js) into shared/toast.{js,css}. Every tool's
build.sh now concatenates them, so window.zddc.toast(msg, level, opts)
is callable from any tool.
API:
window.zddc.toast('Saved.', 'success');
window.zddc.toast('Could not load: ' + err.message, 'error');
window.zddc.toast('Note', 'info', { durationMs: 3000 });
Levels: info (default) | success | warning | error. Single-toast
policy — a second call replaces the first. Click anywhere on the
toast to dismiss. ARIA: error → role=alert/aria-live=assertive,
others → role=status/aria-live=polite.
Class prefix is .zddc-toast (BEM-ish) to avoid colliding with any
tool-local .toast rules. Classifier's existing showToast now
delegates to window.zddc.toast — call sites in excel.js +
selection.js are unchanged. Classifier's local .toast CSS block
deleted in favor of the shared one.
This commit only EXPOSES the API. Replacing the ~25 alert() call
sites scattered across archive/transmittal/mdedit/classifier with
toast calls is left as follow-up — each alert needs per-call review
to decide if it's truly non-blocking.
Five Playwright tests in tests/toast.spec.js lock the contract:
API exposure, level mapping, ARIA roles, single-toast replace,
click-to-dismiss.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
40 lines
1.3 KiB
CSS
40 lines
1.3 KiB
CSS
/* shared/toast.css — single-toast notification styles paired with
|
|
shared/toast.js. Uses BEM-ish .zddc-toast prefix to avoid collisions
|
|
with tool-local .toast classes; the old classifier rules can stay
|
|
alongside until this file is concatenated above them in the build. */
|
|
|
|
.zddc-toast {
|
|
position: fixed;
|
|
bottom: 2rem;
|
|
right: 2rem;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
padding: 0.875rem 1.25rem;
|
|
border-radius: var(--radius);
|
|
border: 1px solid var(--border);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
z-index: 9000;
|
|
max-width: 400px;
|
|
font-size: 0.875rem;
|
|
cursor: pointer;
|
|
animation: zddc-toast-in 0.3s ease-out;
|
|
}
|
|
|
|
.zddc-toast--success { border-left: 4px solid var(--success); }
|
|
.zddc-toast--error { border-left: 4px solid var(--danger); }
|
|
.zddc-toast--info { border-left: 4px solid var(--info); }
|
|
.zddc-toast--warning { border-left: 4px solid var(--warning); }
|
|
|
|
.zddc-toast--fade {
|
|
animation: zddc-toast-out 0.3s ease-out forwards;
|
|
}
|
|
|
|
@keyframes zddc-toast-in {
|
|
from { transform: translateX(100%); opacity: 0; }
|
|
to { transform: translateX(0); opacity: 1; }
|
|
}
|
|
|
|
@keyframes zddc-toast-out {
|
|
from { transform: translateX(0); opacity: 1; }
|
|
to { transform: translateX(100%); opacity: 0; }
|
|
}
|