40 lines
1.6 KiB
React
40 lines
1.6 KiB
React
import React from "react";
|
|
|
|
const tones = {
|
|
neutral: { fg: "var(--text-secondary)", bg: "var(--ctv-surface-3)", bd: "var(--border-hairline)" },
|
|
accent: { fg: "var(--ctv-accent)", bg: "var(--ctv-accent-soft)", bd: "rgba(91,124,250,0.35)" },
|
|
ok: { fg: "var(--status-ok)", bg: "var(--ctv-ok-soft)", bd: "rgba(63,185,132,0.35)" },
|
|
warn: { fg: "var(--status-warn)", bg: "var(--ctv-warn-soft)", bd: "rgba(224,168,61,0.35)" },
|
|
error: { fg: "var(--status-error)", bg: "var(--ctv-error-soft)", bd: "rgba(229,72,77,0.35)" },
|
|
};
|
|
|
|
/**
|
|
* Small status/label badge. Soft (tinted) or solid.
|
|
*/
|
|
export function Badge({ children, tone = "neutral", solid = false, dot = false, style = {} }) {
|
|
const t = tones[tone] || tones.neutral;
|
|
const solidBg = { neutral: "var(--ctv-surface-3)", accent: "var(--ctv-accent)", ok: "var(--status-ok)", warn: "var(--status-warn)", error: "var(--status-error)" };
|
|
return (
|
|
<span
|
|
style={{
|
|
display: "inline-flex",
|
|
alignItems: "center",
|
|
gap: "5px",
|
|
height: "20px",
|
|
padding: dot ? "0 8px 0 6px" : "0 8px",
|
|
borderRadius: "var(--radius-xs)",
|
|
font: `var(--weight-medium) var(--text-2xs)/1 var(--font-sans)`,
|
|
letterSpacing: "0.02em",
|
|
color: solid ? (tone === "warn" ? "#1A1206" : "#fff") : t.fg,
|
|
background: solid ? solidBg[tone] : t.bg,
|
|
border: solid ? "1px solid transparent" : `1px solid ${t.bd}`,
|
|
whiteSpace: "nowrap",
|
|
...style,
|
|
}}
|
|
>
|
|
{dot && <span style={{ width: 6, height: 6, borderRadius: "50%", background: solid ? "rgba(255,255,255,0.9)" : t.fg }} />}
|
|
{children}
|
|
</span>
|
|
);
|
|
}
|