feat(admin-ui): sonner Toast + TimeTravel polish (Stage 3.6+3.7)

This commit is contained in:
Александр Зимин
2026-05-11 09:11:21 +00:00
parent 057fd09589
commit e2f1c3527b
5 changed files with 74 additions and 1 deletions
+2 -1
View File
@@ -2,7 +2,7 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { RouterProvider, createRouter } from '@tanstack/react-router'
import { NStartUiProvider, DatePickerProvider, DATE_PICKER_LOCALE_RU } from '@/ui'
import { NStartUiProvider, DatePickerProvider, DATE_PICKER_LOCALE_RU, Toaster } from '@/ui'
import { AuthProvider } from 'react-oidc-context'
import { routeTree } from './routeTree.gen'
import { oidcAuthConfig } from '@/auth/oidcConfig'
@@ -36,6 +36,7 @@ createRoot(document.getElementById('root')!).render(
<QueryClientProvider client={queryClient}>
<DatePickerProvider datePicker={DATE_PICKER_LOCALE_RU}>
<RouterProvider router={router} />
<Toaster />
</DatePickerProvider>
</QueryClientProvider>
</RequireAuth>
@@ -0,0 +1,52 @@
import { Toaster as SonnerToaster, toast } from 'sonner'
import { useTheme } from '@/stores/ThemeProvider'
/**
* Toast notification provider — wraps sonner с our design tokens.
*
* Sonner = headless, кастомизируем через CSS variables. Параметризируется
* theme="light" | "dark" — берётся из ThemeProvider, авто-switch на смену темы.
*
* Использование:
* <pre>
* import { toast } from '@/ui/components/toaster'
* toast.success('Запись сохранена')
* toast.error('Ошибка валидации', { description: '...' })
* toast.promise(mutateAsync(), {loading, success, error})
* </pre>
*
* Mount: <Toaster /> один раз в main.tsx внутри ThemeProvider.
*/
export function Toaster() {
const { resolved } = useTheme()
return (
<SonnerToaster
position="bottom-right"
richColors
closeButton
theme={resolved}
toastOptions={{
// Inline styles переопределяют sonner CSS — tokens из @theme.
// На light: surface bg + ink text + line border.
// На dark: re-uses tokens автомат (другие значения cssvar).
style: {
background: 'var(--color-surface)',
color: 'var(--color-ink)',
border: '1px solid var(--color-line)',
borderRadius: 'var(--radius-lg)',
fontFamily: 'var(--font-sans)',
fontSize: '13px',
boxShadow: '0 12px 30px -10px rgba(40,25,10,0.38)',
},
classNames: {
title: 'font-medium',
description: 'text-mute text-xs',
},
}}
/>
)
}
// Re-export для удобства: `import { toast } from '@/ui/components/toaster'`.
export { toast }
+5
View File
@@ -123,3 +123,8 @@ export {
DropdownMenuRadioGroup,
} from './components/dropdown-menu'
export { Switch as ShadcnSwitch } from './components/switch'
// Toast notifications через sonner (rich, accessible, themable).
// Mount <Toaster /> один раз в main.tsx; call toast.success/error/etc.
// в callbacks / effects.
export { Toaster, toast } from './components/toaster'