some basic view transition support
This commit is contained in:
parent
1d9faff6fe
commit
6800e399ed
7 changed files with 84 additions and 43 deletions
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import ArticleHeader from './ArticleHeader.astro';
|
import ArticleHeader from './ArticleHeader.astro';
|
||||||
import type { Article, Post } from '../content/config.js';
|
import type { Article } from '../content/config.js';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
article: Article;
|
article: Article;
|
||||||
|
@ -24,6 +24,14 @@ const { Content } = await article.render();
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--theme-space-lg);
|
gap: var(--theme-space-lg);
|
||||||
padding-block: var(--theme-space-md);
|
padding-block: var(--theme-space-md);
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--theme-size-content-3);
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-content {
|
||||||
|
max-width: var(--theme-size-content-3);
|
||||||
|
margin-inline: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.e-content > :global(* + *) {
|
.e-content > :global(* + *) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ const { text: readingTime } = await getReadingTime(article.body);
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 class="p-name">{article.data.title}</h1>
|
<h1 class="p-name">article.data.title}</h1>
|
||||||
|
|
||||||
{article.data.categories?.length > 0 && <TagList tags={article.data.categories} />}
|
{article.data.categories?.length > 0 && <TagList tags={article.data.categories} />}
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -11,14 +11,16 @@ export interface Props extends HTMLAttributes<'article'> {
|
||||||
post: Post;
|
post: Post;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post, ...attrs } = Astro.props;
|
const { post, class: className, ...attrs } = Astro.props;
|
||||||
|
|
||||||
const { pubDate, categories = [] } = post.data;
|
const { pubDate, categories = [] } = post.data;
|
||||||
const cover = 'cover' in post.data && post.data.cover;
|
const cover = 'cover' in post.data && post.data.cover;
|
||||||
const title = 'title' in post.data && post.data.title;
|
const title = 'title' in post.data && post.data.title;
|
||||||
|
|
||||||
|
const postUrl = `/post/${post.slug}/`;
|
||||||
---
|
---
|
||||||
|
|
||||||
<article class="h-entry" {...attrs}>
|
<article class:list={['h-entry', className]} transition:name={`card-${post.slug}`} {...attrs}>
|
||||||
<header class="p-author h-card">
|
<header class="p-author h-card">
|
||||||
<Image {...settings.avatar} width={120} class="u-photo" />
|
<Image {...settings.avatar} width={120} class="u-photo" />
|
||||||
<strong class="p-name">{settings.name}</strong>
|
<strong class="p-name">{settings.name}</strong>
|
||||||
|
@ -35,12 +37,24 @@ const title = 'title' in post.data && post.data.title;
|
||||||
isArticle(post) ? (
|
isArticle(post) ? (
|
||||||
<p class="p-summary">{post.data.description}</p>
|
<p class="p-summary">{post.data.description}</p>
|
||||||
) : (
|
) : (
|
||||||
post.render().then(({ Content }) => <div class="e-content"><Content /></div>)
|
post.render().then(({ Content }) => (
|
||||||
|
<div class="e-content">
|
||||||
|
<Content />
|
||||||
|
</div>
|
||||||
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
<footer>
|
<footer>
|
||||||
<a href={`/post/${post.slug}/`} class="u-url">Full {post.collection === 'articles' ? 'article' : 'note'}</a>
|
{
|
||||||
<a href={`javascript: navigator.clipboard.writeText(window.location.href + "post/${post.slug}/");`}>
|
Astro.url.pathname !== postUrl && (
|
||||||
|
<a href={`/post/${post.slug}/`} class="u-url">
|
||||||
|
Full {post.collection === 'articles' ? 'article' : 'note'}
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<a
|
||||||
|
href={`javascript: navigator.clipboard.writeText(window.location.href + "post/${post.slug}/");`}
|
||||||
|
>
|
||||||
<Icon icon="share" size="1.5rem" />
|
<Icon icon="share" size="1.5rem" />
|
||||||
<span class="sr-only">Share this post</span>
|
<span class="sr-only">Share this post</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -49,6 +63,7 @@ const title = 'title' in post.data && post.data.title;
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
article {
|
article {
|
||||||
|
max-width: var(--theme-size-content-2);
|
||||||
padding: var(--theme-space-sm) var(--theme-space-sm) var(--theme-space-md);
|
padding: var(--theme-space-sm) var(--theme-space-sm) var(--theme-space-md);
|
||||||
background-color: var(--theme-bg-accent);
|
background-color: var(--theme-bg-accent);
|
||||||
border-radius: var(--theme-radius-xl);
|
border-radius: var(--theme-radius-xl);
|
||||||
|
@ -65,7 +80,7 @@ const title = 'title' in post.data && post.data.title;
|
||||||
row-gap: var(--theme-space-2xs);
|
row-gap: var(--theme-space-2xs);
|
||||||
column-gap: var(--theme-space-sm);
|
column-gap: var(--theme-space-sm);
|
||||||
}
|
}
|
||||||
.u-photo {
|
.h-card .u-photo {
|
||||||
grid-area: avatar;
|
grid-area: avatar;
|
||||||
width: var(--theme-space-xl);
|
width: var(--theme-space-xl);
|
||||||
height: var(--theme-space-xl);
|
height: var(--theme-space-xl);
|
||||||
|
@ -95,4 +110,7 @@ const title = 'title' in post.data && post.data.title;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
footer > *:only-child {
|
||||||
|
margin-inline-start: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -16,20 +16,17 @@ const { reverse = false, class: className, ...attrs } = Astro.props;
|
||||||
div {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
gap: var(--theme-space-lg);
|
gap: var(--theme-space-lg);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: var(--theme-content-width);
|
max-width: var(--theme-size-content-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 50em) {
|
@media (min-width: 50em) {
|
||||||
div {
|
div {
|
||||||
display: grid;
|
flex-direction: row;
|
||||||
grid-template-columns: 12rem 1fr;
|
align-items: initial;
|
||||||
}
|
|
||||||
|
|
||||||
div.reverse {
|
|
||||||
grid-template-columns: 1fr 12rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
import { ViewTransitions } from 'astro:transitions';
|
||||||
import settings from '../settings';
|
import settings from '../settings';
|
||||||
import '../style/theme.css';
|
import '../style/theme.css';
|
||||||
import '../style/global.css';
|
import '../style/global.css';
|
||||||
|
@ -22,6 +23,7 @@ const { title = settings.name } = Astro.props;
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
|
<ViewTransitions />
|
||||||
|
|
||||||
<!-- Canonical URL -->
|
<!-- Canonical URL -->
|
||||||
<link rel="canonical" href={canonicalURL} />
|
<link rel="canonical" href={canonicalURL} />
|
||||||
|
@ -63,16 +65,19 @@ const { title = settings.name } = Astro.props;
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
</body>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
html {
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--theme-space-lg);
|
gap: var(--theme-space-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header, main {
|
.header,
|
||||||
|
main {
|
||||||
padding-inline: var(--theme-space-sm-lg);
|
padding-inline: var(--theme-space-sm-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,4 +87,5 @@ const { title = settings.name } = Astro.props;
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -31,7 +31,7 @@ const { title } = isArticle(post) && post.data;
|
||||||
<span>Back to feed</span>
|
<span>Back to feed</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{isArticle(post) ? (<Article article={post} />) : (<div class="card"><Card {post} /></div>)}
|
{isArticle(post) ? <Article article={post} /> : <Card {post} class="card" />}
|
||||||
|
|
||||||
{
|
{
|
||||||
(next || prev) && (
|
(next || prev) && (
|
||||||
|
@ -45,7 +45,11 @@ const { title } = isArticle(post) && post.data;
|
||||||
{next && (
|
{next && (
|
||||||
<a href={`/post/${next.slug}`} class="next">
|
<a href={`/post/${next.slug}`} class="next">
|
||||||
<span>Next post</span>
|
<span>Next post</span>
|
||||||
<Icon icon="arrow-right" size="var(--theme-space-md)" color="var(--theme-accent-dark)" />
|
<Icon
|
||||||
|
icon="arrow-right"
|
||||||
|
size="var(--theme-space-md)"
|
||||||
|
color="var(--theme-accent-dark)"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
</footer>
|
</footer>
|
||||||
|
@ -68,12 +72,15 @@ const { title } = isArticle(post) && post.data;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 60ch;
|
margin: var(--theme-space-md) auto;
|
||||||
margin-inline: auto;
|
|
||||||
padding-block: var(--theme-space-md);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.prev, .next {
|
.center {
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prev,
|
||||||
|
.next {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
--theme-shadow-md: 2px 2px 10px rgba(0, 0, 0, 0.1);
|
--theme-shadow-md: 2px 2px 10px rgba(0, 0, 0, 0.1);
|
||||||
--theme-shadow-lg: 2px 2px 20px rgba(0, 0, 0, 0.2);
|
--theme-shadow-lg: 2px 2px 20px rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
|
/* Content Sizes */
|
||||||
|
--theme-size-content-1: 30ch;
|
||||||
|
--theme-size-content-2: 45ch;
|
||||||
|
--theme-size-content-3: 65ch;
|
||||||
|
|
||||||
/* Type Scale */
|
/* Type Scale */
|
||||||
/* @link https://utopia.fyi/type/calculator?c=320,16,1.2,1240,20,1.2,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
|
/* @link https://utopia.fyi/type/calculator?c=320,16,1.2,1240,20,1.2,5,2,&s=0.75|0.5|0.25,1.5|2|3|4|6,s-l&g=s,l,xl,12 */
|
||||||
--theme-text-sm: clamp(0.83rem, calc(0.76rem + 0.36vw), 1.04rem);
|
--theme-text-sm: clamp(0.83rem, calc(0.76rem + 0.36vw), 1.04rem);
|
||||||
|
|
Loading…
Reference in a new issue