mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-10-27 12:56:23 -04:00
fix: view transitions
This commit is contained in:
5 files changed
+40
-32
No files matched your search
+21
-23
@@ -195,7 +195,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* View Transitions */
|
/* View Transitions - uses tw-animate-css's `enter` and `exit` keyframes */
|
||||||
@layer base {
|
@layer base {
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
::view-transition-group(*),
|
::view-transition-group(*),
|
||||||
@@ -205,33 +205,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::view-transition-group(*) {
|
||||||
|
animation-duration: 250ms;
|
||||||
|
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
::view-transition-old(*) {
|
||||||
|
--tw-exit-opacity: 0;
|
||||||
|
animation: 150ms ease-in both exit;
|
||||||
|
}
|
||||||
|
::view-transition-new(*) {
|
||||||
|
--tw-enter-opacity: 0;
|
||||||
|
animation: 200ms ease-out both enter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main content: fade + slide */
|
||||||
main {
|
main {
|
||||||
view-transition-name: main-content;
|
view-transition-name: main-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
::view-transition-old(main-content) {
|
::view-transition-old(main-content) {
|
||||||
animation: fade-out 120ms ease-out;
|
--tw-exit-opacity: 0;
|
||||||
|
--tw-exit-translate-y: -8px;
|
||||||
|
animation: 150ms ease-in forwards exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
::view-transition-new(main-content) {
|
::view-transition-new(main-content) {
|
||||||
animation: fade-in 120ms ease-in 40ms;
|
--tw-enter-opacity: 0;
|
||||||
}
|
--tw-enter-translate-y: 12px;
|
||||||
|
animation: 200ms ease-out forwards enter;
|
||||||
@keyframes fade-out {
|
|
||||||
from {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-in {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-1
@@ -1,3 +1,4 @@
|
|||||||
|
import { ViewTransition } from "react";
|
||||||
import { env } from "@/lib/env";
|
import { env } from "@/lib/env";
|
||||||
import { JsonLd } from "react-schemaorg";
|
import { JsonLd } from "react-schemaorg";
|
||||||
import Providers from "@/components/providers";
|
import Providers from "@/components/providers";
|
||||||
@@ -64,7 +65,9 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => {
|
|||||||
<Providers>
|
<Providers>
|
||||||
<Header />
|
<Header />
|
||||||
<div className="mx-auto mt-4 w-full max-w-4xl px-5">
|
<div className="mx-auto mt-4 w-full max-w-4xl px-5">
|
||||||
<main>{children}</main>
|
<main>
|
||||||
|
<ViewTransition>{children}</ViewTransition>
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,10 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 className="my-5 text-4xl font-semibold tracking-tight sm:text-3xl">
|
<h1
|
||||||
|
className="my-5 text-3xl font-semibold tracking-tight"
|
||||||
|
style={{ viewTransitionName: `note-title-${frontmatter!.slug}` }}
|
||||||
|
>
|
||||||
<Link
|
<Link
|
||||||
href={`/${POSTS_DIR}/${frontmatter!.slug}`}
|
href={`/${POSTS_DIR}/${frontmatter!.slug}`}
|
||||||
dangerouslySetInnerHTML={{ __html: frontmatter!.htmlTitle || frontmatter!.title }}
|
dangerouslySetInnerHTML={{ __html: frontmatter!.htmlTitle || frontmatter!.title }}
|
||||||
|
|||||||
+9
-2
@@ -2,6 +2,7 @@ import { env } from "@/lib/env";
|
|||||||
import { cacheLife } from "next/cache";
|
import { cacheLife } from "next/cache";
|
||||||
import { EyeIcon, MessagesSquareIcon } from "lucide-react";
|
import { EyeIcon, MessagesSquareIcon } from "lucide-react";
|
||||||
import Link from "@/components/link";
|
import Link from "@/components/link";
|
||||||
|
import PageTitle from "@/components/layout/page-title";
|
||||||
import { getFrontMatter, POSTS_DIR, type FrontMatter } from "@/lib/posts";
|
import { getFrontMatter, POSTS_DIR, type FrontMatter } from "@/lib/posts";
|
||||||
import { createMetadata } from "@/lib/metadata";
|
import { createMetadata } from "@/lib/metadata";
|
||||||
import { formatDate, formatDateISO } from "@/lib/date";
|
import { formatDate, formatDateISO } from "@/lib/date";
|
||||||
@@ -97,7 +98,7 @@ const PostsList = async () => {
|
|||||||
Object.entries(postsByYear).forEach(([year, posts]) => {
|
Object.entries(postsByYear).forEach(([year, posts]) => {
|
||||||
sections.push(
|
sections.push(
|
||||||
<section className="my-8 first-of-type:mt-0 last-of-type:mb-0" key={year}>
|
<section className="my-8 first-of-type:mt-0 last-of-type:mb-0" key={year}>
|
||||||
<h2 id={year} className="mt-0 mb-4 text-4xl font-semibold tracking-tight sm:text-3xl">
|
<h2 id={year} className="mt-0 mb-4 text-2xl font-semibold tracking-tight">
|
||||||
{year}
|
{year}
|
||||||
</h2>
|
</h2>
|
||||||
<ul className="space-y-4">
|
<ul className="space-y-4">
|
||||||
@@ -115,6 +116,7 @@ const PostsList = async () => {
|
|||||||
prefetch={false}
|
prefetch={false}
|
||||||
dangerouslySetInnerHTML={{ __html: htmlTitle || title }}
|
dangerouslySetInnerHTML={{ __html: htmlTitle || title }}
|
||||||
className="underline-offset-4 hover:underline"
|
className="underline-offset-4 hover:underline"
|
||||||
|
style={{ viewTransitionName: `note-title-${slug}` }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PostStats slug={slug} views={views} comments={comments} />
|
<PostStats slug={slug} views={views} comments={comments} />
|
||||||
@@ -131,7 +133,12 @@ const PostsList = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Page = async () => {
|
const Page = async () => {
|
||||||
return <PostsList />;
|
return (
|
||||||
|
<>
|
||||||
|
<PageTitle canonical="/notes">Notes</PageTitle>
|
||||||
|
<PostsList />
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
@@ -10,13 +10,10 @@ const PageTitle = ({
|
|||||||
canonical: string;
|
canonical: string;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<h1
|
<h1 className={cn("mt-0 mb-6 text-left text-3xl font-semibold tracking-tight lowercase", className)} {...rest}>
|
||||||
className={cn("mt-0 mb-6 text-left text-4xl font-semibold tracking-tight lowercase sm:text-3xl", className)}
|
|
||||||
{...rest}
|
|
||||||
>
|
|
||||||
<Link
|
<Link
|
||||||
href={canonical}
|
href={canonical}
|
||||||
className="before:text-muted-foreground no-underline before:-mr-1 before:tracking-wider before:content-['\002E\002F']"
|
className="before:text-muted-foreground no-underline before:mr-[-3px] before:tracking-wider before:content-['\002E\002F']"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
Reference in new issue
Block a user