@xingwangzhe/stalux 1.29.8 → 1.30.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 +5 -1
- package/package.json +10 -6
- package/src/components/stalux/archives/archivesList.astro +19 -15
- package/src/components/stalux/archives/toArchive.astro +2 -2
- package/src/components/stalux/categories/categoriesCard.astro +8 -7
- package/src/components/stalux/categories/categoriesList.astro +3 -2
- package/src/components/stalux/common/author.astro +8 -3
- package/src/components/stalux/common/date.astro +3 -4
- package/src/components/stalux/common/textType.astro +7 -2
- package/src/components/stalux/footer/FooterBadges.astro +9 -97
- package/src/components/stalux/footer/FooterBeian.astro +2 -44
- package/src/components/stalux/footer/FooterCopyright.astro +1 -16
- package/src/components/stalux/footer/FooterStats.astro +4 -25
- package/src/components/stalux/footer/FooterThemeInfo.astro +1 -28
- package/src/components/stalux/layout/footer.astro +3 -3
- package/src/components/stalux/layout/listPage.astro +3 -3
- package/src/components/stalux/layout/navs.astro +16 -13
- package/src/components/stalux/links/linkCard.astro +7 -6
- package/src/components/stalux/links/linkList.astro +4 -3
- package/src/components/stalux/links/socialMedia.astro +2 -2
- package/src/components/stalux/posts/PostTaxonomy.astro +13 -8
- package/src/components/stalux/posts/postAuthor.astro +6 -5
- package/src/components/stalux/posts/postCC.astro +10 -9
- package/src/components/stalux/posts/postCard.astro +19 -15
- package/src/components/stalux/posts/postContent.astro +22 -14
- package/src/components/stalux/posts/postLeft.astro +5 -4
- package/src/components/stalux/posts/postList.astro +2 -3
- package/src/components/stalux/posts/postNavigation.astro +24 -23
- package/src/components/stalux/posts/postRight.astro +7 -6
- package/src/components/stalux/posts/postToc.astro +7 -19
- package/src/components/stalux/posts/randomPost.astro +8 -7
- package/src/components/stalux/tags/tagHeader.astro +10 -6
- package/src/components/stalux/tags/tagsCloud.astro +10 -9
- package/src/components/stalux/words/wordCard.astro +11 -10
- package/src/components/stalux/words/wordList.astro +4 -3
- package/src/index.ts +5 -4
- package/src/internal/runtime-cache-key.ts +13 -1
- package/src/layouts/PostLayout.astro +3 -4
- package/src/layouts/Stalux.astro +0 -17
- package/src/pages/404.astro +9 -77
- package/src/pages/archives.astro +3 -3
- package/src/pages/categories/index.astro +3 -3
- package/src/pages/index.astro +6 -18
- package/src/pages/tags/index.astro +3 -3
- package/src/pages/words.astro +3 -3
- package/src/scripts/waline-client.ts +1 -1
- package/src/styles/archives.css +1 -0
- package/src/styles/article.css +1 -0
- package/src/styles/base.css +287 -0
- package/src/styles/categories.css +1 -0
- package/src/styles/content.css +471 -0
- package/src/styles/generated-archives.css +3 -0
- package/src/styles/generated-article.css +3 -0
- package/src/styles/generated-categories.css +3 -0
- package/src/styles/generated-links.css +3 -0
- package/src/styles/generated-prose.css +2 -0
- package/src/styles/generated-tags.css +3 -0
- package/src/styles/generated-waline.css +2 -0
- package/src/styles/generated-words.css +3 -0
- package/src/styles/generated.css +3 -0
- package/src/styles/{components/posts/waline.css → integrations.css} +19 -23
- package/src/styles/links.css +1 -0
- package/src/styles/{shared/view-transitions.css → motion.css} +96 -0
- package/src/styles/prose.css +1 -0
- package/src/styles/tags.css +1 -0
- package/src/styles/theme.css +1 -0
- package/src/styles/words.css +1 -0
- package/src/styles/base/init.css +0 -287
- package/src/styles/components/archives/archivesList.module.css +0 -203
- package/src/styles/components/archives/toArchive.module.css +0 -3
- package/src/styles/components/categories/categoriesCard.module.css +0 -88
- package/src/styles/components/categories/categoriesList.module.css +0 -23
- package/src/styles/components/common/author.module.css +0 -72
- package/src/styles/components/common/date.module.css +0 -15
- package/src/styles/components/common/textType.module.css +0 -10
- package/src/styles/components/footer/footer.module.css +0 -44
- package/src/styles/components/layout/navs.module.css +0 -261
- package/src/styles/components/links/linkCard.module.css +0 -116
- package/src/styles/components/links/linkList.module.css +0 -54
- package/src/styles/components/links/socialLinks.module.css +0 -80
- package/src/styles/components/markdown.css +0 -523
- package/src/styles/components/posts/postAuthor.module.css +0 -31
- package/src/styles/components/posts/postCC.module.css +0 -138
- package/src/styles/components/posts/postCard.module.css +0 -167
- package/src/styles/components/posts/postContent.module.css +0 -238
- package/src/styles/components/posts/postLayout.module.css +0 -138
- package/src/styles/components/posts/postList.module.css +0 -25
- package/src/styles/components/posts/postNavigation.module.css +0 -186
- package/src/styles/components/posts/postSidebar.module.css +0 -59
- package/src/styles/components/posts/postTaxonomy.module.css +0 -87
- package/src/styles/components/posts/postToc.module.css +0 -74
- package/src/styles/components/posts/randomPost.module.css +0 -131
- package/src/styles/components/tags/tagHeader.module.css +0 -44
- package/src/styles/components/tags/tagsCloud.module.css +0 -155
- package/src/styles/components/words/wordCard.module.css +0 -136
- package/src/styles/components/words/wordList.module.css +0 -26
- package/src/styles/pages/archives.module.css +0 -22
- package/src/styles/pages/categories.module.css +0 -17
- package/src/styles/pages/home.module.css +0 -61
- package/src/styles/pages/listPage.module.css +0 -16
- package/src/styles/pages/tags.module.css +0 -16
- package/src/styles/pages/words.module.css +0 -16
- package/src/styles/shared/animations.css +0 -87
- package/src/styles/shared/stagger.css +0 -20
- /package/src/styles/{base/math.css → math.css} +0 -0
package/README.md
CHANGED
|
@@ -119,7 +119,7 @@ TypeScript uses ESNext. The theme defaults `vite.build.target` to `"esnext"` to
|
|
|
119
119
|
|
|
120
120
|
### Initial CSS and search styles
|
|
121
121
|
|
|
122
|
-
The theme defaults to Astro's `build.inlineStylesheets: "
|
|
122
|
+
The theme defaults to Astro's `build.inlineStylesheets: "never"`: hashed shared CSS can be cached across routes, while component styles load on the pages that use them. Normal blocking stylesheets prevent an unstyled first paint. An explicit consumer setting of `build.inlineStylesheets: "always"` restores inline styles at the cost of larger HTML responses.
|
|
123
123
|
|
|
124
124
|
Pagefind dialog CSS is emitted as a separate hashed static file with a `prefetch` hint. Opening search activates the stylesheet and waits for it before displaying the dialog. It does not block the initial content or depend on JavaScript generating a CSS asset. A `<noscript>` stylesheet fallback is included.
|
|
125
125
|
|
|
@@ -281,3 +281,7 @@ In Astro 7.3, integration `logger.debug()` uses the official `DEBUG/--verbose` c
|
|
|
281
281
|
Timing is emitted only as logs, never included in generated pages or cache keys. Switching between normal and verbose builds may require one rebuild; repeated builds in the same mode remain deterministic. Consumers running `astro dev --background` can read terminal output with `astro dev logs`.
|
|
282
282
|
|
|
283
283
|
Keep the TypeScript 6 alias for `astro check`, upgrade Vitest and its coverage provider together, and run `bun run validate` before releasing.
|
|
284
|
+
|
|
285
|
+
## Style development and output
|
|
286
|
+
|
|
287
|
+
Stalux precompiles its UnoCSS styles; consuming projects need no UnoCSS dependency or configuration. Shared CSS is a cacheable external stylesheet by default. Article/math, archive, category, tag and quote styles load with their components. Explicit Astro `build.inlineStylesheets: "always"` restores inline output. New utilities in consumer override components require the consumer’s own compiler. See [STYLING.md](./docs/STYLING.md) for maintenance and watch mode.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xingwangzhe/stalux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.1",
|
|
4
4
|
"description": "A powerful, modern Astro blog theme — use as template or install as plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -67,14 +67,14 @@
|
|
|
67
67
|
"./package.json": "./package.json"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
|
-
"dev": "
|
|
71
|
-
"build": "astro build && node scripts/verify-build.ts",
|
|
70
|
+
"dev": "bun run styles:build && node scripts/dev.ts",
|
|
71
|
+
"build": "bun run styles:build && astro build && node scripts/verify-build.ts",
|
|
72
72
|
"preview": "astro preview",
|
|
73
73
|
"astro": "astro",
|
|
74
74
|
"init": "node scripts/cli.ts init",
|
|
75
75
|
"node:check": "tsc6 --project tsconfig.node.json",
|
|
76
76
|
"build:cli": "bun build scripts/cli.ts --target=node --outfile .release/cli.mjs",
|
|
77
|
-
"prepack": "bun run build:cli",
|
|
77
|
+
"prepack": "bun run styles:build && bun run build:cli",
|
|
78
78
|
"check": "biome check .",
|
|
79
79
|
"check:fix": "biome check --write .",
|
|
80
80
|
"format": "biome format --write .",
|
|
@@ -87,10 +87,12 @@
|
|
|
87
87
|
"test:coverage": "vitest run --coverage",
|
|
88
88
|
"knip": "knip",
|
|
89
89
|
"verify:build": "node scripts/verify-build.ts",
|
|
90
|
-
"validate": "bun run check && bun run node:check && bun run astro:check && bun run knip && bun run test:coverage && bun run build && bun run build:cli",
|
|
90
|
+
"validate": "bun run styles:build && bun run check && bun run node:check && bun run astro:check && bun run knip && bun run test:coverage && bun run build && bun run build:cli",
|
|
91
91
|
"prepare": "git config core.hooksPath scripts/git-hooks",
|
|
92
92
|
"dev:debug": "STALUX_DEBUG=1 astro dev --verbose",
|
|
93
|
-
"build:debug": "STALUX_DEBUG=1 astro build --verbose && node scripts/verify-build.ts"
|
|
93
|
+
"build:debug": "STALUX_DEBUG=1 astro build --verbose && node scripts/verify-build.ts",
|
|
94
|
+
"styles:build": "node scripts/build-styles.ts",
|
|
95
|
+
"styles:watch": "node scripts/build-styles.ts --watch"
|
|
94
96
|
},
|
|
95
97
|
"dependencies": {
|
|
96
98
|
"@astrojs/markdown-satteri": "0.4.2",
|
|
@@ -122,10 +124,12 @@
|
|
|
122
124
|
"@astrojs/check": "0.9.10",
|
|
123
125
|
"@biomejs/biome": "2.5.14",
|
|
124
126
|
"@types/node": "^26.6.2",
|
|
127
|
+
"@unocss/astro": "^66.10.5",
|
|
125
128
|
"@vitest/coverage-v8": "5.0.1",
|
|
126
129
|
"astro": "^7.3.5",
|
|
127
130
|
"knip": "^6.37.0",
|
|
128
131
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
132
|
+
"unocss": "^66.10.5",
|
|
129
133
|
"vite": "8.3.0",
|
|
130
134
|
"vitest": "5.0.1"
|
|
131
135
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
+
import "../../../styles/generated-archives.css";
|
|
2
3
|
import { type CollectionEntry, getCollection } from "astro:content";
|
|
3
|
-
|
|
4
|
+
|
|
4
5
|
import { getSiteData } from "@utils/config-utils";
|
|
5
6
|
import { format, parseDate, toTimestamp } from "@utils/dayjs";
|
|
6
7
|
import { createTranslator } from "@utils/i18n";
|
|
@@ -52,41 +53,44 @@ const archiveYears = [...archivesByYearMonth.entries()]
|
|
|
52
53
|
}));
|
|
53
54
|
---
|
|
54
55
|
|
|
55
|
-
<section class=
|
|
56
|
-
<div class=
|
|
57
|
-
<div class=
|
|
56
|
+
<section class="stalux-archive-container">
|
|
57
|
+
<div class="stalux-archive-page-header">
|
|
58
|
+
<div class="stalux-archive-timeline-container">
|
|
58
59
|
{archiveYears.length > 0 ? (
|
|
59
60
|
archiveYears.map((archiveYear) => (
|
|
60
|
-
<div class=
|
|
61
|
-
<div class=
|
|
62
|
-
<h2 class=
|
|
63
|
-
<div class=
|
|
61
|
+
<div class="stalux-archive-year-section" data-year={String(archiveYear.year)}>
|
|
62
|
+
<div class="stalux-archive-year-header">
|
|
63
|
+
<h2 class="stalux-archive-year-title">{archiveYear.year}</h2>
|
|
64
|
+
<div class="stalux-archive-year-count">
|
|
64
65
|
{t("archives.postCount", { n: archiveYear.count })}
|
|
65
66
|
</div>
|
|
66
67
|
</div>
|
|
67
68
|
{archiveYear.months.map(({ month, posts: monthPosts }) => (
|
|
68
69
|
<div
|
|
69
|
-
class=
|
|
70
|
+
class="stalux-archive-month-section"
|
|
70
71
|
style={{
|
|
71
72
|
"--archive-estimate": `${Math.ceil(monthPosts.length / 12) * 12 * 48 + 40}px`,
|
|
72
73
|
}}
|
|
73
74
|
>
|
|
74
|
-
<h3 class=
|
|
75
|
+
<h3 class="stalux-archive-month-title">{t("archives.month", { n: month })}</h3>
|
|
75
76
|
{Array.from({ length: Math.ceil(monthPosts.length / 12) }, (_, index) =>
|
|
76
77
|
monthPosts.slice(index * 12, (index + 1) * 12),
|
|
77
78
|
).map((group) => (
|
|
78
79
|
<ul
|
|
79
|
-
class=
|
|
80
|
+
class="stalux-archive-post-list"
|
|
80
81
|
style={{ "--archive-group-estimate": `${group.length * 48}px` }}
|
|
81
82
|
>
|
|
82
83
|
{group.map((post) => (
|
|
83
|
-
<li class=
|
|
84
|
-
<time
|
|
84
|
+
<li class="stalux-archive-post-item">
|
|
85
|
+
<time
|
|
86
|
+
class="stalux-archive-post-date"
|
|
87
|
+
datetime={post.data.date}
|
|
88
|
+
>
|
|
85
89
|
{format(parseDate(post.data.date), "yyyy-MM-dd")}
|
|
86
90
|
</time>
|
|
87
91
|
<a
|
|
88
92
|
href={`/posts/${post.data.abbrlink}/`}
|
|
89
|
-
class=
|
|
93
|
+
class="stalux-archive-post-link"
|
|
90
94
|
data-astro-prefetch="viewport"
|
|
91
95
|
>
|
|
92
96
|
{post.data.title}
|
|
@@ -100,7 +104,7 @@ const archiveYears = [...archivesByYearMonth.entries()]
|
|
|
100
104
|
</div>
|
|
101
105
|
))
|
|
102
106
|
) : (
|
|
103
|
-
<div class=
|
|
107
|
+
<div class="stalux-archive-no-posts">{t("archives.noPosts")}</div>
|
|
104
108
|
)}
|
|
105
109
|
</div>
|
|
106
110
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from "astro:content";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { getSiteData } from "@utils/config-utils";
|
|
5
5
|
import { createTranslator } from "@utils/i18n";
|
|
6
6
|
|
|
@@ -9,6 +9,6 @@ const siteConfig = getSiteData(configEntries);
|
|
|
9
9
|
const { t } = createTranslator(siteConfig.lang || "zh-CN");
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
<div id={
|
|
12
|
+
<div id={"stalux-to-archive-archs"}>
|
|
13
13
|
<a href="/archives" data-astro-prefetch>{t("archives.viewAll")}</a>
|
|
14
14
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
+
import "../../../styles/generated-categories.css";
|
|
2
3
|
import { getCollection } from "astro:content";
|
|
3
|
-
|
|
4
|
+
|
|
4
5
|
import { createTranslator } from "@utils/i18n";
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
@@ -19,13 +20,13 @@ const siteConfig = (configEntries.find((e) => e.id === "site")?.data ?? {}) as R
|
|
|
19
20
|
const { t } = createTranslator((siteConfig.lang as string) || "zh-CN");
|
|
20
21
|
---
|
|
21
22
|
|
|
22
|
-
<article class=
|
|
23
|
+
<article class="stalux-category-card">
|
|
23
24
|
<a
|
|
24
25
|
href={`/categories/${props.category.name}/`}
|
|
25
|
-
class=
|
|
26
|
+
class="stalux-categoryheader a-none"
|
|
26
27
|
data-astro-prefetch
|
|
27
28
|
>
|
|
28
|
-
<div class=
|
|
29
|
+
<div class="stalux-category-icon">
|
|
29
30
|
<svg
|
|
30
31
|
aria-hidden="true"
|
|
31
32
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -43,9 +44,9 @@ const { t } = createTranslator((siteConfig.lang as string) || "zh-CN");
|
|
|
43
44
|
></path>
|
|
44
45
|
</svg>
|
|
45
46
|
</div>
|
|
46
|
-
<div class=
|
|
47
|
-
<h2 class=
|
|
48
|
-
<div class=
|
|
47
|
+
<div class="stalux-category-content">
|
|
48
|
+
<h2 class="categoryName">{props.category.name}</h2>
|
|
49
|
+
<div class="categoryCount">
|
|
49
50
|
{t("categories.postCount", { n: props.category.count })}
|
|
50
51
|
</div>
|
|
51
52
|
</div>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
+
import "../../../styles/generated-categories.css";
|
|
2
3
|
import CategoriesCard from "@components/stalux/categories/categoriesCard.astro";
|
|
3
|
-
|
|
4
|
+
|
|
4
5
|
import { getCategoryCountList } from "@utils/collections-stats";
|
|
5
6
|
|
|
6
7
|
const categoryList = await getCategoryCountList(Astro.logger);
|
|
7
8
|
---
|
|
8
9
|
|
|
9
|
-
<ul class=
|
|
10
|
+
<ul class="stalux-categories">
|
|
10
11
|
{categoryList.map((category) => (
|
|
11
12
|
<li>
|
|
12
13
|
<CategoriesCard category={category} />
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Image } from "astro:assets";
|
|
3
3
|
import { getCollection } from "astro:content";
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { getAuthorData } from "@utils/config-utils";
|
|
6
6
|
|
|
7
7
|
const configEntries = await getCollection("config");
|
|
@@ -17,8 +17,13 @@ const isHomePage = Astro.url.pathname === "/";
|
|
|
17
17
|
const navigationHref = isHomePage ? "/about" : "/";
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
<article
|
|
21
|
-
|
|
20
|
+
<article
|
|
21
|
+
class="stalux-author stalux-u-flex stalux-u-justify-center stalux-u-flex-col"
|
|
22
|
+
transition:persist-props
|
|
23
|
+
>
|
|
24
|
+
<figure
|
|
25
|
+
class={`stalux-author-figure ${props.iscolum ? "stalux-author-figure-column stalux-u-flex-col" : ""}`}
|
|
26
|
+
>
|
|
22
27
|
<a href={navigationHref} class="a-none" data-astro-prefetch>
|
|
23
28
|
<Image src={authorConfig.avatar} alt={authorConfig.name} width={100} height={100} />
|
|
24
29
|
</a>
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
import styles from "@styles/components/common/date.module.css";
|
|
3
2
|
---
|
|
4
3
|
|
|
5
|
-
<div id={
|
|
6
|
-
<time id={
|
|
7
|
-
<time id={
|
|
4
|
+
<div id={"stalux-date-date-time"} class="date-time" transition:persist-props>
|
|
5
|
+
<time id={"stalux-date-date"} data-ref="date" datetime=""></time>
|
|
6
|
+
<time id={"stalux-date-time"} data-ref="time" datetime=""></time>
|
|
8
7
|
</div>
|
|
9
8
|
|
|
10
9
|
<script is:inline>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection } from "astro:content";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { getTypetextsData } from "@utils/config-utils";
|
|
5
5
|
import Typewriter from "astro-typewriter";
|
|
6
6
|
|
|
@@ -8,4 +8,9 @@ const configEntries = await getCollection("config");
|
|
|
8
8
|
const typetextsConfig = getTypetextsData(configEntries);
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
{typetextsConfig?.items &&
|
|
11
|
+
{typetextsConfig?.items && (
|
|
12
|
+
<Typewriter
|
|
13
|
+
class="stalux-typewriter stalux-u-flex stalux-u-justify-center stalux-u-w-full stalux-u-text-center"
|
|
14
|
+
messages={typetextsConfig?.items}
|
|
15
|
+
/>
|
|
16
|
+
)}
|
|
@@ -22,7 +22,7 @@ function badgeImg(opts: BadgeOptions) {
|
|
|
22
22
|
const height = svg.match(/<svg\b[^>]*\bheight="(\d+)"/)?.[1];
|
|
23
23
|
const dimensions = width && height ? ` width="${width}" height="${height}"` : "";
|
|
24
24
|
// Closed badge groups should not initialize every SVG document during first paint.
|
|
25
|
-
const img = `<img src="${src}" alt="${alt}" class="badge" loading="lazy" decoding="async"${dimensions} />`;
|
|
25
|
+
const img = `<img src="${src}" alt="${alt}" class="stalux-badge" loading="lazy" decoding="async"${dimensions} />`;
|
|
26
26
|
if (opts.href) {
|
|
27
27
|
return `<a href="${opts.href}" target="_blank" rel="${opts.rel ?? "noopener"}">${img}</a>`;
|
|
28
28
|
}
|
|
@@ -31,23 +31,23 @@ function badgeImg(opts: BadgeOptions) {
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
33
|
{badges && badges.length > 0 && (
|
|
34
|
-
<div class="badges-wrapper">
|
|
34
|
+
<div class="stalux-badges-wrapper stalux-u-flex stalux-u-items-center stalux-u-justify-center stalux-u-flex-wrap">
|
|
35
35
|
{badges.map((item: BadgeItem, idx: number) => {
|
|
36
36
|
if (isBadgeGroup(item)) {
|
|
37
37
|
const groupId = `badge-group-${idx}`;
|
|
38
38
|
return (
|
|
39
|
-
<details class="badge-group" id={groupId}>
|
|
40
|
-
<summary class="badge-group-summary">
|
|
41
|
-
<span class="badge-group-arrow">▶</span>
|
|
42
|
-
<span class="badge-group-title">{item.title}</span>
|
|
43
|
-
<span class="badge-group-hint" data-hint="expanded">
|
|
39
|
+
<details class="stalux-badge-group stalux-u-w-full badge-group" id={groupId}>
|
|
40
|
+
<summary class="stalux-badge-group-summary stalux-u-flex stalux-u-items-center stalux-u-justify-center">
|
|
41
|
+
<span class="stalux-badge-group-arrow">▶</span>
|
|
42
|
+
<span class="stalux-badge-group-title">{item.title}</span>
|
|
43
|
+
<span class="stalux-badge-group-hint" data-hint="expanded">
|
|
44
44
|
{t("footer.collapse")}
|
|
45
45
|
</span>
|
|
46
|
-
<span class="badge-group-hint" data-hint="collapsed">
|
|
46
|
+
<span class="stalux-badge-group-hint" data-hint="collapsed">
|
|
47
47
|
{t("footer.expand")}
|
|
48
48
|
</span>
|
|
49
49
|
</summary>
|
|
50
|
-
<div class="badge-group-items badges">
|
|
50
|
+
<div class="stalux-badge-group-items stalux-badges stalux-u-flex stalux-u-items-center stalux-u-justify-center stalux-u-flex-wrap">
|
|
51
51
|
{item.items.map((b) => (
|
|
52
52
|
<Fragment set:html={badgeImg(b)} />
|
|
53
53
|
))}
|
|
@@ -59,91 +59,3 @@ function badgeImg(opts: BadgeOptions) {
|
|
|
59
59
|
})}
|
|
60
60
|
</div>
|
|
61
61
|
)}
|
|
62
|
-
|
|
63
|
-
<style>
|
|
64
|
-
.badges-wrapper {
|
|
65
|
-
display: flex;
|
|
66
|
-
justify-content: center;
|
|
67
|
-
align-items: center;
|
|
68
|
-
flex-wrap: wrap;
|
|
69
|
-
gap: 0.5rem;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* Badge HTML is emitted by set:html, so target it through the scoped wrapper. */
|
|
73
|
-
.badges-wrapper :global(.badge) {
|
|
74
|
-
width: auto;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.badge-group {
|
|
78
|
-
width: 100%;
|
|
79
|
-
border: none;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.badge-group-summary {
|
|
83
|
-
cursor: pointer;
|
|
84
|
-
display: flex;
|
|
85
|
-
justify-content: center;
|
|
86
|
-
align-items: center;
|
|
87
|
-
gap: 0.4rem;
|
|
88
|
-
padding: 0.2rem 0;
|
|
89
|
-
color: var(--white-70p);
|
|
90
|
-
font-size: 0.85rem;
|
|
91
|
-
user-select: none;
|
|
92
|
-
list-style: none;
|
|
93
|
-
transition: color 0.2s;
|
|
94
|
-
}
|
|
95
|
-
.badge-group-summary:hover {
|
|
96
|
-
color: var(--white-70p);
|
|
97
|
-
}
|
|
98
|
-
.badge-group-summary::-webkit-details-marker {
|
|
99
|
-
display: none;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.badge-group-arrow {
|
|
103
|
-
font-size: 0.65rem;
|
|
104
|
-
transition: transform 0.2s;
|
|
105
|
-
display: inline-block;
|
|
106
|
-
}
|
|
107
|
-
.badge-group[open] .badge-group-arrow {
|
|
108
|
-
transform: rotate(90deg);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.badge-group-title {
|
|
112
|
-
color: var(--white-80p);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.badge-group-hint {
|
|
116
|
-
font-size: 0.7rem;
|
|
117
|
-
color: var(--white-70p);
|
|
118
|
-
}
|
|
119
|
-
.badge-group[open] .badge-group-hint[data-hint="collapsed"],
|
|
120
|
-
.badge-group:not([open]) .badge-group-hint[data-hint="expanded"] {
|
|
121
|
-
display: none;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.badge-group-items {
|
|
125
|
-
padding-top: 0.35rem;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.badges {
|
|
129
|
-
display: flex;
|
|
130
|
-
justify-content: center;
|
|
131
|
-
align-items: center;
|
|
132
|
-
flex-wrap: wrap;
|
|
133
|
-
gap: 0.5rem;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.badge {
|
|
137
|
-
height: 20px;
|
|
138
|
-
vertical-align: middle;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
@media (max-width: 768px) {
|
|
142
|
-
.badges {
|
|
143
|
-
gap: 0.3rem;
|
|
144
|
-
}
|
|
145
|
-
.badge {
|
|
146
|
-
height: 18px;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
</style>
|
|
@@ -19,7 +19,7 @@ const showBeian = !!(icp || pubsec);
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
{showBeian && (
|
|
22
|
-
<div class="beian-info">
|
|
22
|
+
<div class="stalux-beian-beian-info stalux-u-flex stalux-u-justify-center stalux-u-flex-wrap">
|
|
23
23
|
{icp && (
|
|
24
24
|
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener noreferrer">
|
|
25
25
|
{icp}
|
|
@@ -30,7 +30,7 @@ const showBeian = !!(icp || pubsec);
|
|
|
30
30
|
href={`http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=${pubsecNumber}`}
|
|
31
31
|
target="_blank"
|
|
32
32
|
rel="noopener noreferrer"
|
|
33
|
-
class="public-security-beian"
|
|
33
|
+
class="stalux-beian-public-security-beian stalux-u-items-center"
|
|
34
34
|
>
|
|
35
35
|
<img
|
|
36
36
|
src="https://beian.mps.gov.cn/img/logo01.dd7ff50e.png"
|
|
@@ -41,45 +41,3 @@ const showBeian = !!(icp || pubsec);
|
|
|
41
41
|
)}
|
|
42
42
|
</div>
|
|
43
43
|
)}
|
|
44
|
-
|
|
45
|
-
<style>
|
|
46
|
-
.beian-info {
|
|
47
|
-
display: flex;
|
|
48
|
-
justify-content: center;
|
|
49
|
-
flex-wrap: wrap;
|
|
50
|
-
gap: 1rem;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.beian-info a {
|
|
54
|
-
color: rgba(255, 255, 255, 0.7);
|
|
55
|
-
text-decoration: none;
|
|
56
|
-
transition: color 0.3s ease;
|
|
57
|
-
font-size: 0.9rem;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.beian-info a:hover {
|
|
61
|
-
color: rgba(255, 255, 255, 0.9);
|
|
62
|
-
text-decoration: none;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.public-security-beian {
|
|
66
|
-
display: inline-flex;
|
|
67
|
-
align-items: center;
|
|
68
|
-
gap: 5px;
|
|
69
|
-
color: rgba(255, 255, 255, 0.7);
|
|
70
|
-
text-decoration: none;
|
|
71
|
-
transition: color 0.3s ease;
|
|
72
|
-
font-size: 0.9rem;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.public-security-beian:hover {
|
|
76
|
-
color: rgba(255, 255, 255, 0.9);
|
|
77
|
-
text-decoration: none;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.public-security-beian img {
|
|
81
|
-
width: 15px;
|
|
82
|
-
height: 15px;
|
|
83
|
-
display: inline-block;
|
|
84
|
-
}
|
|
85
|
-
</style>
|
|
@@ -21,21 +21,6 @@ const copyrightYear =
|
|
|
21
21
|
: currentYear;
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
<small class="copyright">
|
|
24
|
+
<small class="stalux-copyright stalux-u-flex stalux-u-justify-center stalux-u-flex-wrap">
|
|
25
25
|
<span>© {copyrightYear} {props.author || ""}. {t("footer.rightsReserved")}</span>
|
|
26
26
|
</small>
|
|
27
|
-
|
|
28
|
-
<style>
|
|
29
|
-
.copyright {
|
|
30
|
-
color: var(--white-70p);
|
|
31
|
-
font-weight: 500;
|
|
32
|
-
display: flex;
|
|
33
|
-
gap: 0.3em;
|
|
34
|
-
justify-content: center;
|
|
35
|
-
flex-wrap: wrap;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.copyright span {
|
|
39
|
-
margin: 0;
|
|
40
|
-
}
|
|
41
|
-
</style>
|
|
@@ -16,17 +16,17 @@ const { showStats = true, wordCount, buildtime } = Astro.props;
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
{showStats && (
|
|
19
|
-
<p class="site-stats">
|
|
19
|
+
<p class="stalux-stats-site-stats stalux-u-flex stalux-u-justify-center stalux-u-flex-wrap">
|
|
20
20
|
<span id="vercount_container_site_uv">
|
|
21
21
|
{t("footer.visitors")}
|
|
22
22
|
<span id="vercount_value_site_uv">Loading...</span> {t("footer.visits")}
|
|
23
23
|
</span>
|
|
24
|
-
<span class="stats-separator">|</span>
|
|
24
|
+
<span class="stalux-stats-stats-separator">|</span>
|
|
25
25
|
<span id="vercount_container_site_pv">
|
|
26
26
|
{t("footer.totalVisits")}
|
|
27
27
|
<span id="vercount_value_site_pv">Loading...</span> {t("footer.times")}
|
|
28
28
|
</span>
|
|
29
|
-
<span class="stats-separator">|</span>
|
|
29
|
+
<span class="stalux-stats-stats-separator">|</span>
|
|
30
30
|
<span id="word-count-container">
|
|
31
31
|
{t("footer.totalWords")}
|
|
32
32
|
<span id="word-count-value">{wordCount ?? "Loading..."}</span> {t("footer.chars")}
|
|
@@ -36,7 +36,7 @@ const { showStats = true, wordCount, buildtime } = Astro.props;
|
|
|
36
36
|
|
|
37
37
|
{buildtime && (
|
|
38
38
|
<div
|
|
39
|
-
class="site-build-time"
|
|
39
|
+
class="stalux-stats-site-build-time stalux-u-text-center"
|
|
40
40
|
data-stalux-buildtime={buildtime}
|
|
41
41
|
data-stalux-runtime-format={t("footer.runtimeFormat")}
|
|
42
42
|
>
|
|
@@ -46,24 +46,3 @@ const { showStats = true, wordCount, buildtime } = Astro.props;
|
|
|
46
46
|
</span>
|
|
47
47
|
</div>
|
|
48
48
|
)}
|
|
49
|
-
|
|
50
|
-
<style>
|
|
51
|
-
.site-stats {
|
|
52
|
-
display: flex;
|
|
53
|
-
justify-content: center;
|
|
54
|
-
flex-wrap: wrap;
|
|
55
|
-
gap: 0.5rem;
|
|
56
|
-
font-size: 0.9rem;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.stats-separator {
|
|
60
|
-
color: rgba(255, 255, 255, 0.5);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.site-build-time {
|
|
64
|
-
margin-top: 0.5rem;
|
|
65
|
-
font-size: 0.9rem;
|
|
66
|
-
color: rgba(255, 255, 255, 0.8);
|
|
67
|
-
text-align: center;
|
|
68
|
-
}
|
|
69
|
-
</style>
|
|
@@ -9,7 +9,7 @@ const showThemeInfoSection = !!(showPoweredBy || showThemeInfo);
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
{showThemeInfoSection && (
|
|
12
|
-
<div class="theme-info">
|
|
12
|
+
<div class="stalux-theme-info stalux-u-flex stalux-u-justify-center stalux-u-flex-wrap">
|
|
13
13
|
{showPoweredBy && (
|
|
14
14
|
<span>
|
|
15
15
|
Powered by
|
|
@@ -33,30 +33,3 @@ const showThemeInfoSection = !!(showPoweredBy || showThemeInfo);
|
|
|
33
33
|
)}
|
|
34
34
|
</div>
|
|
35
35
|
)}
|
|
36
|
-
|
|
37
|
-
<style>
|
|
38
|
-
.theme-info {
|
|
39
|
-
color: var(--white-70p);
|
|
40
|
-
font-size: 0.85rem;
|
|
41
|
-
display: flex;
|
|
42
|
-
justify-content: center;
|
|
43
|
-
gap: 0.3em;
|
|
44
|
-
flex-wrap: wrap;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.theme-info span {
|
|
48
|
-
margin: 0;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.theme-info a {
|
|
52
|
-
color: rgba(255, 255, 255, 0.8);
|
|
53
|
-
text-decoration: none;
|
|
54
|
-
transition: color 0.3s ease;
|
|
55
|
-
margin: 0 0.2em;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.theme-info a:hover {
|
|
59
|
-
color: rgba(255, 255, 255, 1);
|
|
60
|
-
text-decoration: none;
|
|
61
|
-
}
|
|
62
|
-
</style>
|
|
@@ -5,7 +5,7 @@ import FooterBeian from "@components/stalux/footer/FooterBeian.astro";
|
|
|
5
5
|
import FooterCopyright from "@components/stalux/footer/FooterCopyright.astro";
|
|
6
6
|
import FooterStats from "@components/stalux/footer/FooterStats.astro";
|
|
7
7
|
import FooterThemeInfo from "@components/stalux/footer/FooterThemeInfo.astro";
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
import type { BadgeItem, BadgeOptions } from "@utils/badge-generator";
|
|
10
10
|
import { getAuthorData, getFooterData, getSiteData } from "@utils/config-utils";
|
|
11
11
|
import { formatWordCount, getTotalWordCount } from "@utils/word-count-utils";
|
|
@@ -50,8 +50,8 @@ const totalWordCount = await getTotalWordCount(Astro.logger);
|
|
|
50
50
|
const formattedWordCount = formatWordCount(totalWordCount, siteConfig.lang || "zh-CN");
|
|
51
51
|
---
|
|
52
52
|
|
|
53
|
-
<footer class=
|
|
54
|
-
<div class=
|
|
53
|
+
<footer class="stalux-footer stalux-u-w-full stalux-u-text-center" transition:persist-props>
|
|
54
|
+
<div class="stalux-footer-content stalux-u-flex stalux-u-flex-col">
|
|
55
55
|
<!-- 版权信息 -->
|
|
56
56
|
{footerConfig?.copyright?.enabled && (
|
|
57
57
|
<FooterCopyright author={author} startYear={footerConfig?.copyright?.startYear} />
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { getCollection } from "astro:content";
|
|
3
3
|
import Navs from "@components/stalux/layout/navs.astro";
|
|
4
4
|
import Stalux from "@layouts/Stalux.astro";
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
import { getSiteData } from "@utils/config-utils";
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
@@ -20,7 +20,7 @@ const siteConfig = getSiteData(configEntries);
|
|
|
20
20
|
<Stalux title={`${title} | ${siteConfig.title}`} description={description}>
|
|
21
21
|
<div style="height: 3em;"></div>
|
|
22
22
|
<Navs />
|
|
23
|
-
<h1 class=
|
|
24
|
-
{subheading && <div class=
|
|
23
|
+
<h1 class="stalux-page-title stalux-u-text-center">{heading}</h1>
|
|
24
|
+
{subheading && <div class="stalux-page-description stalux-u-text-center">{subheading}</div>}
|
|
25
25
|
<slot />
|
|
26
26
|
</Stalux>
|