Update transitions to persist theme color smoothly

This commit is contained in:
Steve Paul
2024-11-22 15:55:24 +05:30
parent 75dadabc58
commit a07d1c7b20
7 changed files with 510 additions and 449 deletions
+43 -38
View File
@@ -1,53 +1,58 @@
.link-card {
list-style: none;
display: flex;
background-color: var(--background-secondary);
background-position: 100%;
border-radius: var(--spacing-03);
height: 8.5rem;
position: relative;
--shadow-color: rgb(0 0 0 / 0.04);
box-shadow: 0px 0px 0px 1px var(--background-selected),
0px 1px 1px -0.5px var(--shadow-color),
0px 3px 3px -1.5px var(--shadow-color),
0px 12px 12px -6px var(--shadow-color);
transition:all .2s ease-out;
list-style: none;
display: flex;
background-color: var(--background-secondary);
background-position: 100%;
border-radius: var(--spacing-03);
height: 8.5rem;
position: relative;
--shadow-color: rgb(0 0 0 / 0.04);
box-shadow:
0px 0px 0px 1px var(--background-selected),
0px 1px 1px -0.5px var(--shadow-color),
0px 3px 3px -1.5px var(--shadow-color),
0px 12px 12px -6px var(--shadow-color);
content-visibility: auto;
contain-intrinsic-size: 8.5rem;
will-change: transform;
transition: box-shadow 0.2s ease-out;
}
.link-card>a {
width: 100%;
text-decoration: none;
padding: 0.8rem 1.2rem;
color: var(--support-info);
justify-content: space-between;
.link-card > a {
width: 100%;
text-decoration: none;
padding: 0.8rem 1.2rem;
color: var(--support-info);
justify-content: space-between;
}
p {
color: var(--text-secondary);
color: var(--text-secondary);
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
box-shadow: 0px 0px 0px 2px var(--link),
0px 1px 1px -0.5px var(--shadow-color),
0px 3px 3px -1.5px var(--shadow-color),
0px 12px 12px -6px var(--shadow-color);
background-position: 0;
box-shadow:
0px 0px 0px 2px var(--link),
0px 1px 1px -0.5px var(--shadow-color),
0px 3px 3px -1.5px var(--shadow-color),
0px 12px 12px -6px var(--shadow-color);
}
p.distribution {
margin: var(--spacing-00);
position: absolute;
bottom: var(--spacing-06);
margin: var(--spacing-00);
position: absolute;
bottom: var(--spacing-06);
}
span.tag {
background-color: var(--background-selected);
padding: calc(.25rem - 1px) calc(.5rem - 1px);
border-radius: var(--spacing-02);
display: inline-block;
color: var(--text-secondary);
margin-top: var(--spacing-08);
font-size: var(--desktop-caption);
line-height: var(--lh-desktop-caption);
font-family: var(--body-copy);
}
background-color: var(--background-selected);
padding: calc(0.25rem - 1px) calc(0.5rem - 1px);
border-radius: var(--spacing-02);
display: inline-block;
color: var(--text-secondary);
margin-top: var(--spacing-08);
font-size: var(--desktop-caption);
line-height: var(--lh-desktop-caption);
font-family: var(--body-copy);
}
+12 -14
View File
@@ -1,19 +1,17 @@
import "./Card.css";
export default function Card(props) {
const {href, title, body, tag} = props;
const { href, title, body, tag } = props;
return <li className="link-card">
<a href={href}>
<strong className="nu-c-h6 nu-u-mt-1 nu-u-mb-1">
{title}
</strong>
<p className="nu-c-fs-small nu-u-mt-1 nu-u-mb-1">
{body}
</p>
<p className="distribution">
<span className="tag">{tag}</span>
</p>
</a>
</li>
return (
<li className="link-card">
<a href={href}>
<strong className="nu-c-h6 nu-u-mt-1 nu-u-mb-1">{title}</strong>
<p className="nu-c-fs-small nu-u-mt-1 nu-u-mb-1">{body}</p>
<p className="distribution">
<span className="tag">{tag}</span>
</p>
</a>
</li>
);
}
+20 -24
View File
@@ -1,33 +1,29 @@
import { useMemo } from "react";
import Card from "./Card";
import "./CardsContainer.css";
import data from "../data/tools.json";
import data from "../data/tools.json"
export default function CardsContainer({ filter }) {
const filteredCards = useMemo(() => {
return data.tools
.filter((item) => filter === "all" || filter === item.category)
.flatMap((item) => item.content)
.sort((a, b) => a.title.localeCompare(b.title));
}, [filter]);
export default function CardsContainer(props) {
const { filter } = props;
return <section>
<ul role="list" className="link-card-grid">
{data.tools
.filter(item => {
if (filter === "all" || filter === item.category) {
return item;
}
})
.flatMap(item => item.content)
.sort((a, b) => {
return a.title < b.title ? -1 : 1;
})
.map(({url, title, body, tag}, i) => {
return <Card
key={i}
return (
<section>
<ul role="list" className="link-card-grid">
{filteredCards.map(({ url, title, body, tag }, i) => (
<Card
key={`${title}-${i}`}
href={url}
title={title}
body={body}
tag={tag}
/>
})
}
</ul>
</section>
}
))}
</ul>
</section>
);
}
+37 -29
View File
@@ -4,39 +4,47 @@ import data from "../data/tools.json";
import "./CategoryNavItem.css";
export default function CategoryNavItem(props) {
const { title, category, filter } = props;
const [isActive, setIsActive] = useState(false);
const { title, category, filter } = props;
const [isActive, setIsActive] = useState(false);
const getCategoryCount = () => {
if (category === "all") {
return data.tools.reduce((acc, item) => acc + item.content.length, 0);
}
const handleNavigation = (e) => {
e.preventDefault();
navigate(`/categories/${category}`, {
history: "push",
state: { category },
});
};
const navItemData = data.tools.filter((item) => item.category === category);
return navItemData[0]?.content.length;
};
const getCategoryCount = () => {
if (category === "all") {
return data.tools.reduce((acc, item) => acc + item.content.length, 0);
}
useEffect(() => {
let subscription = true;
const navItemData = data.tools.filter((item) => item.category === category);
return navItemData[0]?.content.length;
};
if (filter === category) {
setIsActive(true);
} else {
setIsActive(false);
}
useEffect(() => {
let subscription = true;
return () => (subscription = !subscription);
}, [filter]);
if (filter === category) {
setIsActive(true);
} else {
setIsActive(false);
}
return (
<button
onClick={() => navigate(`/categories/${category}`)}
className={`nav__item nu-u-text--secondary-alt nu-c-fs-normal nu-u-py-5 nu-u-px-0 nu-u-me-8 nav__item--filter ${
isActive ? "is-active" : ""
}`}
dangerouslySetInnerHTML={{
__html: `${title} - ${getCategoryCount()}`,
}}
></button>
);
return () => (subscription = !subscription);
}, [filter]);
return (
<button
onClick={() => navigate(`/categories/${category}`)}
className={`nav__item nu-u-text--secondary-alt nu-c-fs-normal nu-u-py-5 nu-u-px-0 nu-u-me-8 nav__item--filter ${
isActive ? "is-active" : ""
}`}
dangerouslySetInnerHTML={{
__html: `${title} - ${getCategoryCount()}`,
}}
></button>
);
}
+13 -6
View File
@@ -1,11 +1,18 @@
import { useEffect, useState } from "react";
import CategoryNav from "./CategoryNav";
import CardsContainer from "./CardsContainer";
export default function Dashboard({ category }) {
return (
<>
<CategoryNav filter={category} />
<CardsContainer filter={category} />
</>
);
const [currentCategory, setCurrentCategory] = useState(category);
useEffect(() => {
setCurrentCategory(category);
}, [category]);
return (
<>
<CategoryNav filter={category} />
<CardsContainer filter={category} />
</>
);
}