@dxos/react-ui-markdown 0.8.4-main.21d9917

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/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@dxos/react-ui-markdown",
3
+ "version": "0.8.4-main.21d9917",
4
+ "description": "Markdown components.",
5
+ "homepage": "https://dxos.org",
6
+ "bugs": "https://github.com/dxos/dxos/issues",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "MIT",
12
+ "author": "DXOS.org",
13
+ "type": "module",
14
+ "exports": {
15
+ ".": {
16
+ "source": "./src/index.ts",
17
+ "types": "./dist/types/src/index.d.ts",
18
+ "browser": "./dist/lib/browser/index.mjs"
19
+ }
20
+ },
21
+ "types": "dist/types/src/index.d.ts",
22
+ "typesVersions": {
23
+ "*": {}
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src"
28
+ ],
29
+ "dependencies": {
30
+ "@codemirror/autocomplete": "^6.19.0",
31
+ "@codemirror/language": "^6.11.3",
32
+ "@codemirror/state": "^6.5.2",
33
+ "@codemirror/view": "^6.38.4",
34
+ "@lezer/common": "^1.2.2",
35
+ "@lezer/highlight": "^1.2.1",
36
+ "@lezer/markdown": "^1.3.1",
37
+ "@lezer/xml": "^1.0.6",
38
+ "@radix-ui/react-compose-refs": "1.1.1",
39
+ "@radix-ui/react-context": "1.1.1",
40
+ "effect": "3.19.11",
41
+ "json5": "^2.2.3",
42
+ "react-markdown": "^10.1.0",
43
+ "react-resize-detector": "^11.0.1",
44
+ "remark-gfm": "^4.0.1",
45
+ "@dxos/async": "0.8.4-main.21d9917",
46
+ "@dxos/echo": "0.8.4-main.21d9917",
47
+ "@dxos/invariant": "0.8.4-main.21d9917",
48
+ "@dxos/react-ui-editor": "0.8.4-main.21d9917",
49
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.21d9917",
50
+ "@dxos/log": "0.8.4-main.21d9917",
51
+ "@dxos/util": "0.8.4-main.21d9917"
52
+ },
53
+ "devDependencies": {
54
+ "@types/react": "~19.2.7",
55
+ "@types/react-dom": "~19.2.3",
56
+ "react": "~19.2.3",
57
+ "react-dom": "~19.2.3",
58
+ "vite": "7.1.9",
59
+ "@dxos/lit-ui": "0.8.4-main.21d9917",
60
+ "@dxos/random": "0.8.4-main.21d9917",
61
+ "@dxos/react-client": "0.8.4-main.21d9917",
62
+ "@dxos/react-ui": "0.8.4-main.21d9917",
63
+ "@dxos/storybook-utils": "0.8.4-main.21d9917",
64
+ "@dxos/echo": "0.8.4-main.21d9917",
65
+ "@dxos/ui-theme": "0.8.4-main.21d9917",
66
+ "@dxos/schema": "0.8.4-main.21d9917"
67
+ },
68
+ "peerDependencies": {
69
+ "effect": "3.19.11",
70
+ "react": "~19.2.3",
71
+ "react-dom": "~19.2.3",
72
+ "@dxos/ui-theme": "0.8.4-main.21d9917",
73
+ "@dxos/react-ui": "0.8.4-main.21d9917"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public"
77
+ }
78
+ }
@@ -0,0 +1,75 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+
7
+ import { faker } from '@dxos/random';
8
+ import { withLayout, withTheme } from '@dxos/react-ui/testing';
9
+ import { trim } from '@dxos/util';
10
+
11
+ import { MarkdownViewer } from './MarkdownViewer';
12
+
13
+ faker.seed(0);
14
+
15
+ const meta = {
16
+ title: 'ui/react-ui-markdown/MarkdownViewer',
17
+ component: MarkdownViewer,
18
+ decorators: [withTheme, withLayout({ layout: 'column' })],
19
+ } satisfies Meta<typeof MarkdownViewer>;
20
+
21
+ export default meta;
22
+
23
+ type Story = StoryObj<typeof MarkdownViewer>;
24
+
25
+ const content = trim`
26
+ # Hello World!
27
+
28
+ > An example of the MarkdownViewer component.
29
+
30
+ ${faker.lorem.paragraphs(1)}
31
+
32
+ Here's a JSON block:
33
+
34
+ ~~~json
35
+ {
36
+ "hello": "world"
37
+ }
38
+ ~~~
39
+
40
+ And some code:
41
+
42
+ ~~~tsx
43
+ import React from 'react'
44
+
45
+ const App = () => {
46
+ const title = 'Hello, world!'
47
+ return <div>{title}</div>
48
+ }
49
+ ~~~
50
+
51
+ ## Task lists
52
+
53
+ - [ ] Task one
54
+ - [x] Task two
55
+ - [ ] Task three
56
+
57
+ ## Tables
58
+
59
+ | Column 1 | Column 2 | Column 3 |
60
+ | -------- | -------- | -------- |
61
+ | Cell 1 | Cell 2 | Cell 3 |
62
+ | Cell 4 | Cell 5 | Cell 6 |
63
+ | Cell 7 | Cell 8 | Cell 9 |
64
+
65
+ ## Examples
66
+
67
+ ${faker.lorem.paragraphs(1)}
68
+ `;
69
+
70
+ export const Default: Story = {
71
+ args: {
72
+ classNames: 'p-4 border border-border rounded-md overflow-y-auto bg-baseSurface',
73
+ content,
74
+ },
75
+ };
@@ -0,0 +1,95 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React, { type PropsWithChildren } from 'react';
6
+ import ReactMarkdown, { type Options as ReactMarkdownOptions } from 'react-markdown';
7
+ import remarkGfm from 'remark-gfm';
8
+
9
+ import { type ThemedClassName } from '@dxos/react-ui';
10
+ import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
11
+ import { mx } from '@dxos/ui-theme';
12
+
13
+ export type MarkdownViewerProps = ThemedClassName<
14
+ PropsWithChildren<{
15
+ content?: string;
16
+ components?: ReactMarkdownOptions['components'];
17
+ }>
18
+ >;
19
+
20
+ /**
21
+ * Transforms markdown text into react elements.
22
+ * https://github.com/remarkjs/react-markdown
23
+ * markdown -> remark -> [mdast -> remark plugins] -> [hast -> rehype plugins] -> components -> react elements.
24
+ * Consider using @dxos/react-ui-editor.
25
+ */
26
+ export const MarkdownViewer = ({ classNames, children, components, content = '' }: MarkdownViewerProps) => {
27
+ return (
28
+ <div className={mx(classNames)}>
29
+ <ReactMarkdown remarkPlugins={[remarkGfm]} skipHtml components={{ ...defaultComponents, ...components }}>
30
+ {content}
31
+ </ReactMarkdown>
32
+ {children}
33
+ </div>
34
+ );
35
+ };
36
+
37
+ const defaultComponents: ReactMarkdownOptions['components'] = {
38
+ h1: ({ children }) => {
39
+ return <h1 className='pbs-1 pbe-1 text-xl'>{children}</h1>;
40
+ },
41
+ h2: ({ children }) => {
42
+ return <h2 className='pbs-1 pbe-1 text-lg'>{children}</h2>;
43
+ },
44
+ h3: ({ children }) => {
45
+ return <h3 className='pbs-1 pbe-1 text-base'>{children}</h3>;
46
+ },
47
+ blockquote: ({ children, ...props }) => (
48
+ <blockquote className='pis-4 mbs-2 mbe-2 pbs-2 pbe-2 border-l-4 border-accentText text-accentText' {...props}>
49
+ {children}
50
+ </blockquote>
51
+ ),
52
+ p: ({ children }) => {
53
+ return <div className='pbs-1 pbe-1'>{children}</div>;
54
+ },
55
+ a: ({ children, href, ...props }) => (
56
+ <a
57
+ href={href}
58
+ className='text-primary-500 hover:text-primary-500' // TODO(burdon): Use link token.
59
+ target='_blank'
60
+ rel='noopener noreferrer'
61
+ {...props}
62
+ >
63
+ {children}
64
+ </a>
65
+ ),
66
+ ol: ({ children, ...props }) => (
67
+ <ol className='pbs-1 pbe-1 pis-6 leading-tight list-decimal' {...props}>
68
+ {children}
69
+ </ol>
70
+ ),
71
+ ul: ({ children, ...props }) => (
72
+ <ul className='pbs-1 pbe-1 pis-6 leading-tight list-disc' {...props}>
73
+ {children}
74
+ </ul>
75
+ ),
76
+ li: ({ children, ...props }) => (
77
+ <li className='' {...props}>
78
+ {children}
79
+ </li>
80
+ ),
81
+ pre: ({ children }) => children,
82
+ // TODO(burdon): Copy/paste button.
83
+ code: ({ children, className }) => {
84
+ const [, language] = /language-(\w+)/.exec(className || '') || [];
85
+ return (
86
+ <SyntaxHighlighter
87
+ language={language}
88
+ classNames='mbs-2 mbe-2 border border-separator rounded-sm text-sm bg-groupSurface'
89
+ PreTag='pre'
90
+ >
91
+ {children}
92
+ </SyntaxHighlighter>
93
+ );
94
+ },
95
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './MarkdownViewer';
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export * from './MarkdownViewer';
@@ -0,0 +1,8 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ declare module '*.md?raw' {
6
+ const content: string;
7
+ export default content;
8
+ }