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);
}
})();
import { LocalStorage, Hash, RefreshState } from "@web/state";
import "@web/state";
var top = "top";
var bottom = "bottom";
var right = "right";
@ -7176,53 +7176,41 @@ const bootstrap = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
Toast,
Tooltip
}, Symbol.toStringTag, { value: "Module" }));
const GlobalStates = { Hash, LocalStorage };
const Bootstrap = {
// 原始 Bootstrap 实例引用
...bootstrap,
/**
* 绑定暗色模式State 路径
* @param {string|Object} stateOrPath 例如 'LocalStorage.darkMode' 或某个 NewState 对象
* @param {string} [key] 如果第一个参数是对象则需要指定 key
* 绑定暗色模式
* @param {Object} state NewState 对象 ( LocalStorage)
* @param {string} key 键名 ( 'darkMode')
*/
bindDarkMode: (stateOrPath, key) => {
bindDarkMode: (state, key) => {
if (typeof document === "undefined") return;
const htmlNode = document.documentElement;
const updateTheme = (val) => {
const theme = val ? "dark" : "light";
htmlNode.setAttribute("data-bs-theme", theme);
htmlNode.setAttribute("$data-bs-theme", theme);
htmlNode.setAttribute("data-bs-theme", val ? "dark" : "light");
};
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 && key) {
state.__watch(key, updateTheme);
updateTheme(state[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);
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);
const colors = ["primary", "secondary", "success", "info", "warning", "danger", "light", "dark"];
colors.forEach((name) => {
const hex = config[name];
if (hex) {
root.style.setProperty(`--bs-${name}`, hex);
const rgb = Bootstrap._hexToRgb(hex);
if (rgb) root.style.setProperty(`--bs-${name}-rgb`, `${rgb.r}, ${rgb.g}, ${rgb.b}`);
}
});
},
_hexToRgb: (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 = {
// 原始 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 {string} [key] 如果第一个参数是对象则需要指定 key
*/
bindDarkMode: (stateOrPath, key) => {
if (typeof document === 'undefined') return
const htmlNode = document.documentElement
const updateTheme = (val) => {
const theme = val ? 'dark' : 'light'
htmlNode.setAttribute('data-bs-theme', theme)
htmlNode.setAttribute('$data-bs-theme', theme)
/**
* 动态配置主题变量
* @param {Object} config { primary: '#6366f1', ... }
*/
config: (config = {}) => {
if (typeof document === 'undefined') return
const root = document.documentElement
const colors = ['primary', 'secondary', 'success', 'info', 'warning', 'danger', 'light', 'dark']
colors.forEach(name => {
const hex = config[name]
if (hex) {
root.style.setProperty(`--bs-${name}`, hex)
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) => {
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;
Bootstrap.bindDarkMode('LocalStorage.darkMode');
Bootstrap.bindDarkMode(LocalStorage, 'darkMode');
document.getElementById('toggle-btn').onclick = () => {
LocalStorage.darkMode = !LocalStorage.darkMode;