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