some basic view transition support

This commit is contained in:
Tony Sullivan 2023-09-18 12:50:14 -05:00
parent 1d9faff6fe
commit 6800e399ed
7 changed files with 84 additions and 43 deletions

View file

@ -1,6 +1,6 @@
---
import ArticleHeader from './ArticleHeader.astro';
import type { Article, Post } from '../content/config.js';
import type { Article } from '../content/config.js';
export interface Props {
article: Article;
@ -13,9 +13,9 @@ const { Content } = await article.render();
<article>
<ArticleHeader {article} class="header" />
<div class="e-content">
<Content />
</div>
<div class="e-content">
<Content />
</div>
</article>
<style>
@ -24,6 +24,14 @@ const { Content } = await article.render();
flex-direction: column;
gap: var(--theme-space-lg);
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(* + *) {

View file

@ -41,7 +41,7 @@ const { text: readingTime } = await getReadingTime(article.body);
</p>
</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} />}
</header>
@ -93,7 +93,7 @@ const { text: readingTime } = await getReadingTime(article.body);
@media (min-width: 640px) {
.cover {
margin-block-end: var(--theme-space-sm);
margin-block-end: var(--theme-space-sm);
}
.p-author {

View file

@ -11,14 +11,16 @@ export interface Props extends HTMLAttributes<'article'> {
post: Post;
}
const { post, ...attrs } = Astro.props;
const { post, class: className, ...attrs } = Astro.props;
const { pubDate, categories = [] } = post.data;
const cover = 'cover' in post.data && post.data.cover;
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">
<Image {...settings.avatar} width={120} class="u-photo" />
<strong class="p-name">{settings.name}</strong>
@ -35,12 +37,24 @@ const title = 'title' in post.data && post.data.title;
isArticle(post) ? (
<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>
<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" />
<span class="sr-only">Share this post</span>
</a>
@ -49,6 +63,7 @@ const title = 'title' in post.data && post.data.title;
<style>
article {
max-width: var(--theme-size-content-2);
padding: var(--theme-space-sm) var(--theme-space-sm) var(--theme-space-md);
background-color: var(--theme-bg-accent);
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);
column-gap: var(--theme-space-sm);
}
.u-photo {
.h-card .u-photo {
grid-area: avatar;
width: 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;
justify-content: space-between;
}
footer > *:only-child {
margin-inline-start: auto;
}
</style>

View file

@ -16,20 +16,17 @@ const { reverse = false, class: className, ...attrs } = Astro.props;
div {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--theme-space-lg);
margin: 0 auto;
width: 100%;
max-width: var(--theme-content-width);
max-width: var(--theme-size-content-3);
}
@media (min-width: 50em) {
div {
display: grid;
grid-template-columns: 12rem 1fr;
}
div.reverse {
grid-template-columns: 1fr 12rem;
flex-direction: row;
align-items: initial;
}
}
</style>

View file

@ -1,4 +1,5 @@
---
import { ViewTransitions } from 'astro:transitions';
import settings from '../settings';
import '../style/theme.css';
import '../style/global.css';
@ -22,6 +23,7 @@ const { title = settings.name } = Astro.props;
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<ViewTransitions />
<!-- Canonical URL -->
<link rel="canonical" href={canonicalURL} />
@ -63,23 +65,27 @@ const { title = settings.name } = Astro.props;
<slot />
</main>
<Footer />
<style>
html {
scrollbar-gutter: stable;
}
body {
display: flex;
flex-direction: column;
gap: var(--theme-space-lg);
}
.header,
main {
padding-inline: var(--theme-space-sm-lg);
}
main {
width: 100%;
max-width: 55rem;
margin-inline: auto;
}
</style>
</body>
<style>
body {
display: flex;
flex-direction: column;
gap: var(--theme-space-lg);
}
.header, main {
padding-inline: var(--theme-space-sm-lg);
}
main {
width: 100%;
max-width: 55rem;
margin-inline: auto;
}
</style>
</html>

View file

@ -31,7 +31,7 @@ const { title } = isArticle(post) && post.data;
<span>Back to feed</span>
</a>
{isArticle(post) ? (<Article article={post} />) : (<div class="card"><Card {post} /></div>)}
{isArticle(post) ? <Article article={post} /> : <Card {post} class="card" />}
{
(next || prev) && (
@ -45,7 +45,11 @@ const { title } = isArticle(post) && post.data;
{next && (
<a href={`/post/${next.slug}`} class="next">
<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>
)}
</footer>
@ -68,12 +72,15 @@ const { title } = isArticle(post) && post.data;
.card {
width: 100%;
max-width: 60ch;
margin-inline: auto;
padding-block: var(--theme-space-md);
margin: var(--theme-space-md) auto;
}
.prev, .next {
.center {
margin-inline: auto;
}
.prev,
.next {
display: flex;
align-items: center;
gap: 0.5rem;

View file

@ -26,6 +26,11 @@
--theme-shadow-md: 2px 2px 10px rgba(0, 0, 0, 0.1);
--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 */
/* @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);