@vertigis/react-ui 21.6.0 → 21.7.0
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/Markdown/Markdown.d.ts +23 -10
- package/Markdown/Markdown.js +131 -6
- package/package.json +4 -1
- package/utils/markdown.d.ts +4 -0
- package/utils/markdown.js +4 -0
package/Markdown/Markdown.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FC } from "react";
|
|
2
2
|
import type { BoxProps } from "../Box/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Properties for the `Markdown` component.
|
|
5
5
|
*/
|
|
6
6
|
export interface MarkdownProps extends BoxProps {
|
|
7
7
|
/**
|
|
8
|
-
* The markdown text to render.
|
|
8
|
+
* The markdown text to render. Optional, you can also supply the text as a
|
|
9
|
+
* child of this component.
|
|
9
10
|
*/
|
|
10
|
-
markdown
|
|
11
|
+
markdown?: string;
|
|
11
12
|
/**
|
|
12
13
|
* Override the default sanitization behaviour with a caller-supplied
|
|
13
14
|
* sanitization function that ensures that the resulting HTML is safe to
|
|
14
15
|
* insert into the DOM.
|
|
16
|
+
*
|
|
17
|
+
* @deprecated The Markdown component no longer operates by attaching raw
|
|
18
|
+
* HTML strings to the DOM, so this property is ignored.
|
|
15
19
|
*/
|
|
16
20
|
sanitize?: (unsafeHtml: string) => string;
|
|
17
21
|
/**
|
|
@@ -28,21 +32,30 @@ export interface MarkdownProps extends BoxProps {
|
|
|
28
32
|
* Markdown syntax without also supporting HTML syntax. The default is
|
|
29
33
|
* `false`.
|
|
30
34
|
*
|
|
31
|
-
* IMPORTANT:
|
|
32
|
-
* this
|
|
35
|
+
* IMPORTANT: A sanitizer is run on any inline HTML before it is passed to
|
|
36
|
+
* React, but you should still probably set this to `true` when dealing with
|
|
37
|
+
* untrusted sources.
|
|
33
38
|
*/
|
|
34
39
|
escapeHtml?: boolean;
|
|
35
40
|
/**
|
|
36
41
|
* An optional value to apply to external hyperlinks via the `target`
|
|
37
|
-
* attribute.
|
|
38
|
-
*
|
|
39
|
-
* If this is omitted, links may still open in a separate target if the host
|
|
40
|
-
* page specifies a `target` via the `<base>` element in its `<head>`.
|
|
42
|
+
* attribute. Defaults to "_blank".
|
|
41
43
|
*/
|
|
42
44
|
linkTarget?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Whether to use standard HTML elements instead of their `react-ui`
|
|
47
|
+
* equivalents. If this is `true` the VertiGIS 'Meridian' style will not be
|
|
48
|
+
* applied to the output. Defaults to `false`.
|
|
49
|
+
*/
|
|
50
|
+
useBasicHtml?: boolean;
|
|
43
51
|
}
|
|
44
52
|
/**
|
|
45
|
-
* A component that renders markdown as
|
|
53
|
+
* A component that renders markdown as React nodes.
|
|
54
|
+
*
|
|
55
|
+
* GitHub style sanitation is applied to any inline HTML encountered, see:
|
|
56
|
+
* https://github.com/gjtorikian/html-pipeline/blob/a2e02ac/lib/html_pipeline/sanitization_filter.rb
|
|
57
|
+
* However, it is still recommended to set `escapeHtml` to true with untrusted
|
|
58
|
+
* content.
|
|
46
59
|
*/
|
|
47
60
|
declare const Markdown: FC<MarkdownProps>;
|
|
48
61
|
export default Markdown;
|
package/Markdown/Markdown.js
CHANGED
|
@@ -1,12 +1,137 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
2
3
|
import clsx from "clsx";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import ReactMarkdown, {} from "react-markdown";
|
|
6
|
+
import rehypeRaw from "rehype-raw";
|
|
7
|
+
import rehypeSanitize from "rehype-sanitize";
|
|
3
8
|
import Box from "../Box/index.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
9
|
+
import Link, {} from "../Link/index.js";
|
|
10
|
+
import Typography, {} from "../Typography/index.js";
|
|
11
|
+
import { useTheme } from "../styles/index.js";
|
|
12
|
+
const disallowedInlineElements = [
|
|
13
|
+
"a",
|
|
14
|
+
"abbr",
|
|
15
|
+
"area",
|
|
16
|
+
"audio",
|
|
17
|
+
"b",
|
|
18
|
+
"bdi",
|
|
19
|
+
"bdo",
|
|
20
|
+
"br",
|
|
21
|
+
"button",
|
|
22
|
+
"canvas",
|
|
23
|
+
"cite",
|
|
24
|
+
"code",
|
|
25
|
+
"data",
|
|
26
|
+
"datalist",
|
|
27
|
+
"del",
|
|
28
|
+
"dfn",
|
|
29
|
+
"em",
|
|
30
|
+
"embed",
|
|
31
|
+
"i",
|
|
32
|
+
"iframe",
|
|
33
|
+
"img",
|
|
34
|
+
"input",
|
|
35
|
+
"ins",
|
|
36
|
+
"kbd",
|
|
37
|
+
"label",
|
|
38
|
+
"link",
|
|
39
|
+
"map",
|
|
40
|
+
"mark",
|
|
41
|
+
"math",
|
|
42
|
+
"meta",
|
|
43
|
+
"meter",
|
|
44
|
+
"noscript",
|
|
45
|
+
"object",
|
|
46
|
+
"output",
|
|
47
|
+
"picture",
|
|
48
|
+
"progress",
|
|
49
|
+
"q",
|
|
50
|
+
"ruby",
|
|
51
|
+
"s",
|
|
52
|
+
"samp",
|
|
53
|
+
"script",
|
|
54
|
+
"select",
|
|
55
|
+
"slot",
|
|
56
|
+
"small",
|
|
57
|
+
"span",
|
|
58
|
+
"strong",
|
|
59
|
+
"sub",
|
|
60
|
+
"sup",
|
|
61
|
+
"svg",
|
|
62
|
+
"template",
|
|
63
|
+
"textarea",
|
|
64
|
+
"time",
|
|
65
|
+
"u",
|
|
66
|
+
"var",
|
|
67
|
+
"video",
|
|
68
|
+
"wbr",
|
|
69
|
+
];
|
|
6
70
|
/**
|
|
7
|
-
* A component that renders markdown as
|
|
71
|
+
* A component that renders markdown as React nodes.
|
|
72
|
+
*
|
|
73
|
+
* GitHub style sanitation is applied to any inline HTML encountered, see:
|
|
74
|
+
* https://github.com/gjtorikian/html-pipeline/blob/a2e02ac/lib/html_pipeline/sanitization_filter.rb
|
|
75
|
+
* However, it is still recommended to set `escapeHtml` to true with untrusted
|
|
76
|
+
* content.
|
|
8
77
|
*/
|
|
9
|
-
const Markdown = ({ markdown, inline, escapeHtml, sanitize =
|
|
10
|
-
|
|
11
|
-
|
|
78
|
+
const Markdown = ({ markdown, inline, escapeHtml, sanitize, linkTarget = "_blank", children, className, useBasicHtml, ...otherProps }) => {
|
|
79
|
+
const theme = useTheme();
|
|
80
|
+
const disallowedElements = useMemo(() => (inline ? disallowedInlineElements : []), [inline]);
|
|
81
|
+
const components = useMemo(() => useBasicHtml
|
|
82
|
+
? {}
|
|
83
|
+
: {
|
|
84
|
+
a({ node, href, ...props }) {
|
|
85
|
+
const localLink = href?.startsWith(`${location.protocol}//${location.hostname}`) ||
|
|
86
|
+
href?.startsWith(location.hostname) ||
|
|
87
|
+
href?.startsWith("#") ||
|
|
88
|
+
href?.startsWith("/");
|
|
89
|
+
return (_jsx(Link, { target: href?.startsWith("#") ? undefined : linkTarget, showExternalLinkIcon: !localLink, href: href, ...props }));
|
|
90
|
+
},
|
|
91
|
+
// Default margin values based on https://www.w3.org/TR/CSS2/sample.html
|
|
92
|
+
h1({ node, ...props }) {
|
|
93
|
+
return (_jsx(Typography, { ...props, sx: {
|
|
94
|
+
marginBlockStart: theme.spacing(0.67),
|
|
95
|
+
marginBlockEnd: theme.spacing(0.67),
|
|
96
|
+
}, variant: "h1" }));
|
|
97
|
+
},
|
|
98
|
+
h2({ node, ...props }) {
|
|
99
|
+
return (_jsx(Typography, { ...props, sx: {
|
|
100
|
+
marginBlockStart: theme.spacing(0.75),
|
|
101
|
+
marginBlockEnd: theme.spacing(0.75),
|
|
102
|
+
}, variant: "h2" }));
|
|
103
|
+
},
|
|
104
|
+
h3({ node, ...props }) {
|
|
105
|
+
return (_jsx(Typography, { ...props, sx: {
|
|
106
|
+
marginBlockStart: theme.spacing(0.83),
|
|
107
|
+
marginBlockEnd: theme.spacing(0.83),
|
|
108
|
+
}, variant: "h3" }));
|
|
109
|
+
},
|
|
110
|
+
h4({ node, ...props }) {
|
|
111
|
+
return (_jsx(Typography, { ...props, sx: {
|
|
112
|
+
marginBlockStart: theme.spacing(1),
|
|
113
|
+
marginBlockEnd: theme.spacing(1),
|
|
114
|
+
}, variant: "h4" }));
|
|
115
|
+
},
|
|
116
|
+
h5({ node, ...props }) {
|
|
117
|
+
return (_jsx(Typography, { ...props, sx: {
|
|
118
|
+
marginBlockStart: theme.spacing(1.5),
|
|
119
|
+
marginBlockEnd: theme.spacing(1.5),
|
|
120
|
+
}, variant: "h5" }));
|
|
121
|
+
},
|
|
122
|
+
h6({ node, ...props }) {
|
|
123
|
+
return (_jsx(Typography, { ...props, sx: {
|
|
124
|
+
marginBlockStart: theme.spacing(1.67),
|
|
125
|
+
marginBlockEnd: theme.spacing(1.67),
|
|
126
|
+
}, variant: "h6" }));
|
|
127
|
+
},
|
|
128
|
+
p({ node, ...props }) {
|
|
129
|
+
return (_jsx(Typography, { component: "p", ...props, sx: {
|
|
130
|
+
marginBlockStart: theme.spacing(1),
|
|
131
|
+
marginBlockEnd: theme.spacing(1),
|
|
132
|
+
}, variant: "body1" }));
|
|
133
|
+
},
|
|
134
|
+
}, [linkTarget, theme, useBasicHtml]);
|
|
135
|
+
return (_jsx(Box, { component: inline ? "span" : "div", className: clsx("GcxMarkdown", className), ...otherProps, children: _jsx(ReactMarkdown, { components: components, disallowedElements: disallowedElements, rehypePlugins: escapeHtml ? [] : [rehypeRaw, rehypeSanitize], children: children && typeof children === "string" ? children : markdown }) }));
|
|
136
|
+
};
|
|
12
137
|
export default Markdown;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertigis/react-ui",
|
|
3
|
-
"version": "21.
|
|
3
|
+
"version": "21.7.0",
|
|
4
4
|
"description": "Utilities and React components used in VertiGIS applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vertigis",
|
|
@@ -27,6 +27,9 @@
|
|
|
27
27
|
"lodash.escape": "^4.0.1",
|
|
28
28
|
"marked": "^12.0.1",
|
|
29
29
|
"react-color": "^2.19.3",
|
|
30
|
+
"react-markdown": "^10.1.0",
|
|
31
|
+
"rehype-raw": "^7.0.0",
|
|
32
|
+
"rehype-sanitize": "^6.0.0",
|
|
30
33
|
"tslib": "^2.6.2",
|
|
31
34
|
"xss": "^1.0.15"
|
|
32
35
|
},
|
package/utils/markdown.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export interface MarkdownToHtmlOptions {
|
|
|
33
33
|
* Converts markdown text into HTML. The resulting HTML is sanitized and safe to
|
|
34
34
|
* insert into the DOM.
|
|
35
35
|
*
|
|
36
|
+
* @deprecated Use the `Markdown` component to add markdown safely without
|
|
37
|
+
* parsing raw HTML strings.
|
|
36
38
|
* @param markdown The markdown text to convert.
|
|
37
39
|
* @param options Options that affect how the text is converted.
|
|
38
40
|
*/
|
|
@@ -44,6 +46,8 @@ export declare function markdownToSafeHtml(markdown: string, options?: MarkdownT
|
|
|
44
46
|
* caller's responsibility to sanitize the resulting HTML prior to inserting it
|
|
45
47
|
* into the DOM. You must do this even if `escapeHtml` is set to true.
|
|
46
48
|
*
|
|
49
|
+
* @deprecated Use the `Markdown` component to add markdown safely without
|
|
50
|
+
* parsing raw HTML strings.
|
|
47
51
|
* @param markdown The markdown text to convert.
|
|
48
52
|
* @param options Options that affect how the text is converted.
|
|
49
53
|
*/
|
package/utils/markdown.js
CHANGED
|
@@ -33,6 +33,8 @@ class CustomRenderer extends marked.Renderer {
|
|
|
33
33
|
* Converts markdown text into HTML. The resulting HTML is sanitized and safe to
|
|
34
34
|
* insert into the DOM.
|
|
35
35
|
*
|
|
36
|
+
* @deprecated Use the `Markdown` component to add markdown safely without
|
|
37
|
+
* parsing raw HTML strings.
|
|
36
38
|
* @param markdown The markdown text to convert.
|
|
37
39
|
* @param options Options that affect how the text is converted.
|
|
38
40
|
*/
|
|
@@ -46,6 +48,8 @@ export function markdownToSafeHtml(markdown, options) {
|
|
|
46
48
|
* caller's responsibility to sanitize the resulting HTML prior to inserting it
|
|
47
49
|
* into the DOM. You must do this even if `escapeHtml` is set to true.
|
|
48
50
|
*
|
|
51
|
+
* @deprecated Use the `Markdown` component to add markdown safely without
|
|
52
|
+
* parsing raw HTML strings.
|
|
49
53
|
* @param markdown The markdown text to convert.
|
|
50
54
|
* @param options Options that affect how the text is converted.
|
|
51
55
|
*/
|