# @cloud-ru/ds-calendar
> Пакет календаря и выбора времени — Calendar с режимами даты, диапазона и месяца/года, TimePicker и TimePickerDropdown для времени в составе полей ввода.
Docs: /snack-v2/components/calendar/
## Установка
```sh
pnpm add @cloud-ru/ds-calendar
```
## Когда использовать
- Нужен выбор периода или точечной даты с доступностью с клавиатуры и поддержкой локали.
- Время задаётся отдельно от даты или внутри поля — берите `TimePicker` или `TimePickerDropdown` по контексту (inline vs popover).
Когда **не** подходит: для простого текстового поля с маской без визуального календаря рассмотрите нативный `input type="date"` или поле с маской; для таймзон и сложного расписания — специализированные виджеты.
## API
### Calendar
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `autofocus` | `boolean` | — | no | Автофокус |
| `bottomSlot` | `ReactNode` | — | no | Рендерится после основной разметки календаря, внутри `CalendarContext` (например футер с Apply в дропдауне). |
| `buildCellProps` | `(date: Date, viewMode: ViewMode) => { isDisabled?: boolean; isHoliday?: boolean } ;` | — | no | Колбек установки свойств ячеек календаря. Вызывается на построение каждой ячейки. Принимает два параметра: `Date` - дата ячейки `ViewMode`: - `month` отображение месяца, каждая ячейка - 1 день - `year` отображение года, каждая ячейка - 1 месяц - `decade` отображение декады, каждая ячейка - 1 год
Колбек должен возвращать объект с полями, отвечающими за отключение и подкраску ячейки. |
| `className` | `string` | — | no | CSS-класс контейнера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `Date \| Range` | — | no | Значение по-умолчанию для uncontrolled. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `locale` | `Intl.Locale` | `Проставляется в соответствие с языком в настройках браузера` | no | Локаль, в соответствие с которой выставляется язык названий и первый день недели |
| `mode` | `date \| date-range \| date-time \| month \| month-range \| year \| year-range` | — | yes | Режим работы календаря: - `date` - режим выбора даты - `date-range` - режим выбора периода - `month-range` - режим выбора периода из месяцев - `year-range` - режим выбора периода из лет - `month` - режим выбора месяца - `date-time` - режим выбора даты и времени - `year` - режим выбора года |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onChangeValue` | `((value: Date) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Date) => void) \| ((value: Date) => void) \| ((value: Date) => void)` | — | no | Колбек выбора значения. - в режиме date принимает тип `Date` - в режиме date-range принимает тип `Range` - в режиме month-range принимает тип `Range` - в режиме year-range принимает тип `Range` - в режиме month принимает тип `Date` - в режиме date-time принимает тип `Date` - в режиме year принимает тип `Date` |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `presets` | `PresetsOptions` | — | no | Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) |
| `showHolidays` | `boolean` | — | no | Раскрашивает субботу и воскресенье |
| `showSeconds` | `boolean` | — | no | Показывать ли секунды (только в режиме date-time) |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `style` | `CSSProperties` | — | no | Объект со стилями на контейнер. |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `value` | `Date \| Range` | — | no | Выбранное значение. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
#### Related types
- `BuildCellPropsFunction` (alias)
- `PresetItem` (interface)
- `PresetsOptions` (interface)
- `Range` (interface)
- `Size` = `l | m | s`
### CalendarBase
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `autofocus` | `boolean` | — | no | |
| `bottomSlot` | `ReactNode` | — | no | Рендерится после основной разметки календаря, внутри `CalendarContext` (например футер с Apply в дропдауне). |
| `buildCellProps` | `BuildCellPropsFunction` | — | no | |
| `className` | `string` | — | no | |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `Range` | — | no | |
| `fitToContainer` | `boolean` | `true` | no | |
| `locale` | `Locale` | — | no | |
| `mode` | `date \| date-range \| date-time \| month \| month-range \| year \| year-range` | — | yes | |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | |
| `onChangeValue` | `(value: Range) => void` | — | yes | |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | |
| `presets` | `PresetsOptions` | — | no | |
| `showHolidays` | `boolean` | `false` | no | |
| `showSeconds` | `boolean` | `true` | no | |
| `size` | `l \| m \| s` | `m` | no | |
| `style` | `CSSProperties` | — | no | |
| `today` | `number \| Date` | — | no | |
| `value` | `Range` | — | no | |
### CalendarDropdown
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `autofocus` | `boolean` | — | no | Автофокус |
| `bottomSlot` | `ReactNode` | — | no | Рендерится после основной разметки календаря, внутри `CalendarContext` (например футер с Apply в дропдауне). |
| `buildCellProps` | `(date: Date, viewMode: ViewMode) => { isDisabled?: boolean; isHoliday?: boolean } ;` | — | no | Колбек установки свойств ячеек календаря. Вызывается на построение каждой ячейки. Принимает два параметра: `Date` - дата ячейки `ViewMode`: - `month` отображение месяца, каждая ячейка - 1 день - `year` отображение года, каждая ячейка - 1 месяц - `decade` отображение декады, каждая ячейка - 1 год
Колбек должен возвращать объект с полями, отвечающими за отключение и подкраску ячейки. |
| `children` | `ReactNode` | — | no | Элемент открытия dropdown (триггер). |
| `className` | `string` | — | no | CSS-класс контейнера |
| `closeOnApply` | `boolean` | — | no | Закрыть dropdown после нажатия Apply. |
| `closeOnEscapeKey` | `boolean` | `true` | no | Закрывать ли по нажатию на кнопку `Esc` |
| `closeOnPopstate` | `boolean` | — | no | Закрывать ли поповер при переходе по истории браузера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `Date \| Range` | — | no | Значение по-умолчанию для uncontrolled. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
| `disableSpanWrapper` | `boolean` | — | no | Отключает для `isValidElement` внешнюю обертку триггера Пригодится для элементов с `position: absolute` Работает для триггеров, которые умеют отдать свою DOM-ноду: нативные элементы, `forwardRef`-компоненты и компоненты, помеченные `withInnerRefSupport` из `@cloud-ru/ds-utils`. Остальные всё равно получают `` — без ноды поповеру не от чего считать позицию; в dev-режиме об этом печатается предупреждение. |
| `fallbackPlacements` | `Placement[]` | — | no | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `hoverDelayClose` | `number` | — | no | Задержка закрытия по ховеру |
| `hoverDelayOpen` | `number` | — | no | Задержка открытия по ховеру |
| `locale` | `Intl.Locale` | `Проставляется в соответствие с языком в настройках браузера` | no | Локаль, в соответствие с которой выставляется язык названий и первый день недели |
| `mode` | `date \| date-range \| date-time \| month \| month-range \| year \| year-range` | — | yes | Режим работы календаря: - `date` - режим выбора даты - `date-range` - режим выбора периода - `month-range` - режим выбора периода из месяцев - `year-range` - режим выбора периода из лет - `month` - режим выбора месяца - `date-time` - режим выбора даты и времени - `year` - режим выбора года |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onApply` | `(() => void)` | — | no | Колбек после подтверждения в футере. |
| `onChangeValue` | `((value: Date) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Date) => void) \| ((value: Date) => void) \| ((value: Date) => void)` | — | no | Колбек выбора значения. - в режиме date принимает тип `Date` - в режиме date-range принимает тип `Range` - в режиме month-range принимает тип `Range` - в режиме year-range принимает тип `Range` - в режиме month принимает тип `Date` - в режиме date-time принимает тип `Date` - в режиме year принимает тип `Date` |
| `onCurrent` | `(() => void)` | — | no | Колбек по кнопке Current в футере. |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `onOpenChange` | `((isOpen: boolean) => void)` | — | no | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| `open` | `boolean` | — | no | Управляет состоянием показан/не показан. |
| `outsideClick` | `boolean \| OutsideClickHandler` | — | no | Закрывать ли при клике вне поповера |
| `placement` | `bottom \| bottom-end \| bottom-start \| left \| left-end \| left-start \| right \| right-end \| right-start \| top \| top-end \| top-start` | `top` | no | Положение поповера относительно своего триггера (children). |
| `presets` | `PresetsOptions` | — | no | Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) |
| `showHolidays` | `boolean` | — | no | Раскрашивает субботу и воскресенье |
| `showSeconds` | `boolean` | — | no | Показывать ли секунды (только в режиме date-time) |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `style` | `CSSProperties` | — | no | Объект со стилями на контейнер. |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `trigger` | `click \| clickAndFocusVisible \| focus \| focusVisible \| hover \| hoverAndFocus \| hoverAndFocusVisible` | — | no | Условие отображения поповера: - `click` - открывать по клику - `hover` - открывать по ховеру - `focusVisible` - открывать по focus-visible - `focus` - открывать по фокусу - `hoverAndFocusVisible` - открывать по ховеру и focus-visible - `hoverAndFocus` - открывать по ховеру и фокусу - `clickAndFocusVisible` - открывать по клику и focus-visible |
| `triggerClassName` | `string` | — | no | CSS-класс триггера |
| `triggerClickByKeys` | `boolean` | `true` | no | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| `triggerRef` | `ForwardedRef` | — | no | Ref ссылка на триггер |
| `value` | `Date \| Range` | — | no | Выбранное значение. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
#### Related types
- `BuildCellPropsFunction` (alias)
- `OutsideClickHandler` (alias)
- `Placement` = `bottom | bottom-end | bottom-start | left | left-end | left-start | right | right-end | right-start | top | top-end | top-start`
- `PresetItem` (interface)
- `PresetsOptions` (interface)
- `Range` (interface)
- `Size` = `l | m | s`
- `Trigger` = `click | clickAndFocusVisible | focus | focusVisible | hover | hoverAndFocus | hoverAndFocusVisible`
### DesktopCalendarDropdown
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `autofocus` | `boolean` | — | no | Автофокус |
| `bottomSlot` | `ReactNode` | — | no | Рендерится после основной разметки календаря, внутри `CalendarContext` (например футер с Apply в дропдауне). |
| `buildCellProps` | `(date: Date, viewMode: ViewMode) => { isDisabled?: boolean; isHoliday?: boolean } ;` | — | no | Колбек установки свойств ячеек календаря. Вызывается на построение каждой ячейки. Принимает два параметра: `Date` - дата ячейки `ViewMode`: - `month` отображение месяца, каждая ячейка - 1 день - `year` отображение года, каждая ячейка - 1 месяц - `decade` отображение декады, каждая ячейка - 1 год
Колбек должен возвращать объект с полями, отвечающими за отключение и подкраску ячейки. |
| `children` | `ReactNode` | — | no | Элемент открытия dropdown (триггер). |
| `className` | `string` | — | no | CSS-класс контейнера |
| `closeOnApply` | `boolean` | `false` | no | Закрыть dropdown после нажатия Apply. |
| `closeOnEscapeKey` | `boolean` | `true` | no | Закрывать ли по нажатию на кнопку `Esc` |
| `closeOnPopstate` | `boolean` | — | no | Закрывать ли поповер при переходе по истории браузера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `Date \| Range` | — | no | Значение по-умолчанию для uncontrolled. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
| `disableSpanWrapper` | `boolean` | — | no | Отключает для `isValidElement` внешнюю обертку триггера Пригодится для элементов с `position: absolute` Работает для триггеров, которые умеют отдать свою DOM-ноду: нативные элементы, `forwardRef`-компоненты и компоненты, помеченные `withInnerRefSupport` из `@cloud-ru/ds-utils`. Остальные всё равно получают `` — без ноды поповеру не от чего считать позицию; в dev-режиме об этом печатается предупреждение. |
| `fallbackPlacements` | `Placement[]` | — | no | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `hoverDelayClose` | `number` | — | no | Задержка закрытия по ховеру |
| `hoverDelayOpen` | `number` | — | no | Задержка открытия по ховеру |
| `locale` | `Intl.Locale` | `Проставляется в соответствие с языком в настройках браузера` | no | Локаль, в соответствие с которой выставляется язык названий и первый день недели |
| `mode` | `date \| date-range \| date-time \| month \| month-range \| year \| year-range` | — | yes | Режим работы календаря: - `date` - режим выбора даты - `date-range` - режим выбора периода - `month-range` - режим выбора периода из месяцев - `year-range` - режим выбора периода из лет - `month` - режим выбора месяца - `date-time` - режим выбора даты и времени - `year` - режим выбора года |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onApply` | `(() => void)` | — | no | Колбек после подтверждения в футере. |
| `onChangeValue` | `((value: Date) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Date) => void) \| ((value: Date) => void) \| ((value: Date) => void)` | — | no | Колбек выбора значения. - в режиме date принимает тип `Date` - в режиме date-range принимает тип `Range` - в режиме month-range принимает тип `Range` - в режиме year-range принимает тип `Range` - в режиме month принимает тип `Date` - в режиме date-time принимает тип `Date` - в режиме year принимает тип `Date` |
| `onCurrent` | `(() => void)` | — | no | Колбек по кнопке Current в футере. |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `onOpenChange` | `((isOpen: boolean) => void)` | — | no | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| `open` | `boolean` | — | no | Управляет состоянием показан/не показан. |
| `outsideClick` | `boolean \| OutsideClickHandler` | — | no | Закрывать ли при клике вне поповера |
| `placement` | `bottom \| bottom-end \| bottom-start \| left \| left-end \| left-start \| right \| right-end \| right-start \| top \| top-end \| top-start` | `bottom-start` | no | Положение поповера относительно своего триггера (children). |
| `presets` | `PresetsOptions` | — | no | Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) |
| `showHolidays` | `boolean` | — | no | Раскрашивает субботу и воскресенье |
| `showSeconds` | `boolean` | — | no | Показывать ли секунды (только в режиме date-time) |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `style` | `CSSProperties` | — | no | Объект со стилями на контейнер. |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `trigger` | `click \| clickAndFocusVisible \| focus \| focusVisible \| hover \| hoverAndFocus \| hoverAndFocusVisible` | `click` | no | Условие отображения поповера: - `click` - открывать по клику - `hover` - открывать по ховеру - `focusVisible` - открывать по focus-visible - `focus` - открывать по фокусу - `hoverAndFocusVisible` - открывать по ховеру и focus-visible - `hoverAndFocus` - открывать по ховеру и фокусу - `clickAndFocusVisible` - открывать по клику и focus-visible |
| `triggerClassName` | `string` | — | no | CSS-класс триггера |
| `triggerClickByKeys` | `boolean` | `true` | no | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| `triggerRef` | `ForwardedRef` | — | no | Ref ссылка на триггер |
| `value` | `Date \| Range` | — | no | Выбранное значение. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
### DesktopTimePickerDropdown
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `children` | `ReactNode` | — | no | Контент триггера открытия dropdown |
| `className` | `string` | — | no | CSS-класс контейнера |
| `closeOnApply` | `boolean` | `false` | no | Закрыть dropdown после нажатия кнопки Apply |
| `closeOnEscapeKey` | `boolean` | `true` | no | Закрывать ли по нажатию на кнопку `Esc` |
| `closeOnPopstate` | `boolean` | — | no | Закрывать ли поповер при переходе по истории браузера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `TimeValue` | — | no | Значение по-умолчанию для uncontrolled. |
| `disableSpanWrapper` | `boolean` | — | no | Отключает для `isValidElement` внешнюю обертку триггера Пригодится для элементов с `position: absolute` Работает для триггеров, которые умеют отдать свою DOM-ноду: нативные элементы, `forwardRef`-компоненты и компоненты, помеченные `withInnerRefSupport` из `@cloud-ru/ds-utils`. Остальные всё равно получают `` — без ноды поповеру не от чего считать позицию; в dev-режиме об этом печатается предупреждение. |
| `fallbackPlacements` | `Placement[]` | — | no | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| `fitToContainer` | `boolean` | `false` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `hoverDelayClose` | `number` | — | no | Задержка закрытия по ховеру |
| `hoverDelayOpen` | `number` | — | no | Задержка открытия по ховеру |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onApply` | `(() => void)` | — | no | Колбек по нажатию Apply |
| `onChangeValue` | `((value?: TimeValue) => void)` | — | no | Колбек выбора значения |
| `onCurrent` | `(() => void)` | — | no | Колбек по нажатию Current |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `onOpenChange` | `((isOpen: boolean) => void)` | — | no | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| `open` | `boolean` | — | no | Управляет состоянием показан/не показан. |
| `outsideClick` | `boolean \| OutsideClickHandler` | — | no | Закрывать ли при клике вне поповера |
| `placement` | `bottom \| bottom-end \| bottom-start \| left \| left-end \| left-start \| right \| right-end \| right-start \| top \| top-end \| top-start` | `bottom-start` | no | Положение поповера относительно своего триггера (children). |
| `showSeconds` | `boolean` | `true` | no | Показывать ли секунды |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `trigger` | `click \| clickAndFocusVisible \| focus \| focusVisible \| hover \| hoverAndFocus \| hoverAndFocusVisible` | `click` | no | Условие отображения поповера: - `click` - открывать по клику - `hover` - открывать по ховеру - `focusVisible` - открывать по focus-visible - `focus` - открывать по фокусу - `hoverAndFocusVisible` - открывать по ховеру и focus-visible - `hoverAndFocus` - открывать по ховеру и фокусу - `clickAndFocusVisible` - открывать по клику и focus-visible |
| `triggerClassName` | `string` | — | no | CSS-класс триггера |
| `triggerClickByKeys` | `boolean` | `true` | no | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| `triggerRef` | `ForwardedRef` | — | no | Ref ссылка на триггер |
| `value` | `TimeValue` | — | no | Выбранное значение. |
### Footer
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `inline` | `boolean` | `false` | no | Inline-раскладка: футер рендерится внутри тела дропдауна (bottomSlot календаря), поэтому сам рисует divider, паддинги и полную ширину. По умолчанию (`false`) возвращает голые кнопки для `bottomBar`-слота дропдауна (`footer` + `footerDivider`), где обвязку даёт сам Dropdown. |
| `onApply` | `(() => void)` | — | no | Колбек по клику на Apply |
| `onCurrent` | `(() => void)` | — | no | Колбек по клику на Current |
### Grid
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `grid` | `Cell[][]` | — | yes | |
### Item
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `address` | `[number, number]` | — | no | Адрес ячейки в сетке — синхронизация фокуса и клавиатуры |
| `another` | `boolean` | — | no | Относится ли к иному периоду (не к просматриваемому в данный момент) |
| `checked` | `boolean` | — | no | Выбран ли элемент |
| `className` | `string` | — | no | CSS-класс |
| `current` | `boolean` | — | no | Является ли сегодняшним днем |
| `date` | `Date` | — | no | Дата ячейки (для колбэков выбора) |
| `disabled` | `boolean` | — | no | Деактивирован ли |
| `holiday` | `boolean` | — | no | Является ли выходным/праздником |
| `label` | `string` | — | yes | Значение |
| `onKeyDown` | `KeyboardEventHandler` | — | no | |
| `onLeave` | `(() => void)` | — | no | |
| `onPreselect` | `((date: Date) => void)` | — | no | |
| `onSelect` | `((date: Date) => void)` | — | no | |
| `rangePosition` | `end \| in \| out \| start \| start-end` | `out` | no | Является ли частью range |
| `size` | `l \| m \| s` | — | yes | Размер |
| `tabIndex` | `-1 \| 0` | — | no | Индекс фокуса кнопки |
| `testIdSegment` | `string` | — | no | Сегмент для `data-test-id` (`getTestId(segment)`). По умолчанию `item`; подписи дней недели в `WeekRow` используют `header-item`. |
| `visible` | `boolean` | `true` | no | Отображается ли в интерфейсе (ячейка без содержимого для мобильной сетки) |
### MobileCalendar
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `buildCellProps` | `BuildCellPropsFunction` | — | no | |
| `closeOnApply` | `boolean` | `false` | no | |
| `closeOnPopstate` | `boolean` | — | no | |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `Range` | — | no | |
| `locale` | `Locale` | — | no | |
| `mode` | `date \| date-range \| date-time \| month \| month-range \| year \| year-range` | — | yes | |
| `onApply` | `(() => void)` | — | no | |
| `onChangeValue` | `(value: Range) => void` | — | yes | |
| `onClose` | `() => void` | — | yes | |
| `onCurrent` | `(() => void)` | — | no | |
| `open` | `boolean` | — | yes | |
| `presets` | `PresetsOptions` | — | no | |
| `showHolidays` | `boolean` | `false` | no | |
| `showSeconds` | `boolean` | `true` | no | |
| `size` | `l \| m \| s` | `m` | no | |
| `today` | `number \| Date` | — | no | |
| `value` | `Range` | — | no | |
### MobileCalendarDropdown
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `autofocus` | `boolean` | — | no | Автофокус |
| `bottomSlot` | `ReactNode` | — | no | Рендерится после основной разметки календаря, внутри `CalendarContext` (например футер с Apply в дропдауне). |
| `buildCellProps` | `(date: Date, viewMode: ViewMode) => { isDisabled?: boolean; isHoliday?: boolean } ;` | — | no | Колбек установки свойств ячеек календаря. Вызывается на построение каждой ячейки. Принимает два параметра: `Date` - дата ячейки `ViewMode`: - `month` отображение месяца, каждая ячейка - 1 день - `year` отображение года, каждая ячейка - 1 месяц - `decade` отображение декады, каждая ячейка - 1 год
Колбек должен возвращать объект с полями, отвечающими за отключение и подкраску ячейки. |
| `children` | `ReactNode` | — | no | Элемент открытия dropdown (триггер). |
| `className` | `string` | — | no | CSS-класс контейнера |
| `closeOnApply` | `boolean` | — | no | Закрыть dropdown после нажатия Apply. |
| `closeOnEscapeKey` | `boolean` | `true` | no | Закрывать ли по нажатию на кнопку `Esc` |
| `closeOnPopstate` | `boolean` | — | no | Закрывать ли поповер при переходе по истории браузера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `Date \| Range` | — | no | Значение по-умолчанию для uncontrolled. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
| `disableSpanWrapper` | `boolean` | — | no | Отключает для `isValidElement` внешнюю обертку триггера Пригодится для элементов с `position: absolute` Работает для триггеров, которые умеют отдать свою DOM-ноду: нативные элементы, `forwardRef`-компоненты и компоненты, помеченные `withInnerRefSupport` из `@cloud-ru/ds-utils`. Остальные всё равно получают `` — без ноды поповеру не от чего считать позицию; в dev-режиме об этом печатается предупреждение. |
| `fallbackPlacements` | `Placement[]` | — | no | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `hoverDelayClose` | `number` | — | no | Задержка закрытия по ховеру |
| `hoverDelayOpen` | `number` | — | no | Задержка открытия по ховеру |
| `locale` | `Intl.Locale` | `Проставляется в соответствие с языком в настройках браузера` | no | Локаль, в соответствие с которой выставляется язык названий и первый день недели |
| `mode` | `date \| date-range \| date-time \| month \| month-range \| year \| year-range` | — | yes | Режим работы календаря: - `date` - режим выбора даты - `date-range` - режим выбора периода - `month-range` - режим выбора периода из месяцев - `year-range` - режим выбора периода из лет - `month` - режим выбора месяца - `date-time` - режим выбора даты и времени - `year` - режим выбора года |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onApply` | `(() => void)` | — | no | Колбек после подтверждения в футере. |
| `onChangeValue` | `((value: Date) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Date) => void) \| ((value: Date) => void) \| ((value: Date) => void)` | — | no | Колбек выбора значения. - в режиме date принимает тип `Date` - в режиме date-range принимает тип `Range` - в режиме month-range принимает тип `Range` - в режиме year-range принимает тип `Range` - в режиме month принимает тип `Date` - в режиме date-time принимает тип `Date` - в режиме year принимает тип `Date` |
| `onCurrent` | `(() => void)` | — | no | Колбек по кнопке Current в футере. |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `onOpenChange` | `((isOpen: boolean) => void)` | — | no | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| `open` | `boolean` | — | no | Управляет состоянием показан/не показан. |
| `outsideClick` | `boolean \| OutsideClickHandler` | — | no | Закрывать ли при клике вне поповера |
| `placement` | `bottom \| bottom-end \| bottom-start \| left \| left-end \| left-start \| right \| right-end \| right-start \| top \| top-end \| top-start` | `top` | no | Положение поповера относительно своего триггера (children). |
| `presets` | `PresetsOptions` | — | no | Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) |
| `showHolidays` | `boolean` | — | no | Раскрашивает субботу и воскресенье |
| `showSeconds` | `boolean` | — | no | Показывать ли секунды (только в режиме date-time) |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `style` | `CSSProperties` | — | no | Объект со стилями на контейнер. |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `trigger` | `click \| clickAndFocusVisible \| focus \| focusVisible \| hover \| hoverAndFocus \| hoverAndFocusVisible` | — | no | Условие отображения поповера: - `click` - открывать по клику - `hover` - открывать по ховеру - `focusVisible` - открывать по focus-visible - `focus` - открывать по фокусу - `hoverAndFocusVisible` - открывать по ховеру и focus-visible - `hoverAndFocus` - открывать по ховеру и фокусу - `clickAndFocusVisible` - открывать по клику и focus-visible |
| `triggerClassName` | `string` | — | no | CSS-класс триггера |
| `triggerClickByKeys` | `boolean` | `true` | no | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| `triggerRef` | `ForwardedRef` | — | no | Ref ссылка на триггер |
| `value` | `Date \| Range` | — | no | Выбранное значение. - в режиме date тип `Date` - в режиме date-range тип `Range` (`[Date, Date]`) - в режиме month-range тип `Range` (`[Date, Date]`) - в режиме year-range тип `Range` (`[Date, Date]`) - в режиме month тип `Date` - в режиме date-time тип `Date` - в режиме year тип `Date` |
### MobileFooter
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `applyDisabled` | `boolean` | — | yes | Блокировка Apply (нет полного выбора). |
| `onApply` | `() => void` | — | yes | Подтверждение выбора. |
| `onCurrent` | `() => void` | — | yes | Сброс к «сейчас» / переход к текущей дате. |
### MobilePeriodBlock
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `config` | `LevelConfig` | — | yes | Конфиг уровня. |
| `date` | `Date` | — | yes | Дата периода блока (1-е число месяца / 1 января года / 1 января старта декады). |
| `level` | `decade \| month \| year` | — | yes | Текущий уровень (определяет сетку и гранулярность ячеек). |
| `onSelect` | `(date: Date) => void` | — | yes | Выбор ячейки (tap). |
| `size` | `l \| m \| s` | — | yes | Размер ячеек. |
### MobilePeriodScroller
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `anchorDate` | `Date` | — | yes | Дата, на период которой центрируется скролл (при маунте и смене). |
| `config` | `LevelConfig` | — | yes | |
| `level` | `decade \| month \| year` | — | yes | |
| `onSelect` | `(date: Date) => void` | — | yes | Выбор ячейки (tap). |
| `size` | `l \| m \| s` | — | yes | |
### MobilePresetsScreen
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `items` | `PresetItem[]` | — | yes | |
| `onSelect` | `(range: Range) => void` | — | yes | |
### MobileTimePickerDropdown
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `children` | `ReactNode` | — | no | Контент триггера открытия dropdown |
| `className` | `string` | — | no | CSS-класс контейнера |
| `closeOnApply` | `boolean` | `false` | no | Закрыть dropdown после нажатия кнопки Apply |
| `closeOnEscapeKey` | `boolean` | `true` | no | Закрывать ли по нажатию на кнопку `Esc` |
| `closeOnPopstate` | `boolean` | — | no | Закрывать ли поповер при переходе по истории браузера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `TimeValue` | — | no | Значение по-умолчанию для uncontrolled. |
| `disableSpanWrapper` | `boolean` | — | no | Отключает для `isValidElement` внешнюю обертку триггера Пригодится для элементов с `position: absolute` Работает для триггеров, которые умеют отдать свою DOM-ноду: нативные элементы, `forwardRef`-компоненты и компоненты, помеченные `withInnerRefSupport` из `@cloud-ru/ds-utils`. Остальные всё равно получают `` — без ноды поповеру не от чего считать позицию; в dev-режиме об этом печатается предупреждение. |
| `fallbackPlacements` | `Placement[]` | — | no | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `hoverDelayClose` | `number` | — | no | Задержка закрытия по ховеру |
| `hoverDelayOpen` | `number` | — | no | Задержка открытия по ховеру |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onApply` | `(() => void)` | — | no | Колбек по нажатию Apply |
| `onChangeValue` | `((value?: TimeValue) => void)` | — | no | Колбек выбора значения |
| `onCurrent` | `(() => void)` | — | no | Колбек по нажатию Current |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `onOpenChange` | `((isOpen: boolean) => void)` | — | no | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| `open` | `boolean` | — | no | Управляет состоянием показан/не показан. |
| `outsideClick` | `boolean \| OutsideClickHandler` | — | no | Закрывать ли при клике вне поповера |
| `placement` | `bottom \| bottom-end \| bottom-start \| left \| left-end \| left-start \| right \| right-end \| right-start \| top \| top-end \| top-start` | `top` | no | Положение поповера относительно своего триггера (children). |
| `showSeconds` | `boolean` | `true` | no | Показывать ли секунды |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `trigger` | `click \| clickAndFocusVisible \| focus \| focusVisible \| hover \| hoverAndFocus \| hoverAndFocusVisible` | — | no | Условие отображения поповера: - `click` - открывать по клику - `hover` - открывать по ховеру - `focusVisible` - открывать по focus-visible - `focus` - открывать по фокусу - `hoverAndFocusVisible` - открывать по ховеру и focus-visible - `hoverAndFocus` - открывать по ховеру и фокусу - `clickAndFocusVisible` - открывать по клику и focus-visible |
| `triggerClassName` | `string` | — | no | CSS-класс триггера |
| `triggerClickByKeys` | `boolean` | `true` | no | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| `triggerRef` | `ForwardedRef` | — | no | Ref ссылка на триггер |
| `value` | `TimeValue` | — | no | Выбранное значение. |
### MobileTimeScreen
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `drumRef` | `Ref` | — | no | Ref барабана — для форс-коммита незавершённого жеста при уходе с экрана (см. FF-8654, комментарий #2). |
| `size` | `l \| m \| s` | — | yes | |
### NavButton
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `data-test-id` | `string` | — | no | |
| `disabled` | `boolean` | — | no | |
| `focusName` | `string` | — | no | |
| `icon` | `Element` | — | no | |
| `label` | `string` | — | no | |
| `onClick` | `(() => void)` | — | no | |
| `onDownArrowKeyDown` | `(() => void)` | — | no | |
| `onLeftArrowKeyDown` | `(() => void)` | — | no | |
| `onRightArrowKeyDown` | `(() => void)` | — | no | |
| `tabIndex` | `-1 \| 0` | — | no | |
| `useNavigationStartRef` | `boolean` | — | no | |
### PeriodPresetsList
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | — | no | CSS-класс |
| `items` | `PresetItem[]` | — | yes | Список пресетов |
| `onChange` | `(range: Range) => void` | — | yes | Действие при выборе пресета |
### TimeList
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | — | no | |
| `data-test-id` | `string` | — | no | |
| `keyboardNavigationRef` | `RefObject<{ focusItem(id: ItemId): void; }>` | — | no | |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | |
| `numberOfItems` | `number` | — | yes | |
| `onChange` | `(value: number) => void` | — | yes | |
| `onKeyDownGetter` | `OnKeyDownGetter` | — | no | |
| `value` | `number` | — | no | |
### TimePicker
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | — | no | CSS-класс контейнера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `TimeValue` | — | no | Значение по-умолчанию для uncontrolled. |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onChangeValue` | `((value?: TimeValue) => void)` | — | no | Колбек выбора значения |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `showSeconds` | `boolean` | `true` | no | Показывать ли секунды |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `value` | `TimeValue` | — | no | Выбранное значение. |
#### Related types
- `Size` = `l | m | s`
- `TimeValue` (interface)
### TimePickerBase
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | — | no | CSS-класс |
| `fixedWidth` | `boolean` | — | no | Фиксированная ширина (оверрайдит fitToContainer) |
### TimePickerDropdown
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `children` | `ReactNode` | — | no | Контент триггера открытия dropdown |
| `className` | `string` | — | no | CSS-класс контейнера |
| `closeOnApply` | `boolean` | — | no | Закрыть dropdown после нажатия кнопки Apply |
| `closeOnEscapeKey` | `boolean` | `true` | no | Закрывать ли по нажатию на кнопку `Esc` |
| `closeOnPopstate` | `boolean` | — | no | Закрывать ли поповер при переходе по истории браузера |
| `data-test-id` | `string` | — | no | |
| `defaultValue` | `TimeValue` | — | no | Значение по-умолчанию для uncontrolled. |
| `disableSpanWrapper` | `boolean` | — | no | Отключает для `isValidElement` внешнюю обертку триггера Пригодится для элементов с `position: absolute` Работает для триггеров, которые умеют отдать свою DOM-ноду: нативные элементы, `forwardRef`-компоненты и компоненты, помеченные `withInnerRefSupport` из `@cloud-ru/ds-utils`. Остальные всё равно получают `` — без ноды поповеру не от чего считать позицию; в dev-режиме об этом печатается предупреждение. |
| `fallbackPlacements` | `Placement[]` | — | no | Цепочка расположений которая будет применяться к поповеру от первого к последнему если при текущем он не влезает. |
| `fitToContainer` | `boolean` | `true` | no | Отключает предустановленный размер, заставляя компонент подстраиваться к размеру контейнра: (width: 100%, height: 100%). |
| `hoverDelayClose` | `number` | — | no | Задержка закрытия по ховеру |
| `hoverDelayOpen` | `number` | — | no | Задержка открытия по ховеру |
| `navigationStartRef` | `RefObject<{ focus(): void; }>` | — | no | Ссылка на управление первым элементом навигации |
| `onApply` | `(() => void)` | — | no | Колбек по нажатию Apply |
| `onChangeValue` | `((value?: TimeValue) => void)` | — | no | Колбек выбора значения |
| `onCurrent` | `(() => void)` | — | no | Колбек по нажатию Current |
| `onFocusLeave` | `((direction: FocusDirection) => void)` | — | no | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
| `onOpenChange` | `((isOpen: boolean) => void)` | — | no | Колбек отображения компонента. Срабатывает при изменении состояния open. |
| `open` | `boolean` | — | no | Управляет состоянием показан/не показан. |
| `outsideClick` | `boolean \| OutsideClickHandler` | — | no | Закрывать ли при клике вне поповера |
| `placement` | `bottom \| bottom-end \| bottom-start \| left \| left-end \| left-start \| right \| right-end \| right-start \| top \| top-end \| top-start` | `top` | no | Положение поповера относительно своего триггера (children). |
| `showSeconds` | `boolean` | — | no | Показывать ли секунды |
| `size` | `l \| m \| s` | `m` | no | Размер |
| `today` | `number \| Date` | — | no | Дата сегодняшнего дня |
| `trigger` | `click \| clickAndFocusVisible \| focus \| focusVisible \| hover \| hoverAndFocus \| hoverAndFocusVisible` | — | no | Условие отображения поповера: - `click` - открывать по клику - `hover` - открывать по ховеру - `focusVisible` - открывать по focus-visible - `focus` - открывать по фокусу - `hoverAndFocusVisible` - открывать по ховеру и focus-visible - `hoverAndFocus` - открывать по ховеру и фокусу - `clickAndFocusVisible` - открывать по клику и focus-visible |
| `triggerClassName` | `string` | — | no | CSS-класс триггера |
| `triggerClickByKeys` | `boolean` | `true` | no | Вызывается ли попоповер по нажатию клавиш Enter/Space (при trigger = `click`) |
| `triggerRef` | `ForwardedRef` | — | no | Ref ссылка на триггер |
| `value` | `TimeValue` | — | no | Выбранное значение. |
#### Related types
- `OutsideClickHandler` (alias)
- `Placement` = `bottom | bottom-end | bottom-start | left | left-end | left-start | right | right-end | right-start | top | top-end | top-start`
- `Size` = `l | m | s`
- `TimeValue` (interface)
- `Trigger` = `click | clickAndFocusVisible | focus | focusVisible | hover | hoverAndFocus | hoverAndFocusVisible`
### TimePickerDrum
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | — | no | Дополнительный CSS-класс корневого контейнера барабана. |
| `customOptions` | `TimePickerDrumCustomOptions` | — | no | Ограничение допустимых значений в колонках: whitelist (`allowed*`) или нижняя граница (`min*`). Если задан непустой `allowed*` после нормализации, для этой колонки используется только он; иначе при наличии `min*` — диапазон от `min` до максимума (часы 0–23, минуты и секунды 0–59). При несовпадении текущего `hours` / `minutes` / `seconds` с допустимым набором компонент подставит ближайшее допустимое значение через соответствующий `on*Change`. |
| `data-test-id` | `string` | — | no | |
| `hours` | `number` | — | yes | Текущий выбранный час (0–23), контролируемое значение колонки часов. |
| `minutes` | `number` | — | yes | Текущая выбранная минута (0–59), контролируемое значение колонки минут. |
| `onHoursChange` | `(value: number) => void` | — | yes | Вызывается при смене часа после жеста (отпускание указателя / `lostpointercapture`) или после паузы при прокрутке колесом, а также при автоподгонке под `customOptions`. В контролируемом режиме обработчик обязан записать переданный `value` в состояние, иначе эффект подгонки может вызываться на каждом рендере. |
| `onMinutesChange` | `(value: number) => void` | — | yes | Вызывается при смене минуты после жеста или после паузы при прокрутке колесом, а также при автоподгонке под `customOptions`. В контролируемом режиме обработчик обязан записать переданный `value` в состояние, иначе эффект подгонки может вызываться на каждом рендере. |
| `onSecondsChange` | `((value: number) => void)` | — | no | Вызывается при смене секунды после жеста или после паузы при прокрутке колесом, а также при автоподгонке под `customOptions`. Нужен при `showSeconds === true`. В контролируемом режиме обработчик обязан записать переданный `value` в состояние, иначе эффект подгонки может вызываться на каждом рендере. |
| `seconds` | `number` | — | no | Текущая выбранная секунда (0–59), контролируемое значение колонки секунд. Учитывается при `showSeconds === true`. |
| `selectedDateLabel` | `string` | — | no | Текст даты над дисплеем времени (локализуется снаружи). В подписи выводится только дата; время — в `timeRow`. Допускается ISO или строка, распознаваемая `Date.parse`. |
| `showSeconds` | `boolean` | `true` | no | Показывать третью колонку секунд (`secondsList` в макете). Если `false`, колонка скрыта и `onSecondsChange` не используется. |
| `size` | `l \| m \| s` | `m` | no | Размер по оси Figma `size` календаря (высота строк барабана и отступы). |
### TimePickerDrumWheelColumn
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | — | no | Дополнительный CSS-класс корневого элемента колонки (обёртка с обработчиками указателя). |
| `data-test-id` | `string` | — | no | Идентификатор для автотестов на корневом элементе колонки. |
| `formatLabel` | `(value: number) => string` | — | yes | Форматирование подписи в ячейке (например с ведущим нулём для минут). |
| `height` | `number` | — | yes | Высота видимой области колонки («окна») в пикселях. |
| `itemHeight` | `number` | — | yes | Высота одной строки барабана в пикселях (шаг дискретизации при перетаскивании и колесе). |
| `onChange` | `(value: number) => void` | — | yes | Вызывается при смене значения после жеста (отпускание / `lostpointercapture`) или после паузы при прокрутке колесом. |
| `options` | `number[]` | — | yes | Допустимые значения колонки: отсортированный по возрастанию список без дубликатов. Циклическая прокрутка выполняется только по индексам этого массива. |
| `value` | `number` | — | yes | Текущее выбранное значение; должно входить в `options` (иначе для отображения берётся ближайшее из списка). |
## Примеры
### CalendarDateRange
```tsx
import { Calendar, CALENDAR_MODE, Range, SIZE } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function CalendarDateRange() {
const [value, setValue] = useState(() => [new Date(2026, 3, 1), new Date(2026, 3, 20)]);
return (
setValue(r)}
/>
);
}
```
### CalendarDateSingle
```tsx
import { Calendar, CALENDAR_MODE, SIZE } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function CalendarDateSingle() {
const [value, setValue] = useState(() => new Date(2026, 3, 10));
return (
setValue(d)} />
);
}
```
### CalendarDateTime
```tsx
import { Calendar, CALENDAR_MODE, SIZE } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function CalendarDateTime() {
const [value, setValue] = useState(() => new Date(2026, 3, 10, 14, 30, 0));
return (
setValue(d)}
/>
);
}
```
### CalendarMonthMode
```tsx
import { Calendar, CALENDAR_MODE, SIZE } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function CalendarMonthMode() {
const [value, setValue] = useState(() => new Date(2026, 3, 1));
return (
setValue(d)}
/>
);
}
```
### CalendarWithPresets
```tsx
import { Calendar, CALENDAR_MODE, Range, SIZE } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function CalendarWithPresets() {
const [value, setValue] = useState();
return (
setValue(r)}
/>
);
}
```
### CalendarYearRange
```tsx
import { Calendar, CALENDAR_MODE, Range, SIZE } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function CalendarYearRange() {
const [value, setValue] = useState(() => [new Date(2024, 0, 1), new Date(2026, 0, 1)]);
return (