@surrealdb/ui 1.2.11 → 1.2.13
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/.claude/launch.json +17 -0
- package/.oxfmtrc.json +27 -0
- package/.oxlintrc.json +23 -0
- package/.zed/settings.json +34 -34
- package/AGENTS.md +21 -19
- package/README.md +15 -10
- package/dist/assets/245b1ccaa4927818.svg +3 -0
- package/dist/assets/333e1fe6e67ca4a2.svg +10 -0
- package/dist/assets/4b0e10c655814886.svg +21 -0
- package/dist/assets/9932da008ea5dd32.svg +3 -0
- package/dist/assets/a372168d5789daa2.svg +4 -0
- package/dist/assets/b140e44ee4ae7e35.svg +5 -0
- package/dist/assets/e028075817d928e4.svg +3 -0
- package/dist/assets/ee1065ad5a8f7f14.svg +6 -0
- package/dist/ui.css +1 -1
- package/dist/ui.d.ts +579 -1
- package/dist/ui.js +11553 -8988
- package/dist/ui.js.map +1 -1
- package/doc/code-style.md +264 -0
- package/doc/stacker-plan.md +219 -0
- package/package.json +119 -115
- package/res/_mixins.scss +15 -11
- package/tests/_setup/e2e-helpers.tsx +85 -85
- package/tests/_setup/portable-stories.ts +11 -10
- package/tests/e2e/MarkdownEditor/content-blocks.test.tsx +140 -139
- package/tests/e2e/MarkdownEditor/edits.test.tsx +101 -100
- package/tests/e2e/MarkdownEditor/heading-fold.test.tsx +35 -34
- package/tests/e2e/MarkdownEditor/hybrid-widgets.test.tsx +178 -177
- package/tests/e2e/MarkdownEditor/image-on-image.test.tsx +50 -49
- package/tests/e2e/MarkdownEditor/jsx-block-content.test.tsx +195 -194
- package/tests/e2e/MarkdownEditor/jsx-highlight.test.tsx +47 -46
- package/tests/e2e/MarkdownEditor/jsx-inline-badges.test.tsx +35 -34
- package/tests/e2e/MarkdownEditor/jsx-inline-click.test.tsx +39 -38
- package/tests/e2e/MarkdownEditor/jsx-selection.test.tsx +28 -27
- package/tests/e2e/MarkdownEditor/link-placeholder.test.tsx +49 -48
- package/tests/e2e/MarkdownEditor/media-align.test.tsx +40 -39
- package/tests/e2e/MarkdownEditor/media-edit.test.tsx +49 -48
- package/tests/e2e/MarkdownEditor/media-sizing.test.tsx +108 -107
- package/tests/e2e/MarkdownEditor/modes.test.tsx +79 -78
- package/tests/e2e/MarkdownEditor/onimage-parity.test.tsx +29 -28
- package/tests/e2e/MarkdownEditor/regressions.test.tsx +194 -193
- package/tests/e2e/MarkdownEditor/slash-commands.test.tsx +81 -80
- package/tests/e2e/MarkdownEditor/table-click.test.tsx +36 -35
- package/tests/e2e/MarkdownEditor/table-controls.test.tsx +44 -43
- package/tests/e2e/MarkdownEditor/table-format.test.tsx +28 -27
- package/tests/e2e/MarkdownEditor/undo-redo.test.tsx +22 -21
- package/tests/e2e/MarkdownViewer/parity.test.tsx +144 -143
- package/tests/e2e/MarkdownViewer/render.test.tsx +20 -19
- package/tests/e2e/Stacker/stacker.test.tsx +304 -0
- package/tests/unit/Editor/helpers.test.ts +26 -26
- package/tests/unit/MarkdownConformance/error-isolation.test.tsx +26 -25
- package/tests/unit/MarkdownConformance/indentation.test.tsx +20 -19
- package/tests/unit/MarkdownConformance/inline-code-fuzz.test.tsx +255 -0
- package/tests/unit/MarkdownConformance/jsx-attributes.test.tsx +39 -38
- package/tests/unit/MarkdownConformance/jsx-fuzz.test.tsx +122 -122
- package/tests/unit/MarkdownConformance/links.test.tsx +78 -54
- package/tests/unit/MarkdownConformance/render-helpers.tsx +60 -60
- package/tests/unit/MarkdownEditor/code-info.test.ts +58 -58
- package/tests/unit/MarkdownEditor/decorations.test.ts +423 -421
- package/tests/unit/MarkdownEditor/editor-ready.test.ts +22 -22
- package/tests/unit/MarkdownEditor/html-descriptors.test.ts +70 -70
- package/tests/unit/MarkdownEditor/indented-fence.test.ts +80 -80
- package/tests/unit/MarkdownEditor/jsx-attr-scan.test.ts +87 -87
- package/tests/unit/MarkdownEditor/jsx-block-widget.test.ts +51 -51
- package/tests/unit/MarkdownEditor/jsx-tag-grammar.test.ts +63 -63
- package/tests/unit/MarkdownEditor/list-indent.test.ts +67 -67
- package/tests/unit/MarkdownEditor/slash-commands.test.ts +150 -150
- package/tests/unit/MarkdownEditor/table-format.test.ts +67 -67
- package/tests/unit/MarkdownEditor/table.test.ts +96 -96
- package/tests/unit/MarkdownEditor/triggers.test.ts +167 -167
- package/tests/unit/MarkdownEditor/widget-store.test.ts +90 -90
- package/tests/unit/MarkdownViewer/callout.test.tsx +42 -42
- package/tests/unit/MarkdownViewer/code-highlight.test.tsx +41 -41
- package/tests/unit/MarkdownViewer/code-title.test.tsx +45 -45
- package/tests/unit/MarkdownViewer/features.test.tsx +129 -129
- package/tests/unit/MarkdownViewer/headings.test.tsx +28 -28
- package/tests/unit/MarkdownViewer/indented-jsx-children.test.tsx +53 -53
- package/tests/unit/MarkdownViewer/jsx-block-nesting.test.tsx +137 -137
- package/tests/unit/MarkdownViewer/jsx.test.tsx +188 -188
- package/tests/unit/MarkdownViewer/list-bullets.test.tsx +31 -31
- package/tests/unit/MarkdownViewer/list-code.test.tsx +45 -45
- package/tests/unit/MarkdownViewer/preserve-newlines.test.tsx +109 -109
- package/tests/unit/MarkdownViewer/read-time.test.ts +13 -13
- package/tests/unit/MarkdownViewer/renderers.test.tsx +75 -75
- package/tests/unit/MarkdownViewer/runnable.test.tsx +51 -51
- package/tests/unit/MarkdownViewer/ssr.test.tsx +56 -55
- package/tests/unit/MarkdownViewer/syntax-highlighting.test.tsx +43 -42
- package/tests/unit/MarkdownViewer/tabs-fenced-code.test.tsx +120 -120
- package/tests/unit/MarkdownViewer/tabs.test.tsx +83 -82
- package/tests/unit/Stacker/drag.test.ts +21 -0
- package/tests/unit/Stacker/helpers.test.ts +105 -0
- package/tests/unit/Stacker/reducer.test.ts +107 -0
- package/tools/duplicate-vector-mappings.json +141 -141
- package/tools/glass-export-overrides.json +6 -6
- package/tools/icon-parser.ts +41 -40
- package/tools/integration-gradient-exports.json +55 -55
- package/tools/picto-compare.ts +32 -32
- package/tools/picto-merge-urls.ts +19 -19
- package/tools/picto-sync.ts +543 -543
- package/tools/picto-verify-gradients.ts +50 -50
- package/tools/vector-export-nodes.json +975 -975
|
@@ -7,158 +7,158 @@ import { renderToString } from "react-dom/server";
|
|
|
7
7
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
8
8
|
|
|
9
9
|
beforeAll(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
|
|
11
|
+
Object.defineProperty(window, "matchMedia", {
|
|
12
|
+
writable: true,
|
|
13
|
+
value: (query: string) => ({
|
|
14
|
+
matches: false,
|
|
15
|
+
media: query,
|
|
16
|
+
onchange: null,
|
|
17
|
+
addListener: () => {},
|
|
18
|
+
removeListener: () => {},
|
|
19
|
+
addEventListener: () => {},
|
|
20
|
+
removeEventListener: () => {},
|
|
21
|
+
dispatchEvent: () => false,
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
function shell(node: ReactElement): string {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
return renderToString(
|
|
29
|
+
<MantineProvider
|
|
30
|
+
theme={MANTINE_THEME}
|
|
31
|
+
cssVariablesResolver={v8CssVariablesResolver}
|
|
32
|
+
forceColorScheme="dark"
|
|
33
|
+
>
|
|
34
|
+
{node}
|
|
35
|
+
</MantineProvider>,
|
|
36
|
+
);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
describe("MarkdownViewer / features", () => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
it("renders bare URL autolinks as links", () => {
|
|
41
|
+
const html = shell(<MarkdownViewer content="Visit https://example.com today." />);
|
|
42
|
+
expect(html).toContain('href="https://example.com"');
|
|
43
|
+
expect(html).toContain("https://example.com");
|
|
44
|
+
});
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
it("renders www autolinks with https href", () => {
|
|
47
|
+
const html = shell(<MarkdownViewer content="Go to www.example.com" />);
|
|
48
|
+
expect(html).toContain('href="https://www.example.com"');
|
|
49
|
+
});
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
it("renders inline <u> and inline <Since /> with default components", () => {
|
|
52
|
+
const html = shell(
|
|
53
|
+
<MarkdownViewer content={'Text <u>underlined</u> and <Since v="2.0.0" /> here.'} />,
|
|
54
|
+
);
|
|
55
|
+
expect(html).toContain("<u>");
|
|
56
|
+
expect(html).toContain("underlined");
|
|
57
|
+
expect(html).toContain("2.0.0");
|
|
58
|
+
expect(html).not.toContain("<Since");
|
|
59
|
+
expect(html).not.toMatch(/<p[^>]*>underlined<\/p>/);
|
|
60
|
+
});
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
it("uses custom heading id from {#suffix}", () => {
|
|
63
|
+
const html = shell(<MarkdownViewer content="## Visible {#my-anchor}" />);
|
|
64
|
+
expect(html).toMatch(/id="my-anchor"/);
|
|
65
|
+
expect(html).toContain('href="#my-anchor"');
|
|
66
|
+
expect(html).not.toContain("{#my-anchor}");
|
|
67
|
+
});
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
it("extractHeadings respects custom {#id}", () => {
|
|
70
|
+
const source = "## Title {#custom}\n";
|
|
71
|
+
const tree = parseMarkdownTree(source);
|
|
72
|
+
const headings = extractHeadings(tree, markdownSourceFromString(source));
|
|
73
|
+
expect(headings[0]?.id).toBe("custom");
|
|
74
|
+
expect(headings[0]?.text).toBe("Title");
|
|
75
|
+
});
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
it("preserves ordered list start attribute", () => {
|
|
78
|
+
const html = shell(
|
|
79
|
+
<MarkdownViewer
|
|
80
|
+
content={`3. Third step
|
|
81
81
|
4. Fourth step`}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
/>,
|
|
83
|
+
);
|
|
84
|
+
expect(html).toMatch(/start="3"/);
|
|
85
|
+
expect(html).toContain("3.");
|
|
86
|
+
expect(html).toContain("4.");
|
|
87
|
+
});
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
it("renders HTML table cells with markdown and inline HTML", () => {
|
|
90
|
+
const html = shell(
|
|
91
|
+
<MarkdownViewer
|
|
92
|
+
content={`<table>
|
|
93
93
|
<thead><tr><th>Fn</th></tr></thead>
|
|
94
94
|
<tbody><tr><td>**bold** and <code>x</code></td></tr></tbody>
|
|
95
95
|
</table>`}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
96
|
+
/>,
|
|
97
|
+
);
|
|
98
|
+
expect(html).toContain("<table");
|
|
99
|
+
expect(html).toContain("bold");
|
|
100
|
+
expect(html).toContain("<code");
|
|
101
|
+
});
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
it("wraps a GFM table in a horizontal scroll container", () => {
|
|
104
|
+
const html = shell(
|
|
105
|
+
<MarkdownViewer
|
|
106
|
+
content={`| A | B |
|
|
107
107
|
| - | - |
|
|
108
108
|
| 1 | 2 |`}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
109
|
+
/>,
|
|
110
|
+
);
|
|
111
|
+
expect(html).toContain("mantine-TableScrollContainer-scrollContainer");
|
|
112
|
+
expect(html).toContain("<table");
|
|
113
|
+
expect(html).toContain("1");
|
|
114
|
+
});
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
it("wraps an HTML table in a horizontal scroll container", () => {
|
|
117
|
+
const html = shell(
|
|
118
|
+
<MarkdownViewer
|
|
119
|
+
content={`<table>
|
|
120
120
|
<tbody><tr><td>cell</td></tr></tbody>
|
|
121
121
|
</table>`}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
/>,
|
|
123
|
+
);
|
|
124
|
+
expect(html).toContain("mantine-TableScrollContainer-scrollContainer");
|
|
125
|
+
expect(html).toContain("<table");
|
|
126
|
+
expect(html).toContain("cell");
|
|
127
|
+
});
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
it("renders default Button component", () => {
|
|
130
|
+
const html = shell(
|
|
131
|
+
<MarkdownViewer content={'<Button label="Go" href="https://surrealdb.com" />'} />,
|
|
132
|
+
);
|
|
133
|
+
expect(html).toContain("Go");
|
|
134
|
+
expect(html).toContain('href="https://surrealdb.com"');
|
|
135
|
+
});
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
137
|
+
it("resolves image sources through onImage (e.g. CDN code → URL)", () => {
|
|
138
|
+
const html = shell(
|
|
139
|
+
<MarkdownViewer
|
|
140
|
+
content={""}
|
|
141
|
+
onResolveMedia={(node) => ({
|
|
142
|
+
...node,
|
|
143
|
+
src: `https://cdn.surrealdb.com/${node.src}.auto`,
|
|
144
|
+
})}
|
|
145
|
+
/>,
|
|
146
|
+
);
|
|
147
|
+
expect(html).toContain("cdn.surrealdb.com/cdn-code-123.auto");
|
|
148
|
+
expect(html).toContain("Example");
|
|
149
|
+
});
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
151
|
+
it("renders a video player when onImage resolves a source to a video container", () => {
|
|
152
|
+
const html = shell(
|
|
153
|
+
<MarkdownViewer
|
|
154
|
+
content={""}
|
|
155
|
+
onResolveMedia={(node) => ({
|
|
156
|
+
...node,
|
|
157
|
+
src: `https://cdn.surrealdb.com/${node.src}.mp4`,
|
|
158
|
+
})}
|
|
159
|
+
/>,
|
|
160
|
+
);
|
|
161
|
+
expect(html).toContain("cdn.surrealdb.com/cdn-video-123.mp4");
|
|
162
|
+
expect(html).toContain("<video");
|
|
163
|
+
});
|
|
164
164
|
});
|
|
@@ -2,39 +2,39 @@ import { extractHeadings, markdownSourceFromString, parseMarkdownTree } from "@s
|
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
3
|
|
|
4
4
|
describe("extractHeadings", () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
it("finds headings nested inside blockquotes", () => {
|
|
6
|
+
const source = "> ## Inside quote\n\n## Top";
|
|
7
|
+
const tree = parseMarkdownTree(source);
|
|
8
|
+
const headings = extractHeadings(tree, markdownSourceFromString(source));
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
expect(headings).toHaveLength(2);
|
|
11
|
+
expect(headings.map((h) => h.text)).toEqual(["Inside quote", "Top"]);
|
|
12
|
+
});
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
it("finds headings between details HTML blocks", () => {
|
|
15
|
+
const source = `<details>
|
|
16
16
|
<summary>Toggle</summary>
|
|
17
17
|
|
|
18
18
|
### Inside details
|
|
19
19
|
|
|
20
20
|
</details>`;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
21
|
+
const tree = parseMarkdownTree(source);
|
|
22
|
+
const headings = extractHeadings(tree, markdownSourceFromString(source), {
|
|
23
|
+
depths: [2, 3],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(headings).toHaveLength(1);
|
|
27
|
+
expect(headings[0]?.text).toBe("Inside details");
|
|
28
|
+
expect(headings[0]?.depth).toBe(3);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("strips inline emphasis marks from heading text", () => {
|
|
32
|
+
const source = "## Hello **world**";
|
|
33
|
+
const tree = parseMarkdownTree(source);
|
|
34
|
+
const headings = extractHeadings(tree, markdownSourceFromString(source));
|
|
35
|
+
|
|
36
|
+
expect(headings).toHaveLength(1);
|
|
37
|
+
expect(headings[0]?.text).toBe("Hello world");
|
|
38
|
+
expect(headings[0]?.id).toBe("hello-world");
|
|
39
|
+
});
|
|
40
40
|
});
|
|
@@ -8,55 +8,55 @@ import { renderToString } from "react-dom/server";
|
|
|
8
8
|
import { beforeAll, describe, expect, it } from "vitest";
|
|
9
9
|
|
|
10
10
|
beforeAll(() => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
|
|
12
|
+
Object.defineProperty(window, "matchMedia", {
|
|
13
|
+
writable: true,
|
|
14
|
+
value: (query: string) => ({
|
|
15
|
+
matches: false,
|
|
16
|
+
media: query,
|
|
17
|
+
onchange: null,
|
|
18
|
+
addListener: () => {},
|
|
19
|
+
removeListener: () => {},
|
|
20
|
+
addEventListener: () => {},
|
|
21
|
+
removeEventListener: () => {},
|
|
22
|
+
dispatchEvent: () => false,
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
function shell(node: ReactElement): string {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
return renderToString(
|
|
30
|
+
<MantineProvider
|
|
31
|
+
theme={MANTINE_THEME}
|
|
32
|
+
cssVariablesResolver={v8CssVariablesResolver}
|
|
33
|
+
forceColorScheme="dark"
|
|
34
|
+
>
|
|
35
|
+
{node}
|
|
36
|
+
</MantineProvider>,
|
|
37
|
+
);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function nodeNames(text: string): string[] {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
const tree = parseMarkdownTree(text);
|
|
42
|
+
const names: string[] = [];
|
|
43
|
+
const cursor = tree.cursor();
|
|
44
|
+
do {
|
|
45
|
+
names.push(cursor.name);
|
|
46
|
+
} while (cursor.next());
|
|
47
|
+
return names;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
function Boxes({ children }: { children?: ReactNode }): ReactElement {
|
|
51
|
-
|
|
51
|
+
return <div data-boxes>{children}</div>;
|
|
52
52
|
}
|
|
53
53
|
function IconBox({ title }: { title?: string }): ReactElement {
|
|
54
|
-
|
|
54
|
+
return <div data-iconbox>{title}</div>;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
const components: MarkdownComponents = {
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
Boxes: { component: Boxes, block: true },
|
|
59
|
+
IconBox: { component: IconBox, block: true },
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
// Children indented with tabs, exactly as authored in docs' index.mdx.
|
|
@@ -76,23 +76,23 @@ const CONTENT = `<Boxes>
|
|
|
76
76
|
</Boxes>`;
|
|
77
77
|
|
|
78
78
|
describe("MarkdownViewer / no indented code blocks", () => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
it("does not parse tab/4-space indented lines as code blocks", () => {
|
|
80
|
+
expect(nodeNames("\t<IconBox />")).not.toContain("CodeBlock");
|
|
81
|
+
expect(nodeNames(" plain indented text")).not.toContain("CodeBlock");
|
|
82
|
+
// Fenced code blocks still work.
|
|
83
|
+
expect(nodeNames("```\ncode\n```")).toContain("FencedCode");
|
|
84
|
+
});
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
it("renders tab-indented IconBox children inside a Boxes block", () => {
|
|
87
|
+
const html = shell(
|
|
88
|
+
<MarkdownViewer
|
|
89
|
+
content={CONTENT}
|
|
90
|
+
components={components}
|
|
91
|
+
/>,
|
|
92
|
+
);
|
|
93
|
+
expect(html).toContain("data-boxes");
|
|
94
|
+
expect(html).toContain("data-iconbox");
|
|
95
|
+
expect(html).toContain("Querying");
|
|
96
|
+
expect(html).toContain("Schema management");
|
|
97
|
+
});
|
|
98
98
|
});
|