@xingwangzhe/stalux 1.27.0 → 1.28.0

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.
Files changed (40) hide show
  1. package/README.md +6 -6
  2. package/package.json +3 -2
  3. package/src/components/stalux/archives/archivesList.astro +34 -42
  4. package/src/components/stalux/categories/categoriesList.astro +4 -4
  5. package/src/components/stalux/common/textType.astro +1 -3
  6. package/src/components/stalux/footer/FooterBadges.astro +28 -24
  7. package/src/components/stalux/footer/FooterBeian.astro +22 -26
  8. package/src/components/stalux/footer/FooterStats.astro +28 -27
  9. package/src/components/stalux/footer/FooterThemeInfo.astro +24 -28
  10. package/src/components/stalux/layout/footer.astro +5 -14
  11. package/src/components/stalux/layout/head.astro +5 -9
  12. package/src/components/stalux/layout/navs.astro +16 -20
  13. package/src/components/stalux/links/linkList.astro +4 -4
  14. package/src/components/stalux/links/socialMedia.astro +34 -34
  15. package/src/components/stalux/posts/PostTaxonomy.astro +14 -14
  16. package/src/components/stalux/posts/WalineComment.astro +20 -464
  17. package/src/components/stalux/posts/postCC.astro +7 -7
  18. package/src/components/stalux/posts/postCard.astro +41 -41
  19. package/src/components/stalux/posts/postContent.astro +46 -41
  20. package/src/components/stalux/posts/postList.astro +4 -4
  21. package/src/components/stalux/posts/postNavigation.astro +107 -119
  22. package/src/components/stalux/posts/postToc.astro +20 -20
  23. package/src/components/stalux/tags/tagsCloud.astro +15 -15
  24. package/src/components/stalux/words/wordCard.astro +27 -32
  25. package/src/components/stalux/words/wordList.astro +18 -18
  26. package/src/i18n/en.json +1 -0
  27. package/src/i18n/zh-CN.json +1 -0
  28. package/src/index.ts +82 -34
  29. package/src/internal/font-slices.ts +151 -136
  30. package/src/layouts/PostLayout.astro +6 -6
  31. package/src/layouts/Stalux.astro +4 -8
  32. package/src/pages/about.astro +6 -6
  33. package/src/pages/categories/[category].astro +5 -1
  34. package/src/pages/posts/[post].astro +2 -2
  35. package/src/plugins/feature-flags.ts +60 -8
  36. package/src/scripts/waline.ts +32 -11
  37. package/src/styles/base/init.css +2 -1
  38. package/src/styles/base/math.css +1 -1
  39. package/src/styles/components/posts/waline.css +440 -0
  40. package/src/utils/i18n.ts +16 -5
@@ -43,51 +43,56 @@ const mdSourceUrl = exportMd ? `${Astro.url.pathname.replace(/\/$/, "")}.md` : "
43
43
  <h1 class={style.title}>{props.title}</h1>
44
44
  <div class={style.metadata}>
45
45
  {props.date && (
46
- <time class={style.metaItem} datetime={timezone ? toMachineDateTime(props.date, timezone) : props.date}>
47
- {t("post.publishTime")}
48
- {props.date}
49
- </time>
50
- )}
46
+ <time
47
+ class={style.metaItem}
48
+ datetime={timezone ? toMachineDateTime(props.date, timezone) : props.date}
49
+ >
50
+ {t("post.publishTime")}
51
+ {props.date}
52
+ </time>
53
+ )}
51
54
 
52
55
  {props.updated && (
53
- <time class={style.metaItem} datetime={timezone ? toMachineDateTime(props.updated, timezone) : props.updated}>
54
- {t("post.updateTime")}
55
- {props.updated}
56
- </time>
57
- )}
56
+ <time
57
+ class={style.metaItem}
58
+ datetime={timezone ? toMachineDateTime(props.updated, timezone) : props.updated}
59
+ >
60
+ {t("post.updateTime")}
61
+ {props.updated}
62
+ </time>
63
+ )}
58
64
  </div>
59
- {<div class={style.pageStats}>
60
- {(props.readingMinutes ?? 0) > 0 && (
61
- <span class={style.readingTime}>
62
- {t("post.readingTime")}{props.readingMinutes && props.readingMinutes > 0
63
- ? (props.readingMinutes < 1
64
- ? t("common.lessThanOneMinute")
65
- : t("common.minute", { n: props.readingMinutes }))
66
- : ""}
67
- </span>
68
- )}
69
- {(props.wordCount ?? 0) > 0 && (
70
- <span class={style.wordCount}>
71
- {t("post.wordCount")}{props.wordCount}
72
- </span>
73
- )}
74
- <span id="vercount_container_page_pv">
75
- {t("post.viewCount")}
76
- <span id="vercount_value_page_pv">Loading...</span>
77
- </span>
78
- </div>}
65
+ {(
66
+ <div class={style.pageStats}>
67
+ {(props.readingMinutes ?? 0) > 0 && (
68
+ <span class={style.readingTime}>
69
+ {t("post.readingTime")}
70
+ {props.readingMinutes && props.readingMinutes > 0
71
+ ? props.readingMinutes < 1
72
+ ? t("common.lessThanOneMinute")
73
+ : t("common.minute", { n: props.readingMinutes })
74
+ : ""}
75
+ </span>
76
+ )}
77
+ {(props.wordCount ?? 0) > 0 && (
78
+ <span class={style.wordCount}>
79
+ {t("post.wordCount")}
80
+ {props.wordCount}
81
+ </span>
82
+ )}
83
+ <span id="vercount_container_page_pv">
84
+ {t("post.viewCount")}
85
+ <span id="vercount_value_page_pv">Loading...</span>
86
+ </span>
87
+ </div>
88
+ )}
79
89
  {exportMd && (
80
- <div class={style.sourceLinkRow}>
81
- <a
82
- class={style.sourceLink}
83
- href={mdSourceUrl}
84
- target="_blank"
85
- rel="noopener noreferrer"
86
- >
87
- {t("post.viewSource")}
88
- </a>
89
- </div>
90
- )}
90
+ <div class={style.sourceLinkRow}>
91
+ <a class={style.sourceLink} href={mdSourceUrl} target="_blank" rel="noopener noreferrer">
92
+ {t("post.viewSource")}
93
+ </a>
94
+ </div>
95
+ )}
91
96
  </header>
92
97
 
93
98
  <!-- Article Body -->
@@ -15,9 +15,9 @@ const posts = props.posts ?? (await getCollection("posts", ({ data }) => !data.d
15
15
  <div data-stalux="postlist" class={styles.container}>
16
16
  <ul class={styles["post-list"]}>
17
17
  {posts.map((post, index) => (
18
- <li>
19
- <PostCard post={post} priority={index === 0} />
20
- </li>
21
- ))}
18
+ <li>
19
+ <PostCard post={post} priority={index === 0} />
20
+ </li>
21
+ ))}
22
22
  </ul>
23
23
  </div>
@@ -18,125 +18,113 @@ const { t } = createTranslator((siteConfig.lang as string) || "zh-CN");
18
18
  ---
19
19
 
20
20
  {(props.prev || props.next) && (
21
- <nav class={style.postNavigation} aria-label="文章导航">
22
- <div class={style.postNavigationInner}>
23
- {props.prev ? (
24
- <a
25
- href={props.prev.url}
26
- class={`${style.postNavLink} ${style.prevPost}`}
27
- rel="prev"
28
- data-astro-prefetch
29
- >
30
- <span class={style.postNavArrow}>
31
- <svg
32
- aria-hidden="true"
33
- xmlns="http://www.w3.org/2000/svg"
34
- viewBox="0 0 24 24"
35
- width="24"
36
- height="24"
37
- fill="none"
38
- stroke="currentColor"
39
- stroke-width="2"
40
- stroke-linecap="round"
41
- stroke-linejoin="round"
42
- >
43
- <path d="M19 12H5M12 19l-7-7 7-7" />
44
- </svg>
45
- </span>
46
- <div class={style.postNavContent}>
47
- <span class={style.postNavLabel}>{t("post.prevPost")}</span>
48
- <span class={style.postNavTitle}>
49
- {props.prev.title}
50
- </span>
51
- </div>
52
- </a>
53
- ) : (
54
- <span
55
- class={`${style.postNavLink} ${style.prevPost} ${style.disabled}`}
56
- >
57
- <span class={style.postNavArrow}>
58
- <svg
59
- aria-hidden="true"
60
- xmlns="http://www.w3.org/2000/svg"
61
- viewBox="0 0 24 24"
62
- width="24"
63
- height="24"
64
- fill="none"
65
- stroke="currentColor"
66
- stroke-width="2"
67
- stroke-linecap="round"
68
- stroke-linejoin="round"
69
- >
70
- <path d="M19 12H5M12 19l-7-7 7-7" />
71
- </svg>
72
- </span>
73
- <div class={style.postNavContent}>
74
- <span class={style.postNavLabel}>{t("post.prevPost")}</span>
75
- <span class={style.postNavTitle}>
76
- {t("post.noPrev")}
77
- </span>
78
- </div>
21
+ <nav class={style.postNavigation} aria-label={t("post.navigation")}>
22
+ <div class={style.postNavigationInner}>
23
+ {props.prev ? (
24
+ <a
25
+ href={props.prev.url}
26
+ class={`${style.postNavLink} ${style.prevPost}`}
27
+ rel="prev"
28
+ data-astro-prefetch
29
+ >
30
+ <span class={style.postNavArrow}>
31
+ <svg
32
+ aria-hidden="true"
33
+ xmlns="http://www.w3.org/2000/svg"
34
+ viewBox="0 0 24 24"
35
+ width="24"
36
+ height="24"
37
+ fill="none"
38
+ stroke="currentColor"
39
+ stroke-width="2"
40
+ stroke-linecap="round"
41
+ stroke-linejoin="round"
42
+ >
43
+ <path d="M19 12H5M12 19l-7-7 7-7" />
44
+ </svg>
79
45
  </span>
80
- )}
46
+ <div class={style.postNavContent}>
47
+ <span class={style.postNavLabel}>{t("post.prevPost")}</span>
48
+ <span class={style.postNavTitle}>{props.prev.title}</span>
49
+ </div>
50
+ </a>
51
+ ) : (
52
+ <span class={`${style.postNavLink} ${style.prevPost} ${style.disabled}`}>
53
+ <span class={style.postNavArrow}>
54
+ <svg
55
+ aria-hidden="true"
56
+ xmlns="http://www.w3.org/2000/svg"
57
+ viewBox="0 0 24 24"
58
+ width="24"
59
+ height="24"
60
+ fill="none"
61
+ stroke="currentColor"
62
+ stroke-width="2"
63
+ stroke-linecap="round"
64
+ stroke-linejoin="round"
65
+ >
66
+ <path d="M19 12H5M12 19l-7-7 7-7" />
67
+ </svg>
68
+ </span>
69
+ <div class={style.postNavContent}>
70
+ <span class={style.postNavLabel}>{t("post.prevPost")}</span>
71
+ <span class={style.postNavTitle}>{t("post.noPrev")}</span>
72
+ </div>
73
+ </span>
74
+ )}
81
75
 
82
- {props.next ? (
83
- <a
84
- href={props.next.url}
85
- class={`${style.postNavLink} ${style.nextPost}`}
86
- rel="next"
87
- data-astro-prefetch
88
- >
89
- <div class={style.postNavContent}>
90
- <span class={style.postNavLabel}>{t("post.nextPost")}</span>
91
- <span class={style.postNavTitle}>
92
- {props.next.title}
93
- </span>
94
- </div>
95
- <span class={style.postNavArrow}>
96
- <svg
97
- aria-hidden="true"
98
- xmlns="http://www.w3.org/2000/svg"
99
- viewBox="0 0 24 24"
100
- width="24"
101
- height="24"
102
- fill="none"
103
- stroke="currentColor"
104
- stroke-width="2"
105
- stroke-linecap="round"
106
- stroke-linejoin="round"
107
- >
108
- <path d="M5 12h14M12 5l7 7-7 7" />
109
- </svg>
110
- </span>
111
- </a>
112
- ) : (
113
- <span
114
- class={`${style.postNavLink} ${style.nextPost} ${style.disabled}`}
115
- >
116
- <div class={style.postNavContent}>
117
- <span class={style.postNavLabel}>{t("post.nextPost")}</span>
118
- <span class={style.postNavTitle}>
119
- {t("post.noNext")}
120
- </span>
121
- </div>
122
- <span class={style.postNavArrow}>
123
- <svg
124
- aria-hidden="true"
125
- xmlns="http://www.w3.org/2000/svg"
126
- viewBox="0 0 24 24"
127
- width="24"
128
- height="24"
129
- fill="none"
130
- stroke="currentColor"
131
- stroke-width="2"
132
- stroke-linecap="round"
133
- stroke-linejoin="round"
134
- >
135
- <path d="M5 12h14M12 5l7 7-7 7" />
136
- </svg>
137
- </span>
76
+ {props.next ? (
77
+ <a
78
+ href={props.next.url}
79
+ class={`${style.postNavLink} ${style.nextPost}`}
80
+ rel="next"
81
+ data-astro-prefetch
82
+ >
83
+ <div class={style.postNavContent}>
84
+ <span class={style.postNavLabel}>{t("post.nextPost")}</span>
85
+ <span class={style.postNavTitle}>{props.next.title}</span>
86
+ </div>
87
+ <span class={style.postNavArrow}>
88
+ <svg
89
+ aria-hidden="true"
90
+ xmlns="http://www.w3.org/2000/svg"
91
+ viewBox="0 0 24 24"
92
+ width="24"
93
+ height="24"
94
+ fill="none"
95
+ stroke="currentColor"
96
+ stroke-width="2"
97
+ stroke-linecap="round"
98
+ stroke-linejoin="round"
99
+ >
100
+ <path d="M5 12h14M12 5l7 7-7 7" />
101
+ </svg>
102
+ </span>
103
+ </a>
104
+ ) : (
105
+ <span class={`${style.postNavLink} ${style.nextPost} ${style.disabled}`}>
106
+ <div class={style.postNavContent}>
107
+ <span class={style.postNavLabel}>{t("post.nextPost")}</span>
108
+ <span class={style.postNavTitle}>{t("post.noNext")}</span>
109
+ </div>
110
+ <span class={style.postNavArrow}>
111
+ <svg
112
+ aria-hidden="true"
113
+ xmlns="http://www.w3.org/2000/svg"
114
+ viewBox="0 0 24 24"
115
+ width="24"
116
+ height="24"
117
+ fill="none"
118
+ stroke="currentColor"
119
+ stroke-width="2"
120
+ stroke-linecap="round"
121
+ stroke-linejoin="round"
122
+ >
123
+ <path d="M5 12h14M12 5l7 7-7 7" />
124
+ </svg>
138
125
  </span>
139
- )}
140
- </div>
141
- </nav>
142
- )}
126
+ </span>
127
+ )}
128
+ </div>
129
+ </nav>
130
+ )}
@@ -36,26 +36,26 @@ const tocItems = headings
36
36
  >
37
37
  <h3 class={style.title}>{title}</h3>
38
38
  {tocItems.length > 0 ? (
39
- <ul
40
- class={style.list}
41
- transition:name="toc-content"
42
- transition:animate={fade({ duration: "0.3s" })}
43
- >
44
- {tocItems.map((heading) => (
45
- <li>
46
- <a
47
- class={`${style.item} ${style[`depth-${heading.depth}`] || ""} a-none`}
48
- href={`#${heading.slug}`}
49
- data-toc-link
50
- >
51
- {heading.text}
52
- </a>
53
- </li>
54
- ))}
55
- </ul>
56
- ) : (
57
- <div class={style.empty}>{t("taxonomy.noToc")}</div>
58
- )}
39
+ <ul
40
+ class={style.list}
41
+ transition:name="toc-content"
42
+ transition:animate={fade({ duration: "0.3s" })}
43
+ >
44
+ {tocItems.map((heading) => (
45
+ <li>
46
+ <a
47
+ class={`${style.item} ${style[`depth-${heading.depth}`] || ""} a-none`}
48
+ href={`#${heading.slug}`}
49
+ data-toc-link
50
+ >
51
+ {heading.text}
52
+ </a>
53
+ </li>
54
+ ))}
55
+ </ul>
56
+ ) : (
57
+ <div class={style.empty}>{t("taxonomy.noToc")}</div>
58
+ )}
59
59
  </nav>
60
60
 
61
61
  <script src="../../../scripts/toc-scrollspy.ts"></script>
@@ -19,21 +19,21 @@ const tagLinks = tagList.map((t) => ({
19
19
  <!-- 移动端:SSR 卡片 -->
20
20
  <div class={styles.cards} id="tags-cards">
21
21
  {tagList.length > 0 ? (
22
- tagList.map(({ name, count }) => (
23
- <a
24
- href={`/tags/${name}/`}
25
- class={styles.tagCard}
26
- data-stalux-tag-card
27
- data-count={count}
28
- data-astro-prefetch
29
- >
30
- <span class={styles.tagName}>{name}</span>
31
- <span class={styles.tagCount}>{count}</span>
32
- </a>
33
- ))
34
- ) : (
35
- <div class={styles.noTags}>{t("tags.noTags")}</div>
36
- )}
22
+ tagList.map(({ name, count }) => (
23
+ <a
24
+ href={`/tags/${name}/`}
25
+ class={styles.tagCard}
26
+ data-stalux-tag-card
27
+ data-count={count}
28
+ data-astro-prefetch
29
+ >
30
+ <span class={styles.tagName}>{name}</span>
31
+ <span class={styles.tagCount}>{count}</span>
32
+ </a>
33
+ ))
34
+ ) : (
35
+ <div class={styles.noTags}>{t("tags.noTags")}</div>
36
+ )}
37
37
  </div>
38
38
 
39
39
  <!-- 桌面端:Canvas 标签云 -->
@@ -22,37 +22,32 @@ const machineDate = date && timezone ? toMachineDateTime(date, timezone) : date;
22
22
  <Content />
23
23
  </div>
24
24
  {(date || source || sourceDate) && (
25
- <footer class={styles.footer}>
26
- {date ? (
27
- <time class={styles.date} datetime={machineDate}>
28
- {date}
29
- </time>
30
- ) : (
31
- <span />
32
- )}
33
- {
34
- (source || sourceDate) && (
35
- <div class={styles.sourceMeta}>
36
- {sourceDate && (
37
- <span class={styles.sourceDate}>{sourceDate}</span>
38
- )}
39
- {source && (
40
- link ? (
41
- <a
42
- href={link}
43
- target="_blank"
44
- rel="noopener noreferrer"
45
- class={styles.sourceLink}
46
- >
47
- — {source}
48
- </a>
49
- ) : (
50
- <span class={styles.sourceText}>— {source}</span>
51
- )
52
- )}
53
- </div>
54
- )
55
- }
56
- </footer>
25
+ <footer class={styles.footer}>
26
+ {date ? (
27
+ <time class={styles.date} datetime={machineDate}>
28
+ {date}
29
+ </time>
30
+ ) : (
31
+ <span />
57
32
  )}
33
+ {(source || sourceDate) && (
34
+ <div class={styles.sourceMeta}>
35
+ {sourceDate && <span class={styles.sourceDate}>{sourceDate}</span>}
36
+ {source &&
37
+ (link ? (
38
+ <a
39
+ href={link}
40
+ target="_blank"
41
+ rel="noopener noreferrer"
42
+ class={styles.sourceLink}
43
+ >
44
+ — {source}
45
+ </a>
46
+ ) : (
47
+ <span class={styles.sourceText}>— {source}</span>
48
+ ))}
49
+ </div>
50
+ )}
51
+ </footer>
52
+ )}
58
53
  </article>
@@ -20,24 +20,24 @@ const sorted = [...entries].sort((a, b) => {
20
20
 
21
21
  <ul class={`${styles.list} stagger-children`}>
22
22
  {sorted.map((entry) => {
23
- const hash = entry.data.abbrlink ? `#word-${entry.data.abbrlink}` : undefined;
24
- return (
25
- <li class={styles.item}>
26
- {hash ? (
27
- <a
28
- href={hash}
29
- class="a-none"
30
- data-word-hash={hash}
31
- aria-label={`Jump to ${entry.data.abbrlink}`}
32
- >
33
- <WordCard entry={entry} timezone={timezone} />
34
- </a>
35
- ) : (
36
- <WordCard entry={entry} timezone={timezone} />
37
- )}
38
- </li>
39
- );
40
- })}
23
+ const hash = entry.data.abbrlink ? `#word-${entry.data.abbrlink}` : undefined;
24
+ return (
25
+ <li class={styles.item}>
26
+ {hash ? (
27
+ <a
28
+ href={hash}
29
+ class="a-none"
30
+ data-word-hash={hash}
31
+ aria-label={`Jump to ${entry.data.abbrlink}`}
32
+ >
33
+ <WordCard entry={entry} timezone={timezone} />
34
+ </a>
35
+ ) : (
36
+ <WordCard entry={entry} timezone={timezone} />
37
+ )}
38
+ </li>
39
+ );
40
+ })}
41
41
  </ul>
42
42
 
43
43
  <script src="../../../scripts/word-list.ts"></script>
package/src/i18n/en.json CHANGED
@@ -24,6 +24,7 @@
24
24
  "backHome": "Back to Home"
25
25
  },
26
26
  "post": {
27
+ "navigation": "Post navigation",
27
28
  "publishTime": "Published: ",
28
29
  "updateTime": "Updated: ",
29
30
  "readingTime": "🕒 Reading time: ",
@@ -24,6 +24,7 @@
24
24
  "backHome": "返回首页"
25
25
  },
26
26
  "post": {
27
+ "navigation": "文章导航",
27
28
  "publishTime": "发布时间:",
28
29
  "updateTime": "更新时间:",
29
30
  "readingTime": "🕒 阅读时间:",