@xingwangzhe/stalux 1.42.0 → 1.43.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 +7 -5
- package/package.json +7 -1
- package/src/components/stalux/archives/archivesList.astro +0 -2
- package/src/components/stalux/archives/toArchive.astro +1 -5
- package/src/components/stalux/common/Typewriter.astro +1 -7
- package/src/components/stalux/common/author.astro +1 -6
- package/src/components/stalux/common/date.astro +1 -11
- package/src/components/stalux/layout/PageHeading.astro +2 -11
- package/src/components/stalux/layout/footer.astro +1 -6
- package/src/components/stalux/layout/head.astro +0 -2
- package/src/components/stalux/links/socialMedia.astro +1 -10
- package/src/components/stalux/posts/ArticleSummary.astro +2 -8
- package/src/components/stalux/posts/PostTaxonomy.astro +3 -14
- package/src/components/stalux/posts/postCC.astro +2 -2
- package/src/components/stalux/posts/postCard.astro +1 -5
- package/src/components/stalux/posts/postContent.astro +4 -23
- package/src/components/stalux/posts/postLeft.astro +4 -22
- package/src/components/stalux/posts/postRight.astro +5 -27
- package/src/components/stalux/posts/postToc.astro +3 -10
- package/src/components/stalux/posts/randomPost.astro +0 -1
- package/src/components/stalux/tags/tagHeader.astro +1 -5
- package/src/index.ts +20 -1
- package/src/internal/style-names.generated.ts +59 -69
- package/src/layouts/PostLayout.astro +1 -5
- package/src/layouts/Stalux.astro +3 -19
- package/src/pages/index.astro +1 -5
- package/src/scripts/navigation-client.ts +13 -0
- package/src/scripts/navigation-scripts.ts +191 -0
- package/src/scripts/route-motion.ts +82 -11
- package/src/scripts/route-out.ts +33 -0
- package/src/scripts/smooth-scroll.ts +52 -0
- package/src/scripts/swup-router.ts +381 -0
- package/src/scripts/tags-cloud.ts +1 -1
- package/src/scripts/view-transitions.ts +3 -233
- package/src/scripts/word-list.ts +9 -3
- package/src/styles/generated-words.css +1 -1
- package/src/styles/generated.css +1 -1
- package/src/styles/motion.css +7 -211
- package/src/utils/toc-scrollspy.ts +21 -14
- package/src/scripts/archive-reveal.ts +0 -76
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@ Standalone images written as `` receive a `figure` and
|
|
|
18
18
|
|
|
19
19
|
Code blocks default to the single `dark-plus` theme, with system color-scheme switching and theme selectors disabled. To opt into another theme or switching behavior, explicitly override `themes`, `useDarkModeMediaQuery`, and `themeCssSelector` through `expressiveCode`. This only changes generated code styles and adds no telemetry.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Swup owns soft navigation and transition timing. Astro renders the static documents; the browser runtime replaces only `main[data-stalux-route]`, keeping the header, footer, scroll sentinel and two background layers alive. The incoming visible heading receives a brief opacity or directional hint selected by the route policy: entering an article can move 6px vertically, explicit previous/next article links use opposite 8px horizontal hints, and returning to a list uses a 4px upward hint. Other article links and taxonomy changes fade without inventing a reading direction. Desktop effects last 80–140ms; phones use an 80ms fade without translation. The article body and long lists stay immediately readable. Reduced motion and browser-provided history gestures skip content motion; same-page anchors use their scrolling behavior and same-URL clicks preserve the reading position. Standalone HTML and exported data use document navigation. See the [Swup transition architecture and route policy](docs/view-transitions-swup.md).
|
|
22
22
|
|
|
23
|
-
The
|
|
23
|
+
The runtime uses Swup's Head, Accessibility, Preload, Scroll and JS plugins with Stalux lifecycle handlers. It waits for incoming stylesheets and gives the destination font a bounded 150ms head start, disposes old interactions before replacement, loads first-seen page scripts, then dispatches the Astro-compatible page lifecycle events used by comments, counters, tag clouds and WebMCP. Backgrounds decode independently and crossfade after the content animation finishes; stale navigation work cannot replace the current background. History positions are restored by the Swup runtime, including reduced-motion visits. This requires no new configuration or telemetry. Animation duration describes the effect itself, not total navigation time or a measured performance improvement.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -136,7 +136,7 @@ Processed pages are cached under `node_modules/.astro/stalux-page-output/`. The
|
|
|
136
136
|
|
|
137
137
|
### Visibility-aware loading and updates
|
|
138
138
|
|
|
139
|
-
The desktop tag cloud loads dynamically near the viewport. Switching to mobile, leaving the viewport or hiding the document destroys it and stops animation scheduling; becoming visible recreates it. Tag clicks use
|
|
139
|
+
The desktop tag cloud loads dynamically near the viewport. Switching to mobile, leaving the viewport or hiding the document destroys it and stops animation scheduling; becoming visible recreates it. Tag clicks use the same Swup navigation as ordinary internal links. Clocks and the footer runtime update only while visible, and the date changes only on a new day. Comments load within half a viewport (capped at 400px). Tag groups, archive months and category cards retain static HTML while deferring offscreen rendering.
|
|
140
140
|
|
|
141
141
|
### Modern JavaScript
|
|
142
142
|
|
|
@@ -195,7 +195,7 @@ id: head
|
|
|
195
195
|
bingClarityId: "YOUR_CLARITY_PROJECT_ID"
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
-
Google Analytics, Clarity, and Umami use low-priority native asynchronous scripts. Each SDK loads once per session, and failures do not block reading or navigation. Vercount rebinds visible counters after each `astro:page-load`. GA captures each URL, title, and referrer, then sends pageviews in visit order through separate background tasks after the
|
|
198
|
+
Google Analytics, Clarity, and Umami use low-priority native asynchronous scripts. Each SDK loads once per session, and failures do not block reading or navigation. Vercount rebinds visible counters after each `astro:page-load`. GA captures each URL, title, and referrer, then sends pageviews in visit order through separate background tasks after the shared Swup content-motion gate settles and a paint has been yielded. A bounded timer handles task starvation; hiding or leaving the document flushes pending views immediately. The SDK still runs on the main thread; this scheduling reduces synchronous work on the route's first frame. Umami disables automatic pageviews while retaining click tracking and captures page information before the SDK resolves so rapid navigation cannot mix visits. An existing older runtime or legacy Partytown session performs one full reload when it encounters the new runtime to prevent duplicate listeners and tracking.
|
|
199
199
|
|
|
200
200
|
For Google Analytics, turn off **Page changes based on browser history events** under **Admin → Data streams → Enhanced measurement → Page views → Advanced settings**. Stalux sets `send_page_view: false` and sends the URL and title for each navigation explicitly. GA's history tracking must also be disabled in the property to prevent duplicate soft-navigation pageviews. Other enhanced measurement options can remain enabled. See [Google's pageview documentation](https://developers.google.com/analytics/devguides/collection/ga4/views).
|
|
201
201
|
|
|
@@ -284,7 +284,7 @@ This is a build-time metadata field. It does not create a contact endpoint or ex
|
|
|
284
284
|
|
|
285
285
|
The root reserves scrollbar space and uses explicit line height. The homepage typewriter reserves the maximum wrapped height of its complete messages and keeps the text origin fixed; clocks reserve line boxes and use tabular digits. Existing typing, cursor and route animations remain enabled. No additional configuration is required.
|
|
286
286
|
|
|
287
|
-
|
|
287
|
+
Swup's pre-replacement preparation warms the destination body font without installing it on the old page. The font receives at most 150ms of preparation time; failure, timeout and superseding navigation release that font wait. Incoming stylesheets and first-seen page modules have separate bounded loading waits so the next page can initialize its interactions. Initial loads on slow networks may still show the system fallback. Content authors must reserve dimensions for remote images and third-party embeds. Reduced-motion and print behavior remain supported.
|
|
288
288
|
|
|
289
289
|
See [style maintenance](docs/STYLING.md) and [lifecycle and static interfaces](docs/RUNTIME.md). Astro development documentation is available through the [official MCP endpoint](https://mcp.docs.astro.build/mcp); `.codex/config.toml`, `.mcp.json` and `AGENTS.md` record the project setup. This development MCP is separate from the blog's browser WebMCP tools.
|
|
290
290
|
|
|
@@ -370,3 +370,5 @@ og:image: /images/custom-social-card.png
|
|
|
370
370
|
`@takumi-rs/core` renders a static 1200×630 WebP at `/og/<metadata-hash>.webp` using the bundled LXGW WenKai font. Cards include the title, summary, site identity, author, category, accent color and date in the site timezone. No renderer JavaScript is sent to the browser. Static `og:image`, `twitter:image` and BlogPosting `image` use the same absolute URL; generated images also declare dimensions and MIME type. Articles use `summary_large_image`. A second `og:image` points to a PNG fallback; platforms choose which format they can read. WebP quality is 86; AVIF is not the default.
|
|
371
371
|
|
|
372
372
|
Local covers are read from the final `publicDir`. Remote covers are requested by the build machine, with an 8-second timeout and an 8 MiB limit (remote bytes are cached for 24 hours); unreadable or undecodable artwork emits a warning and falls back to a title card. No remote image-generation service is used. WebP and PNG outputs are cached in `stalux-social-cards/` under Astro's cache directory and copied into each build output. Explicit sharing images are fetched by social platforms, so they must be publicly accessible images. Platforms maintain their own preview caches and may not refresh an existing share immediately after deployment.
|
|
373
|
+
|
|
374
|
+
Content transitions follow Fuwari’s fade and vertical movement: keep the old content readable until destination assets are ready, fade it out over 140ms, then reveal the new content over 220ms (180ms on phones). The header and background persist. History restores the reading position without an outgoing animation. Same-page anchors use interruptible native smooth scrolling; reduced motion uses instant positioning. Cross-page scroll resets happen while content is hidden. No configuration is required.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xingwangzhe/stalux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.43.1",
|
|
4
4
|
"description": "A powerful, modern Astro blog theme — use as template or install as plugin",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astro",
|
|
@@ -110,6 +110,11 @@
|
|
|
110
110
|
"@mcp-b/webmcp-polyfill": "^5.1.0",
|
|
111
111
|
"@microsoft/clarity": "1.0.2",
|
|
112
112
|
"@pagefind/component-ui": "^1.5.2",
|
|
113
|
+
"@swup/a11y-plugin": "^5.2.1",
|
|
114
|
+
"@swup/head-plugin": "^2.3.1",
|
|
115
|
+
"@swup/js-plugin": "^3.2.0",
|
|
116
|
+
"@swup/preload-plugin": "^3.2.12",
|
|
117
|
+
"@swup/scroll-plugin": "^4.0.0",
|
|
113
118
|
"@takumi-rs/core": "2.17.1",
|
|
114
119
|
"@waline/client": "^3.16.1",
|
|
115
120
|
"@xingwangzhe/cjk-font-split-native": "^0.4.10",
|
|
@@ -127,6 +132,7 @@
|
|
|
127
132
|
"photoswipe": "^5.4.4",
|
|
128
133
|
"satteri": "^0.10.5",
|
|
129
134
|
"simple-icons": "^16.35.0",
|
|
135
|
+
"swup": "4.10.0",
|
|
130
136
|
"temml": "^0.14.0",
|
|
131
137
|
"yaml": "^2.9.1"
|
|
132
138
|
},
|
|
@@ -127,9 +127,7 @@ const archiveYears = [...archivesByYearMonth.entries()]
|
|
|
127
127
|
|
|
128
128
|
<script>
|
|
129
129
|
import { mountArchiveDescriptions } from "../../../scripts/archive-descriptions";
|
|
130
|
-
import { mountArchiveReveal } from "../../../scripts/archive-reveal";
|
|
131
130
|
import { registerPageLifecycle } from "../../../scripts/page-runtime";
|
|
132
131
|
|
|
133
|
-
registerPageLifecycle("archive-reveal", mountArchiveReveal);
|
|
134
132
|
registerPageLifecycle("archive-descriptions", mountArchiveDescriptions);
|
|
135
133
|
</script>
|
|
@@ -9,10 +9,6 @@ const siteConfig = getSiteData(configEntries);
|
|
|
9
9
|
const { t } = createTranslator(siteConfig.lang || "zh-CN");
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
<div
|
|
13
|
-
id={"stalux-to-archive-archs"}
|
|
14
|
-
transition:name="stalux-home-archive-link"
|
|
15
|
-
transition:animate="slide"
|
|
16
|
-
>
|
|
12
|
+
<div id={"stalux-to-archive-archs"}>
|
|
17
13
|
<a href="/archives" data-astro-prefetch>{t("archives.viewAll")}</a>
|
|
18
14
|
</div>
|
|
@@ -10,13 +10,7 @@ const texts = normalizeMessages(messages);
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
{texts.length > 0 && (
|
|
13
|
-
<div
|
|
14
|
-
class={className}
|
|
15
|
-
data-stalux-typewriter
|
|
16
|
-
data-messages={JSON.stringify(texts)}
|
|
17
|
-
transition:name="stalux-home-typewriter"
|
|
18
|
-
transition:animate="fade"
|
|
19
|
-
>
|
|
13
|
+
<div class={className} data-stalux-typewriter data-messages={JSON.stringify(texts)}>
|
|
20
14
|
<span class="stalux-typewriter-accessible">{texts.join(", ")}</span>
|
|
21
15
|
<span class="stalux-typewriter-reserve" aria-hidden="true">
|
|
22
16
|
{texts.map((text) => (
|
|
@@ -17,12 +17,7 @@ const isHomePage = Astro.url.pathname === "/";
|
|
|
17
17
|
const navigationHref = isHomePage ? "/about" : "/";
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
<article
|
|
21
|
-
class="stalux-author stalux-u-flex stalux-u-justify-center stalux-u-flex-col"
|
|
22
|
-
transition:persist-props
|
|
23
|
-
transition:name={isHomePage ? "stalux-home-author" : undefined}
|
|
24
|
-
transition:animate={isHomePage ? "fade" : undefined}
|
|
25
|
-
>
|
|
20
|
+
<article class="stalux-author stalux-u-flex stalux-u-justify-center stalux-u-flex-col">
|
|
26
21
|
<figure
|
|
27
22
|
class={`stalux-author-figure ${props.iscolum ? "stalux-author-figure-column stalux-u-flex-col" : ""}`}
|
|
28
23
|
>
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
const isHomePage = Astro.url.pathname === "/";
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<div
|
|
6
|
-
id={"stalux-date-date-time"}
|
|
7
|
-
class="date-time"
|
|
8
|
-
transition:persist-props
|
|
9
|
-
transition:name={isHomePage ? "stalux-home-date-time" : undefined}
|
|
10
|
-
transition:animate={isHomePage ? "fade" : undefined}
|
|
11
|
-
>
|
|
1
|
+
<div id={"stalux-date-date-time"} class="date-time">
|
|
12
2
|
<time id={"stalux-date-date"} data-ref="date" datetime=""></time>
|
|
13
3
|
<time id={"stalux-date-time"} data-ref="time" datetime=""></time>
|
|
14
4
|
</div>
|
|
@@ -8,20 +8,11 @@ const { heading, description } = Astro.props;
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
<>
|
|
11
|
-
<h1
|
|
12
|
-
class="stalux-page-title stalux-u-text-center"
|
|
13
|
-
data-stalux-motion-focus
|
|
14
|
-
transition:animate="none"
|
|
15
|
-
>
|
|
11
|
+
<h1 class="stalux-page-title stalux-u-text-center" data-stalux-motion-focus>
|
|
16
12
|
{heading}
|
|
17
13
|
</h1>
|
|
18
14
|
{description && (
|
|
19
|
-
<div
|
|
20
|
-
class="stalux-page-description stalux-u-text-center"
|
|
21
|
-
data-stalux-motion-content
|
|
22
|
-
transition:name="stalux-page-description"
|
|
23
|
-
transition:animate="none"
|
|
24
|
-
>
|
|
15
|
+
<div class="stalux-page-description stalux-u-text-center" data-stalux-motion-content>
|
|
25
16
|
{description}
|
|
26
17
|
</div>
|
|
27
18
|
)}
|
|
@@ -51,12 +51,7 @@ const totalWordCount = await getTotalWordCount(Astro.logger);
|
|
|
51
51
|
const formattedWordCount = formatWordCount(totalWordCount, siteConfig.lang || "zh-CN");
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
-
<footer
|
|
55
|
-
class="stalux-footer stalux-u-w-full stalux-u-text-center"
|
|
56
|
-
data-stalux-font-group="footer"
|
|
57
|
-
transition:persist="stalux-site-footer"
|
|
58
|
-
transition:persist-props
|
|
59
|
-
>
|
|
54
|
+
<footer class="stalux-footer stalux-u-w-full stalux-u-text-center" data-stalux-font-group="footer">
|
|
60
55
|
<div class="stalux-footer-content stalux-u-flex stalux-u-flex-col">
|
|
61
56
|
<!-- 版权信息 -->
|
|
62
57
|
{footerConfig?.copyright?.enabled && (
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Font } from "astro:assets";
|
|
3
3
|
import { getCollection } from "astro:content";
|
|
4
|
-
import { ClientRouter } from "astro:transitions";
|
|
5
4
|
// Emit a stable asset even while the search component JavaScript stays lazy.
|
|
6
5
|
// The closed search dialog does not need to block the page's first paint.
|
|
7
6
|
import pagefindStyles from "virtual:stalux-search-style";
|
|
@@ -54,7 +53,6 @@ const ldJson = JSON.stringify(seo.schema).replace(/<\//g, "<\\/");
|
|
|
54
53
|
|
|
55
54
|
<head>
|
|
56
55
|
<meta charset="utf-8">
|
|
57
|
-
<ClientRouter fallback="swap" />
|
|
58
56
|
<SEO
|
|
59
57
|
title={seo.title}
|
|
60
58
|
description={seo.description}
|
|
@@ -17,8 +17,6 @@ import {
|
|
|
17
17
|
const configEntries = await getCollection("config");
|
|
18
18
|
const mediaLinksSection = getMediaLinksData(configEntries);
|
|
19
19
|
const mediaLinks = mediaLinksSection?.items ?? [];
|
|
20
|
-
const isPostPage = Astro.url.pathname.startsWith("/posts/");
|
|
21
|
-
const isHomePage = Astro.url.pathname === "/";
|
|
22
20
|
|
|
23
21
|
// 静态图标映射表:新增图标时只需添加对应的 simple-icons 导入和映射
|
|
24
22
|
const iconMap: Record<string, SimpleIcon> = {
|
|
@@ -35,14 +33,7 @@ function getIconByTitle(iconName: string): SimpleIcon | undefined {
|
|
|
35
33
|
}
|
|
36
34
|
---
|
|
37
35
|
|
|
38
|
-
<nav
|
|
39
|
-
class="stalux-social"
|
|
40
|
-
transition:persist-props
|
|
41
|
-
transition:name={isHomePage ? "stalux-home-social" : undefined}
|
|
42
|
-
transition:animate={isHomePage ? "fade" : undefined}
|
|
43
|
-
aria-label="Social media"
|
|
44
|
-
data-stalux-social-animate={String(!isPostPage)}
|
|
45
|
-
>
|
|
36
|
+
<nav class="stalux-social" aria-label="Social media">
|
|
46
37
|
<ul>
|
|
47
38
|
{mediaLinks.map((item) => {
|
|
48
39
|
const icon = item.icon ? getIconByTitle(item.icon) : undefined;
|
|
@@ -4,18 +4,12 @@ interface Props {
|
|
|
4
4
|
label: string;
|
|
5
5
|
transitionName: string;
|
|
6
6
|
}
|
|
7
|
-
const { description, label
|
|
7
|
+
const { description, label } = Astro.props;
|
|
8
8
|
const summary = description?.trim();
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
{summary && (
|
|
12
|
-
<aside
|
|
13
|
-
class="stalux-article-summary"
|
|
14
|
-
data-stalux-motion-content
|
|
15
|
-
aria-label={label}
|
|
16
|
-
transition:name={transitionName}
|
|
17
|
-
transition:animate="none"
|
|
18
|
-
>
|
|
12
|
+
<aside class="stalux-article-summary" data-stalux-motion-content aria-label={label}>
|
|
19
13
|
<p class="stalux-article-summary-label">{label}</p>
|
|
20
14
|
<p class="stalux-article-summary-text">{summary}</p>
|
|
21
15
|
</aside>
|
|
@@ -43,15 +43,10 @@ const cfg = {
|
|
|
43
43
|
}[kind];
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
-
<nav
|
|
47
|
-
class="stalux-post-taxonomy-container"
|
|
48
|
-
transition:name={cfg.containerName}
|
|
49
|
-
transition:animate="none"
|
|
50
|
-
aria-label={title ?? cfg.heading}
|
|
51
|
-
>
|
|
46
|
+
<nav class="stalux-post-taxonomy-container" aria-label={title ?? cfg.heading}>
|
|
52
47
|
<h3 class="stalux-post-taxonomy-title">{title ?? cfg.heading}</h3>
|
|
53
48
|
{items.length > 0 ? (
|
|
54
|
-
<div class={cfg.listClass}
|
|
49
|
+
<div class={cfg.listClass}>
|
|
55
50
|
{items.map((item) => (
|
|
56
51
|
<a
|
|
57
52
|
href={`${cfg.prefix}${item}/`}
|
|
@@ -63,12 +58,6 @@ const cfg = {
|
|
|
63
58
|
))}
|
|
64
59
|
</div>
|
|
65
60
|
) : (
|
|
66
|
-
<div
|
|
67
|
-
class="stalux-post-taxonomy-empty"
|
|
68
|
-
transition:name={cfg.contentName}
|
|
69
|
-
transition:animate="fade"
|
|
70
|
-
>
|
|
71
|
-
{cfg.empty}
|
|
72
|
-
</div>
|
|
61
|
+
<div class="stalux-post-taxonomy-empty">{cfg.empty}</div>
|
|
73
62
|
)}
|
|
74
63
|
</nav>
|
|
@@ -20,13 +20,13 @@ const siteConfig = (configEntries.find((e) => e.id === "site")?.data ?? {}) as R
|
|
|
20
20
|
unknown
|
|
21
21
|
>;
|
|
22
22
|
const { t } = createTranslator((siteConfig.lang as string) || "zh-CN");
|
|
23
|
-
const { title, author, url, cc = "CC-BY-NC-SA-4.0"
|
|
23
|
+
const { title, author, url, cc = "CC-BY-NC-SA-4.0" } = Astro.props;
|
|
24
24
|
|
|
25
25
|
const licenseLink = buildCCLink(cc);
|
|
26
26
|
const licenseName = buildCCName(cc, t);
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
<div class="stalux-license-box"
|
|
29
|
+
<div class="stalux-license-box">
|
|
30
30
|
<div class="stalux-license-content">
|
|
31
31
|
<p class="stalux-license-title">{title}</p>
|
|
32
32
|
<p class="stalux-license-author">{t("post.author")}{author}</p>
|
|
@@ -4,7 +4,6 @@ import { getCollection } from "astro:content";
|
|
|
4
4
|
|
|
5
5
|
import { getSiteData } from "@utils/config-utils";
|
|
6
6
|
import { toMachineDateTime } from "@utils/semantic-time";
|
|
7
|
-
import { getPostTitleTransitionName } from "@utils/view-transitions";
|
|
8
7
|
|
|
9
8
|
interface Props {
|
|
10
9
|
post: CollectionEntry<"posts">;
|
|
@@ -42,10 +41,7 @@ const description = post.data.desc || "";
|
|
|
42
41
|
</div>
|
|
43
42
|
</a>
|
|
44
43
|
)}
|
|
45
|
-
<h2
|
|
46
|
-
class="stalux-card-post-title"
|
|
47
|
-
transition:name={priority ? getPostTitleTransitionName(post.data.abbrlink) : undefined}
|
|
48
|
-
>
|
|
44
|
+
<h2 class="stalux-card-post-title">
|
|
49
45
|
<a href={`/posts/${post.data.abbrlink}/`} class="a-none" data-astro-prefetch="viewport">
|
|
50
46
|
{post.data.title}
|
|
51
47
|
</a>
|
|
@@ -38,26 +38,13 @@ const exportMd = Boolean(promoteConfig?.export_md) && !isAboutPage;
|
|
|
38
38
|
const mdSourceUrl = exportMd ? `${Astro.url.pathname.replace(/\/$/, "")}.md` : "";
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
-
<article
|
|
42
|
-
class="stalux-article"
|
|
43
|
-
data-stalux-gallery={props.hasImage ? "true" : undefined}
|
|
44
|
-
transition:name={props.transitionName ?? "stalux-article-container"}
|
|
45
|
-
transition:animate="none"
|
|
46
|
-
>
|
|
41
|
+
<article class="stalux-article" data-stalux-gallery={props.hasImage ? "true" : undefined}>
|
|
47
42
|
<!-- Article Header -->
|
|
48
|
-
<header
|
|
49
|
-
class="stalux-post-article-header"
|
|
50
|
-
transition:name={`${transitionPrefix}-header`}
|
|
51
|
-
transition:animate="fade"
|
|
52
|
-
>
|
|
43
|
+
<header class="stalux-post-article-header">
|
|
53
44
|
<h1 class="stalux-post-title" data-stalux-motion-focus>
|
|
54
45
|
{props.title}
|
|
55
46
|
</h1>
|
|
56
|
-
<div
|
|
57
|
-
class="stalux-post-metadata"
|
|
58
|
-
transition:name={`${transitionPrefix}-metadata`}
|
|
59
|
-
transition:animate="none"
|
|
60
|
-
>
|
|
47
|
+
<div class="stalux-post-metadata">
|
|
61
48
|
{props.date && (
|
|
62
49
|
<time
|
|
63
50
|
class="stalux-post-meta-item"
|
|
@@ -78,11 +65,7 @@ const mdSourceUrl = exportMd ? `${Astro.url.pathname.replace(/\/$/, "")}.md` : "
|
|
|
78
65
|
</time>
|
|
79
66
|
)}
|
|
80
67
|
</div>
|
|
81
|
-
<div
|
|
82
|
-
class="stalux-post-page-stats"
|
|
83
|
-
transition:name={`${transitionPrefix}-stats`}
|
|
84
|
-
transition:animate="none"
|
|
85
|
-
>
|
|
68
|
+
<div class="stalux-post-page-stats">
|
|
86
69
|
{(props.readingMinutes ?? 0) > 0 && (
|
|
87
70
|
<span class="stalux-post-reading-time">
|
|
88
71
|
{t("post.readingTime")}
|
|
@@ -131,8 +114,6 @@ const mdSourceUrl = exportMd ? `${Astro.url.pathname.replace(/\/$/, "")}.md` : "
|
|
|
131
114
|
data-pagefind-body
|
|
132
115
|
data-stalux-post-id={props.postId === undefined ? undefined : String(props.postId)}
|
|
133
116
|
data-pagefind-filter={props.postId === undefined ? undefined : "post[data-stalux-post-id]"}
|
|
134
|
-
transition:name={`${transitionPrefix}-body`}
|
|
135
|
-
transition:animate="none"
|
|
136
117
|
>
|
|
137
118
|
<slot />
|
|
138
119
|
</section>
|
|
@@ -3,34 +3,16 @@ import "../../../styles/generated-article.css";
|
|
|
3
3
|
import SocialMedia from "@components/stalux/links/socialMedia.astro";
|
|
4
4
|
import PostAuthor from "@components/stalux/posts/postAuthor.astro";
|
|
5
5
|
import RandomPost from "@components/stalux/posts/randomPost.astro";
|
|
6
|
-
|
|
7
|
-
import { getSidebarAnimation } from "@utils/view-transitions";
|
|
8
6
|
---
|
|
9
7
|
|
|
10
|
-
<aside
|
|
11
|
-
class="stalux-sidebar"
|
|
12
|
-
transition:name="left-sidebar"
|
|
13
|
-
transition:animate={getSidebarAnimation("left")}
|
|
14
|
-
>
|
|
15
|
-
<div
|
|
16
|
-
class="stalux-sidebar-container"
|
|
17
|
-
transition:name="stalux-article-left-author"
|
|
18
|
-
transition:animate="fade"
|
|
19
|
-
>
|
|
8
|
+
<aside class="stalux-sidebar">
|
|
9
|
+
<div class="stalux-sidebar-container">
|
|
20
10
|
<PostAuthor />
|
|
21
11
|
</div>
|
|
22
|
-
<div
|
|
23
|
-
class="stalux-sidebar-container"
|
|
24
|
-
transition:name="stalux-article-left-social"
|
|
25
|
-
transition:animate="fade"
|
|
26
|
-
>
|
|
12
|
+
<div class="stalux-sidebar-container">
|
|
27
13
|
<SocialMedia />
|
|
28
14
|
</div>
|
|
29
|
-
<div
|
|
30
|
-
class="stalux-sidebar-container"
|
|
31
|
-
transition:name="stalux-article-left-random"
|
|
32
|
-
transition:animate="fade"
|
|
33
|
-
>
|
|
15
|
+
<div class="stalux-sidebar-container">
|
|
34
16
|
<RandomPost />
|
|
35
17
|
</div>
|
|
36
18
|
</aside>
|
|
@@ -5,8 +5,6 @@ import Weather from "@components/stalux/common/Weather.astro";
|
|
|
5
5
|
import PostTaxonomy from "@components/stalux/posts/PostTaxonomy.astro";
|
|
6
6
|
import PostToc from "@components/stalux/posts/postToc.astro";
|
|
7
7
|
|
|
8
|
-
import { getSidebarAnimation } from "@utils/view-transitions";
|
|
9
|
-
|
|
10
8
|
interface Props {
|
|
11
9
|
headings?: Array<{ depth: number; slug: string; text: string }>;
|
|
12
10
|
tags?: string[];
|
|
@@ -16,38 +14,18 @@ interface Props {
|
|
|
16
14
|
const { headings = [], tags = [], categories = [] } = Astro.props;
|
|
17
15
|
---
|
|
18
16
|
|
|
19
|
-
<aside
|
|
20
|
-
class="stalux-sidebar-
|
|
21
|
-
transition:name="right-sidebar"
|
|
22
|
-
transition:animate={getSidebarAnimation("right")}
|
|
23
|
-
>
|
|
24
|
-
<div
|
|
25
|
-
class="stalux-sidebar-container"
|
|
26
|
-
transition:name="stalux-article-right-date"
|
|
27
|
-
transition:animate="none"
|
|
28
|
-
>
|
|
17
|
+
<aside class="stalux-sidebar-right" data-stalux-scroll-pane>
|
|
18
|
+
<div class="stalux-sidebar-container">
|
|
29
19
|
<PostDate />
|
|
30
20
|
<Weather />
|
|
31
21
|
</div>
|
|
32
|
-
<div
|
|
33
|
-
class="stalux-sidebar-container"
|
|
34
|
-
transition:name="stalux-article-right-toc"
|
|
35
|
-
transition:animate="none"
|
|
36
|
-
>
|
|
22
|
+
<div class="stalux-sidebar-container">
|
|
37
23
|
<PostToc headings={headings} />
|
|
38
24
|
</div>
|
|
39
|
-
<div
|
|
40
|
-
class="stalux-sidebar-container"
|
|
41
|
-
transition:name="stalux-article-right-tags"
|
|
42
|
-
transition:animate="none"
|
|
43
|
-
>
|
|
25
|
+
<div class="stalux-sidebar-container">
|
|
44
26
|
<PostTaxonomy kind="tag" items={tags} />
|
|
45
27
|
</div>
|
|
46
|
-
<div
|
|
47
|
-
class="stalux-sidebar-container"
|
|
48
|
-
transition:name="stalux-article-right-categories"
|
|
49
|
-
transition:animate="none"
|
|
50
|
-
>
|
|
28
|
+
<div class="stalux-sidebar-container">
|
|
51
29
|
<PostTaxonomy kind="category" items={categories} />
|
|
52
30
|
</div>
|
|
53
31
|
</aside>
|
|
@@ -29,15 +29,10 @@ const tocItems = headings
|
|
|
29
29
|
}));
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
<nav
|
|
33
|
-
transition:name="toc-container"
|
|
34
|
-
transition:animate="none"
|
|
35
|
-
data-toc-active-class="stalux-toc-active"
|
|
36
|
-
aria-label={t("taxonomy.toc")}
|
|
37
|
-
>
|
|
32
|
+
<nav data-toc-active-class="stalux-toc-active" aria-label={t("taxonomy.toc")}>
|
|
38
33
|
<h3 class="stalux-toc-title">{title}</h3>
|
|
39
34
|
{tocItems.length > 0 ? (
|
|
40
|
-
<ul class="stalux-toc-list"
|
|
35
|
+
<ul class="stalux-toc-list">
|
|
41
36
|
{tocItems.map((heading) => (
|
|
42
37
|
<li>
|
|
43
38
|
<a
|
|
@@ -51,9 +46,7 @@ const tocItems = headings
|
|
|
51
46
|
))}
|
|
52
47
|
</ul>
|
|
53
48
|
) : (
|
|
54
|
-
<div class="stalux-toc-empty"
|
|
55
|
-
{t("taxonomy.noToc")}
|
|
56
|
-
</div>
|
|
49
|
+
<div class="stalux-toc-empty">{t("taxonomy.noToc")}</div>
|
|
57
50
|
)}
|
|
58
51
|
</nav>
|
|
59
52
|
|
|
@@ -27,11 +27,7 @@ if (typeKey === "category" || typeKey === "categories" || typeKey === "分类")
|
|
|
27
27
|
}
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
<header
|
|
31
|
-
class="stalux-tag-header"
|
|
32
|
-
transition:name="stalux-taxonomy-page-header-shell"
|
|
33
|
-
transition:animate="none"
|
|
34
|
-
>
|
|
30
|
+
<header class="stalux-tag-header">
|
|
35
31
|
<h1 class="stalux-tag-page-title" data-stalux-motion-focus>
|
|
36
32
|
<span class="stalux-tag-category-icon">
|
|
37
33
|
<svg
|
package/src/index.ts
CHANGED
|
@@ -163,7 +163,26 @@ export function stalux(options: StaluxOptions = {}): AstroIntegration[] {
|
|
|
163
163
|
config.build.inlineStylesheets === "always" ? "always" : "never",
|
|
164
164
|
},
|
|
165
165
|
vite: {
|
|
166
|
-
optimizeDeps: {
|
|
166
|
+
optimizeDeps: {
|
|
167
|
+
exclude: ["@mcp-b/webmcp-polyfill"],
|
|
168
|
+
// Discover lazy page features before the first visit:
|
|
169
|
+
// Vite re-optimization would otherwise reload the
|
|
170
|
+
// entire document midway through a Swup navigation.
|
|
171
|
+
include: [
|
|
172
|
+
"swup",
|
|
173
|
+
"@swup/a11y-plugin",
|
|
174
|
+
"@swup/head-plugin",
|
|
175
|
+
"@swup/js-plugin",
|
|
176
|
+
"@swup/preload-plugin",
|
|
177
|
+
"@swup/scroll-plugin",
|
|
178
|
+
"@microsoft/clarity",
|
|
179
|
+
"@pagefind/component-ui",
|
|
180
|
+
"@waline/client",
|
|
181
|
+
"@xingwangzhe/tags-cloud",
|
|
182
|
+
"photoswipe",
|
|
183
|
+
"photoswipe/lightbox",
|
|
184
|
+
],
|
|
185
|
+
},
|
|
167
186
|
css: { lightningcss: { targets: modernCssTargets } },
|
|
168
187
|
build: {
|
|
169
188
|
target: config.vite.build?.target ?? "esnext",
|