mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 11:49:16 +00:00
AC0 задачи: пока референс лежит вложением в issue, ревью сравнивает продукт с макетом «на глаз», и ровно это дало выпущенный в 1.77.0-beta.2 ложный паритет — карточки снаружи, старая разметка внутри. Содержимое архива `houseplan-settings-design-2026-09-18.zip` (SHA-256 06f07fc212947ee9da1a39aaab2d14cbd41154cc9effe39bc48e1c2e1517255b, сверен побайтово с вложением #591) разложено по образцу #505: - `SPEC.md`, `IMPLEMENTATION-GUIDE.md`, `OPEN-POINTS.md`, карта полей Space — с этого коммита часть ТЗ: расхождение называется ссылкой на пункт документа; - `reference/` — свёрстанный прототип четырёх форм; - `screenshots/` — четыре формы целиком, 560 px, 2x; - `README.md` — происхождение, отпечаток, границы использования; - `ACCEPTANCE.md` — место для парных кадров «референс / продукт» по AC1. Автор — сотрудник владельца (подтверждено 20.09 в #600), внешний грант не нужен. Windows-лаунчеры `START.cmd` и `START.ps1` не переносились: `node serve.mjs` делает то же самое. `room-fill.test.mjs` перенесён как документ намерения, CI его не запускает — под `docs/**` не попадает ни один тестовый glob. В бандл отсюда не попадает ничего; `repo-hygiene` и полный набор зелёные (2793 pass). Issue: #600 User-Visible: no
67 lines
2.3 KiB
JavaScript
67 lines
2.3 KiB
JavaScript
/* Demo navigation belongs to the gallery, not to the production settings form. */
|
|
const forms = new Map();
|
|
const selector = document.querySelector('#demo-form-select');
|
|
const gallery = document.querySelector('#launch-screen');
|
|
const list = document.querySelector('#demo-form-list');
|
|
let activeForm = null;
|
|
let switching = false;
|
|
|
|
export function registerDemoForm(form) {
|
|
if (forms.has(form.id)) throw new Error(`Duplicate demo form: ${form.id}`);
|
|
forms.set(form.id, form);
|
|
const option = new Option(form.title, form.id);
|
|
selector.add(option);
|
|
|
|
const card = document.createElement('article');
|
|
card.className = 'demo-form-card';
|
|
const heading = document.createElement('h2');
|
|
heading.textContent = form.title;
|
|
const description = document.createElement('p');
|
|
description.textContent = form.description;
|
|
const button = document.createElement('button');
|
|
button.className = 'button primary';
|
|
button.type = 'button';
|
|
button.textContent = 'Open preview';
|
|
button.setAttribute('aria-label', `Open ${form.title} preview`);
|
|
button.addEventListener('click', () => openDemoForm(form.id));
|
|
card.append(heading, description);
|
|
if (form.galleryControls) {
|
|
form.galleryControls.hidden = false;
|
|
card.append(form.galleryControls);
|
|
}
|
|
card.append(button);
|
|
list.append(card);
|
|
}
|
|
|
|
export async function openDemoForm(id) {
|
|
if (switching || id === activeForm) return;
|
|
if (id && !forms.has(id)) throw new Error(`Unknown demo form: ${id}`);
|
|
// Keep showing the current selection until the form agrees to close.
|
|
selector.value = activeForm || '';
|
|
switching = true;
|
|
try {
|
|
if (activeForm && !(await forms.get(activeForm).requestClose())) return;
|
|
if (!id) return;
|
|
activeForm = id;
|
|
selector.value = id;
|
|
gallery.hidden = true;
|
|
document.body.dataset.demoForm = id;
|
|
document.title = `${forms.get(id).title} · House Plan previews`;
|
|
forms.get(id).open();
|
|
} finally {
|
|
switching = false;
|
|
}
|
|
}
|
|
|
|
export function notifyDemoFormClosed(id) {
|
|
if (activeForm !== id) return;
|
|
activeForm = null;
|
|
selector.value = '';
|
|
gallery.hidden = false;
|
|
delete document.body.dataset.demoForm;
|
|
document.title = 'Form previews · House Plan';
|
|
selector.focus({preventScroll:true});
|
|
}
|
|
|
|
selector.addEventListener('change', () => openDemoForm(selector.value));
|