@lark-apaas/miaoda-core 0.1.0-alpha.22 → 0.1.0-alpha.24
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.
- package/lib/components/AppContainer/IframeBridge.d.ts +1 -0
- package/lib/components/AppContainer/IframeBridge.js +7 -8
- package/lib/components/AppContainer/{childApi.d.ts → utils/childApi.d.ts} +1 -1
- package/lib/components/AppContainer/{childApi.js → utils/childApi.js} +1 -1
- package/lib/components/AppContainer/utils/listenHot.d.ts +1 -0
- package/lib/components/AppContainer/utils/listenHot.js +43 -0
- package/lib/components/index.d.ts +0 -1
- package/lib/components/index.js +0 -1
- package/lib/types/iframe-events.d.ts +6 -1
- package/lib/utils/getParentOrigin.js +2 -2
- package/lib/utils/utils.d.ts +1 -0
- package/lib/utils/utils.js +7 -1
- package/package.json +4 -2
- package/lib/apis/components/TopNav.d.ts +0 -1
- package/lib/apis/components/TopNav.js +0 -2
- package/lib/components/TopNav/BottomNav.d.ts +0 -12
- package/lib/components/TopNav/BottomNav.js +0 -81
- package/lib/components/TopNav/TitleBar.d.ts +0 -10
- package/lib/components/TopNav/TitleBar.js +0 -130
- package/lib/components/TopNav/TopNav.d.ts +0 -10
- package/lib/components/TopNav/TopNav.js +0 -86
- package/lib/components/TopNav/index.d.ts +0 -12
- package/lib/components/TopNav/index.js +0 -65
@@ -5,7 +5,8 @@ import { connectToParent } from "penpal";
|
|
5
5
|
import { useUpdatingRef } from "../../hooks/useUpdatingRef.js";
|
6
6
|
import { postMessage } from "../../utils/postMessage.js";
|
7
7
|
import { getPreviewParentOrigin } from "../../utils/getParentOrigin.js";
|
8
|
-
import { childApi } from "./childApi.js";
|
8
|
+
import { childApi } from "./utils/childApi.js";
|
9
|
+
import "./utils/listenHot.js";
|
9
10
|
import "./LogInterceptor.js";
|
10
11
|
var IframeBridge_RouteMessageType = /*#__PURE__*/ function(RouteMessageType) {
|
11
12
|
RouteMessageType["RouteChange"] = "RouteChange";
|
@@ -17,6 +18,10 @@ function isRouteMessageType(type) {
|
|
17
18
|
return Object.values(IframeBridge_RouteMessageType).includes(type);
|
18
19
|
}
|
19
20
|
async function connectParent() {
|
21
|
+
postMessage({
|
22
|
+
type: 'PreviewReady',
|
23
|
+
data: {}
|
24
|
+
});
|
20
25
|
const connection = connectToParent({
|
21
26
|
parentOrigin: getPreviewParentOrigin(),
|
22
27
|
methods: {
|
@@ -25,6 +30,7 @@ async function connectParent() {
|
|
25
30
|
});
|
26
31
|
await connection.promise;
|
27
32
|
}
|
33
|
+
'production' !== process.env.NODE_ENV && connectParent();
|
28
34
|
function IframeBridge() {
|
29
35
|
const location = useLocation();
|
30
36
|
const navigate = useNavigate();
|
@@ -51,13 +57,6 @@ function IframeBridge() {
|
|
51
57
|
historyForward,
|
52
58
|
navigateRef
|
53
59
|
]);
|
54
|
-
useEffect(()=>{
|
55
|
-
postMessage({
|
56
|
-
type: 'PreviewReady',
|
57
|
-
data: {}
|
58
|
-
});
|
59
|
-
connectParent();
|
60
|
-
}, []);
|
61
60
|
useEffect(()=>{
|
62
61
|
if (isActive.current) {
|
63
62
|
isActive.current = false;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function connectDevServer(): WebSocket;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import sockjs_client from "sockjs-client";
|
2
|
+
import { postMessage } from "../../../utils/postMessage.js";
|
3
|
+
import { getWsPath } from "../../../utils/utils.js";
|
4
|
+
let hotInited = false;
|
5
|
+
function handleDevServerMessage(msg) {
|
6
|
+
if ('hash' === msg.type) {
|
7
|
+
if (!hotInited) {
|
8
|
+
hotInited = true;
|
9
|
+
return;
|
10
|
+
}
|
11
|
+
postMessage({
|
12
|
+
type: 'HmrMessage',
|
13
|
+
msg: {
|
14
|
+
type: 'hot'
|
15
|
+
},
|
16
|
+
data: null
|
17
|
+
});
|
18
|
+
} else if ('errors' === msg.type) postMessage({
|
19
|
+
type: 'HmrMessage',
|
20
|
+
msg: {
|
21
|
+
type: 'errors',
|
22
|
+
data: JSON.stringify(msg.data)
|
23
|
+
},
|
24
|
+
data: null
|
25
|
+
});
|
26
|
+
}
|
27
|
+
function connectDevServer() {
|
28
|
+
const sockUrl = getWsPath();
|
29
|
+
const sock = new sockjs_client(sockUrl);
|
30
|
+
sock.onopen = ()=>console.log("✅ connect DevServer SockJS");
|
31
|
+
sock.onmessage = (event)=>{
|
32
|
+
try {
|
33
|
+
const msg = JSON.parse(event.data);
|
34
|
+
console.log("hmr 消息:", msg);
|
35
|
+
handleDevServerMessage(msg);
|
36
|
+
} catch (err) {
|
37
|
+
console.error("解析 hmr 消息失败:", event.data);
|
38
|
+
}
|
39
|
+
};
|
40
|
+
return sock;
|
41
|
+
}
|
42
|
+
'production' !== process.env.NODE_ENV && connectDevServer();
|
43
|
+
export { connectDevServer };
|
package/lib/components/index.js
CHANGED
@@ -30,8 +30,13 @@ export interface UpdateRoutesMessage extends IframeMessage<{
|
|
30
30
|
}> {
|
31
31
|
type: 'UpdateRoutes';
|
32
32
|
}
|
33
|
+
/** 热更新消息 */
|
33
34
|
export interface HmrMessage extends IframeMessage<Record<string, never>> {
|
34
|
-
type: '
|
35
|
+
type: 'HmrMessage';
|
36
|
+
msg: {
|
37
|
+
type: 'hot' | 'errors';
|
38
|
+
data?: any;
|
39
|
+
};
|
35
40
|
}
|
36
41
|
export type OutgoingMessage = PreviewReadyMessage | HmrMessage | ConsoleMessage | ChildLocationChangeMessage | CreatePageMessage | RenderErrorMessage | RenderErrorRepairMessage | PageScreenshotMessage | UpdateRoutesMessage;
|
37
42
|
export interface GetRoutesMessage extends IframeMessage<Record<string, never>> {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
function getPreviewParentOrigin() {
|
2
2
|
const { origin } = window.location;
|
3
|
-
if (origin.includes('miaoda.feishuapp.net')) return 'https://miaoda.feishu.cn';
|
4
|
-
if (origin.includes('miaoda-pre.feishuapp.net')) return 'https://miaoda.feishu-pre.cn';
|
3
|
+
if (origin.includes('feishuapp.cn') || origin.includes('miaoda.feishuapp.net')) return 'https://miaoda.feishu.cn';
|
4
|
+
if (origin.includes('fsapp.kundou.cn') || origin.includes('miaoda-pre.feishuapp.net')) return 'https://miaoda.feishu-pre.cn';
|
5
5
|
return 'https://miaoda.feishu-boe.cn';
|
6
6
|
}
|
7
7
|
export { getPreviewParentOrigin };
|
package/lib/utils/utils.d.ts
CHANGED
@@ -15,5 +15,6 @@ export declare function isPreview(): boolean;
|
|
15
15
|
* 移除末尾的斜杠,确保路径不以斜杠结尾
|
16
16
|
*/
|
17
17
|
export declare function normalizeBasePath(basePath?: string): string;
|
18
|
+
export declare function getWsPath(): string;
|
18
19
|
/** 判断是否是沙箱模式 */
|
19
20
|
export declare function isSparkRuntime(): boolean;
|
package/lib/utils/utils.js
CHANGED
@@ -10,7 +10,13 @@ function normalizeBasePath(basePath) {
|
|
10
10
|
if (!basePath || '/' === basePath) return '';
|
11
11
|
return basePath.replace(/\/+$/, '');
|
12
12
|
}
|
13
|
+
function getWsPath() {
|
14
|
+
const rawBasePath = process.env.CLIENT_BASE_PATH || '/';
|
15
|
+
const normalizedBasePath = rawBasePath.startsWith('/') ? rawBasePath : `/${rawBasePath}`;
|
16
|
+
const basePathWithoutTrailingSlash = normalizedBasePath.endsWith('/') ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
|
17
|
+
return `${basePathWithoutTrailingSlash}/ws`;
|
18
|
+
}
|
13
19
|
function isSparkRuntime() {
|
14
20
|
return window._IS_Spark_RUNTIME ?? 'fullstack' === process.env.runtimeMode;
|
15
21
|
}
|
16
|
-
export { clsxWithTw, isPreview, isSparkRuntime, normalizeBasePath };
|
22
|
+
export { clsxWithTw, getWsPath, isPreview, isSparkRuntime, normalizeBasePath };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lark-apaas/miaoda-core",
|
3
|
-
"version": "0.1.0-alpha.
|
3
|
+
"version": "0.1.0-alpha.24",
|
4
4
|
"types": "./lib/index.d.ts",
|
5
5
|
"main": "./lib/index.js",
|
6
6
|
"files": [
|
@@ -76,13 +76,14 @@
|
|
76
76
|
"@ant-design/colors": "^7.2.1",
|
77
77
|
"@ant-design/cssinjs": "^1.24.0",
|
78
78
|
"@data-loom/js": "0.3.1",
|
79
|
-
"@lark-apaas/miaoda-inspector": "0.1.0-alpha.
|
79
|
+
"@lark-apaas/miaoda-inspector": "0.1.0-alpha.8",
|
80
80
|
"clsx": "~2.0.1",
|
81
81
|
"dayjs": "^1.11.13",
|
82
82
|
"echarts": "^6.0.0",
|
83
83
|
"html2canvas-pro": "^1.5.11",
|
84
84
|
"lodash": "^4.17.21",
|
85
85
|
"penpal": "^6.2.2",
|
86
|
+
"sockjs-client": "^1.6.1",
|
86
87
|
"sonner": "~2.0.0",
|
87
88
|
"tailwind-merge": "~2.0.0",
|
88
89
|
"tailwind-variants": "0.3.1",
|
@@ -107,6 +108,7 @@
|
|
107
108
|
"@types/node": "^22.10.2",
|
108
109
|
"@types/react": "^18.3.23",
|
109
110
|
"@types/react-dom": "^18.3.7",
|
111
|
+
"@types/sockjs-client": "^1",
|
110
112
|
"antd": "^5.26.6",
|
111
113
|
"eslint": "^8.57.0",
|
112
114
|
"jsdom": "^26.1.0",
|
@@ -1 +0,0 @@
|
|
1
|
-
export { default as TopNav } from '../../components/TopNav';
|
@@ -1,12 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* 底部导航栏:应用模式,移动端转用
|
3
|
-
*/
|
4
|
-
import * as React from 'react';
|
5
|
-
import { NavItemProps } from '../common';
|
6
|
-
import { BaseNavProps } from '../../types';
|
7
|
-
interface BottomNavProps extends BaseNavProps {
|
8
|
-
navList: NavItemProps[];
|
9
|
-
maxBottomItems?: number;
|
10
|
-
}
|
11
|
-
export declare function BottomNav({ navList, className, maxBottomItems, }: BottomNavProps): React.JSX.Element;
|
12
|
-
export {};
|
@@ -1,81 +0,0 @@
|
|
1
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
2
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
3
|
-
import { clsxWithTw } from "../../utils/utils.js";
|
4
|
-
import { BottomBarThemeClass, MaskThemeClass, MoreNavItem, NavItem } from "../common/index.js";
|
5
|
-
function BottomNav({ navList = [], className, maxBottomItems = 6 }) {
|
6
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
7
|
-
const bottomBarRef = useRef(null);
|
8
|
-
const hasMoreItems = navList.length > maxBottomItems;
|
9
|
-
const bottomNavItems = hasMoreItems ? navList.slice(0, maxBottomItems - 1) : navList.slice(0, maxBottomItems);
|
10
|
-
const expandedNavItems = hasMoreItems ? navList.slice(maxBottomItems - 1) : [];
|
11
|
-
const expandedNavItemsPath = useMemo(()=>expandedNavItems.map((item)=>item.to), [
|
12
|
-
expandedNavItems
|
13
|
-
]);
|
14
|
-
const toggleExpanded = ()=>{
|
15
|
-
setIsExpanded(!isExpanded);
|
16
|
-
};
|
17
|
-
const collapsePanel = ()=>{
|
18
|
-
setIsExpanded(false);
|
19
|
-
};
|
20
|
-
const displayGridCols = bottomNavItems.length + (hasMoreItems ? 1 : 0);
|
21
|
-
useEffect(()=>{
|
22
|
-
if (bottomBarRef.current) {
|
23
|
-
const bottomNavMask = document.createElement('div');
|
24
|
-
bottomNavMask.className = 'w-full h-16';
|
25
|
-
bottomNavMask.style.height = `${bottomBarRef.current.offsetHeight}px`;
|
26
|
-
document.body.appendChild(bottomNavMask);
|
27
|
-
return ()=>{
|
28
|
-
document.body.removeChild(bottomNavMask);
|
29
|
-
};
|
30
|
-
}
|
31
|
-
}, []);
|
32
|
-
return /*#__PURE__*/ jsxs(Fragment, {
|
33
|
-
children: [
|
34
|
-
isExpanded ? /*#__PURE__*/ jsx("div", {
|
35
|
-
className: clsxWithTw('fixed inset-0 z-20', MaskThemeClass),
|
36
|
-
onClick: collapsePanel
|
37
|
-
}) : null,
|
38
|
-
/*#__PURE__*/ jsx("div", {
|
39
|
-
className: clsxWithTw(BottomBarThemeClass, 'fixed inset-x-0 z-20 rounded-t-2xl shadow-lg transform transition-transform duration-300 ease-in-out', 'bottom-16', 'max-h-[calc(100vh-4rem)] overflow-y-auto', className, isExpanded ? 'translate-y-0' : 'translate-y-full'),
|
40
|
-
children: /*#__PURE__*/ jsx("div", {
|
41
|
-
className: "grid grid-cols-4 gap-2 py-3",
|
42
|
-
children: expandedNavItems.map((item, index)=>/*#__PURE__*/ jsx(NavItem, {
|
43
|
-
direction: "vertical",
|
44
|
-
className: "text-xs h-20 gap-2",
|
45
|
-
...item,
|
46
|
-
onClick: collapsePanel
|
47
|
-
}, index))
|
48
|
-
})
|
49
|
-
}),
|
50
|
-
/*#__PURE__*/ jsxs("div", {
|
51
|
-
ref: bottomBarRef,
|
52
|
-
className: clsxWithTw(BottomBarThemeClass, 'pt-2.5 pb-2.5 fixed h-16 inset-x-0 bottom-0 z-20 border-gray-200 border-t grid items-center', {
|
53
|
-
'grid-cols-1': 1 === displayGridCols,
|
54
|
-
'grid-cols-2': 2 === displayGridCols,
|
55
|
-
'grid-cols-3': 3 === displayGridCols,
|
56
|
-
'grid-cols-4': 4 === displayGridCols,
|
57
|
-
'grid-cols-5': 5 === displayGridCols,
|
58
|
-
'grid-cols-6': 6 === displayGridCols
|
59
|
-
}, className),
|
60
|
-
children: [
|
61
|
-
bottomNavItems.map((item, index)=>/*#__PURE__*/ jsx(NavItem, {
|
62
|
-
className: "text-xs",
|
63
|
-
hideActive: isExpanded,
|
64
|
-
direction: "vertical",
|
65
|
-
onClick: collapsePanel,
|
66
|
-
...item
|
67
|
-
}, index)),
|
68
|
-
hasMoreItems ? /*#__PURE__*/ jsx(MoreNavItem, {
|
69
|
-
direction: "vertical",
|
70
|
-
className: "text-xs",
|
71
|
-
name: "更多",
|
72
|
-
onClick: toggleExpanded,
|
73
|
-
isExpanded: isExpanded,
|
74
|
-
expandedNavItemsPath: expandedNavItemsPath
|
75
|
-
}) : null
|
76
|
-
]
|
77
|
-
})
|
78
|
-
]
|
79
|
-
});
|
80
|
-
}
|
81
|
-
export { BottomNav };
|
@@ -1,130 +0,0 @@
|
|
1
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
2
|
-
import { useMemo, useState } from "react";
|
3
|
-
import { Link, matchPath, useLocation } from "react-router-dom";
|
4
|
-
import { LogOut, MoreHorizontal, X } from "lucide-react";
|
5
|
-
import { clsxWithTw, isSparkRuntime } from "../../utils/utils.js";
|
6
|
-
import { useAppInfo, useCurrentUserProfile, useLogout } from "../../hooks/index.js";
|
7
|
-
import { DropdownThemeClass, MaskThemeClass, TopHeaderThemeClass } from "../common/index.js";
|
8
|
-
const TitleBar = ({ navList, className })=>{
|
9
|
-
const { pathname } = useLocation();
|
10
|
-
const title = useMemo(()=>{
|
11
|
-
const matched = navList.find((navItem)=>{
|
12
|
-
const match = matchPath(navItem.to, pathname);
|
13
|
-
return match && match.pathname === pathname;
|
14
|
-
});
|
15
|
-
return matched?.name;
|
16
|
-
}, [
|
17
|
-
navList,
|
18
|
-
pathname
|
19
|
-
]);
|
20
|
-
const { appName, appLogo } = useAppInfo();
|
21
|
-
const { name: userName, avatar: userAvatar } = useCurrentUserProfile();
|
22
|
-
const { handlerLogout } = useLogout();
|
23
|
-
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
24
|
-
const closeMenu = ()=>{
|
25
|
-
setIsMenuOpen(false);
|
26
|
-
};
|
27
|
-
return /*#__PURE__*/ jsxs(Fragment, {
|
28
|
-
children: [
|
29
|
-
/*#__PURE__*/ jsx("header", {
|
30
|
-
className: clsxWithTw('px-2 md:px-4 sticky top-0 z-20 w-full h-14', TopHeaderThemeClass, className),
|
31
|
-
children: /*#__PURE__*/ jsxs("div", {
|
32
|
-
className: "flex justify-center items-center w-full h-full px-6",
|
33
|
-
children: [
|
34
|
-
/*#__PURE__*/ jsx("div", {
|
35
|
-
className: "font-semibold w-ful text-ellipsis overflow-hidden whitespace-nowrap",
|
36
|
-
children: title
|
37
|
-
}),
|
38
|
-
isMenuOpen ? /*#__PURE__*/ jsx(X, {
|
39
|
-
className: "w-5 h-5 absolute right-4 top-1/2 -translate-y-1/2 cursor-pointer",
|
40
|
-
onClick: ()=>setIsMenuOpen(!isMenuOpen)
|
41
|
-
}) : /*#__PURE__*/ jsx(MoreHorizontal, {
|
42
|
-
onClick: ()=>setIsMenuOpen(!isMenuOpen),
|
43
|
-
className: "w-5 h-5 absolute right-4 top-1/2 -translate-y-1/2 cursor-pointer"
|
44
|
-
})
|
45
|
-
]
|
46
|
-
})
|
47
|
-
}),
|
48
|
-
isMenuOpen ? /*#__PURE__*/ jsx("div", {
|
49
|
-
className: clsxWithTw('fixed inset-x-0 top-14 bottom-0 z-10', MaskThemeClass),
|
50
|
-
onClick: closeMenu
|
51
|
-
}) : null,
|
52
|
-
/*#__PURE__*/ jsx("div", {
|
53
|
-
className: clsxWithTw('fixed inset-x-0 z-10 transform transition-transform duration-300 ease-in-out', 'top-14', DropdownThemeClass, 'max-h-[calc(100vh-3.5rem)] overflow-y-auto', className, isMenuOpen ? 'translate-y-0 shadow-lg' : '-translate-y-full'),
|
54
|
-
children: /*#__PURE__*/ jsxs("div", {
|
55
|
-
className: "container space-y-4 py-6",
|
56
|
-
hidden: !isMenuOpen,
|
57
|
-
children: [
|
58
|
-
/*#__PURE__*/ jsxs(Link, {
|
59
|
-
to: "/",
|
60
|
-
className: "flex flex-col justify-center items-center space-x-2",
|
61
|
-
onClick: closeMenu,
|
62
|
-
children: [
|
63
|
-
appLogo ? /*#__PURE__*/ jsx("img", {
|
64
|
-
src: appLogo,
|
65
|
-
alt: "avatar",
|
66
|
-
className: "w-14 h-14 mb-4"
|
67
|
-
}) : null,
|
68
|
-
/*#__PURE__*/ jsx("span", {
|
69
|
-
className: "text-xl text-center font-medium w-full text-ellipsis overflow-hidden whitespace-nowrap ",
|
70
|
-
children: appName || '新应用'
|
71
|
-
}),
|
72
|
-
/*#__PURE__*/ jsx("div", {
|
73
|
-
className: "text-center justify-center text-token-text-title font-medium leading-relaxed"
|
74
|
-
})
|
75
|
-
]
|
76
|
-
}),
|
77
|
-
userAvatar ? /*#__PURE__*/ jsxs("div", {
|
78
|
-
children: [
|
79
|
-
/*#__PURE__*/ jsxs("div", {
|
80
|
-
className: "flex items-center justify-between border-gray-200 border-t py-4 ",
|
81
|
-
children: [
|
82
|
-
/*#__PURE__*/ jsx("div", {
|
83
|
-
children: "当前用户"
|
84
|
-
}),
|
85
|
-
/*#__PURE__*/ jsxs("div", {
|
86
|
-
className: "flex items-center",
|
87
|
-
children: [
|
88
|
-
/*#__PURE__*/ jsx("span", {
|
89
|
-
className: "flex-1 text-ellipsis overflow-hidden whitespace-nowrap",
|
90
|
-
children: userName
|
91
|
-
}),
|
92
|
-
/*#__PURE__*/ jsx("img", {
|
93
|
-
onClick: ()=>{
|
94
|
-
if (isSparkRuntime()) location.href = '/suda/user?brand=1';
|
95
|
-
},
|
96
|
-
src: userAvatar,
|
97
|
-
alt: "avatar",
|
98
|
-
className: "w-8 h-8 rounded-full ml-2"
|
99
|
-
})
|
100
|
-
]
|
101
|
-
})
|
102
|
-
]
|
103
|
-
}),
|
104
|
-
/*#__PURE__*/ jsxs("div", {
|
105
|
-
className: "flex items-center justify-between border-t border-gray-200 py-4 cursor-pointer",
|
106
|
-
onClick: async ()=>{
|
107
|
-
await handlerLogout();
|
108
|
-
closeMenu();
|
109
|
-
},
|
110
|
-
children: [
|
111
|
-
/*#__PURE__*/ jsx("div", {
|
112
|
-
children: "退出登录"
|
113
|
-
}),
|
114
|
-
/*#__PURE__*/ jsx("div", {
|
115
|
-
className: "flex items-center",
|
116
|
-
children: /*#__PURE__*/ jsx(LogOut, {
|
117
|
-
className: "w-5 h-5"
|
118
|
-
})
|
119
|
-
})
|
120
|
-
]
|
121
|
-
})
|
122
|
-
]
|
123
|
-
}) : null
|
124
|
-
]
|
125
|
-
})
|
126
|
-
})
|
127
|
-
]
|
128
|
-
});
|
129
|
-
};
|
130
|
-
export { TitleBar };
|
@@ -1,10 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* 顶部标题导航栏:支持 PC 和移动端
|
3
|
-
* 移动端收起导航,点击下拉使用
|
4
|
-
*/
|
5
|
-
import * as React from 'react';
|
6
|
-
import { BaseNavProps } from '../../types';
|
7
|
-
export interface TopNavProps extends BaseNavProps {
|
8
|
-
align?: 'left' | 'center' | 'right';
|
9
|
-
}
|
10
|
-
export declare function TopNav({ navList, align, className, activeClassName, }: TopNavProps): React.JSX.Element;
|
@@ -1,86 +0,0 @@
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
2
|
-
import { useRef, useState } from "react";
|
3
|
-
import { Menu, X } from "lucide-react";
|
4
|
-
import { Link } from "react-router-dom";
|
5
|
-
import { clsxWithTw } from "../../utils/utils.js";
|
6
|
-
import { useAppInfo } from "../../hooks/useAppInfo.js";
|
7
|
-
import { useCurrentUserProfile } from "../../hooks/useCurrentUserProfile.js";
|
8
|
-
import { DropdownThemeClass, NavMenu, TopHeaderThemeClass, UserAvatarMenu } from "../common/index.js";
|
9
|
-
function TopNav({ navList = [], align = 'left', className, activeClassName }) {
|
10
|
-
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
11
|
-
const navRef = useRef(null);
|
12
|
-
const { appName, appLogo } = useAppInfo();
|
13
|
-
const { avatar: userAvatar } = useCurrentUserProfile();
|
14
|
-
return /*#__PURE__*/ jsxs("header", {
|
15
|
-
ref: navRef,
|
16
|
-
className: clsxWithTw('miao-top-nav h-14 items-end w-[100vw] px-3 md:px-4 sticky top-0 z-50 shadow-xs flex', TopHeaderThemeClass, className),
|
17
|
-
children: [
|
18
|
-
/*#__PURE__*/ jsxs("div", {
|
19
|
-
className: "flex w-full h-full items-center justify-between",
|
20
|
-
children: [
|
21
|
-
/*#__PURE__*/ jsx("div", {
|
22
|
-
className: "flex items-center gap-6 md:gap-10 text-ellipsis overflow-hidden whitespace-nowrap",
|
23
|
-
children: /*#__PURE__*/ jsx(Link, {
|
24
|
-
to: "/",
|
25
|
-
className: "flex items-center space-x-2 w-[100%]",
|
26
|
-
children: /*#__PURE__*/ jsxs("div", {
|
27
|
-
className: "flex items-center gap-2 w-[100%]",
|
28
|
-
children: [
|
29
|
-
appLogo ? /*#__PURE__*/ jsx("img", {
|
30
|
-
src: appLogo,
|
31
|
-
alt: "avatar",
|
32
|
-
className: "w-7 h-7"
|
33
|
-
}) : null,
|
34
|
-
/*#__PURE__*/ jsx("span", {
|
35
|
-
className: "max-w-[240px] font-medium w-full truncate",
|
36
|
-
title: appName,
|
37
|
-
children: appName || '新应用'
|
38
|
-
})
|
39
|
-
]
|
40
|
-
})
|
41
|
-
})
|
42
|
-
}),
|
43
|
-
/*#__PURE__*/ jsx("div", {
|
44
|
-
className: clsxWithTw('flex-1 overflow-hidden ml-5 hidden md:block h-full', {
|
45
|
-
'items-start': 'left' === align,
|
46
|
-
'items-center': 'center' === align,
|
47
|
-
'items-end': 'right' === align
|
48
|
-
}),
|
49
|
-
children: /*#__PURE__*/ jsx(NavMenu, {
|
50
|
-
navList: navList,
|
51
|
-
className: className,
|
52
|
-
activeClassName: activeClassName
|
53
|
-
})
|
54
|
-
}),
|
55
|
-
userAvatar ? /*#__PURE__*/ jsx(UserAvatarMenu, {
|
56
|
-
className: className
|
57
|
-
}) : null,
|
58
|
-
navList.length > 0 ? /*#__PURE__*/ jsx("div", {
|
59
|
-
className: "md:hidden flex items-center",
|
60
|
-
children: isMenuOpen ? /*#__PURE__*/ jsx(X, {
|
61
|
-
className: "h-5 w-5 mx-3 cursor-pointer",
|
62
|
-
onClick: ()=>setIsMenuOpen(!isMenuOpen)
|
63
|
-
}) : /*#__PURE__*/ jsx(Menu, {
|
64
|
-
className: "h-5 w-5 mx-3 cursor-pointer",
|
65
|
-
onClick: ()=>setIsMenuOpen(!isMenuOpen)
|
66
|
-
})
|
67
|
-
}) : null
|
68
|
-
]
|
69
|
-
}),
|
70
|
-
isMenuOpen && navList.length > 0 ? /*#__PURE__*/ jsx("div", {
|
71
|
-
className: "md:hidden",
|
72
|
-
children: /*#__PURE__*/ jsx("div", {
|
73
|
-
className: clsxWithTw('overflow-y-auto max-h-[482px] border-t border-gray-200 py-2 absolute top-14 left-0 right-0 shadow-lg', DropdownThemeClass, className),
|
74
|
-
children: /*#__PURE__*/ jsx(NavMenu, {
|
75
|
-
navList: navList,
|
76
|
-
className: className,
|
77
|
-
activeClassName: activeClassName,
|
78
|
-
onClick: ()=>setIsMenuOpen(false),
|
79
|
-
mode: "vertical"
|
80
|
-
})
|
81
|
-
})
|
82
|
-
}) : null
|
83
|
-
]
|
84
|
-
});
|
85
|
-
}
|
86
|
-
export { TopNav };
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import * as React from 'react';
|
2
|
-
import { NavProps } from '../../types';
|
3
|
-
interface NavBarProps extends Omit<NavProps, 'mobileVariant'> {
|
4
|
-
align?: 'left' | 'center' | 'right';
|
5
|
-
/**
|
6
|
-
* 移动端导航栏 变体
|
7
|
-
*/
|
8
|
-
mobileVariant?: 'bottomBar' | 'dropdown';
|
9
|
-
}
|
10
|
-
export declare function Navigation(props: NavBarProps): React.JSX.Element;
|
11
|
-
export { Navigation as TopNav };
|
12
|
-
export default Navigation;
|
@@ -1,65 +0,0 @@
|
|
1
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
2
|
-
import { useEffect, useMemo } from "react";
|
3
|
-
import { useIsMobile } from "../../hooks/useIsMobile.js";
|
4
|
-
import { BottomNav } from "./BottomNav.js";
|
5
|
-
import { TitleBar } from "./TitleBar.js";
|
6
|
-
import { TopNav } from "./TopNav.js";
|
7
|
-
import { ConfigProvider } from "antd";
|
8
|
-
import { useTheme } from "../../hooks/useTheme.js";
|
9
|
-
import { useLocation } from "react-router-dom";
|
10
|
-
import { generateDarkTheme, generateLightTheme } from "../theme/util.js";
|
11
|
-
function NavigationBar({ navList = [], align, className, activeClassName, mobileVariant = 'dropdown' }) {
|
12
|
-
const isMobile = useIsMobile();
|
13
|
-
const location = useLocation();
|
14
|
-
useEffect(()=>{
|
15
|
-
window.scrollTo(0, 0);
|
16
|
-
}, [
|
17
|
-
location.pathname
|
18
|
-
]);
|
19
|
-
if (isMobile && 'bottomBar' === mobileVariant) {
|
20
|
-
if (0 === navList.length) return null;
|
21
|
-
return /*#__PURE__*/ jsxs(Fragment, {
|
22
|
-
children: [
|
23
|
-
/*#__PURE__*/ jsx(TitleBar, {
|
24
|
-
className: className,
|
25
|
-
navList: navList
|
26
|
-
}),
|
27
|
-
/*#__PURE__*/ jsx(BottomNav, {
|
28
|
-
navList: navList,
|
29
|
-
className: className
|
30
|
-
})
|
31
|
-
]
|
32
|
-
});
|
33
|
-
}
|
34
|
-
return /*#__PURE__*/ jsx(TopNav, {
|
35
|
-
navList: navList,
|
36
|
-
activeClassName: activeClassName,
|
37
|
-
align: align,
|
38
|
-
className: className
|
39
|
-
});
|
40
|
-
}
|
41
|
-
function Navigation(props) {
|
42
|
-
const { theme } = useTheme();
|
43
|
-
const { darkColorPrimary, lightColorPrimary } = props;
|
44
|
-
const themeToken = useMemo(()=>{
|
45
|
-
if ('dark' === theme && darkColorPrimary) return generateDarkTheme({
|
46
|
-
colorPrimary: darkColorPrimary
|
47
|
-
});
|
48
|
-
if ('light' === theme && lightColorPrimary) return generateLightTheme({
|
49
|
-
colorPrimary: lightColorPrimary
|
50
|
-
});
|
51
|
-
return {};
|
52
|
-
}, [
|
53
|
-
theme,
|
54
|
-
darkColorPrimary,
|
55
|
-
lightColorPrimary
|
56
|
-
]);
|
57
|
-
return /*#__PURE__*/ jsx(ConfigProvider, {
|
58
|
-
theme: themeToken,
|
59
|
-
children: /*#__PURE__*/ jsx(NavigationBar, {
|
60
|
-
...props
|
61
|
-
})
|
62
|
-
});
|
63
|
-
}
|
64
|
-
const components_TopNav = Navigation;
|
65
|
-
export { Navigation, Navigation as TopNav, components_TopNav as default };
|