Files
crank/apps/ui/js/ui-feedback.js
T
github-ops ba29ac7b94
Deploy / deploy (push) Successful in 2m44s
CI / Rust Checks (push) Successful in 5m31s
CI / UI Checks (push) Successful in 5s
CI / Deployment Manifests (push) Successful in 2s
CI / Frontend E2E (push) Successful in 4m24s
chore: publish clean community baseline
2026-06-19 16:45:51 +00:00

106 lines
3.2 KiB
JavaScript

(function() {
var CONTAINER_ID = 'crank-toast-container';
var nextToastId = 0;
function ensureContainer() {
var container = document.getElementById(CONTAINER_ID);
if (container) return container;
container = document.createElement('div');
container.id = CONTAINER_ID;
container.className = 'toast-stack';
document.body.appendChild(container);
return container;
}
function dismiss(toast) {
if (!toast || !toast.parentNode) return;
toast.classList.add('closing');
window.setTimeout(function() {
if (toast.parentNode) toast.parentNode.removeChild(toast);
}, 180);
}
function notify(options) {
var config = options || {};
var duration = config.duration === 0 ? 0 : (config.duration || 3600);
var toast = document.createElement('div');
var copy = document.createElement('div');
var close = document.createElement('button');
var closeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var lineA = document.createElementNS('http://www.w3.org/2000/svg', 'line');
var lineB = document.createElementNS('http://www.w3.org/2000/svg', 'line');
toast.id = 'toast_' + (++nextToastId);
toast.className = 'toast-card toast-' + (config.type || 'info');
copy.className = 'toast-copy';
if (config.title) {
var title = document.createElement('div');
title.className = 'toast-title';
title.textContent = config.title;
copy.appendChild(title);
}
if (config.message) {
var message = document.createElement('div');
message.className = 'toast-message';
message.textContent = config.message;
copy.appendChild(message);
}
close.className = 'toast-close';
close.type = 'button';
close.setAttribute('aria-label', 'Dismiss');
closeIcon.setAttribute('width', '12');
closeIcon.setAttribute('height', '12');
closeIcon.setAttribute('viewBox', '0 0 12 12');
closeIcon.setAttribute('fill', 'none');
closeIcon.setAttribute('stroke', 'currentColor');
closeIcon.setAttribute('stroke-width', '1.8');
closeIcon.setAttribute('stroke-linecap', 'round');
lineA.setAttribute('x1', '1');
lineA.setAttribute('y1', '1');
lineA.setAttribute('x2', '11');
lineA.setAttribute('y2', '11');
lineB.setAttribute('x1', '11');
lineB.setAttribute('y1', '1');
lineB.setAttribute('x2', '1');
lineB.setAttribute('y2', '11');
closeIcon.appendChild(lineA);
closeIcon.appendChild(lineB);
close.appendChild(closeIcon);
toast.appendChild(copy);
toast.appendChild(close);
close.addEventListener('click', function() {
dismiss(toast);
});
ensureContainer().appendChild(toast);
if (duration > 0) {
window.setTimeout(function() {
dismiss(toast);
}, duration);
}
return toast.id;
}
window.CrankUi = {
notify: notify,
success: function(message, title) {
return notify({ type: 'success', title: title || 'Done', message: message });
},
error: function(message, title) {
return notify({ type: 'error', title: title || 'Request failed', message: message });
},
info: function(message, title) {
return notify({ type: 'info', title: title || 'Info', message: message });
}
};
}());