47 lines
2.3 KiB
React
47 lines
2.3 KiB
React
import React from "react";
|
|
|
|
const map = {
|
|
ok: { c: "var(--status-ok)", bg: "var(--ctv-ok-soft)", icon: "M5 12.5l4.5 4.5L19 7" },
|
|
warn: { c: "var(--status-warn)", bg: "var(--ctv-warn-soft)", icon: "M12 8v5M12 17h.01" },
|
|
error: { c: "var(--status-error)", bg: "var(--ctv-error-soft)", icon: "M12 8v5M12 17h.01" },
|
|
info: { c: "var(--ctv-accent)", bg: "var(--ctv-accent-soft)", icon: "M12 11v5M12 8h.01" },
|
|
};
|
|
|
|
/**
|
|
* Toast / inline alert. Icon, message, optional close.
|
|
*/
|
|
export function Toast({ tone = "info", title, message, onClose, style = {} }) {
|
|
const t = map[tone] || map.info;
|
|
return (
|
|
<div
|
|
role="status"
|
|
style={{
|
|
display: "flex",
|
|
alignItems: "flex-start",
|
|
gap: "11px",
|
|
width: "min(380px, 100%)",
|
|
padding: "12px 13px",
|
|
background: "var(--surface-raised)",
|
|
border: "1px solid var(--border-hairline)",
|
|
borderLeft: `2px solid ${t.c}`,
|
|
borderRadius: "var(--radius-md)",
|
|
boxShadow: "var(--shadow-md)",
|
|
...style,
|
|
}}
|
|
>
|
|
<span style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", width: 22, height: 22, borderRadius: "var(--radius-xs)", background: t.bg, flex: "0 0 auto", marginTop: 1 }}>
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke={t.c} strokeWidth="0" fill="none" /><path d={t.icon} stroke={t.c} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" /></svg>
|
|
</span>
|
|
<div style={{ flex: 1, minWidth: 0 }}>
|
|
{title && <div style={{ font: "var(--weight-semibold) var(--text-sm)/1.3 var(--font-sans)", color: "var(--text-primary)" }}>{title}</div>}
|
|
{message && <div style={{ marginTop: title ? 2 : 0, font: "var(--text-xs)/1.45 var(--font-sans)", color: "var(--text-secondary)" }}>{message}</div>}
|
|
</div>
|
|
{onClose && (
|
|
<button type="button" onClick={onClose} aria-label="Dismiss" style={{ display: "inline-flex", padding: 3, border: "none", background: "transparent", color: "var(--text-disabled)", cursor: "pointer", flex: "0 0 auto" }}>
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" /></svg>
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|