@blocklet/ui-react 2.4.2 → 2.4.5

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.
@@ -9,9 +9,7 @@ var _react = require("react");
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
- var _styled = _interopRequireDefault(require("@emotion/styled"));
13
-
14
- var _styles = require("@mui/material/styles");
12
+ var _Theme = require("@arcblock/ux/lib/Theme");
15
13
 
16
14
  var _jsxRuntime = require("react/jsx-runtime");
17
15
 
@@ -41,7 +39,7 @@ function Brand(_ref) {
41
39
  } = _ref,
42
40
  rest = _objectWithoutProperties(_ref, _excluded);
43
41
 
44
- const theme = (0, _styles.useTheme)();
42
+ const theme = (0, _Theme.useTheme)();
45
43
 
46
44
  if (!name && !logo && !description) {
47
45
  return null;
@@ -78,5 +76,4 @@ Brand.defaultProps = {
78
76
  logo: '',
79
77
  description: ''
80
78
  };
81
-
82
- const Root = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n font-size: 14px;\n a {\n text-decoration: none;\n color: inherit;\n }\n > div:first-child {\n display: flex;\n align-items: center;\n }\n .footer-brand-logo {\n display: flex;\n align-items: center;\n margin-right: 16px;\n line-height: 1;\n img,\n svg {\n width: auto;\n height: 44px;\n max-height: 44px;\n }\n }\n .footer-brand-name {\n font-size: 16px;\n font-weight: bold;\n }\n .footer-brand-desc {\n margin-top: 16px;\n }\n\n ", " {\n width: auto;\n }\n\n ", " {\n .footer-brand-logo {\n img,\n svg {\n height: 32px;\n max-height: 32px;\n }\n }\n }\n"])), props => props.$theme.breakpoints.down('sm'), props => props.$theme.breakpoints.down('md'));
79
+ const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n font-size: 14px;\n a {\n text-decoration: none;\n color: inherit;\n }\n > div:first-child {\n display: flex;\n align-items: center;\n }\n .footer-brand-logo {\n display: flex;\n align-items: center;\n margin-right: 16px;\n line-height: 1;\n img,\n svg {\n width: auto;\n height: 44px;\n max-height: 44px;\n }\n }\n .footer-brand-name {\n font-size: 16px;\n font-weight: bold;\n }\n .footer-brand-desc {\n margin-top: 16px;\n }\n\n ", " {\n width: auto;\n }\n\n ", " {\n .footer-brand-logo {\n img,\n svg {\n height: 32px;\n max-height: 32px;\n }\n }\n }\n"])), props => props.$theme.breakpoints.down('sm'), props => props.$theme.breakpoints.down('md'));
@@ -5,9 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = Copyright;
7
7
 
8
- var _propTypes = _interopRequireDefault(require("prop-types"));
8
+ var _Theme = require("@arcblock/ux/lib/Theme");
9
9
 
10
- var _styled = _interopRequireDefault(require("@emotion/styled"));
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
12
  var _jsxRuntime = require("react/jsx-runtime");
13
13
 
@@ -49,5 +49,4 @@ Copyright.defaultProps = {
49
49
  owner: 'ArcBlock, Inc.',
50
50
  year: "".concat(new Date().getFullYear())
51
51
  };
52
-
53
- const Root = _styled.default.p(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n margin: 0;\n font-size: 13px;\n"])));
52
+ const Root = (0, _Theme.styled)('p')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n align-items: center;\n margin: 0;\n font-size: 13px;\n"])));
@@ -7,9 +7,7 @@ exports.default = void 0;
7
7
 
8
8
  var _react = require("react");
9
9
 
10
- var _styled = _interopRequireDefault(require("@emotion/styled"));
11
-
12
- var _styles = require("@mui/material/styles");
10
+ var _Theme = require("@arcblock/ux/lib/Theme");
13
11
 
14
12
  var _reactErrorBoundary = require("react-error-boundary");
15
13
 
@@ -56,7 +54,7 @@ function Footer(_ref) {
56
54
  } = _ref,
57
55
  rest = _objectWithoutProperties(_ref, _excluded);
58
56
 
59
- const muiTheme = (0, _styles.useTheme)();
57
+ const muiTheme = (0, _Theme.useTheme)();
60
58
  const {
61
59
  locale
62
60
  } = (0, _context.useLocaleContext)() || {};
@@ -115,7 +113,7 @@ Footer.propTypes = {
115
113
  Footer.defaultProps = {
116
114
  meta: {}
117
115
  };
118
- const StyledInternalFooter = (0, _styled.default)(_internalFooter.default)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n border-top: 1px solid #eee;\n color: ", ";\n ", "\n font-family: Lato, Avenir, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,\n 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n"])), props => props.$theme.palette.grey[600], _ref2 => {
116
+ const StyledInternalFooter = (0, _Theme.styled)(_internalFooter.default)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n border-top: 1px solid #eee;\n color: ", ";\n ", "\n font-family: Lato, Avenir, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,\n 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n"])), props => props.$theme.palette.grey[600], _ref2 => {
119
117
  let {
120
118
  $bgcolor
121
119
  } = _ref2;
@@ -21,21 +21,22 @@ var _plain = _interopRequireDefault(require("./layout/plain"));
21
21
 
22
22
  var _jsxRuntime = require("react/jsx-runtime");
23
23
 
24
- const _excluded = ["brand", "navigation", "socialMedia", "copyright", "links"];
24
+ const _excluded = ["brand", "navigation", "socialMedia", "copyright", "links", "layout"];
25
25
 
26
26
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
27
 
28
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
29
+
30
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
31
+
28
32
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
29
33
 
30
34
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
31
35
 
32
36
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
33
37
 
34
- function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
35
-
36
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
37
-
38
38
  const layouts = [{
39
+ name: 'plain',
39
40
  // navigation 数据为空时, 使用简单布局
40
41
  support: (_, data) => {
41
42
  var _data$navigation;
@@ -44,10 +45,14 @@ const layouts = [{
44
45
  },
45
46
  component: _plain.default
46
47
  }, {
48
+ name: 'standard',
47
49
  // 默认标准布局
48
50
  support: () => true,
49
51
  component: _standard.default
50
52
  }];
53
+ const layoutsKeyByName = layouts.reduce((acc, cur) => _objectSpread(_objectSpread({}, acc), {}, {
54
+ [cur.name]: cur
55
+ }), {});
51
56
  /**
52
57
  * 通用的内部 footer 组件, 定义并渲染常见的几种 footer 元素: brand/navigation/social medial 等
53
58
  */
@@ -58,7 +63,8 @@ function InternalFooter(props) {
58
63
  navigation,
59
64
  socialMedia,
60
65
  copyright,
61
- links
66
+ links,
67
+ layout
62
68
  } = props,
63
69
  rest = _objectWithoutProperties(props, _excluded);
64
70
 
@@ -106,9 +112,23 @@ function InternalFooter(props) {
106
112
  copyright: renderCopyright(),
107
113
  links: renderLinks()
108
114
  };
109
- const LayoutComponent = layouts.find(layout => layout.support(elements, props)).component;
115
+ let LayoutComponent = null;
116
+
117
+ if (layout === 'auto') {
118
+ LayoutComponent = layouts.find(item => item.support(elements, props)).component;
119
+ } else {
120
+ var _layoutsKeyByName$lay;
121
+
122
+ LayoutComponent = (_layoutsKeyByName$lay = layoutsKeyByName[layout]) === null || _layoutsKeyByName$lay === void 0 ? void 0 : _layoutsKeyByName$lay.component;
123
+ }
124
+
125
+ if (!LayoutComponent) {
126
+ throw new Error("layout ".concat(layout, " is not supported."));
127
+ }
128
+
110
129
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(LayoutComponent, _objectSpread({
111
- elements: elements
130
+ elements: elements,
131
+ data: props
112
132
  }, rest));
113
133
  }
114
134
 
@@ -134,14 +154,17 @@ InternalFooter.propTypes = {
134
154
  links: _propTypes.default.arrayOf(_propTypes.default.shape({
135
155
  label: _propTypes.default.node,
136
156
  link: _propTypes.default.string
137
- }))
157
+ })),
158
+ // 可显式指定 footer layout, 默认根据内容自动决定 layout
159
+ layout: _propTypes.default.oneOf(['auto', 'standard', 'plain'])
138
160
  };
139
161
  InternalFooter.defaultProps = {
140
162
  brand: null,
141
163
  navigation: null,
142
164
  copyright: null,
143
165
  socialMedia: null,
144
- links: null
166
+ links: null,
167
+ layout: 'auto'
145
168
  };
146
169
  var _default = InternalFooter;
147
170
  exports.default = _default;
@@ -9,15 +9,17 @@ var _react = require("react");
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
- var _styled = _interopRequireDefault(require("@emotion/styled"));
13
-
14
12
  var _Container = _interopRequireDefault(require("@mui/material/Container"));
15
13
 
14
+ var _Theme = require("@arcblock/ux/lib/Theme");
15
+
16
+ var _row = _interopRequireDefault(require("./row"));
17
+
16
18
  var _jsxRuntime = require("react/jsx-runtime");
17
19
 
18
20
  var _templateObject;
19
21
 
20
- const _excluded = ["elements"];
22
+ const _excluded = ["elements", "data"];
21
23
 
22
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
25
 
@@ -38,17 +40,26 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
38
40
  */
39
41
  function PlainLayout(_ref) {
40
42
  let {
41
- elements
43
+ elements,
44
+ data
42
45
  } = _ref,
43
46
  rest = _objectWithoutProperties(_ref, _excluded);
44
47
 
45
48
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Root, _objectSpread(_objectSpread({}, rest), {}, {
46
49
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Container.default, {
47
50
  className: "plain-layout-container",
48
- children: [/*#__PURE__*/(0, _react.cloneElement)(elements.brand, {
49
- name: null,
50
- description: null
51
- }), elements.copyright]
51
+ children: [!!data.links && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_row.default, {
52
+ sx: {
53
+ width: 1
54
+ },
55
+ autoCenter: true,
56
+ children: [elements.copyright, elements.links]
57
+ }), !data.links && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
58
+ children: [/*#__PURE__*/(0, _react.cloneElement)(elements.brand, {
59
+ name: null,
60
+ description: null
61
+ }), elements.copyright]
62
+ })]
52
63
  })
53
64
  }));
54
65
  }
@@ -60,10 +71,9 @@ PlainLayout.propTypes = {
60
71
  socialMedia: _propTypes.default.element,
61
72
  copyright: _propTypes.default.element,
62
73
  links: _propTypes.default.element
63
- }).isRequired
74
+ }).isRequired,
75
+ data: _propTypes.default.object.isRequired
64
76
  };
65
-
66
- const Root = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: 24px 0;\n border-top: 1px solid #eee;\n .plain-layout-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n }\n"])));
67
-
77
+ const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: 24px 0;\n border-top: 1px solid #eee;\n .plain-layout-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n }\n"])));
68
78
  var _default = PlainLayout;
69
79
  exports.default = _default;
@@ -7,9 +7,9 @@ exports.default = Row;
7
7
 
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
 
10
- var _styled = _interopRequireDefault(require("@emotion/styled"));
10
+ var _Box = _interopRequireDefault(require("@mui/material/Box"));
11
11
 
12
- var _styles = require("@mui/material/styles");
12
+ var _Theme = require("@arcblock/ux/lib/Theme");
13
13
 
14
14
  var _clsx = _interopRequireDefault(require("clsx"));
15
15
 
@@ -40,7 +40,7 @@ function Row(_ref) {
40
40
  } = _ref,
41
41
  rest = _objectWithoutProperties(_ref, _excluded);
42
42
 
43
- const theme = (0, _styles.useTheme)();
43
+ const theme = (0, _Theme.useTheme)();
44
44
 
45
45
  if (!children) {
46
46
  return null;
@@ -63,5 +63,4 @@ Row.defaultProps = {
63
63
  children: null,
64
64
  autoCenter: false
65
65
  };
66
-
67
- const RowRoot = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n justify-content: space-between;\n & + & {\n margin-top: 24px;\n }\n &.footer-row-auto-center > *:only-child {\n margin: 0 auto;\n }\n\n ", " {\n align-items: stretch;\n flex-direction: column;\n gap: 16px;\n > * {\n flex: 1 0 100%;\n }\n &.footer-row-auto-center > * {\n margin: 0 auto;\n }\n }\n"])), props => props.$theme.breakpoints.down('md'));
66
+ const RowRoot = (0, _Theme.styled)(_Box.default)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n justify-content: space-between;\n & + & {\n margin-top: 24px;\n }\n &.footer-row-auto-center > *:only-child {\n margin: 0 auto;\n }\n\n ", " {\n align-items: stretch;\n flex-direction: column;\n gap: 16px;\n > * {\n flex: 1 0 100%;\n }\n &.footer-row-auto-center > * {\n margin: 0 auto;\n }\n }\n"])), props => props.$theme.breakpoints.down('md'));
@@ -7,19 +7,19 @@ exports.default = void 0;
7
7
 
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
 
10
- var _styled = _interopRequireDefault(require("@emotion/styled"));
11
-
12
10
  var _Box = _interopRequireDefault(require("@mui/material/Box"));
13
11
 
14
12
  var _Container = _interopRequireDefault(require("@mui/material/Container"));
15
13
 
14
+ var _Theme = require("@arcblock/ux/lib/Theme");
15
+
16
16
  var _row = _interopRequireDefault(require("./row"));
17
17
 
18
18
  var _jsxRuntime = require("react/jsx-runtime");
19
19
 
20
20
  var _templateObject;
21
21
 
22
- const _excluded = ["elements"];
22
+ const _excluded = ["elements", "data"];
23
23
 
24
24
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
25
 
@@ -38,48 +38,61 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
38
38
  /**
39
39
  * footer standard layout
40
40
  */
41
- function Footer(_ref) {
41
+ function StandardLayout(_ref) {
42
+ var _data$navigation;
43
+
42
44
  let {
43
- elements
45
+ elements,
46
+ data
44
47
  } = _ref,
45
48
  rest = _objectWithoutProperties(_ref, _excluded);
46
49
 
47
50
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Root, _objectSpread(_objectSpread({}, rest), {}, {
48
51
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Container.default, {
49
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_row.default, {
50
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
51
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
52
- width: {
53
- md: 240
54
- },
55
- children: elements.brand
56
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
57
- mt: 2,
58
- children: elements.socialMedia
59
- })]
60
- }), elements.navigation]
52
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
53
+ sx: {
54
+ display: 'flex',
55
+ justifyContent: 'space-between',
56
+ pb: 3
57
+ },
58
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
59
+ children: elements.brand
60
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
61
+ lineHeight: 1,
62
+ alignSelf: "end",
63
+ children: elements.socialMedia
64
+ })]
65
+ }), !!((_data$navigation = data.navigation) !== null && _data$navigation !== void 0 && _data$navigation.length) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
66
+ sx: {
67
+ mb: 6,
68
+ pt: 3,
69
+ borderTop: 1,
70
+ borderColor: 'grey.200'
71
+ },
72
+ children: elements.navigation
61
73
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_row.default, {
62
- autoCenter: true,
63
- style: {
64
- marginTop: 72
74
+ sx: {
75
+ pt: 3,
76
+ borderTop: 1,
77
+ borderColor: 'grey.200'
65
78
  },
79
+ autoCenter: true,
66
80
  children: [elements.copyright, elements.links]
67
81
  })]
68
82
  })
69
83
  }));
70
84
  }
71
85
 
72
- Footer.propTypes = {
86
+ StandardLayout.propTypes = {
73
87
  elements: _propTypes.default.shape({
74
88
  brand: _propTypes.default.element,
75
89
  navigation: _propTypes.default.element,
76
90
  socialMedia: _propTypes.default.element,
77
91
  copyright: _propTypes.default.element,
78
92
  links: _propTypes.default.element
79
- }).isRequired
93
+ }).isRequired,
94
+ data: _propTypes.default.object.isRequired
80
95
  };
81
-
82
- const Root = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: 48px 0;\n"])));
83
-
84
- var _default = Footer;
96
+ const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding: 32px 0 24px 0;\n .footer-brand-desc {\n display: none;\n }\n"])));
97
+ var _default = StandardLayout;
85
98
  exports.default = _default;
@@ -9,12 +9,14 @@ var _react = require("react");
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
12
- var _styled = _interopRequireDefault(require("@emotion/styled"));
13
-
14
- var _styles = require("@mui/material/styles");
12
+ var _Theme = require("@arcblock/ux/lib/Theme");
15
13
 
16
14
  var _clsx = _interopRequireDefault(require("clsx"));
17
15
 
16
+ var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore"));
17
+
18
+ var _Icon = _interopRequireDefault(require("../Icon"));
19
+
18
20
  var _jsxRuntime = require("react/jsx-runtime");
19
21
 
20
22
  var _templateObject;
@@ -46,7 +48,7 @@ function Links(_ref) {
46
48
  } = _ref,
47
49
  rest = _objectWithoutProperties(_ref, _excluded);
48
50
 
49
- const theme = (0, _styles.useTheme)();
51
+ const theme = (0, _Theme.useTheme)();
50
52
  const [activeIndex, setActiveIndex] = (0, _react.useState)(-1);
51
53
 
52
54
  if (!(links !== null && links !== void 0 && links.length)) {
@@ -64,6 +66,7 @@ function Links(_ref) {
64
66
  let {
65
67
  label,
66
68
  link,
69
+ icon,
67
70
  render,
68
71
  props
69
72
  } = _ref2;
@@ -83,7 +86,15 @@ function Links(_ref) {
83
86
  }));
84
87
  }
85
88
 
86
- return result;
89
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
90
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
91
+ icon: icon,
92
+ size: 20,
93
+ sx: {
94
+ mr: 0.5
95
+ }
96
+ }), result]
97
+ });
87
98
  };
88
99
 
89
100
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Root, _objectSpread(_objectSpread({}, rest), {}, {
@@ -101,14 +112,22 @@ function Links(_ref) {
101
112
  const {
102
113
  items
103
114
  } = item;
115
+ const isActive = i === activeIndex;
104
116
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
105
117
  className: (0, _clsx.default)('footer-links-group', {
106
- 'footer-links-group--active': i === activeIndex
118
+ 'footer-links-group--active': isActive
107
119
  }),
108
120
  onClick: () => setActiveIndex(activeIndex === i ? -1 : i),
109
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
121
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
110
122
  className: "footer-links-item",
111
- children: renderItem(item)
123
+ children: [renderItem(item), !!(items !== null && items !== void 0 && items.length) && /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
124
+ className: "footer-links-group-expand-icon",
125
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandMore.default, {
126
+ style: {
127
+ transform: "rotate(".concat(isActive ? 180 : 0, "deg)")
128
+ }
129
+ })
130
+ })]
112
131
  }), !!(items !== null && items !== void 0 && items.length) && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
113
132
  className: "footer-links-sub",
114
133
  children: items.map((child, j) => /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
@@ -136,5 +155,4 @@ Links.defaultProps = {
136
155
  links: [],
137
156
  flowLayout: false
138
157
  };
139
-
140
- const Root = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n overflow: hidden;\n color: ", ";\n .footer-links-inner {\n display: flex;\n justify-content: space-between;\n margin: 0 -8px;\n }\n .footer-links-group,\n .footer-links-sub {\n display: flex;\n flex-direction: column;\n }\n .footer-links-item {\n display: inline-block;\n padding: 0 8px;\n font-size: 14px;\n line-height: 1.6;\n }\n .footer-links-group + .footer-links-group {\n margin-left: 128px;\n }\n &.footer-links--grouped {\n .footer-links-group {\n > .footer-links-item {\n font-weight: bold;\n }\n .footer-links-sub {\n margin-top: 8px;\n }\n }\n }\n a {\n color: inherit;\n text-decoration: none;\n &:hover {\n text-decoration: underline;\n }\n }\n\n &.footer-links--flow {\n display: inline-flex;\n .footer-links-inner {\n justify-content: center;\n flex-wrap: wrap;\n margin: 0 -8px;\n .footer-links-item {\n padding: 0 8px;\n }\n }\n }\n\n ", " {\n .footer-links-group + .footer-links-group {\n margin-left: 56px;\n }\n }\n\n ", " {\n .footer-links-group + .footer-links-group {\n margin-left: 40px;\n }\n }\n\n ", " {\n .footer-links-inner {\n flex-direction: column;\n margin: 0;\n }\n .footer-links-sub {\n display: none;\n }\n .footer-links-group {\n padding: 12px 0;\n border-top: 1px solid ", ";\n }\n .footer-links-group + .footer-links-group {\n margin-left: 0;\n }\n .footer-links-group--active {\n .footer-links-sub {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n .footer-links-item {\n flex: 0 0 50%;\n }\n }\n }\n .footer-links-item {\n padding: 0;\n font-size: 13px;\n }\n &.footer-links--grouped {\n .footer-links-group {\n > .footer-links-item {\n font-size: 14px;\n }\n }\n }\n\n &.footer-links--flow {\n .footer-links-inner {\n flex-direction: row;\n }\n }\n }\n"])), props => props.$theme.palette.grey[600], props => props.$theme.breakpoints.down('lg'), props => props.$theme.breakpoints.down('lg'), props => props.$theme.breakpoints.down('sm'), props => props.$theme.palette.grey[200]);
158
+ const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n overflow: hidden;\n color: ", ";\n .footer-links-inner {\n display: flex;\n justify-content: space-between;\n margin: 0 -8px;\n }\n .footer-links-group,\n .footer-links-sub {\n display: flex;\n flex-direction: column;\n }\n .footer-links-group-expand-icon {\n display: none;\n position: absolute;\n right: 16px;\n top: 50%;\n transform: translate(0, -50%);\n svg {\n width: auto;\n height: 0.75em;\n }\n }\n .footer-links-item {\n display: inline-flex;\n align-items: center;\n position: relative;\n padding: 0 8px;\n font-size: 14px;\n line-height: 1.6;\n }\n &.footer-links--grouped {\n .footer-links-group {\n > .footer-links-item {\n font-weight: bold;\n }\n .footer-links-sub {\n margin-top: 8px;\n }\n }\n }\n a {\n display: inline-block;\n max-width: 150px;\n color: inherit;\n text-decoration: none;\n &:hover {\n text-decoration: underline;\n }\n }\n\n &.footer-links--flow {\n display: inline-flex;\n .footer-links-inner {\n justify-content: center;\n flex-wrap: wrap;\n margin: 0 -8px;\n .footer-links-item {\n padding: 0 8px;\n }\n .footer-links-item + .footer-links-item::before {\n content: '';\n position: absolute;\n left: 0;\n top: 50%;\n transform: translate(0, -50%);\n height: 1em;\n border-left: 1px solid ", ";\n }\n }\n }\n\n ", " {\n .footer-links-inner {\n flex-direction: column;\n margin: 0;\n }\n .footer-links-sub {\n display: none;\n }\n .footer-links-group {\n position: relative;\n padding: 12px 0;\n .footer-links-item .footer-links-group-expand-icon {\n display: inline-block;\n }\n }\n .footer-links-group + .footer-links-group {\n border-top: 1px solid ", ";\n }\n .footer-links-group--active {\n .footer-links-sub {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n .footer-links-item {\n flex: 0 0 50%;\n }\n }\n }\n .footer-links-item {\n padding: 0;\n font-size: 13px;\n }\n &.footer-links--grouped {\n .footer-links-group {\n > .footer-links-item {\n font-size: 14px;\n }\n }\n }\n\n &.footer-links--flow {\n .footer-links-inner {\n flex-direction: row;\n }\n }\n }\n"])), props => props.$theme.palette.grey[600], props => props.theme.palette.grey[400], props => props.$theme.breakpoints.down('md'), props => props.$theme.palette.grey[200]);
@@ -7,9 +7,7 @@ exports.default = SocialMedia;
7
7
 
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
 
10
- var _styled = _interopRequireDefault(require("@emotion/styled"));
11
-
12
- var _styles = require("@mui/material/styles");
10
+ var _Theme = require("@arcblock/ux/lib/Theme");
13
11
 
14
12
  var _Icon = _interopRequireDefault(require("../Icon"));
15
13
 
@@ -39,7 +37,7 @@ function SocialMedia(_ref) {
39
37
  } = _ref,
40
38
  rest = _objectWithoutProperties(_ref, _excluded);
41
39
 
42
- const theme = (0, _styles.useTheme)();
40
+ const theme = (0, _Theme.useTheme)();
43
41
 
44
42
  if (!(items !== null && items !== void 0 && items.length)) {
45
43
  return null;
@@ -60,8 +58,7 @@ function SocialMedia(_ref) {
60
58
  bgcolor: theme.palette.grey[600],
61
59
  color: '#fff'
62
60
  },
63
- size: 44,
64
- variant: "rounded",
61
+ size: 24,
65
62
  component: "span"
66
63
  })
67
64
  }, i)
@@ -80,5 +77,4 @@ SocialMedia.propTypes = {
80
77
  SocialMedia.defaultProps = {
81
78
  items: null
82
79
  };
83
-
84
- const Root = _styled.default.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: inline-flex;\n align-items: center;\n a + a {\n margin-left: 12px;\n }\n"])));
80
+ const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: inline-flex;\n align-items: center;\n a {\n color: ", ";\n &:hover {\n color: ", ";\n }\n }\n a + a {\n margin-left: 20px;\n }\n"])), props => props.theme.palette.grey[400], props => props.theme.palette.primary.light);
@@ -11,10 +11,6 @@ var _jsxRuntime = require("react/jsx-runtime");
11
11
 
12
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
- var _styled = _interopRequireDefault(require("@emotion/styled"));
15
-
16
- var _styles = require("@mui/material/styles");
17
-
18
14
  var _reactErrorBoundary = require("react-error-boundary");
19
15
 
20
16
  var _ErrorBoundary = require("@arcblock/ux/lib/ErrorBoundary");
@@ -63,7 +59,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
63
59
 
64
60
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
65
61
 
66
- const muiTheme = (0, _Theme.create)(); // blocklet meta 中的 navigation 数据 => NavMenu 组件的 items
62
+ const muiTheme = (0, _Theme.createTheme)(); // blocklet meta 中的 navigation 数据 => NavMenu 组件的 items
67
63
 
68
64
  const parseNavigation = navigation => {
69
65
  if (!(navigation !== null && navigation !== void 0 && navigation.length)) {
@@ -203,7 +199,7 @@ function Header(_ref) {
203
199
 
204
200
  const renderedAddons = renderAddons();
205
201
  const addonList = /*#__PURE__*/(0, _react.createElement)(_jsxRuntime.Fragment, null, ...(Array.isArray(renderedAddons) ? renderedAddons : [renderedAddons]));
206
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.ThemeProvider, {
202
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Theme.ThemeProvider, {
207
203
  theme: muiTheme,
208
204
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledUxHeader, _objectSpread(_objectSpread({
209
205
  logo: /*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
@@ -265,7 +261,7 @@ Header.defaultProps = {
265
261
  },
266
262
  homeLink: _blocklets.publicPath
267
263
  };
268
- const StyledUxHeader = (0, _styled.default)(_Header.ResponsiveHeader)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n font-family: Lato, Avenir, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,\n 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n .header-logo {\n min-width: 44px;\n }\n ", " {\n .header-logo {\n min-width: 32px;\n }\n }\n .header-nav {\n .navmenu-sub .navmenu-item {\n min-width: 80px;\n }\n }\n .header-nav.navmenu--horizontal {\n .navmenu-root > .navmenu-sub,\n .navmenu-root > .navmenu-item {\n padding: 16px 4px;\n\n .navmenu-sub-container {\n padding-top: 0;\n }\n }\n }\n"])), _ref3 => {
264
+ const StyledUxHeader = (0, _Theme.styled)(_Header.ResponsiveHeader)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n ", "\n font-family: Lato, Avenir, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,\n 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n .header-logo {\n min-width: 44px;\n }\n ", " {\n .header-logo {\n min-width: 32px;\n }\n }\n .header-nav {\n .navmenu-sub .navmenu-item {\n min-width: 80px;\n }\n }\n .header-nav.navmenu--horizontal {\n .navmenu-root > .navmenu-sub,\n .navmenu-root > .navmenu-item {\n padding: 16px 4px;\n\n .navmenu-sub-container {\n padding-top: 0;\n }\n }\n .navmenu-item-icon > .MuiAvatar-root,\n .navmenu-sub-icon > .MuiAvatar-root {\n width: 20px;\n height: 20px;\n }\n }\n"])), _ref3 => {
269
265
  let {
270
266
  $bgcolor
271
267
  } = _ref3;
package/lib/Icon/index.js CHANGED
@@ -56,6 +56,11 @@ function Icon(_ref) {
56
56
  color: 'inherit',
57
57
  backgroundColor: 'transparent',
58
58
  borderRadius: 0
59
+ },
60
+ // 无 icon 背景时, svg icon 尺寸与窗口尺寸一致
61
+ '&.MuiAvatar-root svg': {
62
+ width: '100%',
63
+ height: '100%'
59
64
  }
60
65
  });
61
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/ui-react",
3
- "version": "2.4.2",
3
+ "version": "2.4.5",
4
4
  "description": "Some useful front-end web components that can be used in Blocklets.",
5
5
  "keywords": [
6
6
  "react",
@@ -30,8 +30,8 @@
30
30
  "url": "https://github.com/ArcBlock/ux/issues"
31
31
  },
32
32
  "dependencies": {
33
- "@arcblock/did-connect": "^2.4.2",
34
- "@arcblock/ux": "^2.4.2",
33
+ "@arcblock/did-connect": "^2.4.5",
34
+ "@arcblock/ux": "^2.4.5",
35
35
  "@emotion/react": "^11.10.0",
36
36
  "@emotion/styled": "^11.10.0",
37
37
  "@iconify/iconify": "^2.2.1",
@@ -53,5 +53,5 @@
53
53
  "eslint-plugin-react-hooks": "^4.6.0",
54
54
  "jest": "^24.9.0"
55
55
  },
56
- "gitHead": "6a7e96c930c4ef0dd995bc9383738bb1cdf12844"
56
+ "gitHead": "ba62e426b63dd469d3d139d0de11d4d329d84fef"
57
57
  }
@@ -1,7 +1,6 @@
1
1
  import { isValidElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import styled from '@emotion/styled';
4
- import { useTheme } from '@mui/material/styles';
3
+ import { useTheme, styled } from '@arcblock/ux/lib/Theme';
5
4
 
6
5
  export default function Brand({ name, logo, description, ...rest }) {
7
6
  const theme = useTheme();
@@ -34,7 +33,7 @@ Brand.defaultProps = {
34
33
  description: '',
35
34
  };
36
35
 
37
- const Root = styled.div`
36
+ const Root = styled('div')`
38
37
  display: flex;
39
38
  flex-direction: column;
40
39
  font-size: 14px;
@@ -1,5 +1,5 @@
1
+ import { styled } from '@arcblock/ux/lib/Theme';
1
2
  import PropTypes from 'prop-types';
2
- import styled from '@emotion/styled';
3
3
 
4
4
  export default function Copyright({ owner, year, ...rest }) {
5
5
  return (
@@ -19,7 +19,9 @@ Copyright.defaultProps = {
19
19
  year: `${new Date().getFullYear()}`,
20
20
  };
21
21
 
22
- const Root = styled.p`
22
+ const Root = styled('p')`
23
+ display: flex;
24
+ align-items: center;
23
25
  margin: 0;
24
26
  font-size: 13px;
25
27
  `;
@@ -1,9 +1,9 @@
1
1
  import { useMemo } from 'react';
2
- import styled from '@emotion/styled';
3
- import { useTheme } from '@mui/material/styles';
2
+ import { styled, useTheme } from '@arcblock/ux/lib/Theme';
4
3
  import { withErrorBoundary } from 'react-error-boundary';
5
4
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
5
  import { ErrorFallback } from '@arcblock/ux/lib/ErrorBoundary';
6
+
7
7
  import InternalFooter from './internal-footer';
8
8
  import { mapRecursive } from '../utils';
9
9
  import { formatBlockletInfo, getLocalizedNavigation } from '../blocklets';
@@ -8,22 +8,26 @@ import PlainLayout from './layout/plain';
8
8
 
9
9
  const layouts = [
10
10
  {
11
+ name: 'plain',
11
12
  // navigation 数据为空时, 使用简单布局
12
13
  support: (_, data) => !data.navigation?.length,
13
14
  component: PlainLayout,
14
15
  },
15
16
  {
17
+ name: 'standard',
16
18
  // 默认标准布局
17
19
  support: () => true,
18
20
  component: StandardLayout,
19
21
  },
20
22
  ];
21
23
 
24
+ const layoutsKeyByName = layouts.reduce((acc, cur) => ({ ...acc, [cur.name]: cur }), {});
25
+
22
26
  /**
23
27
  * 通用的内部 footer 组件, 定义并渲染常见的几种 footer 元素: brand/navigation/social medial 等
24
28
  */
25
29
  function InternalFooter(props) {
26
- const { brand, navigation, socialMedia, copyright, links, ...rest } = props;
30
+ const { brand, navigation, socialMedia, copyright, links, layout, ...rest } = props;
27
31
  const renderBrand = () => {
28
32
  return brand ? <Brand {...brand} /> : null;
29
33
  };
@@ -52,8 +56,16 @@ function InternalFooter(props) {
52
56
  copyright: renderCopyright(),
53
57
  links: renderLinks(),
54
58
  };
55
- const LayoutComponent = layouts.find((layout) => layout.support(elements, props)).component;
56
- return <LayoutComponent elements={elements} {...rest} />;
59
+ let LayoutComponent = null;
60
+ if (layout === 'auto') {
61
+ LayoutComponent = layouts.find((item) => item.support(elements, props)).component;
62
+ } else {
63
+ LayoutComponent = layoutsKeyByName[layout]?.component;
64
+ }
65
+ if (!LayoutComponent) {
66
+ throw new Error(`layout ${layout} is not supported.`);
67
+ }
68
+ return <LayoutComponent elements={elements} data={props} {...rest} />;
57
69
  }
58
70
 
59
71
  InternalFooter.propTypes = {
@@ -85,6 +97,8 @@ InternalFooter.propTypes = {
85
97
  link: PropTypes.string,
86
98
  })
87
99
  ),
100
+ // 可显式指定 footer layout, 默认根据内容自动决定 layout
101
+ layout: PropTypes.oneOf(['auto', 'standard', 'plain']),
88
102
  };
89
103
 
90
104
  InternalFooter.defaultProps = {
@@ -93,6 +107,7 @@ InternalFooter.defaultProps = {
93
107
  copyright: null,
94
108
  socialMedia: null,
95
109
  links: null,
110
+ layout: 'auto',
96
111
  };
97
112
 
98
113
  export default InternalFooter;
@@ -1,17 +1,28 @@
1
1
  import { cloneElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import styled from '@emotion/styled';
4
3
  import Container from '@mui/material/Container';
4
+ import { styled } from '@arcblock/ux/lib/Theme';
5
+ import Row from './row';
5
6
 
6
7
  /**
7
8
  * footer plain layout
8
9
  */
9
- function PlainLayout({ elements, ...rest }) {
10
+ function PlainLayout({ elements, data, ...rest }) {
10
11
  return (
11
12
  <Root {...rest}>
12
13
  <Container className="plain-layout-container">
13
- {cloneElement(elements.brand, { name: null, description: null })}
14
- {elements.copyright}
14
+ {!!data.links && (
15
+ <Row sx={{ width: 1 }} autoCenter>
16
+ {elements.copyright}
17
+ {elements.links}
18
+ </Row>
19
+ )}
20
+ {!data.links && (
21
+ <>
22
+ {cloneElement(elements.brand, { name: null, description: null })}
23
+ {elements.copyright}
24
+ </>
25
+ )}
15
26
  </Container>
16
27
  </Root>
17
28
  );
@@ -25,9 +36,10 @@ PlainLayout.propTypes = {
25
36
  copyright: PropTypes.element,
26
37
  links: PropTypes.element,
27
38
  }).isRequired,
39
+ data: PropTypes.object.isRequired,
28
40
  };
29
41
 
30
- const Root = styled.div`
42
+ const Root = styled('div')`
31
43
  padding: 24px 0;
32
44
  border-top: 1px solid #eee;
33
45
  .plain-layout-container {
@@ -1,6 +1,6 @@
1
1
  import PropTypes from 'prop-types';
2
- import styled from '@emotion/styled';
3
- import { useTheme } from '@mui/material/styles';
2
+ import Box from '@mui/material/Box';
3
+ import { useTheme, styled } from '@arcblock/ux/lib/Theme';
4
4
  import clsx from 'clsx';
5
5
 
6
6
  export default function Row({ children, autoCenter, ...rest }) {
@@ -25,7 +25,7 @@ Row.defaultProps = {
25
25
  autoCenter: false,
26
26
  };
27
27
 
28
- const RowRoot = styled.div`
28
+ const RowRoot = styled(Box)`
29
29
  display: flex;
30
30
  justify-content: space-between;
31
31
  & + & {
@@ -1,24 +1,32 @@
1
1
  import PropTypes from 'prop-types';
2
- import styled from '@emotion/styled';
3
2
  import Box from '@mui/material/Box';
4
3
  import Container from '@mui/material/Container';
4
+ import { styled } from '@arcblock/ux/lib/Theme';
5
+
5
6
  import Row from './row';
6
7
 
7
8
  /**
8
9
  * footer standard layout
9
10
  */
10
- function Footer({ elements, ...rest }) {
11
+ function StandardLayout({ elements, data, ...rest }) {
11
12
  return (
12
13
  <Root {...rest}>
13
14
  <Container>
14
- <Row>
15
- <Box>
16
- <Box width={{ md: 240 }}>{elements.brand}</Box>
17
- <Box mt={2}>{elements.socialMedia}</Box>
15
+ <Box
16
+ sx={{
17
+ display: 'flex',
18
+ justifyContent: 'space-between',
19
+ pb: 3,
20
+ }}>
21
+ <Box>{elements.brand}</Box>
22
+ <Box lineHeight={1} alignSelf="end">
23
+ {elements.socialMedia}
18
24
  </Box>
19
- {elements.navigation}
20
- </Row>
21
- <Row autoCenter style={{ marginTop: 72 }}>
25
+ </Box>
26
+ {!!data.navigation?.length && (
27
+ <Box sx={{ mb: 6, pt: 3, borderTop: 1, borderColor: 'grey.200' }}>{elements.navigation}</Box>
28
+ )}
29
+ <Row sx={{ pt: 3, borderTop: 1, borderColor: 'grey.200' }} autoCenter>
22
30
  {elements.copyright}
23
31
  {elements.links}
24
32
  </Row>
@@ -27,7 +35,7 @@ function Footer({ elements, ...rest }) {
27
35
  );
28
36
  }
29
37
 
30
- Footer.propTypes = {
38
+ StandardLayout.propTypes = {
31
39
  elements: PropTypes.shape({
32
40
  brand: PropTypes.element,
33
41
  navigation: PropTypes.element,
@@ -35,10 +43,14 @@ Footer.propTypes = {
35
43
  copyright: PropTypes.element,
36
44
  links: PropTypes.element,
37
45
  }).isRequired,
46
+ data: PropTypes.object.isRequired,
38
47
  };
39
48
 
40
- const Root = styled.div`
41
- padding: 48px 0;
49
+ const Root = styled('div')`
50
+ padding: 32px 0 24px 0;
51
+ .footer-brand-desc {
52
+ display: none;
53
+ }
42
54
  `;
43
55
 
44
- export default Footer;
56
+ export default StandardLayout;
@@ -1,9 +1,10 @@
1
1
  /* eslint-disable react/no-array-index-key */
2
2
  import { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import styled from '@emotion/styled';
5
- import { useTheme } from '@mui/material/styles';
4
+ import { useTheme, styled } from '@arcblock/ux/lib/Theme';
6
5
  import clsx from 'clsx';
6
+ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
7
+ import Icon from '../Icon';
7
8
 
8
9
  /**
9
10
  * footer 中的 links (支持分组, 最多支持 2 级)
@@ -17,7 +18,7 @@ export default function Links({ links, flowLayout, ...rest }) {
17
18
  }
18
19
  // 只要发现一项元素有子元素, 就认为是分组 (大字号突出 group title)
19
20
  const isGroupMode = links.some((item) => item.items?.length);
20
- const renderItem = ({ label, link, render, props }) => {
21
+ const renderItem = ({ label, link, icon, render, props }) => {
21
22
  let result = label;
22
23
  if (render) {
23
24
  result = render({ label, link, props });
@@ -28,9 +29,13 @@ export default function Links({ links, flowLayout, ...rest }) {
28
29
  </a>
29
30
  );
30
31
  }
31
- return result;
32
+ return (
33
+ <>
34
+ <Icon icon={icon} size={20} sx={{ mr: 0.5 }} />
35
+ {result}
36
+ </>
37
+ );
32
38
  };
33
-
34
39
  return (
35
40
  <Root
36
41
  {...rest}
@@ -49,14 +54,26 @@ export default function Links({ links, flowLayout, ...rest }) {
49
54
  {!flowLayout &&
50
55
  links.map((item, i) => {
51
56
  const { items } = item;
57
+ const isActive = i === activeIndex;
52
58
  return (
53
59
  <div
54
60
  key={i}
55
61
  className={clsx('footer-links-group', {
56
- 'footer-links-group--active': i === activeIndex,
62
+ 'footer-links-group--active': isActive,
57
63
  })}
58
64
  onClick={() => setActiveIndex(activeIndex === i ? -1 : i)}>
59
- <span className="footer-links-item">{renderItem(item)}</span>
65
+ <span className="footer-links-item">
66
+ {renderItem(item)}
67
+ {!!items?.length && (
68
+ <span className="footer-links-group-expand-icon">
69
+ <ExpandMoreIcon
70
+ style={{
71
+ transform: `rotate(${isActive ? 180 : 0}deg)`,
72
+ }}
73
+ />
74
+ </span>
75
+ )}
76
+ </span>
60
77
  {!!items?.length && (
61
78
  <div className="footer-links-sub">
62
79
  {items.map((child, j) => (
@@ -92,7 +109,7 @@ Links.defaultProps = {
92
109
  flowLayout: false,
93
110
  };
94
111
 
95
- const Root = styled.div`
112
+ const Root = styled('div')`
96
113
  overflow: hidden;
97
114
  color: ${(props) => props.$theme.palette.grey[600]};
98
115
  .footer-links-inner {
@@ -105,15 +122,25 @@ const Root = styled.div`
105
122
  display: flex;
106
123
  flex-direction: column;
107
124
  }
125
+ .footer-links-group-expand-icon {
126
+ display: none;
127
+ position: absolute;
128
+ right: 16px;
129
+ top: 50%;
130
+ transform: translate(0, -50%);
131
+ svg {
132
+ width: auto;
133
+ height: 0.75em;
134
+ }
135
+ }
108
136
  .footer-links-item {
109
- display: inline-block;
137
+ display: inline-flex;
138
+ align-items: center;
139
+ position: relative;
110
140
  padding: 0 8px;
111
141
  font-size: 14px;
112
142
  line-height: 1.6;
113
143
  }
114
- .footer-links-group + .footer-links-group {
115
- margin-left: 128px;
116
- }
117
144
  &.footer-links--grouped {
118
145
  .footer-links-group {
119
146
  > .footer-links-item {
@@ -125,6 +152,8 @@ const Root = styled.div`
125
152
  }
126
153
  }
127
154
  a {
155
+ display: inline-block;
156
+ max-width: 150px;
128
157
  color: inherit;
129
158
  text-decoration: none;
130
159
  &:hover {
@@ -141,22 +170,19 @@ const Root = styled.div`
141
170
  .footer-links-item {
142
171
  padding: 0 8px;
143
172
  }
173
+ .footer-links-item + .footer-links-item::before {
174
+ content: '';
175
+ position: absolute;
176
+ left: 0;
177
+ top: 50%;
178
+ transform: translate(0, -50%);
179
+ height: 1em;
180
+ border-left: 1px solid ${(props) => props.theme.palette.grey[400]};
181
+ }
144
182
  }
145
183
  }
146
184
 
147
- ${(props) => props.$theme.breakpoints.down('lg')} {
148
- .footer-links-group + .footer-links-group {
149
- margin-left: 56px;
150
- }
151
- }
152
-
153
- ${(props) => props.$theme.breakpoints.down('lg')} {
154
- .footer-links-group + .footer-links-group {
155
- margin-left: 40px;
156
- }
157
- }
158
-
159
- ${(props) => props.$theme.breakpoints.down('sm')} {
185
+ ${(props) => props.$theme.breakpoints.down('md')} {
160
186
  .footer-links-inner {
161
187
  flex-direction: column;
162
188
  margin: 0;
@@ -165,11 +191,14 @@ const Root = styled.div`
165
191
  display: none;
166
192
  }
167
193
  .footer-links-group {
194
+ position: relative;
168
195
  padding: 12px 0;
169
- border-top: 1px solid ${(props) => props.$theme.palette.grey[200]};
196
+ .footer-links-item .footer-links-group-expand-icon {
197
+ display: inline-block;
198
+ }
170
199
  }
171
200
  .footer-links-group + .footer-links-group {
172
- margin-left: 0;
201
+ border-top: 1px solid ${(props) => props.$theme.palette.grey[200]};
173
202
  }
174
203
  .footer-links-group--active {
175
204
  .footer-links-sub {
@@ -1,6 +1,5 @@
1
1
  import PropTypes from 'prop-types';
2
- import styled from '@emotion/styled';
3
- import { useTheme } from '@mui/material/styles';
2
+ import { useTheme, styled } from '@arcblock/ux/lib/Theme';
4
3
  import Icon from '../Icon';
5
4
 
6
5
  export default function SocialMedia({ items, ...rest }) {
@@ -17,8 +16,7 @@ export default function SocialMedia({ items, ...rest }) {
17
16
  <Icon
18
17
  icon={item.icon}
19
18
  sx={{ bgcolor: theme.palette.grey[600], color: '#fff' }}
20
- size={44}
21
- variant="rounded"
19
+ size={24}
22
20
  component="span"
23
21
  />
24
22
  </a>
@@ -42,10 +40,16 @@ SocialMedia.defaultProps = {
42
40
  items: null,
43
41
  };
44
42
 
45
- const Root = styled.div`
43
+ const Root = styled('div')`
46
44
  display: inline-flex;
47
45
  align-items: center;
46
+ a {
47
+ color: ${(props) => props.theme.palette.grey[400]};
48
+ &:hover {
49
+ color: ${(props) => props.theme.palette.primary.light};
50
+ }
51
+ }
48
52
  a + a {
49
- margin-left: 12px;
53
+ margin-left: 20px;
50
54
  }
51
55
  `;
@@ -2,11 +2,9 @@ import { useContext, useMemo, createElement } from 'react';
2
2
  // FIXME: 直接从 react 中 import Fragment 可能会在 vite 下出错,先暂时从 react/jsx-runtime 导入 Fragment 来跳过这个问题
3
3
  import { Fragment } from 'react/jsx-runtime';
4
4
  import PropTypes from 'prop-types';
5
- import styled from '@emotion/styled';
6
- import { ThemeProvider } from '@mui/material/styles';
7
5
  import { withErrorBoundary } from 'react-error-boundary';
8
6
  import { ErrorFallback } from '@arcblock/ux/lib/ErrorBoundary';
9
- import { create } from '@arcblock/ux/lib/Theme';
7
+ import { createTheme, ThemeProvider, styled } from '@arcblock/ux/lib/Theme';
10
8
  import { ResponsiveHeader } from '@arcblock/ux/lib/Header';
11
9
  import NavMenu from '@arcblock/ux/lib/NavMenu';
12
10
  import { SessionContext } from '@arcblock/did-connect/lib/Session';
@@ -21,7 +19,7 @@ import { blockletMetaProps, sessionManagerProps } from '../types';
21
19
  import { mapRecursive, flatRecursive, matchPaths } from '../utils';
22
20
  import { publicPath, formatBlockletInfo, getLocalizedNavigation } from '../blocklets';
23
21
 
24
- const muiTheme = create();
22
+ const muiTheme = createTheme();
25
23
 
26
24
  // blocklet meta 中的 navigation 数据 => NavMenu 组件的 items
27
25
  const parseNavigation = (navigation) => {
@@ -209,6 +207,11 @@ const StyledUxHeader = styled(ResponsiveHeader)`
209
207
  padding-top: 0;
210
208
  }
211
209
  }
210
+ .navmenu-item-icon > .MuiAvatar-root,
211
+ .navmenu-sub-icon > .MuiAvatar-root {
212
+ width: 20px;
213
+ height: 20px;
214
+ }
212
215
  }
213
216
  `;
214
217
 
package/src/Icon/index.js CHANGED
@@ -19,6 +19,11 @@ export default function Icon({ icon, size, sx, ...rest }) {
19
19
  backgroundColor: 'transparent',
20
20
  borderRadius: 0,
21
21
  },
22
+ // 无 icon 背景时, svg icon 尺寸与窗口尺寸一致
23
+ '&.MuiAvatar-root svg': {
24
+ width: '100%',
25
+ height: '100%',
26
+ },
22
27
  });
23
28
  }
24
29
  if (isUrl(icon)) {