@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
@@ -2,104 +2,104 @@ import { createWidgetStore } from "@src/lib/markdown/editor/widgets/store";
2
2
  import { describe, expect, it } from "vitest";
3
3
 
4
4
  describe("createWidgetStore", () => {
5
- it("unregisterHost removes only the portal whose host identity matches registration", () => {
6
- const store = createWidgetStore();
7
- const host214 = document.createElement("span");
8
- const host227 = document.createElement("span");
9
- store.register({
10
- portalKey: 1,
11
- id: "list-bullet:214",
12
- host: host214,
13
- render: () => null,
14
- });
15
- store.register({
16
- portalKey: 2,
17
- id: "list-bullet:227",
18
- host: host227,
19
- render: () => null,
20
- });
21
- expect(store.getSnapshot()).toHaveLength(2);
5
+ it("unregisterHost removes only the portal whose host identity matches registration", () => {
6
+ const store = createWidgetStore();
7
+ const host214 = document.createElement("span");
8
+ const host227 = document.createElement("span");
9
+ store.register({
10
+ portalKey: 1,
11
+ id: "list-bullet:214",
12
+ host: host214,
13
+ render: () => null,
14
+ });
15
+ store.register({
16
+ portalKey: 2,
17
+ id: "list-bullet:227",
18
+ host: host227,
19
+ render: () => null,
20
+ });
21
+ expect(store.getSnapshot()).toHaveLength(2);
22
22
 
23
- expect(store.hasPortalKey(1)).toBe(true);
24
- expect(store.hasPortalKey(99)).toBe(false);
23
+ expect(store.hasPortalKey(1)).toBe(true);
24
+ expect(store.hasPortalKey(99)).toBe(false);
25
25
 
26
- store.unregisterHost(host214);
27
- expect(store.getSnapshot()).toHaveLength(1);
28
- expect(store.getSnapshot()[0]?.id).toBe("list-bullet:227");
26
+ store.unregisterHost(host214);
27
+ expect(store.getSnapshot()).toHaveLength(1);
28
+ expect(store.getSnapshot()[0]?.id).toBe("list-bullet:227");
29
29
 
30
- store.unregisterHost(host227);
31
- expect(store.getSnapshot()).toHaveLength(0);
32
- });
30
+ store.unregisterHost(host227);
31
+ expect(store.getSnapshot()).toHaveLength(0);
32
+ });
33
33
 
34
- it("same logical id on two hosts keeps two portals until each host unregisters", () => {
35
- const store = createWidgetStore();
36
- const hostA = document.createElement("span");
37
- const hostB = document.createElement("span");
38
- store.register({
39
- portalKey: 10,
40
- id: "list-bullet:214",
41
- host: hostA,
42
- render: () => null,
43
- });
44
- store.register({
45
- portalKey: 11,
46
- id: "list-bullet:214",
47
- host: hostB,
48
- render: () => null,
49
- });
50
- expect(store.getSnapshot()).toHaveLength(2);
34
+ it("same logical id on two hosts keeps two portals until each host unregisters", () => {
35
+ const store = createWidgetStore();
36
+ const hostA = document.createElement("span");
37
+ const hostB = document.createElement("span");
38
+ store.register({
39
+ portalKey: 10,
40
+ id: "list-bullet:214",
41
+ host: hostA,
42
+ render: () => null,
43
+ });
44
+ store.register({
45
+ portalKey: 11,
46
+ id: "list-bullet:214",
47
+ host: hostB,
48
+ render: () => null,
49
+ });
50
+ expect(store.getSnapshot()).toHaveLength(2);
51
51
 
52
- store.unregisterHost(hostA);
53
- expect(store.getSnapshot()).toHaveLength(1);
54
- expect(store.getSnapshot()[0]?.host).toBe(hostB);
52
+ store.unregisterHost(hostA);
53
+ expect(store.getSnapshot()).toHaveLength(1);
54
+ expect(store.getSnapshot()[0]?.host).toBe(hostB);
55
55
 
56
- store.unregisterHost(hostB);
57
- expect(store.getSnapshot()).toHaveLength(0);
58
- });
56
+ store.unregisterHost(hostB);
57
+ expect(store.getSnapshot()).toHaveLength(0);
58
+ });
59
59
 
60
- it("re-registering the same host evicts the previous portalKey (one portal per host)", () => {
61
- const store = createWidgetStore();
62
- const host = document.createElement("span");
63
- store.register({
64
- portalKey: 1,
65
- id: "checkbox:2-5",
66
- host,
67
- render: () => null,
68
- });
69
- expect(store.getSnapshot()).toHaveLength(1);
60
+ it("re-registering the same host evicts the previous portalKey (one portal per host)", () => {
61
+ const store = createWidgetStore();
62
+ const host = document.createElement("span");
63
+ store.register({
64
+ portalKey: 1,
65
+ id: "checkbox:2-5",
66
+ host,
67
+ render: () => null,
68
+ });
69
+ expect(store.getSnapshot()).toHaveLength(1);
70
70
 
71
- store.register({
72
- portalKey: 2,
73
- id: "checkbox:2-5",
74
- host,
75
- render: () => null,
76
- });
77
- expect(store.getSnapshot()).toHaveLength(1);
78
- expect(store.getSnapshot()[0]?.portalKey).toBe(2);
79
- expect(store.hasPortalKey(1)).toBe(false);
80
- expect(store.hasPortalKey(2)).toBe(true);
81
- });
71
+ store.register({
72
+ portalKey: 2,
73
+ id: "checkbox:2-5",
74
+ host,
75
+ render: () => null,
76
+ });
77
+ expect(store.getSnapshot()).toHaveLength(1);
78
+ expect(store.getSnapshot()[0]?.portalKey).toBe(2);
79
+ expect(store.hasPortalKey(1)).toBe(false);
80
+ expect(store.hasPortalKey(2)).toBe(true);
81
+ });
82
82
 
83
- it("unregisterHost with expectedPortalKey skips when a newer registration owns the host", () => {
84
- const store = createWidgetStore();
85
- const host = document.createElement("span");
86
- store.register({
87
- portalKey: 10,
88
- id: "checkbox:2-5",
89
- host,
90
- render: () => null,
91
- });
92
- store.register({
93
- portalKey: 11,
94
- id: "checkbox:2-5",
95
- host,
96
- render: () => null,
97
- });
98
- store.unregisterHost(host, 10);
99
- expect(store.getSnapshot()).toHaveLength(1);
100
- expect(store.getSnapshot()[0]?.portalKey).toBe(11);
83
+ it("unregisterHost with expectedPortalKey skips when a newer registration owns the host", () => {
84
+ const store = createWidgetStore();
85
+ const host = document.createElement("span");
86
+ store.register({
87
+ portalKey: 10,
88
+ id: "checkbox:2-5",
89
+ host,
90
+ render: () => null,
91
+ });
92
+ store.register({
93
+ portalKey: 11,
94
+ id: "checkbox:2-5",
95
+ host,
96
+ render: () => null,
97
+ });
98
+ store.unregisterHost(host, 10);
99
+ expect(store.getSnapshot()).toHaveLength(1);
100
+ expect(store.getSnapshot()[0]?.portalKey).toBe(11);
101
101
 
102
- store.unregisterHost(host, 11);
103
- expect(store.getSnapshot()).toHaveLength(0);
104
- });
102
+ store.unregisterHost(host, 11);
103
+ expect(store.getSnapshot()).toHaveLength(0);
104
+ });
105
105
  });
@@ -6,55 +6,55 @@ import { renderToString } from "react-dom/server";
6
6
  import { beforeAll, describe, expect, it } from "vitest";
7
7
 
8
8
  beforeAll(() => {
9
- if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
10
- Object.defineProperty(window, "matchMedia", {
11
- writable: true,
12
- value: (query: string) => ({
13
- matches: false,
14
- media: query,
15
- onchange: null,
16
- addListener: () => {},
17
- removeListener: () => {},
18
- addEventListener: () => {},
19
- removeEventListener: () => {},
20
- dispatchEvent: () => false,
21
- }),
22
- });
23
- }
9
+ if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
10
+ Object.defineProperty(window, "matchMedia", {
11
+ writable: true,
12
+ value: (query: string) => ({
13
+ matches: false,
14
+ media: query,
15
+ onchange: null,
16
+ addListener: () => {},
17
+ removeListener: () => {},
18
+ addEventListener: () => {},
19
+ removeEventListener: () => {},
20
+ dispatchEvent: () => false,
21
+ }),
22
+ });
23
+ }
24
24
  });
25
25
 
26
26
  function shell(node: ReactElement): string {
27
- return renderToString(
28
- <MantineProvider
29
- theme={MANTINE_THEME}
30
- cssVariablesResolver={v8CssVariablesResolver}
31
- forceColorScheme="dark"
32
- >
33
- {node}
34
- </MantineProvider>,
35
- );
27
+ return renderToString(
28
+ <MantineProvider
29
+ theme={MANTINE_THEME}
30
+ cssVariablesResolver={v8CssVariablesResolver}
31
+ forceColorScheme="dark"
32
+ >
33
+ {node}
34
+ </MantineProvider>,
35
+ );
36
36
  }
37
37
 
38
38
  describe("MarkdownViewer / callouts", () => {
39
- it("renders the title and body without a leading <br> between them", () => {
40
- const html = shell(
41
- <MarkdownViewer
42
- content={"> [!NOTE]\n> Sandbox data is **not persistent**: it is reset later."}
43
- />,
44
- );
39
+ it("renders the title and body without a leading <br> between them", () => {
40
+ const html = shell(
41
+ <MarkdownViewer
42
+ content={"> [!NOTE]\n> Sandbox data is **not persistent**: it is reset later."}
43
+ />,
44
+ );
45
45
 
46
- expect(html).toContain("Note");
47
- expect(html).toContain("Sandbox data is");
48
- expect(html).toContain("not persistent");
46
+ expect(html).toContain("Note");
47
+ expect(html).toContain("Sandbox data is");
48
+ expect(html).toContain("not persistent");
49
49
 
50
- // The body paragraph must not open with a stray line break.
51
- expect(html).not.toMatch(/<p[^>]*><br\s*\/?>/);
52
- });
50
+ // The body paragraph must not open with a stray line break.
51
+ expect(html).not.toMatch(/<p[^>]*><br\s*\/?>/);
52
+ });
53
53
 
54
- it("supports the title and body on adjacent lines", () => {
55
- const html = shell(<MarkdownViewer content={"> [!WARNING]\n> Be careful here."} />);
56
- expect(html).toContain("Warning");
57
- expect(html).toContain("Be careful here.");
58
- expect(html).not.toMatch(/<p[^>]*><br\s*\/?>/);
59
- });
54
+ it("supports the title and body on adjacent lines", () => {
55
+ const html = shell(<MarkdownViewer content={"> [!WARNING]\n> Be careful here."} />);
56
+ expect(html).toContain("Warning");
57
+ expect(html).toContain("Be careful here.");
58
+ expect(html).not.toMatch(/<p[^>]*><br\s*\/?>/);
59
+ });
60
60
  });
@@ -6,33 +6,33 @@ import { renderToString } from "react-dom/server";
6
6
  import { beforeAll, describe, expect, it } from "vitest";
7
7
 
8
8
  beforeAll(() => {
9
- if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
10
- Object.defineProperty(window, "matchMedia", {
11
- writable: true,
12
- value: (query: string) => ({
13
- matches: false,
14
- media: query,
15
- onchange: null,
16
- addListener: () => {},
17
- removeListener: () => {},
18
- addEventListener: () => {},
19
- removeEventListener: () => {},
20
- dispatchEvent: () => false,
21
- }),
22
- });
23
- }
9
+ if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
10
+ Object.defineProperty(window, "matchMedia", {
11
+ writable: true,
12
+ value: (query: string) => ({
13
+ matches: false,
14
+ media: query,
15
+ onchange: null,
16
+ addListener: () => {},
17
+ removeListener: () => {},
18
+ addEventListener: () => {},
19
+ removeEventListener: () => {},
20
+ dispatchEvent: () => false,
21
+ }),
22
+ });
23
+ }
24
24
  });
25
25
 
26
26
  function shell(node: ReactElement): string {
27
- return renderToString(
28
- <MantineProvider
29
- theme={MANTINE_THEME}
30
- cssVariablesResolver={v8CssVariablesResolver}
31
- forceColorScheme="dark"
32
- >
33
- {node}
34
- </MantineProvider>,
35
- );
27
+ return renderToString(
28
+ <MantineProvider
29
+ theme={MANTINE_THEME}
30
+ cssVariablesResolver={v8CssVariablesResolver}
31
+ forceColorScheme="dark"
32
+ >
33
+ {node}
34
+ </MantineProvider>,
35
+ );
36
36
  }
37
37
 
38
38
  // Dark-scheme syntax colors (see src/syntax/theme.ts).
@@ -40,22 +40,22 @@ const STRING_COLOR = "#00ff6e";
40
40
  const PROPERTY_COLOR = "#e06c75";
41
41
 
42
42
  describe("MarkdownViewer / code syntax highlighting", () => {
43
- it("highlights object keys as property names (not bare identifiers)", () => {
44
- const code = ["{", ' "monthly_sales": "DEFINE TABLE monthly_sales TYPE NORMAL"', "}"].join(
45
- "\n",
46
- );
47
- const html = shell(<MarkdownViewer content={`\`\`\`json\n${code}\n\`\`\``} />);
48
- expect(html).toContain(PROPERTY_COLOR);
49
- expect(html).toContain(STRING_COLOR);
50
- });
43
+ it("highlights object keys as property names (not bare identifiers)", () => {
44
+ const code = ["{", ' "monthly_sales": "DEFINE TABLE monthly_sales TYPE NORMAL"', "}"].join(
45
+ "\n",
46
+ );
47
+ const html = shell(<MarkdownViewer content={`\`\`\`json\n${code}\n\`\`\``} />);
48
+ expect(html).toContain(PROPERTY_COLOR);
49
+ expect(html).toContain(STRING_COLOR);
50
+ });
51
51
 
52
- it("keeps a multi-line string token highlighted as one string across lines", () => {
53
- const code = ["const q = `DEFINE TABLE wishlist", "SCHEMAFULL PERMISSIONS NONE`;"].join(
54
- "\n",
55
- );
56
- const html = shell(<MarkdownViewer content={`\`\`\`js\n${code}\n\`\`\``} />);
57
- // Continuation line content must be inside a string-colored span — proof
58
- // the whole block was parsed once rather than line by line.
59
- expect(html).toMatch(new RegExp(`color:${STRING_COLOR}[^>]*>SCHEMAFULL PERMISSIONS NONE`));
60
- });
52
+ it("keeps a multi-line string token highlighted as one string across lines", () => {
53
+ const code = ["const q = `DEFINE TABLE wishlist", "SCHEMAFULL PERMISSIONS NONE`;"].join(
54
+ "\n",
55
+ );
56
+ const html = shell(<MarkdownViewer content={`\`\`\`js\n${code}\n\`\`\``} />);
57
+ // Continuation line content must be inside a string-colored span — proof
58
+ // the whole block was parsed once rather than line by line.
59
+ expect(html).toMatch(new RegExp(`color:${STRING_COLOR}[^>]*>SCHEMAFULL PERMISSIONS NONE`));
60
+ });
61
61
  });
@@ -6,57 +6,57 @@ import { renderToString } from "react-dom/server";
6
6
  import { beforeAll, describe, expect, it } from "vitest";
7
7
 
8
8
  beforeAll(() => {
9
- if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
10
- Object.defineProperty(window, "matchMedia", {
11
- writable: true,
12
- value: (query: string) => ({
13
- matches: false,
14
- media: query,
15
- onchange: null,
16
- addListener: () => {},
17
- removeListener: () => {},
18
- addEventListener: () => {},
19
- removeEventListener: () => {},
20
- dispatchEvent: () => false,
21
- }),
22
- });
23
- }
9
+ if (typeof window !== "undefined" && typeof window.matchMedia !== "function") {
10
+ Object.defineProperty(window, "matchMedia", {
11
+ writable: true,
12
+ value: (query: string) => ({
13
+ matches: false,
14
+ media: query,
15
+ onchange: null,
16
+ addListener: () => {},
17
+ removeListener: () => {},
18
+ addEventListener: () => {},
19
+ removeEventListener: () => {},
20
+ dispatchEvent: () => false,
21
+ }),
22
+ });
23
+ }
24
24
  });
25
25
 
26
26
  function shell(node: ReactElement): string {
27
- return renderToString(
28
- <MantineProvider
29
- theme={MANTINE_THEME}
30
- cssVariablesResolver={v8CssVariablesResolver}
31
- forceColorScheme="dark"
32
- >
33
- {node}
34
- </MantineProvider>,
35
- );
27
+ return renderToString(
28
+ <MantineProvider
29
+ theme={MANTINE_THEME}
30
+ cssVariablesResolver={v8CssVariablesResolver}
31
+ forceColorScheme="dark"
32
+ >
33
+ {node}
34
+ </MantineProvider>,
35
+ );
36
36
  }
37
37
 
38
38
  describe("MarkdownViewer / code title", () => {
39
- it("renders a title attribute as a caption above the code block", () => {
40
- const html = shell(
41
- <MarkdownViewer content={'```ts title="Example file"\nconst x = 1;\n```'} />,
42
- );
43
- expect(html).toContain("Example file");
44
- });
39
+ it("renders a title attribute as a caption above the code block", () => {
40
+ const html = shell(
41
+ <MarkdownViewer content={'```ts title="Example file"\nconst x = 1;\n```'} />,
42
+ );
43
+ expect(html).toContain("Example file");
44
+ });
45
45
 
46
- it("omits the caption when no title is present", () => {
47
- const html = shell(<MarkdownViewer content={"```ts\nconst x = 1;\n```"} />);
48
- expect(html).not.toContain("code-block-caption");
49
- });
46
+ it("omits the caption when no title is present", () => {
47
+ const html = shell(<MarkdownViewer content={"```ts\nconst x = 1;\n```"} />);
48
+ expect(html).not.toContain("code-block-caption");
49
+ });
50
50
 
51
- it("passes the title through the code renderer override", () => {
52
- const html = shell(
53
- <MarkdownViewer
54
- content={'```ts title="From override"\nconst x = 1;\n```'}
55
- renderers={{
56
- code: ({ title }) => <span data-title={title}>{title}</span>,
57
- }}
58
- />,
59
- );
60
- expect(html).toContain("From override");
61
- });
51
+ it("passes the title through the code renderer override", () => {
52
+ const html = shell(
53
+ <MarkdownViewer
54
+ content={'```ts title="From override"\nconst x = 1;\n```'}
55
+ renderers={{
56
+ code: ({ title }) => <span data-title={title}>{title}</span>,
57
+ }}
58
+ />,
59
+ );
60
+ expect(html).toContain("From override");
61
+ });
62
62
  });