dumi 2.0.0-beta.16 → 2.0.0-beta.17
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/client/theme-api/index.d.ts +1 -0
- package/dist/client/theme-api/index.js +1 -0
- package/dist/client/theme-api/openCodeSandbox.d.ts +9 -0
- package/dist/client/theme-api/openCodeSandbox.js +110 -0
- package/dist/client/theme-api/types.d.ts +4 -2
- package/dist/client/theme-api/utils.d.ts +6 -0
- package/dist/client/theme-api/utils.js +15 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +3 -0
- package/dist/features/configPlugins/index.js +3 -1
- package/dist/features/derivative.js +6 -0
- package/dist/features/routes.js +2 -9
- package/dist/loaders/markdown/index.js +15 -2
- package/dist/loaders/markdown/transformer/rehypeDemo.js +4 -4
- package/dist/loaders/markdown/transformer/remarkMeta.js +2 -0
- package/package.json +2 -3
- package/theme-default/layouts/DocLayout/index.js +5 -1
- package/theme-default/layouts/DocLayout/index.less +18 -0
- package/theme-default/locales/en-US.json +1 -1
- package/theme-default/locales/zh-CN.json +1 -1
- package/theme-default/slots/Content/index.less +7 -1
- package/theme-default/slots/Features/index.js +6 -2
- package/theme-default/slots/Features/index.less +9 -1
- package/theme-default/slots/Footer/index.d.ts +4 -0
- package/theme-default/slots/Footer/index.js +18 -0
- package/theme-default/slots/Footer/index.less +19 -0
- package/theme-default/slots/Hero/index.less +9 -5
- package/theme-default/slots/PreviewerActions/index.js +5 -2
- package/theme-default/slots/Sidebar/index.js +3 -2
- package/theme-default/slots/Toc/index.less +4 -0
- package/theme.d.ts +0 -1
|
@@ -3,6 +3,7 @@ export { useSiteData } from './context';
|
|
|
3
3
|
export { DumiDemo } from './DumiDemo';
|
|
4
4
|
export { DumiDemoGrid } from './DumiDemoGrid';
|
|
5
5
|
export { DumiPage } from './DumiPage';
|
|
6
|
+
export { openCodeSandbox } from './openCodeSandbox';
|
|
6
7
|
export type { IPreviewerProps } from './types';
|
|
7
8
|
export { useAtomAssets } from './useAtomAssets';
|
|
8
9
|
export { useLocale } from './useLocale';
|
|
@@ -3,6 +3,7 @@ export { useSiteData } from "./context";
|
|
|
3
3
|
export { DumiDemo } from "./DumiDemo";
|
|
4
4
|
export { DumiDemoGrid } from "./DumiDemoGrid";
|
|
5
5
|
export { DumiPage } from "./DumiPage";
|
|
6
|
+
export { openCodeSandbox } from "./openCodeSandbox";
|
|
6
7
|
export { useAtomAssets } from "./useAtomAssets";
|
|
7
8
|
export { useLocale } from "./useLocale";
|
|
8
9
|
export { useNavData } from "./useNavData";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* use CodeSandbox.io
|
|
3
|
+
* @param data previewer opts
|
|
4
|
+
* @param opts the api that CodeSandbox calls when creating the demo
|
|
5
|
+
* @note return a open function for open demo on codesandbox.io
|
|
6
|
+
*/
|
|
7
|
+
export declare const openCodeSandbox: (data: IPreviewerProps, opts?: {
|
|
8
|
+
api?: string;
|
|
9
|
+
}) => void;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
|
|
3
|
+
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."); }
|
|
4
|
+
|
|
5
|
+
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); }
|
|
6
|
+
|
|
7
|
+
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; }
|
|
8
|
+
|
|
9
|
+
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; }
|
|
10
|
+
|
|
11
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
12
|
+
|
|
13
|
+
import { getParameters } from 'codesandbox/lib/api/define';
|
|
14
|
+
import { genReactRenderCode } from "./utils";
|
|
15
|
+
var CSB_API_ENDPOINT = 'https://codesandbox.io/api/v1/sandboxes/define';
|
|
16
|
+
/**
|
|
17
|
+
* get serialized data that use to submit to codesandbox.io
|
|
18
|
+
* @param opts previewer props
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
function getCSBData(opts) {
|
|
22
|
+
var _opts$asset$dependenc, _react, _deps$_react, _reactDom, _deps$_reactDom;
|
|
23
|
+
|
|
24
|
+
var isTSX = Boolean((_opts$asset$dependenc = opts.asset.dependencies) === null || _opts$asset$dependenc === void 0 ? void 0 : _opts$asset$dependenc['index.tsx']);
|
|
25
|
+
var ext = isTSX ? '.tsx' : '.jsx';
|
|
26
|
+
var files = {};
|
|
27
|
+
var deps = {};
|
|
28
|
+
var entryFileName = "index".concat(ext);
|
|
29
|
+
Object.entries(opts.asset.dependencies).forEach(function (_ref) {
|
|
30
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
31
|
+
name = _ref2[0],
|
|
32
|
+
_ref2$ = _ref2[1],
|
|
33
|
+
type = _ref2$.type,
|
|
34
|
+
value = _ref2$.value;
|
|
35
|
+
|
|
36
|
+
if (type === 'NPM') {
|
|
37
|
+
// generate dependencies
|
|
38
|
+
deps[name] = value;
|
|
39
|
+
} else {
|
|
40
|
+
// append other imported local files
|
|
41
|
+
files[name === entryFileName ? "App".concat(ext) : name] = {
|
|
42
|
+
content: value,
|
|
43
|
+
isBinary: false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}); // add react、react-dom dependency
|
|
47
|
+
|
|
48
|
+
(_deps$_react = deps[_react = 'react']) !== null && _deps$_react !== void 0 ? _deps$_react : deps[_react] = 'latest';
|
|
49
|
+
(_deps$_reactDom = deps[_reactDom = 'react-dom']) !== null && _deps$_reactDom !== void 0 ? _deps$_reactDom : deps[_reactDom] = deps.react; // append sandbox.config.json
|
|
50
|
+
|
|
51
|
+
files['sandbox.config.json'] = {
|
|
52
|
+
content: JSON.stringify({
|
|
53
|
+
template: isTSX ? 'create-react-app-typescript' : 'create-react-app'
|
|
54
|
+
}, null, 2),
|
|
55
|
+
isBinary: false
|
|
56
|
+
}; // append package.json
|
|
57
|
+
|
|
58
|
+
files['package.json'] = {
|
|
59
|
+
content: JSON.stringify({
|
|
60
|
+
name: opts.title,
|
|
61
|
+
description: opts.description || 'An auto-generated demo by dumi',
|
|
62
|
+
main: entryFileName,
|
|
63
|
+
dependencies: deps,
|
|
64
|
+
// add TypeScript dependency if required, must in devDeps to avoid csb compile error
|
|
65
|
+
devDependencies: isTSX ? {
|
|
66
|
+
typescript: '^4'
|
|
67
|
+
} : {}
|
|
68
|
+
}, null, 2),
|
|
69
|
+
isBinary: false
|
|
70
|
+
}; // append index.html
|
|
71
|
+
|
|
72
|
+
files['index.html'] = {
|
|
73
|
+
content: '<div style="margin: 16px;" id="root"></div>',
|
|
74
|
+
isBinary: false
|
|
75
|
+
}; // append entry file
|
|
76
|
+
|
|
77
|
+
files[entryFileName] = {
|
|
78
|
+
content: genReactRenderCode(deps.react),
|
|
79
|
+
isBinary: false
|
|
80
|
+
};
|
|
81
|
+
return getParameters({
|
|
82
|
+
files: files
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* use CodeSandbox.io
|
|
87
|
+
* @param data previewer opts
|
|
88
|
+
* @param opts the api that CodeSandbox calls when creating the demo
|
|
89
|
+
* @note return a open function for open demo on codesandbox.io
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
export var openCodeSandbox = function openCodeSandbox(data, opts) {
|
|
94
|
+
var _data$assets;
|
|
95
|
+
|
|
96
|
+
var form = document.createElement('form');
|
|
97
|
+
var input = document.createElement('input');
|
|
98
|
+
var CSBData = getCSBData(data);
|
|
99
|
+
form.method = 'POST';
|
|
100
|
+
form.target = '_blank';
|
|
101
|
+
form.style.display = 'none';
|
|
102
|
+
form.action = (opts === null || opts === void 0 ? void 0 : opts.api) || CSB_API_ENDPOINT;
|
|
103
|
+
form.appendChild(input);
|
|
104
|
+
form.setAttribute('data-demo', ((_data$assets = data.assets) === null || _data$assets === void 0 ? void 0 : _data$assets.id) || '');
|
|
105
|
+
input.name = 'parameters';
|
|
106
|
+
input.value = CSBData;
|
|
107
|
+
document.body.appendChild(form);
|
|
108
|
+
form.submit();
|
|
109
|
+
form.remove();
|
|
110
|
+
};
|
|
@@ -10,9 +10,9 @@ export interface IPreviewerProps {
|
|
|
10
10
|
*/
|
|
11
11
|
description?: string;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* filename of current demo
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
filename?: string;
|
|
16
16
|
/**
|
|
17
17
|
* use iframe to render demo
|
|
18
18
|
*/
|
|
@@ -79,6 +79,7 @@ export interface IRouteMeta {
|
|
|
79
79
|
tocDepth?: number;
|
|
80
80
|
};
|
|
81
81
|
atomId?: string;
|
|
82
|
+
filename?: string;
|
|
82
83
|
[key: string]: any;
|
|
83
84
|
};
|
|
84
85
|
toc: {
|
|
@@ -148,6 +149,7 @@ export interface IThemeConfig {
|
|
|
148
149
|
children?: INavItem[];
|
|
149
150
|
})[];
|
|
150
151
|
sidebar?: Record<string, ISidebarGroup[]>;
|
|
152
|
+
footer?: string;
|
|
151
153
|
[key: string]: any;
|
|
152
154
|
}
|
|
153
155
|
export declare type IRoutesById = Record<string, {
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import type { IRoutesById } from './types';
|
|
2
2
|
export declare const useLocaleDocRoutes: () => IRoutesById;
|
|
3
|
+
/**
|
|
4
|
+
* 在 react 18 中需要新的 render 方式,这个函数用来处理不同的 jsx 模式。
|
|
5
|
+
* @param version react version
|
|
6
|
+
* @returns code string
|
|
7
|
+
*/
|
|
8
|
+
export declare const genReactRenderCode: (version: string) => string;
|
|
@@ -41,4 +41,19 @@ export var useLocaleDocRoutes = function useLocaleDocRoutes() {
|
|
|
41
41
|
localeDocRoutes = _useState2[0];
|
|
42
42
|
|
|
43
43
|
return localeDocRoutes;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* 在 react 18 中需要新的 render 方式,这个函数用来处理不同的 jsx 模式。
|
|
47
|
+
* @param version react version
|
|
48
|
+
* @returns code string
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
export var genReactRenderCode = function genReactRenderCode(version) {
|
|
52
|
+
var annotation = "/**\n * This is an auto-generated demo by dumi\n * if you think it is not working as expected,\n * please report the issue at\n * https://github.com/umijs/dumi/issues\n */";
|
|
53
|
+
|
|
54
|
+
if (version.startsWith('18.') || version === 'latest') {
|
|
55
|
+
return "".concat(annotation, "\n\nimport React from 'react';\nimport { createRoot } from \"react-dom/client\";\nimport App from \"./App\";\n\nconst rootElement = document.getElementById(\"root\");\nconst root = createRoot(rootElement);\n\nroot.render(<App />);");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return "".concat(annotation, "\n \nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n \nReactDOM.render(\n <App />,\n document.getElementById('root'),\n);");
|
|
44
59
|
};
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const LOCAL_DUMI_DIR = ".dumi";
|
|
2
2
|
export declare const LOCAL_THEME_DIR: string;
|
|
3
|
+
export declare const LOCAL_PAGES_DIR: string;
|
|
3
4
|
export declare const THEME_PREFIX = "dumi-theme-";
|
|
4
5
|
export declare const SP_ROUTE_PREFIX = "~";
|
|
5
6
|
export declare const PICKED_PKG_FIELDS: {
|
package/dist/constants.js
CHANGED
|
@@ -21,6 +21,7 @@ var constants_exports = {};
|
|
|
21
21
|
__export(constants_exports, {
|
|
22
22
|
CLIENT_DEPS: () => CLIENT_DEPS,
|
|
23
23
|
LOCAL_DUMI_DIR: () => LOCAL_DUMI_DIR,
|
|
24
|
+
LOCAL_PAGES_DIR: () => LOCAL_PAGES_DIR,
|
|
24
25
|
LOCAL_THEME_DIR: () => LOCAL_THEME_DIR,
|
|
25
26
|
PICKED_PKG_FIELDS: () => PICKED_PKG_FIELDS,
|
|
26
27
|
SP_ROUTE_PREFIX: () => SP_ROUTE_PREFIX,
|
|
@@ -29,6 +30,7 @@ __export(constants_exports, {
|
|
|
29
30
|
module.exports = __toCommonJS(constants_exports);
|
|
30
31
|
var LOCAL_DUMI_DIR = ".dumi";
|
|
31
32
|
var LOCAL_THEME_DIR = `${LOCAL_DUMI_DIR}/theme`;
|
|
33
|
+
var LOCAL_PAGES_DIR = `${LOCAL_DUMI_DIR}/pages`;
|
|
32
34
|
var THEME_PREFIX = "dumi-theme-";
|
|
33
35
|
var SP_ROUTE_PREFIX = "~";
|
|
34
36
|
var PICKED_PKG_FIELDS = {
|
|
@@ -57,6 +59,7 @@ var CLIENT_DEPS = [
|
|
|
57
59
|
0 && (module.exports = {
|
|
58
60
|
CLIENT_DEPS,
|
|
59
61
|
LOCAL_DUMI_DIR,
|
|
62
|
+
LOCAL_PAGES_DIR,
|
|
60
63
|
LOCAL_THEME_DIR,
|
|
61
64
|
PICKED_PKG_FIELDS,
|
|
62
65
|
SP_ROUTE_PREFIX,
|
|
@@ -30,7 +30,9 @@ var configPlugins_default = (api) => {
|
|
|
30
30
|
atomDirs: [{ type: "component", dir: "src" }],
|
|
31
31
|
codeBlockMode: "active"
|
|
32
32
|
},
|
|
33
|
-
themeConfig: {
|
|
33
|
+
themeConfig: {
|
|
34
|
+
footer: `Copyright \xA9 ${new Date().getFullYear()} | Powered by <a href="https://d.umijs.org" target="_blank" rel="noreferrer">dumi</a>`
|
|
35
|
+
}
|
|
34
36
|
};
|
|
35
37
|
const schemas = (0, import_schema.getSchemas)();
|
|
36
38
|
for (const key of Object.keys(schemas)) {
|
|
@@ -68,6 +68,12 @@ var derivative_default = (api) => {
|
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
if (api.userConfig.conventionRoutes !== false) {
|
|
72
|
+
memo.conventionRoutes = {
|
|
73
|
+
base: import_path.default.join(api.cwd, import_constants.LOCAL_PAGES_DIR),
|
|
74
|
+
exclude: [/(\/|^)(\.|_\/)/]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
71
77
|
memo.hash = true;
|
|
72
78
|
return memo;
|
|
73
79
|
});
|
package/dist/features/routes.js
CHANGED
|
@@ -58,15 +58,8 @@ var routes_default = (api) => {
|
|
|
58
58
|
{ dir: "docs" }
|
|
59
59
|
]
|
|
60
60
|
].map(({ dir }) => import_path.default.join(api.cwd, dir, "**/*.md"));
|
|
61
|
-
const pagesDir = import_path.default.join(api.cwd, ".dumi/pages");
|
|
62
61
|
api.describe({ key: "dumi:routes" });
|
|
63
62
|
api.addTmpGenerateWatcherPaths(() => extraWatchPaths);
|
|
64
|
-
api.modifyConfig((memo) => {
|
|
65
|
-
memo.conventionRoutes = {
|
|
66
|
-
base: pagesDir
|
|
67
|
-
};
|
|
68
|
-
return memo;
|
|
69
|
-
});
|
|
70
63
|
api.modifyDefaultConfig((memo) => {
|
|
71
64
|
if (api.userConfig.resolve) {
|
|
72
65
|
const keys = ["docDirs", "atomDirs"];
|
|
@@ -117,7 +110,7 @@ var routes_default = (api) => {
|
|
|
117
110
|
};
|
|
118
111
|
}
|
|
119
112
|
Object.entries(pages).forEach(([, route]) => {
|
|
120
|
-
route.file = (0, import_plugin_utils.winPath)(import_path.default.resolve(
|
|
113
|
+
route.file = (0, import_plugin_utils.winPath)(import_path.default.resolve(api.config.conventionRoutes.base, route.file));
|
|
121
114
|
flatRoute(route);
|
|
122
115
|
routes[route.id] = route;
|
|
123
116
|
});
|
|
@@ -125,7 +118,7 @@ var routes_default = (api) => {
|
|
|
125
118
|
const base = import_path.default.join(api.cwd, dir);
|
|
126
119
|
const dirRoutes = (0, import_core.getConventionRoutes)({
|
|
127
120
|
base,
|
|
128
|
-
exclude: [/.*(?<!md)
|
|
121
|
+
exclude: [/.*(?<!md)$/, /(\/|^)(\.|_\/)/]
|
|
129
122
|
});
|
|
130
123
|
Object.entries(dirRoutes).forEach(([key, route]) => {
|
|
131
124
|
route.id = `${dir}/${key}`;
|
|
@@ -87,16 +87,24 @@ function DumiMarkdownContent() {
|
|
|
87
87
|
export default DumiMarkdownContent;`;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
function getEmbedsCacheKey(embeds = []) {
|
|
91
|
+
return JSON.stringify(embeds.map((file) => `${file}:${import_fs.default.statSync(file).mtimeMs}`));
|
|
92
|
+
}
|
|
90
93
|
var deferrer = {};
|
|
94
|
+
var embedsMapping = {};
|
|
91
95
|
function mdLoader(content) {
|
|
92
96
|
const opts = this.getOptions();
|
|
93
97
|
const cb = this.async();
|
|
94
98
|
const cache = (0, import_utils.getCache)("md-loader");
|
|
95
|
-
const
|
|
99
|
+
const baseCacheKey = [
|
|
96
100
|
this.resourcePath,
|
|
97
101
|
import_fs.default.statSync(this.resourcePath).mtimeMs,
|
|
98
102
|
JSON.stringify(import_plugin_utils.lodash.omit(opts, ["mode", "builtins", "onResolveDemos"]))
|
|
99
103
|
].join(":");
|
|
104
|
+
const cacheKey = [
|
|
105
|
+
baseCacheKey,
|
|
106
|
+
getEmbedsCacheKey(embedsMapping[this.resourcePath])
|
|
107
|
+
].join(":");
|
|
100
108
|
const cacheRet = cache.getSync(cacheKey, "");
|
|
101
109
|
if (cacheRet) {
|
|
102
110
|
cb(null, emit.call(this, opts, cacheRet));
|
|
@@ -112,7 +120,12 @@ function mdLoader(content) {
|
|
|
112
120
|
fileAbsPath: this.resourcePath
|
|
113
121
|
});
|
|
114
122
|
deferrer[cacheKey].then((ret) => {
|
|
115
|
-
|
|
123
|
+
const finalCacheKey = [
|
|
124
|
+
baseCacheKey,
|
|
125
|
+
getEmbedsCacheKey(ret.meta.embeds)
|
|
126
|
+
].join(":");
|
|
127
|
+
embedsMapping[this.resourcePath] = ret.meta.embeds || [];
|
|
128
|
+
cache.setSync(finalCacheKey, ret);
|
|
116
129
|
cb(null, emit.call(this, opts, ret));
|
|
117
130
|
}).catch(cb);
|
|
118
131
|
}
|
|
@@ -58,7 +58,7 @@ function getCodeLang(node, opts) {
|
|
|
58
58
|
}
|
|
59
59
|
function getCodeId(cwd, fileAbsPath, localId, atomId) {
|
|
60
60
|
const prefix = atomId || (0, import_utils.getRoutePathFromFsPath)(import_path.default.relative(cwd, fileAbsPath)).replace(/\//g, "-");
|
|
61
|
-
return [prefix, "demo", localId].filter(Boolean).join("-");
|
|
61
|
+
return [prefix.toLowerCase(), "demo", localId.toLowerCase()].filter(Boolean).join("-");
|
|
62
62
|
}
|
|
63
63
|
function tryMarkDemoNode(node, opts) {
|
|
64
64
|
var _a, _b;
|
|
@@ -140,13 +140,13 @@ function rehypeDemo(opts) {
|
|
|
140
140
|
let component = "";
|
|
141
141
|
if (codeType === "external") {
|
|
142
142
|
parseOpts.fileAbsPath = codeNode.properties.src;
|
|
143
|
-
parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, import_path.default.parse(parseOpts.fileAbsPath).name);
|
|
143
|
+
parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, import_path.default.parse(parseOpts.fileAbsPath).name, vFile.data.frontmatter.atomId);
|
|
144
144
|
component = `React.lazy(() => import('${(0, import_plugin_utils.winPath)(parseOpts.fileAbsPath)}?techStack=${techStack.name}'))`;
|
|
145
145
|
codeNode.properties.title = codeValue || void 0;
|
|
146
|
-
(_a2 = codeNode.properties).
|
|
146
|
+
(_a2 = codeNode.properties).filename ?? (_a2.filename = (0, import_plugin_utils.winPath)(import_path.default.relative(opts.cwd, parseOpts.fileAbsPath)));
|
|
147
147
|
} else {
|
|
148
148
|
parseOpts.fileAbsPath = opts.fileAbsPath.replace(".md", ".tsx");
|
|
149
|
-
parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, String(index++));
|
|
149
|
+
parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, String(index++), vFile.data.frontmatter.atomId);
|
|
150
150
|
component = techStack.transformCode(codeValue, {
|
|
151
151
|
type: "code-block",
|
|
152
152
|
fileAbsPath: opts.fileAbsPath
|
|
@@ -52,6 +52,8 @@ function remarkMeta(opts) {
|
|
|
52
52
|
const guessAtomId = getGuessAtomId(opts);
|
|
53
53
|
vFile.data.frontmatter = {
|
|
54
54
|
title: "",
|
|
55
|
+
toc: "menu",
|
|
56
|
+
filename: (0, import_plugin_utils.winPath)(import_path.default.relative(opts.cwd, opts.fileAbsPath)),
|
|
55
57
|
...guessAtomId && { atomId: guessAtomId }
|
|
56
58
|
};
|
|
57
59
|
visit(tree, "yaml", (node) => {
|
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.17",
|
|
4
4
|
"description": "Framework for developing UI components",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"dist",
|
|
13
13
|
"compiled",
|
|
14
14
|
"theme-default",
|
|
15
|
-
"theme.d.ts",
|
|
16
15
|
"index.d.ts"
|
|
17
16
|
],
|
|
18
17
|
"scripts": {
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
"@types/mdast": "^3.0.10",
|
|
60
59
|
"@umijs/bundler-utils": "^4.0.27",
|
|
61
60
|
"@umijs/core": "^4.0.27",
|
|
62
|
-
"
|
|
61
|
+
"codesandbox": "^2.2.3",
|
|
63
62
|
"deepmerge": "^4.2.2",
|
|
64
63
|
"dumi-afx-deps": "^1.0.0-alpha.1",
|
|
65
64
|
"dumi-assets-types": "2.0.0-alpha.0",
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useIntl, useOutlet, useRouteMeta } from 'dumi';
|
|
2
2
|
import Content from 'dumi/theme/slots/Content';
|
|
3
3
|
import Features from 'dumi/theme/slots/Features';
|
|
4
|
+
import Footer from 'dumi/theme/slots/Footer';
|
|
4
5
|
import Header from 'dumi/theme/slots/Header';
|
|
5
6
|
import Hero from 'dumi/theme/slots/Hero';
|
|
6
7
|
import Sidebar from 'dumi/theme/slots/Sidebar';
|
|
8
|
+
import Toc from 'dumi/theme/slots/Toc';
|
|
7
9
|
import React from 'react';
|
|
8
10
|
import Helmet from 'react-helmet';
|
|
9
11
|
import "./index.less";
|
|
@@ -34,7 +36,9 @@ var DocLayout = function DocLayout() {
|
|
|
34
36
|
}), fm.keywords && /*#__PURE__*/React.createElement("meta", {
|
|
35
37
|
property: "og:keywords",
|
|
36
38
|
content: fm.keywords.join(',')
|
|
37
|
-
})), /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement(Hero, null), /*#__PURE__*/React.createElement(Features, null), /*#__PURE__*/React.createElement("main", null, /*#__PURE__*/React.createElement(Sidebar, null), /*#__PURE__*/React.createElement(Content, null, outlet))
|
|
39
|
+
})), /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement(Hero, null), /*#__PURE__*/React.createElement(Features, null), /*#__PURE__*/React.createElement("main", null, /*#__PURE__*/React.createElement(Sidebar, null), /*#__PURE__*/React.createElement(Content, null, outlet, /*#__PURE__*/React.createElement(Footer, null)), fm.toc === 'content' && /*#__PURE__*/React.createElement("div", {
|
|
40
|
+
className: "dumi-default-doc-layout-toc-wrapper"
|
|
41
|
+
}, /*#__PURE__*/React.createElement("h4", null, "TABLE OF CONTENTS"), /*#__PURE__*/React.createElement(Toc, null))));
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
export default DocLayout;
|
|
@@ -19,5 +19,23 @@ body {
|
|
|
19
19
|
flex: 1;
|
|
20
20
|
max-width: 100%;
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
> .@{prefix}-doc-layout-toc-wrapper {
|
|
24
|
+
position: sticky;
|
|
25
|
+
top: @s-header-height + 30px;
|
|
26
|
+
width: @s-sidebar-width;
|
|
27
|
+
margin-left: 24px;
|
|
28
|
+
max-height: 80vh;
|
|
29
|
+
overflow: auto;
|
|
30
|
+
overscroll-behavior: contain;
|
|
31
|
+
-webkit-overflow-scrolling: touch;
|
|
32
|
+
|
|
33
|
+
> h4 {
|
|
34
|
+
margin: 0 0 8px;
|
|
35
|
+
color: @c-text-note;
|
|
36
|
+
font-size: 13px;
|
|
37
|
+
line-height: 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
22
40
|
}
|
|
23
41
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"header.search.placeholder": "Type keywords...",
|
|
4
4
|
"previewer.actions.code.expand": "Show Code",
|
|
5
5
|
"previewer.actions.code.shrink": "Hide Code",
|
|
6
|
-
"previewer.actions.codesandbox": "Open in CodeSandbox
|
|
6
|
+
"previewer.actions.codesandbox": "Open in CodeSandbox",
|
|
7
7
|
"previewer.actions.codepen": "Open in CodePen (Not implemented)",
|
|
8
8
|
"previewer.actions.separate": "Open in separate page",
|
|
9
9
|
"404.title": "PAGE NOT FOUND",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"header.search.placeholder": "输入关键字搜索...",
|
|
4
4
|
"previewer.actions.code.expand": "展开代码",
|
|
5
5
|
"previewer.actions.code.shrink": "收起代码",
|
|
6
|
-
"previewer.actions.codesandbox": "在 CodeSandbox
|
|
6
|
+
"previewer.actions.codesandbox": "在 CodeSandbox 中打开",
|
|
7
7
|
"previewer.actions.codepen": "在 CodePen 中打开(未实现)",
|
|
8
8
|
"previewer.actions.separate": "在独立页面中打开",
|
|
9
9
|
"404.title": "页面未找到",
|
|
@@ -45,13 +45,19 @@
|
|
|
45
45
|
|
|
46
46
|
.@{prefix}-content {
|
|
47
47
|
flex: 1;
|
|
48
|
+
min-width: 0;
|
|
48
49
|
max-width: 100%;
|
|
50
|
+
box-sizing: border-box;
|
|
49
51
|
|
|
50
52
|
&:not([data-no-sidebar]) {
|
|
51
|
-
padding: @s-content-padding;
|
|
53
|
+
padding: @s-content-padding @s-content-padding 0;
|
|
52
54
|
background-color: #fff;
|
|
53
55
|
border-top-left-radius: 10px;
|
|
54
56
|
border-top-right-radius: 10px;
|
|
55
57
|
box-shadow: 0 8px 24px 0 rgb(0 0 0 / 5%);
|
|
56
58
|
}
|
|
59
|
+
|
|
60
|
+
.@{prefix}-header + main > & {
|
|
61
|
+
min-height: calc(100vh - @s-header-height);
|
|
62
|
+
}
|
|
57
63
|
}
|
|
@@ -11,7 +11,7 @@ var Features = function Features() {
|
|
|
11
11
|
return Boolean((_frontmatter$features = frontmatter.features) === null || _frontmatter$features === void 0 ? void 0 : _frontmatter$features.length) ? /*#__PURE__*/React.createElement("div", {
|
|
12
12
|
className: "dumi-default-features" // auto render 2 or 3 cols by feature count
|
|
13
13
|
,
|
|
14
|
-
"data-cols": [
|
|
14
|
+
"data-cols": [3, 2].find(function (n) {
|
|
15
15
|
return frontmatter.features.length % n === 0;
|
|
16
16
|
}) || 3
|
|
17
17
|
}, frontmatter.features.map(function (_ref) {
|
|
@@ -21,7 +21,11 @@ var Features = function Features() {
|
|
|
21
21
|
return /*#__PURE__*/React.createElement("div", {
|
|
22
22
|
key: title,
|
|
23
23
|
className: "dumi-default-features-item"
|
|
24
|
-
}, emoji && /*#__PURE__*/React.createElement("i", null, emoji), title && /*#__PURE__*/React.createElement("h3", null, title), description && /*#__PURE__*/React.createElement("p",
|
|
24
|
+
}, emoji && /*#__PURE__*/React.createElement("i", null, emoji), title && /*#__PURE__*/React.createElement("h3", null, title), description && /*#__PURE__*/React.createElement("p", {
|
|
25
|
+
dangerouslySetInnerHTML: {
|
|
26
|
+
__html: description
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
25
29
|
})) : null;
|
|
26
30
|
};
|
|
27
31
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
margin: 4px 0;
|
|
37
37
|
color: #2c4262;
|
|
38
38
|
font-weight: normal;
|
|
39
|
-
font-size:
|
|
39
|
+
font-size: 20px;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
> p {
|
|
@@ -44,6 +44,14 @@
|
|
|
44
44
|
color: #61728a;
|
|
45
45
|
font-size: 16px;
|
|
46
46
|
line-height: 1.475;
|
|
47
|
+
|
|
48
|
+
a {
|
|
49
|
+
color: @c-primary;
|
|
50
|
+
|
|
51
|
+
&:not(:hover) {
|
|
52
|
+
text-decoration: none;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
57
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useSiteData } from 'dumi';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import "./index.less";
|
|
4
|
+
|
|
5
|
+
var Footer = function Footer() {
|
|
6
|
+
var _useSiteData = useSiteData(),
|
|
7
|
+
themeConfig = _useSiteData.themeConfig;
|
|
8
|
+
|
|
9
|
+
if (!themeConfig.footer) return null;
|
|
10
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
11
|
+
className: "dumi-default-footer",
|
|
12
|
+
dangerouslySetInnerHTML: {
|
|
13
|
+
__html: themeConfig.footer
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default Footer;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@import (reference) '../../styles/variables.less';
|
|
2
|
+
|
|
3
|
+
.@{prefix}-footer {
|
|
4
|
+
margin-top: @s-content-padding;
|
|
5
|
+
border-top: 1px solid @c-border-light;
|
|
6
|
+
color: @c-text-note;
|
|
7
|
+
font-size: 15px;
|
|
8
|
+
line-height: 26px;
|
|
9
|
+
text-align: center;
|
|
10
|
+
padding: @s-content-padding * 0.6 0;
|
|
11
|
+
|
|
12
|
+
a {
|
|
13
|
+
color: @c-primary;
|
|
14
|
+
|
|
15
|
+
&:not(:hover) {
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
text-align: center;
|
|
10
10
|
box-sizing: border-box;
|
|
11
11
|
|
|
12
|
+
+ * {
|
|
13
|
+
position: relative;
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
&::before {
|
|
13
17
|
content: '';
|
|
14
18
|
position: absolute;
|
|
@@ -26,7 +30,7 @@
|
|
|
26
30
|
> p {
|
|
27
31
|
margin: 32px;
|
|
28
32
|
color: #4e6789;
|
|
29
|
-
font-size:
|
|
33
|
+
font-size: 20px;
|
|
30
34
|
line-height: 1.6;
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -37,12 +41,12 @@
|
|
|
37
41
|
|
|
38
42
|
> a {
|
|
39
43
|
display: inline-block;
|
|
40
|
-
height:
|
|
41
|
-
font-size:
|
|
42
|
-
line-height:
|
|
44
|
+
height: 52px;
|
|
45
|
+
font-size: 18px;
|
|
46
|
+
line-height: 52px;
|
|
43
47
|
text-decoration: none;
|
|
44
48
|
min-width: 168px;
|
|
45
|
-
border-radius:
|
|
49
|
+
border-radius: 26px;
|
|
46
50
|
box-sizing: border-box;
|
|
47
51
|
transition: opacity 0.2s;
|
|
48
52
|
|
|
@@ -12,7 +12,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
12
12
|
|
|
13
13
|
import { ReactComponent as IconCodeSandbox } from '@ant-design/icons-svg/inline-svg/outlined/code-sandbox.svg';
|
|
14
14
|
import { ReactComponent as IconCodePen } from '@ant-design/icons-svg/inline-svg/outlined/codepen.svg';
|
|
15
|
-
import { useIntl } from 'dumi';
|
|
15
|
+
import { openCodeSandbox, useIntl } from 'dumi';
|
|
16
16
|
import SourceCode from 'dumi/theme/builtins/SourceCode';
|
|
17
17
|
import PreviewerActionsExtra from 'dumi/theme/slots/PreviewerActionsExtra';
|
|
18
18
|
import Tabs from 'rc-tabs';
|
|
@@ -75,7 +75,10 @@ var PreviewerActions = function PreviewerActions(props) {
|
|
|
75
75
|
type: "button",
|
|
76
76
|
"data-dumi-tooltip": intl.formatMessage({
|
|
77
77
|
id: 'previewer.actions.codesandbox'
|
|
78
|
-
})
|
|
78
|
+
}),
|
|
79
|
+
onClick: function onClick() {
|
|
80
|
+
return openCodeSandbox(props);
|
|
81
|
+
}
|
|
79
82
|
}, /*#__PURE__*/React.createElement(IconCodeSandbox, null)), !((_props$disabledAction2 = props.disabledActions) !== null && _props$disabledAction2 !== void 0 && _props$disabledAction2.includes('CODEPEN')) && /*#__PURE__*/React.createElement("button", {
|
|
80
83
|
className: "dumi-default-previewer-action-btn",
|
|
81
84
|
type: "button",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NavLink, useLocation, useSidebarData } from 'dumi';
|
|
1
|
+
import { NavLink, useLocation, useRouteMeta, useSidebarData } from 'dumi';
|
|
2
2
|
import Toc from 'dumi/theme/slots/Toc';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import "./index.less";
|
|
@@ -7,6 +7,7 @@ var Sidebar = function Sidebar() {
|
|
|
7
7
|
var _useLocation = useLocation(),
|
|
8
8
|
pathname = _useLocation.pathname;
|
|
9
9
|
|
|
10
|
+
var meta = useRouteMeta();
|
|
10
11
|
var sidebar = useSidebarData();
|
|
11
12
|
return sidebar && /*#__PURE__*/React.createElement("div", {
|
|
12
13
|
className: "dumi-default-sidebar"
|
|
@@ -21,7 +22,7 @@ var Sidebar = function Sidebar() {
|
|
|
21
22
|
to: child.link,
|
|
22
23
|
title: child.title,
|
|
23
24
|
end: true
|
|
24
|
-
}, child.title), child.link === pathname && /*#__PURE__*/React.createElement(Toc, null));
|
|
25
|
+
}, child.title), child.link === pathname && meta.frontmatter.toc === 'menu' && /*#__PURE__*/React.createElement(Toc, null));
|
|
25
26
|
}));
|
|
26
27
|
}));
|
|
27
28
|
};
|
package/theme.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './dist/client/theme-api';
|