markdown-design-doc-viewer-embed 1.5.4 → 1.5.5
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.ja.md +53 -1
- package/README.md +53 -1
- package/export.js +1 -1
- package/index.js +545 -30
- package/package.json +1 -1
- package/react.js +78 -10
- package/types/embed/designDocList.d.ts +39 -0
- package/types/embed/react.d.ts +13 -2
- package/types/embed/viewer.d.ts +43 -1
- package/types/src/shared/l10n.d.ts +10 -0
- package/viewer.css +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-design-doc-viewer-embed",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.5",
|
|
4
4
|
"description": "The viewer of Markdown Design Doc Viewer to embed in a web app (React or not): design documents in Markdown with their mermaid sequence diagrams, flowcharts, ER and state diagrams and wireframes linked to the steps after them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
package/react.js
CHANGED
|
@@ -2,21 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
// embed/react.tsx
|
|
4
4
|
import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
|
|
5
|
-
import { createViewer, openLinkInNewTab } from "./index.js";
|
|
5
|
+
import { createDesignDocList, createViewer, openLinkInNewTab, openLinkInPage } from "./index.js";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
var DesignDocViewer = forwardRef(function DesignDocViewer2({ className, style, ...options }, ref) {
|
|
8
8
|
const element = useRef(null);
|
|
9
9
|
const viewer = useRef(void 0);
|
|
10
10
|
const created = useRef(false);
|
|
11
11
|
const latest = useRef(options);
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const viewerOptions = () => ({
|
|
15
|
-
...latest.current,
|
|
16
|
-
onOpenLink: (href) => (latest.current.onOpenLink ?? openLinkInNewTab)(href),
|
|
17
|
-
// Only with one: without, a double-click does nothing.
|
|
18
|
-
onRevealLine: revealing ? (line) => latest.current.onRevealLine?.(line) : void 0
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
latest.current = options;
|
|
19
14
|
});
|
|
15
|
+
const revealing = options.onRevealLine !== void 0;
|
|
16
|
+
const closing = options.onCloseDiff !== void 0;
|
|
17
|
+
const viewerOptions = () => {
|
|
18
|
+
const o = latest.current;
|
|
19
|
+
return {
|
|
20
|
+
markdown: o.markdown,
|
|
21
|
+
documentId: o.documentId,
|
|
22
|
+
baseUrl: o.baseUrl,
|
|
23
|
+
readFile: o.readFile,
|
|
24
|
+
resolveResource: o.resolveResource,
|
|
25
|
+
lang: o.lang,
|
|
26
|
+
theme: o.theme,
|
|
27
|
+
diagramLook: o.diagramLook,
|
|
28
|
+
splitMinWidth: o.splitMinWidth,
|
|
29
|
+
toc: o.toc,
|
|
30
|
+
limitContentWidth: o.limitContentWidth,
|
|
31
|
+
stickyTableHeader: o.stickyTableHeader,
|
|
32
|
+
tableTreeHighlight: o.tableTreeHighlight,
|
|
33
|
+
frontMatter: o.frontMatter,
|
|
34
|
+
headingNumbers: o.headingNumbers,
|
|
35
|
+
messageWrapWidth: o.messageWrapWidth,
|
|
36
|
+
compareWith: o.compareWith,
|
|
37
|
+
compareLabel: o.compareLabel,
|
|
38
|
+
onOpenLink: (href) => (latest.current.onOpenLink ?? openLinkInNewTab)(href),
|
|
39
|
+
// Only with one: without, a double-click does nothing.
|
|
40
|
+
onRevealLine: o.onRevealLine !== void 0 ? (line) => latest.current.onRevealLine?.(line) : void 0,
|
|
41
|
+
// Only with one: without, the viewer closes the differences by itself.
|
|
42
|
+
onCloseDiff: o.onCloseDiff !== void 0 ? () => latest.current.onCloseDiff?.() : void 0
|
|
43
|
+
};
|
|
44
|
+
};
|
|
20
45
|
useEffect(() => {
|
|
21
46
|
const instance = createViewer(element.current, viewerOptions());
|
|
22
47
|
viewer.current = instance;
|
|
@@ -26,20 +51,63 @@ var DesignDocViewer = forwardRef(function DesignDocViewer2({ className, style, .
|
|
|
26
51
|
viewer.current = void 0;
|
|
27
52
|
};
|
|
28
53
|
}, [options.lang]);
|
|
29
|
-
const { markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, messageWrapWidth } = options;
|
|
54
|
+
const { markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, messageWrapWidth, compareWith, compareLabel } = options;
|
|
30
55
|
useEffect(() => {
|
|
31
56
|
if (created.current) {
|
|
32
57
|
created.current = false;
|
|
33
58
|
return;
|
|
34
59
|
}
|
|
35
60
|
void viewer.current?.update(viewerOptions());
|
|
36
|
-
}, [options.lang, markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, messageWrapWidth, revealing]);
|
|
61
|
+
}, [options.lang, markdown, documentId, baseUrl, readFile, resolveResource, theme, diagramLook, splitMinWidth, toc, limitContentWidth, stickyTableHeader, tableTreeHighlight, frontMatter, headingNumbers, messageWrapWidth, compareWith, compareLabel, revealing, closing]);
|
|
37
62
|
useImperativeHandle(ref, () => ({
|
|
38
63
|
scrollToLine: (line) => viewer.current?.scrollToLine(line),
|
|
39
64
|
markLine: (line) => viewer.current?.markLine(line)
|
|
40
65
|
}));
|
|
41
66
|
return /* @__PURE__ */ jsx("div", { ref: element, className, style });
|
|
42
67
|
});
|
|
68
|
+
function DesignDocList({ className, style, ...options }) {
|
|
69
|
+
const element = useRef(null);
|
|
70
|
+
const list = useRef(void 0);
|
|
71
|
+
const created = useRef(false);
|
|
72
|
+
const latest = useRef(options);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
latest.current = options;
|
|
75
|
+
});
|
|
76
|
+
const listOptions = () => {
|
|
77
|
+
const o = latest.current;
|
|
78
|
+
return {
|
|
79
|
+
documents: o.documents,
|
|
80
|
+
title: o.title,
|
|
81
|
+
fileLabel: o.fileLabel,
|
|
82
|
+
filterPlaceholder: o.filterPlaceholder,
|
|
83
|
+
empty: o.empty,
|
|
84
|
+
keepOrder: o.keepOrder,
|
|
85
|
+
lang: o.lang,
|
|
86
|
+
theme: o.theme,
|
|
87
|
+
limitContentWidth: o.limitContentWidth,
|
|
88
|
+
onOpenLink: (href) => (latest.current.onOpenLink ?? openLinkInPage)(href)
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
const instance = createDesignDocList(element.current, listOptions());
|
|
93
|
+
list.current = instance;
|
|
94
|
+
created.current = true;
|
|
95
|
+
return () => {
|
|
96
|
+
instance.destroy();
|
|
97
|
+
list.current = void 0;
|
|
98
|
+
};
|
|
99
|
+
}, [options.lang]);
|
|
100
|
+
const { documents, title, fileLabel, filterPlaceholder, empty, keepOrder, theme, limitContentWidth } = options;
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (created.current) {
|
|
103
|
+
created.current = false;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
void list.current?.update(listOptions());
|
|
107
|
+
}, [options.lang, documents, title, fileLabel, filterPlaceholder, empty, keepOrder, theme, limitContentWidth]);
|
|
108
|
+
return /* @__PURE__ */ jsx("div", { ref: element, className, style });
|
|
109
|
+
}
|
|
43
110
|
export {
|
|
111
|
+
DesignDocList,
|
|
44
112
|
DesignDocViewer
|
|
45
113
|
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The HTML of a list of design documents embedded in a page (`createDesignDocList` of embed/viewer.ts): the list of
|
|
3
|
+
* the design documents of the extension and the desktop app (`indexBody`), of documents given by the app instead of
|
|
4
|
+
* the files of a folder.
|
|
5
|
+
*/
|
|
6
|
+
import type { Translate } from '../src/shared/l10n.js';
|
|
7
|
+
import type { MarkdownIt } from 'markdown-it';
|
|
8
|
+
/** A document of a list (`createDesignDocList`). */
|
|
9
|
+
export interface DesignDocListDocument {
|
|
10
|
+
/** Its Markdown, or only its front matter: its title and the main entries of its front matter come from it. */
|
|
11
|
+
markdown: string;
|
|
12
|
+
/** The link of its title, given to `onOpenLink` when it is clicked (`#...` scrolls the list to that fragment instead). */
|
|
13
|
+
href: string;
|
|
14
|
+
/** The folder it is in, with `/` between the folders: a table and a heading for each. The top one (`''`) by default. */
|
|
15
|
+
folder?: string;
|
|
16
|
+
/** Its file name, shown next to its title (or what `fileLabel` names). */
|
|
17
|
+
file?: string;
|
|
18
|
+
/** Its title, instead of that of the Markdown (the `title` of its front matter, its first `#` heading, `file`, or `href`). */
|
|
19
|
+
title?: string;
|
|
20
|
+
}
|
|
21
|
+
/** The texts and order of a list. */
|
|
22
|
+
export interface DesignDocListContent {
|
|
23
|
+
documents: DesignDocListDocument[];
|
|
24
|
+
/** The heading of the list. `Design Docs` by default. */
|
|
25
|
+
title?: string;
|
|
26
|
+
/** The header of the column of `file`. `File` by default. */
|
|
27
|
+
fileLabel?: string;
|
|
28
|
+
/** The placeholder of the search box. By default, it names the title, the file name and the metadata. */
|
|
29
|
+
filterPlaceholder?: string;
|
|
30
|
+
/** The text without documents. By default, that of the extension. */
|
|
31
|
+
empty?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Lists the folders and the documents in the order of `documents` (a folder where its first document is) instead of
|
|
34
|
+
* by name. false by default.
|
|
35
|
+
*/
|
|
36
|
+
keepOrder?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/** The HTML of the list of `content`, with the texts translated by `t`. */
|
|
39
|
+
export declare function designDocListHtml(md: MarkdownIt, content: DesignDocListContent, t: Translate): string;
|
package/types/embed/react.d.ts
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* The viewer of embed/viewer.ts as a React component. Its styles are embed/viewer.css, which the app imports.
|
|
3
3
|
*
|
|
4
4
|
* <DesignDocViewer markdown={text} baseUrl="/docs/" style={{ height: 600 }} />
|
|
5
|
+
* <DesignDocList documents={[{ markdown, href: '/docs/login', file: 'login.md' }]} onOpenLink={navigate} />
|
|
5
6
|
*
|
|
6
7
|
* It needs a height, which the viewer fills. `readFile` and `resolveResource` render the document again when they
|
|
7
8
|
* change: keep them the same across renders (`useCallback`). The other callbacks may change freely.
|
|
8
9
|
*/
|
|
9
10
|
import { type CSSProperties } from 'react';
|
|
10
|
-
import { type ViewerOptions } from './viewer.js';
|
|
11
|
-
export type { ViewerOptions } from './viewer.js';
|
|
11
|
+
import { type DesignDocListOptions, type ViewerOptions } from './viewer.js';
|
|
12
|
+
export type { DesignDocListDocument, DesignDocListOptions, ViewerOptions } from './viewer.js';
|
|
12
13
|
export interface DesignDocViewerProps extends ViewerOptions {
|
|
13
14
|
className?: string;
|
|
14
15
|
style?: CSSProperties;
|
|
@@ -21,3 +22,13 @@ export interface DesignDocViewerHandle {
|
|
|
21
22
|
markLine(line: number): void;
|
|
22
23
|
}
|
|
23
24
|
export declare const DesignDocViewer: import("react").ForwardRefExoticComponent<DesignDocViewerProps & import("react").RefAttributes<DesignDocViewerHandle>>;
|
|
25
|
+
export interface DesignDocListProps extends DesignDocListOptions {
|
|
26
|
+
className?: string;
|
|
27
|
+
style?: CSSProperties;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The list of the design documents of createDesignDocList (embed/viewer.ts), as high as the list. `onOpenLink` may
|
|
31
|
+
* change freely; the list is shown again when the other options change (keep `documents` the same across renders
|
|
32
|
+
* while they do not change: `useMemo`).
|
|
33
|
+
*/
|
|
34
|
+
export declare function DesignDocList({ className, style, ...options }: DesignDocListProps): import("react").JSX.Element;
|
package/types/embed/viewer.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type DiagramLook } from '../src/shared/protocol.js';
|
|
2
|
+
import { type DesignDocListContent } from './designDocList.js';
|
|
2
3
|
export type { DiagramLook };
|
|
4
|
+
export type { DesignDocListContent, DesignDocListDocument } from './designDocList.js';
|
|
3
5
|
export interface ViewerOptions {
|
|
4
6
|
/** The Markdown of the design document. */
|
|
5
7
|
markdown: string;
|
|
@@ -52,6 +54,20 @@ export interface ViewerOptions {
|
|
|
52
54
|
onOpenLink?: (href: string) => void;
|
|
53
55
|
/** Called with the line (0-based) of the Markdown double-clicked in the viewer, e.g. to show it in an editor. */
|
|
54
56
|
onRevealLine?: (line: number) => void;
|
|
57
|
+
/**
|
|
58
|
+
* The Markdown of another version of the document (an older one, for instance). With it, the viewer shows `markdown`
|
|
59
|
+
* with its differences from that version: the blocks added, changed (with the words changed) and deleted, the
|
|
60
|
+
* diagrams before the change, and a bar with their numbers and buttons to go from one change to the next. Without it,
|
|
61
|
+
* the document alone.
|
|
62
|
+
*/
|
|
63
|
+
compareWith?: string;
|
|
64
|
+
/** What the document is compared with (e.g. `Compared with version 3 (2026-11-01)`), shown on the bar of the differences. */
|
|
65
|
+
compareLabel?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Called when the bar of the differences is closed (its × button), e.g. to remove `compareWith`. Without it, the
|
|
68
|
+
* viewer shows the document alone until `compareWith` changes.
|
|
69
|
+
*/
|
|
70
|
+
onCloseDiff?: () => void;
|
|
55
71
|
}
|
|
56
72
|
export interface Viewer {
|
|
57
73
|
/** Resolves once the document is shown, with its diagrams (that of `createViewer`, or of an update made meanwhile). */
|
|
@@ -69,8 +85,34 @@ export interface Viewer {
|
|
|
69
85
|
export declare function openLinkInNewTab(href: string): void;
|
|
70
86
|
/** Shows the design document of `options` in `container`, which it fills. */
|
|
71
87
|
export declare function createViewer(container: HTMLElement, options: ViewerOptions): Viewer;
|
|
88
|
+
/** The options of `createDesignDocList`. */
|
|
89
|
+
export interface DesignDocListOptions extends DesignDocListContent, Pick<ViewerOptions, 'theme' | 'limitContentWidth'> {
|
|
90
|
+
/** The language of the texts of the list (`en` by default, or that of the browser). Only read by `createDesignDocList`. */
|
|
91
|
+
lang?: 'en' | 'ja';
|
|
92
|
+
/** Opens the link of a title (`href` of its document). By default, goes to it in the page (`openLinkInPage`). */
|
|
93
|
+
onOpenLink?: (href: string) => void;
|
|
94
|
+
}
|
|
95
|
+
export interface DesignDocList {
|
|
96
|
+
/** Resolves once the list is shown. */
|
|
97
|
+
ready: Promise<void>;
|
|
98
|
+
/** Changes some options (all but `lang`) and shows the list again, keeping its search and order. */
|
|
99
|
+
update(options: Partial<Omit<DesignDocListOptions, 'lang'>>): Promise<void>;
|
|
100
|
+
/** Removes the list from its element. */
|
|
101
|
+
destroy(): void;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* What `onOpenLink` of a list does by default: goes to the link in the page, as the links of a list are those of the
|
|
105
|
+
* app (except `javascript:`, `data:` and `vbscript:` ones).
|
|
106
|
+
*/
|
|
107
|
+
export declare function openLinkInPage(href: string): void;
|
|
108
|
+
/**
|
|
109
|
+
* Shows the list of the design documents of `options` in `container`: a table for each folder, with the main entries
|
|
110
|
+
* of their front matter, a search box and sortable columns. Unlike a viewer, it does not scroll inside the element:
|
|
111
|
+
* it is as high as the list.
|
|
112
|
+
*/
|
|
113
|
+
export declare function createDesignDocList(container: HTMLElement, options: DesignDocListOptions): DesignDocList;
|
|
72
114
|
/** The options of `exportHtml` (`markdown-design-doc-viewer-embed/export`). */
|
|
73
|
-
export interface ExportOptions extends Pick<ViewerOptions, 'markdown' | 'baseUrl' | 'readFile' | 'diagramLook' | 'splitMinWidth' | 'toc' | 'limitContentWidth' | 'stickyTableHeader' | 'tableTreeHighlight' | 'frontMatter' | 'headingNumbers' | 'messageWrapWidth'> {
|
|
115
|
+
export interface ExportOptions extends Pick<ViewerOptions, 'markdown' | 'baseUrl' | 'readFile' | 'diagramLook' | 'splitMinWidth' | 'toc' | 'limitContentWidth' | 'stickyTableHeader' | 'tableTreeHighlight' | 'frontMatter' | 'headingNumbers' | 'messageWrapWidth' | 'compareWith' | 'compareLabel'> {
|
|
74
116
|
/** The language of the texts of the exported file: `en`, or `ja`. That of the browser by default. */
|
|
75
117
|
lang?: 'en' | 'ja';
|
|
76
118
|
/** The title of the page when the document has none (neither `title` in its front matter nor a `#` heading). */
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation of the texts shown in the preview. The extension host passes `vscode.l10n.t`;
|
|
3
|
+
* the modules here do not import `vscode`, so they take the function as a parameter.
|
|
4
|
+
*/
|
|
5
|
+
/** Same signature as `vscode.l10n.t`: `message` is the English text, with `{0}`, `{1}`… for `args`. */
|
|
6
|
+
export type Translate = (message: string, ...args: (string | number)[]) => string;
|
|
7
|
+
/** Default `Translate` that keeps the English text and only fills in the arguments. */
|
|
8
|
+
export declare const formatMessage: Translate;
|
|
9
|
+
/** `Translate` with the translations of a bundle (l10n/bundle.l10n.<lang>.json), keeping the English text of the others. */
|
|
10
|
+
export declare function translatorFor(messages: Record<string, string>): Translate;
|
package/viewer.css
CHANGED
|
@@ -1761,3 +1761,12 @@ del.seqnotes-diff-del {
|
|
|
1761
1761
|
position: absolute;
|
|
1762
1762
|
max-width: calc(100% - 32px);
|
|
1763
1763
|
}
|
|
1764
|
+
.seqnotes-viewer.seqnotes-embedded.seqnotes-embedded-list {
|
|
1765
|
+
height: auto;
|
|
1766
|
+
}
|
|
1767
|
+
.seqnotes-embedded-list > .seqnotes-viewer-scroller {
|
|
1768
|
+
height: auto;
|
|
1769
|
+
overflow-x: auto;
|
|
1770
|
+
overflow-y: hidden;
|
|
1771
|
+
padding: 2px 0;
|
|
1772
|
+
}
|