/* Design-system primitives ported from the Leeworks kit: flat, dark, border-led. * Every value rendered here comes from the API and is placed via React children / * textContent — never dangerouslySetInnerHTML — so agent-authored strings stay inert. */ "use client"; import type { ReactNode, ChangeEvent } from "react"; import type { Tone } from "@/lib/format"; import { statusLabel, statusTone } from "@/lib/format"; export function Badge({ tone = "neutral", pill = false, dot = false, children, }: { tone?: Tone; pill?: boolean; dot?: boolean; children: ReactNode; }) { return ( {dot && } {children} ); } /** Status badge that maps a raw handler status string to a tone + tidy label. */ export function StatusBadge({ status }: { status: string | null | undefined }) { return {statusLabel(status)}; } export function Card({ children, interactive = false, onClick, className = "", }: { children: ReactNode; interactive?: boolean; onClick?: () => void; className?: string; }) { return (
{children}
); } type ButtonVariant = "primary" | "secondary" | "ghost" | "danger"; export function Button({ variant = "secondary", size = "md", onClick, disabled, type = "button", children, }: { variant?: ButtonVariant; size?: "md" | "sm"; onClick?: () => void; disabled?: boolean; type?: "button" | "submit"; children: ReactNode; }) { return ( ); } export function Field({ label, children }: { label?: string; children: ReactNode }) { return ( ); } export function Input({ label, value, onChange, placeholder, type = "text", disabled, }: { label?: string; value: string; onChange: (v: string) => void; placeholder?: string; type?: string; disabled?: boolean; }) { return ( ) => onChange(e.target.value)} /> ); } export function Textarea({ label, value, onChange, placeholder, rows = 3, }: { label?: string; value: string; onChange: (v: string) => void; placeholder?: string; rows?: number; }) { return (