@spacego/fe-components 0.0.1-alpha.2 → 0.0.1-alpha.3
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/package.json +9 -1
- package/src/assets/styles/animate.css +0 -62
- package/src/assets/styles/index.css +0 -49
- package/src/assets/svg/chrome-bg-after.svg +0 -1
- package/src/assets/svg/chrome-bg-before.svg +0 -1
- package/src/assets/svg/icon-arrows-right.svg +0 -1
- package/src/assets/svg/icon-bell.svg +0 -1
- package/src/assets/svg/icon-custom.svg +0 -1
- package/src/assets/svg/icon-sun-moon.svg +0 -1
- package/src/assets/svg/icon-system.svg +0 -1
- package/src/assets/svg/loading.svg +0 -13
- package/src/assets/svg/login-view.svg +0 -193
- package/src/config/constants.ts +0 -19
- package/src/config/index.ts +0 -2
- package/src/config/theme.ts +0 -20
- package/src/fe-layouts/auth-layout/index.scss +0 -34
- package/src/fe-layouts/auth-layout/index.tsx +0 -121
- package/src/fe-layouts/basics-layout/components/basics-layout/header.tsx +0 -148
- package/src/fe-layouts/basics-layout/components/basics-layout/setting-custom-color.tsx +0 -52
- package/src/fe-layouts/basics-layout/components/basics-layout/setting-drawer.tsx +0 -165
- package/src/fe-layouts/basics-layout/components/basics-layout/sidebar.tsx +0 -88
- package/src/fe-layouts/basics-layout/components/basics-layout/tabs.tsx +0 -94
- package/src/fe-layouts/basics-layout/components/utils/index.ts +0 -142
- package/src/fe-layouts/basics-layout/index.scss +0 -110
- package/src/fe-layouts/basics-layout/index.tsx +0 -207
- package/src/fe-layouts/blank-layout/index.tsx +0 -12
- package/src/fe-layouts/context/context.ts +0 -11
- package/src/fe-layouts/context/global-context.d.ts +0 -241
- package/src/fe-layouts/context/global-context.provider.tsx +0 -81
- package/src/fe-layouts/context/index.ts +0 -10
- package/src/fe-layouts/index.ts +0 -13
- package/src/fe-layouts/layout.tsx +0 -74
- package/src/hooks/index.ts +0 -1
- package/src/hooks/use-auth.hook.ts +0 -54
- package/src/index.ts +0 -24
- package/src/router/index.ts +0 -110
- package/src/router/permission.tsx +0 -134
- package/src/router/routes.tsx +0 -94
- package/src/router/utils.ts +0 -283
- package/src/store/index.ts +0 -9
- package/src/store/modules/layout-config.store.ts +0 -343
- package/src/store/modules/theme.store.ts +0 -99
- package/src/typings/index.d.ts +0 -59
- package/src/typings/shims-axios.d.ts +0 -38
- package/src/utils/icon.tsx +0 -32
- package/src/utils/index.ts +0 -9
- package/src/utils/theme.ts +0 -219
- package/tsconfig.json +0 -28
- package/vite.config.ts +0 -85
package/src/utils/theme.ts
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author: dushuai
|
|
3
|
-
* @Date: 2026-01-28
|
|
4
|
-
* @LastEditors: dushuai
|
|
5
|
-
* @LastEditTime: 2026-01-31 23:30:06
|
|
6
|
-
* @description: 主题工具函数
|
|
7
|
-
*/
|
|
8
|
-
import { type ThemeMode, useThemeStore } from '@/store';
|
|
9
|
-
|
|
10
|
-
const THEME_ATTRIBUTE = 'data-theme';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 获取当前主题(实际显示的 light/dark)
|
|
14
|
-
* @param mode 主题模式 (light/dark/system)
|
|
15
|
-
* @returns 实际主题 (light/dark)
|
|
16
|
-
*/
|
|
17
|
-
export function getRealTheme(mode: ThemeMode): 'light' | 'dark' {
|
|
18
|
-
if(mode === 'system') {
|
|
19
|
-
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
20
|
-
}
|
|
21
|
-
return mode;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 应用主题到 DOM
|
|
26
|
-
* @param theme 主题模式
|
|
27
|
-
*/
|
|
28
|
-
export function applyTheme(theme: ThemeMode): void {
|
|
29
|
-
const root = document.documentElement;
|
|
30
|
-
// 获取实际主题(system 会转换为 light/dark)
|
|
31
|
-
const realTheme = getRealTheme(theme);
|
|
32
|
-
// data-theme 属性设置为实际主题值,而不是 system
|
|
33
|
-
root.setAttribute(THEME_ATTRIBUTE, realTheme);
|
|
34
|
-
root.classList.toggle('dark', realTheme === 'dark');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 获取当前主题
|
|
39
|
-
* @returns 当前主题模式
|
|
40
|
-
*/
|
|
41
|
-
export function getTheme(): ThemeMode {
|
|
42
|
-
// 优先从 DOM 获取
|
|
43
|
-
const root = document.documentElement;
|
|
44
|
-
const themeFromDom = root.getAttribute(THEME_ATTRIBUTE) as ThemeMode | null;
|
|
45
|
-
if(themeFromDom && (themeFromDom === 'light' || themeFromDom === 'dark')) {
|
|
46
|
-
return themeFromDom;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 从 localStorage 获取
|
|
50
|
-
const { theme } = useThemeStore.getState();
|
|
51
|
-
if(theme && (theme === 'light' || theme === 'dark')) {
|
|
52
|
-
return theme;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 检测系统主题
|
|
56
|
-
if(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
57
|
-
return 'dark';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 默认返回 light
|
|
61
|
-
return 'light';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 监听系统主题变化
|
|
66
|
-
*/
|
|
67
|
-
export function listenSystemTheme(): void {
|
|
68
|
-
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
69
|
-
const handler = (e: MediaQueryListEvent) => {
|
|
70
|
-
const { theme } = useThemeStore.getState();
|
|
71
|
-
if(theme === 'system') {
|
|
72
|
-
const newTheme = e.matches ? 'dark' : 'light';
|
|
73
|
-
document.documentElement.classList.toggle('dark', newTheme === 'dark');
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
mediaQuery.addEventListener('change', handler);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* 初始化主题
|
|
82
|
-
*/
|
|
83
|
-
export function initTheme(): ThemeMode {
|
|
84
|
-
const theme = getTheme();
|
|
85
|
-
applyTheme(theme);
|
|
86
|
-
listenSystemTheme(); // 启动监听
|
|
87
|
-
return theme;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* 切换主题
|
|
92
|
-
* @param currentTheme 当前主题
|
|
93
|
-
* @returns 新主题
|
|
94
|
-
*/
|
|
95
|
-
export function toggleTheme(currentTheme: ThemeMode): ThemeMode {
|
|
96
|
-
let newTheme: ThemeMode;
|
|
97
|
-
if(currentTheme === 'system') {
|
|
98
|
-
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
99
|
-
newTheme = isDark ? 'light' : 'dark';
|
|
100
|
-
} else {
|
|
101
|
-
newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
|
102
|
-
}
|
|
103
|
-
applyTheme(newTheme);
|
|
104
|
-
return newTheme;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* 应用主题色到 DOM
|
|
109
|
-
* @param color 主题色
|
|
110
|
-
*/
|
|
111
|
-
export function applyThemeColor(color: string): void {
|
|
112
|
-
if(document.documentElement) {
|
|
113
|
-
document.documentElement.style.setProperty('--color-primary', color);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* 从指定位置开始应用主题过渡效果
|
|
119
|
-
* @param theme 新主题模式
|
|
120
|
-
* @param x 点击位置的 x 坐标
|
|
121
|
-
* @param y 点击位置的 y 坐标
|
|
122
|
-
*/
|
|
123
|
-
export function applyThemeWithTransition(theme: ThemeMode, x: number, y: number): Promise<void> {
|
|
124
|
-
// 降级处理:不支持 View Transition
|
|
125
|
-
if(!(document as any).startViewTransition) {
|
|
126
|
-
applyTheme(theme);
|
|
127
|
-
return Promise.resolve();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return new Promise((resolve) => {
|
|
131
|
-
// 1. 确定扩散的圆心位置
|
|
132
|
-
const width = window.innerWidth;
|
|
133
|
-
const height = window.innerHeight;
|
|
134
|
-
|
|
135
|
-
// 始终以点击位置为圆心
|
|
136
|
-
const centerX = x;
|
|
137
|
-
const centerY = y;
|
|
138
|
-
|
|
139
|
-
// 2. 计算最大半径,确保圆能覆盖全屏
|
|
140
|
-
const radius = Math.hypot(
|
|
141
|
-
Math.max(centerX, width - centerX),
|
|
142
|
-
Math.max(centerY, height - centerY)
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
// 判断是否是切换到暗色模式(变暗)
|
|
146
|
-
const realTheme = getRealTheme(theme);
|
|
147
|
-
const isDark = realTheme === 'dark';
|
|
148
|
-
|
|
149
|
-
// 3. 注入样式
|
|
150
|
-
// 禁用默认动画
|
|
151
|
-
// 根据是变亮还是变暗,调整层级顺序
|
|
152
|
-
// 变亮(Light): New(Light) 在上,Old(Dark) 在下。New 从 0 变大。 (默认层级 New 在上,无需调整)
|
|
153
|
-
// 变暗(Dark): Old(Light) 在上,New(Dark) 在下。Old 从大变 0。 (需要调整层级 Old 在上)
|
|
154
|
-
const style = document.createElement('style');
|
|
155
|
-
style.innerHTML = `
|
|
156
|
-
::view-transition-old(root),
|
|
157
|
-
::view-transition-new(root) {
|
|
158
|
-
animation: none;
|
|
159
|
-
mix-blend-mode: normal;
|
|
160
|
-
display: block;
|
|
161
|
-
}
|
|
162
|
-
${isDark ? `
|
|
163
|
-
::view-transition-old(root) { z-index: 9999; }
|
|
164
|
-
::view-transition-new(root) { z-index: 1; }
|
|
165
|
-
` : ''}
|
|
166
|
-
`;
|
|
167
|
-
document.head.appendChild(style);
|
|
168
|
-
|
|
169
|
-
// 4. 开始 View Transition
|
|
170
|
-
const transition = (document as any).startViewTransition(() => {
|
|
171
|
-
applyTheme(theme);
|
|
172
|
-
resolve();
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// 5. 自定义动画
|
|
176
|
-
transition.ready.then(() => {
|
|
177
|
-
const clipPath = [
|
|
178
|
-
`circle(0px at ${centerX}px ${centerY}px)`,
|
|
179
|
-
`circle(${radius}px at ${centerX}px ${centerY}px)`
|
|
180
|
-
];
|
|
181
|
-
|
|
182
|
-
// 关键修复:添加 fill: 'forwards' 确保动画结束后保持状态,防止闪烁
|
|
183
|
-
const animationOptions: KeyframeAnimationOptions = {
|
|
184
|
-
duration: 500,
|
|
185
|
-
easing: 'ease-in-out',
|
|
186
|
-
fill: 'forwards'
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
if(isDark) {
|
|
190
|
-
// 变暗:Old(Light) 收缩
|
|
191
|
-
document.documentElement.animate(
|
|
192
|
-
{
|
|
193
|
-
clipPath: [...clipPath].reverse()
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
...animationOptions,
|
|
197
|
-
pseudoElement: '::view-transition-old(root)'
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
} else {
|
|
201
|
-
// 变亮:New(Light) 扩散
|
|
202
|
-
document.documentElement.animate(
|
|
203
|
-
{
|
|
204
|
-
clipPath: clipPath
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
...animationOptions,
|
|
208
|
-
pseudoElement: '::view-transition-new(root)'
|
|
209
|
-
}
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// 6. 动画结束,清理样式
|
|
215
|
-
transition.finished.then(() => {
|
|
216
|
-
document.head.removeChild(style);
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"allowSyntheticDefaultImports": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "node",
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
"jsx": "react-jsx",
|
|
16
|
-
|
|
17
|
-
/* Linting */
|
|
18
|
-
"strict": true,
|
|
19
|
-
"noUnusedLocals": false,
|
|
20
|
-
"noUnusedParameters": true,
|
|
21
|
-
"noFallthroughCasesInSwitch": true,
|
|
22
|
-
"paths": {
|
|
23
|
-
"@/*": ["./src/*"]
|
|
24
|
-
},
|
|
25
|
-
"allowImportingTsExtensions": true
|
|
26
|
-
},
|
|
27
|
-
"include": ["src"]
|
|
28
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author: dushuai
|
|
3
|
-
* @Date: 2025-04-28 00:00:05
|
|
4
|
-
* @LastEditors: dushuai
|
|
5
|
-
* @LastEditTime: 2026-02-01 02:07:30
|
|
6
|
-
* @description: vite.config
|
|
7
|
-
*/
|
|
8
|
-
import tailwindcss from '@tailwindcss/vite';
|
|
9
|
-
import react from '@vitejs/plugin-react-swc';
|
|
10
|
-
import { resolve } from 'path';
|
|
11
|
-
import clear from 'rollup-plugin-clear';
|
|
12
|
-
import { defineConfig } from 'vite';
|
|
13
|
-
import dts from 'vite-plugin-dts';
|
|
14
|
-
|
|
15
|
-
export default defineConfig({
|
|
16
|
-
plugins: [
|
|
17
|
-
clear({ targets: ['dist', 'bin', 'lib', 'es'], watch: true }),
|
|
18
|
-
dts({
|
|
19
|
-
entryRoot: resolve(__dirname, 'src'),
|
|
20
|
-
outDir: resolve(__dirname, 'lib/types')
|
|
21
|
-
}),
|
|
22
|
-
react(),
|
|
23
|
-
tailwindcss()
|
|
24
|
-
],
|
|
25
|
-
resolve: {
|
|
26
|
-
alias: {
|
|
27
|
-
'@': resolve(__dirname, './src')
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
build: {
|
|
31
|
-
outDir: 'lib',
|
|
32
|
-
sourcemap: false,
|
|
33
|
-
lib: {
|
|
34
|
-
entry: 'src/index.ts',
|
|
35
|
-
name: '@spacego/fe-components',
|
|
36
|
-
fileName: 'index'
|
|
37
|
-
},
|
|
38
|
-
rollupOptions: {
|
|
39
|
-
external: [
|
|
40
|
-
'react',
|
|
41
|
-
'react-dom',
|
|
42
|
-
'react/jsx-runtime',
|
|
43
|
-
'react-router-dom',
|
|
44
|
-
'antd',
|
|
45
|
-
'axios',
|
|
46
|
-
'nprogress',
|
|
47
|
-
'react-icons',
|
|
48
|
-
'react-icons/fa6',
|
|
49
|
-
'react-icons/io5',
|
|
50
|
-
'react-icons/lu',
|
|
51
|
-
'react-icons/md',
|
|
52
|
-
'sass',
|
|
53
|
-
'zustand',
|
|
54
|
-
'zustand/middleware',
|
|
55
|
-
'tailwindcss',
|
|
56
|
-
'@ant-design/icons',
|
|
57
|
-
'@types/react',
|
|
58
|
-
'@spacego/turbo-utils',
|
|
59
|
-
'@spacego/hooks',
|
|
60
|
-
'@spacego/zustand'
|
|
61
|
-
],
|
|
62
|
-
output: [
|
|
63
|
-
// 1. ESM 配置 (给 Vite/Webpack/现代浏览器)
|
|
64
|
-
{
|
|
65
|
-
format: 'es',
|
|
66
|
-
dir: resolve(__dirname, 'lib'),
|
|
67
|
-
preserveModules: true, // 保留目录结构,利于 Tree Shaking
|
|
68
|
-
preserveModulesRoot: 'src',
|
|
69
|
-
entryFileNames: '[name].js',
|
|
70
|
-
chunkFileNames: '[name].js'
|
|
71
|
-
}
|
|
72
|
-
// 2. CJS 配置 (给 Node.js/旧工具)
|
|
73
|
-
// {
|
|
74
|
-
// format: 'cjs',
|
|
75
|
-
// dir: resolve(__dirname, 'lib/cjs'),
|
|
76
|
-
// preserveModules: true, // 同样保留结构,方便 Node.js 深层 require
|
|
77
|
-
// preserveModulesRoot: 'src',
|
|
78
|
-
// entryFileNames: '[name].cjs',
|
|
79
|
-
// chunkFileNames: '[name].cjs',
|
|
80
|
-
// exports: 'named' // 推荐:使用命名导出
|
|
81
|
-
// }
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
});
|