77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "framer-motion";
|
|
import { ArrowUpDown } from "lucide-react";
|
|
|
|
import { CurrencySelect } from "@/components/converter/currency-select";
|
|
import { Button } from "@/components/ui/button";
|
|
import type { RateAsset } from "@/lib/rates";
|
|
|
|
interface ConverterCardPairSelectionProps {
|
|
assets: RateAsset[];
|
|
fromCode: string;
|
|
toCode: string;
|
|
shouldReduceMotion: boolean;
|
|
swapAnimationStep: number;
|
|
onFromChange: (code: string) => void;
|
|
onToChange: (code: string) => void;
|
|
onSwap: () => void;
|
|
}
|
|
|
|
export function ConverterCardPairSelection({
|
|
assets,
|
|
fromCode,
|
|
toCode,
|
|
shouldReduceMotion,
|
|
swapAnimationStep,
|
|
onFromChange,
|
|
onToChange,
|
|
onSwap,
|
|
}: ConverterCardPairSelectionProps) {
|
|
return (
|
|
<div className="grid gap-3 sm:grid-cols-[1fr_auto_1fr] sm:items-end">
|
|
<CurrencySelect
|
|
label="From"
|
|
value={fromCode}
|
|
onChange={onFromChange}
|
|
assets={assets}
|
|
/>
|
|
<Button
|
|
type="button"
|
|
size="icon"
|
|
variant="outline"
|
|
className="mx-auto mb-0.5 rounded-full border-border/70 bg-background/50"
|
|
onClick={onSwap}
|
|
aria-label="Swap currencies"
|
|
>
|
|
<motion.span
|
|
className="inline-flex"
|
|
animate={
|
|
shouldReduceMotion
|
|
? { scale: 1 }
|
|
: { rotate: swapAnimationStep * 180, scale: [1, 1.08, 1] }
|
|
}
|
|
transition={{
|
|
rotate: {
|
|
duration: shouldReduceMotion ? 0.01 : 0.28,
|
|
ease: [0.22, 1, 0.36, 1],
|
|
},
|
|
scale: {
|
|
duration: shouldReduceMotion ? 0.01 : 0.22,
|
|
times: [0, 0.35, 1],
|
|
},
|
|
}}
|
|
>
|
|
<ArrowUpDown className="h-4 w-4" />
|
|
</motion.span>
|
|
</Button>
|
|
<CurrencySelect
|
|
label="To"
|
|
value={toCode}
|
|
onChange={onToChange}
|
|
assets={assets}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|