dumi 2.0.0-beta.0 → 2.0.0-beta.1
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/assetParsers/atom.d.ts +25 -0
- package/dist/assetParsers/atom.js +74 -0
- package/dist/client/theme-api/context.d.ts +2 -0
- package/dist/client/theme-api/context.js +3 -1
- package/dist/features/theme/index.js +17 -2
- package/dist/loaders/markdown/index.js +8 -1
- package/package.json +3 -2
- package/theme-default/layouts/DocLayout/index.less +1 -0
- package/theme-default/slots/Content/index.less +1 -1
- package/theme-default/slots/Header/index.less +9 -1
- package/theme-default/slots/Logo/index.less +1 -1
- package/theme-default/slots/Sidebar/index.less +4 -1
- package/theme-default/slots/Toc/index.js +68 -20
- package/theme-default/styles/variables.less +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SchemaParser, SchemaResolver } from 'dumi-afx-deps/compiled/parser';
|
|
2
|
+
import type { webpack } from 'umi';
|
|
3
|
+
declare class AtomParserWatchWebpackPlugin {
|
|
4
|
+
resolveDir: string;
|
|
5
|
+
onWatchRun: (files: string[]) => void;
|
|
6
|
+
constructor(opts: {
|
|
7
|
+
resolveDir: string;
|
|
8
|
+
onWatchRun: typeof AtomParserWatchWebpackPlugin.prototype.onWatchRun;
|
|
9
|
+
});
|
|
10
|
+
apply(compiler: webpack.Compiler): void;
|
|
11
|
+
}
|
|
12
|
+
declare class AtomAssetsParser {
|
|
13
|
+
parser: SchemaParser;
|
|
14
|
+
resolver: Promise<SchemaResolver> | undefined;
|
|
15
|
+
resolveDir: string;
|
|
16
|
+
unresolvedFiles: string[];
|
|
17
|
+
constructor(opts: {
|
|
18
|
+
entryFile: string;
|
|
19
|
+
resolveDir: string;
|
|
20
|
+
});
|
|
21
|
+
parse(): Promise<SchemaResolver>;
|
|
22
|
+
patchUnresolvedFiles(files: string[]): void;
|
|
23
|
+
getWebpackWatchPlugin(): AtomParserWatchWebpackPlugin;
|
|
24
|
+
}
|
|
25
|
+
export default AtomAssetsParser;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
|
|
22
|
+
// src/assetParsers/atom.ts
|
|
23
|
+
var atom_exports = {};
|
|
24
|
+
__export(atom_exports, {
|
|
25
|
+
default: () => atom_default
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(atom_exports);
|
|
28
|
+
var import_parser = require("dumi-afx-deps/compiled/parser");
|
|
29
|
+
var import_path = __toESM(require("path"));
|
|
30
|
+
var import_plugin_utils = require("umi/plugin-utils");
|
|
31
|
+
var AtomParserWatchWebpackPlugin = class {
|
|
32
|
+
constructor(opts) {
|
|
33
|
+
this.resolveDir = opts.resolveDir;
|
|
34
|
+
this.onWatchRun = opts.onWatchRun;
|
|
35
|
+
}
|
|
36
|
+
apply(compiler) {
|
|
37
|
+
compiler.hooks.watchRun.tap(this.constructor.name, (compilation) => {
|
|
38
|
+
const files = Array.from(compilation.watchFileSystem.watcher.fileWatchers.keys());
|
|
39
|
+
this.onWatchRun(files.map((file) => (0, import_plugin_utils.winPath)(import_path.default.relative(this.resolveDir, file))).filter((file) => /\.(j|t)sx?$/.test(file) && !file.startsWith("../") && !file.includes(".umi")));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var AtomAssetsParser = class {
|
|
44
|
+
constructor(opts) {
|
|
45
|
+
this.unresolvedFiles = [];
|
|
46
|
+
this.resolveDir = opts.resolveDir;
|
|
47
|
+
this.parser = new import_parser.SchemaParser({
|
|
48
|
+
entryPath: opts.entryFile,
|
|
49
|
+
basePath: opts.resolveDir,
|
|
50
|
+
unPkgHost: "https://unpkg.com"
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async parse() {
|
|
54
|
+
if (!this.resolver || this.unresolvedFiles.length) {
|
|
55
|
+
this.resolver = (async () => {
|
|
56
|
+
await this.parser.patch(this.unresolvedFiles);
|
|
57
|
+
return new import_parser.SchemaResolver(await this.parser.parse());
|
|
58
|
+
})();
|
|
59
|
+
}
|
|
60
|
+
return this.resolver;
|
|
61
|
+
}
|
|
62
|
+
patchUnresolvedFiles(files) {
|
|
63
|
+
this.unresolvedFiles.push(...files);
|
|
64
|
+
}
|
|
65
|
+
getWebpackWatchPlugin() {
|
|
66
|
+
return new AtomParserWatchWebpackPlugin({
|
|
67
|
+
resolveDir: this.resolveDir,
|
|
68
|
+
onWatchRun: (files) => this.parser.patch(files)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var atom_default = AtomAssetsParser;
|
|
73
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
74
|
+
0 && (module.exports = {});
|
|
@@ -7,6 +7,8 @@ interface ISiteContext {
|
|
|
7
7
|
}>;
|
|
8
8
|
locales: NonNullable<ILocalesConfig>;
|
|
9
9
|
themeConfig: IThemeConfig;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
setLoading: (status: boolean) => void;
|
|
10
12
|
}
|
|
11
13
|
export declare const SiteContext: import("react").Context<ISiteContext>;
|
|
12
14
|
export declare const useSiteData: () => ISiteContext;
|
|
@@ -2,7 +2,9 @@ import { createContext, useContext } from 'react';
|
|
|
2
2
|
export var SiteContext = /*#__PURE__*/createContext({
|
|
3
3
|
demos: {},
|
|
4
4
|
locales: [],
|
|
5
|
-
themeConfig: {}
|
|
5
|
+
themeConfig: {},
|
|
6
|
+
loading: false,
|
|
7
|
+
setLoading: function setLoading() {}
|
|
6
8
|
});
|
|
7
9
|
export var useSiteData = function useSiteData() {
|
|
8
10
|
return useContext(SiteContext);
|
|
@@ -106,16 +106,31 @@ export { default } from '${item.source}';`
|
|
|
106
106
|
api.writeTmpFile({
|
|
107
107
|
noPluginDir: true,
|
|
108
108
|
path: "dumi/theme/ContextWrapper.tsx",
|
|
109
|
-
content: `import {
|
|
109
|
+
content: `import React, { useState, useEffect } from 'react';
|
|
110
|
+
import { useOutlet, history } from 'dumi';
|
|
110
111
|
import { SiteContext } from '${(0, import_plugin_utils.winPath)(require.resolve("../../client/theme-api/context"))}';
|
|
111
112
|
import { demos } from '../meta';
|
|
112
113
|
import { locales } from '../locales/config';
|
|
113
114
|
|
|
114
115
|
export default function DumiContextWrapper() {
|
|
115
116
|
const outlet = useOutlet();
|
|
117
|
+
const [loading, setLoading] = useState(true);
|
|
118
|
+
|
|
119
|
+
// mark loading when route change, page component will set false when loaded
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
return history.listen(() => setLoading(true));
|
|
122
|
+
}, []);
|
|
116
123
|
|
|
117
124
|
return (
|
|
118
|
-
<SiteContext.Provider value={{
|
|
125
|
+
<SiteContext.Provider value={{
|
|
126
|
+
demos,
|
|
127
|
+
locales,
|
|
128
|
+
loading,
|
|
129
|
+
setLoading,
|
|
130
|
+
themeConfig: ${JSON.stringify(api.config.themeConfig)},
|
|
131
|
+
}}>
|
|
132
|
+
{outlet}
|
|
133
|
+
</SiteContext.Provider>
|
|
119
134
|
);
|
|
120
135
|
}`
|
|
121
136
|
});
|
|
@@ -72,11 +72,18 @@ export const toc = {{{toc}}}
|
|
|
72
72
|
}));
|
|
73
73
|
} else {
|
|
74
74
|
cb(null, `${Object.values(opts.builtins).map((item) => `import ${item.specifier} from '${item.source}';`).join("\n")}
|
|
75
|
-
import React from 'react';
|
|
75
|
+
import React, { useEffect } from 'react';
|
|
76
|
+
import { useSiteData } from 'dumi';
|
|
76
77
|
|
|
77
78
|
// export named function for fastRefresh
|
|
78
79
|
// ref: https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#edits-always-lead-to-full-reload
|
|
79
80
|
function DumiMarkdownContent() {
|
|
81
|
+
const { setLoading } = useSiteData();
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
setLoading(false);
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
80
87
|
return ${ret.content};
|
|
81
88
|
}
|
|
82
89
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dumi",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"description": "Framework for developing UI components",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"dev": "father dev",
|
|
22
22
|
"docs:build": "node ./bin/dumi.js build",
|
|
23
23
|
"docs:dev": "node ./bin/dumi.js dev",
|
|
24
|
-
"postinstall": "npm run build && node ./bin/dumi.js setup",
|
|
25
24
|
"lint": "npm run lint:es && npm run lint:css",
|
|
26
25
|
"lint:css": "stylelint \"{src,test}/**/*.{css,less}\"",
|
|
27
26
|
"lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"",
|
|
27
|
+
"prepare": "npm run build && node ./bin/dumi.js setup",
|
|
28
28
|
"prepublishOnly": "npm run build",
|
|
29
29
|
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules pnpm jest"
|
|
30
30
|
},
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@ant-design/icons-svg": "^4.2.1",
|
|
55
|
+
"@makotot/ghostui": "^2.0.0",
|
|
55
56
|
"@swc/core": "^1.2.224",
|
|
56
57
|
"@types/hast": "^2.3.4",
|
|
57
58
|
"@types/mdast": "^3.0.10",
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
@import (reference) '../../styles/variables.less';
|
|
2
2
|
|
|
3
3
|
.@{prefix}-header {
|
|
4
|
+
position: sticky;
|
|
5
|
+
top: 0;
|
|
6
|
+
z-index: 10;
|
|
4
7
|
display: flex;
|
|
8
|
+
margin: 0 -24px;
|
|
9
|
+
padding: 0 24px;
|
|
5
10
|
align-items: center;
|
|
6
|
-
height:
|
|
11
|
+
height: @s-header-height;
|
|
12
|
+
background-color: fadeout(@c-site-bg, 10%);
|
|
13
|
+
backdrop-filter: blur(6px);
|
|
14
|
+
box-sizing: border-box;
|
|
7
15
|
|
|
8
16
|
&-left {
|
|
9
17
|
width: @s-sidebar-width;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
@import (reference) '../../styles/variables.less';
|
|
2
2
|
|
|
3
3
|
.@{prefix}-sidebar {
|
|
4
|
+
position: sticky;
|
|
5
|
+
top: @s-header-height;
|
|
4
6
|
width: @s-sidebar-width;
|
|
5
|
-
|
|
7
|
+
max-height: calc(100vh - @s-header-height);
|
|
6
8
|
padding: 20px 32px 24px 8px;
|
|
7
9
|
box-sizing: border-box;
|
|
10
|
+
overflow: auto;
|
|
8
11
|
|
|
9
12
|
> dl {
|
|
10
13
|
margin: 0;
|
|
@@ -1,33 +1,81 @@
|
|
|
1
1
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
4
|
+
|
|
5
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
6
|
+
|
|
7
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
|
+
|
|
9
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
10
|
+
|
|
11
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
12
|
+
|
|
13
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
14
|
+
|
|
15
|
+
import { Scrollspy as ScrollSpy } from '@makotot/ghostui/src/Scrollspy';
|
|
16
|
+
import { useLocation, useRouteMeta, useSiteData } from 'dumi';
|
|
17
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
5
18
|
import "./index.less";
|
|
6
19
|
|
|
7
20
|
var Toc = function Toc() {
|
|
8
21
|
var _useLocation = useLocation(),
|
|
9
|
-
|
|
22
|
+
pathname = _useLocation.pathname;
|
|
23
|
+
|
|
24
|
+
var meta = useRouteMeta();
|
|
25
|
+
|
|
26
|
+
var _useSiteData = useSiteData(),
|
|
27
|
+
loading = _useSiteData.loading;
|
|
28
|
+
|
|
29
|
+
var prevIndexRef = useRef(0);
|
|
30
|
+
|
|
31
|
+
var _useState = useState([]),
|
|
32
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
33
|
+
sectionRefs = _useState2[0],
|
|
34
|
+
setSectionRefs = _useState2[1]; // only render h2 ~ h4
|
|
10
35
|
|
|
11
|
-
var _useRouteMeta = useRouteMeta(),
|
|
12
|
-
toc = _useRouteMeta.toc;
|
|
13
36
|
|
|
14
|
-
|
|
15
|
-
className: "dumi-default-toc"
|
|
16
|
-
}, toc.filter(function (_ref) {
|
|
37
|
+
var toc = meta.toc.filter(function (_ref) {
|
|
17
38
|
var depth = _ref.depth;
|
|
18
39
|
return depth > 1 && depth < 4;
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
});
|
|
41
|
+
useEffect(function () {
|
|
42
|
+
// wait for page component ready (DOM ready)
|
|
43
|
+
if (!loading) {
|
|
44
|
+
// find all valid headings as ref elements
|
|
45
|
+
var refs = toc.map(function (_ref2) {
|
|
46
|
+
var id = _ref2.id;
|
|
47
|
+
return {
|
|
48
|
+
current: document.getElementById(id)
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
setSectionRefs(refs);
|
|
52
|
+
}
|
|
53
|
+
}, [pathname, loading]);
|
|
54
|
+
return sectionRefs.length ? /*#__PURE__*/React.createElement(ScrollSpy, {
|
|
55
|
+
sectionRefs: sectionRefs
|
|
56
|
+
}, function (_ref3) {
|
|
57
|
+
var currentElementIndexInViewport = _ref3.currentElementIndexInViewport;
|
|
58
|
+
// for keep prev item active when no item in viewport
|
|
59
|
+
if (currentElementIndexInViewport > -1) prevIndexRef.current = currentElementIndexInViewport;
|
|
60
|
+
return /*#__PURE__*/React.createElement("ul", {
|
|
61
|
+
className: "dumi-default-toc"
|
|
62
|
+
}, toc.filter(function (_ref4) {
|
|
63
|
+
var depth = _ref4.depth;
|
|
64
|
+
return depth > 1 && depth < 4;
|
|
65
|
+
}).map(function (item, i) {
|
|
66
|
+
var link = "#".concat(encodeURIComponent(item.id));
|
|
67
|
+
var activeIndex = currentElementIndexInViewport > -1 ? currentElementIndexInViewport : prevIndexRef.current;
|
|
68
|
+
return /*#__PURE__*/React.createElement("li", {
|
|
69
|
+
key: item.id,
|
|
70
|
+
"data-depth": item.depth
|
|
71
|
+
}, /*#__PURE__*/React.createElement("a", _extends({
|
|
72
|
+
href: link,
|
|
73
|
+
title: item.title
|
|
74
|
+
}, activeIndex === i ? {
|
|
75
|
+
className: 'active'
|
|
76
|
+
} : {}), item.title));
|
|
77
|
+
}));
|
|
78
|
+
}) : null;
|
|
31
79
|
};
|
|
32
80
|
|
|
33
81
|
export default Toc;
|