@xingwangzhe/stalux 1.2.0 → 1.3.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 CHANGED
@@ -33,43 +33,69 @@ bun run dev # or npm run dev
33
33
 
34
34
  ### Option B: Install as Astro Integration (Plugin Mode)
35
35
 
36
- Keep your project clean — install stalux as a dependency:
36
+ Keep your project clean — install stalux as a dependency in a new or existing Astro project.
37
+
38
+ **Step-by-step from scratch:**
37
39
 
38
40
  ```bash
39
- npm install @xingwangzhe/stalux
40
- ```
41
+ # 1. Create a new Astro project (choose "minimal" template)
42
+ bun create astro
41
43
 
42
- Then initialize the content template:
44
+ # 2. Enter your project directory
45
+ cd ./myblog
43
46
 
44
- ```bash
45
- npx @xingwangzhe/stalux init
46
- # or: npm run init
47
+ # 3. Install the stalux theme package
48
+ bun add @xingwangzhe/stalux
49
+
50
+ # 4. Initialize content template (creates stalux/ dir with configs & sample posts)
51
+ bunx stalux init
47
52
  ```
48
53
 
49
- This creates the `stalux/` directory structure with example content in your project. Then add to `astro.config.mjs`:
54
+ **5. Configure `astro.config.mjs`:**
50
55
 
51
56
  ```ts
52
57
  import { defineConfig } from "astro/config";
58
+ import { satteri } from "@astrojs/markdown-satteri";
59
+ import sitemap from "@astrojs/sitemap";
60
+ import expressiveCode from "astro-expressive-code";
53
61
  import stalux from "@xingwangzhe/stalux";
62
+ import { mermaidHast } from "@xingwangzhe/satteri-mermaid";
63
+ import { photoswipe } from "@xingwangzhe/satteri-photoswipe";
54
64
 
55
65
  export default defineConfig({
56
- integrations: [stalux({
57
- contentDir: "./content", // customize content directory (default: "stalux")
58
- components: { // optional: override theme components
59
- // Navs: "./src/CustomNavs.astro",
66
+ output: "static",
67
+ site: "https://example.com",
68
+ integrations: [
69
+ stalux({ contentDir: "stalux" }),
70
+ sitemap(),
71
+ expressiveCode({ themes: ["dark-plus", "github-light"] }),
72
+ ],
73
+ markdown: {
74
+ processor: satteri({
75
+ features: { math: true, smartPunctuation: true, gfm: true, frontmatter: true },
76
+ hastPlugins: [photoswipe(), mermaidHast({ responsive: true, theme: "dark" })],
77
+ }),
60
78
  },
61
- })],
62
79
  });
63
80
  ```
64
81
 
65
82
  Create `src/content.config.ts`:
66
83
 
67
84
  ```ts
68
- import { defineCollections } from "stalux/schemas";
69
- export const collections = defineCollections({ contentDir: "./content" });
85
+ import { defineCollections } from "@xingwangzhe/stalux/schemas";
86
+ export const collections = defineCollections({ contentDir: "stalux" });
87
+ ```
88
+
89
+ **6. Start writing and developing:**
90
+
91
+ ```bash
92
+ bun run dev
70
93
  ```
71
94
 
72
- Then write your content in `./content/posts/`, `./content/config/`, etc.
95
+ Your blog is now running at `http://localhost:4321/` with all theme pages, search, RSS, and more ready to go.
96
+
97
+ > 💡 `bunx stalux init` creates the `stalux/` directory structure with example content.
98
+ > Run it any time to see what a valid config looks like — it won't overwrite existing files.
73
99
 
74
100
  ---
75
101
 
@@ -157,13 +183,15 @@ import { defineConfig } from "astro/config";
157
183
  import stalux from "@xingwangzhe/stalux";
158
184
 
159
185
  export default defineConfig({
160
- integrations: [stalux({
161
- components: {
162
- Navs: "./src/components/CustomNavs.astro",
163
- Footer: "./src/components/CustomFooter.astro",
164
- // ... see full list in src/internal/override.ts
165
- }
166
- })],
186
+ integrations: [
187
+ stalux({
188
+ components: {
189
+ Navs: "./src/components/CustomNavs.astro",
190
+ Footer: "./src/components/CustomFooter.astro",
191
+ // ... see full list in src/internal/override.ts
192
+ },
193
+ }),
194
+ ],
167
195
  });
168
196
  ```
169
197
 
package/package.json CHANGED
@@ -1,25 +1,27 @@
1
1
  {
2
2
  "name": "@xingwangzhe/stalux",
3
- "version": "1.2.0",
4
- "description": "A powerful, modern Astro blog theme — use as template or install as plugin",
5
- "type": "module",
6
- "license": "MIT",
7
- "author": "xingwangzhe",
8
- "homepage": "https://stalux.needhelp.icu",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/xingwangzhe/stalux.git"
12
- },
13
- "bugs": "https://github.com/xingwangzhe/stalux/issues",
3
+ "version": "1.3.1",
4
+ "description": "A powerful, modern Astro blog theme \u2014 use as template or install as plugin",
14
5
  "keywords": [
15
6
  "astro",
16
- "astro-theme",
17
7
  "astro-integration",
8
+ "astro-theme",
18
9
  "blog",
19
10
  "blog-theme",
20
11
  "stalux",
21
12
  "static-site"
22
13
  ],
14
+ "homepage": "https://stalux.needhelp.icu",
15
+ "bugs": "https://github.com/xingwangzhe/stalux/issues",
16
+ "license": "MIT",
17
+ "author": "xingwangzhe",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/xingwangzhe/stalux.git"
21
+ },
22
+ "bin": {
23
+ "stalux": "scripts/cli.mjs"
24
+ },
23
25
  "files": [
24
26
  "src/index.ts",
25
27
  "src/config.ts",
@@ -40,6 +42,7 @@
40
42
  "template/**/*",
41
43
  "!src/content.config.ts"
42
44
  ],
45
+ "type": "module",
43
46
  "exports": {
44
47
  ".": "./src/index.ts",
45
48
  "./config": "./src/config.ts",
@@ -56,12 +59,8 @@
56
59
  "./assets/*": "./src/assets/*",
57
60
  "./package.json": "./package.json"
58
61
  },
59
- "bin": {
60
- "stalux": "scripts/cli.mjs"
61
- },
62
62
  "scripts": {
63
63
  "dev": "astro dev ",
64
- "prebuild": "bun run scripts/font-subset.ts",
65
64
  "build": "astro build ",
66
65
  "preview": "astro preview ",
67
66
  "astro": "astro",
@@ -80,19 +79,17 @@
80
79
  "animejs": "^4.5.0",
81
80
  "astro": "^7.1.3",
82
81
  "pagefind": "^1.5.2",
83
- "photoswipe": "^5.4.4"
84
- },
85
- "peerDependencies": {
86
- "astro": "^7.0.0"
82
+ "photoswipe": "^5.4.4",
83
+ "subset-font": "^2.5.0",
84
+ "@astrojs/sitemap": "^3.7.3",
85
+ "@xingwangzhe/satteri-mermaid": "0.7.1",
86
+ "@xingwangzhe/satteri-photoswipe": "^0.2.0",
87
+ "astro-expressive-code": "^0.44.1"
87
88
  },
88
89
  "devDependencies": {
89
90
  "@astrojs/rss": "^4.0.19",
90
- "@astrojs/sitemap": "^3.7.3",
91
91
  "@lucide/astro": "^1.27.0",
92
92
  "@types/node": "^26.1.1",
93
- "@xingwangzhe/satteri-mermaid": "0.7.1",
94
- "@xingwangzhe/satteri-photoswipe": "^0.2.0",
95
- "astro-expressive-code": "^0.44.1",
96
93
  "astro-seo": "^1.1.0",
97
94
  "astro-typewriter": "^1.2.0",
98
95
  "badge-maker": "^6.0.0",
@@ -101,8 +98,10 @@
101
98
  "oxfmt": "^0.60.0",
102
99
  "oxlint": "^1.75.0",
103
100
  "simple-icons": "^16.27.1",
104
- "subset-font": "^2.5.0",
105
101
  "temml": "^0.13.3",
106
102
  "typescript": "^7.0.2"
103
+ },
104
+ "peerDependencies": {
105
+ "astro": "^7.0.0"
107
106
  }
108
107
  }
package/scripts/cli.mjs CHANGED
@@ -18,27 +18,27 @@ const PACKAGE_ROOT = resolve(__dirname, "..");
18
18
  const TEMPLATE_DIR = join(PACKAGE_ROOT, "template");
19
19
 
20
20
  function copyDir(src, dest, overwrite = false) {
21
- mkdirSync(dest, { recursive: true });
22
- for (const entry of readdirSync(src)) {
23
- const srcPath = join(src, entry);
24
- const destPath = join(dest, entry);
25
- if (entry === "node_modules") continue;
26
-
27
- if (statSync(srcPath).isDirectory()) {
28
- copyDir(srcPath, destPath, overwrite);
29
- } else {
30
- if (!overwrite && existsSync(destPath)) {
31
- console.log(` ⏭ ${entry} (already exists, skipped)`);
32
- continue;
33
- }
34
- cpSync(srcPath, destPath);
35
- console.log(` ✅ ${entry}`);
21
+ mkdirSync(dest, { recursive: true });
22
+ for (const entry of readdirSync(src)) {
23
+ const srcPath = join(src, entry);
24
+ const destPath = join(dest, entry);
25
+ if (entry === "node_modules") continue;
26
+
27
+ if (statSync(srcPath).isDirectory()) {
28
+ copyDir(srcPath, destPath, overwrite);
29
+ } else {
30
+ if (!overwrite && existsSync(destPath)) {
31
+ console.log(` ⏭ ${entry} (already exists, skipped)`);
32
+ continue;
33
+ }
34
+ cpSync(srcPath, destPath);
35
+ console.log(` ✅ ${entry}`);
36
+ }
36
37
  }
37
- }
38
38
  }
39
39
 
40
40
  function printHelp() {
41
- console.log(`
41
+ console.log(`
42
42
  Stalux — Modern Astro Blog Theme
43
43
 
44
44
  Usage:
@@ -56,17 +56,17 @@ function printHelp() {
56
56
  }
57
57
 
58
58
  function printNextSteps(targetDir) {
59
- console.log("");
60
- console.log(" 📝 Next Steps:");
61
- console.log("");
62
- console.log(` 1. cd ${targetDir}`);
63
- console.log(` 2. npm install stalux`);
64
- console.log(` 3. Edit astro.config.mjs to add stalux()`);
65
- console.log(` 4. Start writing content in ${targetDir}/stalux/posts/`);
66
- console.log(` 5. npm run dev`);
67
- console.log("");
68
- console.log(" 📖 Docs: https://stalux.needhelp.icu");
69
- console.log("");
59
+ console.log("");
60
+ console.log(" 📝 Next Steps:");
61
+ console.log("");
62
+ console.log(` 1. cd ${targetDir}`);
63
+ console.log(` 2. npm install stalux`);
64
+ console.log(` 3. Edit astro.config.mjs to add stalux()`);
65
+ console.log(` 4. Start writing content in ${targetDir}/stalux/posts/`);
66
+ console.log(` 5. npm run dev`);
67
+ console.log("");
68
+ console.log(" 📖 Docs: https://stalux.needhelp.icu");
69
+ console.log("");
70
70
  }
71
71
 
72
72
  // ---- Main ----
@@ -74,27 +74,29 @@ const args = process.argv.slice(2);
74
74
  const command = args[0];
75
75
 
76
76
  if (!command || command === "--help" || command === "-h") {
77
- printHelp();
78
- process.exit(0);
77
+ printHelp();
78
+ process.exit(0);
79
79
  }
80
80
 
81
81
  if (command === "init") {
82
- const targetArg = args[1] || ".";
83
- const targetPath = resolve(process.cwd(), targetArg);
84
-
85
- if (!existsSync(TEMPLATE_DIR)) {
86
- console.error("❌ Template directory not found. Ensure stalux package is properly installed.");
87
- process.exit(1);
88
- }
82
+ const targetArg = args[1] || ".";
83
+ const targetPath = resolve(process.cwd(), targetArg);
84
+
85
+ if (!existsSync(TEMPLATE_DIR)) {
86
+ console.error(
87
+ "❌ Template directory not found. Ensure stalux package is properly installed.",
88
+ );
89
+ process.exit(1);
90
+ }
89
91
 
90
- console.log(`📦 Initializing Stalux content template...`);
91
- console.log(`📂 Target: ${targetPath}`);
92
- console.log("");
92
+ console.log(`📦 Initializing Stalux content template...`);
93
+ console.log(`📂 Target: ${targetPath}`);
94
+ console.log("");
93
95
 
94
- copyDir(TEMPLATE_DIR, targetPath, false);
96
+ copyDir(TEMPLATE_DIR, targetPath, false);
95
97
 
96
- printNextSteps(targetArg);
97
- process.exit(0);
98
+ printNextSteps(targetArg);
99
+ process.exit(0);
98
100
  }
99
101
 
100
102
  // Unknown command
@@ -10,14 +10,15 @@ interface Props {
10
10
  description: string;
11
11
  heading: string;
12
12
  subheading?: string;
13
+ fontSubsetId?: string;
13
14
  }
14
15
 
15
- const { title, description, heading, subheading } = Astro.props;
16
+ const { title, description, heading, subheading, fontSubsetId } = Astro.props;
16
17
  const configEntries = await getCollection("config");
17
18
  const siteConfig = getSiteData(configEntries);
18
19
  ---
19
20
 
20
- <Stalux title={title + " | " + siteConfig.title} description={description}>
21
+ <Stalux title={title + " | " + siteConfig.title} description={description} fontSubsetId={fontSubsetId}>
21
22
  <div style="height: 3em;"></div>
22
23
  <Navs />
23
24
  <h1 class={styles.title}>{heading}</h1>
package/src/config.ts CHANGED
@@ -11,48 +11,48 @@ export type ComponentOverrideMap = Partial<Record<StaluxComponentKey, string>>;
11
11
 
12
12
  /** 内容集合路径配置 */
13
13
  export interface ContentPaths {
14
- /** 内容根目录,默认为 "stalux" */
15
- root?: string;
16
- /** 文章目录,相对于 root */
17
- posts?: string;
18
- /** 配置目录,相对于 root */
19
- config?: string;
20
- /** 关于页面目录,相对于 root */
21
- about?: string;
22
- /** 随想目录,相对于 root */
23
- words?: string;
14
+ /** 内容根目录,默认为 "stalux" */
15
+ root?: string;
16
+ /** 文章目录,相对于 root */
17
+ posts?: string;
18
+ /** 配置目录,相对于 root */
19
+ config?: string;
20
+ /** 关于页面目录,相对于 root */
21
+ about?: string;
22
+ /** 随想目录,相对于 root */
23
+ words?: string;
24
24
  }
25
25
 
26
26
  /** Analytics 配置 */
27
27
  export interface AnalyticsConfig {
28
- googleAnalyticsId?: string;
29
- bingClarityId?: string;
30
- umami?: {
31
- id: string;
32
- url: string;
33
- };
28
+ googleAnalyticsId?: string;
29
+ bingClarityId?: string;
30
+ umami?: {
31
+ id: string;
32
+ url: string;
33
+ };
34
34
  }
35
35
 
36
36
  /** Stalux 集成选项 */
37
37
  export interface StaluxOptions {
38
- /** 内容目录路径(默认 "stalux") */
39
- contentDir?: string;
38
+ /** 内容目录路径(默认 "stalux") */
39
+ contentDir?: string;
40
40
 
41
- /** 内容子目录路径覆盖 */
42
- contentPaths?: ContentPaths;
41
+ /** 内容子目录路径覆盖 */
42
+ contentPaths?: ContentPaths;
43
43
 
44
- /** 组件覆盖映射 */
45
- components?: ComponentOverrideMap;
44
+ /** 组件覆盖映射 */
45
+ components?: ComponentOverrideMap;
46
46
 
47
- /** Analytics 配置 */
48
- analytics?: AnalyticsConfig;
47
+ /** Analytics 配置 */
48
+ analytics?: AnalyticsConfig;
49
49
 
50
- /** 构建后是否自动运行 Pagefind 索引(默认 true) */
51
- pagefind?: boolean;
50
+ /** 构建后是否自动运行 Pagefind 索引(默认 true) */
51
+ pagefind?: boolean;
52
52
 
53
- /** 开发工具栏应用(默认 true) */
54
- devToolbar?: boolean;
53
+ /** 开发工具栏应用(默认 true) */
54
+ devToolbar?: boolean;
55
55
 
56
- /** 站点 URL(默认从 astro.config 读取) */
57
- site?: string;
56
+ /** 站点 URL(默认从 astro.config 读取) */
57
+ site?: string;
58
58
  }