fix(date-field): polish calendar UX — dropdown nav, today/clear footer, ru weekdays
Some checks are pending
Some checks are pending
Календарь приведён к виду нативного date-picker macOS: - captionLayout="dropdown" + startMonth/endMonth — в шапке селекты «Апрель» и «2026» (можно прыгнуть на любой месяц/год без 12 кликов next). - Стрелки навигации справа в шапке (absolute right-1 top-1), компактные 28×28, hover-bg, без ярко-синего акцента. - footer prop — две inline-ссылки «Очистить» (сбрасывает) и «Сегодня» (ставит сегодняшнюю дату); border-t над ними. - Сегодня = синяя заливка bg-brand text-white (как на референсе); выбранная дата = ring-2 ring-brand; если сегодня = выбранный — применяются обе (сначала заливка, потом ring). - Ширина popover'а w-[340px], ячейки 36×36, weekday и dropdown capitalize → «Пн Вт Ср …», «Апрель 2026». Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
22cc0256b9
commit
88e382d9d7
|
|
@ -140,24 +140,27 @@ export function DateField({ value, onChange, disabled, required, className, widt
|
|||
ref={popRef}
|
||||
style={{
|
||||
position: 'fixed', top: pos.top, left: pos.left,
|
||||
// Тонкие настройки react-day-picker v9 через CSS-переменные —
|
||||
// shadcn-style плотный календарь ~280–290px вместо ~700px.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...({ '--rdp-day-height': '2rem', '--rdp-day-width': '2rem',
|
||||
// Тонкие настройки react-day-picker v9 через CSS-переменные.
|
||||
// Сегодня = синяя заливка (как у нативного date-picker macOS).
|
||||
...({ '--rdp-day-height': '2.25rem', '--rdp-day-width': '2.25rem',
|
||||
'--rdp-weekday-padding': '0', '--rdp-nav-height': '1.75rem',
|
||||
'--rdp-day_button-height': '2rem', '--rdp-day_button-width': '2rem',
|
||||
'--rdp-day_button-height': '2.25rem', '--rdp-day_button-width': '2.25rem',
|
||||
'--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>),
|
||||
'--rdp-accent-background-color': 'transparent',
|
||||
'--rdp-selected-border': 'none',
|
||||
'--rdp-today-color': 'inherit' } 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"
|
||||
className="z-[100] w-[340px] rounded-md border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-md p-3 text-sm"
|
||||
>
|
||||
<DayPicker
|
||||
mode="single"
|
||||
locale={ru}
|
||||
weekStartsOn={1}
|
||||
ISOWeek
|
||||
captionLayout="dropdown"
|
||||
startMonth={new Date(2020, 0)}
|
||||
endMonth={new Date(2035, 11)}
|
||||
selected={isoToDate(value)}
|
||||
defaultMonth={isoToDate(value) ?? new Date()}
|
||||
onSelect={(d) => {
|
||||
|
|
@ -167,23 +170,47 @@ export function DateField({ value, onChange, disabled, required, className, widt
|
|||
setDraft(isoToDisplay(iso))
|
||||
setOpen(false)
|
||||
}}
|
||||
footer={
|
||||
<div className="flex items-center justify-between pt-2 mt-2 border-t border-slate-100 dark:border-slate-800">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => { onChange(''); setDraft(''); setOpen(false) }}
|
||||
className="text-sm text-[var(--color-brand)] hover:underline"
|
||||
>
|
||||
Очистить
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const iso = dateToIso(new Date())
|
||||
onChange(iso); setDraft(isoToDisplay(iso)); setOpen(false)
|
||||
}}
|
||||
className="text-sm text-[var(--color-brand)] hover:underline"
|
||||
>
|
||||
Сегодня
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
classNames={{
|
||||
months: 'flex flex-col gap-2',
|
||||
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',
|
||||
months: 'flex flex-col',
|
||||
month: 'relative space-y-2',
|
||||
month_caption: 'flex items-center pt-0.5 pl-1 h-8 pr-16',
|
||||
dropdowns: 'flex items-center gap-1.5 text-sm font-semibold',
|
||||
dropdown_root: 'relative inline-flex items-center',
|
||||
dropdown: 'appearance-none bg-transparent capitalize cursor-pointer focus:outline-none rounded hover:bg-slate-100 dark:hover:bg-slate-800 px-1.5 py-0.5 pr-5',
|
||||
caption_label: 'capitalize pointer-events-none absolute opacity-0',
|
||||
nav: 'absolute right-1 top-1 flex items-center gap-0.5',
|
||||
button_previous: 'h-7 w-7 inline-flex items-center justify-center rounded-md text-slate-500 hover:bg-slate-100 dark:hover:bg-slate-800',
|
||||
button_next: 'h-7 w-7 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',
|
||||
weekday: 'w-9 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)]',
|
||||
day: 'w-9 h-9 p-0 text-center align-middle',
|
||||
day_button: 'w-9 h-9 inline-flex items-center justify-center rounded-md text-sm font-normal hover:bg-slate-100 dark:hover:bg-slate-800 disabled:hover:bg-transparent',
|
||||
today: '[&_button]:bg-[var(--color-brand)] [&_button]:text-white [&_button]:font-medium [&_button]:hover:bg-[var(--color-brand)]',
|
||||
selected: '[&_button]:ring-2 [&_button]:ring-[var(--color-brand)] [&_button]:ring-offset-1',
|
||||
outside: 'text-slate-300 dark:text-slate-600 opacity-60',
|
||||
disabled: 'text-slate-300 opacity-50',
|
||||
}}
|
||||
|
|
|
|||
Loading…
Reference in a new issue