import type { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import { formatUnits } from 'viem'
import { fmtAmount, sanitizeAmountInput } from '../lib/format'
export function Btn(props: {
onClick?: () => void
disabled?: boolean
tone?: 'default' | 'danger' | 'ghost' | 'amber'
big?: boolean
busy?: boolean
title?: string
children: ReactNode
}) {
const cls = ['btn', props.tone === 'default' ? '' : props.tone, props.big ? 'big' : '']
.filter(Boolean)
.join(' ')
return (
)
}
export function Badge(props: { tone?: 'green' | 'amber' | 'red' | 'cyan' | 'dim'; children: ReactNode }) {
return {props.children}
}
export function Stat(props: { k: string; v: ReactNode; sub?: ReactNode }) {
return (
{props.k}
{props.v}
{props.sub !== undefined &&
{props.sub}
}
)
}
/** amount input row: label + NumInput + wallet balance + MAX chip */
export function AmountRow(props: {
sym: string
value: string
onChange: (v: string) => void
bal?: bigint
dec: number
onMax: (v: string) => void
disabled?: boolean
note?: string
}) {
const { t } = useTranslation()
return (
{props.sym}
{props.bal !== undefined && (
<>
{t('common.bal')} {fmtAmount(props.bal, props.dec)}
>
)}
{props.note && {props.note}}
)
}
/** numeric text input that only accepts decimal strings */
export function NumInput(props: {
value: string
onChange: (v: string) => void
placeholder?: string
disabled?: boolean
width?: number
invalid?: boolean
/** clamp typed fraction digits (token precision); 18 = EVM max */
decimals?: number
}) {
return (
{
const v = sanitizeAmountInput(e.target.value, props.decimals ?? 18)
if (v !== null) props.onChange(v)
}}
/>
)
}