refactor(converter): split converter card into modular section components
This commit is contained in:
82
components/converter/converter-card-amount-input.tsx
Normal file
82
components/converter/converter-card-amount-input.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user