Skip to content

feat(DateTimePicker): новый компонент с двухшаговым попапом и пресетами#55

Open
IgorShevchik wants to merge 4 commits into
mainfrom
claude/date-time-picker-component-NqwmO
Open

feat(DateTimePicker): новый компонент с двухшаговым попапом и пресетами#55
IgorShevchik wants to merge 4 commits into
mainfrom
claude/date-time-picker-component-NqwmO

Conversation

@IgorShevchik
Copy link
Copy Markdown
Collaborator

@IgorShevchik IgorShevchik commented May 27, 2026

О чём PR

Новый компонент B24DateTimePicker — пикер даты и времени в стиле Битрикс24: попап с двумя шагами (календарь → сетка часов/минут), боковая колонка пресетов, режим «только дата» (date-only, время фиксируется на 00:00:00). Закрывает пробел между сегментированными B24InputDate/B24InputTime и более «нативным» UX Битрикс24.

Что сделано

  • Компонент src/runtime/components/DateTimePicker.vue поверх штатных B24Popover, B24Calendar и read-only B24Input (триггер по умолчанию). Модель — CalendarDateTime / ZonedDateTime (или CalendarDate в date-only).
  • Тема src/theme/date-time-picker.ts — минимум стилей, только классы из дизайн-системы.
  • Локализация — раздел dateTimePicker.* добавлен в тип Messages и заполнен во всех 19 локалях. endOfWeek для DE/FR/IT/BR/TR заменён на корректный «конец недели» (было «выходные»).
  • Доступностьrole="group" + aria-labelledby на сетках часов/минут, aria-pressed на ячейках, уникальный id через useId().
  • Корректность — мемоизация резолва пресетов (factory-функции вызываются один раз на рендер), Number.isFinite-защита на minute-step от NaN.
  • Тестыtest/components/DateTimePicker.spec.ts + 2 снапшота: 21 кейс × (nuxt + vue) = 42 теста зелёные, axe-проверка a11y.
  • Документацияdocs/content/docs/2.components/date-time-picker.md + 6 примеров (Basic, DateOnly, CustomPresets, CustomTrigger, FormField, MinMaxDates). Адаптивность: пресеты переезжают вниз на мобиле (flex-col-reverse sm:flex-row).
  • Playgrounds (nuxt + demo синхронно) — страница date-time-picker.vue с матрицей вариантов + регистрация в useNavigation.ts.
  • Skill b24-ui-nuxt — обновлены components.md, component-selection.md и блок «Date» в forms.md.
  • Регистрация — экспорт типов, тема в theme/index.ts, запись в ThemeDefaults.
  • Multi-reviewer ревью учтено (документация / инженерия / тесты / безопасность / CTO).

API

<B24DateTimePicker
  v-model="value"
  :minute-step="5"
  :presets="customPresets"
  date-only
  hide-presets
  locale="ru"
  placeholder="Выберите дату и время"
  :calendar="{ minValue, maxValue, isDateDisabled }"
/>

Ключевые пропсы: modelValue, defaultValue, dateOnly, minuteStep (5), locale, placeholder, presets, hidePresets, format, color, size, disabled, icon, timeIcon, popover, calendar, input.
Слоты: default (триггер), presets, preset, time-header.

Чек-лист на ручную проверку

  • pnpm dev/components/date-time-picker: открывается попап, выбор даты переключает на шаг времени, клик по минуте закрывает попап
  • Переключение Date only — второй шаг исчезает, значение становится CalendarDate
  • minute-step={5|10|15|30} — корректное количество ячеек; NaN/0/9999 не ломают рендер (есть тесты)
  • Пресеты «Сегодня» / «Завтра» / «В конце недели» / «Через неделю» / «В конце месяца» — выставляют верную дату; активный подсвечен
  • Кастомный presets (factory-функция) — пример DateTimePickerCustomPresetsExample, factory вызывается один раз на рендер
  • Кастомный триггер через #default (DateTimePickerCustomTriggerExample) — open отрабатывает; стандартный B24Input триггер
  • locale="ru" / locale="en" — формат значения, дни недели, текст пресетов меняются
  • Адаптив: на узком вьюпорте пресеты переезжают вниз и горизонтально скроллятся
  • color, size, disabled — пробежаться по Matrix в плейграунде
  • hide-presets — боковая колонка пропадает
  • B24FormField (DateTimePickerFormFieldExample) — name/required/label/hint работают
  • :calendar="{ minValue, maxValue }" (DateTimePickerMinMaxDatesExample) — рамки соблюдаются
  • A11y: скринридер озвучивает «группа: часы / группа: минуты» и состояние aria-pressed на ячейке
  • Вычитка переводов в локалях AR/IN/TH/KZ/JA/SC/TC/VN/ID/MS/LA/PL/UA — машинно сгенерированы (вынесено в issue i18n(DateTimePicker): ручная вычитка машинных переводов пресетов #60)
  • pnpm test — снапшоты соседних компонентов не сломались

Что дальше

Follow-up issues уже заведены (по результатам ревью):

После мержа PR ничего срочного делать не нужно — компонент изолированный, breaking changes в публичный API не вносит.


Готов к squash-merge. CI зелёный: pnpm lint, pnpm typecheck, pnpm exec vitest test/components/DateTimePicker.spec.ts — все три прошли локально.

🤖 Generated with Claude Code

claude added 4 commits May 7, 2026 19:02
- Adds B24DateTimePicker built on B24Popover, B24Calendar and B24Input
- Two-step UX: calendar → hour/minute grid with configurable minute step
- Side preset list with localized defaults (Today, Tomorrow, End of week,
  In a week, End of month) and full override via the `presets` prop
- `dateOnly` mode forces value to CalendarDate with 00:00:00
- Works with @internationalized/date types via v-model (CalendarDateTime,
  ZonedDateTime, CalendarDate)
- Adds theme, locale messages for all 19 locales, demo+nuxt playground
  pages, docs page with five examples and skill references update
… i18n, docs)

- tests: add DateTimePicker.spec.ts (snapshots + minuteStep clamp + axe a11y)
  — 42 tests across nuxt + vue projects, both green
- security/correctness: guard `minuteStep` against `NaN` (Number.isFinite check)
- correctness: memoize resolved preset values into `resolvedPresets` so factory
  presets evaluate once per render instead of twice (was called by both
  `:active` and `:data-active`)
- a11y: add `role="group"` + `aria-labelledby` on hour/minute grids and
  `aria-pressed` on each cell
- i18n: fix "endOfWeek" mistranslations in de/fr/it/br/tr — they meant
  "weekend" instead of "end of work week (Friday)"
- docs: drop misleading `B24Button` from intro composition, fix
  "Pick a time" → "Pick a date and time", add "With min/max dates"
  section and matching example, show `open` slot prop in custom trigger,
  add `name`/`required` to form-field example
- skills: mention `DateTimePickerPreset` type for custom presets
- theme: correct `@memo` comment (uses `B24Input`, not `B24InputDate`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants