@blocklet/ui-react 2.1.41 → 2.1.42

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.
@@ -0,0 +1,98 @@
1
+ import { mapRecursive } from './utils';
2
+
3
+ export const publicPath = window?.blocklet?.prefix || '/';
4
+
5
+ /**
6
+ * 格式化 theme (目前仅考虑 background)
7
+ */
8
+ export const formatTheme = (theme) => {
9
+ const formatted = { ...theme };
10
+ const background = theme?.background;
11
+ if (typeof background === 'string') {
12
+ formatted.background = { header: background, footer: background, default: background };
13
+ } else if (background && typeof background === 'object') {
14
+ formatted.background = {
15
+ header: background.header || background.default,
16
+ footer: background.footer || background.default,
17
+ default: background.default,
18
+ };
19
+ }
20
+ return formatted;
21
+ };
22
+
23
+ /**
24
+ * 获取指定 locale 对应的 navigation 数据, 仅考虑 zh/en
25
+ */
26
+ export const getLocalizedNavigation = (navigation, locale = 'en') => {
27
+ if (!navigation?.length) {
28
+ return navigation;
29
+ }
30
+ // eslint-disable-next-line no-shadow
31
+ const getTitle = (title, locale) => {
32
+ if (typeof title === 'string') {
33
+ return title;
34
+ }
35
+ if (typeof title === 'object') {
36
+ return title[locale] || title?.en || title?.zh;
37
+ }
38
+ return title;
39
+ };
40
+ return mapRecursive(
41
+ navigation,
42
+ (item) => {
43
+ return {
44
+ ...item,
45
+ title: getTitle(item.title, locale),
46
+ };
47
+ },
48
+ 'items'
49
+ );
50
+ };
51
+
52
+ export const parseNavigation = (navigation) => {
53
+ if (!navigation?.length) {
54
+ return null;
55
+ }
56
+
57
+ const sections = {
58
+ header: [],
59
+ footer: [],
60
+ // 对应 footer social media
61
+ social: [],
62
+ // 对应 footer 底部 links
63
+ bottom: [],
64
+ };
65
+
66
+ // 对 navigation 顶层元素按 section 分组
67
+ navigation.forEach((item) => {
68
+ // item#section 为空时, 表示只存在于 header
69
+ if (!item.section) {
70
+ sections.header.push(item);
71
+ // item 出现在指定几个 section 中 (array)
72
+ } else if (Array.isArray(item.section)) {
73
+ item.section.forEach((sectionKey) => {
74
+ sections[sectionKey]?.push(item);
75
+ });
76
+ // item 出现在指定的一个 section 中 (string)
77
+ } else if (typeof item.section === 'string') {
78
+ sections[item.section]?.push(item);
79
+ }
80
+ });
81
+
82
+ return sections;
83
+ };
84
+
85
+ /**
86
+ * 格式化 blocklet info 数据
87
+ */
88
+ export const formatBlockletInfo = (blockletInfo) => {
89
+ if (!blockletInfo) {
90
+ return null;
91
+ }
92
+ const formatted = { ...blockletInfo };
93
+ // theme
94
+ formatted.theme = formatTheme(formatted.theme);
95
+ // navigation
96
+ formatted.navigation = parseNavigation(formatted.navigation);
97
+ return formatted;
98
+ };
package/src/types.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import PropTypes from 'prop-types';
3
3
 
4
4
  export const blockletMetaProps = PropTypes.shape({
5
- appLogo: PropTypes.string,
5
+ appLogo: PropTypes.node,
6
6
  appName: PropTypes.string,
7
7
  theme: PropTypes.shape({
8
8
  background: PropTypes.string,
@@ -11,12 +11,12 @@ export const blockletMetaProps = PropTypes.shape({
11
11
  enableLocale: PropTypes.bool,
12
12
  navigation: PropTypes.arrayOf(
13
13
  PropTypes.shape({
14
- title: PropTypes.string,
14
+ title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
15
15
  link: PropTypes.string,
16
16
  icon: PropTypes.string,
17
17
  items: PropTypes.arrayOf(
18
18
  PropTypes.shape({
19
- title: PropTypes.string,
19
+ title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
20
20
  link: PropTypes.string,
21
21
  })
22
22
  ),
package/src/utils.js CHANGED
@@ -17,6 +17,13 @@ export const flatRecursive = (array, childrenKey = 'children') => {
17
17
  return result;
18
18
  };
19
19
 
20
+ // 对有层级结构的 array 元素计数
21
+ export const countRecursive = (array, childrenKey = 'children') => {
22
+ let counter = 0;
23
+ mapRecursive(array, () => counter++, childrenKey);
24
+ return counter;
25
+ };
26
+
20
27
  // "http://", "https://", "//" 开头的 3 种情况
21
28
  export const isUrl = (str) => {
22
29
  return /^(https?:)?\/\//.test(str);
@@ -49,5 +56,3 @@ export const matchPaths = (paths = []) => {
49
56
  }, matched[0]);
50
57
  return mostSpecific.index;
51
58
  };
52
-
53
- export const publicPath = window?.blocklet?.prefix || '/';