Все выпадающие списки (фильтры «Устройства», «Бэкапы», «Журнал», поле «Группа» в окне устройства) оформлены как меню «⋯» (docs/changes/020): - app.js строит меню поверх скрытого select: значение уходит с формой, без JavaScript работает стандартный список; выбор отправляет change — существующие onchange/hx-trigger не менялись; - позиционирование — существующий placeMenu, выбранный пункт отмечен «✓», клавиатура: Tab, Enter/Space, ↑/↓, Escape; - Escape при открытом списке в окне закрывает только список. Тесты: 24 из 24. Автотестов JS нет; ручная проверка UI пользователем на момент коммита не подтверждена. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
24 lines
3.0 KiB
Markdown
24 lines
3.0 KiB
Markdown
# Итоги: 020 — выпадающие списки в стиле меню действий
|
||
|
||
## Сделано
|
||
- Все `select.field` (10 списков: фильтры «Устройства» ×3, «Бэкапы» ×3, «Журнал» ×3, поле «Группа» в окне устройства) выглядят как меню «⋯»:
|
||
кнопка с текстом выбранного пункта и шевроном, панель `.menu-panel` с пунктами `.mi`, выбранный — «✓», включённый фильтр подсвечен.
|
||
- `app/ui/static/app.js::enhanceSelects`: прогрессивное улучшение — нативный `select` остаётся скрытым в разметке (значение уходит с формой,
|
||
без JavaScript — стандартный список). Выбор пункта ставит `select.value` и отправляет `change` — существующие `onchange`, `hx-trigger`
|
||
и «+ Новая группа…» работают без изменений. Применяется при загрузке и к фрагментам HTMX (окно устройства), без дублей (`data-enhanced`).
|
||
- Позиционирование — существующий `placeMenu` (не обрезается таблицей/окном, вверх у нижнего края), панель не уже кнопки, длинные списки прокручиваются (320px).
|
||
- Клавиатура: Tab, Enter/Space, ↑/↓ по пунктам, Escape закрывает список и возвращает фокус на кнопку.
|
||
- `style.css`: `.select-btn`, `.select-menu` — только существующие токены; шеврон через `currentColor` (следует теме).
|
||
- `_device_form.html`: поле «Группа» в `div.lbl` с `aria-labelledby` вместо `label` — клик по подписи не уходит в скрытый `select`.
|
||
|
||
## Найдено на ревью и исправлено
|
||
- Escape при открытом списке внутри окна устройства закрывал и само окно (действие браузера по умолчанию для `<dialog>`) — введённые данные терялись.
|
||
Исправлено: `preventDefault` на keydown и на `cancel` окна, если в момент Escape было открыто меню.
|
||
|
||
## Проверено
|
||
- `pytest`: 24 из 24 (серверная часть не менялась); `node --check app.js` — без ошибок.
|
||
- Стенд (порт 8001) отдаёт новые `app.js` и `style.css`.
|
||
|
||
## Оговорки
|
||
- Автотестов JS в проекте нет; поведение в браузере (темы, клавиатура, окно устройства) проверяется вручную — на момент коммита пользователем не подтверждено.
|