This commit is contained in:
2025-11-25 19:53:38 +08:00
parent 2c4ed896e8
commit db55d8fd83
6 changed files with 116 additions and 28 deletions

56
src/apps/menu.tsx Normal file
View File

@@ -0,0 +1,56 @@
import { useMemo } from "react";
export type MenuProps = {
items: MenuItem[];
basename?: string;
};
export type MenuItem = {
id: string;
data: {
title: string;
tags: string[];
hideInMenu?: boolean;
}
}
export const Menu = (props: MenuProps) => {
const { items, basename = '' } = props;
const list = useMemo(() => {
return items.filter(item => !item.data?.hideInMenu);
}, [items]);
if (list.length === 0) {
return null;
}
return (
<nav className='flex-1 overflow-y-auto scrollbar bg-sidebar border border-sidebar-border rounded-lg p-4 shadow-sm'>
<h2 className="text-sm font-semibold text-sidebar-foreground"></h2>
<div className="space-y-1">
{list.map(item => (
<a
key={item.id}
href={`${basename}/docs/${item.id}/`}
className="group block rounded-md hover:bg-sidebar-accent transition-all duration-200 ease-in-out"
>
<div className="px-3 py-2.5">
<h3 className="text-sm font-semibold text-sidebar-foreground group-hover:text-sidebar-accent-foreground transition-colors">
{item.data?.title}
</h3>
{item.data?.tags && item.data.tags.length > 0 && (
<div className="flex flex-wrap gap-1.5 mt-2">
{item.data.tags.map(tag => (
<span
key={tag}
className="text-xs px-2 py-0.5 rounded-full bg-muted/60 text-muted-foreground font-medium hover:bg-muted transition-colors"
>
{tag}
</span>
))}
</div>
)}
</div>
</a>
))}
</div>
</nav>
);
}

View File

@@ -12,6 +12,11 @@ const docs = defineCollection({
// pubDate: z.coerce.date(),
createdAt: z.coerce.date().optional(),
updatedAt: z.coerce.date().optional(),
showMenu: z.boolean().optional().default(true),
/**
* 在侧边栏隐藏该文档
*/
hideInMenu: z.boolean().optional().default(false),
}),
});

8
src/data/docs/menu.md Normal file
View File

@@ -0,0 +1,8 @@
---
title: 'astro 概览'
tags: ['astro', 'simple', 'template']
createdAt: '2025-11-25 20:00:00'
hideInMenu: true
---
## 概览

View File

@@ -1,6 +1,8 @@
---
title: 'astro 例子'
tags: ['astro', 'simple', 'template']
createdAt: '2025-11-25 20:00:00'
hideInMenu: true
---
## astro-simplate-template

View File

@@ -5,29 +5,34 @@ export interface Props {
import '../styles/global.css';
import '../styles/theme.css';
import 'github-markdown-css/github-markdown-light.css';
import { Menu, MenuItem } from '../apps/menu';
export interface Props {
title?: string;
description?: string;
lang?: string;
charset?: string;
showMenu?: boolean;
menu?: MenuItem[];
basename?: string;
}
const { title = 'Light Code', description = 'A lightweight code editor', lang = 'zh-CN', charset = 'UTF-8' } = Astro.props;
const {
title = 'Light Code',
description = 'A lightweight code editor',
lang = 'zh-CN',
charset = 'UTF-8',
showMenu = true,
menu,
basename = '',
} = Astro.props;
---
<html lang='zh-CN'>
<html lang={lang}>
<head>
<meta charset='UTF-8' />
<meta charset={charset} />
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
<title>Docs</title>
<link
rel='stylesheet'
href='https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.8.1/github-markdown-light.min.css'
integrity='sha512-X175XRJAO6PHAUi8AA7GP8uUF5Wiv+w9bOi64i02CHKDQBsO1yy0jLSKaUKg/NhRCDYBmOLQCfKaTaXiyZlLrw=='
crossorigin='anonymous'
referrerpolicy='no-referrer'
/>
<title>{title}</title>
<meta name='description' content={description} />
<style>
html,
body {
@@ -37,25 +42,29 @@ const { title = 'Light Code', description = 'A lightweight code editor', lang =
padding: 0;
overflow: hidden;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
</head>
<body>
<div>
<body class='flex flex-col items-center bg-background'>
<div class='w-full'>
<slot name='header' />
</div>
<main class='p-2 flex-1 overflow-hidden'>
<div class='markdown-body h-full scrollbar border-gray-200 overflow-auto px-6 py-2 w-[800px] border my-4 rounded-md shadow-md'>
<slot />
<main class='flex-1 flex overflow-hidden w-full max-w-7xl px-4 py-4'>
{
showMenu && (
<aside class='w-64 min-w-64 h-full flex flex-col'>
<Menu items={menu!} client:only basename={basename} />
</aside>
)
}
<div class='flex-1 h-full flex items-start justify-center overflow-hidden'>
<article class='markdown-body h-full scrollbar overflow-auto px-8 py-6 w-full max-w-4xl border border-border rounded-lg shadow-sm bg-card'>
<slot />
</article>
</div>
</main>
<footer>
<footer class='w-full border-t border-border bg-card/50 backdrop-blur-sm'>
<slot name='footer'>
<p>Copyrignt &copy; 2025</p>
<div class='text-center text-sm text-muted-foreground py-4'>Copyright &copy; 2025</div>
</slot>
</footer>
</body>

View File

@@ -1,23 +1,31 @@
---
import { getCollection, render } from 'astro:content';
import Main from '@/layouts/mdx.astro';
import { basename } from '@/modules/basename';
// 1. 为每个集合条目生成一个新路径
export async function getStaticPaths() {
const posts = await getCollection('docs');
return posts.map((post) => ({
params: { id: post.id },
props: { post },
props: { post },
data: post,
}));
}
type Post = {
data: { title: string };
data: { title: string; tags: string[]; showMenu?: boolean };
};
// 2. 对于你的模板,你可以直接从 prop 获取条目
const { post } = Astro.props as { post: Post };
const { Content } = await render(post);
console.log('post', post);
const showMenu = post.data?.showMenu;
const staticPaths = await getStaticPaths();
const menu = staticPaths.map((item) => item.data);
---
<Main>
<!-- <h1 slot={'header'}>{post.data.title}</h1> -->
<Main showMenu={showMenu} menu={menu} basename={basename}>
<Content />
<div slot='menu'>
<div>sdfsdfsdf sfsdfsdf</div>
</div>
</Main>