dumi 2.0.0-alpha.2 → 2.0.0-alpha.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.
- package/dist/client/theme-api/DumiDemoGrid.js +2 -2
- package/dist/client/theme-api/context.d.ts +3 -2
- package/dist/client/theme-api/context.js +2 -1
- package/dist/client/theme-api/index.d.ts +3 -1
- package/dist/client/theme-api/index.js +3 -1
- package/dist/client/theme-api/types.d.ts +40 -3
- package/dist/client/theme-api/useNavData.d.ts +6 -0
- package/dist/client/theme-api/useNavData.js +78 -0
- package/dist/client/theme-api/{useMatchedRouteMeta.d.ts → useRouteMeta.d.ts} +1 -1
- package/dist/client/theme-api/{useMatchedRouteMeta.js → useRouteMeta.js} +2 -2
- package/dist/client/theme-api/useSidebarData.d.ts +8 -0
- package/dist/client/theme-api/useSidebarData.js +132 -0
- package/dist/client/theme-api/utils.d.ts +3 -0
- package/dist/client/theme-api/utils.js +62 -0
- package/dist/features/configPlugins/index.js +2 -1
- package/dist/features/configPlugins/schema.js +5 -1
- package/dist/features/locales.js +16 -8
- package/dist/features/routes.js +1 -1
- package/dist/features/theme/index.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/types.d.ts +7 -2
- package/package.json +3 -1
- package/theme-default/layouts/DocLayout/index.js +22 -1
|
@@ -12,11 +12,11 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
|
|
|
12
12
|
|
|
13
13
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { useRouteMeta } from 'dumi/theme';
|
|
16
16
|
import React, { useState } from 'react';
|
|
17
17
|
import { DumiDemo } from "./DumiDemo";
|
|
18
18
|
export var DumiDemoGrid = function DumiDemoGrid(props) {
|
|
19
|
-
var meta =
|
|
19
|
+
var meta = useRouteMeta();
|
|
20
20
|
|
|
21
21
|
var _useState = useState(function () {
|
|
22
22
|
var _meta$demo;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type ComponentType } from 'react';
|
|
2
|
-
import type { ILocalesConfig, IPreviewerProps } from './types';
|
|
2
|
+
import type { ILocalesConfig, IPreviewerProps, IThemeConfig } from './types';
|
|
3
3
|
export interface IThemeContext {
|
|
4
4
|
demos: Record<string, {
|
|
5
5
|
component: ComponentType;
|
|
6
6
|
asset: IPreviewerProps['asset'];
|
|
7
7
|
}>;
|
|
8
|
-
locales: ILocalesConfig
|
|
8
|
+
locales: NonNullable<ILocalesConfig>;
|
|
9
|
+
themeConfig: IThemeConfig;
|
|
9
10
|
}
|
|
10
11
|
export declare const Context: import("react").Context<IThemeContext>;
|
|
@@ -24,10 +24,17 @@ export interface IPreviewerProps {
|
|
|
24
24
|
[key: string]: any;
|
|
25
25
|
}
|
|
26
26
|
export interface IRouteMeta {
|
|
27
|
-
title
|
|
27
|
+
title: string;
|
|
28
28
|
description?: string;
|
|
29
29
|
keywords?: string[];
|
|
30
|
-
|
|
30
|
+
nav?: string | {
|
|
31
|
+
title?: string;
|
|
32
|
+
order?: number;
|
|
33
|
+
};
|
|
34
|
+
group?: string | {
|
|
35
|
+
title?: string;
|
|
36
|
+
order?: number;
|
|
37
|
+
};
|
|
31
38
|
order?: number;
|
|
32
39
|
toc?: boolean | 'content' | 'menu';
|
|
33
40
|
demo?: {
|
|
@@ -40,8 +47,38 @@ declare type IBasicLocale = {
|
|
|
40
47
|
name: string;
|
|
41
48
|
};
|
|
42
49
|
export declare type ILocalesConfig = ((IBasicLocale & {
|
|
43
|
-
base
|
|
50
|
+
base: string;
|
|
44
51
|
}) | (IBasicLocale & {
|
|
45
52
|
suffix: string;
|
|
46
53
|
}))[];
|
|
54
|
+
export interface INavItem {
|
|
55
|
+
title: string;
|
|
56
|
+
link: string;
|
|
57
|
+
[key: string]: any;
|
|
58
|
+
}
|
|
59
|
+
interface ISidebarItem {
|
|
60
|
+
title: string;
|
|
61
|
+
link: string;
|
|
62
|
+
[key: string]: any;
|
|
63
|
+
}
|
|
64
|
+
export interface ISidebarGroup {
|
|
65
|
+
title?: string;
|
|
66
|
+
children: ISidebarItem[];
|
|
67
|
+
[key: string]: any;
|
|
68
|
+
}
|
|
69
|
+
export interface IThemeConfig {
|
|
70
|
+
nav?: (INavItem & {
|
|
71
|
+
children?: INavItem[];
|
|
72
|
+
})[];
|
|
73
|
+
sidebar?: Record<string, ISidebarGroup[]>;
|
|
74
|
+
[key: string]: any;
|
|
75
|
+
}
|
|
76
|
+
export declare type IRoutesById = Record<string, {
|
|
77
|
+
path?: string;
|
|
78
|
+
parentId?: string;
|
|
79
|
+
meta?: IRouteMeta;
|
|
80
|
+
id: string;
|
|
81
|
+
redirect?: string;
|
|
82
|
+
[key: string]: any;
|
|
83
|
+
}>;
|
|
47
84
|
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
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); }
|
|
2
|
+
|
|
3
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
4
|
+
|
|
5
|
+
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."); }
|
|
6
|
+
|
|
7
|
+
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); }
|
|
8
|
+
|
|
9
|
+
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; }
|
|
10
|
+
|
|
11
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
12
|
+
|
|
13
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
14
|
+
|
|
15
|
+
import { Context } from 'dumi/theme';
|
|
16
|
+
import { useContext, useState } from 'react';
|
|
17
|
+
import { useFullSidebarData } from "./useSidebarData";
|
|
18
|
+
import { useLocaleDocRoutes } from "./utils";
|
|
19
|
+
/**
|
|
20
|
+
* hook for get nav data
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export var useNavData = function useNavData() {
|
|
24
|
+
var routes = useLocaleDocRoutes();
|
|
25
|
+
|
|
26
|
+
var _useContext = useContext(Context),
|
|
27
|
+
themeConfig = _useContext.themeConfig;
|
|
28
|
+
|
|
29
|
+
var sidebar = useFullSidebarData();
|
|
30
|
+
|
|
31
|
+
var _useState = useState(function () {
|
|
32
|
+
// use user config first
|
|
33
|
+
if (themeConfig.nav) return themeConfig.nav; // fallback to generate nav data from sidebar data
|
|
34
|
+
|
|
35
|
+
var data = Object.entries(sidebar).map(function (_ref) {
|
|
36
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
37
|
+
link = _ref2[0],
|
|
38
|
+
groups = _ref2[1];
|
|
39
|
+
|
|
40
|
+
var meta = Object.values(routes).reduce(function (ret, route) {
|
|
41
|
+
var _nav$order;
|
|
42
|
+
|
|
43
|
+
// find routes which within the nav path
|
|
44
|
+
if (route.path.startsWith(link.slice(1))) {
|
|
45
|
+
switch (_typeof(route.meta.nav)) {
|
|
46
|
+
case 'object':
|
|
47
|
+
ret.title = route.meta.nav.title || ret.title;
|
|
48
|
+
ret.order = (_nav$order = route.meta.nav.order) !== null && _nav$order !== void 0 ? _nav$order : ret.order;
|
|
49
|
+
break;
|
|
50
|
+
|
|
51
|
+
case 'string':
|
|
52
|
+
ret.title = route.meta.nav || ret.title;
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
default:
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return ret;
|
|
60
|
+
}, {});
|
|
61
|
+
return {
|
|
62
|
+
title: meta.title || groups[0].title || groups[0].children[0].title,
|
|
63
|
+
order: meta.order || 0,
|
|
64
|
+
link: groups[0].children[0].link
|
|
65
|
+
};
|
|
66
|
+
}); // TODO: 2-level nav data
|
|
67
|
+
|
|
68
|
+
return data.sort(function (a, b) {
|
|
69
|
+
var _a$title;
|
|
70
|
+
|
|
71
|
+
return a.order - b.order || ((_a$title = a.title) === null || _a$title === void 0 ? void 0 : _a$title.localeCompare(b.title));
|
|
72
|
+
});
|
|
73
|
+
}),
|
|
74
|
+
_useState2 = _slicedToArray(_useState, 1),
|
|
75
|
+
nav = _useState2[0];
|
|
76
|
+
|
|
77
|
+
return nav;
|
|
78
|
+
};
|
|
@@ -16,7 +16,7 @@ import { useCallback, useEffect, useState } from 'react';
|
|
|
16
16
|
/**
|
|
17
17
|
* hook for get matched route meta
|
|
18
18
|
*/
|
|
19
|
-
export var
|
|
19
|
+
export var useRouteMeta = function useRouteMeta() {
|
|
20
20
|
var _useRouteData = useRouteData(),
|
|
21
21
|
route = _useRouteData.route;
|
|
22
22
|
|
|
@@ -29,7 +29,7 @@ export var useMatchedRouteMeta = function useMatchedRouteMeta() {
|
|
|
29
29
|
var getter = useCallback(function () {
|
|
30
30
|
var ret;
|
|
31
31
|
|
|
32
|
-
if (route.path === pathname) {
|
|
32
|
+
if (route.path === pathname && !('isLayout' in route)) {
|
|
33
33
|
// use `useRouteData` result if matched, for performance
|
|
34
34
|
ret = route.meta;
|
|
35
35
|
} else {
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
2
|
+
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
|
|
7
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
8
|
+
|
|
9
|
+
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); }
|
|
10
|
+
|
|
11
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
12
|
+
|
|
13
|
+
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."); }
|
|
14
|
+
|
|
15
|
+
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); }
|
|
16
|
+
|
|
17
|
+
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; }
|
|
18
|
+
|
|
19
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
20
|
+
|
|
21
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
22
|
+
|
|
23
|
+
import { useLocation } from 'dumi';
|
|
24
|
+
import { Context } from 'dumi/theme';
|
|
25
|
+
import { useContext, useState } from 'react';
|
|
26
|
+
import { useLocale, useLocaleDocRoutes } from "./utils";
|
|
27
|
+
var DEFAULT_GROUP_STUB_TITLE = '$default-group-title';
|
|
28
|
+
|
|
29
|
+
var getLocaleClearPath = function getLocaleClearPath(routePath, locale) {
|
|
30
|
+
return 'base' in locale ? routePath.replace(locale.base.slice(1), '').replace(/^\//, '') : routePath;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* hook for get sidebar data for all nav
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export var useFullSidebarData = function useFullSidebarData() {
|
|
38
|
+
var locale = useLocale();
|
|
39
|
+
var routes = useLocaleDocRoutes();
|
|
40
|
+
|
|
41
|
+
var _useContext = useContext(Context),
|
|
42
|
+
themeConfig = _useContext.themeConfig;
|
|
43
|
+
|
|
44
|
+
var _useState = useState(function () {
|
|
45
|
+
// auto generate sidebar data from routes
|
|
46
|
+
var data = Object.values(routes).reduce(function (ret, route) {
|
|
47
|
+
var clearPath = getLocaleClearPath(route.path, locale); // skip index routes
|
|
48
|
+
|
|
49
|
+
if (clearPath) {
|
|
50
|
+
var _ret$parentPath, _ret$parentPath$title, _ret$parentPath$title2;
|
|
51
|
+
|
|
52
|
+
// extract parent path from route path
|
|
53
|
+
// a => /a
|
|
54
|
+
// en-US/a => /en-US/a
|
|
55
|
+
// a/b => /a
|
|
56
|
+
// en-US/a/b => /en-US/a
|
|
57
|
+
var parentPath = "/".concat(route.path.replace(/\/[^/]+$/, ''));
|
|
58
|
+
|
|
59
|
+
var _ref = _typeof(route.meta.group) === 'object' ? route.meta.group : {
|
|
60
|
+
title: route.meta.group
|
|
61
|
+
},
|
|
62
|
+
title = _ref.title,
|
|
63
|
+
_ref$order = _ref.order,
|
|
64
|
+
order = _ref$order === void 0 ? 0 : _ref$order;
|
|
65
|
+
|
|
66
|
+
var titleKey = title || DEFAULT_GROUP_STUB_TITLE; // create group data by nav path & group name
|
|
67
|
+
|
|
68
|
+
(_ret$parentPath = ret[parentPath]) !== null && _ret$parentPath !== void 0 ? _ret$parentPath : ret[parentPath] = {};
|
|
69
|
+
ret[parentPath][titleKey] = {
|
|
70
|
+
title: title,
|
|
71
|
+
order: ((_ret$parentPath$title = ret[parentPath][titleKey]) === null || _ret$parentPath$title === void 0 ? void 0 : _ret$parentPath$title.order) || order,
|
|
72
|
+
children: [].concat(_toConsumableArray(((_ret$parentPath$title2 = ret[parentPath][titleKey]) === null || _ret$parentPath$title2 === void 0 ? void 0 : _ret$parentPath$title2.children) || []), [{
|
|
73
|
+
title: route.meta.title,
|
|
74
|
+
link: "/".concat(route.path),
|
|
75
|
+
order: route.meta.order || 0
|
|
76
|
+
}])
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return ret;
|
|
81
|
+
}, {}); // destruct sidebar data into sidebar config
|
|
82
|
+
|
|
83
|
+
var sidebarConfig = Object.entries(data).reduce(function (ret, _ref2) {
|
|
84
|
+
var _ref3 = _slicedToArray(_ref2, 2),
|
|
85
|
+
navPath = _ref3[0],
|
|
86
|
+
groups = _ref3[1];
|
|
87
|
+
|
|
88
|
+
ret[navPath] = Object.values(groups).sort(function (a, b) {
|
|
89
|
+
var _a$title;
|
|
90
|
+
|
|
91
|
+
return (// sort by group order
|
|
92
|
+
a.order - b.order || (a.title ? // sort by group title
|
|
93
|
+
(_a$title = a.title) === null || _a$title === void 0 ? void 0 : _a$title.localeCompare(b.title || '') : // put non-title group at the end
|
|
94
|
+
-1)
|
|
95
|
+
);
|
|
96
|
+
}); // sort group children by order or title
|
|
97
|
+
|
|
98
|
+
ret[navPath].forEach(function (group) {
|
|
99
|
+
return group.children.sort(function (a, b) {
|
|
100
|
+
return a.order - b.order || a.title.localeCompare(b.title);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return ret;
|
|
104
|
+
}, {}); // allow user partial override
|
|
105
|
+
|
|
106
|
+
return Object.assign(sidebarConfig, themeConfig.sidebar);
|
|
107
|
+
}),
|
|
108
|
+
_useState2 = _slicedToArray(_useState, 1),
|
|
109
|
+
sidebar = _useState2[0];
|
|
110
|
+
|
|
111
|
+
return sidebar;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* hook for get sidebar data for current nav
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
export var useSidebarData = function useSidebarData() {
|
|
118
|
+
var locale = useLocale();
|
|
119
|
+
var sidebar = useFullSidebarData();
|
|
120
|
+
|
|
121
|
+
var _useLocation = useLocation(),
|
|
122
|
+
pathname = _useLocation.pathname;
|
|
123
|
+
|
|
124
|
+
var clearPath = getLocaleClearPath(pathname.slice(1), locale); // extract parent path from location pathname
|
|
125
|
+
// /a => /a
|
|
126
|
+
// /a/b => /a
|
|
127
|
+
// /en-US/a => /en-US/a
|
|
128
|
+
// /en-US/a/b => /en-US/a
|
|
129
|
+
|
|
130
|
+
var parentPath = clearPath ? pathname.replace(/(\/[^/]+)(\/[^/]+)$/, '$1') : pathname;
|
|
131
|
+
return parentPath ? sidebar[parentPath] : [];
|
|
132
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
|
|
3
|
+
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."); }
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
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; }
|
|
8
|
+
|
|
9
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
10
|
+
|
|
11
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
12
|
+
|
|
13
|
+
import { useAppData } from 'dumi';
|
|
14
|
+
import { Context, useIntl } from 'dumi/theme';
|
|
15
|
+
import { useContext, useState } from 'react';
|
|
16
|
+
export var useLocale = function useLocale() {
|
|
17
|
+
var intl = useIntl();
|
|
18
|
+
|
|
19
|
+
var _useContext = useContext(Context),
|
|
20
|
+
locales = _useContext.locales;
|
|
21
|
+
|
|
22
|
+
var _useState = useState(function () {
|
|
23
|
+
return locales.find(function (_ref) {
|
|
24
|
+
var id = _ref.id;
|
|
25
|
+
return id === intl.locale;
|
|
26
|
+
});
|
|
27
|
+
}),
|
|
28
|
+
_useState2 = _slicedToArray(_useState, 1),
|
|
29
|
+
locale = _useState2[0];
|
|
30
|
+
|
|
31
|
+
return locale;
|
|
32
|
+
};
|
|
33
|
+
export var useLocaleDocRoutes = function useLocaleDocRoutes() {
|
|
34
|
+
var intl = useIntl();
|
|
35
|
+
|
|
36
|
+
var _useAppData = useAppData(),
|
|
37
|
+
routes = _useAppData.routes;
|
|
38
|
+
|
|
39
|
+
var _useContext2 = useContext(Context),
|
|
40
|
+
locales = _useContext2.locales;
|
|
41
|
+
|
|
42
|
+
var _useState3 = useState(function () {
|
|
43
|
+
var reversedLocales = locales.slice().reverse();
|
|
44
|
+
return Object.values(routes).reduce(function (ret, route) {
|
|
45
|
+
var matched = reversedLocales.find(function (locale) {
|
|
46
|
+
return 'suffix' in locale ? // suffix mode
|
|
47
|
+
route.path.endsWith(locale.suffix) : // base mode
|
|
48
|
+
route.path.startsWith(locale.base.slice(1));
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (route.parentId === 'DocLayout' && matched.id === intl.locale) {
|
|
52
|
+
ret[route.id] = route;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return ret;
|
|
56
|
+
}, {});
|
|
57
|
+
}),
|
|
58
|
+
_useState4 = _slicedToArray(_useState3, 1),
|
|
59
|
+
localeDocRoutes = _useState4[0];
|
|
60
|
+
|
|
61
|
+
return localeDocRoutes;
|
|
62
|
+
};
|
|
@@ -29,7 +29,8 @@ var configPlugins_default = (api) => {
|
|
|
29
29
|
docDirs: ["docs"],
|
|
30
30
|
entityDirs: [{ type: "component", dir: "src" }],
|
|
31
31
|
codeBlockMode: "active"
|
|
32
|
-
}
|
|
32
|
+
},
|
|
33
|
+
themeConfig: {}
|
|
33
34
|
};
|
|
34
35
|
const schemas = (0, import_schema.getSchemas)();
|
|
35
36
|
for (const key of Object.keys(schemas)) {
|
|
@@ -33,7 +33,11 @@ function getSchemas() {
|
|
|
33
33
|
codeBlockMode: Joi.string().valid("active", "passive").optional()
|
|
34
34
|
}).optional(),
|
|
35
35
|
extraRemarkPlugins: getUnifiedPluginSchema,
|
|
36
|
-
extraRehypePlugins: getUnifiedPluginSchema
|
|
36
|
+
extraRehypePlugins: getUnifiedPluginSchema,
|
|
37
|
+
themeConfig: (Joi) => Joi.object({
|
|
38
|
+
nav: Joi.array().items(Joi.object()).optional(),
|
|
39
|
+
sidebar: Joi.object().optional()
|
|
40
|
+
}).optional()
|
|
37
41
|
};
|
|
38
42
|
}
|
|
39
43
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/features/locales.js
CHANGED
|
@@ -23,9 +23,16 @@ __export(locales_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(locales_exports);
|
|
25
25
|
var locales_default = (api) => {
|
|
26
|
+
var _a;
|
|
26
27
|
api.describe({
|
|
27
28
|
config: {
|
|
28
|
-
default: [
|
|
29
|
+
default: [
|
|
30
|
+
{
|
|
31
|
+
id: "zh-CN",
|
|
32
|
+
name: "\u4E2D\u6587",
|
|
33
|
+
...((_a = api.userConfig.locales) == null ? void 0 : _a[0]) && "suffix" in api.userConfig.locales[0] ? {} : { base: "/" }
|
|
34
|
+
}
|
|
35
|
+
],
|
|
29
36
|
schema: (Joi) => {
|
|
30
37
|
const basicOpts = { id: Joi.string(), name: Joi.string() };
|
|
31
38
|
return Joi.alternatives(Joi.array().items(Joi.object({
|
|
@@ -42,8 +49,8 @@ var locales_default = (api) => {
|
|
|
42
49
|
key: "modifyConfig",
|
|
43
50
|
stage: Infinity,
|
|
44
51
|
fn: (memo) => {
|
|
45
|
-
var
|
|
46
|
-
(
|
|
52
|
+
var _a2;
|
|
53
|
+
(_a2 = memo.locales) == null ? void 0 : _a2.forEach((locale, i) => {
|
|
47
54
|
if (!("suffix" in locale)) {
|
|
48
55
|
locale.base ?? (locale.base = i ? `/${locale.id}` : "/");
|
|
49
56
|
}
|
|
@@ -71,11 +78,12 @@ const cache = createIntlCache();
|
|
|
71
78
|
|
|
72
79
|
const LocalesContainer: FC<{ children: ReactNode }> = (props) => {
|
|
73
80
|
const [locale] = useState(() => {
|
|
74
|
-
const matched = locales.find((locale) => (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
const matched = locales.slice().reverse().find((locale) => (
|
|
82
|
+
'suffix' in locale
|
|
83
|
+
// suffix mode
|
|
84
|
+
? history.location.pathname.endsWith(locale.suffix)
|
|
85
|
+
// base mode
|
|
86
|
+
: history.location.pathname.startsWith(locale.base)
|
|
79
87
|
));
|
|
80
88
|
|
|
81
89
|
return matched ? matched.id : locales[0].id;
|
package/dist/features/routes.js
CHANGED
|
@@ -36,7 +36,7 @@ function localizeUmiRoute(route, locales) {
|
|
|
36
36
|
if (locale) {
|
|
37
37
|
const base = !("base" in locale) || locale.base === "/" ? "" : locale.base.replace(/^(\/)(.+)$/, "$2$1");
|
|
38
38
|
const suffix = "suffix" in locale ? locale.suffix : "";
|
|
39
|
-
route.path = `${base}${route.path.replace(new RegExp(`/${locale.id}$`), "").replace(/(
|
|
39
|
+
route.path = `${base}${route.path.replace(new RegExp(`/${locale.id}$`), "").replace(/((^|\/)(index|README))$/, "")}${suffix}`;
|
|
40
40
|
route.absPath = route.path !== "/" ? `/${route.path}` : route.path;
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -115,7 +115,7 @@ export default function DumiContextWrapper() {
|
|
|
115
115
|
const outlet = useOutlet();
|
|
116
116
|
|
|
117
117
|
return (
|
|
118
|
-
<Context.Provider value={{ demos, locales }}>{outlet}</Context.Provider>
|
|
118
|
+
<Context.Provider value={{ demos, locales, themeConfig: ${JSON.stringify(api.config.themeConfig)} }}>{outlet}</Context.Provider>
|
|
119
119
|
);
|
|
120
120
|
}`
|
|
121
121
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IDumiUserConfig } from "./types";
|
|
2
2
|
declare let unistUtilVisit: typeof import('unist-util-visit');
|
|
3
3
|
export { IApi } from "./types";
|
|
4
4
|
export type { Root as HastRoot } from 'hast';
|
|
5
5
|
export * from 'umi';
|
|
6
6
|
export type { Plugin as UnifiedPlugin, Transformer as UnifiedTransformer, } from 'unified';
|
|
7
7
|
export { unistUtilVisit };
|
|
8
|
-
export declare const defineConfig: (config:
|
|
8
|
+
export declare const defineConfig: (config: IDumiUserConfig) => IDumiUserConfig;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IDumiDemoProps, ILocalesConfig } from "./client/theme-api";
|
|
1
|
+
import type { IDumiDemoProps, ILocalesConfig, IThemeConfig } from "./client/theme-api";
|
|
2
2
|
import type { IThemeLoadResult } from "./features/theme/loader";
|
|
3
3
|
import type { IModify } from '@umijs/core';
|
|
4
4
|
import type { ExampleBlockAsset } from 'dumi-assets-types';
|
|
@@ -15,12 +15,17 @@ export interface IDumiConfig extends IUmiConfig {
|
|
|
15
15
|
codeBlockMode: 'active' | 'passive';
|
|
16
16
|
};
|
|
17
17
|
locales: ILocalesConfig;
|
|
18
|
+
themeConfig: IThemeConfig;
|
|
18
19
|
/**
|
|
19
20
|
* extra unified plugins
|
|
20
21
|
*/
|
|
21
22
|
extraRemarkPlugins?: (string | Function | [string | Function, object])[];
|
|
22
23
|
extraRehypePlugins?: (string | Function | [string | Function, object])[];
|
|
23
24
|
}
|
|
25
|
+
export interface IDumiUserConfig extends Partial<Omit<IDumiConfig, 'resolve' | 'locales'>> {
|
|
26
|
+
resolve?: Partial<IDumiConfig['resolve']>;
|
|
27
|
+
locales?: (IDumiConfig['locales'][0] | Omit<IDumiConfig['locales'][0], 'base'>)[];
|
|
28
|
+
}
|
|
24
29
|
export declare abstract class IDumiTechStack {
|
|
25
30
|
/**
|
|
26
31
|
* tech stack name, such as 'react'
|
|
@@ -53,7 +58,7 @@ export declare abstract class IDumiTechStack {
|
|
|
53
58
|
}
|
|
54
59
|
export declare type IApi = IUmiApi & {
|
|
55
60
|
config: IDumiConfig;
|
|
56
|
-
userConfig:
|
|
61
|
+
userConfig: IDumiUserConfig;
|
|
57
62
|
service: IUmiApi['service'] & {
|
|
58
63
|
themeData: IThemeLoadResult;
|
|
59
64
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dumi",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.3",
|
|
4
4
|
"description": "Framework for developing UI components",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"mdast-util-to-string": "^3.1.0",
|
|
64
64
|
"pluralize": "^8.0.0",
|
|
65
65
|
"raw-loader": "^4.0.2",
|
|
66
|
+
"react-helmet": "^6.1.0",
|
|
66
67
|
"react-intl": "^6.1.1",
|
|
67
68
|
"rehype-stringify": "^9.0.3",
|
|
68
69
|
"remark-breaks": "^3.0.2",
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
"@types/node": "^18.6.3",
|
|
87
88
|
"@types/pluralize": "^0.0.29",
|
|
88
89
|
"@types/react": "^18.0.16",
|
|
90
|
+
"@types/react-helmet": "^6.1.5",
|
|
89
91
|
"@umijs/lint": "^4.0.22",
|
|
90
92
|
"@umijs/test": "^4.0.22",
|
|
91
93
|
"cross-env": "^7.0.3",
|
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
import { useOutlet } from 'dumi';
|
|
2
|
+
import { useIntl, useRouteMeta } from 'dumi/theme';
|
|
2
3
|
import Content from 'dumi/theme/slots/Content';
|
|
3
4
|
import Header from 'dumi/theme/slots/Header';
|
|
4
5
|
import Sidebar from 'dumi/theme/slots/Sidebar';
|
|
5
6
|
import React from 'react';
|
|
7
|
+
import Helmet from 'react-helmet';
|
|
6
8
|
|
|
7
9
|
var DocLayout = function DocLayout() {
|
|
10
|
+
var intl = useIntl();
|
|
8
11
|
var outlet = useOutlet();
|
|
9
|
-
|
|
12
|
+
var meta = useRouteMeta();
|
|
13
|
+
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Helmet, null, /*#__PURE__*/React.createElement("html", {
|
|
14
|
+
lang: intl.locale.replace(/-.+$/, '')
|
|
15
|
+
}), meta.title && /*#__PURE__*/React.createElement("title", null, meta.title), meta.title && /*#__PURE__*/React.createElement("meta", {
|
|
16
|
+
property: "og:title",
|
|
17
|
+
content: meta.title
|
|
18
|
+
}), meta.description && /*#__PURE__*/React.createElement("meta", {
|
|
19
|
+
name: "description",
|
|
20
|
+
content: meta.description
|
|
21
|
+
}), meta.description && /*#__PURE__*/React.createElement("meta", {
|
|
22
|
+
property: "og:description",
|
|
23
|
+
content: meta.description
|
|
24
|
+
}), meta.keywords && /*#__PURE__*/React.createElement("meta", {
|
|
25
|
+
name: "keywords",
|
|
26
|
+
content: meta.keywords.join(',')
|
|
27
|
+
}), meta.keywords && /*#__PURE__*/React.createElement("meta", {
|
|
28
|
+
property: "og:keywords",
|
|
29
|
+
content: meta.keywords.join(',')
|
|
30
|
+
})), /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement("main", {
|
|
10
31
|
style: {
|
|
11
32
|
display: 'flex'
|
|
12
33
|
}
|