fix: 优化 bindDarkMode 逻辑并补全色彩变量 (by AI)

This commit is contained in:
AI Engineer 2026-05-30 09:41:48 +08:00
parent 68e19335b7
commit 217b38849f
4 changed files with 55 additions and 89 deletions

50
dist/bootstrap.js vendored
View File

@ -2120,7 +2120,7 @@ url("data:font/woff;base64,d09GRgABAAAAAsBAAAsAAAAHavgAAQAAAAAAAAAAAAAAAAAAAAAAA
console.error("vite-plugin-css-injected-by-js", e); console.error("vite-plugin-css-injected-by-js", e);
} }
})(); })();
import { LocalStorage, Hash, RefreshState } from "@web/state"; import "@web/state";
var top = "top"; var top = "top";
var bottom = "bottom"; var bottom = "bottom";
var right = "right"; var right = "right";
@ -7176,53 +7176,41 @@ const bootstrap = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
Toast, Toast,
Tooltip Tooltip
}, Symbol.toStringTag, { value: "Module" })); }, Symbol.toStringTag, { value: "Module" }));
const GlobalStates = { Hash, LocalStorage };
const Bootstrap = { const Bootstrap = {
// 原始 Bootstrap 实例引用 // 原始 Bootstrap 实例引用
...bootstrap, ...bootstrap,
/** /**
* 绑定暗色模式State 路径 * 绑定暗色模式
* @param {string|Object} stateOrPath 例如 'LocalStorage.darkMode' 或某个 NewState 对象 * @param {Object} state NewState 对象 ( LocalStorage)
* @param {string} [key] 如果第一个参数是对象则需要指定 key * @param {string} key 键名 ( 'darkMode')
*/ */
bindDarkMode: (stateOrPath, key) => { bindDarkMode: (state, key) => {
if (typeof document === "undefined") return; if (typeof document === "undefined") return;
const htmlNode = document.documentElement; const htmlNode = document.documentElement;
const updateTheme = (val) => { const updateTheme = (val) => {
const theme = val ? "dark" : "light"; htmlNode.setAttribute("data-bs-theme", val ? "dark" : "light");
htmlNode.setAttribute("data-bs-theme", theme);
htmlNode.setAttribute("$data-bs-theme", theme);
}; };
let state, finalKey; if (state && key) {
if (typeof stateOrPath === "string") { state.__watch(key, updateTheme);
const parts = stateOrPath.split("."); updateTheme(state[key]);
state = GlobalStates[parts[0]];
finalKey = parts[1];
} else {
state = stateOrPath;
finalKey = key;
} }
if (!state || !finalKey) return console.warn("Bootstrap.bindDarkMode: Invalid state or key");
state.__watch(finalKey, (val) => {
updateTheme(val);
RefreshState(htmlNode);
});
updateTheme(state[finalKey]);
}, },
/** /**
* 动态配置主题 * 动态配置主题变量
* @param {Object} config { primary: '#6366f1', ... } * @param {Object} config { primary: '#6366f1', ... }
*/ */
config: (config = {}) => { config: (config = {}) => {
if (typeof document === "undefined") return; if (typeof document === "undefined") return;
const root = document.documentElement; const root = document.documentElement;
if (config.primary) { const colors = ["primary", "secondary", "success", "info", "warning", "danger", "light", "dark"];
root.style.setProperty("--bs-primary", config.primary); colors.forEach((name) => {
const rgb = Bootstrap._hexToRgb(config.primary); const hex = config[name];
if (rgb) root.style.setProperty("--bs-primary-rgb", `${rgb.r}, ${rgb.g}, ${rgb.b}`); if (hex) {
} root.style.setProperty(`--bs-${name}`, hex);
if (config.success) root.style.setProperty("--bs-success", config.success); const rgb = Bootstrap._hexToRgb(hex);
if (config.danger) root.style.setProperty("--bs-danger", config.danger); if (rgb) root.style.setProperty(`--bs-${name}-rgb`, `${rgb.r}, ${rgb.g}, ${rgb.b}`);
}
});
}, },
_hexToRgb: (hex) => { _hexToRgb: (hex) => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);

File diff suppressed because one or more lines are too long

View File

@ -13,63 +13,41 @@ const GlobalStates = { Hash, LocalStorage }
const Bootstrap = { const Bootstrap = {
// 原始 Bootstrap 实例引用 // 原始 Bootstrap 实例引用
...bootstrap, ...bootstrap,
/**
* 绑定暗色模式
* @param {Object} state NewState 对象 ( LocalStorage)
* @param {string} key 键名 ( 'darkMode')
*/
bindDarkMode: (state, key) => {
if (typeof document === 'undefined') return
const htmlNode = document.documentElement
const updateTheme = (val) => {
htmlNode.setAttribute('data-bs-theme', val ? 'dark' : 'light')
}
if (state && key) {
state.__watch(key, updateTheme)
updateTheme(state[key])
}
},
/** /**
* 绑定暗色模式到 State 路径 * 动态配置主题变量
* @param {string|Object} stateOrPath 例如 'LocalStorage.darkMode' 或某个 NewState 对象 * @param {Object} config { primary: '#6366f1', ... }
* @param {string} [key] 如果第一个参数是对象则需要指定 key */
*/ config: (config = {}) => {
bindDarkMode: (stateOrPath, key) => { if (typeof document === 'undefined') return
if (typeof document === 'undefined') return const root = document.documentElement
const colors = ['primary', 'secondary', 'success', 'info', 'warning', 'danger', 'light', 'dark']
const htmlNode = document.documentElement colors.forEach(name => {
const updateTheme = (val) => { const hex = config[name]
const theme = val ? 'dark' : 'light' if (hex) {
htmlNode.setAttribute('data-bs-theme', theme) root.style.setProperty(`--bs-${name}`, hex)
htmlNode.setAttribute('$data-bs-theme', theme) const rgb = Bootstrap._hexToRgb(hex)
if (rgb) root.style.setProperty(`--bs-${name}-rgb`, `${rgb.r}, ${rgb.g}, ${rgb.b}`)
} }
})
let state, finalKey; },
if (typeof stateOrPath === 'string') {
const parts = stateOrPath.split('.')
state = GlobalStates[parts[0]]
finalKey = parts[1]
} else {
state = stateOrPath
finalKey = key
}
if (!state || !finalKey) return console.warn('Bootstrap.bindDarkMode: Invalid state or key')
// 监听状态变化
state.__watch(finalKey, (val) => {
updateTheme(val)
RefreshState(htmlNode)
})
// 初始值同步
updateTheme(state[finalKey])
},
/**
* 动态配置主题
* @param {Object} config { primary: '#6366f1', ... }
*/
config: (config = {}) => {
if (typeof document === 'undefined') return
const root = document.documentElement
if (config.primary) {
root.style.setProperty('--bs-primary', config.primary)
// 简单计算 RGB 供一些需要透明度的组件使用
const rgb = Bootstrap._hexToRgb(config.primary)
if (rgb) root.style.setProperty('--bs-primary-rgb', `${rgb.r}, ${rgb.g}, ${rgb.b}`)
}
if (config.success) root.style.setProperty('--bs-success', config.success)
if (config.danger) root.style.setProperty('--bs-danger', config.danger)
// ... 其他颜色变量
},
_hexToRgb: (hex) => { _hexToRgb: (hex) => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)

View File

@ -27,7 +27,7 @@
// 初始化 // 初始化
LocalStorage.darkMode = false; LocalStorage.darkMode = false;
Bootstrap.bindDarkMode('LocalStorage.darkMode'); Bootstrap.bindDarkMode(LocalStorage, 'darkMode');
document.getElementById('toggle-btn').onclick = () => { document.getElementById('toggle-btn').onclick = () => {
LocalStorage.darkMode = !LocalStorage.darkMode; LocalStorage.darkMode = !LocalStorage.darkMode;