fix(admin-ui): полноценные стили DayPicker'а + 1 месяц в PeriodFilter

PeriodFilter рендерил DayPicker numberOfMonths={2} со стандартными
rdp-* стилями — `.rdp-months` имеет `flex-wrap: wrap`, при недостатке
ширины два месяца стакались вертикально, ячейки большие/разреженные,
selected/hover состояний под наш accent не было. Выглядело rough.

Два фикса:

1. PeriodFilter → numberOfMonths={1}. Для audit-фильтрации одного
   месяца достаточно (presets покрывают «7д/30д/Этот месяц»; календарь
   нужен для arbitrary range). Простой layout, не зависит от ширины
   popover'а.

2. Полноценные стили `.ord-day-picker` в styles.css (~80 строк):
   - tight cells (2rem × 2rem)
   - hover state на surface-2
   - selected day → accent bg + on-accent text
   - range_middle → accent-bg, обнулённый radius
   - range_start/end → polo'асn'ое closure radius
   - today → 1px outline
   - outside-month days → mute opacity
   - nav buttons → accent цвет + hover
   - mono font на числа (JetBrains Mono), Inter на caption/weekday

Бенефит распространяется и на DateRangePicker (использует тот же класс).
flex-wrap: nowrap override — на случай если когда-то понадобится
numberOfMonths={2} в другом контексте, не будет вертикального стека.
This commit is contained in:
Zimin A.N.
2026-05-25 17:45:39 +03:00
parent 0352e5f212
commit 07a748be53
2 changed files with 110 additions and 1 deletions
@@ -269,7 +269,7 @@ export function PeriodFilter({ value, onChange, label, disabled }: PeriodFilterP
mode="range" mode="range"
selected={dpRange} selected={dpRange}
onSelect={handleSelect} onSelect={handleSelect}
numberOfMonths={2} numberOfMonths={1}
showOutsideDays showOutsideDays
weekStartsOn={1} weekStartsOn={1}
className="ord-day-picker" className="ord-day-picker"
+109
View File
@@ -443,3 +443,112 @@ body {
animation: none; animation: none;
} }
} }
/* === react-day-picker — кастомизация под ordinis design system.
* Без этих overrides DayPicker рендерится дефолтными rdp-* стилями
* (большие квадратные ячейки, нет hover/selected состояний под наш
* accent). Класс `.ord-day-picker` ставится на корень DayPicker'а
* в DateRangePicker и PeriodFilter. === */
.ord-day-picker {
--rdp-day-width: 2rem;
--rdp-day-height: 2rem;
--rdp-day_button-width: 2rem;
--rdp-day_button-height: 2rem;
--rdp-day_button-border-radius: 6px;
--rdp-months-gap: 1rem;
--rdp-nav_button-height: 1.75rem;
--rdp-nav_button-width: 1.75rem;
--rdp-weekday-text-transform: lowercase;
--rdp-weekday-padding: 0.25rem 0;
--rdp-month_caption-font: 600 0.875rem/1.25 'Inter', sans-serif;
--rdp-day-font: 400 0.8125rem/1 'JetBrains Mono', monospace;
--rdp-weekday-font: 500 0.7rem/1 'Inter', sans-serif;
--rdp-accent-color: var(--color-accent);
--rdp-accent-background-color: var(--color-accent-bg);
font-family: 'Inter', sans-serif;
color: var(--color-ink);
}
/* Multi-month layout (если когда-то нужно): 2 столбца side-by-side
* вместо wrap'а вниз. */
.ord-day-picker .rdp-months {
flex-wrap: nowrap;
}
.ord-day-picker .rdp-month_caption {
padding: 0 0 0.5rem;
color: var(--color-ink);
}
.ord-day-picker .rdp-weekday {
color: var(--color-mute);
text-transform: lowercase;
font-weight: 500;
}
.ord-day-picker .rdp-day_button {
border-radius: 6px;
transition: background-color 120ms, color 120ms;
}
.ord-day-picker .rdp-day_button:hover:not(:disabled):not([aria-disabled='true']) {
background-color: var(--color-surface-2);
color: var(--color-ink);
}
.ord-day-picker .rdp-day.rdp-outside .rdp-day_button {
color: var(--color-mute);
opacity: 0.55;
}
.ord-day-picker .rdp-day.rdp-today .rdp-day_button {
font-weight: 600;
outline: 1px solid var(--color-line-2, var(--color-line));
outline-offset: -2px;
}
/* Selected range */
.ord-day-picker .rdp-day.rdp-selected .rdp-day_button {
background-color: var(--color-accent);
color: var(--color-on-accent, white);
font-weight: 500;
}
.ord-day-picker .rdp-day.rdp-range_middle .rdp-day_button {
background-color: var(--color-accent-bg);
color: var(--color-accent);
border-radius: 0;
}
.ord-day-picker .rdp-day.rdp-range_start .rdp-day_button {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.ord-day-picker .rdp-day.rdp-range_end .rdp-day_button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.ord-day-picker .rdp-day.rdp-range_start.rdp-range_end .rdp-day_button {
border-radius: 6px;
}
/* Nav buttons */
.ord-day-picker .rdp-button_previous,
.ord-day-picker .rdp-button_next {
border-radius: 6px;
color: var(--color-accent);
transition: background-color 120ms;
}
.ord-day-picker .rdp-button_previous:hover,
.ord-day-picker .rdp-button_next:hover {
background-color: var(--color-surface-2);
}
.ord-day-picker .rdp-button_previous:disabled,
.ord-day-picker .rdp-button_next:disabled {
opacity: 0.35;
cursor: not-allowed;
}