feat: animate Shop's active category filter with a sliding pill indicator

This commit is contained in:
belviskhoremk
2026-08-03 23:04:38 +00:00
parent e24c1c7be7
commit 7cd84f1c66
2 changed files with 27 additions and 5 deletions

View File

@@ -8,23 +8,37 @@
margin-bottom: var(--space-lg);
}
.filters button {
.filterButton {
position: relative;
background: none;
border: 1px solid var(--color-gold);
padding: 0.5rem 1rem;
cursor: pointer;
text-transform: capitalize;
overflow: hidden;
color: var(--color-charcoal);
}
.filters button.active {
.activePill {
position: absolute;
inset: 0;
background: var(--color-charcoal);
z-index: 0;
}
.filterLabel {
position: relative;
z-index: 1;
}
.filterButton:has(.activePill) .filterLabel {
color: var(--color-cream);
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: var(--space-lg);
gap: var(--space-md);
}
@media (max-width: 640px) {

View File

@@ -1,4 +1,5 @@
import { useState } from 'react'
import { motion } from 'framer-motion'
import ProductCard from '../components/ProductCard'
import InquiryModal from '../components/InquiryModal'
import { getProductsByCategory, type Product } from '../data/products'
@@ -18,10 +19,17 @@ function Shop() {
<button
key={c}
type="button"
className={c === category ? styles.active : ''}
className={styles.filterButton}
onClick={() => setCategory(c)}
>
{c.replace('-', ' ')}
{c === category && (
<motion.span
layoutId="active-filter-pill"
className={styles.activePill}
transition={{ type: 'spring', stiffness: 350, damping: 30 }}
/>
)}
<span className={styles.filterLabel}>{c.replace('-', ' ')}</span>
</button>
))}
</div>