扩展氢能站点、加氢记录与台账原型链路,新增工作台、车辆资产 H5、自营物流等原型,并同步导航注册、PRD 资源与交付技能。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
122
src/common/oneos-app-shell/theme.ts
Normal file
122
src/common/oneos-app-shell/theme.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* OneOS 浅色 / 暗色主题(localStorage + 跨 iframe postMessage)
|
||||
* 暗色参照原型导航页(VoltAgent 深色画布)。
|
||||
* 不对「旧 ONEOS」目录下原型生效。
|
||||
*/
|
||||
|
||||
import './oneos-theme-content.css';
|
||||
|
||||
export type OneOsTheme = 'light' | 'dark';
|
||||
|
||||
export const ONEOS_THEME_STORAGE_KEY = 'oneos-ui-theme';
|
||||
export const ONEOS_THEME_ATTR = 'data-oneos-theme';
|
||||
export const ONEOS_THEME_MESSAGE = 'ONEOS_THEME_CHANGE';
|
||||
|
||||
/** sidebar「旧ONEOS」目录下的原型,不接入主题切换 */
|
||||
export const LEGACY_ONEOS_PROTO_IDS = new Set([
|
||||
'oneos-web-business',
|
||||
'oneos-web-data-analysis',
|
||||
'oneos-web-finance',
|
||||
'oneos-web-help-center',
|
||||
'oneos-web-lease-contract',
|
||||
'oneos-web-ledger-data',
|
||||
'oneos-web-ops',
|
||||
'oneos-web-procurement',
|
||||
]);
|
||||
|
||||
export function isLegacyOneOsPrototype(id?: string | null): boolean {
|
||||
if (!id) return false;
|
||||
return LEGACY_ONEOS_PROTO_IDS.has(id);
|
||||
}
|
||||
|
||||
export function readStoredOneOsTheme(): OneOsTheme {
|
||||
if (typeof window === 'undefined') return 'light';
|
||||
try {
|
||||
const v = window.localStorage.getItem(ONEOS_THEME_STORAGE_KEY);
|
||||
if (v === 'dark' || v === 'light') return v;
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return 'light';
|
||||
}
|
||||
|
||||
export function applyOneOsTheme(theme: OneOsTheme, root: HTMLElement = document.documentElement) {
|
||||
root.setAttribute(ONEOS_THEME_ATTR, theme);
|
||||
if (root === document.documentElement) {
|
||||
document.documentElement.style.colorScheme = theme;
|
||||
}
|
||||
}
|
||||
|
||||
export function persistOneOsTheme(theme: OneOsTheme) {
|
||||
try {
|
||||
window.localStorage.setItem(ONEOS_THEME_STORAGE_KEY, theme);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
export function broadcastOneOsTheme(theme: OneOsTheme) {
|
||||
if (typeof window === 'undefined') return;
|
||||
window.dispatchEvent(new CustomEvent(ONEOS_THEME_MESSAGE, { detail: { theme } }));
|
||||
try {
|
||||
window.parent?.postMessage({ type: ONEOS_THEME_MESSAGE, theme }, '*');
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
const frames = document.querySelectorAll('iframe');
|
||||
frames.forEach((frame) => {
|
||||
try {
|
||||
frame.contentWindow?.postMessage({ type: ONEOS_THEME_MESSAGE, theme }, '*');
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function setOneOsTheme(theme: OneOsTheme) {
|
||||
applyOneOsTheme(theme);
|
||||
persistOneOsTheme(theme);
|
||||
broadcastOneOsTheme(theme);
|
||||
}
|
||||
|
||||
export function toggleOneOsTheme(current?: OneOsTheme): OneOsTheme {
|
||||
const next: OneOsTheme = (current ?? readStoredOneOsTheme()) === 'dark' ? 'light' : 'dark';
|
||||
setOneOsTheme(next);
|
||||
return next;
|
||||
}
|
||||
|
||||
type BootstrapOptions = {
|
||||
prototypeId?: string;
|
||||
/** 强制跳过(如旧 ONEOS) */
|
||||
skip?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* 在原型预览入口调用:同步 localStorage / URL / 父页 postMessage。
|
||||
*/
|
||||
export function bootstrapOneOsTheme(options: BootstrapOptions = {}) {
|
||||
if (typeof window === 'undefined') return;
|
||||
if (options.skip || isLegacyOneOsPrototype(options.prototypeId)) return;
|
||||
|
||||
const fromQuery = new URLSearchParams(window.location.search).get('oneosTheme');
|
||||
const initial: OneOsTheme =
|
||||
fromQuery === 'dark' || fromQuery === 'light' ? fromQuery : readStoredOneOsTheme();
|
||||
|
||||
applyOneOsTheme(initial);
|
||||
persistOneOsTheme(initial);
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
const data = event.data;
|
||||
if (!data || data.type !== ONEOS_THEME_MESSAGE) return;
|
||||
if (data.theme !== 'dark' && data.theme !== 'light') return;
|
||||
applyOneOsTheme(data.theme);
|
||||
persistOneOsTheme(data.theme);
|
||||
});
|
||||
|
||||
window.addEventListener('storage', (event) => {
|
||||
if (event.key !== ONEOS_THEME_STORAGE_KEY) return;
|
||||
if (event.newValue === 'dark' || event.newValue === 'light') {
|
||||
applyOneOsTheme(event.newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user