83 lines
2.5 KiB
TypeScript
83 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { Input } from "@/components/ui/input";
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface ConverterCardAmountInputProps {
|
|
amountInput: string;
|
|
amountPrefix?: string;
|
|
amountInputPaddingLeft?: string;
|
|
amountError: string | null;
|
|
quickAmounts: readonly number[];
|
|
activeQuickAmount: number | null;
|
|
onAmountChange: (nextValue: string) => void;
|
|
onQuickAmountSelect: (value: number) => void;
|
|
}
|
|
|
|
export function ConverterCardAmountInput({
|
|
amountInput,
|
|
amountPrefix,
|
|
amountInputPaddingLeft,
|
|
amountError,
|
|
quickAmounts,
|
|
activeQuickAmount,
|
|
onAmountChange,
|
|
onQuickAmountSelect,
|
|
}: ConverterCardAmountInputProps) {
|
|
return (
|
|
<div className="space-y-2">
|
|
<label
|
|
htmlFor="amount"
|
|
className="text-xs uppercase tracking-[0.14em] text-muted-foreground"
|
|
>
|
|
Amount
|
|
</label>
|
|
<div className="relative">
|
|
{amountPrefix ? (
|
|
<span className="pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-sm text-muted-foreground/80">
|
|
{amountPrefix}
|
|
</span>
|
|
) : null}
|
|
<Input
|
|
id="amount"
|
|
type="text"
|
|
inputMode="decimal"
|
|
value={amountInput}
|
|
onChange={(event) => onAmountChange(event.target.value)}
|
|
placeholder="Enter amount"
|
|
className="h-14 rounded-xl bg-background/70 px-4 text-lg"
|
|
style={amountInputPaddingLeft ? { paddingLeft: amountInputPaddingLeft } : undefined}
|
|
aria-invalid={Boolean(amountError)}
|
|
aria-describedby={amountError ? "amount-error" : undefined}
|
|
/>
|
|
</div>
|
|
<div className="flex flex-wrap items-center gap-2 pt-1">
|
|
{quickAmounts.map((quickAmount) => (
|
|
<Button
|
|
key={quickAmount}
|
|
type="button"
|
|
variant="outline"
|
|
size="sm"
|
|
onClick={() => onQuickAmountSelect(quickAmount)}
|
|
className={cn(
|
|
"h-7 rounded-full border-border/70 px-3 text-xs text-muted-foreground transition-colors hover:text-foreground",
|
|
activeQuickAmount === quickAmount
|
|
? "border-cyan-300/50 bg-cyan-500/15 text-cyan-100"
|
|
: "",
|
|
)}
|
|
aria-label={`Set amount to ${quickAmount}`}
|
|
>
|
|
{quickAmount}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
{amountError ? (
|
|
<p id="amount-error" className="text-sm text-red-300">
|
|
{amountError}
|
|
</p>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|