refactor(settings): reuse DarkModeToggle for app and editor theme

This commit is contained in:
Haileyesus
2026-02-20 09:18:16 +03:00
parent 40c20c9215
commit e47b2702fe
2 changed files with 42 additions and 19 deletions

View File

@@ -1,24 +1,41 @@
import { Moon, Sun } from 'lucide-react';
import { useTheme } from '../contexts/ThemeContext';
function DarkModeToggle() {
type DarkModeToggleProps = {
checked?: boolean;
onToggle?: (nextValue: boolean) => void;
ariaLabel?: string;
};
function DarkModeToggle({ checked, onToggle, ariaLabel = 'Toggle dark mode' }: DarkModeToggleProps) {
const { isDarkMode, toggleDarkMode } = useTheme();
const isControlled = typeof checked === 'boolean' && typeof onToggle === 'function';
const isEnabled = isControlled ? checked : isDarkMode;
const handleToggle = () => {
if (isControlled) {
onToggle(!isEnabled);
return;
}
toggleDarkMode();
};
return (
<button
onClick={toggleDarkMode}
onClick={handleToggle}
className="relative inline-flex h-8 w-14 items-center rounded-full bg-gray-200 dark:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900"
role="switch"
aria-checked={isDarkMode}
aria-label="Toggle dark mode"
aria-checked={isEnabled}
aria-label={ariaLabel}
>
<span className="sr-only">Toggle dark mode</span>
<span className="sr-only">{ariaLabel}</span>
<span
className={`${
isDarkMode ? 'translate-x-7' : 'translate-x-1'
isEnabled ? 'translate-x-7' : 'translate-x-1'
} h-6 w-6 transform rounded-full bg-white shadow-lg transition-transform duration-200 flex items-center justify-center`}
>
{isDarkMode ? (
{isEnabled ? (
<Moon className="h-3.5 w-3.5 text-gray-700" />
) : (
<Sun className="h-3.5 w-3.5 text-yellow-500" />
@@ -28,4 +45,4 @@ function DarkModeToggle() {
);
}
export default DarkModeToggle;
export default DarkModeToggle;

View File

@@ -1,4 +1,3 @@
import { Moon, Sun } from 'lucide-react';
import type { ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import DarkModeToggle from '../../../DarkModeToggle';
@@ -73,6 +72,7 @@ export default function AppearanceSettingsTab({
onCodeEditorFontSizeChange,
}: AppearanceSettingsTabProps) {
const { t } = useTranslation('settings');
const codeEditorThemeLabel = t('appearanceSettings.codeEditor.theme.label');
return (
<div className="space-y-6 md:space-y-8">
@@ -85,7 +85,7 @@ export default function AppearanceSettingsTab({
{t('appearanceSettings.darkMode.description')}
</div>
</div>
<DarkModeToggle />
<DarkModeToggle ariaLabel={t('appearanceSettings.darkMode.label')} />
</div>
</div>
</div>
@@ -120,15 +120,21 @@ export default function AppearanceSettingsTab({
<div className="space-y-4">
<h3 className="text-lg font-semibold text-foreground">{t('appearanceSettings.codeEditor.title')}</h3>
<ToggleCard
label={t('appearanceSettings.codeEditor.theme.label')}
description={t('appearanceSettings.codeEditor.theme.description')}
checked={codeEditorSettings.theme === 'dark'}
onChange={(enabled) => onCodeEditorThemeChange(enabled ? 'dark' : 'light')}
onIcon={<Moon className="w-3.5 h-3.5 text-gray-700" />}
offIcon={<Sun className="w-3.5 h-3.5 text-yellow-500" />}
ariaLabel={t('appearanceSettings.codeEditor.theme.label')}
/>
<div className="bg-gray-50 dark:bg-gray-900/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-foreground">{codeEditorThemeLabel}</div>
<div className="text-sm text-muted-foreground">
{t('appearanceSettings.codeEditor.theme.description')}
</div>
</div>
<DarkModeToggle
checked={codeEditorSettings.theme === 'dark'}
onToggle={(enabled) => onCodeEditorThemeChange(enabled ? 'dark' : 'light')}
ariaLabel={codeEditorThemeLabel}
/>
</div>
</div>
<ToggleCard
label={t('appearanceSettings.codeEditor.wordWrap.label')}