feat: add ViewTransitions from Astro

Integrate ViewTransitions API from Astro v3.

resolve #96
This commit is contained in:
satnaing
2023-09-14 14:00:08 +06:30
committed by Sat Naing
parent e486687610
commit cbdaa59bae
11 changed files with 103 additions and 35 deletions
+22
View File
@@ -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>
+21 -14
View File
@@ -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>
+2 -2
View File
@@ -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]);
+1
View File
@@ -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
+4 -1
View File
@@ -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;
@@ -26,7 +27,7 @@ const socialImageURL = new URL(
).href;
---
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@@ -77,6 +78,8 @@ const socialImageURL = new URL(
)
}
<ViewTransitions />
<script is:inline src="/toggle-theme.js"></script>
</head>
<body>
+23 -4
View File
@@ -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>
+10 -3
View File
@@ -13,7 +13,8 @@ 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();
@@ -21,7 +22,13 @@ 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
@@ -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 />
+1 -1
View File
@@ -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";
+1 -1
View File
@@ -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";
+4 -2
View File
@@ -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";
@@ -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 }) => (