listpage-next 0.0.13 → 0.0.29

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,2 @@
1
+ import { MenuItem } from '../types';
2
+ export declare function useActiveMenuKey(items: MenuItem[]): [string | null, (key: string) => void];
@@ -0,0 +1,64 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { useLocation, useNavigate } from "react-router-dom";
3
+ function useActiveMenuKey(items) {
4
+ const location = useLocation();
5
+ const navigate = useNavigate();
6
+ const setActiveKey = useCallback((key)=>{
7
+ function findKeyPath(items, paths = []) {
8
+ for (const item of items){
9
+ if (item.key === key) return [
10
+ ...paths,
11
+ item.path || item.key
12
+ ];
13
+ if (item.children) {
14
+ const subPaths = findKeyPath(item.children);
15
+ if (subPaths.length) return [
16
+ ...paths,
17
+ item.path || item.key,
18
+ ...subPaths
19
+ ];
20
+ }
21
+ }
22
+ return [];
23
+ }
24
+ const paths = findKeyPath(items, []);
25
+ const urlPath = paths.map((p)=>getPaths(p)).flat().join('/');
26
+ console.log('urlPath', urlPath);
27
+ navigate(urlPath);
28
+ }, [
29
+ items,
30
+ navigate
31
+ ]);
32
+ const activeKey = useMemo(()=>{
33
+ const paths = getPaths(location.pathname);
34
+ return matchRoutes(items, paths);
35
+ }, [
36
+ location.pathname,
37
+ items
38
+ ]);
39
+ return [
40
+ activeKey,
41
+ setActiveKey
42
+ ];
43
+ }
44
+ const matchRoutes = (routes, paths)=>{
45
+ for (const route of routes){
46
+ const routePaths = getPaths(route.path || route.key);
47
+ const isMatch = isPathMatch(paths, routePaths);
48
+ if (isMatch) {
49
+ if (route.children) return matchRoutes(route.children, paths.slice(routePaths.length));
50
+ return route.key;
51
+ }
52
+ }
53
+ return null;
54
+ };
55
+ const isPathMatch = (urlPaths, routePaths)=>{
56
+ for(let i = 0; i < routePaths.length; i++){
57
+ const matchAny = '*' === routePaths[i];
58
+ const matchUrl = routePaths[i] === urlPaths[i];
59
+ if (!matchAny && !matchUrl) return false;
60
+ }
61
+ return true;
62
+ };
63
+ const getPaths = (path = '')=>path.split('/').filter(Boolean);
64
+ export { useActiveMenuKey };
@@ -0,0 +1,2 @@
1
+ import { MenuProps } from './types';
2
+ export declare const Menu: (props: MenuProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { Menu } from "antd";
4
+ import { useActiveMenuKey } from "./hooks/useMenuNavigation.js";
5
+ const Menu_Menu = (props)=>{
6
+ const { menus, theme, style } = props;
7
+ const [activeKey, setActiveKey] = useActiveMenuKey(menus);
8
+ const menuItems = useMemo(()=>menus.map((item)=>({
9
+ key: item.key,
10
+ label: item.label,
11
+ icon: item.icon,
12
+ children: item.children?.map((child)=>({
13
+ key: child.key,
14
+ label: child.label,
15
+ icon: child.icon
16
+ }))
17
+ })), [
18
+ menus
19
+ ]);
20
+ return /*#__PURE__*/ jsx(Menu, {
21
+ mode: "vertical",
22
+ theme: theme,
23
+ style: style,
24
+ items: menuItems,
25
+ selectedKeys: activeKey ? [
26
+ activeKey
27
+ ] : [],
28
+ onSelect: (info)=>{
29
+ setActiveKey(info.key);
30
+ }
31
+ });
32
+ };
33
+ export { Menu_Menu as Menu };
@@ -0,0 +1,14 @@
1
+ import { CSSProperties } from "react";
2
+ export interface MenuItem {
3
+ key: string;
4
+ label: React.ReactNode;
5
+ icon?: React.ReactNode;
6
+ children?: MenuItem[];
7
+ disabled?: boolean;
8
+ path?: string;
9
+ }
10
+ export interface MenuProps {
11
+ menus: MenuItem[];
12
+ theme?: 'light' | 'dark';
13
+ style?: CSSProperties;
14
+ }
File without changes
@@ -0,0 +1 @@
1
+ export declare const Demo4: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,43 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { BrowserRouter } from "react-router-dom";
3
+ import { Menu } from "../components/Menu/index.js";
4
+ const Demo4 = ()=>{
5
+ const menuItems = [
6
+ {
7
+ key: '1',
8
+ label: '首页',
9
+ path: 'home'
10
+ },
11
+ {
12
+ key: '2',
13
+ label: '产品',
14
+ path: 'products',
15
+ children: [
16
+ {
17
+ key: '2-1',
18
+ label: '产品列表',
19
+ path: 'list'
20
+ },
21
+ {
22
+ key: '2-2',
23
+ label: '产品详情',
24
+ path: 'detail'
25
+ }
26
+ ]
27
+ },
28
+ {
29
+ key: '3',
30
+ label: '关于我们',
31
+ path: 'about'
32
+ }
33
+ ];
34
+ return /*#__PURE__*/ jsx(BrowserRouter, {
35
+ children: /*#__PURE__*/ jsx(Menu, {
36
+ menus: menuItems,
37
+ style: {
38
+ width: 200
39
+ }
40
+ })
41
+ });
42
+ };
43
+ export { Demo4 };
@@ -1,6 +1,7 @@
1
1
  function setupBaseUrl(HttpClient) {
2
2
  HttpClient.prototype.getBaseURL = function() {
3
- const { server } = this.options;
3
+ const { server, config } = this.options;
4
+ if (config?.baseURL) return config.baseURL;
4
5
  return `${server?.protocol}//${server?.host}:${server?.port}${server?.publicPath}`;
5
6
  };
6
7
  }
@@ -25,7 +25,7 @@ function setupClient(HttpClient) {
25
25
  return Promise.reject(error);
26
26
  });
27
27
  apiClient.interceptors.response.use((response)=>{
28
- if ('text/event-stream' === response.config.headers['content-type']) return response;
28
+ if ('text/event-stream' === response.headers['content-type']) return response;
29
29
  if ('blob' === response.config.responseType) return response;
30
30
  if (!successCodes.includes(response.data.code)) {
31
31
  const error = {
@@ -1,5 +1,6 @@
1
1
  function setupHeaders(HttpClient) {
2
2
  HttpClient.prototype.getHeaders = function() {
3
+ if (this.options.config?.headers) return this.options.config.headers;
3
4
  return {
4
5
  'Content-Type': 'application/json'
5
6
  };
package/dist/index.d.ts CHANGED
@@ -2,4 +2,5 @@ import '@ant-design/v5-patch-for-react-19';
2
2
  export * from './components/FilterGroup';
3
3
  export * from './components/Page';
4
4
  export * from './components/InfiniteList';
5
+ export * from './components/Menu';
5
6
  export * from './http-client';
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ import "@ant-design/v5-patch-for-react-19";
2
2
  export * from "./components/FilterGroup/index.js";
3
3
  export * from "./components/Page/index.js";
4
4
  export * from "./components/InfiniteList/index.js";
5
+ export * from "./components/Menu/index.js";
5
6
  export * from "./http-client/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "listpage-next",
3
- "version": "0.0.13",
3
+ "version": "0.0.29",
4
4
  "description": "A React component library for creating filter forms with Ant Design",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -45,11 +45,13 @@
45
45
  "storybook": "^8.6.14",
46
46
  "storybook-addon-rslib": "^1.0.3",
47
47
  "storybook-react-rsbuild": "^1.0.3",
48
- "typescript": "^5.9.2"
48
+ "typescript": "^5.9.2",
49
+ "react-router-dom": ">=6.0.0"
49
50
  },
50
51
  "peerDependencies": {
51
52
  "react": ">=16.9.0",
52
- "react-dom": ">=16.9.0"
53
+ "react-dom": ">=16.9.0",
54
+ "react-router-dom": ">=6.0.0"
53
55
  },
54
56
  "dependencies": {
55
57
  "ahooks": "^3.9.5",
@@ -64,4 +66,4 @@
64
66
  "mobx-react-lite": "~4.1.1",
65
67
  "rc-virtual-list": "~3.19.2"
66
68
  }
67
- }
69
+ }