@chaoswise/ui 2.7.8 → 2.7.10

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.
@@ -40,7 +40,25 @@ var localOptionsMap = {
40
40
  en_US: "enName",
41
41
  zh_TW: "name",
42
42
  zh: "name",
43
- zh_CN: "name"
43
+ zh_CN: "name",
44
+ ja: "jaName",
45
+ ja_JP: "jaName"
46
+ };
47
+
48
+ // 获取本地化字段名的方法,提供兜底逻辑
49
+ var getLocalizedField = function getLocalizedField(locale) {
50
+ return localOptionsMap[locale];
51
+ };
52
+
53
+ // 获取本地化的 tab 名称,最终兜底到 name 字段
54
+ var getLocalizedTabName = function getLocalizedTabName(item, locale) {
55
+ var fieldName = getLocalizedField(locale);
56
+ // 判断 item 中是否包含转换后的字段
57
+ if (fieldName && fieldName in item) {
58
+ return item[fieldName];
59
+ }
60
+ // 否则使用 name 字段
61
+ return item.name;
44
62
  };
45
63
  var MessageContent = function MessageContent(props) {
46
64
  var hideOnSinglePage = props.hideOnSinglePage,
@@ -226,7 +244,7 @@ var MessageContent = function MessageContent(props) {
226
244
  className: "cw-message-content-tabs",
227
245
  animated: false
228
246
  }, tabOption.map(function (item) {
229
- var tabName = item[localOptionsMap[locale]];
247
+ var tabName = getLocalizedTabName(item, locale);
230
248
  var moreTitle = formatMessage(localeObj["more"]);
231
249
  return /*#__PURE__*/React.createElement(TabPane, {
232
250
  tab: unreadTypeArr.includes(item.code) ? /*#__PURE__*/React.createElement(_Badge, {
@@ -253,6 +253,9 @@ var CWTable = function CWTable(_ref, ref) {
253
253
  var paginationHeight = 0;
254
254
  var tableHeaderHeight = 0;
255
255
  watcher.current = new ResizeObserver(function (entries) {
256
+ if (!tableRef.current) {
257
+ return;
258
+ }
256
259
  var _iterator = _createForOfIteratorHelper(entries),
257
260
  _step;
258
261
  try {
@@ -3,57 +3,213 @@ import _Icon from "@chaoswise/ui/lib/Icon";
3
3
  import _Menu from "@chaoswise/ui/lib/Menu";
4
4
  import "@chaoswise/ui/lib/TooltipText/index.less";
5
5
  import _TooltipText from "@chaoswise/ui/lib/TooltipText";
6
- import React, { useMemo } from "react";
6
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
7
+ 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."); }
8
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
+ 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; } }
11
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
12
+ import React, { useMemo, useRef, useEffect, useState, useCallback } from "react";
7
13
  import classnames from "classnames";
8
14
  import "./index.less";
9
- // 产品直接在头部容器中展示
10
15
  var TopNavigationMenu = function TopNavigationMenu(props) {
11
16
  var topNavigation = props.topNavigation,
12
17
  onClickTopNavigationSelf = props.onClickTopNavigationSelf,
13
18
  topNavigationOption = props.topNavigationOption;
14
- var _topNavigationOption$ = topNavigationOption.unfoldMaxCount,
15
- unfoldMaxCount = _topNavigationOption$ === void 0 ? 4 : _topNavigationOption$,
16
- _topNavigationOption$2 = topNavigationOption.activeKey,
17
- activeKey = _topNavigationOption$2 === void 0 ? "" : _topNavigationOption$2,
19
+ var _topNavigationOption$ = topNavigationOption.activeKey,
20
+ activeKey = _topNavigationOption$ === void 0 ? "" : _topNavigationOption$,
18
21
  moreOverlayClassName = topNavigationOption.moreOverlayClassName,
19
22
  topNavigationWrapperClassName = topNavigationOption.topNavigationWrapperClassName;
20
23
  var _activeKey = useMemo(function () {
21
24
  return activeKey;
22
25
  }, [activeKey]);
26
+ var wrapperRef = useRef(null);
27
+ var itemsRef = useRef([]);
28
+ var moreRef = useRef(null);
29
+ var _useState = useState(function () {
30
+ return (topNavigation === null || topNavigation === void 0 ? void 0 : topNavigation.length) || 0;
31
+ }),
32
+ _useState2 = _slicedToArray(_useState, 2),
33
+ visibleCount = _useState2[0],
34
+ setVisibleCount = _useState2[1];
35
+ var resizeTimeoutRef = useRef(null);
36
+ var debouncedFnRef = useRef(null);
37
+ var itemWidthsRef = useRef(null);
38
+ var moreWidthRef = useRef(44);
39
+ var isMeasuredRef = useRef(false);
40
+ var measureItems = useCallback(function () {
41
+ if (!topNavigation || !topNavigation.length || !wrapperRef.current) return false;
42
+ var widths = [];
43
+ for (var i = 0; i < topNavigation.length; i++) {
44
+ var _itemsRef$current$i;
45
+ var rect = (_itemsRef$current$i = itemsRef.current[i]) === null || _itemsRef$current$i === void 0 ? void 0 : _itemsRef$current$i.getBoundingClientRect();
46
+ if (rect && rect.width > 0) {
47
+ widths.push(rect.width);
48
+ } else {
49
+ return false;
50
+ }
51
+ }
52
+ if (widths.length === topNavigation.length) {
53
+ var _moreRef$current;
54
+ itemWidthsRef.current = widths;
55
+ var moreRect = (_moreRef$current = moreRef.current) === null || _moreRef$current === void 0 ? void 0 : _moreRef$current.getBoundingClientRect();
56
+ if (moreRect && moreRect.width > 0) {
57
+ moreWidthRef.current = moreRect.width;
58
+ }
59
+ isMeasuredRef.current = true;
60
+ return true;
61
+ }
62
+ return false;
63
+ }, [topNavigation]);
64
+ var updateVisibleCount = useCallback(function () {
65
+ if (!topNavigation || !topNavigation.length || !wrapperRef.current) {
66
+ setVisibleCount((topNavigation === null || topNavigation === void 0 ? void 0 : topNavigation.length) || 0);
67
+ return;
68
+ }
69
+ var wrapper = wrapperRef.current;
70
+ var containerWidth = wrapper.getBoundingClientRect().width;
71
+ if (containerWidth <= 0) return;
72
+ if (!isMeasuredRef.current) {
73
+ var measured = measureItems();
74
+ if (!measured) return;
75
+ }
76
+ var moreTotalWidth = moreWidthRef.current + 16;
77
+ var safetyBuffer = 12;
78
+ var itemGap = 8;
79
+ var widths = itemWidthsRef.current;
80
+ if (!widths || widths.length !== topNavigation.length) return;
81
+ var cumulativeWidth = 0;
82
+ for (var i = 0; i < topNavigation.length; i++) {
83
+ cumulativeWidth += widths[i];
84
+ if (i < topNavigation.length - 1) {
85
+ cumulativeWidth += itemGap;
86
+ }
87
+ }
88
+ var allItemsWidth = cumulativeWidth;
89
+ if (allItemsWidth + safetyBuffer <= containerWidth) {
90
+ setVisibleCount(topNavigation.length);
91
+ return;
92
+ }
93
+ if (allItemsWidth + moreTotalWidth + safetyBuffer <= containerWidth) {
94
+ setVisibleCount(topNavigation.length);
95
+ return;
96
+ }
97
+ for (var count = topNavigation.length - 1; count >= 0; count--) {
98
+ var itemsWidth = 0;
99
+ for (var _i = 0; _i < count; _i++) {
100
+ itemsWidth += widths[_i];
101
+ if (_i < count - 1) {
102
+ itemsWidth += itemGap;
103
+ }
104
+ }
105
+ var totalWidth = itemsWidth + (count > 0 ? moreTotalWidth : 0) + safetyBuffer;
106
+ if (totalWidth <= containerWidth) {
107
+ setVisibleCount(count);
108
+ return;
109
+ }
110
+ }
111
+ setVisibleCount(0);
112
+ }, [topNavigation, measureItems]);
113
+ useEffect(function () {
114
+ if (!debouncedFnRef.current) {
115
+ debouncedFnRef.current = function () {
116
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
117
+ args[_key] = arguments[_key];
118
+ }
119
+ clearTimeout(resizeTimeoutRef.current);
120
+ resizeTimeoutRef.current = setTimeout(function () {
121
+ updateVisibleCount.apply(void 0, args);
122
+ }, 100);
123
+ };
124
+ }
125
+ }, [updateVisibleCount]);
126
+ var attemptUpdateVisibleCount = useCallback(function () {
127
+ measureItems();
128
+ var attempts = 0;
129
+ var maxAttempts = 3;
130
+ var _tryUpdate = function tryUpdate() {
131
+ if (isMeasuredRef.current) {
132
+ var _debouncedFnRef$curre;
133
+ (_debouncedFnRef$curre = debouncedFnRef.current) === null || _debouncedFnRef$curre === void 0 || _debouncedFnRef$curre.call(debouncedFnRef);
134
+ } else if (attempts < maxAttempts) {
135
+ attempts++;
136
+ requestAnimationFrame(_tryUpdate);
137
+ }
138
+ };
139
+ requestAnimationFrame(_tryUpdate);
140
+ }, [measureItems]);
141
+ useEffect(function () {
142
+ var timer = setTimeout(attemptUpdateVisibleCount, 100);
143
+ var resizeObserver;
144
+ if (typeof ResizeObserver !== "undefined" && wrapperRef.current) {
145
+ resizeObserver = new ResizeObserver(function () {
146
+ requestAnimationFrame(function () {
147
+ var _debouncedFnRef$curre2;
148
+ (_debouncedFnRef$curre2 = debouncedFnRef.current) === null || _debouncedFnRef$curre2 === void 0 || _debouncedFnRef$curre2.call(debouncedFnRef);
149
+ });
150
+ });
151
+ resizeObserver.observe(wrapperRef.current);
152
+ }
153
+ var handleResize = function handleResize() {
154
+ var _debouncedFnRef$curre3;
155
+ (_debouncedFnRef$curre3 = debouncedFnRef.current) === null || _debouncedFnRef$curre3 === void 0 || _debouncedFnRef$curre3.call(debouncedFnRef);
156
+ };
157
+ window.addEventListener("resize", handleResize);
158
+ return function () {
159
+ clearTimeout(timer);
160
+ clearTimeout(resizeTimeoutRef.current);
161
+ if (resizeObserver) {
162
+ resizeObserver.disconnect();
163
+ }
164
+ window.removeEventListener("resize", handleResize);
165
+ };
166
+ }, [topNavigation, attemptUpdateVisibleCount]);
23
167
  if (!topNavigation || !topNavigation.length) {
24
168
  return null;
25
169
  }
170
+ var hiddenItems = topNavigation.slice(visibleCount);
171
+ var hasHidden = hiddenItems.length > 0;
26
172
  var menu = /*#__PURE__*/React.createElement(_Menu, {
27
173
  selectable: true,
28
174
  selectedKeys: [_activeKey]
29
- }, topNavigation.slice(unfoldMaxCount).map(function (item) {
175
+ }, hiddenItems.map(function (item) {
30
176
  return /*#__PURE__*/React.createElement(_Menu.Item, {
177
+ key: item.value,
31
178
  onClick: function onClick(_ref) {
32
179
  var domEvent = _ref.domEvent;
33
- onClickTopNavigationSelf(domEvent, item);
34
- },
35
- key: item.value
180
+ return onClickTopNavigationSelf(domEvent, item);
181
+ }
36
182
  }, /*#__PURE__*/React.createElement(_TooltipText, null, item.name));
37
183
  }));
184
+ var shouldShowAll = !isMeasuredRef.current;
38
185
  return /*#__PURE__*/React.createElement("div", {
186
+ ref: wrapperRef,
39
187
  className: classnames("cw-header-top-navigation-menu-wrapper", topNavigationWrapperClassName)
40
- }, topNavigation.slice(0, unfoldMaxCount).map(function (item) {
188
+ }, (shouldShowAll ? topNavigation : topNavigation.slice(0, visibleCount)).map(function (item, index) {
41
189
  return /*#__PURE__*/React.createElement("div", {
42
190
  key: item.value,
191
+ ref: function ref(el) {
192
+ itemsRef.current[index] = el;
193
+ },
43
194
  onClick: function onClick(e) {
44
195
  return onClickTopNavigationSelf(e, item);
45
196
  },
46
197
  className: classnames("cw-header-top-navigation-menu-item", {
47
198
  "cw-header-top-navigation-menu-item-seleted": _activeKey === item.value
48
- })
199
+ }),
200
+ style: shouldShowAll && index >= visibleCount ? {
201
+ visibility: 'hidden',
202
+ pointerEvents: 'none'
203
+ } : undefined
49
204
  }, item.name);
50
- }), (topNavigation === null || topNavigation === void 0 ? void 0 : topNavigation.length) > unfoldMaxCount && /*#__PURE__*/React.createElement(_Dropdown, {
205
+ }), hasHidden && /*#__PURE__*/React.createElement("div", {
206
+ ref: moreRef,
207
+ className: "cw-header-top-navigation-menu-more-wrapper"
208
+ }, /*#__PURE__*/React.createElement(_Dropdown, {
51
209
  overlay: menu,
52
210
  overlayClassName: classnames(moreOverlayClassName)
53
- }, /*#__PURE__*/React.createElement("div", {
54
- className: "cw-header-top-navigation-menu-more-wrapper"
55
- }, /*#__PURE__*/React.createElement(_Icon, {
211
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_Icon, {
56
212
  type: "ellipsis"
57
- }))));
213
+ })))));
58
214
  };
59
215
  export default TopNavigationMenu;
@@ -1,10 +1,18 @@
1
1
  .cw-header-top-navigation-menu-wrapper {
2
+ flex: 1;
2
3
  margin-left: 16px;
4
+ margin-right: 16px; // 与右侧区域保持对称间距
3
5
  display: flex;
4
- justify-content: center;
6
+ justify-content: flex-start;
5
7
  align-items: center;
6
8
  height: 20px;
7
9
  font-size: 12px;
10
+ min-width: 0;
11
+ flex-wrap: nowrap;
12
+ position: relative;
13
+
14
+ // 确保容器有最小宽度,避免极端情况下的布局问题
15
+ min-width: 120px;
8
16
 
9
17
  .cw-header-top-navigation-menu-item {
10
18
  display: flex;
@@ -13,11 +21,19 @@
13
21
  height: 20px;
14
22
  line-height: 20px;
15
23
  padding: 0 12px;
24
+ flex-shrink: 0;
25
+ white-space: nowrap;
26
+ transition: all 0.2s ease-in-out;
27
+
16
28
  &:hover{
17
29
  cursor: pointer;
30
+ transform: translateY(-1px);
18
31
  }
32
+
19
33
  &:not(.cw-header-top-navigation-menu-item-seleted):hover {
20
34
  color: @primary-5;
35
+ background-color: fade(@primary-color, 10%);
36
+ border-radius: 10px;
21
37
  }
22
38
 
23
39
  &:not(:first-child) {
@@ -26,16 +42,88 @@
26
42
 
27
43
  &.cw-header-top-navigation-menu-item-seleted {
28
44
  background-color: @primary-color;
45
+ color: #fff;
29
46
  font-weight: 500;
30
47
  border-radius: 10px;
48
+ box-shadow: 0 2px 4px fade(@primary-color, 20%);
49
+ }
50
+
51
+ &.cw-header-top-navigation-menu-item-hidden {
52
+ visibility: hidden;
53
+ pointer-events: none;
31
54
  }
32
55
  }
33
56
 
34
57
  .cw-header-top-navigation-menu-more-wrapper {
35
- margin-left: 20px;
58
+ margin-left: 16px; // 减少间距,更美观
59
+ flex-shrink: 0;
60
+ display: flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ width: 32px;
64
+ height: 32px;
65
+ border-radius: 6px;
66
+ transition: all 0.2s ease-in-out;
67
+
36
68
  &:hover{
37
69
  cursor: pointer;
38
70
  color: @primary-5;
71
+ background-color: fade(@primary-color, 10%);
72
+ transform: translateY(-1px);
73
+ }
74
+
75
+ &.cw-header-top-navigation-menu-more-hidden {
76
+ display: none;
77
+ }
78
+
79
+ // 展开图标样式优化
80
+ .ant-dropdown-trigger {
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: center;
84
+ width: 100%;
85
+ height: 100%;
86
+ }
87
+ }
88
+
89
+ // 响应式间距调整
90
+ @media (max-width: 768px) {
91
+ margin-left: 8px;
92
+ margin-right: 8px;
93
+
94
+ .cw-header-top-navigation-menu-item {
95
+ padding: 0 8px;
96
+ font-size: 11px;
97
+
98
+ &:not(:first-child) {
99
+ margin-left: 6px;
100
+ }
101
+ }
102
+
103
+ .cw-header-top-navigation-menu-more-wrapper {
104
+ margin-left: 12px;
105
+ width: 28px;
106
+ height: 28px;
107
+ }
108
+ }
109
+
110
+ @media (max-width: 480px) {
111
+ margin-left: 4px;
112
+ margin-right: 4px;
113
+
114
+ .cw-header-top-navigation-menu-item {
115
+ padding: 0 6px;
116
+ font-size: 10px;
117
+
118
+ &:not(:first-child) {
119
+ margin-left: 4px;
120
+ }
121
+ }
122
+
123
+ .cw-header-top-navigation-menu-more-wrapper {
124
+ margin-left: 8px;
125
+ width: 24px;
126
+ height: 24px;
39
127
  }
40
128
  }
41
- }
129
+ }
@@ -19,8 +19,11 @@
19
19
  }
20
20
  .cw-header-left{
21
21
  height: 100%;
22
+ flex: 1;
22
23
  display: flex;
23
24
  align-items: center;
25
+ min-width: 0;
26
+ margin-right: 24px;
24
27
  .cw-header-logo{
25
28
  overflow: hidden;
26
29
  margin-left: 24px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chaoswise/ui",
3
- "version": "2.7.8",
3
+ "version": "2.7.10",
4
4
  "description": "公共UI库",
5
5
  "keywords": [
6
6
  "ui",