Extend the authentic pinned-HA diagnostic with explicit light and dark palettes, a 32 px root-font case, one-scroller geometry assertions, and reviewed evidence images. Correct stale AC references in the mutation descriptions. Issue: #609 User-Visible: no
17 KiB
#600 · приёмка против референса
AC1 в #600 требует не «эталоны изменились», а парное сравнение с референсом:
для каждого диалога кадр продукта рядом с кадром референса, и каждое расхождение
названо со ссылкой на пункт SPEC.md или узел reference/.
Этот документ — место, где такое сравнение живёт. Он пополняется по мере реализации, по одной таблице на диалог, и предъявляется на код-ревью вместе с кадрами.
Как снимать парные кадры
Кадры продукта — одной командой из корня репозитория, на собранном бандле:
npm run build && npm run bundle:sync
node demo/capture_design_pairs_600.mjs # → pairs/<диалог>-<тема>.png
Скрипт открывает четыре диалога в состояниях макетов (пространство с
температурной заливкой и своим севером, общие настройки со статическим фоном,
комната с эффективной температурной заливкой, привязанный светильник с ролью
Always и фиксированным свечением), раскрывает скроллер на всю высоту и снимает
поверхность 560 px в светлой и тёмной теме. Кадры референса — screenshots/
из архива дизайнера (светлая тема, 1120 px при devicePixelRatio 2).
Это диагностические кадры, а не golden-базы: они не принимаются
golden:accept и не участвуют в golden:verify. Эталоны живут отдельно и
закрываются AC10: принято 13 сцен (ed2af1b1) — одиннадцать из ТЗ (список
AC10 унаследован от #598, где диалог комнаты не менялся) плюс две
room-temperature-dialog-{desktop-en,mobile-ru}, потому что диалог комнаты в
скоупе #600. PNG пережаты в палитру 256 цветов — для сравнения
раскладки этого достаточно, а вес папки остаётся в полумегабайте.
#609: оболочка в настоящем Home Assistant
Парные кадры выше были сняты в нативной ветке hp-dialog. Для #609 отдельно
проверена ветка настоящего ha-dialog из закреплённого
home-assistant-frontend==20260729.7 (SHA-256
ba01782297e9506d3185f99a74d829f3811df322623848af21bcc0b8ea834c12):
npm run bundle:sync
node demo/verify_ha_form_shell_609.mjs --capture
Официальный компонент и его CSS не модифицируются; локальная фикстура не поднимает HA, не обращается к сети и падает при внешнем запросе, WebSocket или ошибке страницы. Измерения после завершения 200-миллисекундной анимации показа:
| Режим | Поверхность | Проверенный результат |
|---|---|---|
| desktop 1600×1000 | 560×940 | канва вокруг карточек, один скроллер .body HA, footer внутри |
| dark + text 200%, 1600×1000 | 560×940 | root font 32 px, один HA-скроллер, footer внутри, канва не сливается с карточками |
| граница 480×800 | 480×800 | fullscreen, радиус 0, горизонтального переполнения нет |
| mobile 390×844 | 390×844 | fullscreen, радиус 0, footer внутри |
| низкое окно 1280×480 | 1280×480 | штатный fullscreen HA сохранён |
Снимки приёмки: pairs/room-ha-light.png,
pairs/room-ha-dark-text-200.png и pairs/room-ha-mobile-light.png. Это
диагностические доказательства, а не
golden-базы; 13 нативных golden-сцен остаются неизменными. Быстрый обязательный
свидетель тех же публичных CSS-контрактов —
demo/smoke_ha_form_shell_parity.mjs, а перечень пяти потребителей оболочки
закреплён в test/form-shell-consumers.test.mjs.
Статус по диалогам
| Диалог | Серия | Референс | Продукт (светлая / тёмная) | Расхождения названы | Готово |
|---|---|---|---|---|---|
| Space settings | 1 | screenshots/space-settings-2026-09-18.png |
pairs/space-light.png / pairs/space-dark.png |
ниже | да |
| General settings | 2 | screenshots/general-settings-2026-09-18.png |
pairs/general-light.png / pairs/general-dark.png |
ниже | да |
| Room settings | 3 | screenshots/room-settings-2026-09-18.png |
pairs/room-light.png / pairs/room-dark.png |
ниже | да |
| Device on the plan | 4 | screenshots/device-on-the-plan-2026-09-18.png |
pairs/device-light.png / pairs/device-dark.png |
ниже | да |
Расхождения с референсом, по диалогам
Каждая строка — что видно на кадре продукта иначе, чем на кадре референса, со
ссылкой на пункт SPEC.md или узел reference/, и чем это закрыто.
Space settings (§4)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Образец карточки комнаты | убран (§4.2) | внутри карточки Room cards на тинте | решение владельца Q2 |
| Поле цвета | input[type=color] (§3.2) |
плашка вокруг hp-color-opacity |
решение владельца Q5 |
| Тексты подписей | Space name, Floor plan, Appearance, Room cards, Sun & light… | те же (переименования Q6) | §4.1, решение владельца Q6 |
| Подписи сегмента заливки | Custom · Zigbee · Lights · Temperature | те же — короткие ключи fill.seg_* ленивого словаря, общие с комнатой (r1 M1: полные fill.* в RU переносились посреди слова) |
§4.2 reference/app.js fillOptions |
| Копия / удаление | Copy и Delete слева в футере | то же | §4.1 «Футер» |
General settings (§5)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Zigbee links | один заголовок, тумблер, callout | то же: блок hp-zigbee-topology-settings в режиме embedded без своего заголовка |
§5.1, дефект 1 из #600 |
| Плитки цвета | 3 в ряд, hex, число прозрачности | то же; свотч — trigger прежнего пикера | Q5 |
| Компас | 44 px справа от поля севера | то же, с сохранённым перетаскиванием стрелки | §3.1 «Компас»; прежний ввод с свидетелем smoke_sun |
Room settings (§6)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Образец карточки | убран (§6.1 «Font sizes») | под подсказкой размеров, на тинте | решение владельца Q2 |
| «?» у Basics | у поля Home Assistant area | у поля Home Assistant area (перенесён с заголовка карточки) | §6.1 |
| Подписи сегмента заливки | None · Zigbee · Lights · Temperature · Custom, по одной строке на пункт | те же — короткие ключи fill.seg_* (общие с пространством). Ревью r1 M1: «Temperature» рвалось посреди слова в пяти равных колонках — колонка сегмента больше не сжимается ниже самого длинного слова, слова переносятся только по пробелам, не поместившийся сегмент переносится на вторую строку целыми кнопками; свидетель — smoke_dialog_segments_i18n (четыре диалога × en/ru/de/fr) |
§6.1, §3.1 «Сегмент» |
| Подписи источников | Temperature / Humidity | Temperature source / Humidity source (прежние ключи) | текст, не раскладка |
| Поле цвета «Свой цвет» | input[type=color] |
плашка вокруг hp-color-opacity |
Q5 |
| Кнопка выбора датчика | в потоке, панель с поиском | то же (sourcePicker набора) |
§3.1 «Кнопка выбора источника» |
Device on the plan (§7)
| Что | Референс | Продукт | Основание |
|---|---|---|---|
| Подписи сегмента привязки | Virtual device · Pick from the HA list | Virtual device (no binding) · Pick from the HA list | прежний ключ marker.virtual_option; текст, не раскладка |
| «Show entities» | в панели выбора рядом с поиском | то же | решение владельца Q8 |
| Ask for confirmation | скрыта при Do nothing | показана только при toggle / run | Q8; прежнее условие |
| Display preview | упрощённый макет: сцена и таблица фактов | hp-device-preview целиком со своим заголовком «Display preview · Now» и переключателем деталей |
решение владельца Q3, §3.1 «Превью маркера» |
| Additional actions | строка-тумблер «This is a presence radar» | подзаголовок и кнопка «Объявить радаром» — прежнее действие радара; секции радара и пылесоса внутри диалога рисуются своими модулями без изменений | §7.2: ветки вне прототипа теми же примитивами; внутренняя разметка радара — вне скоупа #600 |
| Иконка | поле с превью, Clear, Pin в подсказке | то же; в HA — ha-icon-picker вместо текстового поля |
§7.1 |
| Value badge | тумблер, Value, Position сегментом | то же; предупреждения бейджа — заметки и callout'ы | §7.1 |
AC8: девять прямых дефектов выпущенного — свидетель на каждый
| № | Дефект (тело issue) | Чем закрыт | Свидетель |
|---|---|---|---|
| 1 | дублированный заголовок Zigbee links | карточка рисует заголовок и «?», hp-zigbee-topology-settings в режиме embedded своего не рисует |
smoke_general_settings_form → zigbeeHeadingOnce; мутант topology-embedded-draws-its-own-heading |
| 2 | «Fill color» дважды в строке заливки пространства | плашка цвета с одной подписью поля (colorRow + colorField, у пикера hide-label) |
smoke_space_settings_form → hexIsPrinted, noNativeColorInputs; noLegacyMarkup |
| 3 | семь rhint-абзацев в четырёх диалогах |
пояснения — под «?» (_help/shelp), сообщения о состоянии — callout'ы (К5) |
noLegacyMarkup в четырёх фокусных смоках (класс .rhint отсутствует); test/i18n-dead-keys; мутант state-callout-hidden-under-help |
| 4 | карточка внутри карточки (fieldset в Light and glow, Value badge) |
плоские блоки .hpf-block с подзаголовком |
smoke_device_settings_form → noLegacyMarkup (fieldset, .markerlightgroup), badgeBlock, neverDisablesGlowBlock |
| 5 | поповер «?» обрезается границей диалога комнаты | подсказка живёт в top layer (Popover API) либо в портале .overlay-portal вне поверхности диалога; тело формы без своего скроллера — резать нечем |
smoke_dialog_help_clipping: короткое окно, «?» нижней карточки комнаты, подсказка выходит за край скроллера и остаётся hit-test'ируемой во всех точках; четыре ветки — нативный <dialog> и ha-dialog × Popover и fallback. Ветка ha-dialog — заглушка с ловушками настоящей mwc-поверхности (transform + overflow: hidden + свой скроллер); настоящий ha-dialog (#505, загрузка колеса HA-frontend) — отдельная диагностическая приёмка владельца, demo/capture_summary_panel_505.mjs как образец |
| 6 | белый инпут на тёмной теме у Glow radius | поле набора .hpf-unit на токенах темы |
pairs/device-dark.png; smoke_device_settings_form |
| 7 | два скролла (тело формы и оболочка) | скроллер один — .content в hp-dialog; .body без max-height/overflow |
фокусные смоки → singleScroller / bodyHasNoOwnScroller |
| 8 | пустое пространство внизу | .body без max-height и лишнего padding-bottom |
те же; кадры pairs/ |
| 9 | «Загружаем редактор…» | editor.loading → «Загрузка…» / «Loading…» |
src/i18n/*.json |
Принятые адаптации
Расхождения, которые не являются дефектом, потому что продиктованы контрактами House Plan или решением владельца. Заполняется по ходу работы; каждая строка — с доводом, а не «так вышло».
| Место | Референс | Продукт | Почему |
|---|---|---|---|
| Образцы карточки комнаты | убраны (SPEC.md §4.2, §6.1) |
сохранены, встроены в карточку | решение владельца Q2: слайдер размера без образца — подбор вслепую |
| Поле цвета | нативный input[type=color] (SPEC.md §3.2) |
прежний hp-color-opacity, новая только раскладка |
решение владельца Q5; nativeColors() === 0 — контракт со свидетелем smoke_color_picker_consumers |
| Цвета | фиксированные hex (#4a9ec6, #f6f6f6, …) |
переменные темы HA | SPEC.md §2 «допустимые адаптации»; тёмная тема обязательна |
| Шапка | круглая кнопка × слева, заголовок, бейдж справа | прежняя шапка hp-dialog (× справа) с бейджем в слоте заголовка |
SPEC.md §3 «Шапка»: «существующая шапка hp-dialog; бейдж добавляется» |
| Тумблеры | input[type=checkbox][role=switch] с нарисованной дорожкой |
нативный чекбокс, нарисованный CSS набора; ha-switch не используется |
К7: один вид в HA, на стенде и в golden; smoke_ha_controls |
| Радар и пылесос внутри диалога устройства | нет в прототипе | прежняя разметка секций (radar-section.ts, _renderVacSection) |
SPEC.md §7.2: ветки вне прототипа; их внутренняя раскладка — отдельная задача |
| Высота строки подписи | 22 px, «?» 22 px | 32 px — по высоте кнопки hp-help |
подписи с «?» и без стоят на одной линии в сетке из двух полей |