dumi 2.2.0-alpha.2 → 2.2.0-rc.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.
Files changed (38) hide show
  1. package/README.md +2 -6
  2. package/compiled/_internal/searchWorker.min.js +1 -1
  3. package/compiled/crates/swc_plugin_react_demo.wasm +0 -0
  4. package/dist/assetParsers/atom.d.ts +2 -0
  5. package/dist/assetParsers/atom.js +19 -12
  6. package/dist/client/theme-api/DumiDemoGrid.js +2 -1
  7. package/dist/client/theme-api/DumiPage.js +2 -0
  8. package/dist/client/theme-api/types.d.ts +4 -1
  9. package/dist/client/theme-api/useNavData.js +77 -15
  10. package/dist/client/theme-api/useSidebarData.js +31 -7
  11. package/dist/client/theme-api/useSiteSearch/index.d.ts +1 -0
  12. package/dist/client/theme-api/utils.d.ts +3 -3
  13. package/dist/client/theme-api/utils.js +1 -1
  14. package/dist/features/autoAlias.js +20 -23
  15. package/dist/features/configPlugins/index.js +2 -1
  16. package/dist/features/configPlugins/schema.js +0 -1
  17. package/dist/features/derivative.js +0 -1
  18. package/dist/features/locales.js +2 -1
  19. package/dist/features/routes.js +25 -12
  20. package/dist/features/theme/index.js +77 -4
  21. package/dist/loaders/markdown/transformer/rehypeDemo.js +35 -9
  22. package/dist/loaders/markdown/transformer/rehypeEnhancedTag.js +1 -0
  23. package/dist/types.d.ts +2 -8
  24. package/dist/utils.d.ts +0 -4
  25. package/dist/utils.js +0 -14
  26. package/package.json +8 -3
  27. package/theme-default/builtins/API/index.js +1 -1
  28. package/theme-default/builtins/SourceCode/index.js +27 -13
  29. package/theme-default/builtins/SourceCode/index.less +53 -3
  30. package/theme-default/builtins/Tree/index.d.ts +4 -0
  31. package/theme-default/builtins/Tree/index.js +206 -0
  32. package/theme-default/builtins/Tree/index.less +186 -0
  33. package/theme-default/slots/ColorSwitch/index.less +4 -2
  34. package/theme-default/slots/Navbar/index.js +80 -13
  35. package/theme-default/slots/Navbar/index.less +128 -4
  36. package/theme-default/slots/RtlSwitch/index.less +2 -1
  37. package/theme-default/slots/SocialIcon/index.less +2 -1
  38. package/theme-default/slots/Toc/index.js +8 -2
@@ -26,13 +26,15 @@ __export(routes_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(routes_exports);
28
28
  var import_constants = require("../constants");
29
- var import_utils = require("../utils");
30
29
  var import_core = require("@umijs/core");
31
- var import_utils2 = require("@umijs/core/dist/route/utils");
30
+ var import_utils = require("@umijs/core/dist/route/utils");
32
31
  var import_path = __toESM(require("path"));
33
32
  var import_pluralize = require("pluralize");
34
33
  var import_plugin_utils = require("umi/plugin-utils");
35
34
  var CTX_LAYOUT_ID = "dumi-context-layout";
35
+ var ALIAS_THEME_TMP = "@/dumi__theme";
36
+ var ALIAS_LAYOUTS_LOCAL = "@/dumi__theme__layouts";
37
+ var ALIAS_INTERNAL_PAGES = "@/dumi__pages";
36
38
  function normalizeDocDir(docDir) {
37
39
  return typeof docDir === "object" ? docDir : { dir: docDir };
38
40
  }
@@ -62,6 +64,13 @@ function flatRoute(route, docLayoutId) {
62
64
  route.path = route.path === "*" ? route.path : route.absPath.slice(1);
63
65
  }
64
66
  }
67
+ function getAliasLayoutFile({
68
+ source,
69
+ specifier
70
+ }) {
71
+ const alias = source.includes("/.dumi/theme/layouts/") ? ALIAS_LAYOUTS_LOCAL : `${ALIAS_THEME_TMP}/layouts`;
72
+ return `${alias}/${specifier}`;
73
+ }
65
74
  var routes_default = (api) => {
66
75
  var _a, _b, _c;
67
76
  const extraWatchPaths = [
@@ -81,6 +90,9 @@ var routes_default = (api) => {
81
90
  memo.resolve[key] = [];
82
91
  });
83
92
  }
93
+ memo.alias[ALIAS_THEME_TMP] = (0, import_plugin_utils.winPath)(import_path.default.join(api.paths.absTmpPath, "dumi/theme"));
94
+ memo.alias[ALIAS_LAYOUTS_LOCAL] = (0, import_plugin_utils.winPath)(import_path.default.join(api.cwd, import_constants.LOCAL_THEME_DIR, "layouts"));
95
+ memo.alias[ALIAS_INTERNAL_PAGES] = (0, import_plugin_utils.winPath)(import_path.default.join(__dirname, "../client/pages"));
84
96
  return memo;
85
97
  });
86
98
  api.modifyRoutes((oRoutes) => {
@@ -104,7 +116,7 @@ var routes_default = (api) => {
104
116
  routes[DocLayout.specifier] = {
105
117
  id: DocLayout.specifier,
106
118
  path: "/",
107
- file: DocLayout.source,
119
+ file: getAliasLayoutFile(DocLayout),
108
120
  parentId: lastLayoutId,
109
121
  absPath: "/",
110
122
  isLayout: true
@@ -115,14 +127,15 @@ var routes_default = (api) => {
115
127
  routes[DemoLayout.specifier] = {
116
128
  id: DemoLayout.specifier,
117
129
  path: "/",
118
- file: DemoLayout.source,
130
+ file: getAliasLayoutFile(DemoLayout),
119
131
  parentId: lastLayoutId,
120
132
  absPath: "/",
121
133
  isLayout: true
122
134
  };
123
135
  }
124
136
  Object.entries(pages).forEach(([, route]) => {
125
- route.file = (0, import_plugin_utils.winPath)(import_path.default.resolve(api.config.conventionRoutes.base, route.file));
137
+ const { base } = api.config.conventionRoutes;
138
+ route.file = (0, import_plugin_utils.winPath)(import_path.default.resolve(base, route.file));
126
139
  routes[route.id] = route;
127
140
  });
128
141
  docDirs.map(normalizeDocDir).forEach(({ type, dir }) => {
@@ -142,13 +155,13 @@ var routes_default = (api) => {
142
155
  routes[route.id] = route;
143
156
  });
144
157
  });
145
- atomDirs.forEach(({ type, dir }) => {
158
+ atomDirs.forEach(({ type, subType = "", dir }) => {
146
159
  const base = import_path.default.join(api.cwd, dir);
147
160
  const atomFiles = import_plugin_utils.glob.sync("{*,*/index,*/index.*,*/README,*/README.*}.md", { cwd: base });
148
161
  atomFiles.forEach((file) => {
149
- const routeFile = (0, import_plugin_utils.winPath)(import_path.default.join((0, import_pluralize.plural)(type), file));
162
+ const routeFile = (0, import_plugin_utils.winPath)(import_path.default.join((0, import_pluralize.plural)(type), subType, file));
150
163
  const routePath = routeFile.replace(/(\/index|\/README)?\.md$/, "").replace(/\./g, "/");
151
- const routeId = (0, import_utils2.createRouteId)(routeFile);
164
+ const routeId = (0, import_utils.createRouteId)(routeFile);
152
165
  routes[routeId] = {
153
166
  id: routeId,
154
167
  path: routePath,
@@ -173,7 +186,7 @@ var routes_default = (api) => {
173
186
  path: "*",
174
187
  absPath: "/*",
175
188
  parentId: docLayoutId,
176
- file: (0, import_utils.getClientDistFile)("dist/client/pages/404", api.cwd)
189
+ file: `${ALIAS_INTERNAL_PAGES}/404`
177
190
  };
178
191
  }
179
192
  routes["demo-render"] = {
@@ -181,7 +194,7 @@ var routes_default = (api) => {
181
194
  path: `${import_constants.SP_ROUTE_PREFIX}demos/:id`,
182
195
  absPath: `/${import_constants.SP_ROUTE_PREFIX}demos/:id`,
183
196
  parentId: demoLayoutId,
184
- file: (0, import_utils.getClientDistFile)("dist/client/pages/Demo", api.cwd)
197
+ file: `${ALIAS_INTERNAL_PAGES}/Demo`
185
198
  };
186
199
  return routes;
187
200
  });
@@ -189,14 +202,14 @@ var routes_default = (api) => {
189
202
  const layouts = [
190
203
  {
191
204
  id: CTX_LAYOUT_ID,
192
- file: `${api.paths.absTmpPath}/dumi/theme/ContextWrapper.tsx`
205
+ file: `${ALIAS_THEME_TMP}/ContextWrapper`
193
206
  }
194
207
  ];
195
208
  const { GlobalLayout } = api.service.themeData.layouts;
196
209
  if (GlobalLayout) {
197
210
  layouts.unshift({
198
211
  id: GlobalLayout.specifier,
199
- file: GlobalLayout.source
212
+ file: getAliasLayoutFile(GlobalLayout)
200
213
  });
201
214
  }
202
215
  return layouts;
@@ -26,13 +26,13 @@ __export(theme_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(theme_exports);
28
28
  var import_constants = require("../../constants");
29
- var import_utils = require("../../utils");
30
29
  var import_bundler_utils = require("@umijs/bundler-utils");
31
30
  var import_fs = __toESM(require("fs"));
32
31
  var import_path = __toESM(require("path"));
33
32
  var import_plugin_utils = require("umi/plugin-utils");
34
33
  var import_derivative = require("../derivative");
35
34
  var import_loader = __toESM(require("./loader"));
35
+ var DEFAULT_THEME_PATH = import_path.default.join(__dirname, "../../../theme-default");
36
36
  function getPkgThemeName(api) {
37
37
  const validDeps = Object.assign({}, api.pkg.dependencies, api.pkg.devDependencies);
38
38
  const pkgThemeName = Object.keys(validDeps).find((pkg) => pkg.split("/").pop().startsWith(import_constants.THEME_PREFIX));
@@ -40,7 +40,7 @@ function getPkgThemeName(api) {
40
40
  }
41
41
  function getPkgThemePath(api) {
42
42
  const pkgThemeName = getPkgThemeName(api);
43
- return process.env.DUMI_THEME || pkgThemeName && import_path.default.dirname(import_plugin_utils.resolve.sync(`${pkgThemeName}/package.json`, {
43
+ return pkgThemeName && import_path.default.dirname(import_plugin_utils.resolve.sync(`${pkgThemeName}/package.json`, {
44
44
  basedir: api.cwd,
45
45
  preserveSymlinks: true
46
46
  }));
@@ -52,7 +52,6 @@ function getModuleExports(modulePath) {
52
52
  })[1];
53
53
  }
54
54
  var theme_default = (api) => {
55
- const DEFAULT_THEME_PATH = import_path.default.join((0, import_utils.getClientDistFile)("package.json", api.cwd), "../theme-default");
56
55
  const defaultThemeData = (0, import_loader.default)(DEFAULT_THEME_PATH);
57
56
  const pkgThemePath = getPkgThemePath(api);
58
57
  const pkgThemeData = (0, import_plugin_utils.deepmerge)(defaultThemeData, pkgThemePath ? (0, import_loader.default)(import_path.default.join(pkgThemePath, "dist")) : {});
@@ -138,7 +137,7 @@ var theme_default = (api) => {
138
137
  return memo;
139
138
  });
140
139
  api.onGenerateFiles(() => {
141
- var _a;
140
+ var _a, _b, _c, _d;
142
141
  themeMapKeys.forEach((key) => {
143
142
  Object.values(originalThemeData[key] || {}).forEach((item) => {
144
143
  if (item.source === "dumi")
@@ -162,11 +161,16 @@ var theme_default = (api) => {
162
161
  const entryExports = entryFile ? getModuleExports(entryFile) : [];
163
162
  const hasDefaultExport = entryExports.includes("default");
164
163
  const hasNamedExport = entryExports.some((exp) => exp !== "default");
164
+ const enableNProgress = !!api.config.themeConfig.nprogress;
165
165
  api.writeTmpFile({
166
166
  noPluginDir: true,
167
167
  path: "dumi/theme/ContextWrapper.tsx",
168
168
  content: `import React, { useState, useEffect, useRef } from 'react';
169
169
  import { useOutlet, history } from 'dumi';
170
+ ${enableNProgress ? `
171
+ import nprogress from '${(0, import_plugin_utils.winPath)(import_path.default.dirname(require.resolve("nprogress/package")))}';
172
+ import './nprogress.css';
173
+ ` : ""}
170
174
  import { SiteContext } from '${(0, import_plugin_utils.winPath)(require.resolve("../../client/theme-api/context"))}';
171
175
  import { demos, components } from '../meta';
172
176
  import { locales } from '../locales/config';${hasDefaultExport ? `
@@ -191,6 +195,9 @@ export default function DumiContextWrapper() {
191
195
  // mark loading when route change, page component will set false when loaded
192
196
  setLoading(true);
193
197
 
198
+ // start nprogress
199
+ ${enableNProgress ? `nprogress.start();` : ""}
200
+
194
201
  // scroll to top when route changed
195
202
  document.documentElement.scrollTo(0, 0);
196
203
  }
@@ -214,6 +221,72 @@ export default function DumiContextWrapper() {
214
221
  );
215
222
  }`
216
223
  });
224
+ const primaryColor = typeof ((_b = api.config) == null ? void 0 : _b.theme) === "object" ? (_d = (_c = api.config) == null ? void 0 : _c.theme) == null ? void 0 : _d["@c-primary"] : "#1677ff";
225
+ api.writeTmpFile({
226
+ noPluginDir: true,
227
+ path: "dumi/theme/nprogress.css",
228
+ content: `
229
+ /* https://unpkg.com/browse/nprogress@0.2.0/nprogress.css */
230
+ #nprogress {
231
+ pointer-events: none;
232
+ }
233
+
234
+ #nprogress .bar {
235
+ background: var;
236
+ position: fixed;
237
+ z-index: 1031;
238
+ top: 0;
239
+ left: 0;
240
+ width: 100%;
241
+ height: 2px;
242
+ }
243
+
244
+ #nprogress .peg {
245
+ display: block;
246
+ position: absolute;
247
+ right: 0px;
248
+ width: 100px;
249
+ height: 100%;
250
+ box-shadow: 0 0 10px ${primaryColor}, 0 0 5px ${primaryColor};
251
+ opacity: 1.0;
252
+ transform: rotate(3deg) translate(0px, -4px);
253
+ }
254
+
255
+ #nprogress .spinner {
256
+ display: block;
257
+ position: fixed;
258
+ z-index: 1031;
259
+ top: 15px;
260
+ right: 15px;
261
+ }
262
+
263
+ #nprogress .spinner-icon {
264
+ width: 18px;
265
+ height: 18px;
266
+ box-sizing: border-box;
267
+ border: solid 2px transparent;
268
+ border-top-color: ${primaryColor};
269
+ border-left-color: ${primaryColor};
270
+ border-radius: 50%;
271
+ animation: nprogress-spinner 400ms linear infinite;
272
+ }
273
+
274
+ .nprogress-custom-parent {
275
+ overflow: hidden;
276
+ position: relative;
277
+ }
278
+
279
+ .nprogress-custom-parent #nprogress .spinner,
280
+ .nprogress-custom-parent #nprogress .bar {
281
+ position: absolute;
282
+ }
283
+
284
+ @keyframes nprogress-spinner {
285
+ 0% { transform: rotate(0deg); }
286
+ 100% { transform: rotate(360deg); }
287
+ }
288
+ `
289
+ });
217
290
  });
218
291
  api.addEntryCodeAhead(() => {
219
292
  const { prefersColor } = api.config.themeConfig;
@@ -34,6 +34,7 @@ var import_path = __toESM(require("path"));
34
34
  var import_plugin_utils = require("umi/plugin-utils");
35
35
  var visit;
36
36
  var SKIP;
37
+ var EXIT;
37
38
  var toString;
38
39
  var isElement;
39
40
  var DEMO_NODE_CONTAINER = "$demo-container";
@@ -41,7 +42,7 @@ var DEMO_PROP_VALUE_KEY = "$demo-prop-value-key";
41
42
  var DUMI_DEMO_TAG = "DumiDemo";
42
43
  var DUMI_DEMO_GRID_TAG = "DumiDemoGrid";
43
44
  (async () => {
44
- ({ visit, SKIP } = await import("unist-util-visit"));
45
+ ({ visit, SKIP, EXIT } = await import("unist-util-visit"));
45
46
  ({ toString } = await import("hast-util-to-string"));
46
47
  ({ isElement } = await import("hast-util-is-element"));
47
48
  })();
@@ -125,13 +126,35 @@ function rehypeDemo(opts) {
125
126
  }
126
127
  }
127
128
  });
129
+ let hasOnlySign = false;
130
+ let hasSkipSign = false;
128
131
  visit(tree, "element", (node) => {
129
132
  var _a;
133
+ if (isElement(node, "p") && ((_a = node.data) == null ? void 0 : _a[DEMO_NODE_CONTAINER])) {
134
+ for (const codeNode of node.children) {
135
+ if (isElement(codeNode, "code")) {
136
+ hasSkipSign || (hasSkipSign = "skip" in codeNode.properties);
137
+ if ("only" in codeNode.properties) {
138
+ hasOnlySign = true;
139
+ return EXIT;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ });
145
+ if (process.env.NODE_ENV === "production" && (hasOnlySign || hasSkipSign)) {
146
+ import_plugin_utils.logger.warn(`The 'only' or 'skip' mark is not supported in production environment, please remove it. at ${vFile.data.frontmatter.filename}`);
147
+ }
148
+ visit(tree, "element", (node) => {
149
+ var _a, _b, _c;
130
150
  if (isElement(node, "p") && ((_a = node.data) == null ? void 0 : _a[DEMO_NODE_CONTAINER])) {
131
151
  const demosPropData = [];
132
- node.children.forEach((codeNode) => {
133
- var _a2, _b;
152
+ for (const codeNode of node.children) {
134
153
  if (isElement(codeNode, "code")) {
154
+ const shouldSkipNonOnlyDemos = hasOnlySign && !("only" in codeNode.properties);
155
+ if (process.env.NODE_ENV !== "production" && ("skip" in codeNode.properties || shouldSkipNonOnlyDemos)) {
156
+ continue;
157
+ }
135
158
  const codeType = codeNode.data.type;
136
159
  const techStack = codeNode.data.techStack;
137
160
  const codeValue = toString(codeNode).trim();
@@ -147,12 +170,12 @@ function rehypeDemo(opts) {
147
170
  if (codeType === "external") {
148
171
  const chunkName = [vFile.data.frontmatter.atomId, "demos"].filter(Boolean).join("__");
149
172
  parseOpts.fileAbsPath = (0, import_plugin_utils.winPath)(codeNode.properties.src);
150
- let localId = ((_a2 = codeNode.properties) == null ? void 0 : _a2.id) ?? import_path.default.parse(parseOpts.fileAbsPath.replace(/\/index\.(j|t)sx?$/, "")).name;
173
+ let localId = ((_b = codeNode.properties) == null ? void 0 : _b.id) ?? import_path.default.parse(parseOpts.fileAbsPath.replace(/\/index\.(j|t)sx?$/, "")).name;
151
174
  parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, localId, vFile.data.frontmatter.atomId);
152
175
  component = `React.lazy(() => import( /* webpackChunkName: "${chunkName}" */ '${(0, import_plugin_utils.winPath)(parseOpts.fileAbsPath)}?techStack=${techStack.name}'))`;
153
176
  if (codeValue)
154
177
  codeNode.properties.title = codeValue;
155
- (_b = codeNode.properties).filename ?? (_b.filename = (0, import_plugin_utils.winPath)(import_path.default.relative(opts.cwd, parseOpts.fileAbsPath)));
178
+ (_c = codeNode.properties).filename ?? (_c.filename = (0, import_plugin_utils.winPath)(import_path.default.relative(opts.cwd, parseOpts.fileAbsPath)));
156
179
  } else {
157
180
  parseOpts.fileAbsPath = opts.fileAbsPath.replace(".md", ".tsx");
158
181
  parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, String(index++), vFile.data.frontmatter.atomId);
@@ -164,9 +187,9 @@ function rehypeDemo(opts) {
164
187
  const propDemo = { id: parseOpts.id };
165
188
  demoIds.push(parseOpts.id);
166
189
  deferrers.push((0, import_block.default)(parseOpts).then(async ({ asset, sources, frontmatter }) => {
167
- var _a3, _b2, _c;
190
+ var _a2, _b2, _c2;
168
191
  if (demoIds.indexOf(parseOpts.id) !== demoIds.lastIndexOf(parseOpts.id)) {
169
- const startLine = (_a3 = node.position) == null ? void 0 : _a3.start.line;
192
+ const startLine = (_a2 = node.position) == null ? void 0 : _a2.start.line;
170
193
  const suffix = startLine ? `:${startLine}` : "";
171
194
  import_plugin_utils.logger.warn(`Duplicate demo id found due to filename conflicts, please consider adding a unique id to code tag to resolve this.
172
195
  at ${opts.fileAbsPath}${suffix}`);
@@ -199,7 +222,7 @@ function rehypeDemo(opts) {
199
222
  component
200
223
  };
201
224
  }
202
- Object.assign(previewerProps, await ((_c = techStack.generatePreviewerProps) == null ? void 0 : _c.call(techStack, originalProps, techStackOpts)) || originalProps);
225
+ Object.assign(previewerProps, await ((_c2 = techStack.generatePreviewerProps) == null ? void 0 : _c2.call(techStack, originalProps, techStackOpts)) || originalProps);
203
226
  if (previewerProps.description) {
204
227
  const { unified } = await import("unified");
205
228
  const { default: remarkParse } = await import("remark-parse");
@@ -224,8 +247,11 @@ function rehypeDemo(opts) {
224
247
  demo: propDemo,
225
248
  previewerProps
226
249
  });
250
+ if (process.env.NODE_ENV !== "production" && "only" in codeNode.properties) {
251
+ break;
252
+ }
227
253
  }
228
- });
254
+ }
229
255
  replaceNodes.push(node);
230
256
  node.children = [];
231
257
  if (demosPropData.length === 1) {
@@ -45,6 +45,7 @@ function rehypeEnhancedTag() {
45
45
  type: "element",
46
46
  tagName: "SourceCode",
47
47
  properties: { lang },
48
+ data: node.children[0].data,
48
49
  JSXAttributes: [
49
50
  {
50
51
  type: "JSXAttribute",
package/dist/types.d.ts CHANGED
@@ -9,7 +9,7 @@ import type { AssetsPackage, ExampleBlockAsset } from 'dumi-assets-types';
9
9
  import type { Element } from 'hast';
10
10
  import type { defineConfig as defineUmiConfig, IApi as IUmiApi } from 'umi';
11
11
  declare type Subset<K> = {
12
- [attr in keyof K]?: K[attr] extends Array<any> ? K[attr] : K[attr] extends object ? Subset<K[attr]> : K[attr] extends object | null ? Subset<K[attr]> | null : K[attr] extends object | null | undefined ? Subset<K[attr]> | null | undefined : K[attr];
12
+ [attr in keyof K]?: K[attr] extends Array<any> ? K[attr] : K[attr] extends Function | undefined ? K[attr] : K[attr] extends object ? Subset<K[attr]> : K[attr] extends object | null ? Subset<K[attr]> | null : K[attr] extends object | null | undefined ? Subset<K[attr]> | null | undefined : K[attr];
13
13
  };
14
14
  declare type NoStringIndex<T> = {
15
15
  [K in keyof T as string extends K ? never : K]: T[K];
@@ -21,15 +21,9 @@ interface IDumiExtendsConfig {
21
21
  type?: string;
22
22
  dir: string;
23
23
  })[];
24
- /**
25
- * @deprecated use `resolve.atomDirs` instead
26
- */
27
- entityDirs?: {
28
- type: string;
29
- dir: string;
30
- }[];
31
24
  atomDirs: {
32
25
  type: string;
26
+ subType?: string;
33
27
  dir: string;
34
28
  }[];
35
29
  codeBlockMode: 'active' | 'passive';
package/dist/utils.d.ts CHANGED
@@ -34,8 +34,4 @@ export declare function tryFatherBuildConfigs(cwd: string): Promise<any[]>;
34
34
  * get root dir for monorepo project
35
35
  */
36
36
  export declare function getProjectRoot(cwd: string): string;
37
- /**
38
- * get dumi client dist file and preserve symlink(pnpm, tnpm & etc.) to make chunk name clean
39
- */
40
- export declare function getClientDistFile(file: string, cwd: string): string;
41
37
  export {};
package/dist/utils.js CHANGED
@@ -23,7 +23,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
23
23
  var utils_exports = {};
24
24
  __export(utils_exports, {
25
25
  getCache: () => getCache,
26
- getClientDistFile: () => getClientDistFile,
27
26
  getFileContentByRegExp: () => getFileContentByRegExp,
28
27
  getFileRangeLines: () => getFileRangeLines,
29
28
  getProjectRoot: () => getProjectRoot,
@@ -118,22 +117,9 @@ function getProjectRoot(cwd) {
118
117
  }
119
118
  return (0, import_plugin_utils.winPath)(cwd);
120
119
  }
121
- function getClientDistFile(file, cwd) {
122
- let clientFile;
123
- try {
124
- clientFile = import_plugin_utils.resolve.sync(`dumi/${file}`, {
125
- basedir: cwd,
126
- preserveSymlinks: true
127
- });
128
- } catch {
129
- clientFile = require.resolve(`../${file}`);
130
- }
131
- return (0, import_plugin_utils.winPath)(clientFile);
132
- }
133
120
  // Annotate the CommonJS export names for ESM import in node:
134
121
  0 && (module.exports = {
135
122
  getCache,
136
- getClientDistFile,
137
123
  getFileContentByRegExp,
138
124
  getFileRangeLines,
139
125
  getProjectRoot,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.2.0-alpha.2",
3
+ "version": "2.2.0-rc.0",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -79,9 +79,10 @@
79
79
  "@ant-design/icons-svg": "^4.2.1",
80
80
  "@makotot/ghostui": "^2.0.0",
81
81
  "@stackblitz/sdk": "^1.8.1",
82
- "@swc/core": "1.3.44",
82
+ "@swc/core": "1.3.57",
83
83
  "@types/hast": "^2.3.4",
84
84
  "@types/mdast": "^3.0.10",
85
+ "@types/nprogress": "^0.2.0",
85
86
  "@umijs/bundler-utils": "^4.0.64",
86
87
  "@umijs/core": "^4.0.64",
87
88
  "animated-scroll-to": "^2.3.0",
@@ -106,12 +107,15 @@
106
107
  "js-yaml": "^4.1.0",
107
108
  "lodash.throttle": "^4.1.1",
108
109
  "mdast-util-to-string": "^3.1.0",
110
+ "nprogress": "^0.2.0",
109
111
  "pluralize": "^8.0.0",
110
112
  "prism-react-renderer": "^1.3.5",
111
113
  "prism-themes": "^1.9.0",
112
114
  "prismjs": "^1.29.0",
113
115
  "raw-loader": "^4.0.2",
116
+ "rc-motion": "^2.7.3",
114
117
  "rc-tabs": "^12.5.6",
118
+ "rc-tree": "^5.7.3",
115
119
  "react-copy-to-clipboard": "^5.1.0",
116
120
  "react-error-boundary": "^3.1.4",
117
121
  "react-intl": "^6.1.1",
@@ -149,6 +153,7 @@
149
153
  "@umijs/plugins": "4.0.32",
150
154
  "dumi-theme-mobile": "workspace:*",
151
155
  "eslint": "^8.20.0",
156
+ "fast-glob": "^3.2.12",
152
157
  "father": "^4.1.0",
153
158
  "highlight-words-core": "^1.2.2",
154
159
  "husky": "^8.0.1",
@@ -166,7 +171,7 @@
166
171
  "react": ">=16.8",
167
172
  "react-dom": ">=16.8"
168
173
  },
169
- "packageManager": "pnpm@7.3.0",
174
+ "packageManager": "pnpm@8.4.0",
170
175
  "publishConfig": {
171
176
  "access": "public"
172
177
  },
@@ -25,7 +25,7 @@ var HANDLERS = {
25
25
  return this.getValidClassName(prop) || prop.type;
26
26
  } else if ('const' in prop) {
27
27
  // const value
28
- return prop.const;
28
+ return "".concat(prop.const);
29
29
  } else if ('oneOf' in prop) {
30
30
  // oneOf value
31
31
  return this.oneOf(prop);
@@ -15,6 +15,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
15
15
  import { ReactComponent as IconCheck } from '@ant-design/icons-svg/inline-svg/outlined/check.svg';
16
16
  import { ReactComponent as IconCopy } from '@ant-design/icons-svg/inline-svg/outlined/copy.svg';
17
17
  import classNames from 'classnames';
18
+ import { useSiteData } from 'dumi';
18
19
  import Highlight, { defaultProps } from 'prism-react-renderer';
19
20
  import 'prism-themes/themes/prism-one-light.css';
20
21
  import React, { useRef, useState } from 'react';
@@ -42,6 +43,9 @@ var SourceCode = function SourceCode(props) {
42
43
  isCopied = _useState2[0],
43
44
  setIsCopied = _useState2[1];
44
45
 
46
+ var _useSiteData = useSiteData(),
47
+ themeConfig = _useSiteData.themeConfig;
48
+
45
49
  return /*#__PURE__*/React.createElement("div", {
46
50
  className: "dumi-default-source-code"
47
51
  }, /*#__PURE__*/React.createElement(CopyToClipboard, {
@@ -71,22 +75,32 @@ var SourceCode = function SourceCode(props) {
71
75
  className: className,
72
76
  style: style
73
77
  }, tokens.map(function (line, i) {
74
- return /*#__PURE__*/React.createElement("div", _extends({
75
- key: String(i)
76
- }, getLineProps({
78
+ return /*#__PURE__*/React.createElement("div", {
79
+ key: String(i),
80
+ className: classNames({
81
+ highlighted: highlightLines.includes(i + 1),
82
+ wrap: themeConfig.showLineNum
83
+ })
84
+ }, themeConfig.showLineNum && /*#__PURE__*/React.createElement("span", {
85
+ className: "token-line-num"
86
+ }, i + 1), /*#__PURE__*/React.createElement("div", _extends({}, getLineProps({
77
87
  line: line,
78
- key: i,
88
+ key: i
89
+ }), {
79
90
  className: classNames({
80
- highlighted: highlightLines.includes(i + 1)
91
+ 'line-cell': themeConfig.showLineNum
81
92
  })
82
- })), line.map(function (token, key) {
83
- return /*#__PURE__*/React.createElement("span", _extends({
84
- key: String(i)
85
- }, getTokenProps({
86
- token: token,
87
- key: key
88
- })));
89
- }));
93
+ }), line.map(function (token, key) {
94
+ return (
95
+ /*#__PURE__*/
96
+ // getTokenProps 返回值包含 key
97
+ // eslint-disable-next-line react/jsx-key
98
+ React.createElement("span", getTokenProps({
99
+ token: token,
100
+ key: key
101
+ }))
102
+ );
103
+ })));
90
104
  }));
91
105
  }));
92
106
  };
@@ -41,10 +41,50 @@
41
41
 
42
42
  // highlight line
43
43
  & > .highlighted {
44
+ position: relative;
45
+ width: calc(100% + 24px);
44
46
  background-color: shade(@bg-color, 5%);
45
- width: calc(100% + 48px);
46
- margin-inline-start: -24px;
47
- padding-inline-start: 24px;
47
+
48
+ .line-cell {
49
+ position: relative;
50
+
51
+ &::after {
52
+ content: '';
53
+ position: absolute;
54
+ top: 0;
55
+ right: -24px;
56
+ bottom: 0;
57
+ width: 24px;
58
+ background-color: shade(@bg-color, 5%);
59
+ }
60
+ }
61
+
62
+ &::after {
63
+ content: '';
64
+ position: absolute;
65
+ top: 0;
66
+ left: -24px;
67
+ bottom: 0;
68
+ width: 24px;
69
+ background-color: shade(@bg-color, 5%);
70
+ }
71
+ }
72
+
73
+ & > .wrap {
74
+ display: table-row;
75
+
76
+ & > .token-line-num {
77
+ display: table-cell;
78
+ text-align: right;
79
+ padding-right: 1em;
80
+ user-select: none;
81
+ opacity: 0.5;
82
+ }
83
+
84
+ & > .line-cell {
85
+ display: table-cell;
86
+ width: 100%;
87
+ }
48
88
  }
49
89
  }
50
90
 
@@ -103,6 +143,16 @@
103
143
 
104
144
  & > pre.prism-code > .highlighted {
105
145
  background-color: tint(@bg-color, 10%);
146
+
147
+ &::after {
148
+ background-color: tint(@bg-color, 10%);
149
+ }
150
+
151
+ .line-cell {
152
+ &::after {
153
+ background-color: tint(@bg-color, 10%);
154
+ }
155
+ }
106
156
  }
107
157
  }
108
158
  }
@@ -0,0 +1,4 @@
1
+ import type { ComponentProps } from 'react';
2
+ import './index.less';
3
+ declare const _default: (props: ComponentProps<'div'>) => JSX.Element;
4
+ export default _default;