@matfsw/docusaurus-plantuml-plugin 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.
Files changed (40) hide show
  1. package/CHANGELOG.md +99 -1
  2. package/README.md +150 -18
  3. package/assets/stdlib/LICENSES.md +21 -0
  4. package/assets/stdlib/archimate.min.js +22 -0
  5. package/assets/stdlib/azure.min.js +305 -0
  6. package/assets/stdlib/c4.min.js +47 -0
  7. package/assets/stdlib/cloudinsight.min.js +93 -0
  8. package/assets/stdlib/eip.min.js +14 -0
  9. package/assets/stdlib/k8s.min.js +52 -0
  10. package/assets/stdlib/kubernetes.min.js +17 -0
  11. package/assets/stdlib/manifest.json +112 -0
  12. package/assets/stdlib/office.min.js +557 -0
  13. package/dist/index.cjs +380 -7
  14. package/dist/index.d.cts +86 -3
  15. package/dist/index.d.ts +12 -2
  16. package/dist/index.js +20 -1
  17. package/dist/options.d.ts +52 -1
  18. package/dist/options.js +81 -0
  19. package/dist/runtime/assetLoader.d.ts +13 -1
  20. package/dist/runtime/assetLoader.js +36 -13
  21. package/dist/runtime/cache.d.ts +6 -1
  22. package/dist/runtime/cache.js +2 -2
  23. package/dist/runtime/errors.d.ts +3 -1
  24. package/dist/runtime/errors.js +27 -1
  25. package/dist/runtime/renderer.d.ts +3 -0
  26. package/dist/runtime/renderer.js +21 -7
  27. package/dist/runtime/stdlibLoader.d.ts +31 -0
  28. package/dist/runtime/stdlibLoader.js +99 -0
  29. package/dist/stdlib.d.ts +35 -0
  30. package/dist/stdlib.js +163 -0
  31. package/dist/stdlibBundle.d.ts +60 -0
  32. package/dist/stdlibBundle.js +218 -0
  33. package/dist/stdlibShared.d.ts +51 -0
  34. package/dist/stdlibShared.js +54 -0
  35. package/dist/theme/PlantUmlDiagram/icons.d.ts +38 -0
  36. package/dist/theme/PlantUmlDiagram/icons.js +44 -0
  37. package/dist/theme/PlantUmlDiagram/index.js +5 -3
  38. package/dist/theme/usePlantUmlConfig.d.ts +8 -0
  39. package/dist/theme/usePlantUmlConfig.js +14 -8
  40. package/package.json +3 -1
@@ -7,6 +7,7 @@ import { PlantUmlError } from '../../runtime/errors.js';
7
7
  import { renderGraphvizDiagram } from '../../runtime/graphvizRenderer.js';
8
8
  import { renderDiagram } from '../../runtime/renderer.js';
9
9
  import { usePlantUmlConfig } from '../usePlantUmlConfig.js';
10
+ import { CloseIcon, MaximizeIcon, ResetZoomIcon, SourceIcon, ZoomInIcon, ZoomOutIcon, } from './icons.js';
10
11
  import { useZoomPan } from './useZoomPan.js';
11
12
  import styles from './styles.module.css';
12
13
  /**
@@ -170,7 +171,7 @@ export default function PlantUmlDiagram({ source, title, language, engine = 'pla
170
171
  transparentBackground: options.graphviz.transparentBackground,
171
172
  maxSourceBytes: options.graphviz.maxSourceBytes,
172
173
  })
173
- : renderDiagram({ ...shared, dark: renderDark });
174
+ : renderDiagram({ ...shared, dark: renderDark, stdlib: config.stdlib });
174
175
  void pending
175
176
  .then((svg) => commit({ status: 'ready', svg, error: null }))
176
177
  .catch((error) => {
@@ -190,6 +191,7 @@ export default function PlantUmlDiagram({ source, title, language, engine = 'pla
190
191
  config,
191
192
  config?.assetsBaseUrl,
192
193
  config?.coreVersion,
194
+ config?.stdlib,
193
195
  config?.options.sanitizeSvg,
194
196
  config?.options.renderTimeoutMs,
195
197
  config?.options.cache,
@@ -205,7 +207,7 @@ export default function PlantUmlDiagram({ source, title, language, engine = 'pla
205
207
  // Sanitized above unless `sanitizeSvg: false` was explicitly opted into.
206
208
  dangerouslySetInnerHTML: { __html: state.svg } }));
207
209
  const copyControl = sourceAvailable && sourceOpen && state.status === 'ready' && (_jsx("button", { type: "button", className: `${styles.toolbarButton} ${styles.toolbarTextButton}`, "aria-label": `Copy ${engineName} source to clipboard`, onClick: copySource, children: "Copy" }));
208
- const sourceToggle = sourceAvailable && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": sourceOpen ? 'Hide diagram source' : 'Show diagram source', "aria-expanded": sourceOpen, "aria-controls": sourcePanelId, onClick: () => setSourceOpen((open) => !open), children: _jsx("span", { "aria-hidden": "true", children: '</>' }) }));
210
+ const sourceToggle = sourceAvailable && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": sourceOpen ? 'Hide diagram source' : 'Show diagram source', "aria-expanded": sourceOpen, "aria-controls": sourcePanelId, onClick: () => setSourceOpen((open) => !open), children: _jsx(SourceIcon, {}) }));
209
211
  /**
210
212
  * The source *replaces the diagram in its own frame* rather than appearing beneath it.
211
213
  *
@@ -223,7 +225,7 @@ export default function PlantUmlDiagram({ source, title, language, engine = 'pla
223
225
  [DATA_ATTR.theme]: dark ? 'dark' : 'light',
224
226
  ...(interactive ? { [DATA_ATTR.interactive]: 'true' } : {}),
225
227
  ...(zoom.maximized ? { [DATA_ATTR.maximized]: 'true' } : {}),
226
- ...(sourceOpen ? { [DATA_ATTR.sourceOpen]: 'true' } : {}), children: [state.status === 'ready' && state.svg !== null && !interactive && canvas, state.status === 'ready' && state.svg !== null && !interactive && sourceView, state.status === 'ready' && state.svg !== null && !interactive && sourceAvailable && (_jsxs("div", { className: styles.plainToolbar, role: "group", "aria-label": `${label} source controls`, children: [sourceToggle, copyControl] })), state.status === 'ready' && state.svg !== null && interactive && (_jsxs("div", { ref: zoom.stageRef, className: zoom.maximized ? `${styles.stage} ${styles.maximized}` : styles.stage, children: [_jsxs("div", { className: styles.stageBody, children: [_jsx("div", { ref: zoom.viewportRef, className: sourceOpen ? `${styles.viewport} ${styles.invisibleView}` : styles.viewport, tabIndex: sourceOpen ? -1 : 0, "aria-describedby": hintId, "aria-keyshortcuts": "Plus Minus 0 ArrowUp ArrowDown ArrowLeft ArrowRight", onKeyDown: zoom.onKeyDown, [DATA_ATTR.zoom]: '1', children: _jsx("div", { ref: zoom.layerRef, className: styles.layer, children: canvas }) }), sourceView] }), _jsxs("div", { className: styles.toolbar, role: "group", "aria-label": `${label} zoom controls`, children: [!sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Zoom out", onClick: zoom.zoomOut, children: _jsx("span", { "aria-hidden": "true", children: "\u2212" }) })), !sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Zoom in", onClick: zoom.zoomIn, children: _jsx("span", { "aria-hidden": "true", children: "+" }) })), !sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Reset zoom", onClick: zoom.reset, children: _jsx("span", { "aria-hidden": "true", children: "\u27F2" }) })), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Maximize diagram", "aria-pressed": zoom.maximized, onClick: zoom.toggleMaximize, children: _jsx("span", { "aria-hidden": "true", children: zoom.maximized ? '✕' : '⛶' }) }), sourceToggle, copyControl, _jsx("span", { ref: zoom.readoutRef, className: sourceOpen ? `${styles.readout} ${styles.hiddenView}` : styles.readout, "aria-hidden": "true", children: "100%" })] })] })), state.status === 'ready' && state.svg !== null && interactive && (_jsx("p", { id: hintId, className: styles.visuallyHidden, children: "Zoomable diagram. Use the zoom controls, or press plus and minus to zoom, the arrow keys to pan, and zero to reset." })), state.status !== 'ready' && state.status !== 'error' && (
228
+ ...(sourceOpen ? { [DATA_ATTR.sourceOpen]: 'true' } : {}), children: [state.status === 'ready' && state.svg !== null && !interactive && canvas, state.status === 'ready' && state.svg !== null && !interactive && sourceView, state.status === 'ready' && state.svg !== null && !interactive && sourceAvailable && (_jsxs("div", { className: styles.plainToolbar, role: "group", "aria-label": `${label} source controls`, children: [sourceToggle, copyControl] })), state.status === 'ready' && state.svg !== null && interactive && (_jsxs("div", { ref: zoom.stageRef, className: zoom.maximized ? `${styles.stage} ${styles.maximized}` : styles.stage, children: [_jsxs("div", { className: styles.stageBody, children: [_jsx("div", { ref: zoom.viewportRef, className: sourceOpen ? `${styles.viewport} ${styles.invisibleView}` : styles.viewport, tabIndex: sourceOpen ? -1 : 0, "aria-describedby": hintId, "aria-keyshortcuts": "Plus Minus 0 ArrowUp ArrowDown ArrowLeft ArrowRight", onKeyDown: zoom.onKeyDown, [DATA_ATTR.zoom]: '1', children: _jsx("div", { ref: zoom.layerRef, className: styles.layer, children: canvas }) }), sourceView] }), _jsxs("div", { className: styles.toolbar, role: "group", "aria-label": `${label} zoom controls`, children: [!sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Zoom out", onClick: zoom.zoomOut, children: _jsx(ZoomOutIcon, {}) })), !sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Zoom in", onClick: zoom.zoomIn, children: _jsx(ZoomInIcon, {}) })), !sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Reset zoom", onClick: zoom.reset, children: _jsx(ResetZoomIcon, {}) })), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Maximize diagram", "aria-pressed": zoom.maximized, onClick: zoom.toggleMaximize, children: zoom.maximized ? _jsx(CloseIcon, {}) : _jsx(MaximizeIcon, {}) }), sourceToggle, copyControl, _jsx("span", { ref: zoom.readoutRef, className: sourceOpen ? `${styles.readout} ${styles.hiddenView}` : styles.readout, "aria-hidden": "true", children: "100%" })] })] })), state.status === 'ready' && state.svg !== null && interactive && (_jsx("p", { id: hintId, className: styles.visuallyHidden, children: "Zoomable diagram. Use the zoom controls, or press plus and minus to zoom, the arrow keys to pan, and zero to reset." })), state.status !== 'ready' && state.status !== 'error' && (
227
229
  // `aria-busy` on the figure already conveys progress; announcing every phase change
228
230
  // would make a page with several diagrams unusable with a screen reader.
229
231
  _jsxs("div", { className: styles.placeholder, children: [_jsx("span", { className: styles.spinner, "aria-hidden": "true" }), _jsxs("span", { children: [state.status === 'loading' ? `Loading ${engineName} runtime…` : null, state.status === 'rendering' ? `Rendering ${label}…` : null, state.status === 'idle' ? `${label} (waiting to render)` : null] })] })), state.status === 'error' && (_jsxs("div", { className: styles.error, role: "alert", children: [_jsxs("p", { className: styles.errorHeading, children: [_jsx("span", { className: styles.errorIcon, "aria-hidden": "true", children: "\u26A0" }), _jsxs("span", { children: ["Error: ", engineName, " diagram could not be rendered"] })] }), _jsx("pre", { className: styles.errorMessage, children: state.error }), config?.options.showSourceOnError !== false && (_jsxs("details", { className: styles.errorDetails, children: [_jsx("summary", { children: "Show diagram source" }), _jsx("pre", { className: styles.source, children: source })] }))] })), title !== undefined && _jsx("figcaption", { className: styles.caption, children: title }), _jsx("noscript", { dangerouslySetInnerHTML: {
@@ -1,9 +1,17 @@
1
1
  import { type ResolvedPlantUmlOptions } from '../options.js';
2
+ import type { StdlibRuntimeManifest } from '../stdlibShared.js';
3
+ /** The standard library as the browser sees it: a URL to fetch bundles from, and an index. */
4
+ export interface StdlibRuntimeConfig {
5
+ baseUrl: string;
6
+ manifest: StdlibRuntimeManifest;
7
+ }
2
8
  export interface PlantUmlRuntimeConfig {
3
9
  options: ResolvedPlantUmlOptions;
4
10
  /** Absolute, `baseUrl`-prefixed URL of the directory holding the runtime assets. */
5
11
  assetsBaseUrl: string;
6
12
  coreVersion: string;
13
+ /** `null` when the standard library is switched off for this site. */
14
+ stdlib: StdlibRuntimeConfig | null;
7
15
  }
8
16
  /**
9
17
  * Reads the plugin's configuration from Docusaurus global data.
@@ -2,7 +2,7 @@ import { useMemo } from 'react';
2
2
  import useBaseUrl from '@docusaurus/useBaseUrl';
3
3
  import { useAllPluginInstancesData } from '@docusaurus/useGlobalData';
4
4
  import { PLUGIN_NAME } from '../constants.js';
5
- import { DEFAULT_GRAPHVIZ_OPTIONS } from '../options.js';
5
+ import { DEFAULT_GRAPHVIZ_OPTIONS, DEFAULT_STDLIB_OPTIONS, } from '../options.js';
6
6
  function isGlobalData(value) {
7
7
  if (typeof value !== 'object' || value === null)
8
8
  return false;
@@ -23,26 +23,32 @@ export function usePlantUmlConfig() {
23
23
  const first = instances ? Object.values(instances).find(isGlobalData) : undefined;
24
24
  // `useBaseUrl` must be called unconditionally; the placeholder path is discarded below.
25
25
  const assetsBaseUrl = useBaseUrl(first ? first.assetsDir : '/');
26
+ const stdlibBaseUrl = useBaseUrl(first?.stdlib ? first.stdlib.dir : '/');
26
27
  // Memoized because consumers use this object as an effect dependency. Returning a fresh
27
28
  // object on every render would restart the render effect on every state update, which
28
29
  // re-enters rendering forever.
29
30
  return useMemo(() => first
30
31
  ? {
31
- options: withGraphvizDefaults(first.options),
32
+ options: withDefaults(first.options),
32
33
  assetsBaseUrl,
33
34
  coreVersion: first.coreVersion,
35
+ stdlib: first.stdlib ? { baseUrl: stdlibBaseUrl, manifest: first.stdlib.manifest } : null,
34
36
  }
35
- : null, [first, assetsBaseUrl]);
37
+ : null, [first, assetsBaseUrl, stdlibBaseUrl]);
36
38
  }
37
39
  /**
38
- * Fills in the `graphviz` group when it is missing from global data.
40
+ * Fills in the nested option groups when they are missing from global data.
39
41
  *
40
- * `resolveOptions` always produces it, so this only matters for data written by an older
42
+ * `resolveOptions` always produces them, so this only matters for data written by an older
41
43
  * version of the plugin — a stale `.docusaurus` cache surviving an upgrade, most plausibly.
42
44
  * Substituting the defaults keeps such a site rendering instead of failing on a missing key.
43
45
  */
44
- function withGraphvizDefaults(options) {
45
- if (options.graphviz)
46
+ function withDefaults(options) {
47
+ if (options.graphviz && options.stdlib)
46
48
  return options;
47
- return { ...options, graphviz: DEFAULT_GRAPHVIZ_OPTIONS };
49
+ return {
50
+ ...options,
51
+ graphviz: options.graphviz ?? DEFAULT_GRAPHVIZ_OPTIONS,
52
+ stdlib: options.stdlib ?? DEFAULT_STDLIB_OPTIONS,
53
+ };
48
54
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matfsw/docusaurus-plantuml-plugin",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Render PlantUML diagrams in Docusaurus 3 entirely in the browser - no Java, no PlantUML server, no CDN.",
5
5
  "keywords": [
6
6
  "docusaurus",
@@ -35,6 +35,7 @@
35
35
  "./package.json": "./package.json"
36
36
  },
37
37
  "files": [
38
+ "assets",
38
39
  "dist",
39
40
  "README.md",
40
41
  "LICENSE",
@@ -62,6 +63,7 @@
62
63
  "verify:tag": "node scripts/verify-tag-version.mjs",
63
64
  "sync:meta": "node scripts/sync-project-metadata.mjs",
64
65
  "sync:check": "node scripts/sync-project-metadata.mjs --check",
66
+ "stdlib:update": "node scripts/update-stdlib.mjs",
65
67
  "example:install": "npm --prefix examples/docusaurus install",
66
68
  "example:build": "npm --prefix examples/docusaurus run build",
67
69
  "example:serve": "npm --prefix examples/docusaurus run serve",