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 type { Article, Post } from '../content/config.js';
|
||||
import type { Article } from '../content/config.js';
|
||||
|
||||
export interface Props {
|
||||
article: Article;
|
||||
|
@ -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(* + *) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,16 +65,19 @@ const { title = settings.name } = Astro.props;
|
|||
<slot />
|
||||
</main>
|
||||
<Footer />
|
||||
</body>
|
||||
|
||||
<style>
|
||||
html {
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--theme-space-lg);
|
||||
}
|
||||
|
||||
.header, main {
|
||||
.header,
|
||||
main {
|
||||
padding-inline: var(--theme-space-sm-lg);
|
||||
}
|
||||
|
||||
|
@ -82,4 +87,5 @@ const { title = settings.name } = Astro.props;
|
|||
margin-inline: auto;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue