dumi 2.1.0 → 2.1.2

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.
@@ -29,7 +29,9 @@ export var DumiDemo = function DumiDemo(props) {
29
29
 
30
30
  var _demos$props$demo$id = demos[props.demo.id],
31
31
  component = _demos$props$demo$id.component,
32
- asset = _demos$props$demo$id.asset;
32
+ asset = _demos$props$demo$id.asset; // hide debug demo in production
33
+
34
+ if (process.env.NODE_ENV === 'production' && props.previewerProps.debug) return null;
33
35
 
34
36
  if (props.demo.inline) {
35
37
  return /*#__PURE__*/React.createElement(DemoErrorBoundary, null, /*#__PURE__*/createElement(component));
@@ -18,10 +18,14 @@ export var DumiDemoGrid = function DumiDemoGrid(props) {
18
18
  var _useRouteMeta = useRouteMeta(),
19
19
  fm = _useRouteMeta.frontmatter;
20
20
 
21
- var generator = useCallback(function (fm, items) {
21
+ var generator = useCallback(function (fm, oItems) {
22
22
  var _fm$demo;
23
23
 
24
24
  var cols = [];
25
+ var items = process.env.NODE_ENV === 'production' ? // hide debug demo in production
26
+ oItems.filter(function (d) {
27
+ return !d.previewerProps.debug;
28
+ }) : oItems;
25
29
 
26
30
  if ((_fm$demo = fm.demo) !== null && _fm$demo !== void 0 && _fm$demo.cols && fm.demo.cols > 1 && ( // compatible for ssr env
27
31
  typeof window === 'undefined' || window.innerWidth > 1024)) {
@@ -110,6 +110,8 @@ export interface IRouteMeta {
110
110
  }[];
111
111
  tabs?: {
112
112
  key: string;
113
+ name?: string;
114
+ nameIntlId?: string;
113
115
  components: {
114
116
  default: ComponentType;
115
117
  Extra: ComponentType;
@@ -35,16 +35,19 @@ var CTX_LAYOUT_ID = "dumi-context-layout";
35
35
  function normalizeDocDir(docDir) {
36
36
  return typeof docDir === "object" ? docDir : { dir: docDir };
37
37
  }
38
+ function kebabCaseRoutePath(routePath) {
39
+ return routePath.split("/").map((p) => import_plugin_utils.lodash.kebabCase(p)).join("/");
40
+ }
38
41
  function localizeUmiRoute(route, locales) {
39
42
  const locale = locales.find((locale2) => route.path.endsWith(`/${locale2.id}`) && import_path.default.parse(route.file).name.endsWith(`.${locale2.id}`));
40
43
  if (locale) {
41
44
  const base = !("base" in locale) || locale.base === "/" ? "" : locale.base.replace(/^(\/)(.+)$/, "$2$1");
42
45
  const suffix = "suffix" in locale ? locale.suffix : "";
43
- route.path = `${base}${route.path.replace(new RegExp(`/${locale.id}$`), "").replace(/((^|\/)(index|README))$/, "").toLowerCase()}${suffix}`;
46
+ route.path = `${base}${kebabCaseRoutePath(route.path.replace(new RegExp(`/${locale.id}$`), "").replace(/((^|\/)(index|README))$/, ""))}${suffix}`;
44
47
  route.absPath = route.path !== "/" ? `/${route.path}` : route.path;
45
48
  } else {
46
- route.path = route.path.toLowerCase();
47
- route.absPath = route.absPath.toLowerCase();
49
+ route.path = kebabCaseRoutePath(route.path);
50
+ route.absPath = kebabCaseRoutePath(route.absPath);
48
51
  }
49
52
  }
50
53
  function flatRoute(route, docLayoutId) {
@@ -53,10 +56,6 @@ function flatRoute(route, docLayoutId) {
53
56
  route.path = route.path === "*" ? route.path : route.absPath.slice(1);
54
57
  }
55
58
  }
56
- function kebabCaseRoute(route) {
57
- route.path = route.path.split("/").map((p) => import_plugin_utils.lodash.kebabCase(p)).join("/");
58
- route.absPath = route.absPath.split("/").map((p) => import_plugin_utils.lodash.kebabCase(p)).join("/");
59
- }
60
59
  function getClientPageFile(file, cwd) {
61
60
  try {
62
61
  return import_plugin_utils.resolve.sync(`dumi/dist/${file}`, {
@@ -134,7 +133,7 @@ var routes_default = (api) => {
134
133
  const base = import_path.default.join(api.cwd, dir);
135
134
  const dirRoutes = (0, import_core.getConventionRoutes)({
136
135
  base,
137
- exclude: [/.*(?<!md)$/, /(\/|^)(\.|_\/)/]
136
+ exclude: [/.*(?<!md)$/, /(\/|^)(\.|_)/]
138
137
  });
139
138
  Object.entries(dirRoutes).forEach(([key, route]) => {
140
139
  route.id = `${dir}/${key}`;
@@ -168,7 +167,6 @@ var routes_default = (api) => {
168
167
  throw new Error(`Invalid route path: ${route.path}, please rename it with only alphanumeric, dash and slash.
169
168
  at ${route.file}`);
170
169
  } else if (!route.isLayout) {
171
- kebabCaseRoute(route);
172
170
  flatRoute(route, docLayoutId);
173
171
  localizeUmiRoute(route, api.config.locales);
174
172
  }
@@ -3,6 +3,8 @@ export interface IContentTab {
3
3
  key: string;
4
4
  id?: string;
5
5
  test?: RegExp;
6
+ name?: string;
7
+ nameIntlId?: string;
6
8
  component: string;
7
9
  }
8
10
  export declare function isTabRouteFile(file: string): boolean;
@@ -86,6 +86,8 @@ var tabs_default = (api) => {
86
86
  index: tabs.length + index,
87
87
  key: tab.key,
88
88
  id: tab.id,
89
+ name: tab.name,
90
+ nameIntlId: tab.nameIntlId,
89
91
  file: tab.component
90
92
  })));
91
93
  return routes;
@@ -118,7 +120,7 @@ import * as tab{{{index}}} from '{{{file}}}';
118
120
 
119
121
  export const tabs = {
120
122
  {{#tabs}}
121
- '{{{id}}}': { key: '{{{key}}}', components: tab{{{index}}} },
123
+ '{{{id}}}': { key: '{{{key}}}', name: '{{{name}}}', nameIntlId: '{{{nameIntlId}}}', components: tab{{{index}}} },
122
124
  {{/tabs}}
123
125
  }
124
126
  `, { tabs })
@@ -29,7 +29,10 @@ var import_plugin_utils = require("umi/plugin-utils");
29
29
  var raw;
30
30
  var visit;
31
31
  var COMPONENT_NAME_REGEX = /<[A-Z][a-zA-Z\d]*/g;
32
+ var COMPONENT_PROP_REGEX = /\s[a-z][a-z\d]*[A-Z]+[a-zA-Z\d]*(=|\s|>)/g;
32
33
  var COMPONENT_STUB_ATTR = "$tag-name";
34
+ var PROP_STUB_ATTR = "-$u";
35
+ var PROP_STUB_ATTR_REGEX = new RegExp(`${PROP_STUB_ATTR.replace("$", "\\$")}[a-z]`, "g");
33
36
  var CODE_META_STUB_ATTR = "$code-meta";
34
37
  (async () => {
35
38
  ({ visit } = await import("unist-util-visit"));
@@ -44,6 +47,9 @@ function rehypeRaw(opts) {
44
47
  const tagName = str.slice(1);
45
48
  return `${str} ${COMPONENT_STUB_ATTR}="${tagName}"`;
46
49
  });
50
+ node.value = node.value.replace(COMPONENT_PROP_REGEX, (str) => {
51
+ return str.replace(/[A-Z]/g, (s) => `${PROP_STUB_ATTR}${s.toLowerCase()}`);
52
+ });
47
53
  } else if (node.type === "element" && ((_a = node.data) == null ? void 0 : _a.meta)) {
48
54
  node.properties ?? (node.properties = {});
49
55
  node.properties[CODE_META_STUB_ATTR] = node.data.meta;
@@ -63,6 +69,14 @@ File: ${opts.fileAbsPath}`);
63
69
  node.data = { meta: node.properties[CODE_META_STUB_ATTR] };
64
70
  delete node.properties[CODE_META_STUB_ATTR];
65
71
  }
72
+ Object.keys(node.properties || {}).forEach((p) => {
73
+ if (PROP_STUB_ATTR_REGEX.test(p)) {
74
+ const originalName = p.replace(PROP_STUB_ATTR_REGEX, (s) => s.slice(PROP_STUB_ATTR.length).toUpperCase());
75
+ node.properties[originalName] = node.properties[p];
76
+ node.properties[originalName.toLowerCase()] = node.properties[p];
77
+ delete node.properties[p];
78
+ }
79
+ });
66
80
  });
67
81
  return newTree;
68
82
  };
package/dist/types.d.ts CHANGED
@@ -50,6 +50,7 @@ export declare type IDumiUserConfig = Subset<Omit<IDumiConfig, 'locales'>> & {
50
50
  }>[] | Omit<Exclude<IDumiConfig['locales'][0], {
51
51
  suffix: string;
52
52
  }>, 'base'>[];
53
+ [key: string]: any;
53
54
  };
54
55
  export declare abstract class IDumiTechStack {
55
56
  /**
@@ -82,7 +83,9 @@ export declare abstract class IDumiTechStack {
82
83
  }): Promise<IDumiDemoProps['previewerProps']> | IDumiDemoProps['previewerProps'];
83
84
  }
84
85
  export declare type IApi = IUmiApi & {
85
- config: IDumiConfig;
86
+ config: IDumiConfig & {
87
+ [key: string]: any;
88
+ };
86
89
  userConfig: IDumiUserConfig;
87
90
  service: IUmiApi['service'] & {
88
91
  themeData: IThemeLoadResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -1,5 +1,9 @@
1
1
  @import (reference) '../../styles/variables.less';
2
2
 
3
+ @{dark-selector} {
4
+ color-scheme: dark;
5
+ }
6
+
3
7
  body {
4
8
  margin: 0;
5
9
  padding: 0;
@@ -10,7 +10,7 @@ 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 { FormattedMessage, useIntl, usePrefersColor } from 'dumi';
13
+ import { FormattedMessage, useIntl, usePrefersColor, useSiteData } from 'dumi';
14
14
  import React from 'react';
15
15
  import "./index.less";
16
16
 
@@ -45,11 +45,15 @@ var ICON_MAPPING = {
45
45
  };
46
46
 
47
47
  var ColorSwitch = function ColorSwitch() {
48
+ var _useSiteData = useSiteData(),
49
+ defaultColor = _useSiteData.themeConfig.prefersColor.default;
50
+
48
51
  var intl = useIntl();
49
52
 
50
53
  var _usePrefersColor = usePrefersColor(),
51
54
  _usePrefersColor2 = _slicedToArray(_usePrefersColor, 3),
52
- prefersColor = _usePrefersColor2[1],
55
+ _usePrefersColor2$ = _usePrefersColor2[1],
56
+ prefersColor = _usePrefersColor2$ === void 0 ? defaultColor : _usePrefersColor2$,
53
57
  setPrefersColor = _usePrefersColor2[2];
54
58
 
55
59
  var Icon = ICON_MAPPING[prefersColor];
@@ -28,7 +28,9 @@ var ContentTabs = function ContentTabs(_ref) {
28
28
  "data-active": key === tab.key || undefined
29
29
  }, /*#__PURE__*/React.createElement("button", {
30
30
  type: "button"
31
- }, tab.meta.frontmatter.title));
31
+ }, tab.nameIntlId ? intl.formatMessage({
32
+ id: tab.nameIntlId
33
+ }) : tab.name || tab.meta.frontmatter.title));
32
34
  })) : null;
33
35
  };
34
36
 
@@ -20,7 +20,9 @@ function getTargetLocalePath(_ref) {
20
20
  current = _ref.current,
21
21
  target = _ref.target;
22
22
  var clearPath = 'base' in current ? pathname.replace(current.base.replace(/\/$/, ''), '') : pathname.replace(new RegExp("".concat(current.suffix, "$")), '');
23
- return 'base' in target ? "".concat(target.base).concat(clearPath).replace(/^\/\//, '/') : "".concat(clearPath).concat(target.suffix);
23
+ return 'base' in target ? "".concat( // for `/` base, strip duplicated leading slash
24
+ target.base.replace(/\/$/, '')).concat(clearPath) // for `/` clearPath, strip duplicated ending slash
25
+ .replace(/([^/])\/$/, '$1') : "".concat(clearPath).concat(target.suffix);
24
26
  }
25
27
 
26
28
  var SingleSwitch = function SingleSwitch(_ref2) {
@@ -62,7 +62,7 @@ var PreviewerActions = function PreviewerActions(props) {
62
62
  activeKey = _useState2[0],
63
63
  setActiveKey = _useState2[1];
64
64
 
65
- var _useState3 = useState(props === null || props === void 0 ? void 0 : props.forceShowCode),
65
+ var _useState3 = useState(props.forceShowCode || props.defaultShowCode),
66
66
  _useState4 = _slicedToArray(_useState3, 2),
67
67
  showCode = _useState4[0],
68
68
  setShowCode = _useState4[1];