fix(date-field): compact calendar popup — shadcn-style sizing

Календарь react-day-picker раздувался на ~700px из-за дефолтных
стилей. Теперь plотный shadcn-style ~280–290px:

- CSS-переменные v9 на враппере: --rdp-day-height/width=2rem,
  --rdp-day_button-height/width=2rem, --rdp-weekday-padding=0,
  --rdp-accent-color=brand. Контейнер p-3 text-sm.
- classNames переписаны: ячейка дня h-8 w-8 (32×32) с rounded-md,
  weekday w-8 capitalize, caption_label text-sm font-medium.
  Кнопки навигации 24×24 с hover-bg, chevron 16×16.
- Сегодня: bg-slate-100 + font-semibold (без жирной обводки).
  Выбранная дата: bg-brand text-white. Outside-дни выцветшие.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
nns 2026-04-26 03:19:13 +05:00
parent c31611d6c4
commit 6a673e536e

View file

@ -138,8 +138,20 @@ export function DateField({ value, onChange, disabled, required, className, widt
{open && pos && createPortal( {open && pos && createPortal(
<div <div
ref={popRef} ref={popRef}
style={{ position: 'fixed', top: pos.top, left: pos.left }} style={{
className="z-[100] rounded-md border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-lg p-2" position: 'fixed', top: pos.top, left: pos.left,
// Тонкие настройки react-day-picker v9 через CSS-переменные —
// shadcn-style плотный календарь ~280290px вместо ~700px.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
...({ '--rdp-day-height': '2rem', '--rdp-day-width': '2rem',
'--rdp-weekday-padding': '0', '--rdp-nav-height': '1.75rem',
'--rdp-day_button-height': '2rem', '--rdp-day_button-width': '2rem',
'--rdp-day_button-border-radius': '0.375rem',
'--rdp-accent-color': 'var(--color-brand)',
'--rdp-accent-background-color': 'var(--color-brand)',
'--rdp-selected-border': 'none' } as Record<string, string>),
}}
className="z-[100] rounded-md border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-md p-3 text-sm"
> >
<DayPicker <DayPicker
mode="single" mode="single"
@ -156,8 +168,24 @@ export function DateField({ value, onChange, disabled, required, className, widt
setOpen(false) setOpen(false)
}} }}
classNames={{ classNames={{
caption_label: 'capitalize', months: 'flex flex-col gap-2',
weekday: 'capitalize', month: 'space-y-2',
month_caption: 'flex justify-center pt-1 relative items-center h-7',
caption_label: 'text-sm font-medium capitalize',
nav: 'absolute inset-x-0 top-0 flex items-center justify-between px-1 h-7',
button_previous: 'h-6 w-6 inline-flex items-center justify-center rounded-md text-slate-500 hover:bg-slate-100 dark:hover:bg-slate-800',
button_next: 'h-6 w-6 inline-flex items-center justify-center rounded-md text-slate-500 hover:bg-slate-100 dark:hover:bg-slate-800',
chevron: 'w-4 h-4 fill-current',
weekdays: 'flex',
weekday: 'w-8 text-center text-[0.75rem] font-normal text-slate-500 capitalize',
weeks: 'mt-1',
week: 'flex w-full mt-1',
day: 'w-8 h-8 p-0 text-center align-middle',
day_button: 'w-8 h-8 inline-flex items-center justify-center rounded-md text-sm font-normal hover:bg-slate-100 dark:hover:bg-slate-800',
today: '[&_button]:bg-slate-100 dark:[&_button]:bg-slate-800 [&_button]:font-semibold',
selected: '[&_button]:bg-[var(--color-brand)] [&_button]:text-white [&_button]:hover:bg-[var(--color-brand)]',
outside: 'text-slate-300 dark:text-slate-600 opacity-60',
disabled: 'text-slate-300 opacity-50',
}} }}
/> />
</div>, </div>,