/** @jsxImportSource @opentui/solid */
import { TextAttributes } from "@opentui/core"
import type { JSX } from "solid-js"
import { pct } from "./format"
import type { Theme, ThemeColor, TuiApi } from "./types"
export function DcpFrame(props: {
api: TuiApi
title?: string
eyebrow: string
children: JSX.Element
onBack?: () => void
}) {
const theme = props.api.theme.current
return (
{props.eyebrow}
{props.title ? (
{props.title}
) : null}
props.api.ui.dialog.clear()}>
esc
{props.children}
{props.onBack ? (
) : (
)}
props.api.ui.dialog.clear()}
/>
)
}
function FooterButton(props: {
theme: Theme
label: string
variant: "muted" | "primary"
onClick: () => void
}) {
const primary = props.variant === "primary"
return (
{props.label}
)
}
export function Card(props: { theme: Theme; title: string; children: JSX.Element }) {
const accent = props.theme.primary
return (
{props.title}
{props.children}
)
}
export function Metric(props: { theme: Theme; label: string; value: string; hint?: string }) {
return (
{props.label}
{props.value}
{props.hint ? {props.hint} : null}
)
}
export function Progress(props: {
theme: Theme
label: string
value: number
total: number
color: ThemeColor
detail: string
}) {
const width = 32
const filled =
props.total > 0 ? Math.max(0, Math.round((props.value / props.total) * width)) : 0
const empty = Math.max(0, width - filled)
return (
{props.label}
{pct(props.value, props.total)}
{props.detail}
{"█".repeat(filled)}
{"░".repeat(empty)}
)
}
export function PromptRow(props: {
theme: Theme
command: string
description: string
accent?: ThemeColor
}) {
const accent = props.theme[props.accent ?? "accent"]
return (
{props.command}
{props.description}
)
}
export function StatusPill(props: {
theme: Theme
label: string
value: string
accent: ThemeColor
}) {
const accent = props.theme[props.accent]
return (
{props.label}
{props.value}
)
}
export function ActionRow(props: {
theme: Theme
title: string
detail: string
onClick: () => void
}) {
const accent = props.theme.primary
return (
{props.title}
{props.detail}
open
)
}