@chatui/core
Version:
The React library for Chatbot UI
63 lines (58 loc) • 2.45 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import { useEffect, useState } from 'react';
import { useIsomorphicLayoutEffect } from './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'
*/
export function useColorScheme() {
var colorScheme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'light';
// 根据 colorScheme 计算实际应使用的主题
var computeResolvedScheme = function computeResolvedScheme() {
return resolveColorScheme(colorScheme);
};
// 使用函数式初始值避免重复计算
var _useState = useState(function () {
return typeof window !== 'undefined' ? computeResolvedScheme() : 'light';
}),
_useState2 = _slicedToArray(_useState, 2),
resolvedScheme = _useState2[0],
setResolvedScheme = _useState2[1];
// 处理 colorScheme 变化(非 auto 模式或初始值)
useIsomorphicLayoutEffect(function () {
setResolvedScheme(computeResolvedScheme());
}, [colorScheme]);
// 监听系统主题变化(仅在 auto 模式下)
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 避免闪烁)
useIsomorphicLayoutEffect(function () {
document.documentElement.dataset.colorScheme = resolvedScheme;
}, [resolvedScheme]);
return resolvedScheme;
}