| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /*
- Copyright (C) 2025 QuantumNous
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
- For commercial licensing, please contact support@quantumnous.com
- */
- import React, { useMemo } from 'react';
- import { Button, Dropdown } from '@douyinfe/semi-ui';
- import { Sun, Moon, Monitor } from 'lucide-react';
- import { useActualTheme } from '../../../context/Theme';
- const ThemeToggle = ({ theme, onThemeToggle, t }) => {
- const actualTheme = useActualTheme();
- const themeOptions = useMemo(
- () => [
- {
- key: 'light',
- icon: <Sun size={18} />,
- buttonIcon: <Sun size={18} />,
- label: t('浅色模式'),
- description: t('始终使用浅色主题'),
- },
- {
- key: 'dark',
- icon: <Moon size={18} />,
- buttonIcon: <Moon size={18} />,
- label: t('深色模式'),
- description: t('始终使用深色主题'),
- },
- {
- key: 'auto',
- icon: <Monitor size={18} />,
- buttonIcon: <Monitor size={18} />,
- label: t('自动模式'),
- description: t('跟随系统主题设置'),
- },
- ],
- [t],
- );
- const getItemClassName = (isSelected) =>
- isSelected
- ? '!bg-semi-color-primary-light-default !font-semibold'
- : 'hover:!bg-semi-color-fill-1';
- const currentButtonIcon = useMemo(() => {
- const currentOption = themeOptions.find((option) => option.key === theme);
- return currentOption?.buttonIcon || themeOptions[2].buttonIcon;
- }, [theme, themeOptions]);
- return (
- <Dropdown
- position='bottomRight'
- render={
- <Dropdown.Menu>
- {themeOptions.map((option) => (
- <Dropdown.Item
- key={option.key}
- icon={option.icon}
- onClick={() => onThemeToggle(option.key)}
- className={getItemClassName(theme === option.key)}
- >
- <div className='flex flex-col'>
- <span>{option.label}</span>
- <span className='text-xs text-semi-color-text-2'>
- {option.description}
- </span>
- </div>
- </Dropdown.Item>
- ))}
- {theme === 'auto' && (
- <>
- <Dropdown.Divider />
- <div className='px-3 py-2 text-xs text-semi-color-text-2'>
- {t('当前跟随系统')}:
- {actualTheme === 'dark' ? t('深色') : t('浅色')}
- </div>
- </>
- )}
- </Dropdown.Menu>
- }
- >
- <Button
- icon={currentButtonIcon}
- aria-label={t('切换主题')}
- theme='borderless'
- type='tertiary'
- className='!p-1.5 !text-current focus:!bg-semi-color-fill-1 !rounded-full !bg-semi-color-fill-0 hover:!bg-semi-color-fill-1'
- />
- </Dropdown>
- );
- };
- export default ThemeToggle;
|