@multiplatform.one/markdown 7.6.1 → 7.6.3
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/dist/cjs/Aside/index.native.js.map +1 -1
- package/dist/cjs/ExternalIcon/index.native.js.map +1 -1
- package/dist/cjs/Hr/index.native.js.map +1 -1
- package/dist/cjs/Li/index.native.js.map +1 -1
- package/dist/cjs/Markdown.native.js.map +1 -1
- package/dist/cjs/MarkdownSimpleTable/index.native.js.map +1 -1
- package/dist/cjs/Mdx/index.native.js +1 -1
- package/dist/cjs/Mdx/index.native.js.map +1 -1
- package/dist/cjs/MdxCodeBlock/index.native.js +1 -1
- package/dist/cjs/MdxCodeBlock/index.native.js.map +1 -1
- package/dist/cjs/MdxCodeBlock/mdxCodeBlockContext.native.js.map +1 -1
- package/dist/cjs/Notice/index.native.js.map +1 -1
- package/dist/cjs/Table/index.native.js.map +1 -1
- package/dist/cjs/Tabs/index.native.js.map +1 -1
- package/dist/cjs/Ul/index.native.js.map +1 -1
- package/dist/cjs/Video/index.native.js.map +1 -1
- package/dist/cjs/components/Blockquote.native.js.map +1 -1
- package/dist/cjs/components/Break.native.js.map +1 -1
- package/dist/cjs/components/CodeBlock.native.js.map +1 -1
- package/dist/cjs/components/Heading.native.js.map +1 -1
- package/dist/cjs/components/HorizontalRule.native.js.map +1 -1
- package/dist/cjs/components/Image.native.js.map +1 -1
- package/dist/cjs/components/InlineCode.native.js.map +1 -1
- package/dist/cjs/components/InlineStyles.native.js.map +1 -1
- package/dist/cjs/components/Link.native.js.map +1 -1
- package/dist/cjs/components/List.native.js +1 -1
- package/dist/cjs/components/List.native.js.map +1 -1
- package/dist/cjs/components/Paragraph.native.js.map +1 -1
- package/dist/cjs/components/Table.native.js.map +1 -1
- package/dist/cjs/components/index.native.js.map +1 -1
- package/dist/cjs/hooks/index.native.js.map +1 -1
- package/dist/cjs/hooks/useCompileAndEvaluateMdx.native.js.map +1 -1
- package/dist/cjs/hooks/useCompileMdx.native.js.map +1 -1
- package/dist/cjs/hooks/useEvaluateMdx.native.js.map +1 -1
- package/dist/cjs/icons/index.native.js.map +1 -1
- package/dist/cjs/index.native.js +15 -15
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/mdxComponents.native.js +5 -5
- package/dist/cjs/mdxComponents.native.js.map +1 -1
- package/dist/cjs/mermaid/MermaidBlock.native.js +1 -1
- package/dist/cjs/mermaid/index.native.js.map +1 -1
- package/dist/cjs/mermaid/mountDiagramSvg.native.js.map +1 -1
- package/dist/cjs/parser.native.js.map +1 -1
- package/dist/cjs/renderer.native.js +1 -1
- package/dist/cjs/renderer.native.js.map +1 -1
- package/dist/cjs/shared/colorRamps.native.js.map +1 -1
- package/dist/cjs/shared/cutoffGradient.native.js.map +1 -1
- package/dist/cjs/shared/index.native.js.map +1 -1
- package/dist/cjs/shared/textRidesText.native.js.map +1 -1
- package/dist/cjs/shared/tokenPx.native.js.map +1 -1
- package/dist/cjs/shared/useMarkdownTableKnobs.native.js.map +1 -1
- package/dist/cjs/shiki/index.native.js.map +1 -1
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/cjs/util/rehypeMetaAttributes.native.js.map +1 -1
- package/package.json +9 -9
- package/src/Notice/Notice.spec.tsx +68 -0
- package/src/mermaid/MermaidBlock.spec.tsx +70 -0
- package/src/mermaid/MermaidBlock.stories.tsx +59 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/markdown",
|
|
3
|
-
"version": "7.6.
|
|
3
|
+
"version": "7.6.3",
|
|
4
4
|
"description": "Cross-platform markdown renderer with Shiki syntax highlighting for React and React Native",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cross-platform",
|
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
"tamagui": "2.7.6",
|
|
83
83
|
"unified": "^11.0.5",
|
|
84
84
|
"unist-util-visit": "^5.1.0",
|
|
85
|
-
"@multiplatform.one/components": "7.6.
|
|
86
|
-
"@multiplatform.one/platform": "7.6.
|
|
87
|
-
"@multiplatform.one/router": "7.6.
|
|
88
|
-
"@multiplatform.one/
|
|
89
|
-
"@multiplatform.one/
|
|
85
|
+
"@multiplatform.one/components": "7.6.3",
|
|
86
|
+
"@multiplatform.one/platform": "7.6.3",
|
|
87
|
+
"@multiplatform.one/router": "7.6.3",
|
|
88
|
+
"@multiplatform.one/table-primitives": "7.6.3",
|
|
89
|
+
"@multiplatform.one/theme": "7.6.3"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@tamagui/build": "2.7.6",
|
|
@@ -99,9 +99,9 @@
|
|
|
99
99
|
"react": "19.2.5",
|
|
100
100
|
"react-dom": "19.2.5",
|
|
101
101
|
"vitest": "^4.1.5",
|
|
102
|
-
"@multiplatform.one/config": "7.6.
|
|
103
|
-
"@multiplatform.one/storybook": "7.6.
|
|
104
|
-
"@multiplatform.one/test-utils": "7.6.
|
|
102
|
+
"@multiplatform.one/config": "7.6.3",
|
|
103
|
+
"@multiplatform.one/storybook": "7.6.3",
|
|
104
|
+
"@multiplatform.one/test-utils": "7.6.3"
|
|
105
105
|
},
|
|
106
106
|
"peerDependencies": {
|
|
107
107
|
"react": "^19.1.0",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notice spec (MPO-120). Stories live in Markdown/Callouts; this file covers
|
|
3
|
+
* the theme → Alert intent map the Callouts variants render.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
7
|
+
import { Paragraph } from "tamagui";
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { Notice } from "./index";
|
|
10
|
+
|
|
11
|
+
describe("Notice", () => {
|
|
12
|
+
it("yellow maps onto warning (assertive alert)", () => {
|
|
13
|
+
const { container } = renderWithProviders(
|
|
14
|
+
<Notice theme="yellow" title="Warning">
|
|
15
|
+
Yellow warning notice.
|
|
16
|
+
</Notice>,
|
|
17
|
+
);
|
|
18
|
+
expect(container.querySelector('[role="alert"]')).toBeTruthy();
|
|
19
|
+
expect(container.textContent).toContain("Warning");
|
|
20
|
+
expect(container.textContent).toContain("Yellow warning notice.");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("blue maps onto info (polite status)", () => {
|
|
24
|
+
const { container } = renderWithProviders(
|
|
25
|
+
<Notice theme="blue" title="Info">
|
|
26
|
+
Blue info notice.
|
|
27
|
+
</Notice>,
|
|
28
|
+
);
|
|
29
|
+
expect(container.querySelector('[role="status"]')).toBeTruthy();
|
|
30
|
+
expect(container.querySelector('[role="alert"]')).toBeNull();
|
|
31
|
+
expect(container.textContent).toContain("Info");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("green maps onto success (polite status)", () => {
|
|
35
|
+
const { container } = renderWithProviders(
|
|
36
|
+
<Notice theme="green" title="Success">
|
|
37
|
+
Green success notice.
|
|
38
|
+
</Notice>,
|
|
39
|
+
);
|
|
40
|
+
expect(container.querySelector('[role="status"]')).toBeTruthy();
|
|
41
|
+
expect(container.textContent).toContain("Success");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("red maps onto error (assertive alert)", () => {
|
|
45
|
+
const { container } = renderWithProviders(
|
|
46
|
+
<Notice theme="red" title="Error">
|
|
47
|
+
Red error notice.
|
|
48
|
+
</Notice>,
|
|
49
|
+
);
|
|
50
|
+
expect(container.querySelector('[role="alert"]')).toBeTruthy();
|
|
51
|
+
expect(container.textContent).toContain("Error");
|
|
52
|
+
expect(container.textContent).toContain("Red error notice.");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("empty children still mount a notice", () => {
|
|
56
|
+
const { container } = renderWithProviders(<Notice theme="blue">{""}</Notice>);
|
|
57
|
+
expect(container.querySelector('[role="status"]')).toBeTruthy();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("disableUnwrap keeps element children instead of flattening them", () => {
|
|
61
|
+
const { container } = renderWithProviders(
|
|
62
|
+
<Notice theme="green" disableUnwrap>
|
|
63
|
+
<Paragraph>kept as an element</Paragraph>
|
|
64
|
+
</Notice>,
|
|
65
|
+
);
|
|
66
|
+
expect(container.querySelector("p")?.textContent).toBe("kept as an element");
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MermaidBlock spec (MPO-120). The block owns three faces: loading (source
|
|
3
|
+
* as a mermaid CodeBlock), ok (mounted SVG), error (parse message above the
|
|
4
|
+
* source). Native is a CodeBlock of the source and never mounts a diagram.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
8
|
+
import { waitFor } from "@testing-library/react";
|
|
9
|
+
import { describe, expect, it, vi } from "vitest";
|
|
10
|
+
|
|
11
|
+
const { renderMermaidDiagram, mountDiagramSvg } = vi.hoisted(() => ({
|
|
12
|
+
renderMermaidDiagram: vi.fn(),
|
|
13
|
+
mountDiagramSvg: vi.fn(() => true),
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock("./renderMermaidDiagram", () => ({
|
|
17
|
+
renderMermaidDiagram,
|
|
18
|
+
resetMermaidForTesting: vi.fn(),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
vi.mock("./mountDiagramSvg", () => ({
|
|
22
|
+
mountDiagramSvg,
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
import { MermaidBlock } from "./MermaidBlock";
|
|
26
|
+
import { MermaidBlock as NativeMermaidBlock } from "./MermaidBlock.native";
|
|
27
|
+
|
|
28
|
+
const FLOWCHART = "graph TD\n A-->B";
|
|
29
|
+
|
|
30
|
+
describe("MermaidBlock", () => {
|
|
31
|
+
it("mounts a diagram after the lazy render succeeds", async () => {
|
|
32
|
+
renderMermaidDiagram.mockResolvedValue({ ok: true, svg: "<svg><g>ok</g></svg>" });
|
|
33
|
+
const { container } = renderWithProviders(<MermaidBlock>{FLOWCHART}</MermaidBlock>);
|
|
34
|
+
await waitFor(() => {
|
|
35
|
+
expect(container.querySelector('[data-mermaid-diagram="true"]')).toBeTruthy();
|
|
36
|
+
});
|
|
37
|
+
expect(renderMermaidDiagram).toHaveBeenCalledWith(FLOWCHART, expect.objectContaining({}));
|
|
38
|
+
expect(mountDiagramSvg).toHaveBeenCalled();
|
|
39
|
+
expect(container.querySelector('[role="img"]')?.getAttribute("aria-label")).toBe(
|
|
40
|
+
"Mermaid diagram",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("shows the parse error above the source when the engine fails (Axiom 6)", async () => {
|
|
45
|
+
renderMermaidDiagram.mockResolvedValue({ ok: false, error: "Parse error on line 2" });
|
|
46
|
+
const { container } = renderWithProviders(<MermaidBlock>{"graph TD\n A--"}</MermaidBlock>);
|
|
47
|
+
await waitFor(() => {
|
|
48
|
+
expect(container.querySelector('[role="alert"]')?.textContent).toContain(
|
|
49
|
+
"Parse error on line 2",
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
expect(container.querySelector('[data-mermaid-diagram="true"]')).toBeNull();
|
|
53
|
+
expect(container.textContent).toContain("graph TD");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("shows the mermaid CodeBlock while loading", () => {
|
|
57
|
+
renderMermaidDiagram.mockReturnValue(new Promise(() => {}));
|
|
58
|
+
const { container } = renderWithProviders(<MermaidBlock>{FLOWCHART}</MermaidBlock>);
|
|
59
|
+
expect(container.querySelector('[data-mermaid-diagram="true"]')).toBeNull();
|
|
60
|
+
expect(container.textContent).toContain("graph TD");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("MermaidBlock native fallback", () => {
|
|
65
|
+
it("renders the source as a mermaid CodeBlock, never a diagram host", () => {
|
|
66
|
+
const { container } = renderWithProviders(<NativeMermaidBlock>{FLOWCHART}</NativeMermaidBlock>);
|
|
67
|
+
expect(container.querySelector('[data-mermaid-diagram="true"]')).toBeNull();
|
|
68
|
+
expect(container.textContent).toContain("graph TD");
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MermaidBlock — read-only mermaid diagram for rendered markdown.
|
|
3
|
+
* Engine is lazy; native falls back to a mermaid CodeBlock because the
|
|
4
|
+
* engine needs a DOM. Import is colocated (MPO-10: the ./mermaid subpath
|
|
5
|
+
* is the engine helpers, not this block).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Meta, StoryObj } from "@storybook/react-native-web-vite";
|
|
9
|
+
import { Text, YStack } from "tamagui";
|
|
10
|
+
import { MermaidBlock } from "./MermaidBlock";
|
|
11
|
+
|
|
12
|
+
const FLOWCHART = `graph TD
|
|
13
|
+
A[Scan] --> B[Preview]
|
|
14
|
+
B --> C[Commit]`;
|
|
15
|
+
|
|
16
|
+
const meta: Meta<typeof MermaidBlock> = {
|
|
17
|
+
title: "Markdown/Mermaid",
|
|
18
|
+
component: MermaidBlock,
|
|
19
|
+
parameters: {
|
|
20
|
+
status: { type: "beta" },
|
|
21
|
+
docs: {
|
|
22
|
+
description: {
|
|
23
|
+
component:
|
|
24
|
+
"Fenced mermaid source rendered as SVG on web. Invalid source shows the parse error above the source (Axiom 6). Native hosts fall back to a mermaid CodeBlock.",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default meta;
|
|
31
|
+
type Story = StoryObj<typeof MermaidBlock>;
|
|
32
|
+
|
|
33
|
+
export const Main: Story = {
|
|
34
|
+
name: "Main",
|
|
35
|
+
args: { children: FLOWCHART },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Same diagram; Storybook scheme addon is the dark specimen. */
|
|
39
|
+
export const DarkScheme: Story = {
|
|
40
|
+
args: { children: FLOWCHART },
|
|
41
|
+
parameters: { backgrounds: { default: "dark" } },
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** Axiom 6: parse failure is visible, never a blank box. */
|
|
45
|
+
export const InvalidSource: Story = {
|
|
46
|
+
args: { children: "graph TD\n A--" },
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const NativeFallbackNote: Story = {
|
|
50
|
+
render: () => (
|
|
51
|
+
<YStack gap="$3" maxWidth={700} padding="$4">
|
|
52
|
+
<Text fontSize="$2" color="$color10">
|
|
53
|
+
Native has no DOM mermaid engine, so MermaidBlock.native.tsx renders the source as a mermaid
|
|
54
|
+
CodeBlock. This web story is the live SVG path.
|
|
55
|
+
</Text>
|
|
56
|
+
<MermaidBlock>{FLOWCHART}</MermaidBlock>
|
|
57
|
+
</YStack>
|
|
58
|
+
),
|
|
59
|
+
};
|