Skip to content

Commit f33ab8b

Browse files
montogeekEugeneHlushko
authored andcommitted
Rebuild Support for custom Markdown on Configuration page (#2564)
1 parent 8508b8c commit f33ab8b

File tree

16 files changed

+1225
-597
lines changed

16 files changed

+1225
-597
lines changed

.editorconfig

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ insert_final_newline = true
1111
charset = utf-8
1212
indent_style = space
1313
indent_size = 2
14+
quote_type = single
1415

1516
# Format Configs
1617
[.eslintignore,*rc]

package.json

+11-7
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
]
6363
},
6464
"devDependencies": {
65+
"@mdx-js/loader": "0.15.7",
66+
"@mdx-js/mdx": "0.15.7",
6567
"@octokit/rest": "^15.9.4",
6668
"alex": "^5.1.0",
6769
"autoprefixer": "^7.2.3",
@@ -76,8 +78,8 @@
7678
"copy-webpack-plugin": "4.5.2",
7779
"cross-env": "5.2.0",
7880
"css-loader": "^0.28.5",
79-
"directory-tree": "2.1.0",
80-
"directory-tree-webpack-plugin": "^0.3.1",
81+
"directory-tree": "2.2.0",
82+
"directory-tree-webpack-plugin": "0.3",
8183
"duplexer": "^0.1.1",
8284
"eslint": "4.19.1",
8385
"eslint-loader": "^2.0.0",
@@ -92,14 +94,14 @@
9294
"http-server": "^0.10.0",
9395
"husky": "^1.0.0-rc.8",
9496
"hyperlink": "^4.0.0",
95-
"lint-staged": "^7.2.0",
97+
"lint-staged": "^8.1.0",
9698
"loader-utils": "^1.1.0",
9799
"lodash": "^4.17.4",
98-
"markdown-loader": "^2.0.1",
100+
"markdown-loader": "^4.0.0",
99101
"markdownlint": "^0.11.0",
100102
"markdownlint-cli": "^0.13.0",
101103
"markdownlint-rule-emphasis-style": "^1.0.0",
102-
"marked": "^0.3.7",
104+
"marked": "^0.5.2",
103105
"mermaid.cli": "^0.3.6",
104106
"minimist": "1.2.0",
105107
"mkdirp": "^0.5.1",
@@ -108,13 +110,13 @@
108110
"npm-run-all": "^4.1.1",
109111
"postcss-loader": "^2.0.6",
110112
"redirect-webpack-plugin": "^0.1.1",
111-
"remark": "^9.0.0",
113+
"remark": "^10.0.1",
112114
"remark-autolink-headings": "^5.0.0",
113115
"remark-custom-blockquotes": "1.0.0",
114116
"remark-extract-anchors": "1.0.0",
115117
"remark-loader": "^0.3.0",
116118
"remark-mermaid": "^0.2.0",
117-
"remark-refractor": "1.0.0",
119+
"remark-refractor": "1.1.0",
118120
"remark-responsive-tables": "1.0.0",
119121
"remark-slug": "^5.0.0",
120122
"request": "^2.81.0",
@@ -146,7 +148,9 @@
146148
"react-dom": "^16.2.0",
147149
"react-g-analytics": "0.4.2",
148150
"react-hot-loader": "^4.0.0-beta.12",
151+
"react-markdown": "4.0.4",
149152
"react-router-dom": "^4.2.2",
153+
"react-tiny-popover": "3.4.2",
150154
"webpack.vote": "^0.1.2",
151155
"whatwg-fetch": "^2.0.3"
152156
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from "react";
2+
import ReactMarkdown from "react-markdown";
3+
import { Details } from "./components";
4+
5+
const detailComponentsList = ['link', 'mode', 'entry', 'filename', 'publicPath', 'advancedOutput', 'expert', 'advancedModule', 'alias', 'advancedResolve', 'hints', 'devtool', 'target', 'externals', 'stats', 'advanced', 'libraryTarget'];
6+
7+
const Pre = props => {
8+
const newChildren = React.Children.map(props.children.props.children, child => {
9+
if (React.isValidElement(child)) {
10+
if (child.props.props.className.includes("keyword")) {
11+
if (!detailComponentsList.includes(child.props.props.componentname)) return child;
12+
13+
return <Details children={child.props.children.slice(4, React.Children.count(child.props.children) - 4)} url={child.props.props.url} />;
14+
}
15+
16+
if (child.props.props.className.includes("comment")) {
17+
return <ReactMarkdown source={child.props.children} disallowedTypes={["paragraph"]} unwrapDisallowed />;
18+
}
19+
}
20+
21+
return child;
22+
});
23+
24+
const newProps = {
25+
children: newChildren
26+
};
27+
28+
return (
29+
<pre>
30+
<code {...newProps} />
31+
</pre>
32+
);
33+
};
34+
35+
export default {
36+
components: {
37+
pre: Pre
38+
}
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.shadow {
2+
overflow: visible;
3+
border-radius: 4px;
4+
box-shadow: -1px 1px 10px 0 rgba(255, 255, 255, 0.44);
5+
}
6+
7+
.inline {
8+
padding-right: 15px !important;
9+
margin: 0 !important;
10+
}
+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React from 'react';
2+
import Popover from 'react-tiny-popover';
3+
import './Configuration.scss';
4+
import { timeout } from 'q';
5+
6+
const DEFAULT_CHILDREN_SIZE = 4;
7+
8+
const isFirstChild = child => typeof child === 'string' && child !== ' ';
9+
10+
const removeSpaces = child => (isFirstChild(child) ? child.trim() : child);
11+
12+
const addLink = (child, i, url) => {
13+
return isFirstChild(child) ? (
14+
<a href={url} key={i}>
15+
{child}
16+
</a>
17+
) : (
18+
child
19+
);
20+
};
21+
22+
const Card = ({ body }) => {
23+
return (
24+
<div className="markdown">
25+
<pre className="inline">
26+
<code>{body}</code>
27+
</pre>
28+
</div>
29+
);
30+
};
31+
32+
export class Details extends React.Component {
33+
constructor(props) {
34+
super(props);
35+
this.state = {
36+
open: false,
37+
summary: null,
38+
content: null
39+
};
40+
}
41+
42+
componentDidMount() {
43+
const { children, url } = this.props;
44+
45+
// Find the index of </default>
46+
const closeDefaultTagIndex = children.findIndex(child => {
47+
if (React.isValidElement(child)) {
48+
return (
49+
child.props.props.className.includes('tag') &&
50+
child.props.children.length === DEFAULT_CHILDREN_SIZE
51+
);
52+
}
53+
});
54+
55+
// Summary is the part of the snippet that would be shown in the code snippet,
56+
// to get it we need to cut the <default></default> enclosing tags
57+
const summary = children
58+
.splice(2, closeDefaultTagIndex - 3)
59+
.map(removeSpaces)
60+
.map((child, i) => addLink(child, i, url));
61+
62+
children.splice(0, DEFAULT_CHILDREN_SIZE); // Remove <default></default> information
63+
64+
this.setState({
65+
summary,
66+
content: children
67+
});
68+
}
69+
70+
clickOutsideHandler = () => {
71+
this.setState({ open: false });
72+
};
73+
74+
toggleVisibility = () => {
75+
this.setState({ open: !this.state.open });
76+
};
77+
78+
render() {
79+
const { open, summary, content } = this.state;
80+
return (
81+
<Popover
82+
isOpen={open}
83+
position={['right', 'top']}
84+
padding={0}
85+
onClickOutside={this.clickOutsideHandler}
86+
containerClassName={'shadow'}
87+
content={<Card body={content} />}
88+
>
89+
<span
90+
className='code-details-summary-span'
91+
onClick={this.toggleVisibility}
92+
>
93+
{summary}
94+
</span>
95+
</Popover>
96+
);
97+
}
98+
}

0 commit comments

Comments
 (0)