@zat-design/sisyphus-react 4.6.5-beta.5 → 4.6.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.
@@ -184,13 +184,13 @@ const InputNumber = (props) => {
184
184
  onBlur == null ? void 0 : onBlur(value, (_b = e == null ? void 0 : e.target) == null ? void 0 : _b.value);
185
185
  return false;
186
186
  }
187
+ value = parser(String(value), props.precision ?? (valueProps == null ? void 0 : valueProps.precision));
187
188
  if (_max !== void 0 && value > _max) {
188
189
  value = _max;
189
190
  }
190
191
  if (_min !== void 0 && value < _min) {
191
192
  value = _min;
192
193
  }
193
- value = parser(String(value), props.precision ?? (valueProps == null ? void 0 : valueProps.precision));
194
194
  (_c = rest == null ? void 0 : rest.onChange) == null ? void 0 : _c.call(rest, value);
195
195
  const limit = { min: Number(_min), max: Number(_max) };
196
196
  switch (valueType || viewType) {
@@ -2,36 +2,33 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useContext } from "react";
3
3
  import { Popover, Tooltip } from "antd";
4
4
  import classnames from "classnames";
5
- import { Link as RouterLink, useLocation } from "react-router-dom";
5
+ import { Link as RouterLink } from "react-router-dom";
6
6
  import ProIcon from "../../../../../ProIcon";
7
7
  import SideMenu from "../SideMenu";
8
8
  import { LayoutContext } from "../../../../index";
9
- import { findMenuItemByKey, resolveMenuKeyIdPath } from "../../../../utils";
9
+ import { getUrlParams, getPathNameKey, findMenuItemByKey } from "../../../../utils";
10
10
  const Link = RouterLink;
11
11
  const FoldMenu = (props) => {
12
12
  const { style, dataSource, onMenuClick } = props;
13
13
  const { menus, iconfontUrl, notice, collapsed, headerHeight } = dataSource;
14
- const location = useLocation();
14
+ const pathNamePrefix = `/${window.location.pathname.split("/")[1]}`;
15
15
  const noticeCls = classnames({
16
16
  "pro-layout-menu-tooltip": true,
17
17
  "pro-layout-menu-tooltip-has-notice": notice,
18
18
  "pro-layout-menu-tooltip-nav-open": collapsed
19
19
  });
20
- const { selectedPath, onSelected } = useContext(LayoutContext) || {
20
+ const { selectedPath, onSelected, menuSelectedPath } = useContext(LayoutContext) || {
21
21
  selectedPath: "",
22
22
  onSelected: () => {
23
23
  }
24
24
  };
25
- const currentKeyIdPath = resolveMenuKeyIdPath({
26
- menus,
27
- pathname: location.pathname,
28
- search: location.search,
29
- selectedPath
30
- });
31
25
  return /* @__PURE__ */ jsx("div", { className: "pro-layout-menu-fold", style: { ...style }, children: /* @__PURE__ */ jsx("ul", { className: "pro-layout-menu-fold-list", style: { ...style }, children: menus.filter((item) => !item.hideInMenu).map((item, index) => {
32
26
  var _a;
33
27
  const { id, url, name, icon, imgUrl, imgActiveUrl, children } = item;
34
28
  const toPath = item.redirectUrl || item.url;
29
+ const selectedMenu = getUrlParams("activeMenu");
30
+ const pathToMatch = menuSelectedPath ?? (selectedPath || selectedMenu || window.location.pathname);
31
+ const currentKeyIdPath = pathToMatch ? getPathNameKey({ menus, pathName: pathToMatch }) || [] : [];
35
32
  const cls = classnames({
36
33
  active: currentKeyIdPath.includes(id)
37
34
  });
@@ -41,7 +38,7 @@ const FoldMenu = (props) => {
41
38
  "img",
42
39
  {
43
40
  className: "pro-layout-icon",
44
- src: currentKeyIdPath.includes(id) ? imgActiveUrl || imgUrl : imgUrl,
41
+ src: pathNamePrefix === url ? imgActiveUrl || imgUrl : imgUrl,
45
42
  alt: "icon"
46
43
  }
47
44
  ) : /* @__PURE__ */ jsx(
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { MenusType } from '../../../propTypes';
3
+ /** 单页路由命中菜单时更新入口,未命中的详情页沿用最近入口。 */
4
+ declare const NormalMenuSelection: ({ menus, children }: {
5
+ menus: MenusType[];
6
+ children: ReactNode;
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ export default NormalMenuSelection;
@@ -0,0 +1,29 @@
1
+ import { Fragment, jsx } from "react/jsx-runtime";
2
+ import { useContext, useEffect } from "react";
3
+ import { useLocation } from "react-router-dom";
4
+ import { LayoutContext } from "../../../index";
5
+ import { getIdsByPathName } from "../../../utils";
6
+ const NormalMenuSelection = ({ menus, children }) => {
7
+ const location = useLocation();
8
+ const context = useContext(LayoutContext);
9
+ const onSelected = context == null ? void 0 : context.onSelected;
10
+ const activeMenu = new URLSearchParams(location.search).get("activeMenu");
11
+ const routeMenuPath = activeMenu || (getIdsByPathName(menus, location.pathname).length ? location.pathname : "");
12
+ useEffect(() => {
13
+ if (routeMenuPath)
14
+ onSelected == null ? void 0 : onSelected({ selectedPath: routeMenuPath });
15
+ }, [routeMenuPath, onSelected]);
16
+ if (!context)
17
+ return /* @__PURE__ */ jsx(Fragment, { children });
18
+ return /* @__PURE__ */ jsx(
19
+ LayoutContext.Provider,
20
+ {
21
+ value: { ...context, menuSelectedPath: routeMenuPath || context.selectedPath },
22
+ children
23
+ }
24
+ );
25
+ };
26
+ var NormalMenuSelection_default = NormalMenuSelection;
27
+ export {
28
+ NormalMenuSelection_default as default
29
+ };
@@ -4,14 +4,15 @@ import { Menu } from "antd";
4
4
  import { useDeepCompareEffect, useSetState } from "ahooks";
5
5
  import { CaretDownOutlined } from "@ant-design/icons";
6
6
  import classnames from "classnames";
7
- import { Link as RouterLink, useLocation } from "react-router-dom";
7
+ import { Link as RouterLink } from "react-router-dom";
8
8
  import cloneDeep from "lodash/cloneDeep";
9
9
  import { LayoutContext } from "../../../../index";
10
- import { findMenuItemByKey, resolveMenuKeyIdPath } from "../../../../utils";
10
+ import { getIdsByPathName, findMenuItemByKey } from "../../../../utils";
11
11
  import { canOpenAsTab } from "../../../TabsManager/utils";
12
12
  import ProIcon from "../../../../../ProIcon";
13
13
  const Link = RouterLink;
14
14
  const OpenMenu = (props) => {
15
+ var _a;
15
16
  const { className, dataSource, style, onMenuClick, textVisible = true } = props;
16
17
  const { menus, sideMenu } = dataSource || {};
17
18
  const linkRef = useRef(null);
@@ -20,7 +21,7 @@ const OpenMenu = (props) => {
20
21
  openKeys: [],
21
22
  router: ""
22
23
  });
23
- const location = useLocation();
24
+ const query = new URLSearchParams(window.location.search);
24
25
  const layoutContext = useContext(LayoutContext);
25
26
  const layoutSelectedPath = layoutContext == null ? void 0 : layoutContext.selectedPath;
26
27
  const layoutOnSelected = layoutContext == null ? void 0 : layoutContext.onSelected;
@@ -30,12 +31,8 @@ const OpenMenu = (props) => {
30
31
  "pro-layout-menu-text-hidden": textVisible === false,
31
32
  [`${className}`]: className
32
33
  });
33
- const selectKeyIdPath = resolveMenuKeyIdPath({
34
- menus,
35
- pathname: location.pathname,
36
- search: location.search,
37
- selectedPath: layoutSelectedPath
38
- }).map((item) => String(item));
34
+ const preferredPath = (layoutContext == null ? void 0 : layoutContext.menuSelectedPath) ?? (query.get("activeMenu") || (layoutSelectedPath === "##EMPTY##" ? null : layoutSelectedPath) || window.location.pathname);
35
+ const selectKeyIdPath = preferredPath ? ((_a = getIdsByPathName(menus, preferredPath)) == null ? void 0 : _a.map((item) => String(item))) || [] : [];
39
36
  const selectedRootKey = selectKeyIdPath[0];
40
37
  const itemsTransform = useMemo(() => {
41
38
  const result = cloneDeep(menus);
@@ -44,8 +41,8 @@ const OpenMenu = (props) => {
44
41
  }
45
42
  const menuDeep = (data) => {
46
43
  data.forEach((item) => {
47
- var _a, _b, _c;
48
- const isFirstMenu = ((_a = item.keyIdPath) == null ? void 0 : _a.length) === 1 || sideMenu && ((_b = item.keyIdPath) == null ? void 0 : _b.length) === 2;
44
+ var _a2, _b, _c;
45
+ const isFirstMenu = ((_a2 = item.keyIdPath) == null ? void 0 : _a2.length) === 1 || sideMenu && ((_b = item.keyIdPath) == null ? void 0 : _b.length) === 2;
49
46
  item.label = /* @__PURE__ */ jsxs(
50
47
  "div",
51
48
  {
@@ -143,7 +140,7 @@ const OpenMenu = (props) => {
143
140
  }
144
141
  if (menuItem && canOpenAsTab(menuItem) && shouldActivate) {
145
142
  setState({
146
- selectedKeys: menuKeyPath,
143
+ selectedKeys: keyPath,
147
144
  router: menuRouter
148
145
  });
149
146
  layoutOnSelected == null ? void 0 : layoutOnSelected({
@@ -1,4 +1,8 @@
1
- import type { FC } from 'react';
1
+ import type { FC, ReactNode } from 'react';
2
2
  import type { ProLayoutType } from '../../../propTypes';
3
- declare const Menu: FC<ProLayoutType>;
3
+ type MenuProps = Pick<ProLayoutType, 'mode' | 'headerHeight' | 'dataSource' | 'iconfontUrl' | 'collapsed' | 'notice' | 'pure' | 'sideMenuFooterRender' | 'onMenuClick'> & {
4
+ sideMenuHeaderRender?: ReactNode;
5
+ onToggle?: () => void;
6
+ };
7
+ declare const Menu: FC<MenuProps>;
4
8
  export default Menu;
@@ -3,6 +3,7 @@ import { useEffect, useRef, useState, useCallback } from "react";
3
3
  import classnames from "classnames";
4
4
  import OpenMenu from "./OpenMenu";
5
5
  import FoldMenu from "./FoldMenu";
6
+ import NormalMenuSelection from "./NormalMenuSelection";
6
7
  const iconfontCache = /* @__PURE__ */ new Set();
7
8
  const loadIconfontScript = (url) => {
8
9
  if (!url || iconfontCache.has(url))
@@ -33,7 +34,8 @@ const Menu = (props) => {
33
34
  pure,
34
35
  sideMenuFooterRender,
35
36
  sideMenuHeaderRender,
36
- onMenuClick
37
+ onMenuClick,
38
+ mode
37
39
  } = props || {};
38
40
  let menus = [];
39
41
  const menuRef = useRef(null);
@@ -110,7 +112,7 @@ const Menu = (props) => {
110
112
  if ((pure == null ? void 0 : pure.leftMenu) || pure === true) {
111
113
  return /* @__PURE__ */ jsx(Fragment, {});
112
114
  }
113
- return /* @__PURE__ */ jsxs(
115
+ const menuDom = /* @__PURE__ */ jsxs(
114
116
  "div",
115
117
  {
116
118
  ref: menuRef,
@@ -170,6 +172,7 @@ const Menu = (props) => {
170
172
  ]
171
173
  }
172
174
  );
175
+ return mode === "normal" ? /* @__PURE__ */ jsx(NormalMenuSelection, { menus, children: menuDom }) : menuDom;
173
176
  };
174
177
  var Menu_default = Menu;
175
178
  export {
@@ -4,6 +4,8 @@ import { useProLayoutTabs } from './components/TabsManager/hooks/useProLayoutTab
4
4
  import { useActiveTab } from './components/TabsManager/hooks/useActiveTab';
5
5
  interface LayoutContextValue {
6
6
  selectedPath: string;
7
+ /** normal 模式根据当前路由解析后的菜单路径,空字符串表示没有选中项。 */
8
+ menuSelectedPath?: string;
7
9
  onSelected: (params: Partial<ProLayoutStatesType>) => void;
8
10
  target: '_blank' | '_parent' | '_self' | '_top';
9
11
  }
@@ -238,6 +238,7 @@ const ProLayout = (props) => {
238
238
  noticeRef: setNoticeElRef
239
239
  };
240
240
  const menuProps = {
241
+ mode,
241
242
  headerHeight,
242
243
  dataSource: Array.isArray(menus) ? { menus } : menus,
243
244
  iconfontUrl,
@@ -6,16 +6,6 @@ import type { MenusType } from '../propTypes';
6
6
  * @return result
7
7
  */
8
8
  export declare const getIdsByPathName: (menus: any[], activeMenu?: string) => number[];
9
- interface ResolveMenuKeyIdPathOptions {
10
- menus: any[];
11
- pathname: string;
12
- search?: string;
13
- selectedPath?: string;
14
- }
15
- /**
16
- * 统一解析菜单激活路径:显式 activeMenu 优先,其次匹配真实路由,最后回退上次选择。
17
- */
18
- export declare const resolveMenuKeyIdPath: ({ menus, pathname, search, selectedPath, }: ResolveMenuKeyIdPathOptions) => number[];
19
9
  /**
20
10
  * 转换菜单数据源评价keyUrlPath与keyIdPath
21
11
  * @param menuData 菜单数据源
@@ -51,4 +41,3 @@ export declare const getPathNameKey: ({ menus, pathName }: {
51
41
  * @returns 找到的菜单项数据或null
52
42
  */
53
43
  export declare const findMenuItemByKey: (menus: any[], key: string) => any;
54
- export {};
@@ -1,21 +1,12 @@
1
1
  import isPlainObject from "lodash/isPlainObject";
2
2
  const updateBestMatch = (pathName, itemUrl, itemRedirectUrl, keyIdPath, bestMatch) => {
3
- const isSameOrNestedPath = (candidate) => {
4
- if (!candidate)
5
- return false;
6
- const normalizedCandidate = candidate.length > 1 ? candidate.replace(/\/+$/, "") : candidate;
7
- if (pathName === normalizedCandidate)
8
- return true;
9
- const boundary = pathName.charAt(normalizedCandidate.length);
10
- return pathName.startsWith(normalizedCandidate) && ["/", "?", "#"].includes(boundary);
11
- };
12
- if (isSameOrNestedPath(itemUrl)) {
3
+ if (itemUrl && pathName.includes(itemUrl)) {
13
4
  const urlLength = itemUrl.length;
14
5
  if (!bestMatch || urlLength > bestMatch.urlLength) {
15
6
  return { keyIdPath, urlLength };
16
7
  }
17
8
  }
18
- if (isSameOrNestedPath(itemRedirectUrl)) {
9
+ if (itemRedirectUrl && pathName.includes(itemRedirectUrl)) {
19
10
  const urlLength = itemRedirectUrl.length;
20
11
  if (!bestMatch || urlLength > bestMatch.urlLength) {
21
12
  return { keyIdPath, urlLength };
@@ -23,27 +14,6 @@ const updateBestMatch = (pathName, itemUrl, itemRedirectUrl, keyIdPath, bestMatc
23
14
  }
24
15
  return bestMatch;
25
16
  };
26
- const getExactMenuKeyIdPath = (menus, pathname) => {
27
- const normalizePathname = (value) => {
28
- if (!value)
29
- return "";
30
- const path = value.split(/[?#]/)[0];
31
- return path.length > 1 ? path.replace(/\/+$/, "") : path;
32
- };
33
- const targetPathname = normalizePathname(pathname);
34
- for (const item of menus || []) {
35
- const routes = [item == null ? void 0 : item.redirectUrl, item == null ? void 0 : item.router, item == null ? void 0 : item.url].map(normalizePathname);
36
- if (targetPathname && routes.includes(targetPathname)) {
37
- return item.keyIdPath || [];
38
- }
39
- if (Array.isArray(item == null ? void 0 : item.children) && item.children.length) {
40
- const childPath = getExactMenuKeyIdPath(item.children, pathname);
41
- if (childPath.length)
42
- return childPath;
43
- }
44
- }
45
- return [];
46
- };
47
17
  const getIdsByPathName = (menus, activeMenu) => {
48
18
  const _pathName = activeMenu || window.location.pathname;
49
19
  let result;
@@ -72,26 +42,6 @@ const getIdsByPathName = (menus, activeMenu) => {
72
42
  menuDeep(menus);
73
43
  return result || (bestMatch == null ? void 0 : bestMatch.keyIdPath) || [];
74
44
  };
75
- const resolveMenuKeyIdPath = ({
76
- menus,
77
- pathname,
78
- search = "",
79
- selectedPath
80
- }) => {
81
- if (selectedPath === "##EMPTY##")
82
- return [];
83
- const activeMenu = new URLSearchParams(search).get("activeMenu");
84
- const activeMenuPath = activeMenu ? getIdsByPathName(menus, activeMenu) : [];
85
- if (activeMenuPath.length)
86
- return activeMenuPath;
87
- const exactRoutePath = getExactMenuKeyIdPath(menus, pathname);
88
- if (exactRoutePath.length)
89
- return exactRoutePath;
90
- const nestedRoutePath = getIdsByPathName(menus, pathname);
91
- if (nestedRoutePath.length)
92
- return nestedRoutePath;
93
- return selectedPath ? getIdsByPathName(menus, selectedPath) : [];
94
- };
95
45
  const transformMenu = (menuData, pathPrefix) => {
96
46
  const data = [...menuData];
97
47
  const menuDeep = (menuDeepItem) => {
@@ -213,7 +163,6 @@ export {
213
163
  getIdsByPathName,
214
164
  getPathNameKey,
215
165
  getUrlParams,
216
- resolveMenuKeyIdPath,
217
166
  transformMenu,
218
167
  transformMenus
219
168
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zat-design/sisyphus-react",
3
- "version": "4.6.5-beta.5",
3
+ "version": "4.6.5",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public",