@matfsw/docusaurus-plantuml-plugin 1.5.1 → 1.6.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.
- package/CHANGELOG.md +67 -1
- package/README.md +26 -5
- package/dist/theme/PlantUmlDiagram/index.js +2 -2
- package/dist/theme/PlantUmlDiagram/styles.module.css +66 -30
- package/package.json +9 -8
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.6.0] - 2026-08-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **The zoom controls no longer cover the diagram.** The toolbar was painted over the frame's
|
|
15
|
+
top-right corner and the minimap toggle over its bottom-left, so at 100% — the view a reader
|
|
16
|
+
arrives at without touching anything — a sequence diagram's first participant and a graph's
|
|
17
|
+
leftmost node were sitting underneath a row of buttons. No placement fixes that, because the
|
|
18
|
+
picture is whatever shape its author drew.
|
|
19
|
+
|
|
20
|
+
A zoomable diagram is now two stacked rows: every control in one row (search bar included),
|
|
21
|
+
and the diagram beneath it. Nothing is painted over the picture at any zoom level; the frame
|
|
22
|
+
is one button-bar row taller than before, which is the price of never covering the content.
|
|
23
|
+
The control row is also the frame's **first** child in the DOM, so tab order follows what the
|
|
24
|
+
reader sees. Maximizing uses the same two rows.
|
|
25
|
+
|
|
26
|
+
The **minimap toggle has moved into the toolbar**, beside Maximize; it no longer has a row of
|
|
27
|
+
its own beneath the diagram. The toolbar wraps rather than overflowing a narrow column. The
|
|
28
|
+
minimap _panel_ still opens over the diagram's bottom-left corner — the reader opens it
|
|
29
|
+
deliberately, closes it from its own ✕, and putting it opposite the toolbar keeps the control
|
|
30
|
+
from covering the map. The source view's header no longer reserves a 12rem gutter for a
|
|
31
|
+
toolbar that is no longer above it.
|
|
32
|
+
|
|
33
|
+
Released as a **minor** rather than the patch these headings would normally derive: the
|
|
34
|
+
rendered markup changed shape. The minimap's own bar element is gone, its toggle is a button
|
|
35
|
+
inside the existing control group, and that group is now the frame's first child rather than
|
|
36
|
+
its last. Site CSS or tests that reached for those positions need updating; the documented
|
|
37
|
+
selectors — `[data-plantuml-diagram]`, `div[role="img"] > svg`, `[data-plantuml-zoom]` and the
|
|
38
|
+
control group's accessible name — are all unchanged.
|
|
39
|
+
|
|
40
|
+
## [1.5.2] - 2026-08-20
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- **Development dependencies:** `jsdom` `26` → `29`, `@testing-library/jest-dom` `7.0.0` → `7.0.1`,
|
|
45
|
+
`@testing-library/user-event` `14.6.3` → `14.6.5`, `@types/node` `26.1.2` → `26.2.0`, `globals`
|
|
46
|
+
`17.9.0` → `17.11.0`, `typescript-eslint` `8.66.0` → `8.67.0`. No product code changed; all 651
|
|
47
|
+
tests pass unchanged.
|
|
48
|
+
|
|
49
|
+
jsdom 27 added `@exodus/bytes`, which needs `@noble/hashes` `^1.8.0 || ^2.0.0`, while
|
|
50
|
+
`@docusaurus/core`'s dev server reaches `pkijs`, which pins that package to **exactly** `1.4.0`.
|
|
51
|
+
npm 11 hoists `1.4.0` and leaves the tree invalid without saying so; npm 10 — what Node 20 and
|
|
52
|
+
22 ship, and what CI therefore runs — correctly refuses the resulting lockfile with
|
|
53
|
+
`Missing: @noble/hashes@2.3.0`. An `overrides` entry pins `@noble/hashes` to `^1.8.0`, which
|
|
54
|
+
both consumers accept. Overrides apply only to this repository's own installs, never to a
|
|
55
|
+
consumer's.
|
|
56
|
+
|
|
57
|
+
`.github/dependabot.yml` now ignores **jsdom 30 and above**. jsdom 30 requires Node
|
|
58
|
+
`^22.22.2 || ^24.15.0 || >=26.0.0`, dropping Node 20 outright, and the honest consequence of
|
|
59
|
+
taking it would be raising this package's `engines.node`. That is not ours to raise:
|
|
60
|
+
`@docusaurus/core` still declares `node: >=20.0` as of 3.10.2, and a plugin whose floor sits
|
|
61
|
+
above its host's cannot be installed into a site Docusaurus itself supports. jsdom 29 still
|
|
62
|
+
supports `^20.19.0`, which is what `.nvmrc` pins.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- **The Dependabot branch refresh no longer races GitHub.** It selected pull requests by
|
|
67
|
+
`mergeStateStatus == "BEHIND"`, but GitHub recomputes that field asynchronously after a push to
|
|
68
|
+
the base branch — on its first live run it reported nothing behind while two pull requests were
|
|
69
|
+
ten commits behind. It now asks `compare` for `behind_by`, which is computed on demand.
|
|
70
|
+
|
|
71
|
+
- `actions/create-github-app-token` and `dependabot/fetch-metadata` were pinned at `v2`; both are
|
|
72
|
+
at `v3`.
|
|
73
|
+
|
|
10
74
|
## [1.5.1] - 2026-08-20
|
|
11
75
|
|
|
12
76
|
### Changed
|
|
@@ -506,7 +570,9 @@ Initial release.
|
|
|
506
570
|
opt-out.
|
|
507
571
|
- Plugin option validation that rejects unknown keys and out-of-range values at build time.
|
|
508
572
|
|
|
509
|
-
[Unreleased]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.
|
|
573
|
+
[Unreleased]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.6.0...HEAD
|
|
574
|
+
[1.6.0]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.5.2...v1.6.0
|
|
575
|
+
[1.5.2]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.5.1...v1.5.2
|
|
510
576
|
[1.5.1]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.5.0...v1.5.1
|
|
511
577
|
[1.5.0]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.4.0...v1.5.0
|
|
512
578
|
[1.4.0]: https://github.com/matf/docusaurus-plantuml-plugin/compare/v1.3.1...v1.4.0
|
package/README.md
CHANGED
|
@@ -525,7 +525,24 @@ diagram, whichever engine produced it.
|
|
|
525
525
|
## Zoom and pan
|
|
526
526
|
|
|
527
527
|
Large diagrams are unreadable at column width. Rendered diagrams are therefore zoomable and
|
|
528
|
-
pannable by default, with a small control toolbar
|
|
528
|
+
pannable by default, with a small control toolbar above the picture.
|
|
529
|
+
|
|
530
|
+
### The frame's layout
|
|
531
|
+
|
|
532
|
+
A zoomable diagram is two stacked rows: **the controls**, at the top right, and **the diagram**
|
|
533
|
+
beneath them. The search bar opens beside the toolbar, in the same row, and the toolbar wraps
|
|
534
|
+
rather than overflowing a narrow column.
|
|
535
|
+
|
|
536
|
+
Nothing is painted over the picture, so at 100% — the view a reader arrives at — the whole
|
|
537
|
+
diagram is visible. The controls used to float over the frame's corners, which is exactly where
|
|
538
|
+
a sequence diagram draws its first participant and a graph its leftmost node; no amount of
|
|
539
|
+
nudging fixes that, because the picture is whatever shape its author drew. The row costs the
|
|
540
|
+
height of one small button bar per diagram, which is the price of never covering the content.
|
|
541
|
+
|
|
542
|
+
Zooming in can still slide the diagram under the row's edge — the viewport clips it there — and
|
|
543
|
+
that is deliberate: by then the reader is driving, and a frame that grew as you zoomed would
|
|
544
|
+
reflow the page around it. The **minimap**, once opened, does float over the picture's
|
|
545
|
+
bottom-left corner: the reader asked for it, and it closes with its own ✕.
|
|
529
546
|
|
|
530
547
|
### Interaction
|
|
531
548
|
|
|
@@ -587,10 +604,12 @@ highlight without touching the plugin.
|
|
|
587
604
|
|
|
588
605
|
### Minimap
|
|
589
606
|
|
|
590
|
-
The button in the
|
|
591
|
-
rectangle marking what the viewport currently shows.
|
|
592
|
-
|
|
593
|
-
|
|
607
|
+
The minimap button in the toolbar opens a minimap: a small copy of the diagram with a
|
|
608
|
+
rectangle marking what the viewport currently shows. It appears in the diagram's bottom-left
|
|
609
|
+
corner — the opposite one from the toolbar, so the control that opens it never covers it.
|
|
610
|
+
Press or drag anywhere on the map to centre the view there — a single press works as "jump
|
|
611
|
+
there". The map follows every zoom, pan and resize, works while maximized, and closes from its
|
|
612
|
+
own ✕ or the toggle.
|
|
594
613
|
|
|
595
614
|
The map is pointer-only and hidden from assistive technology on purpose: the real viewport is
|
|
596
615
|
already keyboard-operable with the arrow keys, so announcing a second, duplicated view of the
|
|
@@ -635,6 +654,8 @@ would mean most readers never discover it. The costs are real and worth knowing:
|
|
|
635
654
|
|
|
636
655
|
- Each zoomable diagram adds a **keyboard tab stop for the viewport and one per toolbar
|
|
637
656
|
button**. On a page with six diagrams that is a meaningful amount of tabbing.
|
|
657
|
+
- The frame is **one button-bar row taller** than the picture, because the controls sit above it
|
|
658
|
+
rather than over it — see [The frame's layout](#the-frames-layout).
|
|
638
659
|
- The rendered markup gains a viewport and transform wrapper around the `role="img"` container.
|
|
639
660
|
Site CSS that targets `[data-plantuml-diagram] > div[role="img"]` as a **direct child** needs
|
|
640
661
|
updating — see [Accessibility](#accessibility) for both shapes.
|
|
@@ -296,9 +296,9 @@ export default function PlantUmlDiagram({ source, title, language, engine = 'pla
|
|
|
296
296
|
...(zoom.maximized ? { [DATA_ATTR.maximized]: 'true' } : {}),
|
|
297
297
|
...(sourceOpen ? { [DATA_ATTR.sourceOpen]: 'true' } : {}),
|
|
298
298
|
...(minimapOpen ? { [DATA_ATTR.minimapOpen]: 'true' } : {}),
|
|
299
|
-
...(search.open ? { [DATA_ATTR.searchOpen]: '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.
|
|
299
|
+
...(search.open ? { [DATA_ATTR.searchOpen]: '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.controls, children: [search.open && !sourceOpen && (_jsxs("div", { className: styles.searchBar, role: "search", "aria-label": `${label} search`, children: [_jsx("input", { ref: search.inputRef, type: "text", className: styles.searchInput, placeholder: "Search diagram", "aria-label": "Search diagram text", value: search.query, onChange: (event) => search.setQuery(event.target.value), onKeyDown: onSearchKeyDown }), _jsx("span", { className: styles.searchCount, role: "status", children: search.matchCount === 0
|
|
300
300
|
? '0/0'
|
|
301
|
-
: `${search.currentIndex + 1}/${search.matchCount}` }), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Previous match", onClick: search.previous, children: _jsx(ChevronUpIcon, {}) }), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Next match", onClick: search.next, children: _jsx(ChevronDownIcon, {}) }), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Close search", onClick: closeSearch, children: _jsx(CloseIcon, {}) })] })), _jsxs("div", { className: styles.toolbar, role: "group", "aria-label": `${label} zoom controls`, children: [!sourceOpen && (_jsx("button", { ref: searchToggleRef, type: "button", className: styles.toolbarButton, "aria-label": "Search diagram", "aria-expanded": search.open, onClick: search.toggle, children: _jsx(SearchIcon, {}) })), !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, {}) })), !sourceOpen && zoom.maximized && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Fit diagram to screen", onClick: zoom.fit, children: _jsx(FitIcon, {}) })), _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%" })] })] }),
|
|
301
|
+
: `${search.currentIndex + 1}/${search.matchCount}` }), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Previous match", onClick: search.previous, children: _jsx(ChevronUpIcon, {}) }), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Next match", onClick: search.next, children: _jsx(ChevronDownIcon, {}) }), _jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Close search", onClick: closeSearch, children: _jsx(CloseIcon, {}) })] })), _jsxs("div", { className: styles.toolbar, role: "group", "aria-label": `${label} zoom controls`, children: [!sourceOpen && (_jsx("button", { ref: searchToggleRef, type: "button", className: styles.toolbarButton, "aria-label": "Search diagram", "aria-expanded": search.open, onClick: search.toggle, children: _jsx(SearchIcon, {}) })), !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, {}) })), !sourceOpen && zoom.maximized && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": "Fit diagram to screen", onClick: zoom.fit, children: _jsx(FitIcon, {}) })), _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, {}) }), !sourceOpen && (_jsx("button", { type: "button", className: styles.toolbarButton, "aria-label": minimapOpen ? 'Hide minimap' : 'Show minimap', "aria-expanded": minimapOpen, onClick: () => setMinimapOpen((open) => !open), children: _jsx(MinimapIcon, {}) })), sourceToggle, copyControl, _jsx("span", { ref: zoom.readoutRef, className: sourceOpen ? `${styles.readout} ${styles.hiddenView}` : styles.readout, "aria-hidden": "true", children: "100%" })] })] }), _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 }) }), !sourceOpen && minimapOpen && (_jsx(Minimap, { svg: state.svg, zoom: zoom, onClose: () => setMinimapOpen(false) })), sourceView] })] })), 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' && (
|
|
302
302
|
// `aria-busy` on the figure already conveys progress; announcing every phase change
|
|
303
303
|
// would make a page with several diagrams unusable with a screen reader.
|
|
304
304
|
_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: {
|
|
@@ -52,8 +52,26 @@
|
|
|
52
52
|
* the figure keeps the exact height it has at 100% no matter how far the reader zooms in, and
|
|
53
53
|
* `max-width: 100%` on the SVG keeps constraining the base size as it always did.
|
|
54
54
|
*/
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
* The frame is two stacked rows — controls, then picture — not one box with chrome floating
|
|
58
|
+
* over it.
|
|
59
|
+
*
|
|
60
|
+
* Floating it covered the diagram: the toolbar sat over the top right of every figure and the
|
|
61
|
+
* minimap toggle over the bottom left, and at 100% — the view every reader arrives at — that
|
|
62
|
+
* is exactly where a sequence diagram's first participant and a graph's leftmost node are
|
|
63
|
+
* drawn. No amount of nudging fixes that, because the picture is whatever shape its author
|
|
64
|
+
* drew. A row above the picture means the opening view has nothing painted over it at all.
|
|
65
|
+
* Zooming can still slide content under the row's edge, which is fine: by then the reader is
|
|
66
|
+
* driving, and the alternative is a frame that grows as you zoom.
|
|
67
|
+
*
|
|
68
|
+
* `position: relative` stays for the maximized overlay's sake, not for the controls.
|
|
69
|
+
*/
|
|
55
70
|
.stage {
|
|
56
71
|
position: relative;
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-direction: column;
|
|
74
|
+
gap: 0.5rem;
|
|
57
75
|
}
|
|
58
76
|
|
|
59
77
|
.viewport {
|
|
@@ -108,25 +126,32 @@
|
|
|
108
126
|
/*
|
|
109
127
|
* One flex row holds the search bar and the toolbar, so opening the search never needs to
|
|
110
128
|
* know how wide the toolbar happens to be — it simply takes the space to its left.
|
|
129
|
+
*
|
|
130
|
+
* `flex-end` keeps the toolbar where readers have always found it, at the top right of the
|
|
131
|
+
* frame — now above the picture rather than on top of it.
|
|
111
132
|
*/
|
|
112
133
|
.controls {
|
|
113
|
-
position: absolute;
|
|
114
|
-
top: 0.5rem;
|
|
115
|
-
right: 0.5rem;
|
|
116
134
|
display: flex;
|
|
135
|
+
/*
|
|
136
|
+
* Wrapping, in both directions, because the row is the only thing holding the controls now:
|
|
137
|
+
* in a narrow column the search bar drops below the toolbar rather than squeezing it, and
|
|
138
|
+
* the toolbar itself breaks across lines rather than overflowing the frame.
|
|
139
|
+
*/
|
|
140
|
+
flex-wrap: wrap;
|
|
117
141
|
gap: 0.5rem;
|
|
118
142
|
align-items: flex-start;
|
|
143
|
+
justify-content: flex-end;
|
|
119
144
|
}
|
|
120
145
|
|
|
121
146
|
.toolbar {
|
|
122
147
|
display: flex;
|
|
148
|
+
flex-wrap: wrap;
|
|
123
149
|
gap: 0.25rem;
|
|
124
150
|
align-items: center;
|
|
125
151
|
padding: 0.25rem;
|
|
126
152
|
border: 1px solid var(--ifm-color-emphasis-300);
|
|
127
153
|
border-radius: var(--ifm-global-radius);
|
|
128
154
|
background: var(--ifm-background-surface-color);
|
|
129
|
-
opacity: 0.92;
|
|
130
155
|
}
|
|
131
156
|
|
|
132
157
|
.searchBar {
|
|
@@ -137,7 +162,6 @@
|
|
|
137
162
|
border: 1px solid var(--ifm-color-emphasis-300);
|
|
138
163
|
border-radius: var(--ifm-global-radius);
|
|
139
164
|
background: var(--ifm-background-surface-color);
|
|
140
|
-
opacity: 0.92;
|
|
141
165
|
}
|
|
142
166
|
|
|
143
167
|
.searchInput {
|
|
@@ -275,9 +299,8 @@
|
|
|
275
299
|
position: fixed;
|
|
276
300
|
inset: 0;
|
|
277
301
|
z-index: var(--ifm-z-index-overlay, 400);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
justify-content: center;
|
|
302
|
+
/* Keeps the control rows off the screen's edges; `inset: 0` fixes the border box either way. */
|
|
303
|
+
padding: 0.5rem;
|
|
281
304
|
/*
|
|
282
305
|
* `--ifm-background-surface-color`, not `--ifm-background-color`: Infima defines the latter
|
|
283
306
|
* as `#0000` in light mode, so the overlay would be transparent and the page would show
|
|
@@ -288,35 +311,49 @@
|
|
|
288
311
|
background: var(--ifm-background-surface-color, #ffffff);
|
|
289
312
|
}
|
|
290
313
|
|
|
314
|
+
/*
|
|
315
|
+
* The picture takes every pixel the two control rows leave. `min-height: 0` is what allows
|
|
316
|
+
* that: a flex item's floor is its content, so without it a tall diagram would push the
|
|
317
|
+
* minimap row off the bottom of the screen instead of being clipped by its own viewport.
|
|
318
|
+
*
|
|
319
|
+
* The viewport itself needs no size: it is the lone item in `.stageBody`'s grid cell, so it
|
|
320
|
+
* stretches to whatever the row is given — 100vw/100dvh here would ignore the padding and
|
|
321
|
+
* the rows and overflow the overlay by exactly their height.
|
|
322
|
+
*/
|
|
323
|
+
.maximized .stageBody {
|
|
324
|
+
flex: 1;
|
|
325
|
+
min-height: 0;
|
|
326
|
+
/*
|
|
327
|
+
* The row must take the height it is *given*, not the height the picture wants. A grid
|
|
328
|
+
* track sized `auto` floors at max-content, so a diagram taller than the screen sized the
|
|
329
|
+
* row past the frame and the viewport painted straight over the minimap row below it —
|
|
330
|
+
* and, worse, `fitScale` then measured that overflowing viewport and concluded the diagram
|
|
331
|
+
* already fitted. `minmax(0, 1fr)` removes the floor, so the track is exactly the free
|
|
332
|
+
* height and the viewport clips the picture as it does everywhere else.
|
|
333
|
+
*/
|
|
334
|
+
grid-template-rows: minmax(0, 1fr);
|
|
335
|
+
}
|
|
336
|
+
|
|
291
337
|
.maximized .viewport {
|
|
292
|
-
width: 100vw;
|
|
293
|
-
height: 100dvh;
|
|
294
338
|
max-height: none;
|
|
295
339
|
}
|
|
296
340
|
|
|
297
341
|
/*
|
|
298
342
|
* Minimap.
|
|
299
343
|
*
|
|
300
|
-
* A small copy of the diagram
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
344
|
+
* A small copy of the diagram with a rectangle marking the visible part. The copy is laid out
|
|
345
|
+
* at the content's own width and scaled down as one block, so it keeps exactly the geometry of
|
|
346
|
+
* the real canvas and the rectangle's coordinates can be multiplied straight through.
|
|
347
|
+
*
|
|
348
|
+
* It floats over the picture's bottom-left corner — it is a child of `.stageBody`, so that is
|
|
349
|
+
* the box it is anchored in, and it is the one control positioned that way. A control the
|
|
350
|
+
* reader has explicitly opened may cover the picture; the toolbar, which is simply always
|
|
351
|
+
* there, may not. The corner is deliberately the opposite one from the toolbar that opens it:
|
|
352
|
+
* a map painted under its own control would be half hidden by it.
|
|
304
353
|
*/
|
|
305
|
-
.minimapBar {
|
|
306
|
-
position: absolute;
|
|
307
|
-
bottom: 0.5rem;
|
|
308
|
-
left: 0.5rem;
|
|
309
|
-
display: flex;
|
|
310
|
-
padding: 0.25rem;
|
|
311
|
-
border: 1px solid var(--ifm-color-emphasis-300);
|
|
312
|
-
border-radius: var(--ifm-global-radius);
|
|
313
|
-
background: var(--ifm-background-surface-color);
|
|
314
|
-
opacity: 0.92;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
354
|
.minimap {
|
|
318
355
|
position: absolute;
|
|
319
|
-
bottom:
|
|
356
|
+
bottom: 0.5rem;
|
|
320
357
|
left: 0.5rem;
|
|
321
358
|
/*
|
|
322
359
|
* The close control sits *beside* the map, not floating over it: a wide, short diagram
|
|
@@ -383,7 +420,6 @@
|
|
|
383
420
|
@media (forced-colors: active) {
|
|
384
421
|
.toolbar,
|
|
385
422
|
.searchBar,
|
|
386
|
-
.minimapBar,
|
|
387
423
|
.minimap {
|
|
388
424
|
border-color: ButtonBorder;
|
|
389
425
|
}
|
|
@@ -563,8 +599,8 @@
|
|
|
563
599
|
align-items: center;
|
|
564
600
|
flex-wrap: wrap;
|
|
565
601
|
gap: 0.5rem;
|
|
566
|
-
/*
|
|
567
|
-
padding: 0.5rem
|
|
602
|
+
/* No clearance needed: the toolbar has a row above the frame, not a corner inside it. */
|
|
603
|
+
padding: 0.5rem 0.75rem 0.25rem;
|
|
568
604
|
}
|
|
569
605
|
|
|
570
606
|
.sourceViewTitle {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matfsw/docusaurus-plantuml-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
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",
|
|
@@ -90,10 +90,10 @@
|
|
|
90
90
|
"@eslint/js": "^9.39.5",
|
|
91
91
|
"@playwright/test": "^1.57.0",
|
|
92
92
|
"@testing-library/dom": "^10.4.1",
|
|
93
|
-
"@testing-library/jest-dom": "^7.0.
|
|
93
|
+
"@testing-library/jest-dom": "^7.0.1",
|
|
94
94
|
"@testing-library/react": "^16.3.0",
|
|
95
|
-
"@testing-library/user-event": "^14.6.
|
|
96
|
-
"@types/node": "^26.
|
|
95
|
+
"@testing-library/user-event": "^14.6.5",
|
|
96
|
+
"@types/node": "^26.2.0",
|
|
97
97
|
"@types/react": "^19.2.18",
|
|
98
98
|
"@types/react-dom": "^19.2.4",
|
|
99
99
|
"@vitest/coverage-v8": "^4.1.10",
|
|
@@ -101,19 +101,20 @@
|
|
|
101
101
|
"eslint-config-prettier": "^10.1.8",
|
|
102
102
|
"eslint-plugin-react": "^7.37.5",
|
|
103
103
|
"eslint-plugin-react-hooks": "^5.2.0",
|
|
104
|
-
"globals": "^17.
|
|
105
|
-
"jsdom": "^
|
|
104
|
+
"globals": "^17.11.0",
|
|
105
|
+
"jsdom": "^29.1.1",
|
|
106
106
|
"prettier": "^3.6.2",
|
|
107
107
|
"react": "^19.2.8",
|
|
108
108
|
"react-dom": "^19.2.8",
|
|
109
109
|
"tsup": "^8.5.0",
|
|
110
110
|
"typescript": "~5.9.3",
|
|
111
|
-
"typescript-eslint": "^8.
|
|
111
|
+
"typescript-eslint": "^8.67.0",
|
|
112
112
|
"vitest": "^4.1.10"
|
|
113
113
|
},
|
|
114
114
|
"overrides": {
|
|
115
115
|
"serialize-javascript": "^7.0.7",
|
|
116
116
|
"uuid": "^11.1.1",
|
|
117
|
-
"esbuild": "^0.28.1"
|
|
117
|
+
"esbuild": "^0.28.1",
|
|
118
|
+
"@noble/hashes": "^1.8.0"
|
|
118
119
|
}
|
|
119
120
|
}
|