dumi 2.3.0-beta.2 → 2.3.0-beta.4

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 (42) hide show
  1. package/dist/client/misc/reactDemoCompiler.d.ts +3 -0
  2. package/dist/client/misc/reactDemoCompiler.js +24 -0
  3. package/dist/client/pages/Demo/index.js +15 -0
  4. package/dist/client/theme-api/types.d.ts +9 -0
  5. package/dist/client/theme-api/useLiveDemo.d.ts +7 -3
  6. package/dist/client/theme-api/useLiveDemo.js +133 -50
  7. package/dist/client/theme-api/useNavData.js +11 -8
  8. package/dist/client/theme-api/usePrefersColor.js +1 -1
  9. package/dist/client/theme-api/useRouteMeta.d.ts +1 -1
  10. package/dist/client/theme-api/useRouteMeta.js +4 -8
  11. package/dist/client/theme-api/useSidebarData.d.ts +9 -1
  12. package/dist/client/theme-api/useSidebarData.js +9 -6
  13. package/dist/client/theme-api/useSiteSearch/useSearchData.js +2 -1
  14. package/dist/client/theme-api/utils.d.ts +0 -10
  15. package/dist/client/theme-api/utils.js +0 -25
  16. package/dist/constants.d.ts +1 -0
  17. package/dist/constants.js +3 -0
  18. package/dist/features/compile/index.js +39 -10
  19. package/dist/features/exports.js +0 -2
  20. package/dist/features/parser.js +23 -1
  21. package/dist/features/theme/index.js +13 -11
  22. package/dist/loaders/markdown/index.js +25 -7
  23. package/dist/loaders/markdown/transformer/index.d.ts +2 -1
  24. package/dist/loaders/markdown/transformer/index.js +1 -0
  25. package/dist/loaders/markdown/transformer/rehypeDemo.js +5 -2
  26. package/dist/loaders/markdown/transformer/remarkEmbed.js +2 -1
  27. package/dist/techStacks/react.d.ts +1 -0
  28. package/dist/techStacks/react.js +3 -0
  29. package/dist/templates/meta/exports.ts.tpl +33 -1
  30. package/dist/types.d.ts +14 -0
  31. package/dist/utils.d.ts +1 -3
  32. package/dist/utils.js +8 -2
  33. package/package.json +1 -1
  34. package/theme-default/builtins/Previewer/index.js +11 -31
  35. package/theme-default/builtins/Previewer/index.less +59 -15
  36. package/theme-default/slots/ColorSwitch/index.js +4 -1
  37. package/theme-default/slots/PreviewerActions/index.d.ts +1 -0
  38. package/theme-default/slots/PreviewerActions/index.js +18 -20
  39. package/theme-default/slots/SearchBar/index.less +3 -0
  40. package/theme-default/slots/SearchResult/index.js +18 -5
  41. package/theme-default/slots/SourceCodeEditor/index.d.ts +1 -0
  42. package/theme-default/slots/SourceCodeEditor/index.js +8 -31
package/dist/constants.js CHANGED
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/constants.ts
20
20
  var constants_exports = {};
21
21
  __export(constants_exports, {
22
+ FS_CACHE_DIR: () => FS_CACHE_DIR,
22
23
  LOCAL_DUMI_DIR: () => LOCAL_DUMI_DIR,
23
24
  LOCAL_PAGES_DIR: () => LOCAL_PAGES_DIR,
24
25
  LOCAL_THEME_DIR: () => LOCAL_THEME_DIR,
@@ -51,8 +52,10 @@ var PICKED_PKG_FIELDS = {
51
52
  var USELESS_TMP_FILES = ["tsconfig.json", "typings.d.ts"];
52
53
  var VERSION_2_LEVEL_NAV = "^2.2.0";
53
54
  var VERSION_2_DEPRECATE_SOFT_BREAKS = "^2.2.0";
55
+ var FS_CACHE_DIR = "node_modules/.cache/dumi";
54
56
  // Annotate the CommonJS export names for ESM import in node:
55
57
  0 && (module.exports = {
58
+ FS_CACHE_DIR,
56
59
  LOCAL_DUMI_DIR,
57
60
  LOCAL_PAGES_DIR,
58
61
  LOCAL_THEME_DIR,
@@ -33,29 +33,58 @@ __export(compile_exports, {
33
33
  });
34
34
  module.exports = __toCommonJS(compile_exports);
35
35
  var import_react = __toESM(require("../../techStacks/react"));
36
+ var import_utils = require("../../utils");
37
+ var import_path = __toESM(require("path"));
36
38
  var import_assets = require("../assets");
37
39
  var compile_default = (api) => {
40
+ const techStacks = [];
38
41
  api.describe({ key: "dumi:compile" });
39
42
  api.register({
40
43
  key: "registerTechStack",
41
44
  stage: Infinity,
42
45
  fn: () => new import_react.default()
43
46
  });
44
- api.modifyConfig((memo) => {
45
- if (memo.babelLoaderCustomize) {
46
- api.logger.warn(
47
- "Config `babelLoaderCustomize` will be override by dumi, please report issue if you need it."
47
+ api.modifyConfig({
48
+ stage: Infinity,
49
+ fn: (memo) => {
50
+ if (memo.babelLoaderCustomize) {
51
+ api.logger.warn(
52
+ "Config `babelLoaderCustomize` will be override by dumi, please report issue if you need it."
53
+ );
54
+ }
55
+ memo.babelLoaderCustomize = require.resolve("./babelLoaderCustomize");
56
+ const cacheDirPath = api.userConfig.cacheDirectoryPath || memo.cacheDirectoryPath;
57
+ if (cacheDirPath)
58
+ (0, import_utils._setFSCacheDir)(import_path.default.join(cacheDirPath, "dumi"));
59
+ return memo;
60
+ }
61
+ });
62
+ api.onGenerateFiles({
63
+ // make sure called before `addRuntimePlugin` key
64
+ // why not use `before: 'tmpFiles'`?
65
+ // because @umijs/preset-umi/.../tmpFiles has two `onGenerateFiles` key
66
+ // and `before` only insert before the last one
67
+ stage: -Infinity,
68
+ async fn() {
69
+ techStacks.push(
70
+ ...await api.applyPlugins({
71
+ key: "registerTechStack",
72
+ type: api.ApplyPluginsType.add
73
+ })
48
74
  );
49
75
  }
50
- memo.babelLoaderCustomize = require.resolve("./babelLoaderCustomize");
51
- return memo;
52
76
  });
77
+ api.addRuntimePlugin(
78
+ () => techStacks.reduce((acc, techStack) => {
79
+ var _a;
80
+ if ((_a = techStack.runtimeOpts) == null ? void 0 : _a.pluginPath) {
81
+ acc.push(techStack.runtimeOpts.pluginPath);
82
+ }
83
+ return acc;
84
+ }, [])
85
+ );
53
86
  api.chainWebpack(async (memo) => {
54
87
  const babelInUmi = memo.module.rule("src").use("babel-loader").entries();
55
- const techStacks = await api.applyPlugins({
56
- key: "registerTechStack",
57
- type: api.ApplyPluginsType.add
58
- });
59
88
  const loaderPath = require.resolve("../../loaders/markdown");
60
89
  const loaderBaseOpts = {
61
90
  techStacks,
@@ -32,13 +32,11 @@ __export(exports_exports, {
32
32
  default: () => exports_default
33
33
  });
34
34
  module.exports = __toCommonJS(exports_exports);
35
- var import_path = __toESM(require("path"));
36
35
  var import_plugin_utils = require("umi/plugin-utils");
37
36
  var exports_default = (api) => {
38
37
  api.describe({ key: "dumi:exports" });
39
38
  api.modifyConfig((memo) => {
40
39
  memo.alias["dumi$"] = "@@/dumi/exports";
41
- memo.alias["dumi/dist"] = (0, import_plugin_utils.winPath)(import_path.default.join(__dirname, ".."));
42
40
  return memo;
43
41
  });
44
42
  api.onGenerateFiles(() => {
@@ -32,16 +32,38 @@ __export(parser_exports, {
32
32
  default: () => parser_default
33
33
  });
34
34
  module.exports = __toCommonJS(parser_exports);
35
+ var import_utils = require("@umijs/utils");
35
36
  var import_assert = __toESM(require("assert"));
36
37
  var import_meta = require("./meta");
38
+ function filterIgnoredProps(props) {
39
+ return import_utils.lodash.pickBy(props, (prop) => {
40
+ let isHidden = false;
41
+ if (prop.type === "array" && "items" in prop) {
42
+ prop.items = filterIgnoredProps({ _: prop.items })._;
43
+ } else if (prop.type === "object" && "properties" in prop) {
44
+ prop.properties = filterIgnoredProps(prop.properties);
45
+ } else if (prop.oneOf) {
46
+ prop.oneOf = prop.oneOf.filter(Boolean).map((item) => filterIgnoredProps({ _: item })._);
47
+ } else if (prop.allOf) {
48
+ prop.allOf = prop.allOf.filter(Boolean).map((item) => filterIgnoredProps({ _: item })._);
49
+ } else if ("hidden" in prop) {
50
+ isHidden = true;
51
+ }
52
+ return !isHidden;
53
+ });
54
+ }
37
55
  var parser_default = (api) => {
38
56
  let prevData;
39
57
  const writeAtomsMetaFile = (data) => {
58
+ const components = import_utils.lodash.mapValues(data.components, (component) => ({
59
+ ...component,
60
+ propsConfig: filterIgnoredProps({ _: component.propsConfig })._
61
+ }));
40
62
  api.writeTmpFile({
41
63
  noPluginDir: true,
42
64
  path: import_meta.ATOMS_META_PATH,
43
65
  content: `export const components = ${JSON.stringify(
44
- data.components,
66
+ components,
45
67
  null,
46
68
  2
47
69
  )};`
@@ -75,11 +75,12 @@ function getPkgThemePath(api) {
75
75
  })
76
76
  );
77
77
  }
78
- function getModuleExports(modulePath) {
79
- return (0, import_bundler_utils.parseModuleSync)({
78
+ async function getModuleExports(modulePath) {
79
+ const [_, exports] = await (0, import_bundler_utils.parseModule)({
80
80
  path: modulePath,
81
81
  content: import_fs.default.readFileSync(modulePath, "utf-8")
82
- })[1];
82
+ });
83
+ return exports || [];
83
84
  }
84
85
  function checkMinor2ByPkg(pkg) {
85
86
  var _a, _b, _c;
@@ -254,14 +255,14 @@ export default DumiLoading;
254
255
  });
255
256
  }
256
257
  });
257
- api.onGenerateFiles(() => {
258
+ api.onGenerateFiles(async () => {
258
259
  var _a, _b, _c, _d, _e;
259
- themeMapKeys.forEach((key) => {
260
- Object.values(originalThemeData[key] || {}).forEach((item) => {
260
+ const pAll = themeMapKeys.flatMap(
261
+ (key) => Object.values(originalThemeData[key] || {}).map(async (item) => {
261
262
  if (item.source === "dumi")
262
263
  return;
263
- let contents = [];
264
- const exports = getModuleExports(item.source);
264
+ const exports = await getModuleExports(item.source);
265
+ const contents = [];
265
266
  if (exports.includes("default")) {
266
267
  contents.push(`export { default } from '${item.source}';`);
267
268
  }
@@ -273,10 +274,11 @@ export default DumiLoading;
273
274
  path: `dumi/theme/${key}/${item.specifier}.ts`,
274
275
  content: contents.join("\n")
275
276
  });
276
- });
277
- });
277
+ })
278
+ );
279
+ await Promise.all(pAll);
278
280
  const entryFile = api.config.resolve.entryFile && [import_path.default.resolve(api.cwd, api.config.resolve.entryFile)].find(import_fs.default.existsSync);
279
- const entryExports = entryFile ? getModuleExports(entryFile) : [];
281
+ const entryExports = entryFile ? await getModuleExports(entryFile) : [];
280
282
  const hasDefaultExport = entryExports.includes("default");
281
283
  const hasNamedExport = entryExports.some((exp) => exp !== "default");
282
284
  api.writeTmpFile({
@@ -86,7 +86,8 @@ export const demos = {
86
86
  '{{{id}}}': {
87
87
  component: {{{component}}},
88
88
  asset: {{{renderAsset}}},
89
- context: {{{renderContext}}}
89
+ context: {{{renderContext}}},
90
+ renderOpts: {{{renderRenderOpts}}},
90
91
  },
91
92
  {{/demos}}
92
93
  };`,
@@ -98,24 +99,41 @@ export const demos = {
98
99
  let { asset } = this;
99
100
  const { resolveMap } = this;
100
101
  Object.keys(this.resolveMap).forEach((file) => {
101
- if (!asset.dependencies[file])
102
- return;
103
- asset = import_plugin_utils.lodash.cloneDeep(asset);
104
- asset.dependencies[file].value = `{{{require('-!${resolveMap[file]}?dumi-raw').default}}}`;
102
+ var _a;
103
+ if (((_a = asset.dependencies[file]) == null ? void 0 : _a.type) === "FILE") {
104
+ asset = import_plugin_utils.lodash.cloneDeep(asset);
105
+ asset.dependencies[file].value = `{{{require('-!${resolveMap[file]}?dumi-raw').default}}}`;
106
+ }
105
107
  });
106
108
  return JSON.stringify(asset, null, 2).replace(/"{{{|}}}"/g, "");
107
109
  },
108
110
  renderContext: function renderContext() {
109
- if (!("resolveMap" in this))
111
+ if (!("resolveMap" in this) || !("asset" in this))
110
112
  return "undefined";
113
+ const entryFileName = Object.keys(this.asset.dependencies)[0];
111
114
  const context = Object.entries(this.resolveMap).reduce(
112
115
  (acc, [key, path]) => ({
113
116
  ...acc,
114
- [key]: `{{{require('${path}')}}}`
117
+ // omit entry file
118
+ ...key !== entryFileName ? {
119
+ [key]: `{{{require('${path}')}}}`
120
+ } : {}
115
121
  }),
116
122
  {}
117
123
  );
118
124
  return JSON.stringify(context, null, 2).replace(/"{{{|}}}"/g, "");
125
+ },
126
+ renderRenderOpts: function renderRenderOpts() {
127
+ if (!("renderOpts" in this) || !this.renderOpts.compilePath) {
128
+ return "undefined";
129
+ }
130
+ return `{
131
+ compile: async (...args) => {
132
+ return (await import('${(0, import_plugin_utils.winPath)(
133
+ this.renderOpts.compilePath
134
+ )}')).default(...args);
135
+ },
136
+ }`;
119
137
  }
120
138
  }
121
139
  );
@@ -1,6 +1,6 @@
1
1
  import type { IParsedBlockAsset } from "../../../assetParsers/block";
2
2
  import type { ILocalesConfig, IRouteMeta } from "../../../client/theme-api/types";
3
- import type { IApi, IDumiConfig, IDumiTechStack } from "../../../types";
3
+ import type { IApi, IDumiConfig, IDumiTechStack, IDumiTechStackRuntimeOpts } from "../../../types";
4
4
  import type { IRoute } from 'umi';
5
5
  import type { Data } from 'vfile';
6
6
  declare module 'hast' {
@@ -22,6 +22,7 @@ declare module 'vfile' {
22
22
  component: string;
23
23
  asset: IParsedBlockAsset['asset'];
24
24
  resolveMap: IParsedBlockAsset['resolveMap'];
25
+ renderOpts: Pick<IDumiTechStackRuntimeOpts, 'compilePath'>;
25
26
  } | {
26
27
  id: string;
27
28
  component: string;
@@ -78,6 +78,7 @@ var transformer_default = async (raw, opts) => {
78
78
  const { default: rehypeAutolinkHeadings } = await import("rehype-autolink-headings");
79
79
  const { default: rehypeRemoveComments } = await import("rehype-remove-comments");
80
80
  const resolver = import_enhanced_resolve.default.create.sync({
81
+ mainFields: ["browser", "module", "main"],
81
82
  extensions: [".js", ".jsx", ".ts", ".tsx"],
82
83
  alias: opts.alias
83
84
  });
@@ -226,7 +226,7 @@ function rehypeDemo(opts) {
226
226
  deferrers.push(
227
227
  (0, import_block.default)(parseOpts).then(
228
228
  async ({ asset, resolveMap, frontmatter }) => {
229
- var _a2, _b2, _c2;
229
+ var _a2, _b2, _c2, _d;
230
230
  if (demoIds.indexOf(parseOpts.id) !== demoIds.lastIndexOf(parseOpts.id)) {
231
231
  const startLine = (_a2 = node.position) == null ? void 0 : _a2.start.line;
232
232
  const suffix = startLine ? `:${startLine}` : "";
@@ -299,7 +299,10 @@ function rehypeDemo(opts) {
299
299
  resolveMap: techStack.generateSources ? await techStack.generateSources(
300
300
  resolveMap,
301
301
  techStackOpts
302
- ) : resolveMap
302
+ ) : resolveMap,
303
+ renderOpts: {
304
+ compilePath: (_d = techStack.runtimeOpts) == null ? void 0 : _d.compilePath
305
+ }
303
306
  };
304
307
  }
305
308
  )
@@ -38,6 +38,7 @@ var import_fs = __toESM(require("fs"));
38
38
  var import_path = __toESM(require("path"));
39
39
  var import_plugin_utils = require("umi/plugin-utils");
40
40
  var import_url = __toESM(require("url"));
41
+ var import_remarkContainer = __toESM(require("./remarkContainer"));
41
42
  var EMBED_OPEN_TAG = "<embed ";
42
43
  var EMBED_CLOSE_TAG = "</embed>";
43
44
  var unified;
@@ -129,7 +130,7 @@ function remarkEmbed(opts) {
129
130
  const {
130
131
  result: mdast,
131
132
  data: { embeds }
132
- } = unified().use(remarkParse).use(remarkEmbed, { ...opts, fileAbsPath: absPath }).use(remarkFrontmatter).use(remarkDirective).use(remarkGfm).use(remarkReplaceSrc, {
133
+ } = unified().use(remarkParse).use(remarkEmbed, { ...opts, fileAbsPath: absPath }).use(remarkFrontmatter).use(remarkDirective).use(import_remarkContainer.default).use(remarkGfm).use(remarkReplaceSrc, {
133
134
  fileAbsPath: absPath,
134
135
  parentAbsPath: opts.fileAbsPath
135
136
  }).use(remarkRawAST).processSync(content);
@@ -1,6 +1,7 @@
1
1
  import type { IDumiTechStack } from "../types";
2
2
  export default class ReactTechStack implements IDumiTechStack {
3
3
  name: string;
4
+ runtimeOpts?: IDumiTechStack['runtimeOpts'];
4
5
  isSupported(...[, lang]: Parameters<IDumiTechStack['isSupported']>): boolean;
5
6
  transformCode(...[raw, opts]: Parameters<IDumiTechStack['transformCode']>): string;
6
7
  }
@@ -36,6 +36,9 @@ var import_core = require("@swc/core");
36
36
  var ReactTechStack = class {
37
37
  constructor() {
38
38
  this.name = "react";
39
+ this.runtimeOpts = {
40
+ compilePath: require.resolve("../client/misc/reactDemoCompiler")
41
+ };
39
42
  }
40
43
  isSupported(...[, lang]) {
41
44
  return ["jsx", "tsx"].includes(lang);
@@ -1,6 +1,38 @@
1
1
  import { filesMeta, tabsMeta } from '.';
2
2
  import type { IDemoData, IRouteMeta } from 'dumi/dist/client/theme-api/types';
3
- import { use } from 'dumi/dist/client/theme-api/utils';
3
+
4
+ // Copy from React official demo.
5
+ type ReactPromise<T> = Promise<T> & {
6
+ status?: 'pending' | 'fulfilled' | 'rejected';
7
+ value?: T;
8
+ reason?: any;
9
+ };
10
+
11
+ /**
12
+ * @private Internal usage. Safe to remove
13
+ */
14
+ export function use<T>(promise: ReactPromise<T>): T {
15
+ if (promise.status === 'fulfilled') {
16
+ return promise.value!;
17
+ } else if (promise.status === 'rejected') {
18
+ throw promise.reason;
19
+ } else if (promise.status === 'pending') {
20
+ throw promise;
21
+ } else {
22
+ promise.status = 'pending';
23
+ promise.then(
24
+ (result) => {
25
+ promise.status = 'fulfilled';
26
+ promise.value = result;
27
+ },
28
+ (reason) => {
29
+ promise.status = 'rejected';
30
+ promise.reason = reason;
31
+ },
32
+ );
33
+ throw promise;
34
+ }
35
+ }
4
36
 
5
37
  const demoIdMap = Object.keys(filesMeta).reduce((total, current) => {
6
38
  if (filesMeta[current].demoIndex) {
package/dist/types.d.ts CHANGED
@@ -48,11 +48,25 @@ export type IDumiUserConfig = Subset<Omit<IDumiConfig, 'locales'>> & {
48
48
  }>, 'base'>[];
49
49
  [key: string]: any;
50
50
  };
51
+ export interface IDumiTechStackRuntimeOpts {
52
+ /**
53
+ * path to runtime compile function module
54
+ */
55
+ compilePath?: string;
56
+ /**
57
+ * path to runtime plugin for this tech stack
58
+ */
59
+ pluginPath?: string;
60
+ }
51
61
  export declare abstract class IDumiTechStack {
52
62
  /**
53
63
  * tech stack name, such as 'react'
54
64
  */
55
65
  abstract name: string;
66
+ /**
67
+ * runtime options
68
+ */
69
+ abstract runtimeOpts?: IDumiTechStackRuntimeOpts;
56
70
  /**
57
71
  * transform code
58
72
  */
package/dist/utils.d.ts CHANGED
@@ -21,10 +21,8 @@ export declare function parseCodeFrontmatter(raw: string): {
21
21
  code: string;
22
22
  frontmatter: Record<string, any> | null;
23
23
  };
24
- /**
25
- * get file-system cache for specific namespace
26
- */
27
24
  declare const caches: Record<string, ReturnType<typeof Cache>>;
25
+ export declare function _setFSCacheDir(dir: string): void;
28
26
  export declare function getCache(ns: string): (typeof caches)['0'];
29
27
  /**
30
28
  * try to get father config
package/dist/utils.js CHANGED
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/utils.ts
30
30
  var utils_exports = {};
31
31
  __export(utils_exports, {
32
+ _setFSCacheDir: () => _setFSCacheDir,
32
33
  componentToChunkName: () => componentToChunkName,
33
34
  generateMetaChunkName: () => generateMetaChunkName,
34
35
  getCache: () => getCache,
@@ -47,6 +48,7 @@ var import_fs = __toESM(require("fs"));
47
48
  var import_js_yaml = __toESM(require("js-yaml"));
48
49
  var import_path = __toESM(require("path"));
49
50
  var import_plugin_utils = require("umi/plugin-utils");
51
+ var import_constants = require("./constants");
50
52
  function getFileIdFromFsPath(fsPath) {
51
53
  return import_plugin_utils.lodash.kebabCase((0, import_plugin_utils.winPath)(fsPath).replace(/((\/|^)index)?\.\w+$/g, ""));
52
54
  }
@@ -80,8 +82,11 @@ function parseCodeFrontmatter(raw) {
80
82
  }
81
83
  return { code: frontmatter ? code : raw, frontmatter };
82
84
  }
85
+ var cacheDir = import_constants.FS_CACHE_DIR;
83
86
  var caches = {};
84
- var CACHE_PATH = "node_modules/.cache/dumi";
87
+ function _setFSCacheDir(dir) {
88
+ cacheDir = dir;
89
+ }
85
90
  function getCache(ns) {
86
91
  if (process.env.DUMI_CACHE === "none") {
87
92
  return { set() {
@@ -90,7 +95,7 @@ function getCache(ns) {
90
95
  }, getSync() {
91
96
  } };
92
97
  }
93
- return caches[ns] ?? (caches[ns] = (0, import_file_system_cache.default)({ basePath: import_path.default.join(CACHE_PATH, ns) }));
98
+ return caches[ns] ?? (caches[ns] = (0, import_file_system_cache.default)({ basePath: import_path.default.resolve(cacheDir, ns) }));
94
99
  }
95
100
  async function tryFatherBuildConfigs(cwd) {
96
101
  let configs = [];
@@ -156,6 +161,7 @@ function getContentHash(content2, length = 8) {
156
161
  }
157
162
  // Annotate the CommonJS export names for ESM import in node:
158
163
  0 && (module.exports = {
164
+ _setFSCacheDir,
159
165
  componentToChunkName,
160
166
  generateMetaChunkName,
161
167
  getCache,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.3.0-beta.2",
3
+ "version": "2.3.0-beta.4",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -1,16 +1,10 @@
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
  function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
3
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
- 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."); }
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
- 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; }
7
- function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
8
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
9
3
  import { ReactComponent as IconError } from '@ant-design/icons-svg/inline-svg/filled/close-circle.svg';
10
4
  import classnames from 'classnames';
11
5
  import { useLiveDemo, useLocation } from 'dumi';
12
6
  import PreviewerActions from 'dumi/theme/slots/PreviewerActions';
13
- import React, { useRef, useState } from 'react';
7
+ import React, { useRef } from 'react';
14
8
  import "./index.less";
15
9
  var Previewer = function Previewer(props) {
16
10
  var _demoContainer$curren;
@@ -18,15 +12,14 @@ var Previewer = function Previewer(props) {
18
12
  var _useLocation = useLocation(),
19
13
  hash = _useLocation.hash;
20
14
  var link = "#".concat(props.asset.id);
21
- var _useLiveDemo = useLiveDemo(props.asset.id),
15
+ var _useLiveDemo = useLiveDemo(props.asset.id, {
16
+ iframe: Boolean(props.iframe),
17
+ containerRef: demoContainer
18
+ }),
22
19
  liveDemoNode = _useLiveDemo.node,
23
20
  liveDemoError = _useLiveDemo.error,
21
+ liveDemoLoading = _useLiveDemo.loading,
24
22
  setLiveDemoSource = _useLiveDemo.setSource;
25
- var _useState = useState(null),
26
- _useState2 = _slicedToArray(_useState, 2),
27
- editorError = _useState2[0],
28
- setEditorError = _useState2[1];
29
- var combineError = liveDemoError || editorError;
30
23
  return /*#__PURE__*/React.createElement("div", {
31
24
  id: props.asset.id,
32
25
  className: classnames('dumi-default-previewer', props.className),
@@ -41,15 +34,17 @@ var Previewer = function Previewer(props) {
41
34
  "data-compact": props.compact || undefined,
42
35
  "data-transform": props.transform || undefined,
43
36
  "data-iframe": props.iframe || undefined,
37
+ "data-error": Boolean(liveDemoError) || undefined,
38
+ "data-loading": liveDemoLoading || undefined,
44
39
  ref: demoContainer
45
40
  }, props.iframe ? /*#__PURE__*/React.createElement("iframe", {
46
41
  style: ['string', 'number'].includes(_typeof(props.iframe)) ? {
47
42
  height: Number(props.iframe)
48
43
  } : {},
49
44
  src: props.demoUrl
50
- }) : liveDemoNode || props.children), combineError && /*#__PURE__*/React.createElement("div", {
45
+ }) : liveDemoNode || props.children), liveDemoError && /*#__PURE__*/React.createElement("div", {
51
46
  className: "dumi-default-previewer-demo-error"
52
- }, /*#__PURE__*/React.createElement(IconError, null), combineError.toString()), /*#__PURE__*/React.createElement("div", {
47
+ }, /*#__PURE__*/React.createElement(IconError, null), liveDemoError.toString()), /*#__PURE__*/React.createElement("div", {
53
48
  className: "dumi-default-previewer-meta"
54
49
  }, (props.title || props.debug) && /*#__PURE__*/React.createElement("div", {
55
50
  className: "dumi-default-previewer-desc"
@@ -61,22 +56,7 @@ var Previewer = function Previewer(props) {
61
56
  __html: props.description
62
57
  }
63
58
  })), /*#__PURE__*/React.createElement(PreviewerActions, _extends({}, props, {
64
- onSourceTranspile: function onSourceTranspile(_ref) {
65
- var err = _ref.err,
66
- source = _ref.source;
67
- if (err) {
68
- setEditorError(err);
69
- } else {
70
- setEditorError(null);
71
- setLiveDemoSource(source);
72
- if (props.iframe) {
73
- demoContainer.current.querySelector('iframe').contentWindow.postMessage({
74
- type: 'dumi.liveDemo.setSource',
75
- value: source
76
- });
77
- }
78
- }
79
- },
59
+ onSourceChange: setLiveDemoSource,
80
60
  demoContainer: props.iframe ? (_demoContainer$curren = demoContainer.current) === null || _demoContainer$curren === void 0 ? void 0 : _demoContainer$curren.firstElementChild : demoContainer.current
81
61
  }))));
82
62
  };
@@ -1,6 +1,8 @@
1
1
  @import (reference) '../../styles/variables.less';
2
2
 
3
3
  .@{prefix}-previewer {
4
+ @error-bar-height: 30px;
5
+
4
6
  margin: 24px 0 32px;
5
7
  border: 1px solid @c-border-light;
6
8
  border-radius: 4px;
@@ -38,17 +40,11 @@
38
40
  &[data-iframe] {
39
41
  position: relative;
40
42
  padding: 0;
41
- overflow: hidden;
42
-
43
- &::before {
44
- content: '';
45
- display: block;
46
- height: 24px;
47
- background-color: @c-border-light;
43
+ border-top: 24px solid @c-border-light;
44
+ box-sizing: border-box;
48
45
 
49
- @{dark-selector} & {
50
- background-color: @c-border-less-dark;
51
- }
46
+ @{dark-selector} & {
47
+ border-top-color: @c-border-less-dark;
52
48
  }
53
49
 
54
50
  &::after {
@@ -57,7 +53,7 @@
57
53
 
58
54
  content: '';
59
55
  position: absolute;
60
- top: 5px;
56
+ top: -19px;
61
57
  left: @btn-gap;
62
58
  display: inline-block;
63
59
  width: @btn-width;
@@ -76,16 +72,64 @@
76
72
  &[data-compact] {
77
73
  padding: 0;
78
74
  }
75
+
76
+ // error status
77
+ &[data-error][data-compact] {
78
+ min-height: @error-bar-height;
79
+
80
+ + .@{prefix}-previewer-demo-error {
81
+ border-top-left-radius: 3px;
82
+ border-top-right-radius: 3px;
83
+ }
84
+ }
85
+
86
+ // loading status
87
+ &[data-loading] {
88
+ position: relative;
89
+
90
+ &::before {
91
+ @size: 28px;
92
+
93
+ position: absolute;
94
+ top: 50%;
95
+ left: 50%;
96
+ content: '';
97
+ display: block;
98
+ height: @size;
99
+ max-height: 90%;
100
+ aspect-ratio: 1;
101
+ border-radius: 50%;
102
+ border: (@size / 10) solid;
103
+ border-color: @c-primary transparent;
104
+ box-sizing: border-box;
105
+ animation: dumi-previewer-loading 1s infinite;
106
+ transform: translate(-50%, -50%);
107
+
108
+ @{dark-selector} & {
109
+ border-color: @c-primary-dark transparent;
110
+ }
111
+
112
+ @keyframes dumi-previewer-loading {
113
+ to {
114
+ transform: translate(-50%, -50%) rotate(0.5turn);
115
+ }
116
+ }
117
+ }
118
+
119
+ > * {
120
+ opacity: 0.3 !important;
121
+ }
122
+ }
79
123
  }
80
124
 
81
125
  &-demo-error {
82
- @height: 30px;
83
126
  @color: darken(desaturate(@c-error, 20%), 1%);
84
127
 
85
- margin-top: -@height;
86
- height: @height;
128
+ position: relative;
129
+ margin-top: -@error-bar-height;
130
+ height: @error-bar-height;
87
131
  padding: 0 24px;
88
- line-height: @height;
132
+ line-height: @error-bar-height;
89
133
  color: @color;
90
134
  font-size: 13px;
91
135
  white-space: nowrap;