mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
🔧 fix(ThemeContext): Listen for Theme Changes (#2037)
* fix(ThemeContext): listen for changes * fix(Dropdown): theme auto-update not working
This commit is contained in:
parent
db870e55c3
commit
6fcaeaafe2
2 changed files with 17 additions and 22 deletions
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { FC, useContext, useState } from 'react';
|
import React, { FC, useContext, useState } from 'react';
|
||||||
import { Listbox } from '@headlessui/react';
|
import { Listbox } from '@headlessui/react';
|
||||||
import { cn } from '~/utils/';
|
import { cn } from '~/utils/';
|
||||||
import { ThemeContext } from '~/hooks';
|
|
||||||
|
|
||||||
type OptionType = {
|
type OptionType = {
|
||||||
value: string;
|
value: string;
|
||||||
|
|
@ -27,23 +26,8 @@ const Dropdown: FC<DropdownProps> = ({
|
||||||
width,
|
width,
|
||||||
testId = 'dropdown-menu',
|
testId = 'dropdown-menu',
|
||||||
}) => {
|
}) => {
|
||||||
const { theme } = useContext(ThemeContext);
|
|
||||||
const [selectedValue, setSelectedValue] = useState(initialValue);
|
const [selectedValue, setSelectedValue] = useState(initialValue);
|
||||||
|
|
||||||
const themeStyles = {
|
|
||||||
light: 'bg-white text-gray-700 hover:bg-gray-50 border-gray-300',
|
|
||||||
dark: 'bg-gray-800 text-white hover:bg-gray-700 border-gray-600',
|
|
||||||
};
|
|
||||||
|
|
||||||
const isSystemDark =
|
|
||||||
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
||||||
const currentThemeStyle =
|
|
||||||
theme === 'system'
|
|
||||||
? isSystemDark
|
|
||||||
? themeStyles.dark
|
|
||||||
: themeStyles.light
|
|
||||||
: themeStyles[theme] || themeStyles.light;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('relative', className)}>
|
<div className={cn('relative', className)}>
|
||||||
<Listbox
|
<Listbox
|
||||||
|
|
@ -57,8 +41,8 @@ const Dropdown: FC<DropdownProps> = ({
|
||||||
<Listbox.Button
|
<Listbox.Button
|
||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
className={cn(
|
className={cn(
|
||||||
'relative inline-flex items-center justify-between rounded-md py-2 pl-3 pr-10',
|
'relative inline-flex items-center justify-between rounded-md border-gray-300 bg-white py-2 pl-3 pr-10 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700',
|
||||||
currentThemeStyle,
|
|
||||||
'w-auto',
|
'w-auto',
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
|
@ -88,8 +72,7 @@ const Dropdown: FC<DropdownProps> = ({
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
<Listbox.Options
|
<Listbox.Options
|
||||||
className={cn(
|
className={cn(
|
||||||
'absolute z-50 mt-1 max-h-[40vh] overflow-auto rounded-md shadow-lg transition-opacity focus:outline-none',
|
'absolute z-50 mt-1 max-h-[40vh] overflow-auto rounded-md border-gray-300 bg-white text-gray-700 shadow-lg transition-opacity hover:bg-gray-50 focus:outline-none dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700',
|
||||||
currentThemeStyle,
|
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
style={{ width: width ? `${width}px` : 'auto' }}
|
style={{ width: width ? `${width}px` : 'auto' }}
|
||||||
|
|
@ -99,8 +82,7 @@ const Dropdown: FC<DropdownProps> = ({
|
||||||
key={index}
|
key={index}
|
||||||
value={typeof item === 'string' ? item : item.value}
|
value={typeof item === 'string' ? item : item.value}
|
||||||
className={cn(
|
className={cn(
|
||||||
'relative cursor-pointer select-none py-1 pl-3 pr-6',
|
'relative cursor-pointer select-none border-gray-300 bg-white py-1 pl-3 pr-6 text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700',
|
||||||
currentThemeStyle,
|
|
||||||
)}
|
)}
|
||||||
style={{ width: width ? `${width}px` : 'auto' }}
|
style={{ width: width ? `${width}px` : 'auto' }}
|
||||||
data-theme={typeof item === 'string' ? item : (item as OptionType).value}
|
data-theme={typeof item === 'string' ? item : (item as OptionType).value}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,19 @@ export const ThemeProvider = ({ initialTheme, children }) => {
|
||||||
localStorage.setItem('color-theme', rawTheme);
|
localStorage.setItem('color-theme', rawTheme);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
const changeThemeOnSystemChange = () => {
|
||||||
|
rawSetTheme(mediaQuery.matches ? 'dark' : 'light');
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaQuery.addEventListener('change', changeThemeOnSystemChange);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
mediaQuery.removeEventListener('change', changeThemeOnSystemChange);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (initialTheme) {
|
if (initialTheme) {
|
||||||
rawSetTheme(initialTheme);
|
rawSetTheme(initialTheme);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue