dumi 2.1.1 → 2.1.3

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.
@@ -48,7 +48,8 @@ var AtomAssetsParser = class {
48
48
  async parse() {
49
49
  if (!this.parseDeferrer || this.unresolvedFiles.length) {
50
50
  this.parseDeferrer = (async () => {
51
- await this.parser.patch(this.unresolvedFiles.splice(0));
51
+ this.unresolvedFiles.splice(0);
52
+ await this.parser.patch([]);
52
53
  const resolver = new import_parser.SchemaResolver(await this.parser.parse());
53
54
  const result = {
54
55
  components: {},
@@ -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)) {
@@ -21,6 +21,10 @@ export interface IPreviewerProps {
21
21
  * debug mark (will only render in dev by default)
22
22
  */
23
23
  debug?: boolean;
24
+ /**
25
+ * display the source code or not by default
26
+ */
27
+ defaultShowCode?: boolean;
24
28
  /**
25
29
  * url for render current demo in a single page
26
30
  */
@@ -85,6 +89,7 @@ export interface IRouteMeta {
85
89
  };
86
90
  atomId?: string;
87
91
  filename?: string;
92
+ debug?: boolean;
88
93
  [key: string]: any;
89
94
  };
90
95
  toc: {
@@ -110,6 +115,8 @@ export interface IRouteMeta {
110
115
  }[];
111
116
  tabs?: {
112
117
  key: string;
118
+ name?: string;
119
+ nameIntlId?: string;
113
120
  components: {
114
121
  default: ComponentType;
115
122
  Extra: ComponentType;
@@ -136,15 +143,15 @@ export declare type ILocalesConfig = ILocale[];
136
143
  export interface INavItem {
137
144
  title: string;
138
145
  link: string;
139
- order: number;
146
+ order?: number;
140
147
  activePath?: string;
141
148
  [key: string]: any;
142
149
  }
143
150
  export interface ISidebarItem {
144
151
  title: string;
145
152
  link: string;
146
- order: number;
147
- frontmatter: IRouteMeta['frontmatter'];
153
+ order?: number;
154
+ frontmatter?: IRouteMeta['frontmatter'];
148
155
  [key: string]: any;
149
156
  }
150
157
  export interface ISidebarGroup {
@@ -161,7 +168,7 @@ export interface IThemeConfig {
161
168
  children?: INavItem[];
162
169
  })[]>;
163
170
  sidebar?: Record<string, ISidebarGroup[]>;
164
- footer?: string;
171
+ footer?: string | false;
165
172
  prefersColor: {
166
173
  default: 'light' | 'dark' | 'auto';
167
174
  switch: boolean;
@@ -47,7 +47,7 @@ function safeExcludeInMFSU(api, excludes) {
47
47
  var derivative_default = (api) => {
48
48
  api.describe({ key: "dumi:derivative" });
49
49
  api.onCheck(() => {
50
- var _a, _b;
50
+ var _a, _b, _c;
51
51
  (0, import_assert.default)(!api.config.mpa, "MPA mode is not supported in dumi!");
52
52
  (0, import_assert.default)(!api.config.vite, "Vite mode is not supported yet!");
53
53
  if (typeof api.config.mfsu === "object") {
@@ -61,12 +61,15 @@ var derivative_default = (api) => {
61
61
  }
62
62
  try {
63
63
  const tsconfig = require(import_path.default.join(api.cwd, "tsconfig.json"));
64
- const expected = [".dumi/**/*", ".dumirc.ts"];
64
+ const expected = [".dumi/**/*"];
65
+ if ((_c = api.service.configManager) == null ? void 0 : _c.mainConfigFile) {
66
+ expected.push((0, import_plugin_utils.winPath)(import_path.default.relative(api.cwd, api.service.configManager.mainConfigFile)));
67
+ }
65
68
  if (!expected.every((f) => {
66
69
  var _a2;
67
70
  return (_a2 = tsconfig.include) == null ? void 0 : _a2.includes(f);
68
71
  })) {
69
- import_plugin_utils.logger.warn("Please append `.dumi/**/*` & `.dumirc.ts` into `include` option of `tsconfig.json`, to make sure `defineConfig` works.");
72
+ import_plugin_utils.logger.warn(`Please append ${expected.map((e) => `\`${e}\``).join(" & ")} into \`include\` option of \`tsconfig.json\`, to make sure \`defineConfig\` works.`);
70
73
  }
71
74
  } catch {
72
75
  }
@@ -111,13 +111,19 @@ import deepmerge from '${(0, import_plugin_utils.winPath)(import_path.default.di
111
111
  export const patchRoutes = ({ routes }) => {
112
112
  Object.values(routes).forEach((route) => {
113
113
  if (filesMeta[route.id]) {
114
- route.meta = deepmerge(route.meta, filesMeta[route.id]);
114
+ if (process.env.NODE_ENV === 'production' && (route.meta?.frontmatter?.debug || filesMeta[route.id].frontmatter.debug)) {
115
+ // hide route in production which set hide frontmatter
116
+ delete routes[route.id];
117
+ } else {
118
+ // merge meta to route object
119
+ route.meta = deepmerge(route.meta, filesMeta[route.id]);
115
120
 
116
- // apply real tab data from id
117
- route.meta.tabs = route.meta.tabs?.map(id => ({
118
- ...tabs[id],
119
- meta: filesMeta[id],
120
- }));
121
+ // apply real tab data from id
122
+ route.meta.tabs = route.meta.tabs?.map(id => ({
123
+ ...tabs[id],
124
+ meta: filesMeta[id],
125
+ }));
126
+ }
121
127
  }
122
128
  });
123
129
  }
@@ -36,7 +36,11 @@ function normalizeDocDir(docDir) {
36
36
  return typeof docDir === "object" ? docDir : { dir: docDir };
37
37
  }
38
38
  function kebabCaseRoutePath(routePath) {
39
- return routePath.split("/").map((p) => import_plugin_utils.lodash.kebabCase(p)).join("/");
39
+ const replacer = (_, s1, s2, i) => {
40
+ const symbol = ["", "/"].includes(s1) || !i ? "" : "-";
41
+ return `${s1 || ""}${symbol}${s2.toLowerCase()}`;
42
+ };
43
+ return routePath.replace(/(.)?([A-Z][^A-Z/])/g, replacer).replace(/(.)?([A-Z]+)/g, replacer);
40
44
  }
41
45
  function localizeUmiRoute(route, locales) {
42
46
  const locale = locales.find((locale2) => route.path.endsWith(`/${locale2.id}`) && import_path.default.parse(route.file).name.endsWith(`.${locale2.id}`));
@@ -133,7 +137,7 @@ var routes_default = (api) => {
133
137
  const base = import_path.default.join(api.cwd, dir);
134
138
  const dirRoutes = (0, import_core.getConventionRoutes)({
135
139
  base,
136
- exclude: [/.*(?<!md)$/, /(\/|^)(\.|_\/)/]
140
+ exclude: [/.*(?<!md)$/, /(\/|^)(\.|_)/]
137
141
  });
138
142
  Object.entries(dirRoutes).forEach(([key, route]) => {
139
143
  route.id = `${dir}/${key}`;
@@ -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.1",
3
+ "version": "2.1.3",
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, useSiteData } from 'dumi';
13
+ import { useIntl, usePrefersColor, useSiteData } from 'dumi';
14
14
  import React from 'react';
15
15
  import "./index.less";
16
16
 
@@ -68,19 +68,14 @@ var ColorSwitch = function ColorSwitch() {
68
68
  return setPrefersColor(ev.target.value);
69
69
  },
70
70
  value: prefersColor
71
- }, /*#__PURE__*/React.createElement("option", {
72
- value: "light"
73
- }, /*#__PURE__*/React.createElement(FormattedMessage, {
74
- id: "header.color.mode.light"
75
- })), /*#__PURE__*/React.createElement("option", {
76
- value: "dark"
77
- }, /*#__PURE__*/React.createElement(FormattedMessage, {
78
- id: "header.color.mode.dark"
79
- })), /*#__PURE__*/React.createElement("option", {
80
- value: "auto"
81
- }, /*#__PURE__*/React.createElement(FormattedMessage, {
82
- id: "header.color.mode.auto"
83
- }))));
71
+ }, ['light', 'dark', 'auto'].map(function (c) {
72
+ return /*#__PURE__*/React.createElement("option", {
73
+ value: c,
74
+ key: c
75
+ }, intl.formatMessage({
76
+ id: "header.color.mode.".concat(c)
77
+ }));
78
+ })));
84
79
  };
85
80
 
86
81
  export default ColorSwitch;
@@ -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
 
@@ -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];
@@ -97,7 +97,7 @@ var PreviewerActions = function PreviewerActions(props) {
97
97
  "data-dumi-tooltip": intl.formatMessage({
98
98
  id: 'previewer.actions.separate'
99
99
  })
100
- }, /*#__PURE__*/React.createElement(IconExternalLink, null)), /*#__PURE__*/React.createElement(PreviewerActionsExtra, props), !(props !== null && props !== void 0 && props.forceShowCode) && /*#__PURE__*/React.createElement("button", {
100
+ }, /*#__PURE__*/React.createElement(IconExternalLink, null)), /*#__PURE__*/React.createElement(PreviewerActionsExtra, props), !props.forceShowCode && /*#__PURE__*/React.createElement("button", {
101
101
  className: "dumi-default-previewer-action-btn",
102
102
  type: "button",
103
103
  onClick: function onClick() {