astro-mermaid 1.0.2 → 1.0.4

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
@@ -85,10 +85,53 @@ mermaid({
85
85
  flowchart: {
86
86
  curve: 'basis'
87
87
  }
88
- }
88
+ },
89
+
90
+ // Register icon packs for use in diagrams
91
+ iconPacks: [
92
+ {
93
+ name: 'logos',
94
+ loader: () => fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then(res => res.json())
95
+ },
96
+ {
97
+ name: 'iconoir',
98
+ loader: () => fetch('https://unpkg.com/@iconify-json/iconoir@1/icons.json').then(res => res.json())
99
+ }
100
+ ]
89
101
  })
90
102
  ```
91
103
 
104
+ ## Icon Packs
105
+
106
+ You can register icon packs to use custom icons in your diagrams. Icon packs are loaded from Iconify JSON sources:
107
+
108
+ ```js
109
+ iconPacks: [
110
+ {
111
+ name: 'logos',
112
+ loader: () => fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then(res => res.json())
113
+ }
114
+ ]
115
+ ```
116
+
117
+ Then use icons in your diagrams:
118
+
119
+ ````markdown
120
+ ```mermaid
121
+ architecture-beta
122
+ group api(logos:aws-lambda)[API]
123
+
124
+ service db(logos:postgresql)[Database] in api
125
+ service disk1(logos:aws-s3)[Storage] in api
126
+ service disk2(logos:cloudflare)[CDN] in api
127
+ service server(logos:docker)[Server] in api
128
+
129
+ db:L -- R:server
130
+ disk1:T -- B:server
131
+ disk2:T -- B:db
132
+ ```
133
+ ````
134
+
92
135
  ## Theme Switching
93
136
 
94
137
  If `autoTheme` is enabled (default), the integration will automatically switch between themes based on your site's `data-theme` attribute:
@@ -1,5 +1,17 @@
1
1
  import type { AstroIntegration } from 'astro';
2
2
 
3
+ export interface IconPack {
4
+ /**
5
+ * Name of the icon pack
6
+ */
7
+ name: string;
8
+
9
+ /**
10
+ * Function that returns a promise resolving to the icon pack data
11
+ */
12
+ loader: () => Promise<any>;
13
+ }
14
+
3
15
  export interface AstroMermaidOptions {
4
16
  /**
5
17
  * Default mermaid theme
@@ -18,6 +30,20 @@ export interface AstroMermaidOptions {
18
30
  * @see https://mermaid.js.org/config/setup/modules/mermaidAPI.html#mermaidapi-configuration-defaults
19
31
  */
20
32
  mermaidConfig?: Record<string, any>;
33
+
34
+ /**
35
+ * Icon packs to register with mermaid
36
+ * @example
37
+ * ```js
38
+ * iconPacks: [
39
+ * {
40
+ * name: 'logos',
41
+ * loader: () => fetch('https://unpkg.com/@iconify-json/logos@1/icons.json').then(res => res.json())
42
+ * }
43
+ * ]
44
+ * ```
45
+ */
46
+ iconPacks?: IconPack[];
21
47
  }
22
48
 
23
49
  /**
@@ -1,6 +1,42 @@
1
1
  import { fileURLToPath } from 'node:url';
2
2
  import path from 'node:path';
3
3
 
4
+ /**
5
+ * Remark plugin to transform mermaid code blocks at the markdown level
6
+ */
7
+ function remarkMermaidPlugin(options = {}) {
8
+ return async function transformer(tree, file) {
9
+ const { visit } = await import('unist-util-visit');
10
+
11
+ let mermaidCount = 0;
12
+
13
+ visit(tree, 'code', (node, index, parent) => {
14
+ if (node.lang === 'mermaid') {
15
+ mermaidCount++;
16
+
17
+ // Transform to html node with pre.mermaid
18
+ const htmlNode = {
19
+ type: 'html',
20
+ value: `<pre class="mermaid">${node.value}</pre>`
21
+ };
22
+
23
+ // Replace the code node with html node
24
+ if (parent && typeof index === 'number') {
25
+ parent.children[index] = htmlNode;
26
+ }
27
+
28
+ if (options.logger) {
29
+ options.logger.info(`Remark transformed mermaid block #${mermaidCount} in ${file.path || 'unknown file'}`);
30
+ }
31
+ }
32
+ });
33
+
34
+ if (mermaidCount > 0 && options.logger) {
35
+ options.logger.info(`Remark total mermaid blocks transformed: ${mermaidCount}`);
36
+ }
37
+ };
38
+ }
39
+
4
40
  /**
5
41
  * Rehype plugin to transform mermaid code blocks
6
42
  * Converts ```mermaid code blocks to <pre class="mermaid">
@@ -39,14 +75,14 @@ function rehypeMermaidPlugin(options = {}) {
39
75
  }];
40
76
 
41
77
  if (options.logger) {
42
- options.logger.info(`Transformed mermaid block #${mermaidCount} in ${file.path || 'unknown file'}`);
78
+ options.logger.info(`Rehype transformed mermaid block #${mermaidCount} in ${file.path || 'unknown file'}`);
43
79
  }
44
80
  }
45
81
  }
46
82
  });
47
83
 
48
84
  if (mermaidCount > 0 && options.logger) {
49
- options.logger.info(`Total mermaid blocks transformed: ${mermaidCount}`);
85
+ options.logger.info(`Rehype total mermaid blocks transformed: ${mermaidCount}`);
50
86
  }
51
87
  };
52
88
  }
@@ -65,7 +101,8 @@ export default function astroMermaid(options = {}) {
65
101
  const {
66
102
  theme = 'default',
67
103
  autoTheme = true,
68
- mermaidConfig = {}
104
+ mermaidConfig = {},
105
+ iconPacks = []
69
106
  } = options;
70
107
 
71
108
  return {
@@ -77,9 +114,13 @@ export default function astroMermaid(options = {}) {
77
114
  // Log existing rehype plugins
78
115
  logger.info('Existing rehype plugins:', config.markdown?.rehypePlugins?.length || 0);
79
116
 
80
- // Update markdown config to use our rehype plugin
117
+ // Update markdown config to use both remark and rehype plugins
81
118
  updateConfig({
82
119
  markdown: {
120
+ remarkPlugins: [
121
+ ...(config.markdown?.remarkPlugins || []),
122
+ [remarkMermaidPlugin, { logger }]
123
+ ],
83
124
  rehypePlugins: [
84
125
  ...(config.markdown?.rehypePlugins || []),
85
126
  [rehypeMermaidPlugin, { logger }]
@@ -92,6 +133,12 @@ export default function astroMermaid(options = {}) {
92
133
  }
93
134
  });
94
135
 
136
+ // Serialize icon packs for client-side use
137
+ const iconPacksConfig = iconPacks.map(pack => ({
138
+ name: pack.name,
139
+ loader: pack.loader.toString()
140
+ }));
141
+
95
142
  // Inject client-side mermaid script with conditional loading
96
143
  const mermaidScriptContent = `
97
144
  // Check if page has mermaid diagrams
@@ -104,7 +151,17 @@ if (hasMermaidDiagrams()) {
104
151
  console.log('[astro-mermaid] Mermaid diagrams detected, loading mermaid.js...');
105
152
 
106
153
  // Dynamically import mermaid only when needed
107
- import('mermaid').then(({ default: mermaid }) => {
154
+ import('mermaid').then(async ({ default: mermaid }) => {
155
+ // Register icon packs if provided
156
+ const iconPacks = ${JSON.stringify(iconPacksConfig)};
157
+ if (iconPacks && iconPacks.length > 0) {
158
+ console.log('[astro-mermaid] Registering', iconPacks.length, 'icon packs');
159
+ const packs = iconPacks.map(pack => ({
160
+ name: pack.name,
161
+ loader: new Function('return ' + pack.loader)()
162
+ }));
163
+ await mermaid.registerIconPacks(packs);
164
+ }
108
165
  // Mermaid configuration
109
166
  const defaultConfig = ${JSON.stringify({
110
167
  startOnLoad: false,
@@ -129,13 +186,16 @@ if (hasMermaidDiagrams()) {
129
186
  return;
130
187
  }
131
188
 
132
- // Get current theme
189
+ // Get current theme from multiple sources
133
190
  let currentTheme = defaultConfig.theme;
134
191
 
135
192
  if (${autoTheme}) {
136
- const dataTheme = document.documentElement.getAttribute('data-theme');
193
+ // Check both html and body for data-theme attribute
194
+ const htmlTheme = document.documentElement.getAttribute('data-theme');
195
+ const bodyTheme = document.body.getAttribute('data-theme');
196
+ const dataTheme = htmlTheme || bodyTheme;
137
197
  currentTheme = themeMap[dataTheme] || defaultConfig.theme;
138
- console.log('[astro-mermaid] Using theme:', currentTheme);
198
+ console.log('[astro-mermaid] Using theme:', currentTheme, 'from', htmlTheme ? 'html' : 'body');
139
199
  }
140
200
 
141
201
  // Configure mermaid with gitGraph support
@@ -204,10 +264,15 @@ if (hasMermaidDiagrams()) {
204
264
  }
205
265
  });
206
266
 
267
+ // Observe both html and body for data-theme changes
207
268
  observer.observe(document.documentElement, {
208
269
  attributes: true,
209
270
  attributeFilter: ['data-theme']
210
271
  });
272
+ observer.observe(document.body, {
273
+ attributes: true,
274
+ attributeFilter: ['data-theme']
275
+ });
211
276
  }
212
277
 
213
278
  // Handle view transitions (for Astro View Transitions API)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-mermaid",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "An Astro integration for rendering Mermaid diagrams with automatic theme switching and client-side rendering",
5
5
  "type": "module",
6
6
  "main": "./astro-mermaid-integration.js",