feat: animate Shop's active category filter with a sliding pill indicator
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user