ADR-064: строка ввода чата — div вместо form

Убирает системную панель навигации по полям над клавиатурой на iOS
(Safari и Chrome): она держится на элементе <form>, а не на textarea
как таковом. Дешёвый вариант вместо contenteditable — сначала пробуем
его, дороже (переписывать paste/placeholder/лимит руками) не потребовалось.

Отправка теперь идёт по click на кнопке и по keydown Enter вместо
события submit — форму убрали, role="form" держит ту же семантику
для скринридера.
This commit is contained in:
Claude
2026-08-24 06:10:18 +00:00
parent c826d581ea
commit 334ce95935
3 changed files with 40 additions and 8 deletions
+12 -7
View File
@@ -197,9 +197,16 @@ async function refreshRoom(view, known) {
// composer — полоса состояния и строка ввода: рамка 1 px ink, слева «>»
// цветом mark. Enter отправляет только на десктопе; на мобильном он делает
// перенос, а отправляет кнопка «>» справа (docs/ui.md, «Чат»).
//
// div, не form: поле формы на iOS Safari/Chrome поднимает над клавиатурой
// системную панель навигации между полями («‹ ›» и «готово») — лишние
// ~50 px ради одного поля, которому переходить некуда. role="form" держит
// ту же семантику для скринридера (docs/ui.md, «Доступность»), без form-а;
// autocomplete="off" на поле — по той же причине, на случай если панель
// зависит ещё и от него.
function composer(view) {
const form = el("form", "compose");
form.noValidate = true;
const form = el("div", "compose");
form.setAttribute("role", "form");
view.bar = el("p", "bar");
view.bar.hidden = true;
@@ -213,12 +220,14 @@ function composer(view) {
view.field.rows = 1;
view.field.placeholder = "сообщение";
view.field.maxLength = view.limit;
view.field.autocomplete = "off";
view.counter = el("span", "counter");
view.counter.hidden = true;
view.send = el("button", "input__send", ">");
view.send.type = "submit";
view.send.type = "button";
view.send.addEventListener("click", () => submit(view));
row.append(prompt, view.field, view.counter, el("span", "enter", "enter — отправить"), view.send);
form.append(view.bar, row);
@@ -234,10 +243,6 @@ function composer(view) {
event.preventDefault();
submit(view);
});
form.addEventListener("submit", (event) => {
event.preventDefault();
submit(view);
});
return form;
}