@surrealdb/ui 1.2.12 → 1.2.14

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 (99) hide show
  1. package/.claude/launch.json +17 -0
  2. package/.oxfmtrc.json +27 -0
  3. package/.oxlintrc.json +23 -0
  4. package/.zed/settings.json +34 -34
  5. package/AGENTS.md +25 -19
  6. package/CLAUDE.md +111 -0
  7. package/README.md +15 -10
  8. package/dist/icons.d.ts +4 -0
  9. package/dist/icons.js +91 -89
  10. package/dist/icons.js.map +1 -1
  11. package/dist/ui.css +1 -1
  12. package/dist/ui.d.ts +259 -1
  13. package/dist/ui.js +9807 -12265
  14. package/dist/ui.js.map +1 -1
  15. package/doc/code-style.md +264 -0
  16. package/doc/release.md +102 -0
  17. package/doc/stacker-plan.md +219 -0
  18. package/package.json +120 -116
  19. package/release-notes.md +0 -0
  20. package/res/_mixins.scss +15 -11
  21. package/tests/_setup/e2e-helpers.tsx +85 -85
  22. package/tests/_setup/portable-stories.ts +11 -10
  23. package/tests/e2e/MarkdownEditor/content-blocks.test.tsx +140 -139
  24. package/tests/e2e/MarkdownEditor/edits.test.tsx +101 -100
  25. package/tests/e2e/MarkdownEditor/heading-fold.test.tsx +35 -34
  26. package/tests/e2e/MarkdownEditor/hybrid-widgets.test.tsx +178 -177
  27. package/tests/e2e/MarkdownEditor/image-on-image.test.tsx +50 -49
  28. package/tests/e2e/MarkdownEditor/jsx-block-content.test.tsx +195 -194
  29. package/tests/e2e/MarkdownEditor/jsx-highlight.test.tsx +47 -46
  30. package/tests/e2e/MarkdownEditor/jsx-inline-badges.test.tsx +35 -34
  31. package/tests/e2e/MarkdownEditor/jsx-inline-click.test.tsx +39 -38
  32. package/tests/e2e/MarkdownEditor/jsx-selection.test.tsx +28 -27
  33. package/tests/e2e/MarkdownEditor/link-placeholder.test.tsx +49 -48
  34. package/tests/e2e/MarkdownEditor/media-align.test.tsx +40 -39
  35. package/tests/e2e/MarkdownEditor/media-edit.test.tsx +49 -48
  36. package/tests/e2e/MarkdownEditor/media-sizing.test.tsx +108 -107
  37. package/tests/e2e/MarkdownEditor/modes.test.tsx +79 -78
  38. package/tests/e2e/MarkdownEditor/onimage-parity.test.tsx +29 -28
  39. package/tests/e2e/MarkdownEditor/regressions.test.tsx +194 -193
  40. package/tests/e2e/MarkdownEditor/slash-commands.test.tsx +81 -80
  41. package/tests/e2e/MarkdownEditor/table-click.test.tsx +36 -35
  42. package/tests/e2e/MarkdownEditor/table-controls.test.tsx +44 -43
  43. package/tests/e2e/MarkdownEditor/table-format.test.tsx +28 -27
  44. package/tests/e2e/MarkdownEditor/undo-redo.test.tsx +22 -21
  45. package/tests/e2e/MarkdownViewer/parity.test.tsx +144 -143
  46. package/tests/e2e/MarkdownViewer/render.test.tsx +20 -19
  47. package/tests/e2e/Stacker/stacker.test.tsx +304 -0
  48. package/tests/unit/Editor/helpers.test.ts +26 -26
  49. package/tests/unit/MarkdownConformance/error-isolation.test.tsx +26 -25
  50. package/tests/unit/MarkdownConformance/indentation.test.tsx +20 -19
  51. package/tests/unit/MarkdownConformance/inline-code-fuzz.test.tsx +255 -0
  52. package/tests/unit/MarkdownConformance/jsx-attributes.test.tsx +39 -38
  53. package/tests/unit/MarkdownConformance/jsx-fuzz.test.tsx +122 -122
  54. package/tests/unit/MarkdownConformance/links.test.tsx +78 -54
  55. package/tests/unit/MarkdownConformance/render-helpers.tsx +60 -60
  56. package/tests/unit/MarkdownEditor/code-info.test.ts +58 -58
  57. package/tests/unit/MarkdownEditor/decorations.test.ts +423 -421
  58. package/tests/unit/MarkdownEditor/editor-ready.test.ts +22 -22
  59. package/tests/unit/MarkdownEditor/html-descriptors.test.ts +70 -70
  60. package/tests/unit/MarkdownEditor/indented-fence.test.ts +80 -80
  61. package/tests/unit/MarkdownEditor/jsx-attr-scan.test.ts +87 -87
  62. package/tests/unit/MarkdownEditor/jsx-block-widget.test.ts +51 -51
  63. package/tests/unit/MarkdownEditor/jsx-tag-grammar.test.ts +63 -63
  64. package/tests/unit/MarkdownEditor/list-indent.test.ts +67 -67
  65. package/tests/unit/MarkdownEditor/slash-commands.test.ts +150 -150
  66. package/tests/unit/MarkdownEditor/table-format.test.ts +67 -67
  67. package/tests/unit/MarkdownEditor/table.test.ts +96 -96
  68. package/tests/unit/MarkdownEditor/triggers.test.ts +167 -167
  69. package/tests/unit/MarkdownEditor/widget-store.test.ts +90 -90
  70. package/tests/unit/MarkdownViewer/callout.test.tsx +42 -42
  71. package/tests/unit/MarkdownViewer/code-highlight.test.tsx +41 -41
  72. package/tests/unit/MarkdownViewer/code-title.test.tsx +45 -45
  73. package/tests/unit/MarkdownViewer/features.test.tsx +129 -129
  74. package/tests/unit/MarkdownViewer/headings.test.tsx +28 -28
  75. package/tests/unit/MarkdownViewer/indented-jsx-children.test.tsx +53 -53
  76. package/tests/unit/MarkdownViewer/jsx-block-nesting.test.tsx +137 -137
  77. package/tests/unit/MarkdownViewer/jsx.test.tsx +188 -188
  78. package/tests/unit/MarkdownViewer/list-bullets.test.tsx +31 -31
  79. package/tests/unit/MarkdownViewer/list-code.test.tsx +45 -45
  80. package/tests/unit/MarkdownViewer/preserve-newlines.test.tsx +109 -109
  81. package/tests/unit/MarkdownViewer/read-time.test.ts +13 -13
  82. package/tests/unit/MarkdownViewer/renderers.test.tsx +75 -75
  83. package/tests/unit/MarkdownViewer/runnable.test.tsx +51 -51
  84. package/tests/unit/MarkdownViewer/ssr.test.tsx +56 -55
  85. package/tests/unit/MarkdownViewer/syntax-highlighting.test.tsx +43 -42
  86. package/tests/unit/MarkdownViewer/tabs-fenced-code.test.tsx +120 -120
  87. package/tests/unit/MarkdownViewer/tabs.test.tsx +83 -82
  88. package/tests/unit/Stacker/drag.test.ts +21 -0
  89. package/tests/unit/Stacker/helpers.test.ts +105 -0
  90. package/tests/unit/Stacker/reducer.test.ts +107 -0
  91. package/tools/duplicate-vector-mappings.json +141 -141
  92. package/tools/glass-export-overrides.json +6 -6
  93. package/tools/icon-parser.ts +41 -40
  94. package/tools/integration-gradient-exports.json +55 -55
  95. package/tools/picto-compare.ts +32 -32
  96. package/tools/picto-merge-urls.ts +19 -19
  97. package/tools/picto-sync.ts +543 -543
  98. package/tools/picto-verify-gradients.ts +50 -50
  99. package/tools/vector-export-nodes.json +975 -975
@@ -3,51 +3,52 @@ import { MarkdownEditor } from "@src/primitives/MarkdownEditor";
3
3
  import { MANTINE_THEME } from "@src/theme/mantine";
4
4
  import { describe, expect, it } from "vitest";
5
5
  import { page } from "vitest/browser";
6
+
6
7
  import { getEditorView, mountStory, nextFrame } from "../../_setup/e2e-helpers";
7
8
 
8
9
  const DOC = 'Text with <Since v="1.5.0" /> inline here.\n';
9
10
 
10
11
  describe("MarkdownEditor / inline JSX click reveal", () => {
11
- it("reveals the raw source when an inline component badge is clicked", async () => {
12
- mountStory(
13
- <MantineProvider
14
- theme={MANTINE_THEME}
15
- cssVariablesResolver={v8CssVariablesResolver}
16
- forceColorScheme="dark"
17
- >
18
- <Paper
19
- p="md"
20
- withBorder
21
- >
22
- <MarkdownEditor
23
- mode="preview"
24
- document={DOC}
25
- autoFocus={false}
26
- jsxMode="render"
27
- />
28
- </Paper>
29
- </MantineProvider>,
30
- );
12
+ it("reveals the raw source when an inline component badge is clicked", async () => {
13
+ mountStory(
14
+ <MantineProvider
15
+ theme={MANTINE_THEME}
16
+ cssVariablesResolver={v8CssVariablesResolver}
17
+ forceColorScheme="dark"
18
+ >
19
+ <Paper
20
+ p="md"
21
+ withBorder
22
+ >
23
+ <MarkdownEditor
24
+ mode="preview"
25
+ document={DOC}
26
+ autoFocus={false}
27
+ jsxMode="render"
28
+ />
29
+ </Paper>
30
+ </MantineProvider>,
31
+ );
31
32
 
32
- const view = await getEditorView();
33
- await nextFrame();
33
+ const view = await getEditorView();
34
+ await nextFrame();
34
35
 
35
- // Inactive: the badge renders and the raw tag is hidden.
36
- expect(document.querySelector(".cm-content")?.textContent).not.toContain("<Since");
36
+ // Inactive: the badge renders and the raw tag is hidden.
37
+ expect(document.querySelector(".cm-content")?.textContent).not.toContain("<Since");
37
38
 
38
- // Click the rendered inline badge.
39
- await page.getByText("1.5.0").click();
40
- await nextFrame();
41
- await nextFrame();
39
+ // Click the rendered inline badge.
40
+ await page.getByText("1.5.0").click();
41
+ await nextFrame();
42
+ await nextFrame();
42
43
 
43
- // The click selects the component's entire source range (not just a caret),
44
- // revealing the raw markup for editing.
45
- const sel = view.state.selection.main;
46
- const from = DOC.indexOf("<Since");
47
- const to = DOC.indexOf("/>") + 2;
48
- expect(sel.from).toBe(from);
49
- expect(sel.to).toBe(to);
50
- expect(sel.empty).toBe(false);
51
- expect(document.querySelector(".cm-content")?.textContent).toContain("<Since");
52
- });
44
+ // The click selects the component's entire source range (not just a caret),
45
+ // revealing the raw markup for editing.
46
+ const sel = view.state.selection.main;
47
+ const from = DOC.indexOf("<Since");
48
+ const to = DOC.indexOf("/>") + 2;
49
+ expect(sel.from).toBe(from);
50
+ expect(sel.to).toBe(to);
51
+ expect(sel.empty).toBe(false);
52
+ expect(document.querySelector(".cm-content")?.textContent).toContain("<Since");
53
+ });
53
54
  });
@@ -3,6 +3,7 @@ import { MarkdownEditor } from "@src/primitives/MarkdownEditor";
3
3
  import { Since } from "@src/primitives/Since";
4
4
  import { MANTINE_THEME } from "@src/theme/mantine";
5
5
  import { describe, expect, it } from "vitest";
6
+
6
7
  import { getEditorView, mountStory, nextFrame } from "../../_setup/e2e-helpers";
7
8
 
8
9
  const JSX_DOC = `<Since v="9.9.9" />
@@ -11,33 +12,33 @@ Paragraph after component.
11
12
  `;
12
13
 
13
14
  describe("MarkdownEditor / JSX selection reveal", () => {
14
- it("shows JSX widget when inactive and raw source when caret is inside the tag", async () => {
15
- mountStory(
16
- <MantineProvider
17
- theme={MANTINE_THEME}
18
- cssVariablesResolver={v8CssVariablesResolver}
19
- forceColorScheme="dark"
20
- >
21
- <Paper
22
- p="md"
23
- withBorder
24
- >
25
- <MarkdownEditor
26
- mode="preview"
27
- document={JSX_DOC}
28
- autoFocus={false}
29
- jsxMode="render"
30
- components={{ Since }}
31
- />
32
- </Paper>
33
- </MantineProvider>,
34
- );
15
+ it("shows JSX widget when inactive and raw source when caret is inside the tag", async () => {
16
+ mountStory(
17
+ <MantineProvider
18
+ theme={MANTINE_THEME}
19
+ cssVariablesResolver={v8CssVariablesResolver}
20
+ forceColorScheme="dark"
21
+ >
22
+ <Paper
23
+ p="md"
24
+ withBorder
25
+ >
26
+ <MarkdownEditor
27
+ mode="preview"
28
+ document={JSX_DOC}
29
+ autoFocus={false}
30
+ jsxMode="render"
31
+ components={{ Since }}
32
+ />
33
+ </Paper>
34
+ </MantineProvider>,
35
+ );
35
36
 
36
- const view = await getEditorView();
37
- view.contentDOM.blur();
38
- await nextFrame();
37
+ const view = await getEditorView();
38
+ view.contentDOM.blur();
39
+ await nextFrame();
39
40
 
40
- expect(document.body.textContent).toContain("9.9.9");
41
- expect(document.querySelector(".cm-content")?.textContent).not.toContain("<Since");
42
- });
41
+ expect(document.body.textContent).toContain("9.9.9");
42
+ expect(document.querySelector(".cm-content")?.textContent).not.toContain("<Since");
43
+ });
43
44
  });
@@ -4,64 +4,65 @@ import { setMarkdownEditorFocused } from "@src/lib/markdown/editor/decorations/e
4
4
  import { MarkdownEditor } from "@src/primitives/MarkdownEditor";
5
5
  import { MANTINE_THEME } from "@src/theme/mantine";
6
6
  import { describe, expect, it } from "vitest";
7
+
7
8
  import { getEditorView, mountStory, nextFrame } from "../../_setup/e2e-helpers";
8
9
 
9
10
  function shell(doc: string) {
10
- return (
11
- <MantineProvider
12
- theme={MANTINE_THEME}
13
- cssVariablesResolver={v8CssVariablesResolver}
14
- forceColorScheme="dark"
15
- >
16
- <Paper p="md">
17
- <MarkdownEditor
18
- mode="preview"
19
- document={doc}
20
- autoFocus={false}
21
- />
22
- </Paper>
23
- </MantineProvider>
24
- );
11
+ return (
12
+ <MantineProvider
13
+ theme={MANTINE_THEME}
14
+ cssVariablesResolver={v8CssVariablesResolver}
15
+ forceColorScheme="dark"
16
+ >
17
+ <Paper p="md">
18
+ <MarkdownEditor
19
+ mode="preview"
20
+ document={doc}
21
+ autoFocus={false}
22
+ />
23
+ </Paper>
24
+ </MantineProvider>
25
+ );
25
26
  }
26
27
 
27
28
  async function caretAt(doc: string, index: number) {
28
- mountStory(shell(doc));
29
- const view = await getEditorView();
30
- view.focus();
31
- view.dispatch({
32
- selection: EditorSelection.cursor(index),
33
- effects: setMarkdownEditorFocused.of(true),
34
- });
35
- await nextFrame();
36
- await nextFrame();
37
- return view;
29
+ mountStory(shell(doc));
30
+ const view = await getEditorView();
31
+ view.focus();
32
+ view.dispatch({
33
+ selection: EditorSelection.cursor(index),
34
+ effects: setMarkdownEditorFocused.of(true),
35
+ });
36
+ await nextFrame();
37
+ await nextFrame();
38
+ return view;
38
39
  }
39
40
 
40
41
  describe("MarkdownEditor / link placeholders", () => {
41
- it("shows an 'alt text' placeholder for an empty link label", async () => {
42
- const doc = "[](https://surrealdb.com)";
43
- await caretAt(doc, 1); // caret between the empty []
44
- expect(document.querySelector(".cm-content")?.textContent).toContain("alt text");
45
- });
42
+ it("shows an 'alt text' placeholder for an empty link label", async () => {
43
+ const doc = "[](https://surrealdb.com)";
44
+ await caretAt(doc, 1); // caret between the empty []
45
+ expect(document.querySelector(".cm-content")?.textContent).toContain("alt text");
46
+ });
46
47
 
47
- it("shows a 'link' placeholder for an empty link destination", async () => {
48
- const doc = "[label]()";
49
- await caretAt(doc, doc.indexOf("(") + 1); // caret between the empty ()
50
- const text = document.querySelector(".cm-content")?.textContent ?? "";
51
- expect(text).toContain("link");
52
- });
48
+ it("shows a 'link' placeholder for an empty link destination", async () => {
49
+ const doc = "[label]()";
50
+ await caretAt(doc, doc.indexOf("(") + 1); // caret between the empty ()
51
+ const text = document.querySelector(".cm-content")?.textContent ?? "";
52
+ expect(text).toContain("link");
53
+ });
53
54
 
54
- it("shows both placeholders for a fully empty link", async () => {
55
- const doc = "[]()";
56
- await caretAt(doc, 1);
57
- const text = document.querySelector(".cm-content")?.textContent ?? "";
58
- expect(text).toContain("alt text");
59
- expect(text).toContain("link");
60
- });
55
+ it("shows both placeholders for a fully empty link", async () => {
56
+ const doc = "[]()";
57
+ await caretAt(doc, 1);
58
+ const text = document.querySelector(".cm-content")?.textContent ?? "";
59
+ expect(text).toContain("alt text");
60
+ expect(text).toContain("link");
61
+ });
61
62
 
62
- it("does not show placeholders once the sections have content", async () => {
63
- const doc = "[label](https://surrealdb.com)";
64
- await caretAt(doc, 3);
65
- expect(document.querySelector(".cm-content")?.textContent).not.toContain("alt text");
66
- });
63
+ it("does not show placeholders once the sections have content", async () => {
64
+ const doc = "[label](https://surrealdb.com)";
65
+ await caretAt(doc, 3);
66
+ expect(document.querySelector(".cm-content")?.textContent).not.toContain("alt text");
67
+ });
67
68
  });
@@ -4,54 +4,55 @@ import { setMarkdownEditorFocused } from "@src/lib/markdown/editor/decorations/e
4
4
  import { MarkdownEditor } from "@src/primitives/MarkdownEditor";
5
5
  import { MANTINE_THEME } from "@src/theme/mantine";
6
6
  import { describe, expect, it } from "vitest";
7
+
7
8
  import { getEditorView, mountStory, nextFrame, sleep } from "../../_setup/e2e-helpers";
8
9
 
9
10
  const DOC =
10
- "Regular paragraph line.\n\n![Some alt text](https://surrealdb.com/static/logo/light.svg)\n\nAnother paragraph.\n";
11
+ "Regular paragraph line.\n\n![Some alt text](https://surrealdb.com/static/logo/light.svg)\n\nAnother paragraph.\n";
11
12
 
12
13
  /** Left edge of a line's rendered text content (text nodes have no element box). */
13
14
  function textLeft(line: HTMLElement): number {
14
- const range = document.createRange();
15
- range.selectNodeContents(line);
16
- return range.getBoundingClientRect().left;
15
+ const range = document.createRange();
16
+ range.selectNodeContents(line);
17
+ return range.getBoundingClientRect().left;
17
18
  }
18
19
 
19
20
  describe("MarkdownEditor / media alignment", () => {
20
- it("aligns the image preview's left edge with regular text", async () => {
21
- mountStory(
22
- <MantineProvider
23
- theme={MANTINE_THEME}
24
- cssVariablesResolver={v8CssVariablesResolver}
25
- forceColorScheme="dark"
26
- >
27
- <Paper p="md">
28
- <MarkdownEditor
29
- mode="preview"
30
- document={DOC}
31
- autoFocus={false}
32
- />
33
- </Paper>
34
- </MantineProvider>,
35
- );
36
- const view = await getEditorView();
37
- view.focus();
38
- view.dispatch({
39
- selection: EditorSelection.cursor(view.state.doc.length),
40
- effects: setMarkdownEditorFocused.of(true),
41
- });
42
- await sleep(200);
43
- await nextFrame();
21
+ it("aligns the image preview's left edge with regular text", async () => {
22
+ mountStory(
23
+ <MantineProvider
24
+ theme={MANTINE_THEME}
25
+ cssVariablesResolver={v8CssVariablesResolver}
26
+ forceColorScheme="dark"
27
+ >
28
+ <Paper p="md">
29
+ <MarkdownEditor
30
+ mode="preview"
31
+ document={DOC}
32
+ autoFocus={false}
33
+ />
34
+ </Paper>
35
+ </MantineProvider>,
36
+ );
37
+ const view = await getEditorView();
38
+ view.focus();
39
+ view.dispatch({
40
+ selection: EditorSelection.cursor(view.state.doc.length),
41
+ effects: setMarkdownEditorFocused.of(true),
42
+ });
43
+ await sleep(200);
44
+ await nextFrame();
44
45
 
45
- const para = Array.from(document.querySelectorAll<HTMLElement>(".cm-line")).find((l) =>
46
- (l.textContent ?? "").includes("Regular"),
47
- );
48
- const img = document.querySelector<HTMLElement>('[data-md-widget="ImageWidget"] img');
49
- expect(para).toBeTruthy();
50
- expect(img).toBeTruthy();
46
+ const para = Array.from(document.querySelectorAll<HTMLElement>(".cm-line")).find((l) =>
47
+ (l.textContent ?? "").includes("Regular"),
48
+ );
49
+ const img = document.querySelector<HTMLElement>('[data-md-widget="ImageWidget"] img');
50
+ expect(para).toBeTruthy();
51
+ expect(img).toBeTruthy();
51
52
 
52
- const paraLeft = textLeft(para as HTMLElement);
53
- const imageLeft = (img as HTMLElement).getBoundingClientRect().left;
54
- // Within a pixel of the text inset (previously 6px to the left).
55
- expect(Math.abs(imageLeft - paraLeft)).toBeLessThanOrEqual(1.5);
56
- });
53
+ const paraLeft = textLeft(para as HTMLElement);
54
+ const imageLeft = (img as HTMLElement).getBoundingClientRect().left;
55
+ // Within a pixel of the text inset (previously 6px to the left).
56
+ expect(Math.abs(imageLeft - paraLeft)).toBeLessThanOrEqual(1.5);
57
+ });
57
58
  });
@@ -4,60 +4,61 @@ import { setMarkdownEditorFocused } from "@src/lib/markdown/editor/decorations/e
4
4
  import { MarkdownEditor } from "@src/primitives/MarkdownEditor";
5
5
  import { MANTINE_THEME } from "@src/theme/mantine";
6
6
  import { describe, expect, it } from "vitest";
7
+
7
8
  import { getEditorView, mountStory, nextFrame, sleep } from "../../_setup/e2e-helpers";
8
9
 
9
10
  const IMAGE_DOC = "![A logo](https://surrealdb.com/static/logo/light.svg)\n\nParagraph after.\n";
10
11
 
11
12
  function shell(doc: string) {
12
- return (
13
- <MantineProvider
14
- theme={MANTINE_THEME}
15
- cssVariablesResolver={v8CssVariablesResolver}
16
- forceColorScheme="dark"
17
- >
18
- <Paper
19
- p="md"
20
- withBorder
21
- >
22
- <MarkdownEditor
23
- mode="preview"
24
- document={doc}
25
- autoFocus={false}
26
- />
27
- </Paper>
28
- </MantineProvider>
29
- );
13
+ return (
14
+ <MantineProvider
15
+ theme={MANTINE_THEME}
16
+ cssVariablesResolver={v8CssVariablesResolver}
17
+ forceColorScheme="dark"
18
+ >
19
+ <Paper
20
+ p="md"
21
+ withBorder
22
+ >
23
+ <MarkdownEditor
24
+ mode="preview"
25
+ document={doc}
26
+ autoFocus={false}
27
+ />
28
+ </Paper>
29
+ </MantineProvider>
30
+ );
30
31
  }
31
32
 
32
33
  describe("MarkdownEditor / media edit action", () => {
33
- it("shows an image preview with an edit-source action that reveals the source", async () => {
34
- mountStory(shell(IMAGE_DOC));
35
- const view = await getEditorView();
36
-
37
- // Focused, with the caret away from the image, so the image renders as a
38
- // preview widget rather than raw source.
39
- view.focus();
40
- view.dispatch({
41
- selection: EditorSelection.cursor(view.state.doc.length),
42
- effects: setMarkdownEditorFocused.of(true),
43
- });
44
- await nextFrame();
45
- await nextFrame();
46
-
47
- expect(document.querySelector(".cm-content")?.textContent).not.toContain("![A logo]");
48
- expect(document.querySelector("img")).not.toBeNull();
49
-
50
- const action = document.querySelector<HTMLButtonElement>(
51
- 'button[aria-label="Edit source"]',
52
- );
53
- expect(action).not.toBeNull();
54
-
55
- action?.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, button: 0 }));
56
- await sleep(120);
57
- await nextFrame();
58
-
59
- // The image markdown source becomes visible and is selected.
60
- expect(document.querySelector(".cm-content")?.textContent).toContain("![A logo]");
61
- expect(view.state.selection.main.empty).toBe(false);
62
- });
34
+ it("shows an image preview with an edit-source action that reveals the source", async () => {
35
+ mountStory(shell(IMAGE_DOC));
36
+ const view = await getEditorView();
37
+
38
+ // Focused, with the caret away from the image, so the image renders as a
39
+ // preview widget rather than raw source.
40
+ view.focus();
41
+ view.dispatch({
42
+ selection: EditorSelection.cursor(view.state.doc.length),
43
+ effects: setMarkdownEditorFocused.of(true),
44
+ });
45
+ await nextFrame();
46
+ await nextFrame();
47
+
48
+ expect(document.querySelector(".cm-content")?.textContent).not.toContain("![A logo]");
49
+ expect(document.querySelector("img")).not.toBeNull();
50
+
51
+ const action = document.querySelector<HTMLButtonElement>(
52
+ 'button[aria-label="Edit source"]',
53
+ );
54
+ expect(action).not.toBeNull();
55
+
56
+ action?.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, button: 0 }));
57
+ await sleep(120);
58
+ await nextFrame();
59
+
60
+ // The image markdown source becomes visible and is selected.
61
+ expect(document.querySelector(".cm-content")?.textContent).toContain("![A logo]");
62
+ expect(view.state.selection.main.empty).toBe(false);
63
+ });
63
64
  });