@astgov/theme 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -15
- package/package.json +17 -5
- package/src/components/Banner.astro +8 -7
- package/src/components/CategorySection.astro +13 -5
- package/src/components/Countdown.astro +7 -6
- package/src/components/Footer.astro +6 -3
- package/src/components/Header.astro +9 -5
- package/src/components/Headline.astro +3 -1
- package/src/components/Nav.astro +3 -3
- package/src/components/QuickLinks.astro +7 -4
- package/src/layouts/BaseLayout.astro +16 -2
package/README.md
CHANGED
|
@@ -1,30 +1,37 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AstGov 主题包
|
|
2
2
|
|
|
3
|
-
老派机构风 Astro 主题包。看起来像 2005 的政府网站,写起来像 2026 的 Astro
|
|
3
|
+
老派机构风 Astro 主题包。看起来像 2005 的政府网站,写起来像 2026 的 Astro。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
基于 **Astro 6.x**,使用 Content Layer API、`astro:assets` 图片优化、CSS 自定义属性主题系统。
|
|
6
|
+
|
|
7
|
+
完整文档在 `docs/` 目录下:
|
|
8
|
+
|
|
9
|
+
- [快速开始](./docs/getting-started.md) — 5 分钟跑起来
|
|
10
|
+
- [目录结构](./docs/directory-structure.md) — 文件说明
|
|
11
|
+
- [配置详解](./docs/configuration.md) — 所有可配置项
|
|
12
|
+
- [文章与页面管理](./docs/content-management.md) — 写文章、建页面
|
|
13
|
+
- [样式定制](./docs/styling.md) — 改样式、换字体
|
|
14
|
+
- [部署指南](./docs/deployment.md) — 发布上线
|
|
15
|
+
- [常见问题](./docs/faq.md) — 排查问题
|
|
16
|
+
|
|
17
|
+
## 快速上手
|
|
6
18
|
|
|
7
19
|
```bash
|
|
8
|
-
# 1.
|
|
9
|
-
|
|
20
|
+
# 1. 克隆示例网站
|
|
21
|
+
git clone https://github.com/OrO-c/astgov-demo-site my-site
|
|
22
|
+
cd my-site
|
|
10
23
|
|
|
11
|
-
# 2.
|
|
24
|
+
# 2. 安装
|
|
12
25
|
npm install
|
|
13
26
|
|
|
14
27
|
# 3. 启动
|
|
15
28
|
npm run dev
|
|
16
|
-
|
|
17
|
-
# 4. 构建
|
|
18
|
-
npm run build
|
|
19
29
|
```
|
|
20
30
|
|
|
21
|
-
|
|
31
|
+
**要求:Node.js 22.12.0 或更高版本。**
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
- [配置详解](./docs/configuration.md)
|
|
25
|
-
- [页面 API](./docs/pages-api.md)
|
|
26
|
-
- [部署指南](./docs/deployment.md)
|
|
33
|
+
浏览器打开 `http://localhost:4321` 即可看到效果。
|
|
27
34
|
|
|
28
|
-
##
|
|
35
|
+
## 许可证
|
|
29
36
|
|
|
30
37
|
MIT
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astgov/theme",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "2005-style university website theme for Astro — 看起来像 2005,写起来像 2026",
|
|
6
|
+
"peerDependencies": {
|
|
7
|
+
"astro": "^6.4.8"
|
|
8
|
+
},
|
|
6
9
|
"exports": {
|
|
7
10
|
".": "./lib/index.ts",
|
|
8
11
|
"./layouts/*": "./src/layouts/*.astro",
|
|
@@ -14,13 +17,22 @@
|
|
|
14
17
|
"src",
|
|
15
18
|
"README.md"
|
|
16
19
|
],
|
|
17
|
-
"
|
|
18
|
-
"
|
|
20
|
+
"scripts": {
|
|
21
|
+
"dev": "astro dev",
|
|
22
|
+
"build": "astro build",
|
|
23
|
+
"preview": "astro preview"
|
|
19
24
|
},
|
|
20
|
-
"keywords": [
|
|
25
|
+
"keywords": [
|
|
26
|
+
"astro",
|
|
27
|
+
"theme",
|
|
28
|
+
"university",
|
|
29
|
+
"government",
|
|
30
|
+
"retro",
|
|
31
|
+
"china"
|
|
32
|
+
],
|
|
21
33
|
"license": "MIT",
|
|
22
34
|
"repository": {
|
|
23
35
|
"type": "git",
|
|
24
|
-
"url": "https://github.com/
|
|
36
|
+
"url": "https://github.com/OrO-c/AstGov"
|
|
25
37
|
}
|
|
26
38
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { Image } from 'astro:assets';
|
|
3
|
+
interface Props { images: { src: string; alt: string; link?: string }[]; height?: number; autoplayInterval?: number; prevText?: string; nextText?: string }
|
|
4
|
+
const { images = [], height = 360, autoplayInterval = 4000, prevText = '‹', nextText = '›' } = Astro.props;
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
{images.length > 0 && (
|
|
@@ -8,20 +9,20 @@ const { images = [] } = Astro.props;
|
|
|
8
9
|
<div class="banner-slides" id="bannerSlides">
|
|
9
10
|
{images.map((img, i) => (
|
|
10
11
|
<div class="banner-slide" data-index={i}>
|
|
11
|
-
{img.link ? <a href={img.link}><
|
|
12
|
+
{img.link ? <a href={img.link}><Image src={img.src} alt={img.alt} /></a> : <Image src={img.src} alt={img.alt} />}
|
|
12
13
|
</div>
|
|
13
14
|
))}
|
|
14
15
|
</div>
|
|
15
16
|
{images.length > 1 && (<>
|
|
16
|
-
<button class="banner-btn banner-prev" id="bannerPrev" aria-label="上一张"
|
|
17
|
-
<button class="banner-btn banner-next" id="bannerNext" aria-label="下一张"
|
|
17
|
+
<button class="banner-btn banner-prev" id="bannerPrev" aria-label="上一张">{prevText}</button>
|
|
18
|
+
<button class="banner-btn banner-next" id="bannerNext" aria-label="下一张">{nextText}</button>
|
|
18
19
|
<div class="banner-dots" id="bannerDots">{images.map((_, i) => (<span class="banner-dot" data-index={i}></span>))}</div>
|
|
19
20
|
</>)}
|
|
20
21
|
</div>
|
|
21
22
|
)}
|
|
22
23
|
|
|
23
24
|
<script>
|
|
24
|
-
(function(){var b=document.getElementById('banner');if(!b)return;var s=document.getElementById('bannerSlides'),sl=s?.querySelectorAll('.banner-slide'),dt=document.querySelectorAll('.banner-dot'),p=document.getElementById('bannerPrev'),n=document.getElementById('bannerNext');if(!sl||sl.length<2)return;var c=0,iv;function go(i){sl.forEach(function(e,j){e.style.display=j===i?'block':'none'});dt.forEach(function(e,j){e.className=j===i?'banner-dot active':'banner-dot'});c=i}function nx(){go((c+1)%sl.length)}function pr(){go((c-1+sl.length)%sl.length)}function st(){cl();iv=window.setInterval(nx,
|
|
25
|
+
(function(){var b=document.getElementById('banner');if(!b)return;var s=document.getElementById('bannerSlides'),sl=s?.querySelectorAll('.banner-slide'),dt=document.querySelectorAll('.banner-dot'),p=document.getElementById('bannerPrev'),n=document.getElementById('bannerNext');if(!sl||sl.length<2)return;var c=0,iv;function go(i){sl.forEach(function(e,j){e.style.display=j===i?'block':'none'});dt.forEach(function(e,j){e.className=j===i?'banner-dot active':'banner-dot'});c=i}function nx(){go((c+1)%sl.length)}function pr(){go((c-1+sl.length)%sl.length)}function st(){cl();iv=window.setInterval(nx,{autoplayInterval})}function cl(){if(iv){clearInterval(iv);iv=0}}go(0);st();p?.addEventListener('click',function(e){e.preventDefault();pr();st()});n?.addEventListener('click',function(e){e.preventDefault();nx();st()});dt.forEach(function(e){e.addEventListener('click',function(){go(parseInt(this.getAttribute('data-index')||'0',10));st()})});b.addEventListener('mouseenter',cl);b.addEventListener('mouseleave',st)})();
|
|
25
26
|
</script>
|
|
26
27
|
|
|
27
28
|
<style>
|
|
@@ -29,7 +30,7 @@ const { images = [] } = Astro.props;
|
|
|
29
30
|
.banner-slides { position: relative; }
|
|
30
31
|
.banner-slide { display: none; }
|
|
31
32
|
.banner-slide:first-child { display: block; }
|
|
32
|
-
.banner-slide img { display: block; width: 100%; height:
|
|
33
|
+
.banner-slide img { display: block; width: 100%; height: {height}px; object-fit: cover; }
|
|
33
34
|
.banner-btn { position: absolute; top: 50%; transform: translateY(-50%); z-index: 10; background: rgba(0,0,0,.35); color: #FFF; border: none; font-size: 36px; line-height: 1; padding: 8px 14px; cursor: pointer; font-family: Arial,sans-serif; transition: background .2s; border-radius: 0; }
|
|
34
35
|
.banner-btn:hover { background: rgba(0,0,0,.6); }
|
|
35
36
|
.banner-prev { left: 10px; }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
interface Post {
|
|
3
|
-
|
|
3
|
+
id: string;
|
|
4
4
|
data: { title: string; date: string; tags?: string[] };
|
|
5
5
|
}
|
|
6
6
|
|
|
@@ -8,25 +8,33 @@ interface Props {
|
|
|
8
8
|
title?: string;
|
|
9
9
|
posts?: Post[];
|
|
10
10
|
viewAllLink?: string;
|
|
11
|
+
moreText?: string;
|
|
12
|
+
dateFormat?: string;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
const { title, posts = [], viewAllLink } = Astro.props;
|
|
15
|
+
const { title, posts = [], viewAllLink, moreText = '更多 →', dateFormat = '{month}月' } = Astro.props;
|
|
16
|
+
// 从 id 中提取链接路径(去掉 "pages/" 前缀、保留其余路径段)
|
|
17
|
+
function entryLink(id: string): string {
|
|
18
|
+
const parts = id.split('/');
|
|
19
|
+
// id 格式如 "pages/news/001",去掉第一段得到 "news/001"
|
|
20
|
+
return parts.slice(1).join('/');
|
|
21
|
+
}
|
|
14
22
|
---
|
|
15
23
|
|
|
16
24
|
<div class="module">
|
|
17
25
|
<div class="list-header">
|
|
18
26
|
<h3 class="module-title">{title}</h3>
|
|
19
|
-
{viewAllLink && <a href={viewAllLink} class="more-link"
|
|
27
|
+
{viewAllLink && <a href={viewAllLink} class="more-link">{moreText}</a>}
|
|
20
28
|
</div>
|
|
21
29
|
<div class="list-body">
|
|
22
30
|
{posts.map(post => {
|
|
23
31
|
const d = post.data.date;
|
|
24
32
|
return (
|
|
25
33
|
<div class="list-item">
|
|
26
|
-
<a href={`/${post.
|
|
34
|
+
<a href={`/${entryLink(post.id)}`} class="list-link">
|
|
27
35
|
<span class="list-date-block">
|
|
28
36
|
<span class="list-day">{d.slice(8, 10)}</span>
|
|
29
|
-
<span class="list-month">{d.slice(5, 7)}
|
|
37
|
+
<span class="list-month">{dateFormat.replace('{month}', d.slice(5, 7)).replace('{day}', d.slice(8, 10)).replace('{year}', d.slice(0, 4))}</span>
|
|
30
38
|
</span>
|
|
31
39
|
<span class="list-text">{post.data.title}</span>
|
|
32
40
|
</a>
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
---
|
|
2
|
-
interface Props { title?: string; targetDate?: string; buttonLink?: string; buttonText?: string; }
|
|
3
|
-
const { title = '距报名截止还有', targetDate = '', buttonLink = '/signup', buttonText = '立即报名 →' } = Astro.props;
|
|
2
|
+
interface Props { title?: string; targetDate?: string; buttonLink?: string; buttonText?: string; labels?: { days?: string; hours?: string; minutes?: string; seconds?: string } }
|
|
3
|
+
const { title = '距报名截止还有', targetDate = '', buttonLink = '/signup', buttonText = '立即报名 →', labels } = Astro.props;
|
|
4
|
+
const lb = labels || {};
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
{targetDate && (
|
|
7
8
|
<div class="countdown-module">
|
|
8
9
|
<div class="countdown-title">{title}</div>
|
|
9
10
|
<div class="countdown-display" id="countdownDisplay" data-target={targetDate}>
|
|
10
|
-
<span class="countdown-num" id="cdDays">00</span><span class="countdown-label"
|
|
11
|
-
<span class="countdown-num" id="cdHours">00</span><span class="countdown-label"
|
|
12
|
-
<span class="countdown-num" id="cdMinutes">00</span><span class="countdown-label"
|
|
13
|
-
<span class="countdown-num" id="cdSeconds">00</span><span class="countdown-label"
|
|
11
|
+
<span class="countdown-num" id="cdDays">00</span><span class="countdown-label">{lb.days || '天'}</span>
|
|
12
|
+
<span class="countdown-num" id="cdHours">00</span><span class="countdown-label">{lb.hours || '时'}</span>
|
|
13
|
+
<span class="countdown-num" id="cdMinutes">00</span><span class="countdown-label">{lb.minutes || '分'}</span>
|
|
14
|
+
<span class="countdown-num" id="cdSeconds">00</span><span class="countdown-label">{lb.seconds || '秒'}</span>
|
|
14
15
|
</div>
|
|
15
16
|
<a href={buttonLink} class="countdown-btn">{buttonText}</a>
|
|
16
17
|
</div>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { Image } from 'astro:assets';
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
organization?: string;
|
|
4
6
|
contacts?: { label: string; value: string }[];
|
|
@@ -8,9 +10,10 @@ interface Props {
|
|
|
8
10
|
extraLinks?: { text: string; url: string }[];
|
|
9
11
|
qrCodes?: { src: string; alt: string }[];
|
|
10
12
|
footerLogo?: string;
|
|
13
|
+
copyright?: string;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
const { organization = '', contacts = [], records = [], policeRecord, links = [], extraLinks = [], qrCodes = [] } = Astro.props;
|
|
16
|
+
const { organization = '', contacts = [], records = [], policeRecord, links = [], extraLinks = [], qrCodes = [], copyright } = Astro.props;
|
|
14
17
|
---
|
|
15
18
|
|
|
16
19
|
<footer class="footer">
|
|
@@ -24,9 +27,9 @@ const { organization = '', contacts = [], records = [], policeRecord, links = []
|
|
|
24
27
|
<div class="footer-extra">{extraLinks.map((link, i) => (<span>{i > 0 && <span class="footer-sep">|</span>}<a href={link.url}>{link.text}</a></span>))}</div>
|
|
25
28
|
)}
|
|
26
29
|
{qrCodes.length > 0 && (
|
|
27
|
-
<div class="footer-qr">{qrCodes.map(qr => (<div class="qr-item"><
|
|
30
|
+
<div class="footer-qr">{qrCodes.map(qr => (<div class="qr-item"><Image src={qr.src} alt={qr.alt} class="qr-img" /><span class="qr-alt">{qr.alt}</span></div>))}</div>
|
|
28
31
|
)}
|
|
29
|
-
<div class="footer-copyright"
|
|
32
|
+
<div class="footer-copyright">{(copyright || '版权所有 © {year} {org}').replace('{year}', String(new Date().getFullYear())).replace('{org}', organization)}</div>
|
|
30
33
|
</div>
|
|
31
34
|
</footer>
|
|
32
35
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { Image } from 'astro:assets';
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
siteName?: string;
|
|
4
6
|
siteSubtitle?: string;
|
|
@@ -10,9 +12,11 @@ interface Props {
|
|
|
10
12
|
searchEnabled?: boolean;
|
|
11
13
|
searchPlaceholder?: string;
|
|
12
14
|
};
|
|
15
|
+
fontSizeLabels?: { small?: string; medium?: string; large?: string };
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
const { siteName, siteSubtitle, siteLogo, topBar = {} } = Astro.props;
|
|
18
|
+
const { siteName, siteSubtitle, siteLogo, topBar = {}, fontSizeLabels } = Astro.props;
|
|
19
|
+
const fl = fontSizeLabels || {};
|
|
16
20
|
const { enabled = true, quickLinks = [], rightLinks = [], searchEnabled = false, searchPlaceholder = '请输入关键字' } = topBar;
|
|
17
21
|
---
|
|
18
22
|
|
|
@@ -27,11 +31,11 @@ const { enabled = true, quickLinks = [], rightLinks = [], searchEnabled = false,
|
|
|
27
31
|
</div>
|
|
28
32
|
<div class="toolbar-right">
|
|
29
33
|
<span class="font-size-group">
|
|
30
|
-
<a href="#" class="font-btn font-small" data-size="small" title="
|
|
34
|
+
<a href="#" class="font-btn font-small" data-size="small" title="{fl.small || '小'}字号">{fl.small || '小'}</a>
|
|
31
35
|
<span class="font-sep">|</span>
|
|
32
|
-
<a href="#" class="font-btn font-medium" data-size="medium" title="
|
|
36
|
+
<a href="#" class="font-btn font-medium" data-size="medium" title="{fl.medium || '中'}字号">{fl.medium || '中'}</a>
|
|
33
37
|
<span class="font-sep">|</span>
|
|
34
|
-
<a href="#" class="font-btn font-large" data-size="large" title="
|
|
38
|
+
<a href="#" class="font-btn font-large" data-size="large" title="{fl.large || '大'}字号">{fl.large || '大'}</a>
|
|
35
39
|
</span>
|
|
36
40
|
{searchEnabled && (
|
|
37
41
|
<form class="search-form" action="/search" method="get">
|
|
@@ -48,7 +52,7 @@ const { enabled = true, quickLinks = [], rightLinks = [], searchEnabled = false,
|
|
|
48
52
|
)}
|
|
49
53
|
<div class="header-main">
|
|
50
54
|
<div class="container header-main-inner">
|
|
51
|
-
{siteLogo && <a href="/" class="logo-link"><
|
|
55
|
+
{siteLogo && <a href="/" class="logo-link"><Image src={siteLogo} alt={siteName || ''} class="logo-img" /></a>}
|
|
52
56
|
<div class="site-title-group">
|
|
53
57
|
<h1 class="site-name"><a href="/">{siteName}</a></h1>
|
|
54
58
|
{siteSubtitle && <p class="site-subtitle">{siteSubtitle}</p>}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
+
import { Image } from 'astro:assets';
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
cards?: { src: string; alt: string; title: string; date: string; link?: string }[];
|
|
4
6
|
}
|
|
@@ -11,7 +13,7 @@ const { cards = [] } = Astro.props;
|
|
|
11
13
|
{cards.map(card => (
|
|
12
14
|
<article class="headline-card">
|
|
13
15
|
<a href={card.link || '#'}>
|
|
14
|
-
<div class="card-img"><
|
|
16
|
+
<div class="card-img"><Image src={card.src} alt={card.alt} /></div>
|
|
15
17
|
<div class="card-body"><h3 class="card-title">{card.title}</h3><time class="card-date">{card.date}</time></div>
|
|
16
18
|
</a>
|
|
17
19
|
</article>
|
package/src/components/Nav.astro
CHANGED
|
@@ -7,8 +7,8 @@ interface NavItem {
|
|
|
7
7
|
dropdown?: { text: string; url: string; target?: string }[];
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
interface Props { items?: NavItem[] }
|
|
11
|
-
const { items = [] } = Astro.props;
|
|
10
|
+
interface Props { items?: NavItem[]; dropdownArrow?: string }
|
|
11
|
+
const { items = [], dropdownArrow = '▼' } = Astro.props;
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
<nav class="nav">
|
|
@@ -20,7 +20,7 @@ const { items = [] } = Astro.props;
|
|
|
20
20
|
class:list={{ 'nav-link': true, highlight: item.highlight }}
|
|
21
21
|
>
|
|
22
22
|
{item.text}
|
|
23
|
-
{item.dropdown && item.dropdown.length > 0 && <span class="nav-arrow"
|
|
23
|
+
{item.dropdown && item.dropdown.length > 0 && <span class="nav-arrow">{dropdownArrow}</span>}
|
|
24
24
|
</a>
|
|
25
25
|
{item.dropdown && item.dropdown.length > 0 && (
|
|
26
26
|
<div class="dropdown-menu">
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
interface Props {
|
|
3
3
|
links?: { text: string; url: string; target?: string }[];
|
|
4
|
+
title?: string;
|
|
5
|
+
expandText?: string;
|
|
6
|
+
collapseText?: string;
|
|
4
7
|
}
|
|
5
|
-
const { links = [] } = Astro.props;
|
|
8
|
+
const { links = [], title = '快速通道', expandText = '展开更多', collapseText = '收起' } = Astro.props;
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
{links.length > 0 && (
|
|
9
12
|
<section class="ql-section"><div class="container">
|
|
10
13
|
<div class="ql-bar">
|
|
11
|
-
<div class="ql-label"
|
|
14
|
+
<div class="ql-label">{title}</div>
|
|
12
15
|
<div class="ql-list" id="qlList">
|
|
13
16
|
{links.map(link => (
|
|
14
17
|
<a href={link.url} target={link.target || '_self'} class="ql-item">
|
|
@@ -16,13 +19,13 @@ const { links = [] } = Astro.props;
|
|
|
16
19
|
</a>
|
|
17
20
|
))}
|
|
18
21
|
</div>
|
|
19
|
-
{links.length > 4 && <button class="ql-toggle" id="qlToggle"
|
|
22
|
+
{links.length > 4 && <button class="ql-toggle" id="qlToggle" data-expand={expandText} data-collapse={collapseText}>{expandText}</button>}
|
|
20
23
|
</div>
|
|
21
24
|
</div></section>
|
|
22
25
|
)}
|
|
23
26
|
|
|
24
27
|
<script>
|
|
25
|
-
(function(){var t=document.getElementById('qlToggle'),l=document.getElementById('qlList');if(!t||!l)return;t.addEventListener('click',function(){l.classList.toggle('expanded');t.textContent=l.classList.contains('expanded')?
|
|
28
|
+
(function(){var t=document.getElementById('qlToggle'),l=document.getElementById('qlList');if(!t||!l)return;t.addEventListener('click',function(){l.classList.toggle('expanded');t.textContent=l.classList.contains('expanded')?co:ex})})();
|
|
26
29
|
</script>
|
|
27
30
|
|
|
28
31
|
<style>
|
|
@@ -60,6 +60,17 @@ interface Props {
|
|
|
60
60
|
fontFamily?: string;
|
|
61
61
|
};
|
|
62
62
|
defaultFontSize?: string;
|
|
63
|
+
/** UI 文本配置 */
|
|
64
|
+
ui?: {
|
|
65
|
+
moreText?: string;
|
|
66
|
+
dropdownArrow?: string;
|
|
67
|
+
copyright?: string;
|
|
68
|
+
quickLinks?: { title?: string; expandText?: string; collapseText?: string };
|
|
69
|
+
friendLinks?: { title?: string };
|
|
70
|
+
fontSizeLabels?: { small?: string; medium?: string; large?: string };
|
|
71
|
+
countdown?: { labels?: { days?: string; hours?: string; minutes?: string; seconds?: string } };
|
|
72
|
+
dateFormat?: string;
|
|
73
|
+
};
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
const {
|
|
@@ -75,6 +86,7 @@ const {
|
|
|
75
86
|
footer = { organization: '' },
|
|
76
87
|
colors = {},
|
|
77
88
|
defaultFontSize = 'medium',
|
|
89
|
+
ui = {},
|
|
78
90
|
} = Astro.props;
|
|
79
91
|
|
|
80
92
|
const fontSizeAttr = defaultFontSize;
|
|
@@ -106,7 +118,7 @@ const cssVars = `
|
|
|
106
118
|
<meta name="keywords" content={keywords} />
|
|
107
119
|
<link rel="icon" href={siteIcon} type="image/svg+xml" />
|
|
108
120
|
<link rel="stylesheet" href="/styles/global.css" />
|
|
109
|
-
<
|
|
121
|
+
<Fragment set:html={`<style>${cssVars}</style>`} />
|
|
110
122
|
</head>
|
|
111
123
|
<body>
|
|
112
124
|
<Header
|
|
@@ -114,8 +126,9 @@ const cssVars = `
|
|
|
114
126
|
siteSubtitle={siteSubtitle}
|
|
115
127
|
siteLogo={siteLogo}
|
|
116
128
|
topBar={topBar}
|
|
129
|
+
fontSizeLabels={ui.fontSizeLabels}
|
|
117
130
|
/>
|
|
118
|
-
<Nav items={navItems} />
|
|
131
|
+
<Nav items={navItems} dropdownArrow={ui.dropdownArrow} />
|
|
119
132
|
<main>
|
|
120
133
|
<slot />
|
|
121
134
|
</main>
|
|
@@ -128,6 +141,7 @@ const cssVars = `
|
|
|
128
141
|
extraLinks={footer.extraLinks}
|
|
129
142
|
qrCodes={footer.qrCodes}
|
|
130
143
|
footerLogo={footer.footerLogo}
|
|
144
|
+
copyright={ui.copyright}
|
|
131
145
|
/>
|
|
132
146
|
</body>
|
|
133
147
|
</html>
|