make everything noscript compatible as best as possible
This commit is contained in:
parent
bbdc4ea50e
commit
1a0eaf2dcb
|
|
@ -1,12 +0,0 @@
|
|||
function animate() {
|
||||
const animateElements = document.querySelectorAll('.animate')
|
||||
|
||||
animateElements.forEach((element, index) => {
|
||||
setTimeout(() => {
|
||||
element.classList.add('show')
|
||||
}, index * 150)
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", animate)
|
||||
document.addEventListener("astro:after-swap", animate)
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
import { formatDate } from "@/lib/utils";
|
||||
import { Icon } from '@iconify-icon/solid';
|
||||
import { Icon } from "@iconify-icon/solid";
|
||||
|
||||
type Props = {
|
||||
entry: CollectionEntry<"blog"> | CollectionEntry<"projects">;
|
||||
|
|
@ -31,13 +30,11 @@ export default function ArrowCard({ entry, pill }: Props) {
|
|||
|
||||
<div class="text-sm line-clamp-2">{entry.data.summary}</div>
|
||||
<ul class="flex flex-wrap mt-2 gap-1">
|
||||
{entry.data.tags.map(
|
||||
(tag) => (
|
||||
<li class="text-xs font-departure uppercase py-0.5 px-1 rounded bg-black/5 dark:bg-white/20 text-black/75 dark:text-white/75">
|
||||
{tag}
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
{entry.data.tags.map((tag) => (
|
||||
<li class="text-xs font-departure uppercase py-0.5 px-1 rounded bg-black/5 dark:bg-white/20 text-black/75 dark:text-white/75">
|
||||
{tag}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="relative overflow-hidden w-4 h-4">
|
||||
|
|
@ -56,4 +53,4 @@ export default function ArrowCard({ entry, pill }: Props) {
|
|||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ const { title, description, image = "/open-graph.jpg" } = Astro.props;
|
|||
<!-- Global Scripts -->
|
||||
<script is:inline src="/js/theme.js"></script>
|
||||
<script is:inline src="/js/scroll.js"></script>
|
||||
<script is:inline src="/js/animate.js"></script>
|
||||
|
||||
<ClientRouter />
|
||||
|
||||
|
|
@ -107,11 +106,3 @@ const { title, description, image = "/open-graph.jpg" } = Astro.props;
|
|||
integrity="sha384-m7LqaUc4JRc2uA7D4zSVUs/sgkYhmOOe9+Gd8DFmmAXH8vzs15fmw05YXvpxsoQB"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.noscript-hide {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
|
|
|
|||
|
|
@ -10,20 +10,23 @@ type Props = {
|
|||
};
|
||||
|
||||
export default function Blog({ data, tags }: Props) {
|
||||
function filterPosts(): CollectionEntry<"blog">[] {
|
||||
return data.filter((entry) =>
|
||||
Array.from(filter()).every((value) =>
|
||||
entry.data.tags.some(
|
||||
(tag: string) =>
|
||||
tag.toLowerCase() === String(value).toLowerCase(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const [filter, setFilter] = createSignal(new Set<string>());
|
||||
const [posts, setPosts] = createSignal<CollectionEntry<"blog">[]>([]);
|
||||
const [posts, setPosts] =
|
||||
createSignal<CollectionEntry<"blog">[]>(filterPosts());
|
||||
|
||||
createEffect(() => {
|
||||
setPosts(
|
||||
data.filter((entry) =>
|
||||
Array.from(filter()).every((value) =>
|
||||
entry.data.tags.some(
|
||||
(tag: string) =>
|
||||
tag.toLowerCase() === String(value).toLowerCase()
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
setPosts(filterPosts());
|
||||
});
|
||||
|
||||
function toggleTag(tag: string) {
|
||||
|
|
@ -32,14 +35,14 @@ export default function Blog({ data, tags }: Props) {
|
|||
new Set(
|
||||
prev.has(tag)
|
||||
? [...prev].filter((t) => t !== tag)
|
||||
: [...prev, tag]
|
||||
)
|
||||
: [...prev, tag],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6">
|
||||
<div class="col-span-3 sm:col-span-1">
|
||||
<div class="not-noscript:grid grid-cols-1 sm:grid-cols-3 gap-6">
|
||||
<div class="col-span-3 sm:col-span-1 noscript:hidden">
|
||||
<div class="sticky top-24">
|
||||
<div class="text-sm font-semibold font-departure uppercase mb-2 text-black dark:text-white">
|
||||
Filter
|
||||
|
|
@ -58,21 +61,27 @@ export default function Blog({ data, tags }: Props) {
|
|||
"hover:bg-black/10 hover:dark:bg-white/15",
|
||||
"transition-colors duration-300 ease-in-out",
|
||||
filter().has(tag) &&
|
||||
"text-black dark:text-white"
|
||||
"text-black dark:text-white",
|
||||
)}
|
||||
>
|
||||
<div class={cn(
|
||||
"relative size-5 fill-black/50 dark:fill-white/50",
|
||||
"transition-colors duration-300 ease-in-out",
|
||||
filter().has(tag) &&
|
||||
"fill-black dark:fill-white"
|
||||
)}>
|
||||
<div
|
||||
class={cn(
|
||||
"relative size-5 fill-black/50 dark:fill-white/50",
|
||||
"transition-colors duration-300 ease-in-out",
|
||||
filter().has(tag) &&
|
||||
"fill-black dark:fill-white",
|
||||
)}
|
||||
>
|
||||
<Icon icon="pixelarticons:square" />
|
||||
<Icon icon="pixel:check" class={cn("absolute top-0 right-0",
|
||||
filter().has(tag)
|
||||
? "block"
|
||||
: "hidden"
|
||||
)} />
|
||||
<Icon
|
||||
icon="pixel:check"
|
||||
class={cn(
|
||||
"absolute top-0 right-0",
|
||||
filter().has(tag)
|
||||
? "block"
|
||||
: "hidden",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{tag}
|
||||
</button>
|
||||
|
|
@ -105,4 +114,4 @@ export default function Blog({ data, tags }: Props) {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ const { pathname } = Astro.url;
|
|||
const subpath = pathname.match(/[^/]+/g);
|
||||
---
|
||||
|
||||
<header id="header" class="fixed top-0 w-full h-16 z-50">
|
||||
<header
|
||||
id="header"
|
||||
class="fixed top-0 w-full h-16 z-50 noscript:bg-zinc-200/75 noscript:border-black/10 noscript:backdrop-blur-sm noscript:saturate-200"
|
||||
>
|
||||
<Container size="md">
|
||||
<div
|
||||
class="relative h-full w-full flex flex-row justify-between items-center"
|
||||
|
|
|
|||
|
|
@ -10,22 +10,23 @@ type Props = {
|
|||
};
|
||||
|
||||
export default function Projects({ data, tags }: Props) {
|
||||
function filterProjects(): CollectionEntry<"projects">[] {
|
||||
return data.filter((entry) =>
|
||||
Array.from(filter()).every((value) =>
|
||||
entry.data.tags.some(
|
||||
(tag: string) =>
|
||||
tag.toLowerCase() === String(value).toLowerCase(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const [filter, setFilter] = createSignal(new Set<string>());
|
||||
const [projects, setProjects] = createSignal<CollectionEntry<"projects">[]>(
|
||||
[]
|
||||
);
|
||||
const [projects, setProjects] =
|
||||
createSignal<CollectionEntry<"projects">[]>(filterProjects());
|
||||
|
||||
createEffect(() => {
|
||||
setProjects(
|
||||
data.filter((entry) =>
|
||||
Array.from(filter()).every((value) =>
|
||||
entry.data.tags.some(
|
||||
(tag: string) =>
|
||||
tag.toLowerCase() === String(value).toLowerCase()
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
setProjects(filterProjects());
|
||||
});
|
||||
|
||||
function toggleTag(tag: string) {
|
||||
|
|
@ -34,14 +35,14 @@ export default function Projects({ data, tags }: Props) {
|
|||
new Set(
|
||||
prev.has(tag)
|
||||
? [...prev].filter((t) => t !== tag)
|
||||
: [...prev, tag]
|
||||
)
|
||||
: [...prev, tag],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="grid grid-cols-1 sm:grid-cols-3 gap-6">
|
||||
<div class="col-span-3 sm:col-span-1">
|
||||
<div class="not-noscript:grid grid-cols-1 sm:grid-cols-3 gap-6">
|
||||
<div class="col-span-3 sm:col-span-1 noscript:hidden">
|
||||
<div class="sticky top-24">
|
||||
<div class="text-sm font-semibold font-departure uppercase mb-2 text-black dark:text-white">
|
||||
Filter
|
||||
|
|
@ -60,21 +61,27 @@ export default function Projects({ data, tags }: Props) {
|
|||
"hover:bg-black/10 hover:dark:bg-white/15",
|
||||
"transition-colors duration-300 ease-in-out",
|
||||
filter().has(tag) &&
|
||||
"text-black dark:text-white"
|
||||
"text-black dark:text-white",
|
||||
)}
|
||||
>
|
||||
<div class={cn(
|
||||
"relative size-5 fill-black/50 dark:fill-white/50",
|
||||
"transition-colors duration-300 ease-in-out",
|
||||
filter().has(tag) &&
|
||||
"fill-black dark:fill-white"
|
||||
)}>
|
||||
<div
|
||||
class={cn(
|
||||
"relative size-5 fill-black/50 dark:fill-white/50",
|
||||
"transition-colors duration-300 ease-in-out",
|
||||
filter().has(tag) &&
|
||||
"fill-black dark:fill-white",
|
||||
)}
|
||||
>
|
||||
<Icon icon="pixelarticons:square" />
|
||||
<Icon icon="pixel:check" class={cn("absolute top-0 right-0",
|
||||
filter().has(tag)
|
||||
? "block"
|
||||
: "hidden"
|
||||
)} />
|
||||
<Icon
|
||||
icon="pixel:check"
|
||||
class={cn(
|
||||
"absolute top-0 right-0",
|
||||
filter().has(tag)
|
||||
? "block"
|
||||
: "hidden",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{tag}
|
||||
</button>
|
||||
|
|
@ -106,4 +113,4 @@ export default function Projects({ data, tags }: Props) {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,19 +11,10 @@ const { suffix } = Astro.props;
|
|||
name="doomsday-year"
|
||||
id="doomsday-year"
|
||||
min="1583"
|
||||
class="w-16 font-departure"
|
||||
/><span class="noscript-hide">{suffix}</span>
|
||||
<noscript>
|
||||
<span class="text-red-500"
|
||||
>JavaScript is required for this feature to work.</span
|
||||
>
|
||||
|
||||
<style>
|
||||
#doomsday-year {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
class="w-16 font-departure noscript:hidden"
|
||||
/><span class="text-red-500 not-noscript:hidden"
|
||||
>JavaScript is required for this feature to work</span
|
||||
>{suffix}
|
||||
|
||||
<script>
|
||||
const currentYearInput = document.getElementById(
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ First, we take the last two digits of the year. If this number is odd, we add 11
|
|||
Finally, we take 7 minus modulo 7 of the result and count forward that many days from the Doomsday of the century. The resulting weekday is the Doomsday of the year.
|
||||
This algorithm can be remembered with the following flowchart:
|
||||
|
||||
<div class="noscript:hidden">
|
||||
```mermaid
|
||||
flowchart TD
|
||||
B[Let T = last two digits of year] --> C{Is T odd?}
|
||||
|
|
@ -116,6 +117,10 @@ flowchart TD
|
|||
|
||||
K --> L[Doomsday of the year]
|
||||
```
|
||||
</div>
|
||||
<div class="not-noscript:hidden font-semibold italic">
|
||||
Please enable JavaScript to see the flowchart for the first method.
|
||||
</div>
|
||||
|
||||
The second method is more mathematical and follows the steps:
|
||||
|
||||
|
|
|
|||
|
|
@ -84,12 +84,19 @@
|
|||
.animate {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
transition: opacity 1s ease, transform 1s ease;
|
||||
animation: fadeInUp 1s forwards;
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
|
||||
.animate.show {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
@keyframes fadeInUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
article img {
|
||||
|
|
@ -98,4 +105,4 @@
|
|||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue