@arcblock/ux 2.4.65 → 2.4.67

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,84 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FullPageContext = void 0;
7
+ exports.FullPageProvider = FullPageProvider;
8
+ exports.useFullPage = void 0;
9
+
10
+ var _react = require("react");
11
+
12
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
+
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+
16
+ const _excluded = ["children"];
17
+
18
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
+
20
+ 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; }
21
+
22
+ 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; }
23
+
24
+ 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; }
25
+
26
+ 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; }
27
+
28
+ 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; }
29
+
30
+ const FullPageContext = /*#__PURE__*/(0, _react.createContext)();
31
+ exports.FullPageContext = FullPageContext;
32
+
33
+ const useFullPage = initialState => {
34
+ const ctx = (0, _react.useContext)(FullPageContext);
35
+ (0, _react.useLayoutEffect)(() => {
36
+ if (initialState) {
37
+ ctx.configure(initialState);
38
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
39
+
40
+ }, []);
41
+ return ctx;
42
+ };
43
+
44
+ exports.useFullPage = useFullPage;
45
+
46
+ function FullPageProvider(_ref) {
47
+ let {
48
+ children
49
+ } = _ref,
50
+ rest = _objectWithoutProperties(_ref, _excluded);
51
+
52
+ const [state, setState] = (0, _react.useState)({
53
+ inFullPage: false,
54
+ showToggleButton: false,
55
+ headerVisibleInFullPage: true,
56
+ footerVisibleInFullPage: false,
57
+ sidebarVisibleInFullPage: false
58
+ });
59
+
60
+ const toggleFullPage = () => {
61
+ setState(prev => _objectSpread(_objectSpread({}, prev), {}, {
62
+ inFullPage: !prev.inFullPage
63
+ }));
64
+ };
65
+
66
+ const value = (0, _react.useMemo)(() => {
67
+ return _objectSpread(_objectSpread({}, state), {}, {
68
+ headerVisible: !state.inFullPage || state.headerVisibleInFullPage,
69
+ footerVisible: !state.inFullPage || state.footerVisibleInFullPage,
70
+ sidebarVisible: !state.inFullPage || state.sidebarVisibleInFullPage,
71
+ toggleFullPage,
72
+ configure: params => setState(prev => _objectSpread(_objectSpread({}, prev), params))
73
+ });
74
+ }, [state]);
75
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(FullPageContext.Provider, _objectSpread(_objectSpread({
76
+ value: value
77
+ }, rest), {}, {
78
+ children: children
79
+ }));
80
+ }
81
+
82
+ FullPageProvider.propTypes = {
83
+ children: _propTypes.default.node.isRequired
84
+ };
@@ -21,6 +21,10 @@ var _Box = _interopRequireDefault(require("@mui/material/Box"));
21
21
 
22
22
  var _clsx = _interopRequireDefault(require("clsx"));
23
23
 
24
+ var _OpenInFull = _interopRequireDefault(require("@mui/icons-material/OpenInFull"));
25
+
26
+ var _CloseFullscreen = _interopRequireDefault(require("@mui/icons-material/CloseFullscreen"));
27
+
24
28
  var _dashboardLegacy = _interopRequireDefault(require("../dashboard-legacy"));
25
29
 
26
30
  var _Header = require("../../Header");
@@ -35,6 +39,8 @@ var _Theme = require("../../Theme");
35
39
 
36
40
  var _externalLink = require("./external-link");
37
41
 
42
+ var _fullPage = require("./full-page");
43
+
38
44
  var _jsxRuntime = require("react/jsx-runtime");
39
45
 
40
46
  var _templateObject, _templateObject2;
@@ -112,6 +118,14 @@ function Dashboard(_ref2) {
112
118
  rest = _objectWithoutProperties(_ref2, _excluded2);
113
119
 
114
120
  const theme = (0, _Theme.useTheme)();
121
+ const {
122
+ inFullPage,
123
+ showToggleButton,
124
+ headerVisible,
125
+ footerVisible,
126
+ sidebarVisible,
127
+ toggleFullPage
128
+ } = (0, _fullPage.useFullPage)();
115
129
  const location = (0, _reactRouterDom.useLocation)();
116
130
  const navItems = (0, _react.useMemo)(() => formatLinks(links, location), [location, links]);
117
131
  const isGroupedMode = navItems.some(item => {
@@ -143,7 +157,7 @@ function Dashboard(_ref2) {
143
157
  className: classes,
144
158
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactHelmet.default, {
145
159
  title: title
146
- }, title), /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledUxHeader, _objectSpread(_objectSpread({}, _headerProps), {}, {
160
+ }, title), headerVisible && /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledUxHeader, _objectSpread(_objectSpread({}, _headerProps), {}, {
147
161
  className: "dashboard-header",
148
162
  children: links !== null && links !== void 0 && links.length ? _ref3 => {
149
163
  let {
@@ -168,7 +182,7 @@ function Dashboard(_ref2) {
168
182
  className: "dashboard-body",
169
183
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Hidden.default, {
170
184
  mdDown: true,
171
- children: !!(links !== null && links !== void 0 && links.length) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
185
+ children: !!(links !== null && links !== void 0 && links.length) && sidebarVisible && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
172
186
  className: "dashboard-sidebar",
173
187
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sidebar.default, {
174
188
  links: links,
@@ -177,13 +191,38 @@ function Dashboard(_ref2) {
177
191
  })
178
192
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
179
193
  className: "dashboard-main",
180
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Container.default, _objectSpread(_objectSpread({
194
+ children: [showToggleButton && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Box.default, {
195
+ sx: {
196
+ position: 'absolute',
197
+ top: 4,
198
+ right: 4,
199
+ display: 'flex',
200
+ justifyContent: 'center',
201
+ alignItems: 'center',
202
+ width: 24,
203
+ height: 24,
204
+ color: '#fff',
205
+ bgcolor: 'rgba(158,158,158, 0.6);',
206
+ borderRadius: 1,
207
+ cursor: 'pointer'
208
+ },
209
+ onClick: toggleFullPage,
210
+ children: inFullPage ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_CloseFullscreen.default, {
211
+ style: {
212
+ fontSize: 18
213
+ }
214
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_OpenInFull.default, {
215
+ style: {
216
+ fontSize: 18
217
+ }
218
+ })
219
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Container.default, _objectSpread(_objectSpread({
181
220
  className: "dashboard-content"
182
221
  }, fullWidth && {
183
222
  maxWidth: false
184
223
  }), {}, {
185
224
  children: children
186
- })), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Footer.default, _objectSpread({}, footerProps))]
225
+ })), footerVisible && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Footer.default, _objectSpread({}, footerProps))]
187
226
  })]
188
227
  })]
189
228
  }));
@@ -209,7 +248,7 @@ Dashboard.defaultProps = {
209
248
  };
210
249
  const Wrapper = (0, _Theme.styled)('div', {
211
250
  shouldForwardProp: prop => prop !== 'sidebarWidth'
212
- })(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n &.dashboard {\n display: flex;\n flex-direction: column;\n height: 100vh;\n }\n .dashboard-body {\n overflow: hidden;\n flex: 1;\n }\n .dashboard-sidebar {\n box-sizing: border-box;\n flex: 0 0 auto;\n width: ", "px;\n overflow: hidden;\n &:hover {\n overflow-y: auto;\n }\n }\n .dashboard-main {\n display: flex;\n flex-direction: column;\n overflow: auto;\n flex: 1;\n }\n .dashboard-content {\n flex: 1;\n }\n &.dashboard-dense {\n .dashboard-header {\n border-bottom: 1px solid #eee;\n }\n .dashboard-sidebar {\n width: 256px;\n border-right: 1px solid #eee;\n }\n }\n ", " {\n .header-logo {\n display: flex;\n justify-content: center;\n /* logo \u4E0E sidebar \u4E2D\u7684 icon \u5782\u76F4\u5BF9\u9F50, sidebarWidth - 24 * 2 */\n width: ", "px;\n }\n &.dashboard-dense {\n .header-logo {\n /* dense = true \u65F6 logo \u4E0E sidenav icons \u4E0D\u9700\u8981\u5BF9\u9F50 */\n width: auto;\n }\n }\n }\n"])), props => props.sidebarWidth, props => props.theme.breakpoints.up('md'), props => props.sidebarWidth - 24 * 2);
251
+ })(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n &.dashboard {\n display: flex;\n flex-direction: column;\n height: 100vh;\n }\n .dashboard-body {\n overflow: hidden;\n flex: 1;\n }\n .dashboard-sidebar {\n box-sizing: border-box;\n flex: 0 0 auto;\n width: ", "px;\n overflow: hidden;\n &:hover {\n overflow-y: auto;\n }\n }\n .dashboard-main {\n display: flex;\n flex-direction: column;\n overflow: auto;\n flex: 1;\n position: relative;\n }\n .dashboard-content {\n flex: 1;\n }\n &.dashboard-dense {\n .dashboard-header {\n border-bottom: 1px solid #eee;\n }\n .dashboard-sidebar {\n width: 256px;\n border-right: 1px solid #eee;\n }\n }\n ", " {\n .header-logo {\n display: flex;\n justify-content: center;\n /* logo \u4E0E sidebar \u4E2D\u7684 icon \u5782\u76F4\u5BF9\u9F50, sidebarWidth - 24 * 2 */\n width: ", "px;\n }\n &.dashboard-dense {\n .header-logo {\n /* dense = true \u65F6 logo \u4E0E sidenav icons \u4E0D\u9700\u8981\u5BF9\u9F50 */\n width: auto;\n }\n }\n }\n"])), props => props.sidebarWidth, props => props.theme.breakpoints.up('md'), props => props.sidebarWidth - 24 * 2);
213
252
  const StyledUxHeader = (0, _Theme.styled)(_Header.ResponsiveHeader)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n .header-container {\n max-width: 100%;\n }\n"]))); // 兼容旧版 dashboard
214
253
 
215
254
  function DashboardWrapper(_ref4) {
@@ -222,7 +261,9 @@ function DashboardWrapper(_ref4) {
222
261
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_dashboardLegacy.default, _objectSpread({}, rest));
223
262
  }
224
263
 
225
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Dashboard, _objectSpread({}, rest));
264
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_fullPage.FullPageProvider, {
265
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Dashboard, _objectSpread({}, rest))
266
+ });
226
267
  }
227
268
 
228
269
  DashboardWrapper.propTypes = _objectSpread(_objectSpread({}, Dashboard.propTypes), {}, {
@@ -122,6 +122,6 @@ Sidebar.defaultProps = {
122
122
  dense: false
123
123
  };
124
124
  const gradient = 'linear-gradient(32deg, rgba(144, 255, 230, 0.1), rgba(144, 255, 230, 0))';
125
- const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n .layout-sidebar-link {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 22px 24px;\n color: ", ";\n text-decoration: none;\n\n &:hover,\n &.layout-sidebar-link--active {\n color: ", ";\n background: ", ";\n border-left-color: ", ";\n }\n }\n .layout-sidebar-icon {\n display: inline-block;\n width: 32px;\n height: 32px;\n > img,\n > svg {\n width: 32px;\n height: 32px;\n }\n }\n .layout-sidebar-badge {\n position: relative;\n &:after {\n content: '';\n position: absolute;\n width: 10px;\n height: 10px;\n border-radius: 10px;\n background-color: #fe4e44;\n right: -2px;\n top: 0;\n box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3), 0px 0px 20px rgba(0, 0, 0, 0.1);\n }\n }\n .layout-sidebar-link-text {\n margin-top: 8px;\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n text-transform: capitalize;\n letter-spacing: normal;\n }\n &.layout-sidebar-dense {\n box-sizing: border-box;\n padding: 20px 0;\n font-weight: bold;\n .layout-sidebar-item {\n padding: 0 16px;\n }\n .layout-sidebar-item + .layout-sidebar-item {\n margin-top: 1px;\n }\n .layout-sidebar-link {\n box-sizing: border-box;\n flex-direction: row;\n align-items: center;\n width: 100%;\n padding: 8px;\n &:hover,\n &.layout-sidebar-link--active {\n color: ", ";\n background: ", ";\n border: 0;\n border-radius: 4px;\n }\n }\n .layout-sidebar-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n margin-right: 8px;\n > img,\n > svg {\n width: 20px;\n height: 20px;\n }\n }\n .layout-sidebar-badge {\n &:after {\n width: 6px;\n height: 6px;\n border-radius: 6px;\n right: -2px;\n top: 0;\n }\n }\n .layout-sidebar-link-text {\n margin-top: 0;\n font-size: 14px;\n line-height: 1;\n }\n .layout-sidebar-group {\n color: ", ";\n .layout-sidebar-group-title {\n display: inline-block;\n padding: 8px 0 8px 24px;\n font-size: 13px;\n text-transform: uppercase;\n }\n }\n .layout-sidebar-group + .layout-sidebar-group,\n .layout-sidebar-group + .layout-sidebar-item,\n .layout-sidebar-item + .layout-sidebar-group {\n margin-top: 16px;\n }\n }\n"])), props => props.theme.palette.text.secondary, props => props.theme.palette.primary.main, gradient, _colors.teal.A700, props => props.theme.palette.grey[900], props => props.theme.palette.grey[100], props => props.theme.palette.text.hint);
125
+ const Root = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n flex-direction: column;\n ul {\n list-style: none;\n margin: 0;\n padding: 0;\n }\n .layout-sidebar-link {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 22px 24px;\n color: ", ";\n text-decoration: none;\n\n &:hover,\n &.layout-sidebar-link--active {\n color: ", ";\n background: ", ";\n border-left-color: ", ";\n }\n }\n .layout-sidebar-icon {\n display: inline-block;\n width: 32px;\n height: 32px;\n > img,\n > svg {\n width: 32px;\n height: 32px;\n }\n }\n .layout-sidebar-badge {\n position: relative;\n &:after {\n content: '';\n position: absolute;\n width: 10px;\n height: 10px;\n border-radius: 10px;\n background-color: #fe4e44;\n right: -2px;\n top: 0;\n box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3), 0px 0px 20px rgba(0, 0, 0, 0.1);\n }\n }\n .layout-sidebar-link-text {\n margin-top: 8px;\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n text-transform: capitalize;\n letter-spacing: normal;\n }\n /* dense=false \u65F6\u9690\u85CF group title */\n .layout-sidebar-group-title {\n display: none;\n }\n &.layout-sidebar-dense {\n box-sizing: border-box;\n padding: 20px 0;\n font-weight: bold;\n .layout-sidebar-item {\n padding: 0 16px;\n }\n .layout-sidebar-item + .layout-sidebar-item {\n margin-top: 1px;\n }\n .layout-sidebar-link {\n box-sizing: border-box;\n flex-direction: row;\n align-items: center;\n width: 100%;\n padding: 8px;\n &:hover,\n &.layout-sidebar-link--active {\n color: ", ";\n background: ", ";\n border: 0;\n border-radius: 4px;\n }\n }\n .layout-sidebar-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n margin-right: 8px;\n > img,\n > svg {\n width: 20px;\n height: 20px;\n }\n }\n .layout-sidebar-badge {\n &:after {\n width: 6px;\n height: 6px;\n border-radius: 6px;\n right: -2px;\n top: 0;\n }\n }\n .layout-sidebar-link-text {\n margin-top: 0;\n font-size: 14px;\n line-height: 1;\n }\n .layout-sidebar-group {\n color: ", ";\n .layout-sidebar-group-title {\n display: inline-block;\n padding: 8px 0 8px 24px;\n font-size: 13px;\n text-transform: uppercase;\n }\n }\n .layout-sidebar-group + .layout-sidebar-group,\n .layout-sidebar-group + .layout-sidebar-item,\n .layout-sidebar-item + .layout-sidebar-group {\n margin-top: 16px;\n }\n }\n"])), props => props.theme.palette.text.secondary, props => props.theme.palette.primary.main, gradient, _colors.teal.A700, props => props.theme.palette.grey[900], props => props.theme.palette.grey[100], props => props.theme.palette.text.hint);
126
126
  var _default = Sidebar;
127
127
  exports.default = _default;
@@ -145,4 +145,4 @@ SplitButton.defaultProps = {
145
145
  };
146
146
  SplitButton.Item = _MenuItem.default;
147
147
  const StyledButtonGroup = (0, _Theme.styled)(_ButtonGroup.default)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n > .MuiButtonBase-root:last-child {\n min-width: 2em;\n padding-left: 0;\n padding-right: 0;\n }\n"])));
148
- const StyledPopper = (0, _Theme.styled)(_Popper.default)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n .MuiList-root {\n padding: 4px 0;\n }\n .MuiListItem-root {\n padding-top: 4px;\n padding-bottom: 4px;\n }\n"])));
148
+ const StyledPopper = (0, _Theme.styled)(_Popper.default)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n z-index: ", ";\n .MuiList-root {\n padding: 4px 0;\n }\n .MuiListItem-root {\n padding-top: 4px;\n padding-bottom: 4px;\n }\n"])), props => props.theme.zIndex.tooltip);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.4.65",
3
+ "version": "2.4.67",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -47,11 +47,11 @@
47
47
  "react": ">=18.1.0",
48
48
  "react-ga": "^2.7.0"
49
49
  },
50
- "gitHead": "54eb0e1aefdc859dee7c8883f4d9c89c5aa70273",
50
+ "gitHead": "00faa076b7c78a8202b800dc35482b2cc431431b",
51
51
  "dependencies": {
52
52
  "@arcblock/did-motif": "^1.1.10",
53
- "@arcblock/icons": "^2.4.65",
54
- "@arcblock/react-hooks": "^2.4.65",
53
+ "@arcblock/icons": "^2.4.67",
54
+ "@arcblock/react-hooks": "^2.4.67",
55
55
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
56
56
  "@emotion/react": "^11.10.4",
57
57
  "@emotion/styled": "^11.10.4",
@@ -0,0 +1,47 @@
1
+ import { useState, useContext, createContext, useMemo, useLayoutEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ export const FullPageContext = createContext();
5
+
6
+ export const useFullPage = (initialState) => {
7
+ const ctx = useContext(FullPageContext);
8
+ useLayoutEffect(() => {
9
+ if (initialState) {
10
+ ctx.configure(initialState);
11
+ }
12
+ // eslint-disable-next-line react-hooks/exhaustive-deps
13
+ }, []);
14
+ return ctx;
15
+ };
16
+
17
+ export function FullPageProvider({ children, ...rest }) {
18
+ const [state, setState] = useState({
19
+ inFullPage: false,
20
+ showToggleButton: false,
21
+ headerVisibleInFullPage: true,
22
+ footerVisibleInFullPage: false,
23
+ sidebarVisibleInFullPage: false,
24
+ });
25
+ const toggleFullPage = () => {
26
+ setState((prev) => ({ ...prev, inFullPage: !prev.inFullPage }));
27
+ };
28
+ const value = useMemo(() => {
29
+ return {
30
+ ...state,
31
+ headerVisible: !state.inFullPage || state.headerVisibleInFullPage,
32
+ footerVisible: !state.inFullPage || state.footerVisibleInFullPage,
33
+ sidebarVisible: !state.inFullPage || state.sidebarVisibleInFullPage,
34
+ toggleFullPage,
35
+ configure: (params) => setState((prev) => ({ ...prev, ...params })),
36
+ };
37
+ }, [state]);
38
+ return (
39
+ <FullPageContext.Provider value={value} {...rest}>
40
+ {children}
41
+ </FullPageContext.Provider>
42
+ );
43
+ }
44
+
45
+ FullPageProvider.propTypes = {
46
+ children: PropTypes.node.isRequired,
47
+ };
@@ -6,6 +6,8 @@ import Container from '@mui/material/Container';
6
6
  import Hidden from '@mui/material/Hidden';
7
7
  import Box from '@mui/material/Box';
8
8
  import clsx from 'clsx';
9
+ import OpenInFullIcon from '@mui/icons-material/OpenInFull';
10
+ import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen';
9
11
  import DashboardLegacy from '../dashboard-legacy';
10
12
  import { ResponsiveHeader } from '../../Header';
11
13
  import NavMenu from '../../NavMenu';
@@ -13,6 +15,7 @@ import Footer from '../../Footer';
13
15
  import Sidebar from './sidebar';
14
16
  import { styled, useTheme } from '../../Theme';
15
17
  import { Link } from './external-link';
18
+ import { FullPageProvider, useFullPage } from './full-page';
16
19
 
17
20
  // 监听 location 变化并关闭 header 中的 menu (确保 drawer - disablePortal:false, keepMounted:true)
18
21
  // 直接监听 menu 中 link 点击来触发 closeMenu 会有问题 (Suspense & lazy)
@@ -50,6 +53,7 @@ function formatLinks(links, location) {
50
53
 
51
54
  function Dashboard({ children, title, headerProps, links = [], fullWidth, dense, footerProps, ...rest }) {
52
55
  const theme = useTheme();
56
+ const { inFullPage, showToggleButton, headerVisible, footerVisible, sidebarVisible, toggleFullPage } = useFullPage();
53
57
  const location = useLocation();
54
58
  const navItems = useMemo(() => formatLinks(links, location), [location, links]);
55
59
  const isGroupedMode = navItems.some((item) => !!item.children?.length);
@@ -66,38 +70,64 @@ function Dashboard({ children, title, headerProps, links = [], fullWidth, dense,
66
70
  <Wrapper {...rest} className={classes}>
67
71
  <Helmet title={title} key={title} />
68
72
 
69
- <StyledUxHeader {..._headerProps} className="dashboard-header">
70
- {links?.length
71
- ? ({ isMobile, closeMenu }) => {
72
- if (isMobile) {
73
- return (
74
- <NavMenuWrapper
75
- mode="inline"
76
- items={navItems}
77
- closeMenu={closeMenu}
78
- bgColor="transparent"
79
- activeTextColor={theme.palette.primary.main}
80
- />
81
- );
73
+ {headerVisible && (
74
+ <StyledUxHeader {..._headerProps} className="dashboard-header">
75
+ {links?.length
76
+ ? ({ isMobile, closeMenu }) => {
77
+ if (isMobile) {
78
+ return (
79
+ <NavMenuWrapper
80
+ mode="inline"
81
+ items={navItems}
82
+ closeMenu={closeMenu}
83
+ bgColor="transparent"
84
+ activeTextColor={theme.palette.primary.main}
85
+ />
86
+ );
87
+ }
88
+ return null;
82
89
  }
83
- return null;
84
- }
85
- : null}
86
- </StyledUxHeader>
90
+ : null}
91
+ </StyledUxHeader>
92
+ )}
87
93
 
88
94
  <Box display="flex" className="dashboard-body">
89
95
  <Hidden mdDown>
90
- {!!links?.length && (
96
+ {!!links?.length && sidebarVisible && (
91
97
  <Box className="dashboard-sidebar">
92
98
  <Sidebar links={links} dense={_dense} />
93
99
  </Box>
94
100
  )}
95
101
  </Hidden>
96
102
  <Box className="dashboard-main">
103
+ {showToggleButton && (
104
+ <Box
105
+ sx={{
106
+ position: 'absolute',
107
+ top: 4,
108
+ right: 4,
109
+ display: 'flex',
110
+ justifyContent: 'center',
111
+ alignItems: 'center',
112
+ width: 24,
113
+ height: 24,
114
+ color: '#fff',
115
+ bgcolor: 'rgba(158,158,158, 0.6);',
116
+ borderRadius: 1,
117
+ cursor: 'pointer',
118
+ }}
119
+ onClick={toggleFullPage}>
120
+ {inFullPage ? (
121
+ <CloseFullscreenIcon style={{ fontSize: 18 }} />
122
+ ) : (
123
+ <OpenInFullIcon style={{ fontSize: 18 }} />
124
+ )}
125
+ </Box>
126
+ )}
97
127
  <Container className="dashboard-content" {...(fullWidth && { maxWidth: false })}>
98
128
  {children}
99
129
  </Container>
100
- <Footer {...footerProps} />
130
+ {footerVisible && <Footer {...footerProps} />}
101
131
  </Box>
102
132
  </Box>
103
133
  </Wrapper>
@@ -150,6 +180,7 @@ const Wrapper = styled('div', {
150
180
  flex-direction: column;
151
181
  overflow: auto;
152
182
  flex: 1;
183
+ position: relative;
153
184
  }
154
185
  .dashboard-content {
155
186
  flex: 1;
@@ -190,7 +221,11 @@ export default function DashboardWrapper({ legacy, ...rest }) {
190
221
  if (legacy) {
191
222
  return <DashboardLegacy {...rest} />;
192
223
  }
193
- return <Dashboard {...rest} />;
224
+ return (
225
+ <FullPageProvider>
226
+ <Dashboard {...rest} />
227
+ </FullPageProvider>
228
+ );
194
229
  }
195
230
 
196
231
  DashboardWrapper.propTypes = {
@@ -116,6 +116,10 @@ const Root = styled('div')`
116
116
  text-transform: capitalize;
117
117
  letter-spacing: normal;
118
118
  }
119
+ /* dense=false 时隐藏 group title */
120
+ .layout-sidebar-group-title {
121
+ display: none;
122
+ }
119
123
  &.layout-sidebar-dense {
120
124
  box-sizing: border-box;
121
125
  padding: 20px 0;
@@ -96,6 +96,7 @@ const StyledButtonGroup = styled(ButtonGroup)`
96
96
  `;
97
97
 
98
98
  const StyledPopper = styled(Popper)`
99
+ z-index: ${(props) => props.theme.zIndex.tooltip};
99
100
  .MuiList-root {
100
101
  padding: 4px 0;
101
102
  }