dumi 2.2.0 → 2.2.1-alpha.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.
@@ -20,7 +20,7 @@ var DemoErrorBoundary = function DemoErrorBoundary(props) {
20
20
  }, props.children);
21
21
  };
22
22
 
23
- export var DumiDemo = function DumiDemo(props) {
23
+ export var DumiDemo = /*#__PURE__*/React.memo(function (props) {
24
24
  var _useSiteData = useSiteData(),
25
25
  demos = _useSiteData.demos,
26
26
  historyType = _useSiteData.historyType;
@@ -45,4 +45,7 @@ export var DumiDemo = function DumiDemo(props) {
45
45
  props.previewerProps.demoUrl || // when use hash route, browser can automatically handle relative paths starting with #
46
46
  "".concat(isHashRoute ? "#" : '').concat(basename).concat(SP_ROUTE_PREFIX, "demos/").concat(props.demo.id)
47
47
  }, props.previewerProps), props.previewerProps.iframe ? null : /*#__PURE__*/React.createElement(DemoErrorBoundary, null, /*#__PURE__*/createElement(component)));
48
- };
48
+ }, function (prev, next) {
49
+ // compare length for performance
50
+ return JSON.stringify(prev).length === JSON.stringify(next).length;
51
+ });
@@ -14,6 +14,7 @@ interface ISiteContext {
14
14
  components: Record<string, AtomComponentAsset>;
15
15
  locales: ILocalesConfig;
16
16
  themeConfig: IThemeConfig;
17
+ hostname?: string;
17
18
  loading: boolean;
18
19
  setLoading: (status: boolean) => void;
19
20
  /**
@@ -203,8 +203,8 @@ export interface IThemeConfig {
203
203
  switch: boolean;
204
204
  };
205
205
  nprogress?: boolean;
206
- socialLinks: {
207
- [key in SocialTypes]: string;
206
+ socialLinks?: {
207
+ [key in SocialTypes]?: string;
208
208
  };
209
209
  [key: string]: any;
210
210
  }
@@ -1,4 +1,4 @@
1
- import { useLayoutEffect } from 'react';
1
+ import { useEffect } from 'react';
2
2
  import type { ILocale, INav, INavItem, IRouteMeta, IRoutesById, IUserNavValue } from './types';
3
3
  export declare const useLocaleDocRoutes: () => IRoutesById;
4
4
  /**
@@ -7,7 +7,7 @@ export declare const useLocaleDocRoutes: () => IRoutesById;
7
7
  * @returns code string
8
8
  */
9
9
  export declare const genReactRenderCode: (version: string) => string;
10
- export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
10
+ export declare const useIsomorphicLayoutEffect: typeof useEffect;
11
11
  /**
12
12
  * common comparer for sidebar/nav items
13
13
  */
@@ -50,7 +50,7 @@ var sitemap_default = (api) => {
50
50
  const writeStream = import_fs.default.createWriteStream(import_path.default.join(api.paths.absOutputPath, "sitemap.xml"));
51
51
  smis.pipe(writeStream);
52
52
  Object.values(api.appData.routes).forEach((route) => {
53
- if (!exclude.includes(route.path) && ![":", "*"].some((char) => route.path.includes(char))) {
53
+ if (!exclude.includes(route.path) && ![":", "*"].some((char) => route.path.includes(char)) && route.path !== "" && !route.isLayout) {
54
54
  smis.write({ url: route.path });
55
55
  }
56
56
  });
@@ -34,13 +34,17 @@ var import_derivative = require("../derivative");
34
34
  var import_loader = __toESM(require("./loader"));
35
35
  var DEFAULT_THEME_PATH = import_path.default.join(__dirname, "../../../theme-default");
36
36
  function getPkgThemeName(api) {
37
+ if (process.env.DUMI_THEME) {
38
+ const themePkg = require(import_path.default.join(process.env.DUMI_THEME, "package.json"));
39
+ return themePkg.name;
40
+ }
37
41
  const validDeps = Object.assign({}, api.pkg.dependencies, api.pkg.devDependencies);
38
42
  const pkgThemeName = Object.keys(validDeps).find((pkg) => pkg.split("/").pop().startsWith(import_constants.THEME_PREFIX));
39
43
  return pkgThemeName;
40
44
  }
41
45
  function getPkgThemePath(api) {
42
46
  const pkgThemeName = getPkgThemeName(api);
43
- return pkgThemeName && import_path.default.dirname(import_plugin_utils.resolve.sync(`${pkgThemeName}/package.json`, {
47
+ return process.env.DUMI_THEME || pkgThemeName && import_path.default.dirname(import_plugin_utils.resolve.sync(`${process.env.DUMI_THEME || pkgThemeName}/package.json`, {
44
48
  basedir: api.cwd,
45
49
  preserveSymlinks: true
46
50
  }));
@@ -151,7 +155,7 @@ var theme_default = (api) => {
151
155
  return memo;
152
156
  });
153
157
  api.onGenerateFiles(() => {
154
- var _a, _b, _c, _d;
158
+ var _a, _b, _c, _d, _e;
155
159
  themeMapKeys.forEach((key) => {
156
160
  Object.values(originalThemeData[key] || {}).forEach((item) => {
157
161
  if (item.source === "dumi")
@@ -228,6 +232,7 @@ export default function DumiContextWrapper() {
228
232
  locales,
229
233
  loading,
230
234
  setLoading,
235
+ hostname: ${JSON.stringify((_b = api.config.sitemap) == null ? void 0 : _b.hostname)},
231
236
  themeConfig: ${JSON.stringify(Object.assign(import_plugin_utils.lodash.pick(api.config, "logo", "description", "title"), api.config.themeConfig))},
232
237
  _2_level_nav_available: ${api.appData._2LevelNavAvailable},
233
238
  }}>
@@ -236,7 +241,7 @@ export default function DumiContextWrapper() {
236
241
  );
237
242
  }`
238
243
  });
239
- 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";
244
+ const primaryColor = typeof ((_c = api.config) == null ? void 0 : _c.theme) === "object" ? (_e = (_d = api.config) == null ? void 0 : _d.theme) == null ? void 0 : _e["@c-primary"] : "#1677ff";
240
245
  api.writeTmpFile({
241
246
  noPluginDir: true,
242
247
  path: "dumi/theme/nprogress.css",
@@ -172,7 +172,7 @@ function rehypeDemo(opts) {
172
172
  parseOpts.fileAbsPath = (0, import_plugin_utils.winPath)(codeNode.properties.src);
173
173
  let localId = ((_b = codeNode.properties) == null ? void 0 : _b.id) ?? import_path.default.parse(parseOpts.fileAbsPath.replace(/\/index\.(j|t)sx?$/, "")).name;
174
174
  parseOpts.id = getCodeId(opts.cwd, opts.fileAbsPath, localId, vFile.data.frontmatter.atomId);
175
- component = `React.lazy(() => import( /* webpackChunkName: "${chunkName}" */ '${(0, import_plugin_utils.winPath)(parseOpts.fileAbsPath)}?techStack=${techStack.name}'))`;
175
+ component = `React.memo(React.lazy(() => import( /* webpackChunkName: "${chunkName}" */ '${(0, import_plugin_utils.winPath)(parseOpts.fileAbsPath)}?techStack=${techStack.name}')))`;
176
176
  if (codeValue)
177
177
  codeNode.properties.title = codeValue;
178
178
  (_c = codeNode.properties).filename ?? (_c.filename = (0, import_plugin_utils.winPath)(import_path.default.relative(opts.cwd, parseOpts.fileAbsPath)));
@@ -58,9 +58,9 @@ var ReactTechStack = class {
58
58
  type: "es6"
59
59
  }
60
60
  });
61
- return `React.lazy(async () => {
61
+ return `React.memo(React.lazy(async () => {
62
62
  ${code}
63
- })`;
63
+ }))`;
64
64
  }
65
65
  return raw;
66
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.2.0",
3
+ "version": "2.2.1-alpha.0",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -29,10 +29,12 @@ var DocLayout = function DocLayout() {
29
29
  var sidebar = useSidebarData();
30
30
 
31
31
  var _useLocation = useLocation(),
32
- hash = _useLocation.hash;
32
+ hash = _useLocation.hash,
33
+ pathname = _useLocation.pathname;
33
34
 
34
35
  var _useSiteData = useSiteData(),
35
- loading = _useSiteData.loading;
36
+ loading = _useSiteData.loading,
37
+ hostname = _useSiteData.hostname;
36
38
 
37
39
  var _useState = useState(false),
38
40
  _useState2 = _slicedToArray(_useState, 2),
@@ -80,9 +82,15 @@ var DocLayout = function DocLayout() {
80
82
  }), fm.keywords && /*#__PURE__*/React.createElement("meta", {
81
83
  name: "keywords",
82
84
  content: fm.keywords.join(',')
83
- }), fm.keywords && /*#__PURE__*/React.createElement("meta", {
84
- property: "og:keywords",
85
- content: fm.keywords.join(',')
85
+ }), fm.keywords && fm.keywords.map(function (keyword) {
86
+ return /*#__PURE__*/React.createElement("meta", {
87
+ key: keyword,
88
+ property: "article:tag",
89
+ content: keyword
90
+ });
91
+ }), hostname && /*#__PURE__*/React.createElement("link", {
92
+ rel: "canonical",
93
+ href: hostname + pathname
86
94
  })), /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement(Hero, null), /*#__PURE__*/React.createElement(Features, null), showSidebar && /*#__PURE__*/React.createElement("div", {
87
95
  className: "dumi-default-doc-layout-mobile-bar"
88
96
  }, /*#__PURE__*/React.createElement("button", {
@@ -10,11 +10,11 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
10
10
 
11
11
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
12
 
13
- import HeaderExtra from "../HeadeExtra";
14
13
  import { ReactComponent as IconClose } from '@ant-design/icons-svg/inline-svg/outlined/close.svg';
15
14
  import { ReactComponent as IconMenu } from '@ant-design/icons-svg/inline-svg/outlined/menu.svg';
16
15
  import { useRouteMeta, useSiteData } from 'dumi';
17
16
  import ColorSwitch from 'dumi/theme/slots/ColorSwitch';
17
+ import HeaderExtra from 'dumi/theme/slots/HeaderExtra';
18
18
  import LangSwitch from 'dumi/theme/slots/LangSwitch';
19
19
  import Logo from 'dumi/theme/slots/Logo';
20
20
  import Navbar from 'dumi/theme/slots/Navbar';
@@ -36,6 +36,7 @@
36
36
  line-height: 1;
37
37
  border: 0;
38
38
  background-color: transparent;
39
+ cursor: pointer;
39
40
 
40
41
  @{dark-selector} & {
41
42
  color: @c-text-secondary-dark;
@@ -75,7 +75,7 @@ var NavbarContent = function NavbarContent(_ref2) {
75
75
  var data = _ref2.data;
76
76
  return /*#__PURE__*/React.createElement(React.Fragment, null, data.map(function (item) {
77
77
  return /*#__PURE__*/React.createElement("li", {
78
- key: item.activePath
78
+ key: item.activePath || item.link || item.title
79
79
  }, item.link && /^(\w+:)\/\/|^(mailto|tel):/.test(item.link) ? /*#__PURE__*/React.createElement("a", {
80
80
  href: item.link,
81
81
  target: "_blank",
@@ -1,11 +1,12 @@
1
1
  import { type IPreviewerProps } from 'dumi';
2
- import { type FC } from 'react';
2
+ import { type FC, type ReactNode } from 'react';
3
3
  import './index.less';
4
4
  export interface IPreviewerActionsProps extends IPreviewerProps {
5
5
  /**
6
6
  * disabled actions
7
7
  */
8
8
  disabledActions?: ('CSB' | 'STACKBLITZ' | 'EXTERNAL' | 'HTML2SKETCH')[];
9
+ extra?: ReactNode;
9
10
  forceShowCode?: boolean;
10
11
  demoContainer: HTMLDivElement | HTMLIFrameElement;
11
12
  }
@@ -159,7 +159,7 @@ var PreviewerActions = function PreviewerActions(props) {
159
159
  "data-dumi-tooltip": intl.formatMessage({
160
160
  id: 'previewer.actions.separate'
161
161
  })
162
- }, /*#__PURE__*/React.createElement(IconExternalLink, null)), /*#__PURE__*/React.createElement(PreviewerActionsExtra, props), !props.forceShowCode && /*#__PURE__*/React.createElement("button", {
162
+ }, /*#__PURE__*/React.createElement(IconExternalLink, null)), props.extra, /*#__PURE__*/React.createElement(PreviewerActionsExtra, props), !props.forceShowCode && /*#__PURE__*/React.createElement("button", {
163
163
  className: "dumi-default-previewer-action-btn",
164
164
  type: "button",
165
165
  onClick: function onClick() {