Files
mdm-ordinis/ordinis-admin-ui/src/ui/components/toaster.tsx
T
Zimin A.N. b94912789f fix(fonts): semantic typography utilities per handoff (7 roles)
Заменяет blanket override из MR !45 на типизированную type scale per
design_handoff_ordinis_mdm/README.md "Scale" section.

Семь semantic @utility в styles.css:
  text-title-xl  22/600   — modal title, section header
  text-title-lg  17/600   — page title в editor
  text-title-md  15/600   — dictionary card title
  text-body      13/400   — workhorse: body, buttons, tabs, inputs
  text-cell      12.5/500 — table cell text
  text-mono      11/500   — Mono: IDs, dates, FK refs (font-mono baked in)
  text-cap       10.5/600 — Tektur UPPERCASE caption (font/uppercase baked in)

Audit phases:
  P1: добавил 7 утилит, font/uppercase/tracking baked где надо
  P2: 43 deterministic codemods (font-mono+text-2xs/[11px] → text-mono,
      [15/17/22]px+font-semibold → text-title-*, [12.5]px → text-cell,
      [10.5]px+uppercase+tracking → text-cap)
  P3: 64 text-sm → text-body (handoff workhorse), 84 text-2xs context-aware
      (TableCell → text-cell, bare → text-cell, плюс cleanup caps в backticks
      template literals который Phase 2 пропустил), 25 text-xs (6 → text-mono
      когда с font-mono, 19 → text-cell), 8 titles text-base/lg → text-title-*
  P4: убрал --text-2xs override (no users), оставил --text-sm: 13px scoped
      к @nstart/ui passthrough (см. comment в styles.css — убирается в Stage 3.9)

Stats:
  text-body: 69 | text-cell: 99 | text-mono: 50 | text-cap: 42
  text-title-xl: 5 | text-title-lg: 5 | text-title-md: 7
  text-sm/text-2xs/text-xs в src/: 0 (только в styles.css комментариях)

Поведение всех 277 typography usages теперь явно соответствует handoff —
каждое место осознанно выбрано под роль, не плажирующий override.
2026-05-11 14:31:35 +03:00

53 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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-cell',
},
}}
/>
)
}
// Re-export для удобства: `import { toast } from '@/ui/components/toaster'`.
export { toast }