@zat-design/sisyphus-react 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -75,14 +75,14 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
75
75
  confirm?: boolean | import("antd").ModalFuncProps | import("../../../render/propsType").FunctionArgs<any, boolean | import("antd").ModalFuncProps>;
76
76
  show?: boolean | ReactiveFunction<any, boolean>;
77
77
  component?: React.ReactNode | ReactiveFunction<any, React.ReactNode>;
78
- style?: React.CSSProperties;
79
- id?: string;
80
- children?: React.ReactNode | ((form: FormInstance<any>) => React.ReactNode);
81
78
  trim?: boolean;
82
79
  normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
83
- className?: string;
80
+ children?: React.ReactNode | ((form: FormInstance<any>) => React.ReactNode);
84
81
  vertical?: boolean;
82
+ id?: string;
83
+ className?: string;
85
84
  hidden?: boolean;
85
+ style?: React.CSSProperties;
86
86
  onReset?: () => void;
87
87
  prefixCls?: string;
88
88
  rootClassName?: string;
@@ -92,9 +92,6 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
92
92
  isView?: boolean;
93
93
  desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
94
94
  getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
95
- layout?: import("antd/es/form/Form").FormItemLayout;
96
- help?: React.ReactNode;
97
- preserve?: boolean;
98
95
  htmlFor?: string;
99
96
  labelAlign?: import("antd/es/form/interface").FormLabelAlign;
100
97
  labelCol?: import("antd").ColProps;
@@ -106,6 +103,7 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
106
103
  messageVariables?: Record<string, string>;
107
104
  initialValue?: any;
108
105
  onMetaChange?: (meta: import("@rc-component/form/lib/Field").MetaEvent) => void;
106
+ preserve?: boolean;
109
107
  isListField?: boolean;
110
108
  isList?: boolean;
111
109
  noStyle?: boolean;
@@ -113,7 +111,9 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
113
111
  icons: import("antd/es/form/FormItem").FeedbackIcons;
114
112
  };
115
113
  validateStatus?: "" | "success" | "error" | "warning" | "validating";
114
+ layout?: import("antd/es/form/Form").FormItemLayout;
116
115
  wrapperCol?: import("antd").ColProps;
116
+ help?: React.ReactNode;
117
117
  fieldId?: string;
118
118
  valueType?: import("../../../render/propsType").ProFormValueType;
119
119
  switchValue?: [any, any];
@@ -24,7 +24,9 @@ var OpenMenu = props => {
24
24
  var className = props.className,
25
25
  dataSource = props.dataSource,
26
26
  style = props.style,
27
- onMenuClick = props.onMenuClick;
27
+ onMenuClick = props.onMenuClick,
28
+ _props$textVisible = props.textVisible,
29
+ textVisible = _props$textVisible === void 0 ? true : _props$textVisible;
28
30
  var _ref = dataSource || {},
29
31
  menus = _ref.menus,
30
32
  sideMenu = _ref.sideMenu;
@@ -48,6 +50,7 @@ var OpenMenu = props => {
48
50
  var layoutTarget = layoutContext === null || layoutContext === void 0 ? void 0 : layoutContext.target;
49
51
  var cls = classnames({
50
52
  'pro-layout-open-menu': true,
53
+ 'pro-layout-menu-text-hidden': textVisible === false,
51
54
  [`${className}`]: className
52
55
  });
53
56
 
@@ -1,6 +1,17 @@
1
1
  @import '../../../../../../style/variables.less';
2
2
 
3
3
  .pro-layout-open-menu {
4
+ // 展开动画期间(Menu 传入 textVisible=false)隐藏文字,避免”挤压式逐字出现”;宽度过渡结束后再淡入
5
+ &.pro-layout-menu-text-hidden {
6
+ .@{ant-prefix}-menu-title-content {
7
+ div {
8
+ h2 {
9
+ opacity: 0 !important;
10
+ transition: none !important; // 确保隐藏时无过渡动画
11
+ }
12
+ }
13
+ }
14
+ }
4
15
 
5
16
  .@{ant-prefix}-menu-root {
6
17
  overflow-y: auto !important;
@@ -98,7 +109,8 @@
98
109
  font-weight: 400;
99
110
  font-size: var(--zaui-font-size-md, 14px);
100
111
  opacity: 1;
101
- transition: opacity 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), margin 0.3s, color 0.3s;
112
+ // 修改:添加 150ms opacity 淡入动画,消除"突然出现"的卡顿感
113
+ transition: opacity 0.15s ease-out, margin 0.3s, color 0.3s;
102
114
  }
103
115
  }
104
116
  }
@@ -78,9 +78,24 @@
78
78
  overflow-x: hidden;
79
79
  overflow-y: auto;
80
80
 
81
+ // 与展开态一致:hover 使用透明背景 + 左侧品牌色半透明条
81
82
  .@{ant-prefix}-menu-submenu-title:hover,
82
83
  .@{ant-prefix}-menu-item:hover {
83
- background-color: transparent;
84
+ position: relative;
85
+ background-color: transparent !important;
86
+
87
+ &::before {
88
+ position: absolute;
89
+ left: var(--zaui-space-size-sm, 8px);
90
+ right: var(--zaui-space-size-sm, 8px);
91
+ width: auto;
92
+ min-height: 38px;
93
+ height: 80%;
94
+ background-color: var(--zaui-brand, #006aff);
95
+ border-radius: var(--zaui-border-radius, 8px);
96
+ opacity: 0.08;
97
+ content: '';
98
+ }
84
99
  }
85
100
 
86
101
  .@{ant-prefix}-menu-item {
@@ -1,9 +1,24 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ 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."); }
3
+ 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); }
4
+ 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; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { useEffect, useRef, useState, useCallback } from 'react';
1
8
  import classnames from 'classnames';
2
9
  import OpenMenu from "./OpenMenu";
3
10
  import FoldMenu from "./FoldMenu"; // 折叠后菜单
4
11
  import { Fragment as _Fragment } from "react/jsx-runtime";
5
12
  import { jsx as _jsx } from "react/jsx-runtime";
6
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
14
+ // 菜单宽度配置
15
+ var MENU_CONFIG = {
16
+ TRANSITION_DURATION: 300,
17
+ // 宽度过渡时长(ms)
18
+ TEXT_VISIBLE_THRESHOLD: 150,
19
+ // 文字显示阈值(px, 约68%展开)
20
+ FULL_WIDTH: 219 // 完全展开宽度(px)
21
+ };
7
22
  var Menu = props => {
8
23
  var _ref = props || {},
9
24
  headerHeight = _ref.headerHeight,
@@ -17,6 +32,83 @@ var Menu = props => {
17
32
  sideMenuHeaderRender = _ref.sideMenuHeaderRender,
18
33
  onMenuClick = _ref.onMenuClick;
19
34
  var menus = [];
35
+ var menuRef = useRef(null);
36
+ // 整合所有动画相关的refs
37
+ var animationStateRef = useRef({
38
+ timer: null,
39
+ observer: null,
40
+ hasTriggered: false
41
+ });
42
+ var _useState = useState(false),
43
+ _useState2 = _slicedToArray(_useState, 2),
44
+ isOpenMenuTextVisible = _useState2[0],
45
+ setIsOpenMenuTextVisible = _useState2[1];
46
+
47
+ // 提取清理逻辑
48
+ var cleanupAnimation = useCallback(() => {
49
+ var state = animationStateRef.current;
50
+ if (state.timer) {
51
+ clearTimeout(state.timer);
52
+ state.timer = null;
53
+ }
54
+ if (state.observer) {
55
+ try {
56
+ state.observer.disconnect();
57
+ } catch (e) {
58
+ console.warn('ResizeObserver disconnect failed:', e);
59
+ }
60
+ state.observer = null;
61
+ }
62
+ }, []);
63
+
64
+ // 触发文字显示
65
+ var showMenuText = useCallback(() => {
66
+ var state = animationStateRef.current;
67
+ if (state.hasTriggered) return;
68
+ state.hasTriggered = true;
69
+ setIsOpenMenuTextVisible(true);
70
+ // 延迟清理,避免回调内竞态
71
+ setTimeout(cleanupAnimation, 0);
72
+ }, [cleanupAnimation]);
73
+
74
+ // ResizeObserver 监听宽度变化,提前显示文字
75
+ useEffect(() => {
76
+ var _menuRef$current$getB, _menuRef$current, _menuRef$current$getB2;
77
+ var state = animationStateRef.current;
78
+ state.hasTriggered = false;
79
+
80
+ // 折叠态:清理并隐藏文字
81
+ if (!collapsed) {
82
+ setIsOpenMenuTextVisible(false);
83
+ cleanupAnimation();
84
+ return;
85
+ }
86
+
87
+ // 检查是否已展开
88
+ var currentWidth = (_menuRef$current$getB = (_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 || (_menuRef$current$getB2 = _menuRef$current.getBoundingClientRect) === null || _menuRef$current$getB2 === void 0 ? void 0 : _menuRef$current$getB2.call(_menuRef$current).width) !== null && _menuRef$current$getB !== void 0 ? _menuRef$current$getB : 0;
89
+ if (currentWidth >= MENU_CONFIG.FULL_WIDTH) {
90
+ state.hasTriggered = true;
91
+ setIsOpenMenuTextVisible(true);
92
+ return;
93
+ }
94
+
95
+ // 创建 ResizeObserver
96
+ var supportsResizeObserver = typeof ResizeObserver !== 'undefined';
97
+ if (supportsResizeObserver && menuRef.current) {
98
+ state.observer = new ResizeObserver(entries => {
99
+ var _entries$0$contentRec, _entries$;
100
+ var width = (_entries$0$contentRec = (_entries$ = entries[0]) === null || _entries$ === void 0 ? void 0 : _entries$.contentRect.width) !== null && _entries$0$contentRec !== void 0 ? _entries$0$contentRec : 0;
101
+ if (width >= MENU_CONFIG.TEXT_VISIBLE_THRESHOLD) {
102
+ showMenuText();
103
+ }
104
+ });
105
+ state.observer.observe(menuRef.current);
106
+ }
107
+
108
+ // Fallback:定时器保底
109
+ state.timer = setTimeout(showMenuText, MENU_CONFIG.TRANSITION_DURATION);
110
+ return cleanupAnimation;
111
+ }, [collapsed, cleanupAnimation, showMenuText]);
20
112
  var menuCls = classnames({
21
113
  'pro-layout-menu': true,
22
114
  'pro-layout-menu-open': collapsed
@@ -30,10 +122,17 @@ var Menu = props => {
30
122
  return /*#__PURE__*/_jsx(_Fragment, {});
31
123
  }
32
124
  return /*#__PURE__*/_jsxs("div", {
125
+ ref: menuRef,
33
126
  className: menuCls,
34
127
  style: {
35
128
  top: notice ? 96 + headerHeight - 64 : headerHeight
36
129
  },
130
+ onTransitionEnd: e => {
131
+ // Fallback:确保宽度过渡结束后文字一定显示
132
+ if (e.propertyName === 'width' && e.target === menuRef.current && collapsed) {
133
+ showMenuText();
134
+ }
135
+ },
37
136
  children: [sideMenuHeaderRender, /*#__PURE__*/_jsx(OpenMenu, {
38
137
  dataSource: {
39
138
  menus,
@@ -41,6 +140,7 @@ var Menu = props => {
41
140
  height: headerHeight + (notice ? 32 : 0) + 48
42
141
  },
43
142
  onMenuClick: onMenuClick,
143
+ textVisible: isOpenMenuTextVisible,
44
144
  style: {
45
145
  display: collapsed ? 'block' : 'none'
46
146
  }
@@ -60,7 +160,10 @@ var Menu = props => {
60
160
  }
61
161
  }), sideMenuFooterRender || /*#__PURE__*/_jsx("div", {
62
162
  className: "pro-layout-menu-collapsed",
63
- onClick: onToggle,
163
+ onClick: () => {
164
+ setIsOpenMenuTextVisible(false);
165
+ onToggle === null || onToggle === void 0 || onToggle();
166
+ },
64
167
  children: /*#__PURE__*/_jsx("div", {
65
168
  className: "pro-layout-arrow "
66
169
  })
@@ -75,45 +75,43 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
75
75
  confirm?: boolean | import("antd").ModalFuncProps | import("../../../render/propsType").FunctionArgs<any, boolean | import("antd").ModalFuncProps>;
76
76
  show?: boolean | ReactiveFunction<any, boolean>;
77
77
  component?: React.ReactNode | ReactiveFunction<any, React.ReactNode>;
78
- style?: React.CSSProperties;
79
78
  id?: string;
80
- children?: React.ReactNode | ((form: FormInstance<any>) => React.ReactNode);
81
- trim?: boolean;
82
- normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
83
79
  className?: string;
84
- vertical?: boolean;
85
80
  hidden?: boolean;
81
+ style?: React.CSSProperties;
82
+ children?: React.ReactNode | ((form: FormInstance<any>) => React.ReactNode);
86
83
  onReset?: () => void;
87
84
  prefixCls?: string;
85
+ status?: "" | "warning" | "error" | "success" | "validating";
88
86
  rootClassName?: string;
89
- status?: "" | "success" | "error" | "warning" | "validating";
90
- trigger?: string;
91
- colon?: boolean;
92
87
  isView?: boolean;
93
- desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
94
- getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
95
- layout?: import("antd/es/form/Form").FormItemLayout;
96
- help?: React.ReactNode;
97
- preserve?: boolean;
88
+ colon?: boolean;
98
89
  htmlFor?: string;
99
90
  labelAlign?: import("antd/es/form/interface").FormLabelAlign;
100
91
  labelCol?: import("antd").ColProps;
92
+ vertical?: boolean;
101
93
  getValueFromEvent?: (...args: import("@rc-component/form/lib/interface").EventArgs) => any;
94
+ normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
102
95
  shouldUpdate?: import("@rc-component/form/lib/Field").ShouldUpdate<any>;
96
+ trigger?: string;
103
97
  validateTrigger?: string | false | string[];
104
98
  validateDebounce?: number;
105
99
  valuePropName?: string;
100
+ getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
106
101
  messageVariables?: Record<string, string>;
107
102
  initialValue?: any;
108
103
  onMetaChange?: (meta: import("@rc-component/form/lib/Field").MetaEvent) => void;
104
+ preserve?: boolean;
109
105
  isListField?: boolean;
110
106
  isList?: boolean;
111
107
  noStyle?: boolean;
112
108
  hasFeedback?: boolean | {
113
109
  icons: import("antd/es/form/FormItem").FeedbackIcons;
114
110
  };
115
- validateStatus?: "" | "success" | "error" | "warning" | "validating";
111
+ validateStatus?: "" | "warning" | "error" | "success" | "validating";
112
+ layout?: import("antd/es/form/Form").FormItemLayout;
116
113
  wrapperCol?: import("antd").ColProps;
114
+ help?: React.ReactNode;
117
115
  fieldId?: string;
118
116
  valueType?: import("../../../render/propsType").ProFormValueType;
119
117
  switchValue?: [any, any];
@@ -123,10 +121,12 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
123
121
  index?: number;
124
122
  }) => string | React.ReactElement<any, any>;
125
123
  viewType?: import("../../../render/propsType").ViewType;
124
+ trim?: boolean;
126
125
  upperCase?: boolean;
127
126
  toISOString?: boolean;
128
127
  toCSTString?: boolean;
129
128
  clearNotShow?: boolean;
129
+ desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
130
130
  name: any;
131
131
  dependencies: any[];
132
132
  tooltip: string | {
@@ -29,7 +29,9 @@ var OpenMenu = props => {
29
29
  var className = props.className,
30
30
  dataSource = props.dataSource,
31
31
  style = props.style,
32
- onMenuClick = props.onMenuClick;
32
+ onMenuClick = props.onMenuClick,
33
+ _props$textVisible = props.textVisible,
34
+ textVisible = _props$textVisible === void 0 ? true : _props$textVisible;
33
35
  var _ref = dataSource || {},
34
36
  menus = _ref.menus,
35
37
  sideMenu = _ref.sideMenu;
@@ -53,6 +55,7 @@ var OpenMenu = props => {
53
55
  var layoutTarget = layoutContext === null || layoutContext === void 0 ? void 0 : layoutContext.target;
54
56
  var cls = (0, _classnames.default)({
55
57
  'pro-layout-open-menu': true,
58
+ 'pro-layout-menu-text-hidden': textVisible === false,
56
59
  [`${className}`]: className
57
60
  });
58
61
 
@@ -1,6 +1,17 @@
1
1
  @import '../../../../../../style/variables.less';
2
2
 
3
3
  .pro-layout-open-menu {
4
+ // 展开动画期间(Menu 传入 textVisible=false)隐藏文字,避免”挤压式逐字出现”;宽度过渡结束后再淡入
5
+ &.pro-layout-menu-text-hidden {
6
+ .@{ant-prefix}-menu-title-content {
7
+ div {
8
+ h2 {
9
+ opacity: 0 !important;
10
+ transition: none !important; // 确保隐藏时无过渡动画
11
+ }
12
+ }
13
+ }
14
+ }
4
15
 
5
16
  .@{ant-prefix}-menu-root {
6
17
  overflow-y: auto !important;
@@ -98,7 +109,8 @@
98
109
  font-weight: 400;
99
110
  font-size: var(--zaui-font-size-md, 14px);
100
111
  opacity: 1;
101
- transition: opacity 0.3s cubic-bezier(0.645, 0.045, 0.355, 1), margin 0.3s, color 0.3s;
112
+ // 修改:添加 150ms opacity 淡入动画,消除"突然出现"的卡顿感
113
+ transition: opacity 0.15s ease-out, margin 0.3s, color 0.3s;
102
114
  }
103
115
  }
104
116
  }
@@ -78,9 +78,24 @@
78
78
  overflow-x: hidden;
79
79
  overflow-y: auto;
80
80
 
81
+ // 与展开态一致:hover 使用透明背景 + 左侧品牌色半透明条
81
82
  .@{ant-prefix}-menu-submenu-title:hover,
82
83
  .@{ant-prefix}-menu-item:hover {
83
- background-color: transparent;
84
+ position: relative;
85
+ background-color: transparent !important;
86
+
87
+ &::before {
88
+ position: absolute;
89
+ left: var(--zaui-space-size-sm, 8px);
90
+ right: var(--zaui-space-size-sm, 8px);
91
+ width: auto;
92
+ min-height: 38px;
93
+ height: 80%;
94
+ background-color: var(--zaui-brand, #006aff);
95
+ border-radius: var(--zaui-border-radius, 8px);
96
+ opacity: 0.08;
97
+ content: '';
98
+ }
84
99
  }
85
100
 
86
101
  .@{ant-prefix}-menu-item {
@@ -4,13 +4,26 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _react = require("react");
7
8
  var _classnames = _interopRequireDefault(require("classnames"));
8
9
  var _OpenMenu = _interopRequireDefault(require("./OpenMenu"));
9
10
  var _FoldMenu = _interopRequireDefault(require("./FoldMenu"));
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
- // 折叠后菜单
13
-
13
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
14
+ 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."); }
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
+ 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; }
17
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
18
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // 折叠后菜单
19
+ // 菜单宽度配置
20
+ var MENU_CONFIG = {
21
+ TRANSITION_DURATION: 300,
22
+ // 宽度过渡时长(ms)
23
+ TEXT_VISIBLE_THRESHOLD: 150,
24
+ // 文字显示阈值(px, 约68%展开)
25
+ FULL_WIDTH: 219 // 完全展开宽度(px)
26
+ };
14
27
  var Menu = props => {
15
28
  var _ref = props || {},
16
29
  headerHeight = _ref.headerHeight,
@@ -24,6 +37,83 @@ var Menu = props => {
24
37
  sideMenuHeaderRender = _ref.sideMenuHeaderRender,
25
38
  onMenuClick = _ref.onMenuClick;
26
39
  var menus = [];
40
+ var menuRef = (0, _react.useRef)(null);
41
+ // 整合所有动画相关的refs
42
+ var animationStateRef = (0, _react.useRef)({
43
+ timer: null,
44
+ observer: null,
45
+ hasTriggered: false
46
+ });
47
+ var _useState = (0, _react.useState)(false),
48
+ _useState2 = _slicedToArray(_useState, 2),
49
+ isOpenMenuTextVisible = _useState2[0],
50
+ setIsOpenMenuTextVisible = _useState2[1];
51
+
52
+ // 提取清理逻辑
53
+ var cleanupAnimation = (0, _react.useCallback)(() => {
54
+ var state = animationStateRef.current;
55
+ if (state.timer) {
56
+ clearTimeout(state.timer);
57
+ state.timer = null;
58
+ }
59
+ if (state.observer) {
60
+ try {
61
+ state.observer.disconnect();
62
+ } catch (e) {
63
+ console.warn('ResizeObserver disconnect failed:', e);
64
+ }
65
+ state.observer = null;
66
+ }
67
+ }, []);
68
+
69
+ // 触发文字显示
70
+ var showMenuText = (0, _react.useCallback)(() => {
71
+ var state = animationStateRef.current;
72
+ if (state.hasTriggered) return;
73
+ state.hasTriggered = true;
74
+ setIsOpenMenuTextVisible(true);
75
+ // 延迟清理,避免回调内竞态
76
+ setTimeout(cleanupAnimation, 0);
77
+ }, [cleanupAnimation]);
78
+
79
+ // ResizeObserver 监听宽度变化,提前显示文字
80
+ (0, _react.useEffect)(() => {
81
+ var _menuRef$current$getB, _menuRef$current, _menuRef$current$getB2;
82
+ var state = animationStateRef.current;
83
+ state.hasTriggered = false;
84
+
85
+ // 折叠态:清理并隐藏文字
86
+ if (!collapsed) {
87
+ setIsOpenMenuTextVisible(false);
88
+ cleanupAnimation();
89
+ return;
90
+ }
91
+
92
+ // 检查是否已展开
93
+ var currentWidth = (_menuRef$current$getB = (_menuRef$current = menuRef.current) === null || _menuRef$current === void 0 || (_menuRef$current$getB2 = _menuRef$current.getBoundingClientRect) === null || _menuRef$current$getB2 === void 0 ? void 0 : _menuRef$current$getB2.call(_menuRef$current).width) !== null && _menuRef$current$getB !== void 0 ? _menuRef$current$getB : 0;
94
+ if (currentWidth >= MENU_CONFIG.FULL_WIDTH) {
95
+ state.hasTriggered = true;
96
+ setIsOpenMenuTextVisible(true);
97
+ return;
98
+ }
99
+
100
+ // 创建 ResizeObserver
101
+ var supportsResizeObserver = typeof ResizeObserver !== 'undefined';
102
+ if (supportsResizeObserver && menuRef.current) {
103
+ state.observer = new ResizeObserver(entries => {
104
+ var _entries$0$contentRec, _entries$;
105
+ var width = (_entries$0$contentRec = (_entries$ = entries[0]) === null || _entries$ === void 0 ? void 0 : _entries$.contentRect.width) !== null && _entries$0$contentRec !== void 0 ? _entries$0$contentRec : 0;
106
+ if (width >= MENU_CONFIG.TEXT_VISIBLE_THRESHOLD) {
107
+ showMenuText();
108
+ }
109
+ });
110
+ state.observer.observe(menuRef.current);
111
+ }
112
+
113
+ // Fallback:定时器保底
114
+ state.timer = setTimeout(showMenuText, MENU_CONFIG.TRANSITION_DURATION);
115
+ return cleanupAnimation;
116
+ }, [collapsed, cleanupAnimation, showMenuText]);
27
117
  var menuCls = (0, _classnames.default)({
28
118
  'pro-layout-menu': true,
29
119
  'pro-layout-menu-open': collapsed
@@ -37,10 +127,17 @@ var Menu = props => {
37
127
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {});
38
128
  }
39
129
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
130
+ ref: menuRef,
40
131
  className: menuCls,
41
132
  style: {
42
133
  top: notice ? 96 + headerHeight - 64 : headerHeight
43
134
  },
135
+ onTransitionEnd: e => {
136
+ // Fallback:确保宽度过渡结束后文字一定显示
137
+ if (e.propertyName === 'width' && e.target === menuRef.current && collapsed) {
138
+ showMenuText();
139
+ }
140
+ },
44
141
  children: [sideMenuHeaderRender, /*#__PURE__*/(0, _jsxRuntime.jsx)(_OpenMenu.default, {
45
142
  dataSource: {
46
143
  menus,
@@ -48,6 +145,7 @@ var Menu = props => {
48
145
  height: headerHeight + (notice ? 32 : 0) + 48
49
146
  },
50
147
  onMenuClick: onMenuClick,
148
+ textVisible: isOpenMenuTextVisible,
51
149
  style: {
52
150
  display: collapsed ? 'block' : 'none'
53
151
  }
@@ -67,7 +165,10 @@ var Menu = props => {
67
165
  }
68
166
  }), sideMenuFooterRender || /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
69
167
  className: "pro-layout-menu-collapsed",
70
- onClick: onToggle,
168
+ onClick: () => {
169
+ setIsOpenMenuTextVisible(false);
170
+ onToggle === null || onToggle === void 0 || onToggle();
171
+ },
71
172
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
72
173
  className: "pro-layout-arrow "
73
174
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zat-design/sisyphus-react",
3
- "version": "4.1.0",
3
+ "version": "4.1.1",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -92,6 +92,7 @@
92
92
  "@dnd-kit/utilities": "^3.2.1",
93
93
  "@rc-component/picker": "^1.9.0",
94
94
  "@zat-design/utils": "4.0.0",
95
+ "@zat-design/sisyphus-login": "4.0.0-beta.1",
95
96
  "ahooks": "3.9.5",
96
97
  "antd": "^6.2.2",
97
98
  "big.js": "^6.2.1",