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