Skip to content

Commit

Permalink
feat: add ViewTransitions from Astro
Browse files Browse the repository at this point in the history
Integrate ViewTransitions API from Astro v3.

resolve #96
  • Loading branch information
satnaing committed Sep 14, 2023
1 parent 8fda50f commit 9703e54
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 35 deletions.
21 changes: 14 additions & 7 deletions public/toggle-theme.js
Expand Up @@ -50,14 +50,21 @@ function reflectPreference() {
reflectPreference();

window.onload = () => {
// set on load so screen readers can get the latest value on the button
reflectPreference();
function setThemeFeature() {
// set on load so screen readers can get the latest value on the button
reflectPreference();

// now this script can find and listen for clicks on the control
document.querySelector("#theme-btn")?.addEventListener("click", () => {
themeValue = themeValue === "light" ? "dark" : "light";
setPreference();
});
}

// now this script can find and listen for clicks on the control
document.querySelector("#theme-btn")?.addEventListener("click", () => {
themeValue = themeValue === "light" ? "dark" : "light";
setPreference();
});
setThemeFeature();

// Runs on view transitions navigation
document.addEventListener("astro:after-swap", setThemeFeature);
};

// sync with system changes
Expand Down
22 changes: 22 additions & 0 deletions src/components/Card.astro
@@ -0,0 +1,22 @@
---
import Datetime from "@components/Datetime";
import type { BlogFrontmatter } from "@content/_schemas";
export interface Props {
href?: string;
frontmatter: BlogFrontmatter;
secHeading?: boolean;
}
const { href, frontmatter, secHeading = true } = Astro.props;
const { title, pubDatetime, description } = frontmatter;
---

<li class="list-card">
<a href={href} transition:name={title}>
{secHeading ? <h2>{title}</h2> : <h3>{title}</h3>}
</a>
<Datetime datetime={pubDatetime} />
<p>{description}</p>
</li>
35 changes: 21 additions & 14 deletions src/components/Header.astro
Expand Up @@ -189,19 +189,26 @@ const { activeNav } = Astro.props;
</style>

<script>
// Toggle menu
const menuBtn = document.querySelector(".hamburger-menu");
const menuIcon = document.querySelector(".menu-icon");
const menuItems = document.querySelector("#menu-items");
function toggleNav() {
// Toggle menu
const menuBtn = document.querySelector(".hamburger-menu");
const menuIcon = document.querySelector(".menu-icon");
const menuItems = document.querySelector("#menu-items");

menuBtn?.addEventListener("click", () => {
const menuExpanded = menuBtn.getAttribute("aria-expanded") === "true";
menuIcon?.classList.toggle("is-active");
menuBtn.setAttribute("aria-expanded", menuExpanded ? "false" : "true");
menuBtn.setAttribute(
"aria-label",
menuExpanded ? "Open Menu" : "Close Menu"
);
menuItems?.classList.toggle("display-none");
});
menuBtn?.addEventListener("click", () => {
const menuExpanded = menuBtn.getAttribute("aria-expanded") === "true";
menuIcon?.classList.toggle("is-active");
menuBtn.setAttribute("aria-expanded", menuExpanded ? "false" : "true");
menuBtn.setAttribute(
"aria-label",
menuExpanded ? "Open Menu" : "Close Menu"
);
menuItems?.classList.toggle("display-none");
});
}

toggleNav();

// Runs on view transitions navigation
document.addEventListener("astro:after-swap", toggleNav);
</script>
4 changes: 2 additions & 2 deletions src/components/Search.tsx
Expand Up @@ -67,9 +67,9 @@ export default function SearchBar({ searchList }: Props) {
searchParams.set("q", inputVal);
const newRelativePathQuery =
window.location.pathname + "?" + searchParams.toString();
history.replaceState(null, "", newRelativePathQuery);
history.replaceState(history.state, "", newRelativePathQuery);
} else {
history.replaceState(null, "", window.location.pathname);
history.replaceState(history.state, "", window.location.pathname);
}
}, [inputVal]);

Expand Down
1 change: 1 addition & 0 deletions src/components/Tag.astro
Expand Up @@ -14,6 +14,7 @@ const { name, size = "sm" } = Astro.props;
>
<a
href={`/tags/${name.toLowerCase()}`}
transition:name={name.toLowerCase()}
class={`${size === "sm" ? "text-sm" : "text-lg"} pr-2 group`}
>
<svg
Expand Down
5 changes: 4 additions & 1 deletion src/layouts/Layout.astro
@@ -1,6 +1,7 @@
---
import { SITE } from "@config";
import "@styles/base.css";
import { ViewTransitions } from "astro:transitions";
const googleSiteVerification = import.meta.env.PUBLIC_GOOGLE_SITE_VERIFICATION;
Expand All @@ -26,7 +27,7 @@ const socialImageURL = new URL(
).href;
---

<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
Expand Down Expand Up @@ -77,6 +78,8 @@ const socialImageURL = new URL(
)
}

<ViewTransitions />

<script is:inline src="/toggle-theme.js"></script>
</head>
<body>
Expand Down
27 changes: 23 additions & 4 deletions src/layouts/Main.astro
@@ -1,18 +1,37 @@
---
import Breadcrumbs from "@components/Breadcrumbs.astro";
export interface Props {
interface StringTitleProp {
pageTitle: string;
pageDesc?: string;
}
const { pageTitle, pageDesc } = Astro.props;
interface ArrayTitleProp {
pageTitle: [string, string];
titleTransition: string;
pageDesc?: string;
}
export type Props = StringTitleProp | ArrayTitleProp;
const { props } = Astro;
---

<Breadcrumbs />
<main id="main-content">
<h1>{pageTitle}</h1>
<p>{pageDesc}</p>
{
"titleTransition" in props ? (
<h1>
{props.pageTitle[0]}
<span transition:name={props.titleTransition}>
{props.pageTitle[1]}
</span>
</h1>
) : (
<h1>{props.pageTitle}</h1>
)
}
<p>{props.pageDesc}</p>
<slot />
</main>

Expand Down
13 changes: 10 additions & 3 deletions src/layouts/PostDetails.astro
Expand Up @@ -13,15 +13,22 @@ export interface Props {
const { post } = Astro.props;
const { title, author, description, ogImage, canonicalURL, pubDatetime, tags } = post.data;
const { title, author, description, ogImage, canonicalURL, pubDatetime, tags } =
post.data;
const { Content } = await post.render();
const ogUrl = new URL(ogImage ? ogImage : `${title}.png`, Astro.url.origin)
.href;
---

<Layout title={title} author={author} description={description} ogImage={ogUrl} canonicalURL={canonicalURL}>
<Layout
title={title}
author={author}
description={description}
ogImage={ogUrl}
canonicalURL={canonicalURL}
>
<Header />
<div class="mx-auto flex w-full max-w-3xl justify-start px-2">
<button
Expand All @@ -36,7 +43,7 @@ const ogUrl = new URL(ogImage ? ogImage : `${title}.png`, Astro.url.origin)
</button>
</div>
<main id="main-content">
<h1 class="post-title">{title}</h1>
<h1 transition:name={title} class="post-title">{title}</h1>
<Datetime datetime={pubDatetime} size="lg" className="my-2" />
<article id="article" role="article" class="prose mx-auto mt-8 max-w-3xl">
<Content />
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/Posts.astro
Expand Up @@ -4,7 +4,7 @@ import Layout from "@layouts/Layout.astro";
import Main from "@layouts/Main.astro";
import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import Card from "@components/Card";
import Card from "@components/Card.astro";
import LinkButton from "@components/LinkButton.astro";
import slugify from "@utils/slugify";
import type { CollectionEntry } from "astro:content";
Expand Down
2 changes: 1 addition & 1 deletion src/pages/index.astro
Expand Up @@ -5,7 +5,7 @@ import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import LinkButton from "@components/LinkButton.astro";
import Hr from "@components/Hr.astro";
import Card from "@components/Card";
import Card from "@components/Card.astro";
import Socials from "@components/Socials.astro";
import getSortedPosts from "@utils/getSortedPosts";
import slugify from "@utils/slugify";
Expand Down
6 changes: 4 additions & 2 deletions src/pages/tags/[tag].astro
Expand Up @@ -4,7 +4,7 @@ import Layout from "@layouts/Layout.astro";
import Main from "@layouts/Main.astro";
import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import Card from "@components/Card";
import Card from "@components/Card.astro";
import getUniqueTags from "@utils/getUniqueTags";
import getPostsByTag from "@utils/getPostsByTag";
import slugify from "@utils/slugify";
Expand Down Expand Up @@ -41,9 +41,11 @@ const sortTagsPost = getSortedPosts(tagPosts);
<Layout title={`Tag:${tag} | ${SITE.title}`}>
<Header activeNav="tags" />
<Main
pageTitle={`Tag:${tag}`}
pageTitle={[`Tag:`, `${tag}`]}
titleTransition={tag}
pageDesc={`All the articles with the tag "${tag}".`}
>
<h1 slot="title" transition:name={tag}>{`Tag:${tag}`}</h1>
<ul>
{
sortTagsPost.map(({ data }) => (
Expand Down

0 comments on commit 9703e54

Please sign in to comment.