UNPKG

@chatui/core

Version:

The React library for Chatbot UI

70 lines (64 loc) 2.76 kB
"use strict"; 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; }