TimePicker
Компонент для выбора времени в потоке формы: колонки часов/минут/секунд с прокруткой и фокусной навигацией. Делит контекст с календарём через внутренний CalendarContext, если используется рядом с Calendar в кастомной композиции.
Когда использовать
- Нужен только выбор времени без даты на той же панели.
- Поле должно оставаться инлайн без выпадающего попапа.
Когда не нужен: если время выбирают редко и уместнее попап — используйте TimePickerDropdown.
- ✅ Синхронизировать значение с полем ввода через
value/onChangeValue. - ❌ Блокировать
onChangeValueзаглушкой — состояние не обновится и пример перестанет быть показательным.
Анатомия
Size
| Значение | Назначение |
|---|---|
s | Узкие колонки и плотные таблицы |
m | Значение по умолчанию |
l | Крупные тач-цели |
Секунды
showSeconds (true по умолчанию) скрывает третью колонку, если достаточно часов и минут.
Установка
pnpm add @cloud-ru/ds-calendar
import { TimePicker, SIZE } from '@cloud-ru/ds-calendar'
Примеры использования
Базовый выбор
tsx
import { SIZE, TimePicker, TimeValue } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function TimePickerBasic() {
const [value, setValue] = useState<TimeValue | undefined>({ hours: 9, minutes: 15, seconds: 0 });
return (
<div style={{ width: 280, maxWidth: '100%' }}>
<TimePicker fitToContainer size={SIZE.M} value={value} onChangeValue={v => setValue(v)} />
</div>
);
}Без секунд
tsx
import { SIZE, TimePicker, TimeValue } from '@cloud-ru/ds-calendar';
import { useState } from 'react';
export function TimePickerNoSeconds() {
const [value, setValue] = useState<TimeValue | undefined>({ hours: 11, minutes: 45, seconds: 0 });
return (
<div style={{ width: 240, maxWidth: '100%' }}>
<TimePicker fitToContainer showSeconds={false} size={SIZE.M} value={value} onChangeValue={v => setValue(v)} />
</div>
);
}Размеры
tsx
import { SIZE, TimePicker } from '@cloud-ru/ds-calendar';
export function TimePickerSizes() {
return (
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'flex-start' }}>
<div style={{ width: 200 }}>
<TimePicker fitToContainer defaultValue={{ hours: 8, minutes: 0, seconds: 0 }} size={SIZE.S} />
</div>
<div style={{ width: 220 }}>
<TimePicker fitToContainer defaultValue={{ hours: 12, minutes: 30, seconds: 0 }} size={SIZE.M} />
</div>
<div style={{ width: 240 }}>
<TimePicker fitToContainer defaultValue={{ hours: 18, minutes: 45, seconds: 30 }} size={SIZE.L} />
</div>
</div>
);
}Props
Types
Props
TimePickerProps| 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 | Выбранное значение. |