style: add brands button motion

This commit is contained in:
Mahen 2026-02-24 22:54:39 +07:00
parent d7060c8248
commit b8135c3bff
1 changed files with 64 additions and 51 deletions

View File

@ -3,6 +3,8 @@
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useBrandFilter } from "@/src/hooks/useBrandFilter"; import { useBrandFilter } from "@/src/hooks/useBrandFilter";
import { Button } from "../ui/button"; import { Button } from "../ui/button";
import { ChevronRight } from "lucide-react";
import { motion } from "framer-motion";
export function BrandFilter() { export function BrandFilter() {
const { const {
@ -25,65 +27,76 @@ export function BrandFilter() {
} }
return ( return (
<div className="flex flex-wrap gap-2 animate-in fade-in slide-in-from-bottom-2"> <motion.div
<button initial={{ opacity: 0, y: 20 }}
onClick={() => handleSelect(null)} animate={{ opacity: 1, y: 0 }}
className={cn( transition={{ duration: 0.2, ease: "circOut" }}
"rounded-lg border px-4 py-2 text-sm font-medium transition-all cursor-pointer", className="flex items-center justify-center"
selectedBrand === null >
? "border-primary bg-primary text-primary-foreground"
: "border-border bg-card text-muted-foreground hover:border-primary/50 hover:text-foreground",
)}
>
Semua ({totalCount.toLocaleString()})
</button>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
{visibleBrands.map((brand) => { <button
const isActive = onClick={() => handleSelect(null)}
selectedBrand?.toLowerCase() === brand.name.toLowerCase(); className={cn(
"rounded-lg border px-4 py-2 text-sm font-medium transition-all cursor-pointer",
selectedBrand === null
? "border-primary bg-primary text-primary-foreground"
: "border-border bg-card text-muted-foreground hover:border-primary/50 hover:text-foreground",
)}
>
Semua ({totalCount.toLocaleString()})
</button>
return ( <div className="flex flex-wrap gap-2">
{visibleBrands.map((brand) => {
const isActive =
selectedBrand?.toLowerCase() === brand.name.toLowerCase();
return (
<button
key={brand.name}
onClick={() => handleSelect(brand.name)}
className={cn(
"rounded-lg border px-4 py-2 text-sm font-medium transition-all cursor-pointer",
isActive
? "border-primary bg-primary text-primary-foreground"
: "border-border bg-card text-muted-foreground hover:border-primary/50 hover:text-foreground",
)}
>
{brand.name} ({brand.count.toLocaleString()})
</button>
);
})}
{!isExpanded && validBrands.length > 3 && (
<button <button
key={brand.name} onClick={() => setIsExpanded(true)}
onClick={() => handleSelect(brand.name)}
className={cn( className={cn(
"rounded-lg border px-4 py-2 text-sm font-medium transition-all cursor-pointer", "rounded-lg pl-2 text-sm font-medium transition-all cursor-pointer",
isActive "flex-1 sm:flex-none animate-in fade-in slide-in-from-left-2",
? "border-primary bg-primary text-primary-foreground"
: "border-border bg-card text-muted-foreground hover:border-primary/50 hover:text-foreground",
)} )}
> >
{brand.name} ({brand.count.toLocaleString()}) <div className="flex items-center justify-center gap-1 hover:text-primary">
{validBrands.length - 3}
<span>Lainnya</span>
<ChevronRight className="w-4 h-4" />
</div>
</button> </button>
); )}
})}
{!isExpanded && validBrands.length > 3 && ( {isExpanded && (
<button <Button
onClick={() => setIsExpanded(true)} type="button"
className={cn( variant="ghost"
"rounded-lg border border-dashed px-4 py-2 text-sm font-medium hover:bg-accent transition-all cursor-pointer", onClick={() => {
"flex-1 min-w-25 sm:flex-none animate-in fade-in slide-in-from-bottom-2", setIsExpanded(false);
)} }}
> className="text-sentiment-negative hover:text-sentiment-negative hover:bg-sentiment-negative-light shrink-0"
{validBrands.length - 3} Lainnya >
</button>
)} </Button>
)}
{isExpanded && ( </div>
<Button
type="button"
variant="ghost"
onClick={() => {
setIsExpanded(false);
}}
className="text-sentiment-negative hover:text-sentiment-negative hover:bg-sentiment-negative-light shrink-0"
>
</Button>
)}
</div> </div>
</div> </motion.div>
); );
} }