This commit is contained in:
2025-07-18 16:43:10 +02:00
parent ad40616249
commit 8c37084d94
94 changed files with 14759 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
---
import { themeConfig } from '@/config'
import { ClientRouter } from 'astro:transitions'
import ThemeManager from '@/components/ui/ThemeManager.astro'
import FaviconThemeSwitcher from '@/components/ui/FaviconThemeSwitcher.astro'
import TransitionWrapper from '@/components/layout/TransitionWrapper.astro'
import type { LayoutProps } from '@/types'
type Props = LayoutProps
const { type = 'page' } = Astro.props
const language = themeConfig.site.language || 'en-US'
const contentWidth = themeConfig.general.contentWidth
const fadeAnimation = themeConfig.general.fadeAnimation
const widthValue = Math.min(parseFloat(contentWidth), 50)
const shouldUseCustomWidth = widthValue > 25
const finalWidth = shouldUseCustomWidth ? `${widthValue}rem` : '25rem'
---
<html lang={language}>
<head>
{fadeAnimation && <ClientRouter />}
<slot name="head" />
</head>
<body
data-centered={themeConfig.general.centeredLayout}
style={`
max-width: ${finalWidth};
${shouldUseCustomWidth ? `--content-width: ${widthValue}rem;` : ''}
`}
>
<ThemeManager />
<FaviconThemeSwitcher />
{
fadeAnimation ? (
<TransitionWrapper type={type} class="layout-wrapper">
<slot />
</TransitionWrapper>
) : (
<div class="layout-wrapper">
<slot />
</div>
)
}
</body>
</html>
<style is:global>
.layout-wrapper {
display: flex;
flex-direction: column;
min-height: calc(100vh - 7.5rem);
}
@media (max-width: 768px) {
.layout-wrapper {
min-height: calc(100vh - 5.5rem);
}
}
</style>

View File

@@ -0,0 +1,43 @@
---
import '@/styles/global.css'
import BaseHead from '@/components/layout/BaseHead.astro'
import Header from '@/components/layout/Header.astro'
import Footer from '@/components/layout/Footer.astro'
import BaseLayout from '@/layouts/BaseLayout.astro'
import GradientMask from '@/components/ui/GradientMask.astro'
import { themeConfig } from '@/config'
const { title, description } = Astro.props
---
<BaseLayout title={title} description={description} type="page">
<BaseHead title={title} description={description} slot="head" />
<div class="page-content">
<GradientMask />
<div>
<Header />
</div>
<main>
<slot />
</main>
{
themeConfig.general.footer && (
<div>
<Footer />
</div>
)
}
</div>
</BaseLayout>
<style is:global>
.page-content {
flex: 1;
display: flex;
flex-direction: column;
}
.page-content main {
flex: 1;
}
</style>

View File

@@ -0,0 +1,82 @@
---
import '@/styles/global.css'
import type { PostLayoutProps } from '@/types'
import FormattedDate from '@/components/widgets/FormattedDate.astro'
import FootnoteScroll from '@/components/widgets/FootnoteScroll.astro'
import BaseHead from '@/components/layout/BaseHead.astro'
import Footer from '@/components/layout/Footer.astro'
import BackButton from '@/components/ui/BackButton.astro'
import TableOfContents from '@/components/ui/TableOfContents.astro'
import GradientMask from '@/components/ui/GradientMask.astro'
import ImageViewer from '@/components/ui/ImageViewer.astro'
import GitHubCard from '@/components/ui/GitHubCard.astro'
import LinkCard from '@/components/ui/LinkCard.astro'
import ImageOptimizer from '@/components/ui/ImageOptimizer.astro'
import XPOST from '@/components/ui/XPOST.astro'
import CopyCode from '@/components/ui/CopyCode.astro'
import BaseLayout from '@/layouts/BaseLayout.astro'
import { themeConfig } from '@/config'
const { title, pubDate, readingTime, toc } = Astro.props as PostLayoutProps
const postSlug = Astro.url.pathname.split('/').filter(Boolean).pop() || ''
const ogImage = `/open-graph/${postSlug}.png`
---
<BaseLayout
title={`${title} · ${themeConfig.site.title}`}
description={themeConfig.site.description}
type="post"
>
<BaseHead
title={`${title} · ${themeConfig.site.title}`}
description={themeConfig.site.description}
ogImage={ogImage}
slot="head"
/>
<div class="post-container">
<main>
<div class="prose">
<GradientMask />
<BackButton />
{themeConfig.post.toc && <TableOfContents toc={toc} />}
<div class="title">
<h1>{title}</h1>
<div class="date">
<FormattedDate date={pubDate} context="post" />
{
themeConfig.post.readingTime && readingTime && (
<span class="reading-time">
<span class="separator">·</span>
{readingTime.text}
</span>
)
}
</div>
</div>
<slot />
</div>
</main>
<FootnoteScroll />
<CopyCode />
<GitHubCard />
<LinkCard />
<XPOST />
<ImageOptimizer />
{themeConfig.post.imageViewer && <ImageViewer />}
{themeConfig.general.footer && <Footer />}
</div>
</BaseLayout>
<style>
.post-container {
display: flex;
flex-direction: column;
flex: 1;
}
.post-container main {
flex: 1;
}
</style>