@barzhsieh/nuxt-content-mermaid 2.1.3 → 2.2.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.
Files changed (87) hide show
  1. package/README.md +160 -1
  2. package/README.zh-TW.md +163 -1
  3. package/dist/module.d.mts +83 -1
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +28 -5
  6. package/dist/runtime/components/Mermaid.d.vue.ts +6 -4
  7. package/dist/runtime/components/Mermaid.vue +492 -36
  8. package/dist/runtime/components/Mermaid.vue.d.ts +6 -4
  9. package/dist/runtime/components/MermaidExpandOverlay.d.vue.ts +25 -0
  10. package/dist/runtime/components/MermaidExpandOverlay.vue +140 -0
  11. package/dist/runtime/components/MermaidExpandOverlay.vue.d.ts +25 -0
  12. package/dist/runtime/components/MermaidZoomToolbar.d.vue.ts +23 -0
  13. package/dist/runtime/components/MermaidZoomToolbar.vue +66 -0
  14. package/dist/runtime/components/MermaidZoomToolbar.vue.d.ts +23 -0
  15. package/dist/runtime/components/icons/IconClipboard.d.vue.ts +8 -0
  16. package/dist/runtime/components/icons/IconClipboard.vue +32 -0
  17. package/dist/runtime/components/icons/IconClipboard.vue.d.ts +8 -0
  18. package/dist/runtime/components/icons/IconClipboardHover.d.vue.ts +8 -0
  19. package/dist/runtime/components/icons/IconClipboardHover.vue +33 -0
  20. package/dist/runtime/components/icons/IconClipboardHover.vue.d.ts +8 -0
  21. package/dist/runtime/components/icons/IconClipboardSuccess.d.vue.ts +8 -0
  22. package/dist/runtime/components/icons/IconClipboardSuccess.vue +33 -0
  23. package/dist/runtime/components/icons/IconClipboardSuccess.vue.d.ts +8 -0
  24. package/dist/runtime/components/icons/IconCollapse.d.vue.ts +8 -0
  25. package/dist/runtime/components/icons/IconCollapse.vue +34 -0
  26. package/dist/runtime/components/icons/IconCollapse.vue.d.ts +8 -0
  27. package/dist/runtime/components/icons/IconExpand.d.vue.ts +8 -0
  28. package/dist/runtime/components/icons/IconExpand.vue +34 -0
  29. package/dist/runtime/components/icons/IconExpand.vue.d.ts +8 -0
  30. package/dist/runtime/components/icons/IconMinus.d.vue.ts +8 -0
  31. package/dist/runtime/components/icons/IconMinus.vue +46 -0
  32. package/dist/runtime/components/icons/IconMinus.vue.d.ts +8 -0
  33. package/dist/runtime/components/icons/IconPlus.d.vue.ts +8 -0
  34. package/dist/runtime/components/icons/IconPlus.vue +57 -0
  35. package/dist/runtime/components/icons/IconPlus.vue.d.ts +8 -0
  36. package/dist/runtime/components/icons/iconFullScreen.d.vue.ts +8 -0
  37. package/dist/runtime/components/icons/iconFullScreen.vue +26 -0
  38. package/dist/runtime/components/icons/iconFullScreen.vue.d.ts +8 -0
  39. package/dist/runtime/components/icons/iconFullScreenExit.d.vue.ts +8 -0
  40. package/dist/runtime/components/icons/iconFullScreenExit.vue +26 -0
  41. package/dist/runtime/components/icons/iconFullScreenExit.vue.d.ts +8 -0
  42. package/dist/runtime/composables/_configurable.d.ts +27 -0
  43. package/dist/runtime/composables/_configurable.js +5 -0
  44. package/dist/runtime/composables/shared/index.d.ts +5 -0
  45. package/dist/runtime/composables/shared/index.js +5 -0
  46. package/dist/runtime/composables/shared/tryOnMounted.d.ts +10 -0
  47. package/dist/runtime/composables/shared/tryOnMounted.js +11 -0
  48. package/dist/runtime/composables/shared/tryOnScopeDispose.d.ts +7 -0
  49. package/dist/runtime/composables/shared/tryOnScopeDispose.js +8 -0
  50. package/dist/runtime/composables/shared/watchImmediate.d.ts +5 -0
  51. package/dist/runtime/composables/shared/watchImmediate.js +11 -0
  52. package/dist/runtime/composables/unrefElement.d.ts +12 -0
  53. package/dist/runtime/composables/unrefElement.js +5 -0
  54. package/dist/runtime/composables/useEventListener.d.ts +73 -0
  55. package/dist/runtime/composables/useEventListener.js +40 -0
  56. package/dist/runtime/composables/useFullscreen.d.ts +25 -0
  57. package/dist/runtime/composables/useFullscreen.js +122 -0
  58. package/dist/runtime/composables/useMermaidCursors.d.ts +12 -0
  59. package/dist/runtime/composables/useMermaidCursors.js +41 -0
  60. package/dist/runtime/composables/useMermaidExpand.d.ts +45 -0
  61. package/dist/runtime/composables/useMermaidExpand.js +480 -0
  62. package/dist/runtime/composables/useMermaidZoom.d.ts +37 -0
  63. package/dist/runtime/composables/useMermaidZoom.js +261 -0
  64. package/dist/runtime/composables/useMounted.d.ts +8 -0
  65. package/dist/runtime/composables/useMounted.js +16 -0
  66. package/dist/runtime/composables/useSupported.d.ts +2 -0
  67. package/dist/runtime/composables/useSupported.js +10 -0
  68. package/dist/runtime/constants.d.ts +4 -0
  69. package/dist/runtime/constants.js +24 -0
  70. package/dist/runtime/mermaid-config.d.ts +1 -1
  71. package/dist/runtime/plugins/mermaid.client.d.ts +2 -2
  72. package/dist/runtime/styles.css +1 -0
  73. package/dist/runtime/types/expand.d.ts +48 -0
  74. package/dist/runtime/types/expand.js +0 -0
  75. package/dist/runtime/types/utils.d.ts +115 -0
  76. package/dist/runtime/types/utils.js +0 -0
  77. package/dist/runtime/utils/index.d.ts +52 -0
  78. package/dist/runtime/utils/index.js +113 -0
  79. package/dist/runtime/utils/is.d.ts +15 -0
  80. package/dist/runtime/utils/is.js +31 -0
  81. package/dist/runtime/utils/mermaid-transform.d.ts +18 -0
  82. package/dist/runtime/utils/mermaid-transform.js +345 -0
  83. package/dist/runtime/utils/vue.d.ts +2 -0
  84. package/dist/runtime/utils/vue.js +4 -0
  85. package/package.json +4 -2
  86. package/dist/runtime/utils.d.ts +0 -1
  87. package/dist/runtime/utils.js +0 -30
package/README.md CHANGED
@@ -105,6 +105,30 @@ export default defineNuxtConfig({
105
105
  spinner: undefined,
106
106
  error: undefined,
107
107
  },
108
+ toolbar: {
109
+ title: "mermaid",
110
+ fontSize: "14px",
111
+ fullscreenToolbarScale: 1.25,
112
+ buttons: {
113
+ copy: true,
114
+ fullscreen: true,
115
+ expand: true,
116
+ },
117
+ },
118
+ expand: {
119
+ enabled: true,
120
+ margin: 0,
121
+ invokeOpenOn: {
122
+ diagramClick: true,
123
+ },
124
+ invokeCloseOn: {
125
+ esc: true,
126
+ wheel: true,
127
+ swipe: true,
128
+ overlayClick: true,
129
+ closeButtonClick: true,
130
+ },
131
+ },
108
132
  },
109
133
  });
110
134
  ```
@@ -142,8 +166,95 @@ Color mode integration is automatic when `@nuxtjs/color-mode` is installed; manu
142
166
  | `components.spinner` | `string` | `undefined` | Optional: global loading spinner component name. |
143
167
  | `components.error` | `string` | `undefined` | Optional: global error component name when Mermaid rendering fails. |
144
168
 
169
+ **toolbar**
170
+
171
+ | Option | Type | Default | Description |
172
+ | :------------------------- | :----------------- | :------ | :------------------------------------------ |
173
+ | `toolbar.title` | `string` | `'mermaid'` | Default toolbar title for Mermaid blocks. |
174
+ | `toolbar.fontSize` | `string \| number` | `'14px'` | Default toolbar font size. |
175
+ | `toolbar.fullscreenToolbarScale` | `number` | `1.25` | Scale factor for toolbar font/icon size in fullscreen. |
176
+ | `toolbar.buttons.copy` | `boolean` | `true` | Show copy-source button in the toolbar. |
177
+ | `toolbar.buttons.fullscreen` | `boolean` | `true` | Show fullscreen button in the toolbar. |
178
+ | `toolbar.buttons.expand` | `boolean` | `true` | Show expand button in the toolbar. |
179
+
180
+ **expand**
181
+
182
+ Control SVG expand interactions. You can also set `expand: false` to disable it, or `expand: true` to use defaults.
183
+
184
+ | Option | Type | Default | Description |
185
+ | :------------------------- | :-------- | :------ | :------------------------------------------------------------------------- |
186
+ | `expand.enabled` | `boolean` | `true` | Enable or disable expand features entirely. |
187
+ | `expand.margin` | `number` | `0` | Margin (px) around the expanded SVG within the viewport. |
188
+ | `expand.invokeOpenOn.diagramClick` | `boolean` | `true` | Allow clicking the SVG to open expand overlay. |
189
+ | `expand.invokeCloseOn.esc` | `boolean` | `true` | Allow Escape key to close. |
190
+ | `expand.invokeCloseOn.wheel` | `boolean` | `true` | Allow mouse wheel to close. |
191
+ | `expand.invokeCloseOn.swipe` | `boolean` | `true` | Allow swipe gesture to close. |
192
+ | `expand.invokeCloseOn.overlayClick` | `boolean` | `true` | Allow clicking the overlay background to close. |
193
+ | `expand.invokeCloseOn.closeButtonClick`| `boolean`| `true` | Show the overlay close button. |
194
+
195
+ **Pan & Zoom (Expand Overlay / Fullscreen)**
196
+
197
+ When fullscreen or expand mode is active, users can pan and zoom the diagram:
198
+
199
+ | Interaction | Desktop | Mobile |
200
+ |:---|:---|:---|
201
+ | **Pan** | `Space` + Drag | 1-finger Drag |
202
+ | **Zoom** | `Ctrl/⌘` + Scroll | 2-finger Pinch |
203
+ | **Keyboard** | `+`/`-` to zoom, Arrow keys to pan, `0` to reset | — |
204
+
205
+ A zoom toolbar appears with +/−/Reset buttons and a percentage display.
206
+
207
+ Use `toolbar.fullscreenToolbarScale` to scale the fullscreen toolbar and zoom controls.
208
+
209
+
145
210
  > **Note**: All options can be overridden at runtime via `runtimeConfig.public.contentMermaid` (`runtimeConfig.public.mermaidContent` remains supported but deprecated).
146
211
 
212
+ ## Styling (CSS Variables)
213
+
214
+ This module ships global CSS variables (from `runtime/styles.css`) so the Mermaid wrapper and expand overlay share the same palette. You can override them in your app:
215
+
216
+ ```css
217
+ :root {
218
+ --ncm-code-bg: #f3f4f6;
219
+ --ncm-code-bg-hover: #e5e7eb;
220
+ --ncm-border: #e5e7eb;
221
+ --ncm-text: #111827;
222
+ --ncm-text-muted: #4b5563;
223
+ --ncm-text-xmuted: #6b7280;
224
+ --ncm-overlay-bg: rgba(255, 255, 255, 0.98);
225
+ }
226
+
227
+ html[data-theme="dark"],
228
+ .dark {
229
+ --ncm-code-bg: #111827;
230
+ --ncm-code-bg-hover: #1f2937;
231
+ --ncm-border: #1f2937;
232
+ --ncm-text: #f9fafb;
233
+ --ncm-text-muted: #9ca3af;
234
+ --ncm-text-xmuted: #6b7280;
235
+ --ncm-overlay-bg: rgba(17, 24, 39, 0.98);
236
+ }
237
+ ```
238
+
239
+ Variables:
240
+ - `--ncm-code-bg`: Mermaid block background.
241
+ - `--ncm-code-bg-hover`: Hover background for toolbar buttons.
242
+ - `--ncm-border-color`: Border color for the block and toolbar.
243
+ - `--ncm-border-width`: Border thickness.
244
+ - `--ncm-border-style`: Border style.
245
+ - `--ncm-border`: Composite shorthand (width, style, color) for borders.
246
+ - `--ncm-border-bottom`: Border style applied to the toolbar bottom.
247
+ - `--ncm-text`: Primary text color.
248
+ - `--ncm-text-muted`: Title and secondary text.
249
+ - `--ncm-text-xmuted`: Toolbar icon and subtle UI text.
250
+ - `--ncm-overlay-bg`: Expand overlay background (defaults to `--ncm-code-bg`).
251
+ - `--ncm-expand-target-bg`: Background color shown behind the expanded SVG when `expand.margin` leaves breathing room.
252
+ - `--ncm-overlay-opacity`: Overlay transparency (thinned when `expand.margin` creates breathing room).
253
+ - `--ncm-overlay-backdrop`: `backdrop-filter` applied to the overlay when it becomes visible.
254
+ - `--ncm-hint-bg`: Zoom hint toast background (default: `rgba(0,0,0,0.75)`).
255
+ - `--ncm-hint-text`: Zoom hint toast text color (default: `#fff`).
256
+ - `--ncm-hint-radius`: Zoom hint toast border radius (default: `8px`).
257
+
147
258
  ## Advanced Usage
148
259
 
149
260
  ### Debug mode
@@ -231,9 +342,57 @@ The actual priority order when settings take effect is as follows:
231
342
  2. **Frontmatter `config`** — merged on top of the module's `loader.init`.
232
343
  3. **Module-level `contentMermaid.loader.init`** — Project default settings.
233
344
 
345
+ ### Mermaid Inline Attributes & YAML Frontmatter
346
+
347
+ You can control Mermaid blocks in three ways: inline attrs, Mermaid YAML frontmatter, and `%%{init}%%` directives.
348
+
349
+ #### Inline attrs (fence info)
350
+
351
+ Use inline attrs on the `mermaid` fence to pass props to the wrapper component or set Mermaid YAML fields (including `toolbar` options like title/fontSize and `toolbar.buttons.*`).
352
+
353
+ ````markdown
354
+ ```mermaid {title="Diagram A" toolbar='{"title":"My Diagram","fontSize":"14px"}' config='{"theme":"dark"}'}
355
+ graph TD
356
+ A --> B
357
+ ```
358
+ ````
359
+
360
+ #### Mermaid YAML frontmatter (inside the block)
361
+
362
+ Place Mermaid’s own YAML frontmatter at the top of the code block to affect SVG rendering (e.g. title, displayMode, config), and you can also provide `toolbar` values for the wrapper component (including `toolbar.buttons.copy: true`).
363
+
364
+ ````markdown
365
+ ```mermaid
366
+ ---
367
+ title: Sample Flowchart
368
+ displayMode: compact
369
+ config:
370
+ theme: dark
371
+ toolbar:
372
+ title: "Sample Diagram"
373
+ buttons:
374
+ copy: true
375
+ ---
376
+ graph TD
377
+ A --> B
378
+ ```
379
+ ````
380
+
381
+ #### `%%{init}%%` directive (inside the block)
382
+
383
+ Use Mermaid directives to set render options directly in the diagram definition.
384
+
385
+ ````markdown
386
+ ```mermaid
387
+ %%{init: { 'theme': 'forest', 'flowchart': { 'curve': 'step' } }}%%
388
+ graph TD
389
+ A --> B
390
+ ```
391
+ ````
392
+
234
393
  ### Custom Rendering Component
235
394
 
236
- If you want full control over rendering (for example to add a border, zoom controls, or other UI), you can provide a custom component via `components.renderer`.
395
+ If you want full control over rendering (for example to add a border, expand controls, or other UI), you can provide a custom component via `components.renderer`.
237
396
 
238
397
  1. Specify the component name in `nuxt.config.ts`:
239
398
 
package/README.zh-TW.md CHANGED
@@ -105,6 +105,30 @@ export default defineNuxtConfig({
105
105
  spinner: undefined,
106
106
  error: undefined,
107
107
  },
108
+ toolbar: {
109
+ title: "mermaid",
110
+ fontSize: "14px",
111
+ fullscreenToolbarScale: 1.25,
112
+ buttons: {
113
+ copy: true,
114
+ fullscreen: true,
115
+ expand: true,
116
+ },
117
+ },
118
+ expand: {
119
+ enabled: true,
120
+ margin: 0,
121
+ invokeOpenOn: {
122
+ diagramClick: true,
123
+ },
124
+ invokeCloseOn: {
125
+ esc: true,
126
+ wheel: true,
127
+ swipe: true,
128
+ overlayClick: true,
129
+ closeButtonClick: true,
130
+ },
131
+ },
108
132
  },
109
133
  });
110
134
  ```
@@ -142,8 +166,96 @@ export default defineNuxtConfig({
142
166
  | `components.spinner` | `string` | `undefined` | 指定全域的 Loading 元件名稱。 |
143
167
  | `components.error` | `string` | `undefined` | 指定全域的錯誤顯示元件名稱,渲染失敗時會使用。 |
144
168
 
169
+ **toolbar**
170
+
171
+ | 參數 | 類型 | 預設值 | 說明 |
172
+ | :---------------------- | :----------------- | :----- | :------------------------------------- |
173
+ | `toolbar.title` | `string` | `'mermaid'` | Mermaid 工具列預設標題。 |
174
+ | `toolbar.fontSize` | `string \| number` | `'14px'` | Mermaid 工具列預設字體大小。 |
175
+ | `toolbar.fullscreenToolbarScale` | `number` | `1.25` | fullscreen 時工具列字體/圖示的放大倍率。 |
176
+ | `toolbar.buttons.copy` | `boolean` | `true` | 顯示工具列複製原始 Mermaid 的按鈕。 |
177
+ | `toolbar.buttons.fullscreen` | `boolean` | `true` | 顯示工具列全螢幕按鈕。 |
178
+ | `toolbar.buttons.expand` | `boolean` | `true` | 顯示工具列放大按鈕。 |
179
+
180
+ **expand**
181
+
182
+ 控制 SVG 放大互動行為,也可直接設為 `expand: false` 來停用,或 `expand: true` 使用預設值。
183
+
184
+ | 參數 | 類型 | 預設值 | 說明 |
185
+ | :------------------------ | :-------- | :----- | :------------------------------------------------------- |
186
+ | `expand.enabled` | `boolean` | `true` | 是否啟用放大功能。 |
187
+ | `expand.margin` | `number` | `0` | 放大後 SVG 在視窗內保留的邊距(px)。 |
188
+ | `expand.invokeOpenOn.diagramClick` | `boolean` | `true` | 允許直接點擊 SVG 開啟放大。 |
189
+ | `expand.invokeCloseOn.esc` | `boolean` | `true` | 允許按 ESC 關閉。 |
190
+ | `expand.invokeCloseOn.wheel` | `boolean` | `true` | 允許滑鼠滾輪關閉。 |
191
+ | `expand.invokeCloseOn.swipe` | `boolean` | `true` | 允許滑動手勢關閉。 |
192
+ | `expand.invokeCloseOn.overlayClick` | `boolean` | `true` | 允許點擊 overlay 背景關閉。 |
193
+ | `expand.invokeCloseOn.closeButtonClick`| `boolean` | `true` | 顯示 overlay 關閉按鈕。 |
194
+
195
+ **平移與縮放 (Expand Overlay / Fullscreen)**
196
+
197
+ 當放大 Fullscreen 或是 Expand 模式時,使用者可平移與縮放圖表:
198
+
199
+ | 操作 | 桌機 | 行動裝置 |
200
+ |:---|:---|:---|
201
+ | **平移 (Pan)** | `Space` + 拖曳 | 單指拖曳 |
202
+ | **縮放 (Zoom)** | `Ctrl/⌘` + 滾輪 | 雙指捏合 |
203
+ | **鍵盤** | `+`/`-` 縮放、方向鍵平移、`0` 重置 | — |
204
+
205
+ 放大介面會顯示縮放工具列,包含 +/−/Reset 按鈕與百分比顯示。
206
+
207
+ 可透過 `toolbar.fullscreenToolbarScale` 調整 Fullscreen 工具列與縮放控制的尺寸。
208
+
209
+
145
210
  > **Note**: 所有設定皆可透過 `runtimeConfig.public.contentMermaid` 在部署時進行覆寫(`runtimeConfig.public.mermaidContent` 仍支援但已棄用)。
146
211
 
212
+ ## 樣式自訂(CSS 變數)
213
+
214
+ 模組會提供全域 CSS 變數(來源為 `runtime/styles.css`),讓 Mermaid 區塊與放大 overlay 使用同一套配色。你可以在專案中覆寫:
215
+
216
+ ```css
217
+ :root {
218
+ --ncm-code-bg: #f3f4f6;
219
+ --ncm-code-bg-hover: #e5e7eb;
220
+ --ncm-border: #e5e7eb;
221
+ --ncm-text: #111827;
222
+ --ncm-text-muted: #4b5563;
223
+ --ncm-text-xmuted: #6b7280;
224
+ --ncm-overlay-bg: rgba(255, 255, 255, 0.98);
225
+ }
226
+
227
+ html[data-theme="dark"],
228
+ .dark {
229
+ --ncm-code-bg: #111827;
230
+ --ncm-code-bg-hover: #1f2937;
231
+ --ncm-border: #1f2937;
232
+ --ncm-text: #f9fafb;
233
+ --ncm-text-muted: #9ca3af;
234
+ --ncm-text-xmuted: #6b7280;
235
+ --ncm-overlay-bg: rgba(17, 24, 39, 0.98);
236
+ }
237
+ ```
238
+
239
+ 可覆寫的變數:
240
+ 可覆寫的變數:
241
+ - `--ncm-code-bg`:Mermaid 區塊背景色
242
+ - `--ncm-code-bg-hover`:工具列按鈕 hover 背景
243
+ - `--ncm-border-color`:區塊與工具列的邊框顏色
244
+ - `--ncm-border-width`:邊框厚度
245
+ - `--ncm-border-style`:邊框樣式
246
+ - `--ncm-border`:邊框 shorthand(寬度、樣式、顏色)
247
+ - `--ncm-border-bottom`:工具列底部的邊框
248
+ - `--ncm-text`:主要文字顏色
249
+ - `--ncm-text-muted`:標題與次要文字
250
+ - `--ncm-text-xmuted`:工具列 icon 與更淡的文字
251
+ - `--ncm-overlay-bg`:放大 overlay 背景(預設跟 `--ncm-code-bg` 一致)
252
+ - `--ncm-expand-target-bg`:當 `expand.margin > 0` 時,放大後留白的 SVG 外框背景,可以與 overlay 做出區隔
253
+ - `--ncm-overlay-opacity`:overlay 的透明度(搭配 margin 留白時可微調濃淡)
254
+ - `--ncm-overlay-backdrop`:顯示 overlay 時加上的 `backdrop-filter`,可自訂 blur/效果
255
+ - `--ncm-hint-bg`:縮放提示訊息背景色(預設 `rgba(0,0,0,0.75)`)
256
+ - `--ncm-hint-text`:縮放提示訊息文字顏色(預設 `#fff`)
257
+ - `--ncm-hint-radius`:縮放提示訊息圓角(預設 `8px`)
258
+
147
259
  ## Advanced Usage
148
260
 
149
261
  ### Debug 模式
@@ -233,9 +345,59 @@ graph TD
233
345
  2. **frontmatter `config`** —— 深度合併在模組的 `loader.init` 之上。
234
346
  3. **模組層級的 `contentMermaid.loader.init`** —— 專案的全域預設。
235
347
 
348
+ ### Mermaid Inline attrs 與 YAML Frontmatter
349
+
350
+ 支援三種方式控制 Mermaid Svg 的渲染:inline attrs、Mermaid YAML frontmatter、`%%{init}%%` 指令。
351
+
352
+ #### Inline attrs(fence info)
353
+
354
+ 在 `mermaid` fence 上使用 inline attrs,傳遞 wrapper props 或設定 Mermaid 的 YAML 欄位(包含 `toolbar` 的 title/fontSize 與 `toolbar.buttons.*`)。
355
+
356
+ ````markdown
357
+ ```mermaid {title="Diagram A" toolbar='{"title":"My Diagram","fontSize":"14px"}' config='{"theme":"dark"}'}
358
+ graph TD
359
+ A --> B
360
+ ```
361
+ ````
362
+
363
+ #### Mermaid YAML frontmatter(block 內)
364
+
365
+ 把 Mermaid 的 YAML frontmatter 放在 code block 最前面,用來影響 SVG 輸出(例如 title、displayMode、config),也可以提供 `toolbar` 給 wrapper 元件(包含 `toolbar.buttons.copy: true`)。
366
+
367
+ ````markdown
368
+ ```mermaid
369
+ ---
370
+ title: Sample Flowchart
371
+ displayMode: compact
372
+ config:
373
+ theme: dark
374
+ toolbar:
375
+ title: "Sample Diagram"
376
+ buttons:
377
+ copy: true
378
+ expand: true
379
+ fullscreen: false
380
+ ---
381
+ graph TD
382
+ A --> B
383
+ ```
384
+ ````
385
+
386
+ #### `%%{init}%%` 指令(block 內)
387
+
388
+ 使用 Mermaid directive,直接在圖表定義內設定渲染選項。
389
+
390
+ ````markdown
391
+ ```mermaid
392
+ %%{init: { 'theme': 'forest', 'flowchart': { 'curve': 'step' } }}%%
393
+ graph TD
394
+ A --> B
395
+ ```
396
+ ````
397
+
236
398
  ### 自訂渲染元件 (Custom Component)
237
399
 
238
- 若需完全接管 Mermaid 的渲染行為(例如:加入外框、ZoomIn/Out 功能),可指定 `components.renderer`。
400
+ 若需完全接管 Mermaid 的渲染行為(例如:加入外框、Expand/Collapse 功能),可指定 `components.renderer`。
239
401
 
240
402
  1. 在 `nuxt.config.ts` 中指定元件名稱:
241
403
 
package/dist/module.d.mts CHANGED
@@ -1,5 +1,76 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
- import { MermaidConfig } from 'mermaid';
2
+ import { Mermaid, MermaidConfig } from 'mermaid';
3
+ import { ExpandOptions } from '../dist/runtime/types/expand.js';
4
+ import { DefineComponent } from 'vue';
5
+
6
+ type MermaidToolbarButtons = {
7
+ copy?: boolean
8
+ fullscreen?: boolean
9
+ expand?: boolean
10
+ }
11
+
12
+ type MermaidToolbarOptions = {
13
+ title?: string
14
+ fontSize?: string | number
15
+ fullscreenToolbarScale?: number
16
+ buttons?: MermaidToolbarButtons
17
+ }
18
+
19
+ declare module '#app' {
20
+ interface NuxtApp {
21
+ $mermaid: () => Promise<Mermaid>
22
+ }
23
+ }
24
+ declare module 'vue' {
25
+ interface ComponentCustomProperties {
26
+ $mermaid: () => Promise<Mermaid>
27
+ }
28
+ interface GlobalComponents {
29
+ Mermaid: DefineComponent<{
30
+ config?: MermaidConfig
31
+ toolbar?: MermaidToolbarOptions
32
+ code?: string
33
+ }>
34
+ }
35
+ }
36
+
37
+ declare module 'nuxt/schema' {
38
+ interface NuxtConfig {
39
+ contentMermaid?: ModuleOptions
40
+ /**
41
+ * @deprecated Use `contentMermaid`
42
+ */
43
+ mermaidContent?: ModuleOptions
44
+ }
45
+
46
+ interface NuxtOptions {
47
+ contentMermaid?: ModuleOptions
48
+ /**
49
+ * @deprecated Use `contentMermaid`
50
+ */
51
+ mermaidContent?: ModuleOptions
52
+ }
53
+
54
+ interface PublicRuntimeConfig {
55
+ contentMermaid?: Partial<ModuleOptions>
56
+ /**
57
+ * @deprecated Use `contentMermaid`
58
+ */
59
+ mermaidContent?: Partial<ModuleOptions>
60
+ }
61
+ }
62
+
63
+ declare global {
64
+ interface ImportMeta {
65
+ glob<T = unknown>(
66
+ pattern: string,
67
+ options?: {
68
+ eager?: boolean
69
+ import?: string
70
+ },
71
+ ): Record<string, () => Promise<T>>
72
+ }
73
+ }
3
74
 
4
75
  interface ModuleOptions {
5
76
  /**
@@ -64,6 +135,17 @@ interface ModuleOptions {
64
135
  */
65
136
  error?: string;
66
137
  };
138
+ /**
139
+ * Options related to SVG expand (lightbox) interactions
140
+ */
141
+ /**
142
+ * Expand configuration. `false` disables expand, `true` uses defaults.
143
+ */
144
+ expand?: ExpandOptions | boolean;
145
+ /**
146
+ * Default toolbar settings for Mermaid component
147
+ */
148
+ toolbar?: MermaidToolbarOptions;
67
149
  }
68
150
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
69
151
 
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.20.1 || ^4.1.0"
6
6
  },
7
- "version": "2.1.3",
7
+ "version": "2.2.1",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,6 +1,8 @@
1
1
  import { defineNuxtModule, useLogger, createResolver, addVitePlugin, addPlugin, addComponent, addImports, addTypeTemplate } from '@nuxt/kit';
2
2
  import { defu } from 'defu';
3
- import { DEFAULT_MERMAID_CONFIG, DEFAULT_DARK_THEME, DEFAULT_LIGHT_THEME, DEFAULT_FRONTMATTER_CONFIG_KEY } from '../dist/runtime/constants.js';
3
+ import { DEFAULT_MERMAID_CONFIG, DEFAULT_TOOLBAR_OPTIONS, DEFAULT_EXPAND_OPTIONS, DEFAULT_DARK_THEME, DEFAULT_LIGHT_THEME, DEFAULT_FRONTMATTER_CONFIG_KEY } from '../dist/runtime/constants.js';
4
+ import { parseInlineAttrs, parseMermaidFrontmatter, extractMermaidInlineOverrides, applyMermaidFrontmatterOverrides, mergeToolbarProps, extractToolbarProps } from '../dist/runtime/utils/mermaid-transform.js';
5
+ import { isNonEmptyRecord, stringifyInlineValue } from '../dist/runtime/utils/index.js';
4
6
 
5
7
  const SANITIZE_URL_PACKAGE = "@braintree/sanitize-url";
6
8
  const MERMAID_FENCE_RE = /^[ \t]*(?:`{3,}|~{3,})[ \t]*mermaid(?:$|[ \t{[])/im;
@@ -18,7 +20,9 @@ const DEFAULTS = {
18
20
  renderer: void 0,
19
21
  spinner: void 0,
20
22
  error: void 0
21
- }
23
+ },
24
+ expand: DEFAULT_EXPAND_OPTIONS,
25
+ toolbar: DEFAULT_TOOLBAR_OPTIONS
22
26
  };
23
27
  const module$1 = defineNuxtModule({
24
28
  meta: {
@@ -46,6 +50,8 @@ const module$1 = defineNuxtModule({
46
50
  );
47
51
  const resolver = createResolver(import.meta.url);
48
52
  const runtimeDir = resolver.resolve("./runtime");
53
+ nuxt.options.css ||= [];
54
+ nuxt.options.css.push(resolver.resolve("./runtime/styles.css"));
49
55
  const publicRuntimeConfig = nuxt.options.runtimeConfig.public;
50
56
  const runtimeOverrides = publicRuntimeConfig.contentMermaid || publicRuntimeConfig.mermaidContent || {};
51
57
  if (!publicRuntimeConfig.contentMermaid && publicRuntimeConfig.mermaidContent)
@@ -159,7 +165,16 @@ function transformMermaidCodeBlocks(body, componentName, frontmatterConfigKey =
159
165
  const next = lower.slice("mermaid".length, "mermaid".length + 1);
160
166
  return next === "" || /\s/.test(next) || next === "{" || next === "[";
161
167
  };
162
- const buildComponentTag = (encoded) => `<${componentName} :config="${frontmatterConfigKey}" code="${encoded}"></${componentName}>`;
168
+ const buildComponentTag = (encoded, toolbar) => {
169
+ const attrs = [
170
+ `:config="${frontmatterConfigKey}"`
171
+ ];
172
+ if (toolbar && isNonEmptyRecord(toolbar)) {
173
+ attrs.push(`:toolbar='${stringifyInlineValue(toolbar)}'`);
174
+ }
175
+ attrs.push(`code="${encoded}"`);
176
+ return `<${componentName} ${attrs.join(" ")}></${componentName}>`;
177
+ };
163
178
  for (let index = 0; index < lines.length; index++) {
164
179
  const line = lines[index];
165
180
  if (inFence) {
@@ -210,8 +225,16 @@ function transformMermaidCodeBlocks(body, componentName, frontmatterConfigKey =
210
225
  index = closingIndex;
211
226
  continue;
212
227
  }
213
- const encoded = encodeURIComponent(code);
214
- output.push(`${fence.indent}${buildComponentTag(encoded)}`);
228
+ const inlineAttrs = parseInlineAttrs(fence.info);
229
+ const frontmatterInfo = parseMermaidFrontmatter(rawCode, newline);
230
+ const inlineOverrides = extractMermaidInlineOverrides(inlineAttrs);
231
+ const mergedCode = inlineOverrides ? applyMermaidFrontmatterOverrides(rawCode, newline, frontmatterInfo, inlineOverrides, fence.indent) : rawCode;
232
+ const toolbarProps = mergeToolbarProps(
233
+ extractToolbarProps(frontmatterInfo?.data),
234
+ extractToolbarProps(inlineAttrs)
235
+ );
236
+ const encoded = encodeURIComponent(mergedCode.trim());
237
+ output.push(`${fence.indent}${buildComponentTag(encoded, toolbarProps)}`);
215
238
  index = closingIndex;
216
239
  }
217
240
  return output.join(newline);
@@ -1,9 +1,11 @@
1
1
  import type { MermaidConfig } from 'mermaid';
2
+ import type { MermaidToolbarOptions } from '~/src/types/mermaid';
2
3
  type __VLS_Props = {
3
4
  config?: MermaidConfig | string | unknown;
5
+ toolbar?: MermaidToolbarOptions;
4
6
  code?: string;
5
7
  };
6
- declare var __VLS_1: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {}, __VLS_21: {
8
+ declare var __VLS_1: {}, __VLS_9: {}, __VLS_52: {}, __VLS_54: {}, __VLS_62: {
7
9
  error: unknown;
8
10
  source: string;
9
11
  };
@@ -12,11 +14,11 @@ type __VLS_Slots = {} & {
12
14
  } & {
13
15
  default?: (props: typeof __VLS_9) => any;
14
16
  } & {
15
- default?: (props: typeof __VLS_11) => any;
17
+ default?: (props: typeof __VLS_52) => any;
16
18
  } & {
17
- loading?: (props: typeof __VLS_13) => any;
19
+ loading?: (props: typeof __VLS_54) => any;
18
20
  } & {
19
- error?: (props: typeof __VLS_21) => any;
21
+ error?: (props: typeof __VLS_62) => any;
20
22
  };
21
23
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
24
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;