@spacego/fe-components 0.0.1-alpha.1 → 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.
Files changed (56) hide show
  1. package/lib/fe-layouts/auth-layout/index.js +1 -1
  2. package/lib/fe-layouts/layout.js +8 -8
  3. package/lib/index.js +23 -21
  4. package/lib/store/modules/layout-config.store.js +1 -1
  5. package/lib/store/modules/theme.store.js +1 -1
  6. package/lib/types/index.d.ts +2 -0
  7. package/lib/types/router/index.d.ts +1 -1
  8. package/package.json +9 -1
  9. package/src/assets/styles/animate.css +0 -62
  10. package/src/assets/styles/index.css +0 -49
  11. package/src/assets/svg/chrome-bg-after.svg +0 -1
  12. package/src/assets/svg/chrome-bg-before.svg +0 -1
  13. package/src/assets/svg/icon-arrows-right.svg +0 -1
  14. package/src/assets/svg/icon-bell.svg +0 -1
  15. package/src/assets/svg/icon-custom.svg +0 -1
  16. package/src/assets/svg/icon-sun-moon.svg +0 -1
  17. package/src/assets/svg/icon-system.svg +0 -1
  18. package/src/assets/svg/loading.svg +0 -13
  19. package/src/assets/svg/login-view.svg +0 -193
  20. package/src/config/constants.ts +0 -19
  21. package/src/config/index.ts +0 -2
  22. package/src/config/theme.ts +0 -20
  23. package/src/fe-layouts/auth-layout/index.scss +0 -34
  24. package/src/fe-layouts/auth-layout/index.tsx +0 -121
  25. package/src/fe-layouts/basics-layout/components/basics-layout/header.tsx +0 -148
  26. package/src/fe-layouts/basics-layout/components/basics-layout/setting-custom-color.tsx +0 -52
  27. package/src/fe-layouts/basics-layout/components/basics-layout/setting-drawer.tsx +0 -165
  28. package/src/fe-layouts/basics-layout/components/basics-layout/sidebar.tsx +0 -88
  29. package/src/fe-layouts/basics-layout/components/basics-layout/tabs.tsx +0 -94
  30. package/src/fe-layouts/basics-layout/components/utils/index.ts +0 -142
  31. package/src/fe-layouts/basics-layout/index.scss +0 -110
  32. package/src/fe-layouts/basics-layout/index.tsx +0 -207
  33. package/src/fe-layouts/blank-layout/index.tsx +0 -12
  34. package/src/fe-layouts/context/context.ts +0 -11
  35. package/src/fe-layouts/context/global-context.d.ts +0 -241
  36. package/src/fe-layouts/context/global-context.provider.tsx +0 -81
  37. package/src/fe-layouts/context/index.ts +0 -10
  38. package/src/fe-layouts/index.ts +0 -13
  39. package/src/fe-layouts/layout.tsx +0 -74
  40. package/src/hooks/index.ts +0 -1
  41. package/src/hooks/use-auth.hook.ts +0 -54
  42. package/src/index.ts +0 -21
  43. package/src/router/index.ts +0 -110
  44. package/src/router/permission.tsx +0 -134
  45. package/src/router/routes.tsx +0 -94
  46. package/src/router/utils.ts +0 -283
  47. package/src/store/index.ts +0 -9
  48. package/src/store/modules/layout-config.store.ts +0 -343
  49. package/src/store/modules/theme.store.ts +0 -99
  50. package/src/typings/index.d.ts +0 -59
  51. package/src/typings/shims-axios.d.ts +0 -38
  52. package/src/utils/icon.tsx +0 -32
  53. package/src/utils/index.ts +0 -9
  54. package/src/utils/theme.ts +0 -219
  55. package/tsconfig.json +0 -28
  56. package/vite.config.ts +0 -85
@@ -1,343 +0,0 @@
1
- /*
2
- * @Author: dushuai
3
- * @Date: 2026-01-27
4
- * @LastEditors: dushuai
5
- * @LastEditTime: 2026-01-31 23:34:31
6
- * @description: layout config store
7
- */
8
- import type { AxiosRequestConfig } from 'axios';
9
- import { create } from 'zustand';
10
- import { combine, createJSONStorage, persist } from 'zustand/middleware';
11
-
12
- import { STORE_KEY } from '@/index';
13
- import type { TUpdateStore } from '@/typings';
14
-
15
- export interface TabItem {
16
- key: string
17
- label: string
18
- path: string
19
- closable?: boolean
20
- }
21
-
22
- type State = {
23
- /** Tabs 配置 */
24
- tabsAttribute: {
25
- /** 已打开的页面标签列表 */
26
- tabsList: TabItem[]
27
- /** 当前激活的标签页 key */
28
- tabsActiveKey: string
29
- }
30
- /** Loading 配置 */
31
- loadingConfig: {
32
- show: boolean
33
- limit: number
34
- timer: number | null
35
- }
36
- /** 侧边栏折叠状态 */
37
- sidebarCollapsed: boolean
38
- }
39
-
40
- type Update = TUpdateStore<State>;
41
-
42
- type Actions = {
43
- SET_STATE: (data: Update) => void
44
- /** 添加标签页 */
45
- ADD_TAB: (tab: TabItem) => void
46
- /** 移除标签页 */
47
- REMOVE_TAB: (key: string) => void
48
- /** 设置当前激活的标签页 */
49
- SET_ACTIVE_TAB_KEY: (key: string) => void
50
- /** 清空所有标签页 */
51
- CLEAR_TABS: () => void
52
- /** 设置loading配置 */
53
- SET_LOADING: (config?: AxiosRequestConfig) => void
54
- /** 取消loading */
55
- HIDE_LOADING: (config?: AxiosRequestConfig) => void
56
- /** 清除loading定时器 */
57
- CLEAR_LOADING_TIMER: () => void
58
- /** 设置侧边栏折叠状态 */
59
- SET_SIDEBAR_COLLAPSED: (collapsed: boolean) => void
60
- /** 切换侧边栏折叠状态 */
61
- TOGGLE_SIDEBAR_COLLAPSED: () => void
62
- /** 重置 */
63
- RESET: () => void
64
- /** 设置通知的reactNode */
65
- SET_NOTICE_RENDER: (render: React.ReactNode) => void
66
- }
67
-
68
- // 定义完整的 Store 类型
69
- type LayoutConfigStore = State & Actions;
70
-
71
- // define the initial state
72
- const initialState = (): State => ({
73
- tabsAttribute: {
74
- tabsList: [{
75
- key: 'Home',
76
- label: '首页',
77
- path: '/',
78
- closable: false // 首页标签不可关闭
79
- }],
80
- tabsActiveKey: ''
81
- },
82
- loadingConfig: {
83
- show: false,
84
- limit: 0,
85
- timer: null
86
- },
87
- sidebarCollapsed: false
88
- });
89
-
90
- /**
91
- * 当前store版本
92
- * 更改后需要手动修改并添加migrate逻辑
93
- */
94
- const APP_STORE_VERSION: number = 0.1;
95
-
96
- export const useLayoutConfigStore = create(persist(
97
- combine(
98
- initialState() as LayoutConfigStore,
99
-
100
- (set, get) => ({
101
-
102
- SET_STATE: (data: Update) => set(data),
103
-
104
- /**
105
- * 添加标签页
106
- */
107
- ADD_TAB: (tab: TabItem) => {
108
- const { tabsAttribute } = get();
109
- const { tabsList } = tabsAttribute;
110
- // 检查是否已存在
111
- const exists = tabsList.find(t => t.key === tab.key);
112
- if(!exists) {
113
- set({
114
- tabsAttribute: {
115
- ...tabsAttribute,
116
- tabsList: [...tabsList, tab],
117
- tabsActiveKey: tab.key
118
- }
119
- });
120
- } else {
121
- set({
122
- tabsAttribute: {
123
- ...tabsAttribute,
124
- tabsActiveKey: tab.key
125
- }
126
- });
127
- }
128
- },
129
-
130
- /**
131
- * 移除标签页
132
- */
133
- REMOVE_TAB: (key: string): TabItem => {
134
- const { tabsAttribute } = get();
135
- const { tabsList, tabsActiveKey } = tabsAttribute;
136
- const newTabs = tabsList.filter(t => t.key !== key);
137
-
138
- let newActiveKey = tabsActiveKey;
139
- // 如果关闭的是当前激活的标签,切换到最后一个标签
140
- if(tabsActiveKey === key && newTabs.length > 0) {
141
- newActiveKey = newTabs[newTabs.length - 1].key;
142
- } else if(newTabs.length === 0) {
143
- newActiveKey = '';
144
- }
145
-
146
- set({
147
- tabsAttribute: {
148
- tabsList: newTabs,
149
- tabsActiveKey: newActiveKey
150
- }
151
- });
152
-
153
- return tabsList.find(item => item.key === newActiveKey) ?? {} as TabItem;
154
- },
155
-
156
- /**
157
- * 设置当前激活的标签页
158
- */
159
- SET_ACTIVE_TAB_KEY: (key: string) => {
160
- const { tabsAttribute } = get();
161
- set({
162
- tabsAttribute: {
163
- ...tabsAttribute,
164
- tabsActiveKey: key
165
- }
166
- });
167
- },
168
-
169
- /**
170
- * 清空所有标签页
171
- */
172
- CLEAR_TABS: () => {
173
- set({
174
- tabsAttribute: {
175
- tabsList: [],
176
- tabsActiveKey: ''
177
- }
178
- });
179
- },
180
-
181
- /**
182
- * 设置loading配置
183
- */
184
- SET_LOADING: (config?: AxiosRequestConfig) => {
185
- if(!!config && config.showLoading === false) return;
186
- const { CLEAR_LOADING_TIMER, HIDE_LOADING } = get();
187
-
188
- set((state) => {
189
- const { loadingConfig } = state;
190
- const shouldShow = loadingConfig.show === false;
191
- const newLimit = loadingConfig.limit + 1;
192
- const newLoadingConfig = {
193
- show: shouldShow ? true : loadingConfig.show,
194
- limit: newLimit,
195
- timer: loadingConfig.timer
196
- };
197
-
198
- // 如果limit为1,需要设置定时器
199
- if(newLimit === 1) {
200
- CLEAR_LOADING_TIMER();
201
- const timer = setTimeout(() => {
202
- const currentState = get();
203
- if(currentState.loadingConfig.limit === 1 && currentState.loadingConfig.show) {
204
- HIDE_LOADING(config);
205
- }
206
- }, 20 * 1000);
207
- return {
208
- loadingConfig: {
209
- ...newLoadingConfig,
210
- timer
211
- }
212
- };
213
- } else {
214
- CLEAR_LOADING_TIMER();
215
- return {
216
- loadingConfig: newLoadingConfig
217
- };
218
- }
219
- });
220
- },
221
-
222
- /**
223
- * 取消loading
224
- */
225
- HIDE_LOADING: (config?: AxiosRequestConfig) => {
226
- if(!!config && config.showLoading === false) return;
227
- const { CLEAR_LOADING_TIMER, HIDE_LOADING } = get();
228
-
229
- set((state) => {
230
- const { loadingConfig } = state;
231
-
232
- if(loadingConfig.limit <= 0) {
233
- return state;
234
- }
235
-
236
- const newLimit = loadingConfig.limit - 1;
237
- const newLoadingConfig = {
238
- ...loadingConfig,
239
- limit: newLimit
240
- };
241
-
242
- // 如果limit变为0,需要隐藏loading
243
- if(newLimit === 0) {
244
- newLoadingConfig.show = false;
245
- // message.destroy();
246
- CLEAR_LOADING_TIMER();
247
- return {
248
- loadingConfig: {
249
- ...newLoadingConfig,
250
- timer: null
251
- }
252
- };
253
- }
254
-
255
- // 如果limit为1,需要设置定时器
256
- if(newLimit === 1) {
257
- CLEAR_LOADING_TIMER();
258
- const timer = setTimeout(() => {
259
- const currentState = get();
260
- if(currentState.loadingConfig.limit === 1 && currentState.loadingConfig.show) {
261
- HIDE_LOADING(config);
262
- }
263
- }, 20 * 1000);
264
- return {
265
- loadingConfig: {
266
- ...newLoadingConfig,
267
- timer
268
- }
269
- };
270
- }
271
-
272
- // 其他情况只更新limit
273
- return {
274
- loadingConfig: newLoadingConfig
275
- };
276
- });
277
- },
278
-
279
- /**
280
- * 清除loading定时器
281
- */
282
- CLEAR_LOADING_TIMER() {
283
- const { loadingConfig } = get();
284
- if(loadingConfig.timer) {
285
- clearTimeout(loadingConfig.timer);
286
- set({
287
- loadingConfig: {
288
- ...loadingConfig,
289
- timer: null
290
- }
291
- });
292
- }
293
- },
294
-
295
- /**
296
- * 设置侧边栏折叠状态
297
- */
298
- SET_SIDEBAR_COLLAPSED: (collapsed: boolean) => {
299
- set({ sidebarCollapsed: collapsed });
300
- },
301
-
302
- /**
303
- * 切换侧边栏折叠状态
304
- */
305
- TOGGLE_SIDEBAR_COLLAPSED: () => {
306
- const { sidebarCollapsed } = get();
307
- set({ sidebarCollapsed: !sidebarCollapsed });
308
- },
309
-
310
- /**
311
- * 重置
312
- */
313
- RESET: () => {
314
- const { sidebarCollapsed, ...rest } = initialState();
315
- set(rest);
316
- }
317
-
318
- })
319
- ),
320
- {
321
- name: STORE_KEY.LAYOUT_CONFIG, // unique name
322
- storage: createJSONStorage(() => localStorage),
323
- version: APP_STORE_VERSION, // a migration will be triggered if the version in the storage mismatches this one
324
-
325
- // 部分持久化
326
- partialize: (state) => {
327
- const { ...rest } = state;
328
- return rest;
329
- },
330
-
331
- // migration logic
332
- migrate: (persistedState, version) => {
333
-
334
- const state = initialState();
335
-
336
- if(version !== APP_STORE_VERSION) {
337
- Object.assign(state, persistedState);
338
- }
339
-
340
- return state;
341
- }
342
- }
343
- ));
@@ -1,99 +0,0 @@
1
- /*
2
- * @Author: dushuai
3
- * @Date: 2026-01-28
4
- * @LastEditors: dushuai
5
- * @LastEditTime: 2026-01-31 23:33:29
6
- * @description: 主题管理 store
7
- */
8
- import { create } from 'zustand';
9
- import { combine, createJSONStorage, devtools, persist } from 'zustand/middleware';
10
-
11
- import { applyTheme, applyThemeColor, STORE_KEY } from '@/index';
12
- import type { TUpdateStore } from '@/typings';
13
-
14
- export type ThemeMode = 'light' | 'dark' | 'system';
15
-
16
- type State = {
17
- theme: ThemeMode
18
- themeColor: string
19
- /** 是否是自定义主题色 */
20
- isCustomThemeColor: boolean
21
- }
22
-
23
- type Actions = {
24
- SET_THEME: (theme: ThemeMode) => void
25
- TOGGLE_THEME: () => void
26
- SET_THEME_COLOR: (color: string) => void
27
- SET_IS_CUSTOM_THEME_COLOR: (isCustom: boolean) => void
28
- SET_STATE: (data: { key: keyof State, val: State[keyof State] }) => void
29
- }
30
-
31
- type Update = TUpdateStore<State>;
32
-
33
- type ThemeStore = State & Actions;
34
-
35
- const initialState = (): State => ({
36
- theme: 'light',
37
- themeColor: '#006BE6', // 默认主题色
38
- isCustomThemeColor: false
39
- });
40
-
41
- const THEME_STORE_VERSION: number = 0.1;
42
-
43
- export const useThemeStore = create((devtools(
44
- persist(
45
- combine(
46
- initialState() as ThemeStore,
47
-
48
- (set, get) => ({
49
- SET_STATE: (data: Update) => set(data),
50
-
51
- SET_THEME: (theme: ThemeMode) => {
52
- set({ theme });
53
- // 同步应用到 DOM,确保 Tailwind 和 Antd 主题一致
54
- applyTheme(theme);
55
- },
56
-
57
- TOGGLE_THEME: () => {
58
- const currentTheme = get().theme;
59
- // system 模式下 toggle 会切换到 dark 或 light? 这里简单处理为 light/dark 切换
60
- // 或者如果当前是 system,toggle 会切换到相反的非 system 模式
61
- let newTheme: ThemeMode;
62
- if(currentTheme === 'system') {
63
- // 如果是 system,获取当前系统颜色,然后取反
64
- const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
65
- newTheme = isDark ? 'light' : 'dark';
66
- } else {
67
- newTheme = currentTheme === 'light' ? 'dark' : 'light';
68
- }
69
- set({ theme: newTheme });
70
- // 同步应用到 DOM,确保 Tailwind 和 Antd 主题一致
71
- applyTheme(newTheme);
72
- },
73
-
74
- SET_THEME_COLOR: (color: string) => {
75
- set({ themeColor: color });
76
- // 同步应用到 DOM,更新 #root 内的 --color-primary CSS 变量
77
- applyThemeColor(color);
78
- },
79
-
80
- SET_IS_CUSTOM_THEME_COLOR: (isCustom: boolean) => {
81
- set({ isCustomThemeColor: isCustom });
82
- }
83
- })
84
- ),
85
- {
86
- name: STORE_KEY.THEME,
87
- storage: createJSONStorage(() => localStorage),
88
- version: THEME_STORE_VERSION,
89
- migrate: (persistedState, version) => {
90
- const state = initialState();
91
- if(version !== THEME_STORE_VERSION) {
92
- Object.assign(state, persistedState);
93
- }
94
- return state;
95
- }
96
- }
97
- ),
98
- { name: STORE_KEY.THEME, enabled: true }
99
- )));
@@ -1,59 +0,0 @@
1
- /*
2
- * @Author: dushuai
3
- * @Date: 2026-01-13 20:55:57
4
- * @LastEditors: dushuai
5
- * @LastEditTime: 2026-01-26 23:49:50
6
- * @description: 类型声明
7
- */
8
- /// <reference types="vite-plugin-svgr/client" />
9
-
10
- /**
11
- * 菜单类型枚举
12
- * @1 目录 - 仅用于菜单分组,不对应实际页面
13
- * @2 菜单 - 对应实际页面路由
14
- * @3 按钮 - 页面内的按钮权限
15
- */
16
- export type MenuType = 1 | 2 | 3;
17
-
18
- /**
19
- * 路由类型
20
- */
21
- export interface IRoute {
22
- /** 数据库主键id */
23
- id: number
24
- /** 菜单类型:1目录、2菜单、3按钮 */
25
- menuType: MenuType
26
- /** 菜单唯一标识,必填且唯一 */
27
- menuId: string
28
- /** 路由路径 */
29
- path?: string
30
- /**
31
- * 菜单标识
32
- * - 菜单类型:对应 pages 目录下文件夹名称(如 home、system/user)
33
- * - 按钮类型:权限标识(如 user:add、user:edit)
34
- */
35
- menuCode?: string
36
- /** 父级菜单的menuId */
37
- parentId?: string
38
- /** 是否受保护,默认true */
39
- protected?: boolean
40
- /** 是否是首页(仅菜单类型有效) */
41
- index?: boolean
42
- /** 路由/菜单标题 */
43
- title?: string
44
- /** 路由/菜单图标 */
45
- icon?: string
46
- /** 排序,数字越小越靠前 */
47
- sort?: number
48
- /** 是否在侧边栏菜单中显示,默认true(详情页等不需要显示在菜单中的页面设为false) */
49
- isShowMenu?: boolean
50
- /** 是否独立菜单 */
51
- isIndependentMenu?: boolean
52
- /** 激活路由的menuId */
53
- activeRouteMenuId?: string
54
- }
55
-
56
- /**
57
- * 更新store
58
- */
59
- export type TUpdateStore<T> = T | Partial<T> | ((state: T) => T | Partial<T>);
@@ -1,38 +0,0 @@
1
- /*
2
- * @Author: dushuai
3
- * @Date: 2025-12-07 16:31:57
4
- * @LastEditors: dushuai
5
- * @LastEditTime: 2026-01-13 22:14:53
6
- * @description: 请求config配置
7
- */
8
- declare module 'axios' {
9
- export interface AxiosRequestConfig {
10
- /**
11
- * @name 是否单独处理请求数据,true:返回结构为Response类型(且不处理错误码),false:返回结构为data类型,默认false
12
- */
13
- isCheck?: boolean;
14
- /**
15
- * @name 是否加载loading
16
- * @default true
17
- */
18
- showLoading?: boolean;
19
- /**
20
- * @name 加载loading的文本,最多七个字
21
- */
22
- loadingText?: string;
23
- }
24
- }
25
-
26
- export interface IResponse<T = unknown> {
27
- code: number;
28
- data: T;
29
- msg: string;
30
- }
31
-
32
- export interface IRecord<T = unknown> {
33
- pageNum: number;
34
- pageSize: number;
35
- records: T[];
36
- total: number;
37
- totalPage?: number;
38
- }
@@ -1,32 +0,0 @@
1
- /*
2
- * @Author: dushuai
3
- * @Date: 2026-01-27
4
- * @LastEditors: dushuai
5
- * @LastEditTime: 2026-01-27
6
- * @description: 图标工具函数
7
- */
8
- import * as Icons from '@ant-design/icons';
9
- import type { ComponentType } from 'react';
10
-
11
- /**
12
- * 根据图标名称获取图标组件
13
- * @param iconName 图标名称,如 'HomeOutlined'
14
- * @returns 图标组件
15
- */
16
- export function getIcon(iconName?: string): ComponentType<any> | null {
17
- if(!iconName) return null;
18
-
19
- const IconComponent = (Icons as unknown as Record<string, ComponentType<any>>)[iconName];
20
- return IconComponent || null;
21
- }
22
-
23
- /**
24
- * 渲染图标
25
- * @param iconName 图标名称
26
- * @param props 图标属性
27
- * @returns JSX元素
28
- */
29
- export function renderIcon(iconName?: string, props?: any) {
30
- const IconComponent = getIcon(iconName);
31
- return IconComponent ? <IconComponent {...props} /> : null;
32
- }
@@ -1,9 +0,0 @@
1
- /*
2
- * @Author: dushuai
3
- * @Date: 2026-01-31 23:25:51
4
- * @LastEditors: dushuai
5
- * @LastEditTime: 2026-02-01 01:48:55
6
- * @description: utils
7
- */
8
- export * from './icon';
9
- export * from './theme';