ronds-metadata 1.1.46 → 1.1.48
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/es/comps/MdNavbar/index.d.ts +13 -0
- package/es/comps/MdNavbar/index.js +164 -0
- package/es/comps/MdNavbar/index.less +77 -0
- package/es/comps/MdNavbar/utils.d.ts +3 -0
- package/es/comps/MdNavbar/utils.js +34 -0
- package/es/comps/MdView/index.d.ts +10 -1
- package/es/comps/MdView/index.js +7 -6
- package/package.json +1 -1
@@ -0,0 +1,13 @@
|
|
1
|
+
import './index.less';
|
2
|
+
interface IMdNavbarProps {
|
3
|
+
source: string;
|
4
|
+
ordered?: boolean;
|
5
|
+
headingTopOffset?: number;
|
6
|
+
updateHashAuto?: boolean;
|
7
|
+
declarative?: boolean;
|
8
|
+
className?: string;
|
9
|
+
onNavItemClick?: (event: any, element: HTMLDivElement, hashValue: string) => void;
|
10
|
+
onHashChange?: (newHash: string, oldHash: string) => void;
|
11
|
+
}
|
12
|
+
declare const MdNavbar: (props: IMdNavbarProps) => JSX.Element;
|
13
|
+
export default MdNavbar;
|
@@ -0,0 +1,164 @@
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
2
|
+
|
3
|
+
/*
|
4
|
+
* @Author: wangxian
|
5
|
+
* @Date: 2022-10-14 09:05:50
|
6
|
+
* @LastEditTime: 2022-10-14 10:55:42
|
7
|
+
*/
|
8
|
+
import React from 'react';
|
9
|
+
import { getCurrentHashValue, trimArrZero } from './utils';
|
10
|
+
import './index.less';
|
11
|
+
|
12
|
+
var MdNavbar = function MdNavbar(props) {
|
13
|
+
var source = props.source,
|
14
|
+
ordered = props.ordered,
|
15
|
+
declarative = props.declarative,
|
16
|
+
className = props.className,
|
17
|
+
onNavItemClick = props.onNavItemClick,
|
18
|
+
onHashChange = props.onHashChange;
|
19
|
+
|
20
|
+
var _React$useState = React.useState(''),
|
21
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
22
|
+
currentListNo = _React$useState2[0],
|
23
|
+
setCurrentListNo = _React$useState2[1];
|
24
|
+
|
25
|
+
var scrollTimeoutRef = React.useRef();
|
26
|
+
var addTargetTimeoutRef = React.useRef();
|
27
|
+
var navStructure = React.useMemo(function () {
|
28
|
+
var contentWithoutCode = source.replace(/^[^#]+\n/g, '').replace(/(?:[^\n#]+)#+\s([^#\n]+)\n*/g, '') // 匹配行内出现 # 号的情况
|
29
|
+
.replace(/^#\s[^#\n]*\n+/, '').replace(/```[^`\n]*\n+[^```]+```\n+/g, '').replace(/`([^`\n]+)`/g, '$1').replace(/\*\*?([^*\n]+)\*\*?/g, '$1').replace(/__?([^_\n]+)__?/g, '$1').trim();
|
30
|
+
var pattOfTitle = /#+\s([^#\n]+)\n*/g;
|
31
|
+
var matchResult = contentWithoutCode.match(pattOfTitle);
|
32
|
+
|
33
|
+
if (!matchResult) {
|
34
|
+
return [];
|
35
|
+
}
|
36
|
+
|
37
|
+
var navData = matchResult.map(function (r, i) {
|
38
|
+
return {
|
39
|
+
index: i,
|
40
|
+
level: r.match(/^#+/g)[0].length,
|
41
|
+
text: r.replace(pattOfTitle, '$1')
|
42
|
+
};
|
43
|
+
});
|
44
|
+
var maxLevel = 0;
|
45
|
+
navData.forEach(function (t) {
|
46
|
+
if (t.level > maxLevel) {
|
47
|
+
maxLevel = t.level;
|
48
|
+
}
|
49
|
+
});
|
50
|
+
var matchStack = []; // 此部分重构,原有方法会出现次级标题后再次出现高级标题时,listNo重复的bug
|
51
|
+
|
52
|
+
for (var i = 0; i < navData.length; i++) {
|
53
|
+
var t = navData[i];
|
54
|
+
var level = t.level;
|
55
|
+
|
56
|
+
while (matchStack.length && matchStack[matchStack.length - 1].level > level) {
|
57
|
+
matchStack.pop();
|
58
|
+
}
|
59
|
+
|
60
|
+
if (matchStack.length === 0) {
|
61
|
+
var _arr = new Array(maxLevel).fill(0);
|
62
|
+
|
63
|
+
_arr[level - 1] += 1;
|
64
|
+
matchStack.push({
|
65
|
+
level: level,
|
66
|
+
arr: _arr
|
67
|
+
});
|
68
|
+
t.listNo = trimArrZero(_arr).join('.');
|
69
|
+
continue;
|
70
|
+
}
|
71
|
+
|
72
|
+
var arr = matchStack[matchStack.length - 1].arr;
|
73
|
+
var newArr = arr.slice();
|
74
|
+
newArr[level - 1] += 1;
|
75
|
+
matchStack.push({
|
76
|
+
level: level,
|
77
|
+
arr: newArr
|
78
|
+
});
|
79
|
+
t.listNo = trimArrZero(newArr).join('.');
|
80
|
+
}
|
81
|
+
|
82
|
+
return navData;
|
83
|
+
}, [source]);
|
84
|
+
var initHeadingsId = React.useCallback(function () {
|
85
|
+
var headingId = decodeURIComponent(declarative ? window.location.hash.replace(/^#/, '').trim() : (window.location.hash.match(/heading-\d+/g) || [])[0]);
|
86
|
+
navStructure.forEach(function (t) {
|
87
|
+
var headings = document.querySelectorAll("h".concat(t.level));
|
88
|
+
var curHeading = Array.prototype.slice.apply(headings).find(function (h) {
|
89
|
+
return h.innerText.trim() === t.text.trim() && (!h.dataset || !h.dataset.id);
|
90
|
+
});
|
91
|
+
|
92
|
+
if (curHeading) {
|
93
|
+
curHeading.dataset.id = declarative ? "".concat(t.listNo, "-").concat(t.text) : "heading-".concat(t.index);
|
94
|
+
|
95
|
+
if (headingId && headingId === curHeading.dataset.id) {
|
96
|
+
scrollToTarget(headingId);
|
97
|
+
setCurrentListNo(t.listNo);
|
98
|
+
}
|
99
|
+
}
|
100
|
+
});
|
101
|
+
}, []);
|
102
|
+
var refreshNav = React.useCallback(function () {
|
103
|
+
if (addTargetTimeoutRef.current) {
|
104
|
+
clearTimeout(addTargetTimeoutRef.current);
|
105
|
+
}
|
106
|
+
|
107
|
+
addTargetTimeoutRef.current = setTimeout(function () {
|
108
|
+
initHeadingsId();
|
109
|
+
|
110
|
+
if (navStructure.length) {
|
111
|
+
var listNo = navStructure[0].listNo;
|
112
|
+
setCurrentListNo(listNo);
|
113
|
+
}
|
114
|
+
}, 500);
|
115
|
+
}, []);
|
116
|
+
React.useEffect(function () {
|
117
|
+
if (navStructure) {
|
118
|
+
refreshNav();
|
119
|
+
}
|
120
|
+
}, [navStructure]);
|
121
|
+
|
122
|
+
var scrollToTarget = function scrollToTarget(dataId) {
|
123
|
+
if (scrollTimeoutRef.current) {
|
124
|
+
clearTimeout(scrollTimeoutRef.current);
|
125
|
+
}
|
126
|
+
|
127
|
+
scrollTimeoutRef.current = setTimeout(function () {
|
128
|
+
var target = document.querySelector("[data-id=\"".concat(dataId, "\"]"));
|
129
|
+
|
130
|
+
if (target) {
|
131
|
+
target.scrollIntoView({
|
132
|
+
block: 'start',
|
133
|
+
behavior: 'smooth'
|
134
|
+
});
|
135
|
+
}
|
136
|
+
}, 0);
|
137
|
+
};
|
138
|
+
|
139
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
140
|
+
className: "markdown-navigation ".concat(className)
|
141
|
+
}, navStructure.map(function (t) {
|
142
|
+
var cls = "title-anchor title-level".concat(t.level, " ").concat(currentListNo === t.listNo ? 'active' : '');
|
143
|
+
return /*#__PURE__*/React.createElement("div", {
|
144
|
+
className: cls,
|
145
|
+
onClick: function onClick(evt) {
|
146
|
+
var currentHash = declarative ? "".concat(t.listNo, "-").concat(t.text) // 加入listNo确保hash唯一ZZ
|
147
|
+
: "heading-".concat(t.index); // Avoid execution the callback `onHashChange` when clicking current nav item
|
148
|
+
|
149
|
+
if (t.listNo !== currentListNo) {
|
150
|
+
// Hash changing callback
|
151
|
+
onHashChange && onHashChange(currentHash, getCurrentHashValue());
|
152
|
+
} // Nav item clicking callback
|
153
|
+
|
154
|
+
|
155
|
+
onNavItemClick && onNavItemClick(evt, evt.target, currentHash);
|
156
|
+
scrollToTarget(currentHash);
|
157
|
+
setCurrentListNo(t.listNo);
|
158
|
+
},
|
159
|
+
key: "title_anchor_".concat(Math.random().toString(36).substring(2))
|
160
|
+
}, ordered ? /*#__PURE__*/React.createElement("small", null, t.listNo) : null, t.text);
|
161
|
+
})));
|
162
|
+
};
|
163
|
+
|
164
|
+
export default MdNavbar;
|
@@ -0,0 +1,77 @@
|
|
1
|
+
.markdown-navigation {
|
2
|
+
font-size: 14px;
|
3
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Helvetica', 'Arial', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei',
|
4
|
+
'WenQuanYi Micro Hei', sans-serif;
|
5
|
+
width: 100%;
|
6
|
+
overflow-x: hidden;
|
7
|
+
overflow-y: scroll;
|
8
|
+
scrollbar-width: 0;
|
9
|
+
width: 200px;
|
10
|
+
}
|
11
|
+
.markdown-navigation::-webkit-scrollbar {
|
12
|
+
width: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
.markdown-navigation .title-anchor {
|
16
|
+
display: block;
|
17
|
+
color: #bbb;
|
18
|
+
transition: all 0.2s;
|
19
|
+
margin: 0.8em 0;
|
20
|
+
font-weight: lighter;
|
21
|
+
line-height: 2em;
|
22
|
+
padding-right: 1.8em;
|
23
|
+
cursor: pointer;
|
24
|
+
}
|
25
|
+
|
26
|
+
.markdown-navigation .title-anchor:hover,
|
27
|
+
.markdown-navigation .title-anchor.active {
|
28
|
+
background-color: #f8f8f8;
|
29
|
+
text-decoration: inherit;
|
30
|
+
}
|
31
|
+
|
32
|
+
.markdown-navigation .title-anchor.active {
|
33
|
+
color: #007fff;
|
34
|
+
}
|
35
|
+
|
36
|
+
.markdown-navigation .title-anchor small {
|
37
|
+
margin: 0 0.8em;
|
38
|
+
}
|
39
|
+
|
40
|
+
.markdown-navigation .title-level1 {
|
41
|
+
color: #000;
|
42
|
+
font-size: 1.2em;
|
43
|
+
padding-left: 1em;
|
44
|
+
font-weight: normal;
|
45
|
+
}
|
46
|
+
|
47
|
+
.markdown-navigation .title-level2 {
|
48
|
+
color: #000;
|
49
|
+
font-size: 1em;
|
50
|
+
padding-left: 1em;
|
51
|
+
font-weight: normal;
|
52
|
+
}
|
53
|
+
|
54
|
+
.markdown-navigation .title-level3 {
|
55
|
+
color: #000;
|
56
|
+
font-size: 0.8em;
|
57
|
+
padding-left: 3em;
|
58
|
+
font-weight: normal;
|
59
|
+
}
|
60
|
+
|
61
|
+
.markdown-navigation .title-level4 {
|
62
|
+
color: #000;
|
63
|
+
font-size: 0.72em;
|
64
|
+
padding-left: 5em;
|
65
|
+
}
|
66
|
+
|
67
|
+
.markdown-navigation .title-level5 {
|
68
|
+
color: #000;
|
69
|
+
font-size: 0.72em;
|
70
|
+
padding-left: 7em;
|
71
|
+
}
|
72
|
+
|
73
|
+
.markdown-navigation .title-level6 {
|
74
|
+
color: #000;
|
75
|
+
font-size: 0.72em;
|
76
|
+
padding-left: 9em;
|
77
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: wangxian
|
3
|
+
* @Date: 2022-10-14 10:03:03
|
4
|
+
* @LastEditTime: 2022-10-14 10:17:18
|
5
|
+
*/
|
6
|
+
export var getCurrentHashValue = function getCurrentHashValue() {
|
7
|
+
return decodeURIComponent(window.location.hash.replace(/^#/, ''));
|
8
|
+
};
|
9
|
+
export var trimArrZero = function trimArrZero(arr) {
|
10
|
+
var start, end;
|
11
|
+
|
12
|
+
for (start = 0; start < arr.length; start++) {
|
13
|
+
if (arr[start]) {
|
14
|
+
break;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
for (end = arr.length - 1; end >= 0; end--) {
|
19
|
+
if (arr[end]) {
|
20
|
+
break;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
return arr.slice(start, end + 1);
|
25
|
+
};
|
26
|
+
export var updateHash = function updateHash(updateHashTimeout, value) {
|
27
|
+
if (updateHashTimeout) {
|
28
|
+
clearTimeout(updateHashTimeout);
|
29
|
+
}
|
30
|
+
|
31
|
+
updateHashTimeout = setTimeout(function () {
|
32
|
+
window.history.replaceState({}, '', "".concat(window.location.pathname).concat(window.location.search, "#").concat(value));
|
33
|
+
}, 0);
|
34
|
+
};
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import 'markdown-navbar/dist/navbar.css';
|
2
1
|
import 'github-markdown-css';
|
3
2
|
import './index.less';
|
4
3
|
interface IMdViewProps {
|
@@ -10,6 +9,16 @@ interface IMdViewProps {
|
|
10
9
|
* 是否显示导航
|
11
10
|
*/
|
12
11
|
isMarkNav?: boolean;
|
12
|
+
navOptions?: {
|
13
|
+
/** Automatically update the hash value of browser address when page scrolling if true */
|
14
|
+
updateHashAuto?: boolean;
|
15
|
+
/** Use the text of the title from Markdown content as the hash value for the anchor if true */
|
16
|
+
declarative?: boolean;
|
17
|
+
/** The event callback function after clicking navbar item */
|
18
|
+
onNavItemClick?: (event: any, element: HTMLDivElement, hashValue: string) => void;
|
19
|
+
/** The event callback function before the hash value of browser address changing */
|
20
|
+
onHashChange?: (newHash: string, oldHash: string) => void;
|
21
|
+
};
|
13
22
|
}
|
14
23
|
declare const MdView: (props: IMdViewProps) => JSX.Element;
|
15
24
|
export default MdView;
|
package/es/comps/MdView/index.js
CHANGED
@@ -1,22 +1,23 @@
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
1
2
|
import React from "react";
|
2
3
|
|
3
4
|
/*
|
4
5
|
* @Author: wangxian
|
5
6
|
* @Date: 2022-09-02 16:17:38
|
6
|
-
* @LastEditTime: 2022-10-
|
7
|
+
* @LastEditTime: 2022-10-14 11:06:26
|
7
8
|
*/
|
8
9
|
import ReactMarkdown from 'react-markdown';
|
9
10
|
import remarkGfm from 'remark-gfm';
|
10
11
|
import rehypeRaw from 'rehype-raw';
|
11
|
-
import MarkNav from 'markdown-navbar';
|
12
|
-
import 'markdown-navbar/dist/navbar.css';
|
13
12
|
import 'github-markdown-css';
|
14
13
|
import './index.less';
|
14
|
+
import MdNavbar from '../MdNavbar';
|
15
15
|
|
16
16
|
var MdView = function MdView(props) {
|
17
17
|
var source = props.source,
|
18
18
|
_props$isMarkNav = props.isMarkNav,
|
19
|
-
isMarkNav = _props$isMarkNav === void 0 ? false : _props$isMarkNav
|
19
|
+
isMarkNav = _props$isMarkNav === void 0 ? false : _props$isMarkNav,
|
20
|
+
navOptions = props.navOptions;
|
20
21
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
21
22
|
className: "react-mark-down",
|
22
23
|
style: {
|
@@ -35,11 +36,11 @@ var MdView = function MdView(props) {
|
|
35
36
|
padding: '10px',
|
36
37
|
overflowY: 'auto'
|
37
38
|
}
|
38
|
-
}, /*#__PURE__*/React.createElement(
|
39
|
+
}, /*#__PURE__*/React.createElement(MdNavbar, _extends({
|
39
40
|
className: "h-full w-full",
|
40
41
|
source: source,
|
41
42
|
ordered: true
|
42
|
-
}))));
|
43
|
+
}, navOptions)))));
|
43
44
|
};
|
44
45
|
|
45
46
|
export default MdView;
|