yingzios-platform-frontend-devtools 1.0.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.
Files changed (39) hide show
  1. package/README.md +77 -0
  2. package/dist/base-path.d.ts +2 -0
  3. package/dist/base-path.d.ts.map +1 -0
  4. package/dist/base-path.js +2 -0
  5. package/dist/components/DevUserMenu/JwtGeneratorModal.d.ts +13 -0
  6. package/dist/components/DevUserMenu/JwtGeneratorModal.d.ts.map +1 -0
  7. package/dist/components/DevUserMenu/JwtGeneratorModal.js +137 -0
  8. package/dist/components/DevUserMenu/index.d.ts +31 -0
  9. package/dist/components/DevUserMenu/index.d.ts.map +1 -0
  10. package/dist/components/DevUserMenu/index.js +219 -0
  11. package/dist/components/DevUserMenu/jwt-utils.d.ts +34 -0
  12. package/dist/components/DevUserMenu/jwt-utils.d.ts.map +1 -0
  13. package/dist/components/DevUserMenu/jwt-utils.js +85 -0
  14. package/dist/components/DevUserMenu/styles.d.ts +5 -0
  15. package/dist/components/DevUserMenu/styles.d.ts.map +1 -0
  16. package/dist/components/DevUserMenu/styles.js +225 -0
  17. package/dist/components/StandaloneAppLayout/index.d.ts +63 -0
  18. package/dist/components/StandaloneAppLayout/index.d.ts.map +1 -0
  19. package/dist/components/StandaloneAppLayout/index.js +161 -0
  20. package/dist/components/StandaloneAppLayout/styles.d.ts +5 -0
  21. package/dist/components/StandaloneAppLayout/styles.d.ts.map +1 -0
  22. package/dist/components/StandaloneAppLayout/styles.js +230 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +4 -0
  26. package/dist/manifest-loader.d.ts +50 -0
  27. package/dist/manifest-loader.d.ts.map +1 -0
  28. package/dist/manifest-loader.js +90 -0
  29. package/package.json +50 -0
  30. package/src/base-path.ts +2 -0
  31. package/src/components/DevUserMenu/JwtGeneratorModal.tsx +219 -0
  32. package/src/components/DevUserMenu/index.tsx +372 -0
  33. package/src/components/DevUserMenu/jwt-utils.ts +121 -0
  34. package/src/components/DevUserMenu/styles.ts +229 -0
  35. package/src/components/StandaloneAppLayout/index.tsx +332 -0
  36. package/src/components/StandaloneAppLayout/styles.ts +234 -0
  37. package/src/index.ts +4 -0
  38. package/src/manifest-loader.ts +146 -0
  39. package/src/types/scss.d.ts +19 -0
@@ -0,0 +1,225 @@
1
+ export const devUserMenuStyles = {
2
+ container: {
3
+ position: 'relative',
4
+ display: 'flex',
5
+ alignItems: 'center',
6
+ gap: 10,
7
+ },
8
+ switchOrgButton: {
9
+ height: 32,
10
+ padding: '0 14px',
11
+ border: '1px solid #d8e0eb',
12
+ borderRadius: 16,
13
+ background: '#ffffff',
14
+ color: '#10233d',
15
+ fontSize: 13,
16
+ fontWeight: 500,
17
+ cursor: 'pointer',
18
+ transition: 'border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease',
19
+ },
20
+ avatar: {
21
+ width: 32,
22
+ height: 32,
23
+ borderRadius: '50%',
24
+ background: '#1890ff',
25
+ color: '#fff',
26
+ border: 'none',
27
+ cursor: 'pointer',
28
+ display: 'flex',
29
+ alignItems: 'center',
30
+ justifyContent: 'center',
31
+ fontSize: 14,
32
+ fontWeight: 500,
33
+ transition: 'opacity 0.2s',
34
+ },
35
+ avatarImage: {
36
+ width: '100%',
37
+ height: '100%',
38
+ borderRadius: '50%',
39
+ objectFit: 'cover',
40
+ },
41
+ loginButton: {
42
+ padding: '6px 16px',
43
+ background: '#1890ff',
44
+ color: '#fff',
45
+ border: 'none',
46
+ borderRadius: 4,
47
+ cursor: 'pointer',
48
+ fontSize: 14,
49
+ transition: 'background 0.2s',
50
+ },
51
+ dropdown: {
52
+ position: 'absolute',
53
+ top: '100%',
54
+ right: 0,
55
+ marginTop: 8,
56
+ minWidth: 180,
57
+ background: '#fff',
58
+ borderRadius: 6,
59
+ boxShadow: '0 3px 12px rgba(0, 0, 0, 0.15)',
60
+ zIndex: 1000,
61
+ overflow: 'hidden',
62
+ },
63
+ dropdownHeader: {
64
+ padding: '12px 16px',
65
+ display: 'flex',
66
+ flexDirection: 'column',
67
+ gap: 4,
68
+ },
69
+ dropdownNickname: {
70
+ fontSize: 14,
71
+ fontWeight: 500,
72
+ color: '#333',
73
+ },
74
+ dropdownPhone: {
75
+ fontSize: 12,
76
+ color: '#999',
77
+ },
78
+ dropdownDivider: {
79
+ height: 1,
80
+ background: '#f0f0f0',
81
+ margin: '0 8px',
82
+ },
83
+ dropdownItem: {
84
+ display: 'block',
85
+ width: '100%',
86
+ padding: '10px 16px',
87
+ textAlign: 'left',
88
+ background: 'none',
89
+ border: 'none',
90
+ fontSize: 14,
91
+ color: '#333',
92
+ cursor: 'pointer',
93
+ transition: 'background 0.2s',
94
+ },
95
+ };
96
+ export const modalStyles = {
97
+ overlay: {
98
+ position: 'fixed',
99
+ top: 0,
100
+ left: 0,
101
+ right: 0,
102
+ bottom: 0,
103
+ background: 'rgba(0, 0, 0, 0.45)',
104
+ display: 'flex',
105
+ alignItems: 'center',
106
+ justifyContent: 'center',
107
+ zIndex: 10000,
108
+ },
109
+ modal: {
110
+ width: 360,
111
+ background: '#fff',
112
+ borderRadius: 8,
113
+ boxShadow: '0 6px 24px rgba(0, 0, 0, 0.2)',
114
+ },
115
+ header: {
116
+ display: 'flex',
117
+ alignItems: 'center',
118
+ justifyContent: 'space-between',
119
+ padding: '16px 20px',
120
+ borderBottom: '1px solid #f0f0f0',
121
+ },
122
+ title: {
123
+ margin: 0,
124
+ fontSize: 16,
125
+ fontWeight: 500,
126
+ color: '#333',
127
+ },
128
+ closeButton: {
129
+ width: 24,
130
+ height: 24,
131
+ background: 'none',
132
+ border: 'none',
133
+ fontSize: 20,
134
+ color: '#999',
135
+ cursor: 'pointer',
136
+ display: 'flex',
137
+ alignItems: 'center',
138
+ justifyContent: 'center',
139
+ borderRadius: 4,
140
+ transition: 'background 0.2s',
141
+ },
142
+ form: {
143
+ padding: 20,
144
+ },
145
+ tip: {
146
+ margin: '12px 0',
147
+ padding: '8px 12px',
148
+ background: '#fffbe6',
149
+ border: '1px solid #ffe58f',
150
+ borderRadius: 4,
151
+ fontSize: 12,
152
+ color: '#8c6d1f',
153
+ },
154
+ tipCode: {
155
+ padding: '2px 6px',
156
+ background: 'rgba(0, 0, 0, 0.06)',
157
+ borderRadius: 3,
158
+ fontFamily: 'monospace',
159
+ },
160
+ submitButton: {
161
+ width: '100%',
162
+ padding: 10,
163
+ background: '#1890ff',
164
+ color: '#fff',
165
+ border: 'none',
166
+ borderRadius: 4,
167
+ fontSize: 14,
168
+ cursor: 'pointer',
169
+ transition: 'background 0.2s',
170
+ },
171
+ submitButtonDisabled: {
172
+ opacity: 0.65,
173
+ cursor: 'not-allowed',
174
+ },
175
+ error: {
176
+ marginBottom: 12,
177
+ padding: '8px 12px',
178
+ background: '#fff2f0',
179
+ border: '1px solid #ffccc7',
180
+ borderRadius: 4,
181
+ fontSize: 13,
182
+ color: '#cf1322',
183
+ },
184
+ };
185
+ export const formGroupStyles = {
186
+ group: {
187
+ marginBottom: 16,
188
+ },
189
+ label: {
190
+ display: 'block',
191
+ marginBottom: 6,
192
+ fontSize: 14,
193
+ color: '#333',
194
+ },
195
+ input: {
196
+ width: '100%',
197
+ padding: '8px 12px',
198
+ border: '1px solid #d9d9d9',
199
+ borderRadius: 4,
200
+ fontSize: 14,
201
+ outline: 'none',
202
+ transition: 'border-color 0.2s',
203
+ boxSizing: 'border-box',
204
+ },
205
+ inputRow: {
206
+ display: 'flex',
207
+ gap: 8,
208
+ },
209
+ sendButton: {
210
+ flexShrink: 0,
211
+ padding: '8px 12px',
212
+ background: '#fff',
213
+ border: '1px solid #d9d9d9',
214
+ borderRadius: 4,
215
+ fontSize: 14,
216
+ color: '#333',
217
+ cursor: 'pointer',
218
+ whiteSpace: 'nowrap',
219
+ transition: 'border-color 0.2s, color 0.2s',
220
+ },
221
+ sendButtonDisabled: {
222
+ color: '#bfbfbf',
223
+ cursor: 'not-allowed',
224
+ },
225
+ };
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import type { FrontendNavIconKey } from 'yz-frontend-core';
3
+ export type IconRenderer = (iconKey: FrontendNavIconKey) => React.ReactNode;
4
+ export interface StandaloneAppLayoutProps {
5
+ /**
6
+ * manifest 文件路径,默认 'app-manifest.json'(相对路径,受 <base> 标签影响)
7
+ */
8
+ manifestUrl?: string;
9
+ /**
10
+ * 子内容
11
+ */
12
+ children: React.ReactNode;
13
+ /**
14
+ * 自定义 Logo 组件
15
+ */
16
+ logo?: React.ReactNode;
17
+ /**
18
+ * 自定义顶部右侧内容
19
+ * 如果为 false,则不显示默认的登录组件
20
+ */
21
+ headerRight?: React.ReactNode | false;
22
+ /**
23
+ * 自定义图标渲染函数
24
+ * 传入 iconKey,返回 React 节点
25
+ */
26
+ renderIcon?: IconRenderer;
27
+ /**
28
+ * API 基础路径,用于登录接口
29
+ * 默认 '/portal/api'
30
+ */
31
+ apiBasePath?: string;
32
+ /**
33
+ * 组织切换页面路径
34
+ * 默认 '/org-select'
35
+ */
36
+ orgSwitchPath?: string;
37
+ }
38
+ /**
39
+ * 独立运行模式下的应用布局
40
+ *
41
+ * 自动从 app-manifest.json 加载配置并生成导航菜单。
42
+ * 用于微应用本地独立开发时提供统一的导航体验。
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * import { StandaloneAppLayout } from 'yz-frontend-devtools';
47
+ *
48
+ * function StandaloneApp() {
49
+ * return (
50
+ * <StandaloneAppLayout>
51
+ * <AppRoutes />
52
+ * </StandaloneAppLayout>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export declare function StandaloneAppLayout({ manifestUrl, children, logo, headerRight, renderIcon, apiBasePath, orgSwitchPath, }: StandaloneAppLayoutProps): React.JSX.Element;
58
+ export declare namespace StandaloneAppLayout {
59
+ var displayName: string;
60
+ }
61
+ declare const _default: React.MemoExoticComponent<typeof StandaloneAppLayout>;
62
+ export default _default;
63
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/StandaloneAppLayout/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAGlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAW3D,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,KAAK,CAAC,SAAS,CAAC;AA+B5E,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;IACtC;;;OAGG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,WAAiC,EACjC,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,UAAU,EACV,WAA2B,EAC3B,aAA6B,GAC9B,EAAE,wBAAwB,qBA4G1B;yBApHe,mBAAmB;;;;AAwOnC,wBAAyC"}
@@ -0,0 +1,161 @@
1
+ import React, { memo, useEffect, useMemo, useState } from 'react';
2
+ import { Link, useLocation } from 'react-router-dom';
3
+ import { loadAppManifest, buildMenuGroupsFromManifest, } from '../../manifest-loader';
4
+ import { DevUserMenu } from '../DevUserMenu';
5
+ import { layoutStyles, leftNavStyles, groupNavStyles } from './styles';
6
+ function isPathActive(currentPath, candidatePath, end) {
7
+ if (candidatePath === currentPath) {
8
+ return true;
9
+ }
10
+ return end === false && currentPath.startsWith(candidatePath + '/');
11
+ }
12
+ function isStandaloneMenuItemActive(currentPath, item) {
13
+ if (isPathActive(currentPath, item.path, item.end)) {
14
+ return true;
15
+ }
16
+ return item.matchPaths.some((matchPath) => isPathActive(currentPath, matchPath, item.end));
17
+ }
18
+ /**
19
+ * 独立运行模式下的应用布局
20
+ *
21
+ * 自动从 app-manifest.json 加载配置并生成导航菜单。
22
+ * 用于微应用本地独立开发时提供统一的导航体验。
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * import { StandaloneAppLayout } from 'yz-frontend-devtools';
27
+ *
28
+ * function StandaloneApp() {
29
+ * return (
30
+ * <StandaloneAppLayout>
31
+ * <AppRoutes />
32
+ * </StandaloneAppLayout>
33
+ * );
34
+ * }
35
+ * ```
36
+ */
37
+ export function StandaloneAppLayout({ manifestUrl = 'app-manifest.json', children, logo, headerRight, renderIcon, apiBasePath = '/portal/api', orgSwitchPath = '/org-select', }) {
38
+ const [menuGroups, setMenuGroups] = useState([]);
39
+ const [appName, setAppName] = useState('');
40
+ const [loading, setLoading] = useState(true);
41
+ const [error, setError] = useState(null);
42
+ const location = useLocation();
43
+ useEffect(() => {
44
+ loadAppManifest(manifestUrl)
45
+ .then((manifest) => {
46
+ const groups = buildMenuGroupsFromManifest(manifest);
47
+ setMenuGroups(groups);
48
+ setAppName(manifest.displayName);
49
+ setLoading(false);
50
+ })
51
+ .catch((err) => {
52
+ console.error('[StandaloneAppLayout] Failed to load manifest:', err);
53
+ setError(err.message);
54
+ setLoading(false);
55
+ });
56
+ }, [manifestUrl]);
57
+ const isMenuItemActive = (item) => isStandaloneMenuItemActive(location.pathname, item);
58
+ const primaryNavItems = useMemo(() => menuGroups.flatMap((group) => {
59
+ const firstItem = group.items[0];
60
+ if (!firstItem) {
61
+ return [];
62
+ }
63
+ return [{
64
+ key: `group-${group.groupLabel}`,
65
+ label: group.groupLabel,
66
+ path: firstItem.path,
67
+ iconKey: firstItem.iconKey,
68
+ items: group.items,
69
+ }];
70
+ }), [menuGroups]);
71
+ const activePrimaryNav = useMemo(() => primaryNavItems.find((item) => item.items.some((child) => isMenuItemActive(child))) || primaryNavItems[0], [location.pathname, primaryNavItems]);
72
+ const activeSidebarItems = activePrimaryNav?.items ?? [];
73
+ // 渲染右上角内容
74
+ const renderHeaderRight = () => {
75
+ // 如果显式传入 false,则不渲染
76
+ if (headerRight === false) {
77
+ return null;
78
+ }
79
+ // 如果传入了自定义内容,则渲染自定义内容
80
+ if (headerRight) {
81
+ return headerRight;
82
+ }
83
+ // 默认渲染登录组件
84
+ return React.createElement(DevUserMenu, { apiBasePath: apiBasePath, orgSwitchPath: orgSwitchPath });
85
+ };
86
+ if (loading) {
87
+ return (React.createElement("div", { style: layoutStyles.layout },
88
+ React.createElement("div", { style: layoutStyles.loading }, "\u52A0\u8F7D\u4E2D...")));
89
+ }
90
+ if (error) {
91
+ return (React.createElement("div", { style: layoutStyles.layout },
92
+ React.createElement("div", { style: layoutStyles.error },
93
+ React.createElement("span", null,
94
+ "\u52A0\u8F7D\u5931\u8D25: ",
95
+ error))));
96
+ }
97
+ return (React.createElement("div", { style: layoutStyles.layout },
98
+ React.createElement("header", { style: layoutStyles.header },
99
+ React.createElement("div", { style: layoutStyles.headerLeft },
100
+ logo ?? (React.createElement("span", { style: layoutStyles.logo }, appName || 'App')),
101
+ React.createElement("span", { style: layoutStyles.devBadge }, "DEV")),
102
+ React.createElement("div", { style: layoutStyles.headerRight }, renderHeaderRight())),
103
+ React.createElement("div", { style: layoutStyles.shell },
104
+ React.createElement("aside", { style: layoutStyles.sidebar },
105
+ React.createElement(LeftNav, { items: activeSidebarItems, currentPath: location.pathname, renderIcon: renderIcon })),
106
+ React.createElement("main", { style: layoutStyles.main },
107
+ React.createElement(GroupNav, { items: primaryNavItems, currentPath: location.pathname }),
108
+ React.createElement("div", { style: layoutStyles.content }, children)))));
109
+ }
110
+ function LeftNav({ items, currentPath, renderIcon }) {
111
+ const [hoveredKey, setHoveredKey] = useState(null);
112
+ const isActive = (item) => isStandaloneMenuItemActive(currentPath, item);
113
+ const getIcon = (iconKey, active) => {
114
+ if (!iconKey) {
115
+ return React.createElement("span", { style: leftNavStyles.itemIconPlaceholder });
116
+ }
117
+ if (renderIcon) {
118
+ return renderIcon(iconKey);
119
+ }
120
+ // 默认:显示一个简单的圆点
121
+ return React.createElement("span", { style: leftNavStyles.itemIconDot });
122
+ };
123
+ const getItemStyle = (item) => {
124
+ const active = isActive(item);
125
+ const hovered = hoveredKey === item.key;
126
+ return {
127
+ ...leftNavStyles.item,
128
+ ...(hovered && !active ? leftNavStyles.itemHover : {}),
129
+ ...(active ? leftNavStyles.itemActive : {}),
130
+ };
131
+ };
132
+ const getIconStyle = (item) => {
133
+ const active = isActive(item);
134
+ return {
135
+ ...leftNavStyles.itemIcon,
136
+ ...(active ? leftNavStyles.itemIconActive : {}),
137
+ };
138
+ };
139
+ return (React.createElement("nav", { "aria-label": "\u5F00\u53D1\u6A21\u5F0F\u4E3B\u5BFC\u822A", style: leftNavStyles.nav },
140
+ React.createElement("div", { style: leftNavStyles.scrollArea },
141
+ React.createElement("section", { style: leftNavStyles.group }, items.map((item) => (React.createElement(Link, { "aria-current": isActive(item) ? 'page' : undefined, key: item.key, to: item.path, title: item.label, style: getItemStyle(item), onMouseEnter: () => setHoveredKey(item.key), onMouseLeave: () => setHoveredKey(null) },
142
+ React.createElement("span", { style: getIconStyle(item) }, getIcon(item.iconKey, isActive(item))),
143
+ React.createElement("span", { style: leftNavStyles.itemLabel }, item.label))))))));
144
+ }
145
+ function GroupNav({ items, currentPath }) {
146
+ const [hoveredKey, setHoveredKey] = useState(null);
147
+ const isActive = (item) => item.items.some((child) => isStandaloneMenuItemActive(currentPath, child));
148
+ const getItemStyle = (item) => {
149
+ const active = isActive(item);
150
+ const hovered = hoveredKey === item.key;
151
+ return {
152
+ ...groupNavStyles.item,
153
+ ...(hovered && !active ? groupNavStyles.itemHover : {}),
154
+ ...(active ? groupNavStyles.itemActive : {}),
155
+ };
156
+ };
157
+ return (React.createElement("div", { style: groupNavStyles.nav },
158
+ React.createElement("div", { style: groupNavStyles.scroll }, items.map((item) => (React.createElement(Link, { "aria-current": isActive(item) ? 'page' : undefined, key: item.key, to: item.path, style: getItemStyle(item), onMouseEnter: () => setHoveredKey(item.key), onMouseLeave: () => setHoveredKey(null) }, item.label))))));
159
+ }
160
+ StandaloneAppLayout.displayName = 'StandaloneAppLayout';
161
+ export default memo(StandaloneAppLayout);
@@ -0,0 +1,5 @@
1
+ import type { CSSProperties } from 'react';
2
+ export declare const layoutStyles: Record<string, CSSProperties>;
3
+ export declare const leftNavStyles: Record<string, CSSProperties>;
4
+ export declare const groupNavStyles: Record<string, CSSProperties>;
5
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/components/StandaloneAppLayout/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAgGtD,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAsFvD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CA4CxD,CAAC"}
@@ -0,0 +1,230 @@
1
+ // CSS-in-JS 样式定义,避免 scss 构建问题
2
+ export const layoutStyles = {
3
+ layout: {
4
+ display: 'flex',
5
+ flexDirection: 'column',
6
+ height: '100vh',
7
+ minHeight: 0,
8
+ width: '100%',
9
+ overflow: 'hidden',
10
+ background: '#ffffff',
11
+ },
12
+ loading: {
13
+ display: 'flex',
14
+ alignItems: 'center',
15
+ justifyContent: 'center',
16
+ minHeight: '100vh',
17
+ color: '#666',
18
+ fontSize: 14,
19
+ },
20
+ error: {
21
+ display: 'flex',
22
+ alignItems: 'center',
23
+ justifyContent: 'center',
24
+ minHeight: '100vh',
25
+ color: '#ff4d4f',
26
+ fontSize: 14,
27
+ },
28
+ header: {
29
+ position: 'sticky',
30
+ top: 0,
31
+ zIndex: 20,
32
+ display: 'flex',
33
+ alignItems: 'center',
34
+ justifyContent: 'space-between',
35
+ height: 56,
36
+ padding: '0 16px',
37
+ background: '#ffffff',
38
+ borderBottom: '1px solid rgba(226, 232, 240, 0.9)',
39
+ flexShrink: 0,
40
+ },
41
+ headerLeft: {
42
+ display: 'flex',
43
+ alignItems: 'center',
44
+ gap: 12,
45
+ },
46
+ headerRight: {
47
+ display: 'flex',
48
+ alignItems: 'center',
49
+ gap: 8,
50
+ },
51
+ logo: {
52
+ fontSize: 18,
53
+ fontWeight: 600,
54
+ color: '#0f172a',
55
+ },
56
+ devBadge: {
57
+ display: 'inline-flex',
58
+ alignItems: 'center',
59
+ padding: '2px 8px',
60
+ fontSize: 11,
61
+ fontWeight: 600,
62
+ color: '#0f172a',
63
+ background: '#f1f5f9',
64
+ border: '1px solid #e2e8f0',
65
+ borderRadius: 999,
66
+ textTransform: 'uppercase',
67
+ letterSpacing: 0.5,
68
+ },
69
+ shell: {
70
+ display: 'flex',
71
+ flex: 1,
72
+ overflow: 'hidden',
73
+ minHeight: 0,
74
+ background: 'linear-gradient(180deg, #f8fafc 0%, #f3f6fb 100%)',
75
+ },
76
+ sidebar: {
77
+ width: 256,
78
+ display: 'flex',
79
+ flexShrink: 0,
80
+ minHeight: 0,
81
+ overflow: 'hidden',
82
+ },
83
+ main: {
84
+ flex: 1,
85
+ display: 'flex',
86
+ flexDirection: 'column',
87
+ minWidth: 0,
88
+ minHeight: 0,
89
+ },
90
+ content: {
91
+ flex: 1,
92
+ overflowY: 'auto',
93
+ minHeight: 0,
94
+ position: 'relative',
95
+ padding: '24px 28px 28px',
96
+ background: 'transparent',
97
+ },
98
+ };
99
+ export const leftNavStyles = {
100
+ nav: {
101
+ width: 256,
102
+ flex: 1,
103
+ flexShrink: 0,
104
+ display: 'flex',
105
+ flexDirection: 'column',
106
+ minHeight: 0,
107
+ height: '100%',
108
+ borderRight: '1px solid rgba(226, 232, 240, 0.9)',
109
+ background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(248, 250, 252, 0.98) 100%)',
110
+ padding: 0,
111
+ overflow: 'hidden',
112
+ },
113
+ scrollArea: {
114
+ flex: 1,
115
+ overflowY: 'auto',
116
+ padding: '18px 16px 12px',
117
+ },
118
+ group: {
119
+ display: 'flex',
120
+ flexDirection: 'column',
121
+ gap: 6,
122
+ },
123
+ item: {
124
+ display: 'flex',
125
+ alignItems: 'center',
126
+ justifyContent: 'flex-start',
127
+ gap: 12,
128
+ minHeight: 44,
129
+ padding: '10px 12px',
130
+ color: '#475569',
131
+ textDecoration: 'none',
132
+ border: '1px solid transparent',
133
+ borderRadius: 8,
134
+ background: 'transparent',
135
+ transition: 'background 0.15s, color 0.15s',
136
+ cursor: 'pointer',
137
+ },
138
+ itemHover: {
139
+ background: '#f8fafc',
140
+ color: '#0f172a',
141
+ },
142
+ itemActive: {
143
+ background: '#030213',
144
+ color: '#ffffff',
145
+ fontWeight: 500,
146
+ boxShadow: '0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1)',
147
+ },
148
+ itemIcon: {
149
+ display: 'flex',
150
+ alignItems: 'center',
151
+ justifyContent: 'center',
152
+ width: 32,
153
+ minWidth: 32,
154
+ height: 32,
155
+ borderRadius: 8,
156
+ background: 'linear-gradient(180deg, #f8fafc 0%, #edf2f7 100%)',
157
+ color: '#64748b',
158
+ boxShadow: 'inset 0 0 0 1px rgba(226, 232, 240, 0.85)',
159
+ },
160
+ itemIconActive: {
161
+ background: 'rgba(255, 255, 255, 0.15)',
162
+ color: '#ffffff',
163
+ boxShadow: 'none',
164
+ },
165
+ itemIconPlaceholder: {
166
+ width: 6,
167
+ height: 6,
168
+ borderRadius: '50%',
169
+ background: '#94a3b8',
170
+ },
171
+ itemIconDot: {
172
+ width: 6,
173
+ height: 6,
174
+ borderRadius: '50%',
175
+ background: 'currentColor',
176
+ opacity: 0.5,
177
+ },
178
+ itemLabel: {
179
+ fontSize: 14,
180
+ fontWeight: 500,
181
+ whiteSpace: 'nowrap',
182
+ overflow: 'hidden',
183
+ textOverflow: 'ellipsis',
184
+ },
185
+ };
186
+ export const groupNavStyles = {
187
+ nav: {
188
+ display: 'flex',
189
+ alignItems: 'center',
190
+ height: 56,
191
+ padding: '0 28px',
192
+ borderBottom: '1px solid rgba(226, 232, 240, 0.9)',
193
+ background: 'rgba(255, 255, 255, 0.7)',
194
+ backdropFilter: 'blur(8px)',
195
+ flexShrink: 0,
196
+ },
197
+ scroll: {
198
+ display: 'flex',
199
+ alignItems: 'center',
200
+ gap: 8,
201
+ overflowX: 'auto',
202
+ },
203
+ item: {
204
+ display: 'inline-flex',
205
+ alignItems: 'center',
206
+ justifyContent: 'center',
207
+ height: 32,
208
+ padding: '0 14px',
209
+ fontSize: 13,
210
+ fontWeight: 500,
211
+ color: '#64748b',
212
+ textDecoration: 'none',
213
+ border: '1px solid transparent',
214
+ borderRadius: 8,
215
+ background: 'transparent',
216
+ whiteSpace: 'nowrap',
217
+ cursor: 'pointer',
218
+ transition: 'all 0.15s',
219
+ },
220
+ itemHover: {
221
+ color: '#0f172a',
222
+ background: '#f1f5f9',
223
+ },
224
+ itemActive: {
225
+ color: '#0f172a',
226
+ background: '#ffffff',
227
+ borderColor: '#e2e8f0',
228
+ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.05)',
229
+ },
230
+ };
@@ -0,0 +1,5 @@
1
+ export * from './base-path';
2
+ export * from './components/StandaloneAppLayout';
3
+ export * from './components/DevUserMenu';
4
+ export * from './manifest-loader';
5
+ //# sourceMappingURL=index.d.ts.map