- Fix negative margin overflow in all dialog content areas - Standardize dialog structure with flex-col layout - Add consistent py-4 spacing to all content areas - Ensure proper spacing between header, content, and footer Affected components: - AddProviderDialog, EditProviderDialog - McpFormModal, McpPanel - UsageScriptModal - SettingsDialog All dialogs now follow unified layout pattern: - DialogContent: flex flex-col max-h-[90vh] - Content area: flex-1 overflow-y-auto px-6 py-4 - No negative margins that cause content overflow
79 lines
2.1 KiB
TypeScript
79 lines
2.1 KiB
TypeScript
import { Monitor, Moon, Sun } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useTheme } from "@/components/theme-provider";
|
|
|
|
export function ThemeSettings() {
|
|
const { t } = useTranslation();
|
|
const { theme, setTheme } = useTheme();
|
|
|
|
return (
|
|
<section className="space-y-2">
|
|
<header className="space-y-1">
|
|
<h3 className="text-sm font-medium">{t("settings.theme")}</h3>
|
|
<p className="text-xs text-muted-foreground">
|
|
{t("settings.themeHint", {
|
|
defaultValue: "选择应用的外观主题,立即生效。",
|
|
})}
|
|
</p>
|
|
</header>
|
|
<div className="inline-flex gap-1 rounded-md border border-border bg-background p-1">
|
|
<ThemeButton
|
|
active={theme === "light"}
|
|
onClick={() => setTheme("light")}
|
|
icon={Sun}
|
|
>
|
|
{t("settings.themeLight", { defaultValue: "浅色" })}
|
|
</ThemeButton>
|
|
<ThemeButton
|
|
active={theme === "dark"}
|
|
onClick={() => setTheme("dark")}
|
|
icon={Moon}
|
|
>
|
|
{t("settings.themeDark", { defaultValue: "深色" })}
|
|
</ThemeButton>
|
|
<ThemeButton
|
|
active={theme === "system"}
|
|
onClick={() => setTheme("system")}
|
|
icon={Monitor}
|
|
>
|
|
{t("settings.themeSystem", { defaultValue: "跟随系统" })}
|
|
</ThemeButton>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
interface ThemeButtonProps {
|
|
active: boolean;
|
|
onClick: () => void;
|
|
icon: React.ComponentType<{ className?: string }>;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
function ThemeButton({
|
|
active,
|
|
onClick,
|
|
icon: Icon,
|
|
children,
|
|
}: ThemeButtonProps) {
|
|
return (
|
|
<Button
|
|
type="button"
|
|
onClick={onClick}
|
|
size="sm"
|
|
variant={active ? "default" : "ghost"}
|
|
className={cn(
|
|
"min-w-[96px] gap-1.5",
|
|
active
|
|
? "shadow-sm"
|
|
: "text-muted-foreground hover:text-foreground hover:bg-muted",
|
|
)}
|
|
>
|
|
<Icon className="h-3.5 w-3.5" />
|
|
{children}
|
|
</Button>
|
|
);
|
|
}
|