style: add brands button motion
This commit is contained in:
parent
d7060c8248
commit
b8135c3bff
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue