@chatui/core
Version:
The React library for Chatbot UI
70 lines (64 loc) • 2.76 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useColorScheme = useColorScheme;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = require("react");
var _useIsomorphicLayoutEffect = require("./useIsomorphicLayoutEffect");
var MEDIA_QUERY = '(prefers-color-scheme: dark)';
var getSystemColorScheme = function getSystemColorScheme() {
return window.matchMedia(MEDIA_QUERY).matches ? 'dark' : 'light';
};
var resolveColorScheme = function resolveColorScheme(colorScheme) {
return colorScheme === 'auto' ? getSystemColorScheme() : colorScheme;
};
/**
* 处理颜色主题的 Hook
*
* 特性:
* - 支持 'light' | 'dark' | 'auto' 三种模式
* - 自动监听系统主题变化(auto 模式)
* - 同步更新 document.documentElement.dataset.colorScheme
* - 支持 SSR,服务端默认返回 'light'
* - 使用 useLayoutEffect 确保主题在绘制前应用,避免闪烁
*
* @param colorScheme - 主题模式,默认为 'light'
* @returns 当前实际应用的主题 'light' | 'dark'
*/
function useColorScheme() {
var colorScheme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'light';
// 根据 colorScheme 计算实际应使用的主题
var computeResolvedScheme = function computeResolvedScheme() {
return resolveColorScheme(colorScheme);
};
// 使用函数式初始值避免重复计算
var _useState = (0, _react.useState)(function () {
return typeof window !== 'undefined' ? computeResolvedScheme() : 'light';
}),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
resolvedScheme = _useState2[0],
setResolvedScheme = _useState2[1];
// 处理 colorScheme 变化(非 auto 模式或初始值)
(0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(function () {
setResolvedScheme(computeResolvedScheme());
}, [colorScheme]);
// 监听系统主题变化(仅在 auto 模式下)
(0, _react.useEffect)(function () {
if (colorScheme !== 'auto') return;
var mediaQuery = window.matchMedia(MEDIA_QUERY);
var handleChange = function handleChange(event) {
setResolvedScheme(event.matches ? 'dark' : 'light');
};
mediaQuery.addEventListener('change', handleChange);
return function () {
return mediaQuery.removeEventListener('change', handleChange);
};
}, [colorScheme]);
// 同步到 DOM(使用 layout effect 避免闪烁)
(0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(function () {
document.documentElement.dataset.colorScheme = resolvedScheme;
}, [resolvedScheme]);
return resolvedScheme;
}