fix(token): center copy toasts with dedicated toaster

This commit is contained in:
yun-zhi-ztl 2026-03-15 13:44:07 +08:00
parent cc3e45dc30
commit b1bbbeb7c9
3 changed files with 53 additions and 31 deletions

View file

@ -14,7 +14,7 @@ import {
import { Button } from '@/shared/ui/button'
import { Input } from '@/shared/ui/input'
import { Label } from '@/shared/ui/label'
import { toast } from '@/shared/lib/toast'
import { centeredToastOptions, toast } from '@/shared/lib/toast'
import type { CreateTokenRequest, CreateTokenResponse } from '@/api/types'
interface CreateTokenDialogProps {
@ -78,22 +78,10 @@ export function CreateTokenDialog({ children, existingNames = [] }: CreateTokenD
try {
await navigator.clipboard.writeText(createdToken.token)
toast.success(t('createToken.copySuccess'), undefined, {
position: 'top-center',
classNames: {
title: 'text-center font-semibold',
description: 'text-center',
},
})
toast.success(t('createToken.copySuccess'), undefined, centeredToastOptions())
} catch (error) {
console.error('Failed to copy token:', error)
toast.error(t('createToken.copyFailed'), undefined, {
position: 'top-center',
classNames: {
title: 'text-center font-semibold',
description: 'text-center',
},
})
toast.error(t('createToken.copyFailed'), undefined, centeredToastOptions())
}
}

View file

@ -1,22 +1,42 @@
import { Toaster as Sonner } from 'sonner'
import { CENTER_TOASTER_ID } from '@/shared/lib/toast'
export function Toaster() {
return (
<Sonner
position="top-right"
toastOptions={{
classNames: {
toast: 'glass-strong border border-border/40',
title: 'text-foreground font-semibold',
description: 'text-muted-foreground',
actionButton: 'bg-primary text-primary-foreground',
cancelButton: 'bg-muted text-muted-foreground',
error: 'border-destructive/40',
success: 'border-emerald-500/40',
warning: 'border-amber-500/40',
info: 'border-blue-500/40',
},
}}
/>
<>
<Sonner
position="top-right"
toastOptions={{
classNames: {
toast: 'glass-strong border border-border/40',
title: 'text-foreground font-semibold',
description: 'text-muted-foreground',
actionButton: 'bg-primary text-primary-foreground',
cancelButton: 'bg-muted text-muted-foreground',
error: 'border-destructive/40',
success: 'border-emerald-500/40',
warning: 'border-amber-500/40',
info: 'border-blue-500/40',
},
}}
/>
<Sonner
id={CENTER_TOASTER_ID}
position="top-center"
toastOptions={{
classNames: {
toast: 'glass-strong border border-border/40',
title: 'text-foreground font-semibold text-center',
description: 'text-muted-foreground text-center',
actionButton: 'bg-primary text-primary-foreground',
cancelButton: 'bg-muted text-muted-foreground',
error: 'border-destructive/40',
success: 'border-emerald-500/40',
warning: 'border-amber-500/40',
info: 'border-blue-500/40',
},
}}
/>
</>
)
}

View file

@ -1,5 +1,19 @@
import { toast as sonnerToast, type ExternalToast } from 'sonner'
export const CENTER_TOASTER_ID = 'top-center'
export function centeredToastOptions(options?: ExternalToast): ExternalToast {
return {
toasterId: CENTER_TOASTER_ID,
classNames: {
title: 'text-center font-semibold',
description: 'text-center',
...options?.classNames,
},
...options,
}
}
export const toast = {
success: (message: string, description?: string, options?: ExternalToast) => {
sonnerToast.success(message, { description, ...options })