fix(ui): use sonner toast library with product styling
Replace hand-rolled notice with sonner; single Toaster in AppLayout; token-based toast styles, top-right.
This commit is contained in:
parent
e0ecf5b106
commit
dcf66f23d0
|
|
@ -2,7 +2,6 @@
|
|||
* 鉴权页主体:薄 SSR — 外层容器 + AuthForm 在浏览器渲染。
|
||||
*/
|
||||
import type { Locale } from "@app/i18n";
|
||||
import { Toaster } from "@app/ui";
|
||||
import AuthForm, { type AuthFormMode } from "~/components/AuthForm";
|
||||
|
||||
export interface AuthBodyProps {
|
||||
|
|
@ -18,7 +17,6 @@ export default function AuthBody({ locale, mode, next, token }: AuthBodyProps) {
|
|||
<div className="flex min-h-[60vh] items-center justify-center px-4 py-16">
|
||||
<AuthForm locale={locale} mode={mode} next={next} defaultToken={token} />
|
||||
</div>
|
||||
<Toaster />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { ClientRouter } from "astro:transitions";
|
||||
import "../styles/globals.css";
|
||||
import UserMenu from "~/components/UserMenu";
|
||||
import { Toaster } from "@app/ui";
|
||||
import ThemeSwitch from "~/components/ThemeSwitch";
|
||||
import LocaleSwitch from "~/components/LocaleSwitch";
|
||||
import {
|
||||
|
|
@ -238,5 +239,6 @@ const nav = [
|
|||
</footer>
|
||||
)}
|
||||
</div>
|
||||
</body>
|
||||
<Toaster client:load />
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import { type Locale, t } from "@app/i18n";
|
||||
import { Toaster } from "@app/ui";
|
||||
import { BrowseBody } from "~/components/pages/BrowseBody";
|
||||
import AppLayout from "~/layouts/AppLayout.astro";
|
||||
|
||||
|
|
@ -23,5 +22,4 @@ const { locale } = Astro.props;
|
|||
}}
|
||||
>
|
||||
<BrowseBody locale={locale} client:load />
|
||||
<Toaster client:load />
|
||||
</AppLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import { type Locale, t } from "@app/i18n";
|
||||
import { Toaster } from "@app/ui";
|
||||
import { DanmakuSettingsBody } from "~/components/pages/DanmakuSettingsBody";
|
||||
import AppLayout from "~/layouts/AppLayout.astro";
|
||||
|
||||
|
|
@ -23,5 +22,4 @@ const { locale } = Astro.props;
|
|||
}}
|
||||
>
|
||||
<DanmakuSettingsBody locale={locale} client:load />
|
||||
<Toaster client:load />
|
||||
</AppLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import { type Locale, t } from "@app/i18n";
|
||||
import { Toaster } from "@app/ui";
|
||||
import { LibraryBody } from "~/components/pages/LibraryBody";
|
||||
import AppLayout from "~/layouts/AppLayout.astro";
|
||||
|
||||
|
|
@ -23,5 +22,4 @@ const { locale } = Astro.props;
|
|||
}}
|
||||
>
|
||||
<LibraryBody locale={locale} client:load />
|
||||
<Toaster client:load />
|
||||
</AppLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import { type Locale, t } from "@app/i18n";
|
||||
import { Toaster } from "@app/ui";
|
||||
import { MountsBody } from "~/components/pages/MountsBody";
|
||||
import AppLayout from "~/layouts/AppLayout.astro";
|
||||
|
||||
|
|
@ -23,5 +22,4 @@ const { locale } = Astro.props;
|
|||
}}
|
||||
>
|
||||
<MountsBody locale={locale} client:load />
|
||||
<Toaster client:load />
|
||||
</AppLayout>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import { type Locale, t } from "@app/i18n";
|
||||
import { Toaster } from "@app/ui";
|
||||
import { WatchBody } from "~/components/pages/WatchBody";
|
||||
import AppLayout from "~/layouts/AppLayout.astro";
|
||||
|
||||
|
|
@ -24,5 +23,4 @@ const { locale, mediaItemId } = Astro.props;
|
|||
}}
|
||||
>
|
||||
<WatchBody locale={locale} mediaItemId={mediaItemId} client:load />
|
||||
<Toaster client:load />
|
||||
</AppLayout>
|
||||
|
|
|
|||
|
|
@ -3,19 +3,31 @@ import { Toaster as SonnerToaster, toast } from "sonner";
|
|||
|
||||
type ToasterProps = React.ComponentProps<typeof SonnerToaster>;
|
||||
|
||||
const Toaster = ({ style, ...props }: ToasterProps) => {
|
||||
/**
|
||||
* sonner 封装:站点统一 toast。
|
||||
* 视觉用 design tokens,位置右上角,跟随主题。
|
||||
*/
|
||||
const Toaster = ({ ...props }: ToasterProps) => {
|
||||
return (
|
||||
<SonnerToaster
|
||||
theme="light"
|
||||
className="toaster group"
|
||||
position="top-right"
|
||||
offset={16}
|
||||
gap={10}
|
||||
mobileOffset={12}
|
||||
toastOptions={{
|
||||
unstyled: false,
|
||||
classNames: {
|
||||
toast: "group toast group-[.toaster]:bg-[var(--color-background)] group-[.toaster]:text-[var(--color-foreground)] group-[.toaster]:border-[var(--color-border)] group-[.toaster]:shadow-lg",
|
||||
description: "group-[.toast]:text-[var(--color-muted-foreground)]",
|
||||
toast:
|
||||
"group toast w-[min(22rem,calc(100vw-2rem))] rounded-lg border border-[var(--color-border)] bg-[var(--color-background)] px-3.5 py-2.5 text-sm text-[var(--color-foreground)] shadow-lg",
|
||||
title: "text-sm font-medium leading-snug",
|
||||
description: "text-[var(--color-muted-foreground)] text-xs",
|
||||
actionButton:
|
||||
"group-[.toast]:bg-[var(--color-primary)] group-[.toast]:text-[var(--color-primary-foreground)]",
|
||||
"bg-[var(--color-primary)] text-[var(--color-primary-foreground)] rounded-md px-2.5 py-1 text-xs font-medium",
|
||||
cancelButton:
|
||||
"group-[.toast]:bg-[var(--color-muted)] group-[.toast]:text-[var(--color-muted-foreground)]",
|
||||
"bg-[var(--color-muted)] text-[var(--color-muted-foreground)] rounded-md px-2.5 py-1 text-xs",
|
||||
success: "border-[var(--color-border)]",
|
||||
error: "border-[var(--color-destructive,#dc2626)]/45",
|
||||
info: "border-[var(--color-border)]",
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
|
|
|
|||
Loading…
Reference in New Issue