@_tc/template-core 0.2.0-bate.3 → 0.2.0-bate.4
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/README.md +14 -2
- package/fe/frontend/apps/dash/dash.entry.js +2 -0
- package/fe/frontend/src/common/theme.d.ts +7 -0
- package/fe/frontend/src/common/theme.js +33 -0
- package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.d.ts +3 -2
- package/fe/frontend/src/components/ThemeSwitch/ThemeSwitch.js +2 -26
- package/fe/frontend/src/components/ThemeSwitch/index.d.ts +1 -0
- package/fe/frontend/src/components/ThemeSwitch/index.js +3 -2
- package/fe/frontend/src/components/index.js +2 -2
- package/fe/frontend/src/index.d.ts +2 -0
- package/fe/frontend/src/index.js +2 -2
- package/fe/packages/react/hooks/index.d.ts +9 -0
- package/fe/packages/react/hooks/index.js +8 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -176,7 +176,7 @@ http://localhost:9000/dash?projk=demo
|
|
|
176
176
|
|
|
177
177
|
## 常用公开入口
|
|
178
178
|
|
|
179
|
-
完整 exports 以发布包内 `package.json` 为准,除下表外还包含 `./fe/main`、`./fe/*`、`./fe/rc/*`、`./fe/rc/hooks
|
|
179
|
+
完整 exports 以发布包内 `package.json` 为准,除下表外还包含 `./fe/main`、`./fe/*`、`./fe/rc/*`、`./fe/rc/hooks` 等子路径。
|
|
180
180
|
|
|
181
181
|
| 入口 | 用途 |
|
|
182
182
|
| --- | --- |
|
|
@@ -184,6 +184,7 @@ http://localhost:9000/dash?projk=demo
|
|
|
184
184
|
| `@_tc/template-core/bundler` | 构建入口,提供前端资源构建 `buildFE` 和消费方 Node/backend 构建 `buildBE` |
|
|
185
185
|
| `@_tc/template-core/fe` | 前端初始化、Dash 路由扩展、请求方法、SchemaPage 事件、共享状态和内置前端组件 |
|
|
186
186
|
| `@_tc/template-core/fe/rc` | UI/SchemaForm 组件和类型 |
|
|
187
|
+
| `@_tc/template-core/fe/rc/hooks` | React hooks 汇总入口 |
|
|
187
188
|
| `@_tc/template-core/fe/tailwind_ui.css` | 前端全局样式入口,源码对应 `frontend/src/main.css` |
|
|
188
189
|
| `@_tc/template-core/model` | model 配置类型 |
|
|
189
190
|
|
|
@@ -502,7 +503,7 @@ export function Toolbar() {
|
|
|
502
503
|
}
|
|
503
504
|
```
|
|
504
505
|
|
|
505
|
-
`ThemeSwitch` 会切换 `document.documentElement` 上的 `dark` class,并同步 `color-scheme`。默认写入 localStorage,key 是 `tc_theme`。刷新页面后会优先读取本地主题;没有本地主题时,读取当前根节点是否已有 `dark` class
|
|
506
|
+
`ThemeSwitch` 会切换 `document.documentElement` 上的 `dark` class,并同步 `color-scheme`。默认写入 localStorage,key 是 `tc_theme`。刷新页面后会优先读取本地主题;没有本地主题时,读取当前根节点是否已有 `dark` class。默认 Dashboard 会在渲染前调用 `initThemeMode()`,让已保存主题尽早生效。
|
|
506
507
|
|
|
507
508
|
常用参数:
|
|
508
509
|
|
|
@@ -514,6 +515,17 @@ export function Toolbar() {
|
|
|
514
515
|
| `persist` | 是否写入 localStorage,默认 `true`。 |
|
|
515
516
|
| `storageKey` | 自定义本地存储 key,默认 `tc_theme`。 |
|
|
516
517
|
|
|
518
|
+
如需在自定义入口或组件外手动初始化/切换主题,可以从 `@_tc/template-core/fe` 导入主题工具:
|
|
519
|
+
|
|
520
|
+
```ts
|
|
521
|
+
import { applyThemeMode, getCurrentThemeMode, initThemeMode, themeSwitchStorageKey } from '@_tc/template-core/fe'
|
|
522
|
+
|
|
523
|
+
initThemeMode()
|
|
524
|
+
applyThemeMode('dark', true)
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
`@_tc/template-core/fe/rc` 和 `@_tc/template-core/fe/rc/hooks` 也会随发布包提供对应 UI 与 hooks 入口;hooks 汇总入口包含 `useBreadcrumb`、`useExecuteOnce`、`useInit`、`useLanguage`、`usePagination`、`useRefState`、`useWatch`。
|
|
528
|
+
|
|
517
529
|
### 前端请求封装详解
|
|
518
530
|
|
|
519
531
|
框架内置的请求封装基于 `@tc/common/http`,底层使用原生 `fetch` API,实现了类似 Axios 的接口和拦截器机制,提供了签名、鉴权、错误处理等能力。
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QK, leftSidebarBasePath } from "../../src/common/menu.js";
|
|
2
2
|
import Dashboard from "./Dashboard.js";
|
|
3
3
|
import { renderImportComponent } from "../../src/common/importComponent.js";
|
|
4
|
+
import { initThemeMode } from "../../src/common/theme.js";
|
|
4
5
|
import { initApp } from "../../src/main.js";
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
import extendDashRoutes from "@tc/scalability/dash/customRoutes";
|
|
@@ -54,6 +55,7 @@ initApp(({ children }) => /* @__PURE__ */ jsx("div", {
|
|
|
54
55
|
}), {
|
|
55
56
|
routes: getDefaultPageRoutes(),
|
|
56
57
|
beforeRender: async (context) => {
|
|
58
|
+
initThemeMode();
|
|
57
59
|
if (typeof initDash === "function") await initDash(context);
|
|
58
60
|
}
|
|
59
61
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type ThemeSwitchMode = 'light' | 'dark';
|
|
2
|
+
export declare const themeSwitchStorageKey = "tc_theme";
|
|
3
|
+
export declare const getStoredThemeMode: (storageKey?: string) => ThemeSwitchMode | null;
|
|
4
|
+
export declare const getCurrentThemeMode: (defaultValue?: ThemeSwitchMode, storageKey?: string) => ThemeSwitchMode;
|
|
5
|
+
export declare const persistThemeMode: (mode: ThemeSwitchMode, storageKey?: string) => void;
|
|
6
|
+
export declare const applyThemeMode: (mode?: ThemeSwitchMode, persist?: boolean, storageKey?: string) => void;
|
|
7
|
+
export declare const initThemeMode: (defaultValue?: ThemeSwitchMode, storageKey?: string) => ThemeSwitchMode;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region frontend/src/common/theme.ts
|
|
2
|
+
var themeSwitchStorageKey = "tc_theme";
|
|
3
|
+
var canUseDocument = () => typeof document !== "undefined";
|
|
4
|
+
var canUseLocalStorage = () => typeof localStorage !== "undefined";
|
|
5
|
+
var getStoredThemeMode = (storageKey = themeSwitchStorageKey) => {
|
|
6
|
+
if (!canUseLocalStorage()) return null;
|
|
7
|
+
const value = localStorage.getItem(storageKey);
|
|
8
|
+
return value === "light" || value === "dark" ? value : null;
|
|
9
|
+
};
|
|
10
|
+
var getCurrentThemeMode = (defaultValue, storageKey = themeSwitchStorageKey) => {
|
|
11
|
+
const storedMode = getStoredThemeMode(storageKey);
|
|
12
|
+
if (storedMode) return storedMode;
|
|
13
|
+
if (defaultValue) return defaultValue;
|
|
14
|
+
if (!canUseDocument()) return "light";
|
|
15
|
+
return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
16
|
+
};
|
|
17
|
+
var persistThemeMode = (mode, storageKey = themeSwitchStorageKey) => {
|
|
18
|
+
if (canUseLocalStorage()) localStorage.setItem(storageKey, mode);
|
|
19
|
+
};
|
|
20
|
+
var applyThemeMode = (mode = getCurrentThemeMode(), persist = false, storageKey = themeSwitchStorageKey) => {
|
|
21
|
+
if (!canUseDocument()) return;
|
|
22
|
+
const root = document.documentElement;
|
|
23
|
+
root.classList.toggle("dark", mode === "dark");
|
|
24
|
+
root.style.colorScheme = mode;
|
|
25
|
+
if (persist) persistThemeMode(mode, storageKey);
|
|
26
|
+
};
|
|
27
|
+
var initThemeMode = (defaultValue, storageKey = themeSwitchStorageKey) => {
|
|
28
|
+
const mode = getCurrentThemeMode(defaultValue, storageKey);
|
|
29
|
+
applyThemeMode(mode, false, storageKey);
|
|
30
|
+
return mode;
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { applyThemeMode, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ThemeSwitchMode } from "../../common/theme";
|
|
2
|
+
export { applyThemeMode, themeSwitchStorageKey } from "../../common/theme";
|
|
3
|
+
export type { ThemeSwitchMode } from "../../common/theme";
|
|
2
4
|
export interface ThemeSwitchProps {
|
|
3
5
|
value?: ThemeSwitchMode;
|
|
4
6
|
defaultValue?: ThemeSwitchMode;
|
|
@@ -9,6 +11,5 @@ export interface ThemeSwitchProps {
|
|
|
9
11
|
persist?: boolean;
|
|
10
12
|
storageKey?: string;
|
|
11
13
|
}
|
|
12
|
-
export declare const themeSwitchStorageKey = "tc_theme";
|
|
13
14
|
declare const ThemeSwitch: ({ value, defaultValue, onChange, disabled, className, showLabel, persist, storageKey, }: ThemeSwitchProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
15
|
export default ThemeSwitch;
|
|
@@ -6,35 +6,11 @@ import { cn } from "../../../../packages/react/ui/lib/utils.js";
|
|
|
6
6
|
import { Switch } from "../../../../packages/react/ui/components/Switch/Switch.js";
|
|
7
7
|
import { Tooltip } from "../../../../packages/react/ui/components/Tooltip/Tooltip.js";
|
|
8
8
|
import "../../../../packages/react/ui/index.js";
|
|
9
|
+
import { applyThemeMode, getCurrentThemeMode, persistThemeMode, themeSwitchStorageKey } from "../../common/theme.js";
|
|
9
10
|
import { useEffect, useState } from "react";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
import { Moon, Sun } from "lucide-react";
|
|
12
13
|
//#region frontend/src/components/ThemeSwitch/ThemeSwitch.tsx
|
|
13
|
-
var themeSwitchStorageKey = "tc_theme";
|
|
14
|
-
var canUseDocument = () => typeof document !== "undefined";
|
|
15
|
-
var canUseLocalStorage = () => typeof localStorage !== "undefined";
|
|
16
|
-
var getStoredThemeMode = (storageKey) => {
|
|
17
|
-
if (!canUseLocalStorage()) return null;
|
|
18
|
-
const value = localStorage.getItem(storageKey);
|
|
19
|
-
return value === "light" || value === "dark" ? value : null;
|
|
20
|
-
};
|
|
21
|
-
var getCurrentThemeMode = (defaultValue, storageKey = themeSwitchStorageKey) => {
|
|
22
|
-
const storedMode = getStoredThemeMode(storageKey);
|
|
23
|
-
if (storedMode) return storedMode;
|
|
24
|
-
if (defaultValue) return defaultValue;
|
|
25
|
-
if (!canUseDocument()) return "light";
|
|
26
|
-
return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
27
|
-
};
|
|
28
|
-
var persistThemeMode = (mode, storageKey) => {
|
|
29
|
-
if (canUseLocalStorage()) localStorage.setItem(storageKey, mode);
|
|
30
|
-
};
|
|
31
|
-
var applyThemeMode = (mode, persist, storageKey) => {
|
|
32
|
-
if (!canUseDocument()) return;
|
|
33
|
-
const root = document.documentElement;
|
|
34
|
-
root.classList.toggle("dark", mode === "dark");
|
|
35
|
-
root.style.colorScheme = mode;
|
|
36
|
-
if (persist) persistThemeMode(mode, storageKey);
|
|
37
|
-
};
|
|
38
14
|
var ThemeSwitch = ({ value, defaultValue, onChange, disabled, className, showLabel = false, persist = true, storageKey = themeSwitchStorageKey }) => {
|
|
39
15
|
useI18nStore((state) => state.language);
|
|
40
16
|
const [internalMode, setInternalMode] = useState(() => getCurrentThemeMode(defaultValue, storageKey));
|
|
@@ -84,4 +60,4 @@ var ThemeSwitch = ({ value, defaultValue, onChange, disabled, className, showLab
|
|
|
84
60
|
});
|
|
85
61
|
};
|
|
86
62
|
//#endregion
|
|
87
|
-
export { ThemeSwitch as default, themeSwitchStorageKey };
|
|
63
|
+
export { applyThemeMode, ThemeSwitch as default, themeSwitchStorageKey };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { applyThemeMode, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey } from "../../common/theme.js";
|
|
2
|
+
import ThemeSwitch from "./ThemeSwitch.js";
|
|
2
3
|
//#region frontend/src/components/ThemeSwitch/index.ts
|
|
3
4
|
var ThemeSwitch_default = ThemeSwitch;
|
|
4
5
|
//#endregion
|
|
5
|
-
export { ThemeSwitch_default as default, themeSwitchStorageKey };
|
|
6
|
+
export { applyThemeMode, ThemeSwitch_default as default, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import HeaderView from "./BasePage/HeaderView.js";
|
|
2
|
+
import { applyThemeMode, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey } from "../common/theme.js";
|
|
2
3
|
import { generateRouter } from "./Router/index.js";
|
|
3
4
|
import AsyncSelect_default from "./AsyncSelect/index.js";
|
|
4
5
|
import LanguageSwitch_default from "./LanguageSwitch/index.js";
|
|
5
|
-
import { themeSwitchStorageKey } from "./ThemeSwitch/ThemeSwitch.js";
|
|
6
6
|
import ThemeSwitch_default from "./ThemeSwitch/index.js";
|
|
7
|
-
export { AsyncSelect_default as AsyncSelect, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, generateRouter, themeSwitchStorageKey };
|
|
7
|
+
export { AsyncSelect_default as AsyncSelect, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, applyThemeMode, generateRouter, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey };
|
|
@@ -8,6 +8,8 @@ export { api, del, get, patch, post, put, request } from "./common/request";
|
|
|
8
8
|
export type { AxiosError, BaseResponse, PageParams, PageResponse, RequestConfig, ResponseConfig } from "./common/request";
|
|
9
9
|
export { clearRafTimer, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout } from "./common/rafTimer";
|
|
10
10
|
export type { RafTimerCallback, RafTimerId } from "./common/rafTimer";
|
|
11
|
+
export { applyThemeMode, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey, } from "./common/theme";
|
|
12
|
+
export type { ThemeSwitchMode } from "./common/theme";
|
|
11
13
|
export * from "./defaultPages/SchemaPage/data/eventInfo";
|
|
12
14
|
export { merge } from "./defaultPages/SchemaPage/utils/permissions";
|
|
13
15
|
export * from "./exportStore";
|
package/fe/frontend/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { FreezeState, apiFreezerStore, useApiFreezer } from "./stores/apiFreezer
|
|
|
5
5
|
import { api, del, get, patch, post, put, request } from "./common/request.js";
|
|
6
6
|
import { modeStore, useModeStore } from "./stores/mode.js";
|
|
7
7
|
import HeaderView from "./components/BasePage/HeaderView.js";
|
|
8
|
+
import { applyThemeMode, getCurrentThemeMode, getStoredThemeMode, initThemeMode, persistThemeMode, themeSwitchStorageKey } from "./common/theme.js";
|
|
8
9
|
import { generateRouter } from "./components/Router/index.js";
|
|
9
10
|
import { schemaEventBus } from "./stores/schemaEventBus.js";
|
|
10
11
|
import { schemaStore, useSchemaStore } from "./stores/schemaStore.js";
|
|
@@ -13,9 +14,8 @@ import { initApp } from "./main.js";
|
|
|
13
14
|
import { clearRafTimer, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout } from "./common/rafTimer.js";
|
|
14
15
|
import AsyncSelect_default from "./components/AsyncSelect/index.js";
|
|
15
16
|
import LanguageSwitch_default from "./components/LanguageSwitch/index.js";
|
|
16
|
-
import { themeSwitchStorageKey } from "./components/ThemeSwitch/ThemeSwitch.js";
|
|
17
17
|
import ThemeSwitch_default from "./components/ThemeSwitch/index.js";
|
|
18
18
|
import "./components/index.js";
|
|
19
19
|
import { eventsInfo } from "./defaultPages/SchemaPage/data/eventInfo.js";
|
|
20
20
|
import { merge } from "./defaultPages/SchemaPage/utils/permissions.js";
|
|
21
|
-
export { AsyncSelect_default as AsyncSelect, FreezeState, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, api, apiFreezerStore, clearRafTimer, del, eventsInfo, generateRouter, get, getAuthToken, i18n, i18nStore, initApp, localKeyMap, merge, modeStore, patch, post, put, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, request, schemaEventBus, schemaStore, setAuthToken, themeSwitchStorageKey, useApiFreezer, useModeStore, useSchemaStore };
|
|
21
|
+
export { AsyncSelect_default as AsyncSelect, FreezeState, HeaderView, LanguageSwitch_default as LanguageSwitch, ThemeSwitch_default as ThemeSwitch, api, apiFreezerStore, applyThemeMode, clearRafTimer, del, eventsInfo, generateRouter, get, getAuthToken, getCurrentThemeMode, getStoredThemeMode, i18n, i18nStore, initApp, initThemeMode, localKeyMap, merge, modeStore, patch, persistThemeMode, post, put, rafClearInterval, rafClearTimeout, rafSetInterval, rafSetTimeout, request, schemaEventBus, schemaStore, setAuthToken, themeSwitchStorageKey, useApiFreezer, useModeStore, useSchemaStore };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./useBreadcrumb";
|
|
2
|
+
export { default as useExecuteOnce } from "./useExecuteOnce";
|
|
3
|
+
export * from "./useExecuteOnce";
|
|
4
|
+
export { default as useInit } from "./useInit";
|
|
5
|
+
export * from "./useLanguage";
|
|
6
|
+
export { default as usePagination } from "./usePagination";
|
|
7
|
+
export { default as useRefState } from "./useRefState";
|
|
8
|
+
export { default as useWatch } from "./useWatch";
|
|
9
|
+
export * from "./useWatch";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useBreadcrumb } from "./useBreadcrumb.js";
|
|
2
|
+
import { useLanguage } from "./useLanguage.js";
|
|
3
|
+
import useInit from "./useInit.js";
|
|
4
|
+
import useExecuteOnce, { executionPhaseType } from "./useExecuteOnce.js";
|
|
5
|
+
import useRefState from "./useRefState.js";
|
|
6
|
+
import useWatch, { defaultCompare, identityCompare, shallowCompare } from "./useWatch.js";
|
|
7
|
+
import usePagination from "./usePagination.js";
|
|
8
|
+
export { defaultCompare, executionPhaseType, identityCompare, shallowCompare, useBreadcrumb, useExecuteOnce, useInit, useLanguage, usePagination, useRefState, useWatch };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@_tc/template-core",
|
|
3
|
-
"version": "0.2.0-bate.
|
|
3
|
+
"version": "0.2.0-bate.4",
|
|
4
4
|
"description": "A full-stack TypeScript admin framework powered by Koa, React, and Vite - monorepo root",
|
|
5
5
|
"types": "./types/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"require": "./fe/packages/react/ui/index.js",
|
|
35
35
|
"types": "./fe/packages/react/ui/index.d.ts"
|
|
36
36
|
},
|
|
37
|
-
"./fe/rc/hooks
|
|
38
|
-
"import": "./fe/packages/react/hooks
|
|
39
|
-
"require": "./fe/packages/react/hooks
|
|
40
|
-
"types": "./fe/packages/react/hooks
|
|
37
|
+
"./fe/rc/hooks": {
|
|
38
|
+
"import": "./fe/packages/react/hooks/index.js",
|
|
39
|
+
"require": "./fe/packages/react/hooks/index.js",
|
|
40
|
+
"types": "./fe/packages/react/hooks/index.d.ts"
|
|
41
41
|
},
|
|
42
42
|
"./fe/rc/*": {
|
|
43
43
|
"import": "./fe/packages/react/ui/*",
|