dumi 2.2.7 → 2.3.0-alpha.1

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 (39) hide show
  1. package/dist/client/pages/Demo/index.js +3 -4
  2. package/dist/client/theme-api/DumiDemo/DemoErrorBoundary.d.ts +5 -0
  3. package/dist/client/theme-api/DumiDemo/DemoErrorBoundary.js +16 -0
  4. package/dist/client/theme-api/{DumiDemo.d.ts → DumiDemo/index.d.ts} +1 -1
  5. package/dist/client/theme-api/DumiDemo/index.js +37 -0
  6. package/dist/client/theme-api/DumiDemoGrid.js +4 -1
  7. package/dist/client/theme-api/{context.d.ts → context/index.d.ts} +11 -7
  8. package/dist/client/theme-api/context/index.js +50 -0
  9. package/dist/client/theme-api/context/use.d.ts +10 -0
  10. package/dist/client/theme-api/context/use.js +25 -0
  11. package/dist/client/theme-api/index.d.ts +2 -2
  12. package/dist/client/theme-api/index.js +2 -2
  13. package/dist/client/theme-api/useRouteMeta.js +27 -26
  14. package/dist/client/theme-api/useSiteSearch/index.js +31 -13
  15. package/dist/client/theme-api/useSiteSearch/useSearchData.d.ts +9 -0
  16. package/dist/client/theme-api/useSiteSearch/useSearchData.js +76 -0
  17. package/dist/constants.d.ts +1 -0
  18. package/dist/constants.js +4 -0
  19. package/dist/features/compile/index.js +13 -1
  20. package/dist/features/exports.js +3 -1
  21. package/dist/features/meta.js +41 -76
  22. package/dist/features/theme/index.js +19 -55
  23. package/dist/loaders/markdown/index.d.ts +15 -3
  24. package/dist/loaders/markdown/index.js +117 -38
  25. package/dist/templates/ContextWrapper.ts.tpl +92 -0
  26. package/dist/templates/meta-demos.ts.tpl +34 -0
  27. package/dist/templates/meta-frontmatter.ts.tpl +9 -0
  28. package/dist/templates/meta-route.ts.tpl +43 -0
  29. package/dist/templates/meta-runtime.ts.tpl +48 -0
  30. package/dist/templates/meta-search.ts.tpl +43 -0
  31. package/index.d.ts +3 -0
  32. package/package.json +2 -1
  33. package/theme-default/locales/en-US.json +1 -0
  34. package/theme-default/locales/zh-CN.json +1 -0
  35. package/theme-default/slots/ContentTabs/index.js +0 -1
  36. package/theme-default/slots/SearchBar/index.js +3 -3
  37. package/theme-default/slots/SearchResult/index.js +34 -22
  38. package/dist/client/theme-api/DumiDemo.js +0 -46
  39. package/dist/client/theme-api/context.js +0 -16
@@ -0,0 +1,43 @@
1
+ // This will bundle all the site demos and meta data into one file
2
+ // which should only async load on search
3
+ const filesMetaTabs = {
4
+ {{#metaFiles}}
5
+ {{#tabs}}
6
+ '{{{id}}}': {{{tabs}}},
7
+ {{/tabs}}
8
+ {{/metaFiles}}
9
+ }
10
+
11
+ // generate demos data in runtime, for reuse route.id to reduce bundle size
12
+ export const demos = {};
13
+
14
+ /** @private Internal usage. Safe to refactor. */
15
+ export async function loadFilesMeta() {
16
+ const metaMap: Record<string, any> = {};
17
+ const idList = [
18
+ {{#metaFiles}}
19
+ '{{{id}}}',
20
+ {{/metaFiles}}
21
+ ];
22
+
23
+ {{#metaFiles}}
24
+ metaMap['{{{id}}}'] = import('{{{file}}}?type=meta');
25
+ {{/metaFiles}}
26
+
27
+ // Wait for all meta data to be loaded
28
+ const metaList = await Promise.all(idList.map(id => metaMap[id]));
29
+
30
+ // Merge into filesMeta
31
+ const filesMeta = {};
32
+
33
+ idList.forEach((id, index) => {
34
+ const meta = metaList[index];
35
+
36
+ filesMeta[id] = {
37
+ ...meta,
38
+ tabs: filesMetaTabs[id],
39
+ };
40
+ });
41
+
42
+ return filesMeta;
43
+ }
package/index.d.ts CHANGED
@@ -9,3 +9,6 @@ export * from './dist';
9
9
  export { defineConfig } from './dist';
10
10
  export * from './dist/client/theme-api';
11
11
  export { IApi } from './dist/types';
12
+ export function getRouteMetaById(id: string): Promise<any>;
13
+ /** @private Internal usage. Safe to remove */
14
+ export function loadFilesMeta(): Promise<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.2.7",
3
+ "version": "2.3.0-alpha.1",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -117,6 +117,7 @@
117
117
  "rc-motion": "^2.7.3",
118
118
  "rc-tabs": "^12.10.0",
119
119
  "rc-tree": "^5.7.9",
120
+ "rc-util": "^5.37.0",
120
121
  "react-copy-to-clipboard": "^5.1.0",
121
122
  "react-error-boundary": "^4.0.10",
122
123
  "react-intl": "^6.4.4",
@@ -38,5 +38,6 @@
38
38
  "content.footer.actions.previous": "PREV",
39
39
  "content.footer.actions.next": "NEXT",
40
40
  "search.not.found": "No content was found",
41
+ "search.loading": "Loading...",
41
42
  "layout.sidebar.btn": "Sidebar"
42
43
  }
@@ -37,5 +37,6 @@
37
37
  "content.footer.actions.previous": "上一篇",
38
38
  "content.footer.actions.next": "下一篇",
39
39
  "search.not.found": "未找到相关内容",
40
+ "search.loading": "加载中...",
40
41
  "layout.sidebar.btn": "侧边菜单"
41
42
  }
@@ -8,7 +8,6 @@ var ContentTabs = function ContentTabs(_ref) {
8
8
  var intl = useIntl();
9
9
 
10
10
  // TODO: tab.Extra & tab.Action render
11
-
12
11
  return Boolean(tabs === null || tabs === void 0 ? void 0 : tabs.length) ? /*#__PURE__*/React.createElement("ul", {
13
12
  className: "dumi-default-content-tabs"
14
13
  }, /*#__PURE__*/React.createElement("li", {
@@ -9,11 +9,11 @@ import { ReactComponent as IconArrowDown } from '@ant-design/icons-svg/inline-sv
9
9
  import { ReactComponent as IconArrowUp } from '@ant-design/icons-svg/inline-svg/outlined/arrow-up.svg';
10
10
  import { ReactComponent as IconSearch } from '@ant-design/icons-svg/inline-svg/outlined/search.svg';
11
11
  import { useSiteSearch } from 'dumi';
12
- import React, { useEffect, useRef, useState } from 'react';
13
12
  import SearchResult from 'dumi/theme/slots/SearchResult';
14
- import "./index.less";
13
+ import React, { useEffect, useRef, useState } from 'react';
15
14
  import { Input } from "./Input";
16
15
  import { Mask } from "./Mask";
16
+ import "./index.less";
17
17
  export { Input as SearchInput } from "./Input";
18
18
  export { Mask as SearchMask } from "./Mask";
19
19
  var isAppleDevice = /(mac|iphone|ipod|ipad)/i.test(typeof navigator !== 'undefined' ? (_navigator = navigator) === null || _navigator === void 0 ? void 0 : _navigator.platform : '');
@@ -100,7 +100,7 @@ var SearchBar = function SearchBar() {
100
100
  ref: inputRef
101
101
  }), /*#__PURE__*/React.createElement("span", {
102
102
  className: "dumi-default-search-shortcut"
103
- }, symbol, " K"), keywords.trim() && focusing && (result.length || !loading) && !modalVisible && /*#__PURE__*/React.createElement("div", {
103
+ }, symbol, " K"), keywords.trim() && focusing && !modalVisible && /*#__PURE__*/React.createElement("div", {
104
104
  className: "dumi-default-search-popover"
105
105
  }, /*#__PURE__*/React.createElement("section", null, /*#__PURE__*/React.createElement(SearchResult, {
106
106
  data: result,
@@ -123,6 +123,39 @@ var SearchResult = function SearchResult(props) {
123
123
  return document.removeEventListener('keydown', handler);
124
124
  };
125
125
  });
126
+ var returnNode = null;
127
+ if (props.loading) {
128
+ returnNode = /*#__PURE__*/React.createElement("div", {
129
+ className: "dumi-default-search-empty"
130
+ }, /*#__PURE__*/React.createElement(IconInbox, null), /*#__PURE__*/React.createElement(FormattedMessage, {
131
+ id: "search.loading"
132
+ }));
133
+ } else if (props.data.length) {
134
+ returnNode = /*#__PURE__*/React.createElement("dl", null, data.map(function (item, i) {
135
+ return item.type === 'title' ? /*#__PURE__*/React.createElement("dt", {
136
+ key: String(i)
137
+ }, item.value.title) : /*#__PURE__*/React.createElement("dd", {
138
+ key: String(i)
139
+ }, /*#__PURE__*/React.createElement(Link, {
140
+ to: item.value.link,
141
+ "data-active": activeIndex === item.activeIndex || undefined,
142
+ onClick: function onClick() {
143
+ var _props$onItemSelect2;
144
+ return (_props$onItemSelect2 = props.onItemSelect) === null || _props$onItemSelect2 === void 0 ? void 0 : _props$onItemSelect2.call(props, item.value);
145
+ }
146
+ }, /*#__PURE__*/React.createElement(ICONS_MAPPING[item.value.type]), /*#__PURE__*/React.createElement("h4", null, /*#__PURE__*/React.createElement(Highlight, {
147
+ texts: item.value.highlightTitleTexts
148
+ })), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(Highlight, {
149
+ texts: item.value.highlightTexts
150
+ }))));
151
+ }));
152
+ } else {
153
+ returnNode = /*#__PURE__*/React.createElement("div", {
154
+ className: "dumi-default-search-empty"
155
+ }, /*#__PURE__*/React.createElement(IconInbox, null), /*#__PURE__*/React.createElement(FormattedMessage, {
156
+ id: "search.not.found"
157
+ }));
158
+ }
126
159
  return /*#__PURE__*/React.createElement("div", {
127
160
  className: "dumi-default-search-result",
128
161
  onMouseEnter: function onMouseEnter() {
@@ -136,27 +169,6 @@ var SearchResult = function SearchResult(props) {
136
169
  onMouseUpCapture: function onMouseUpCapture() {
137
170
  document.activeElement.blur();
138
171
  }
139
- }, Boolean(props.data.length || props.loading) ? /*#__PURE__*/React.createElement("dl", null, data.map(function (item, i) {
140
- return item.type === 'title' ? /*#__PURE__*/React.createElement("dt", {
141
- key: String(i)
142
- }, item.value.title) : /*#__PURE__*/React.createElement("dd", {
143
- key: String(i)
144
- }, /*#__PURE__*/React.createElement(Link, {
145
- to: item.value.link,
146
- "data-active": activeIndex === item.activeIndex || undefined,
147
- onClick: function onClick() {
148
- var _props$onItemSelect2;
149
- return (_props$onItemSelect2 = props.onItemSelect) === null || _props$onItemSelect2 === void 0 ? void 0 : _props$onItemSelect2.call(props, item.value);
150
- }
151
- }, /*#__PURE__*/React.createElement(ICONS_MAPPING[item.value.type]), /*#__PURE__*/React.createElement("h4", null, /*#__PURE__*/React.createElement(Highlight, {
152
- texts: item.value.highlightTitleTexts
153
- })), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement(Highlight, {
154
- texts: item.value.highlightTexts
155
- }))));
156
- })) : /*#__PURE__*/React.createElement("div", {
157
- className: "dumi-default-search-empty"
158
- }, /*#__PURE__*/React.createElement(IconInbox, null), /*#__PURE__*/React.createElement(FormattedMessage, {
159
- id: "search.not.found"
160
- })));
172
+ }, returnNode);
161
173
  };
162
174
  export default SearchResult;
@@ -1,46 +0,0 @@
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
- import { SP_ROUTE_PREFIX } from "../../constants";
3
- import { useAppData, useSiteData } from 'dumi';
4
- import Container from 'dumi/theme/builtins/Container';
5
- import Previewer from 'dumi/theme/builtins/Previewer';
6
- import React, { createElement } from 'react';
7
- import { ErrorBoundary } from 'react-error-boundary';
8
- var DemoErrorBoundary = function DemoErrorBoundary(props) {
9
- return /*#__PURE__*/React.createElement(ErrorBoundary, {
10
- fallbackRender: function fallbackRender(_ref) {
11
- var error = _ref.error;
12
- return /*#__PURE__*/React.createElement(Container, {
13
- type: "error"
14
- }, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("strong", null, error.message || 'This demo has been crashed.')), error.stack && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("details", {
15
- open: true
16
- }, /*#__PURE__*/React.createElement("summary", null, "Error stack"), /*#__PURE__*/React.createElement("pre", null, error.stack))));
17
- }
18
- }, props.children);
19
- };
20
- export var DumiDemo = /*#__PURE__*/React.memo(function (props) {
21
- var _useSiteData = useSiteData(),
22
- demos = _useSiteData.demos,
23
- historyType = _useSiteData.historyType;
24
- var _useAppData = useAppData(),
25
- basename = _useAppData.basename;
26
- var _demos$props$demo$id = demos[props.demo.id],
27
- component = _demos$props$demo$id.component,
28
- asset = _demos$props$demo$id.asset;
29
-
30
- // hide debug demo in production
31
- if (process.env.NODE_ENV === 'production' && props.previewerProps.debug) return null;
32
- if (props.demo.inline) {
33
- return /*#__PURE__*/React.createElement(DemoErrorBoundary, null, /*#__PURE__*/createElement(component));
34
- }
35
- var isHashRoute = historyType === 'hash';
36
- return /*#__PURE__*/React.createElement(Previewer, _extends({
37
- asset: asset,
38
- demoUrl:
39
- // allow user override demoUrl by frontmatter
40
- props.previewerProps.demoUrl || // when use hash route, browser can automatically handle relative paths starting with #
41
- "".concat(isHashRoute ? "#" : '').concat(basename).concat(SP_ROUTE_PREFIX, "demos/").concat(props.demo.id)
42
- }, props.previewerProps), props.previewerProps.iframe ? null : /*#__PURE__*/React.createElement(DemoErrorBoundary, null, /*#__PURE__*/createElement(component)));
43
- }, function (prev, next) {
44
- // compare length for performance
45
- return JSON.stringify(prev).length === JSON.stringify(next).length;
46
- });
@@ -1,16 +0,0 @@
1
- import { createContext, useContext } from 'react';
2
- export var SiteContext = /*#__PURE__*/createContext({
3
- pkg: {},
4
- historyType: 'browser',
5
- entryExports: {},
6
- demos: {},
7
- components: {},
8
- locales: [],
9
- themeConfig: {},
10
- loading: false,
11
- setLoading: function setLoading() {},
12
- _2_level_nav_available: true
13
- });
14
- export var useSiteData = function useSiteData() {
15
- return useContext(SiteContext);
16
- };