import type { ReactNode, CSSProperties } from 'react';
import { Stack, Cluster, Divider } from './Layout';
interface TerminalProps {
children: ReactNode;
title?: string;
subtitle?: string;
showBack?: boolean;
className?: string;
}
/**
* Terminal - main wrapper with brutalist monospace aesthetic
*/
export function Terminal({ children, title = '@toshi', subtitle, showBack = false, className = '' }: TerminalProps) {
const displayTitle = subtitle ? `${title} ${subtitle}` : title;
return (
{showBack && <}
{displayTitle}
{children}
);
}
interface SectionProps {
children: ReactNode;
title?: string;
}
/**
* Section - grouped content with optional title
*/
export function Section({ children, title }: SectionProps) {
return (
{title && {title}
}
{children}
);
}
interface LabelValueProps {
label: string;
value: ReactNode;
status?: 'default' | 'success' | 'error' | 'warning';
}
/**
* LabelValue - key-value display (e.g., "BALANCE: 1000")
*/
export function LabelValue({ label, value, status = 'default' }: LabelValueProps) {
return (
{label}:{' '}
{value}
);
}
interface DataRowProps {
cells: ReactNode[];
widths?: string[];
href?: string;
}
/**
* DataRow - single row in a data table
*/
export function DataRow({ cells, widths, href }: DataRowProps) {
const content = (
{cells.map((cell, i) => (
{cell}
))}
);
if (href) {
return {content};
}
return content;
}
interface DataTableProps {
headers: string[];
widths?: string[];
children: ReactNode;
emptyMessage?: string;
}
/**
* DataTable - tabular data display
*/
export function DataTable({ headers, widths, children, emptyMessage = '(no data)' }: DataTableProps) {
const hasChildren = Array.isArray(children) ? children.length > 0 : !!children;
return (
{headers.map((header, i) => (
{header}
))}
{hasChildren ? children :
{emptyMessage}
}
);
}
interface ActionBarProps {
children: ReactNode;
}
/**
* ActionBar - row of action buttons
*/
export function ActionBar({ children }: ActionBarProps) {
return (
{children}
);
}
interface StatusBadgeProps {
status: 'online' | 'offline' | 'loading';
label?: string;
}
/**
* StatusBadge - inline status indicator
*/
export function StatusBadge({ status, label }: StatusBadgeProps) {
const labels = {
online: 'ONLINE',
offline: 'OFFLINE',
loading: 'LOADING...',
};
return (
{label || labels[status]}
);
}
interface InputFieldProps {
label: string;
value: string;
onChange: (value: string) => void;
placeholder?: string;
type?: 'text' | 'number';
disabled?: boolean;
width?: string;
min?: number;
max?: number;
}
/**
* InputField - labeled input in terminal style
*/
export function InputField({
label,
value,
onChange,
placeholder,
type = 'text',
disabled = false,
width = '200px',
min,
max,
}: InputFieldProps) {
return (
{' '}
onChange(e.target.value)}
placeholder={placeholder}
disabled={disabled}
style={{ width }}
min={min}
max={max}
/>
);
}
interface MessageProps {
type: 'success' | 'error' | 'info';
children: ReactNode;
}
/**
* Message - styled message display
*/
export function Message({ type, children }: MessageProps) {
return (
{children}
);
}