Files
bare/docs/decisions/064-composer-not-form.md
T
Claude 334ce95935 ADR-064: строка ввода чата — div вместо form
Убирает системную панель навигации по полям над клавиатурой на iOS
(Safari и Chrome): она держится на элементе <form>, а не на textarea
как таковом. Дешёвый вариант вместо contenteditable — сначала пробуем
его, дороже (переписывать paste/placeholder/лимит руками) не потребовалось.

Отправка теперь идёт по click на кнопке и по keydown Enter вместо
события submit — форму убрали, role="form" держит ту же семантику
для скринридера.
2026-08-24 06:10:18 +00:00

29 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-064: строка ввода — div, а не form
Уточняет `docs/ui.md`, «Доступность»: `form` в списке семантики держит `role="form"`, а не элемент `<form>`, — для строки ввода чата.
## Контекст
Тест с реальными пользователями (iPhone, Safari и Chrome): над клавиатурой при фокусе в строке ввода всплывает системная панель навигации между полями — «‹ ›» и «готово», около 50 px. Полю переходить некуда — оно на экране одно, — а место съедено.
Панель — не наша вёрстка, это поведение WebKit для полей, лежащих внутри `<form>`. Строка ввода была оформлена именно так: `<form class="compose">` с `<textarea>` и кнопкой `type="submit"`.
Дорогой вариант — `contenteditable` вместо `textarea` — снял бы панель гарантированно, но потребовал бы вручную переписать то, что сейчас даёт браузер бесплатно: placeholder, обрезку на 4000 символов, автовысоту, и обязательно — очистку `paste` до текста, потому что `contenteditable` иначе вставляет форматированный HTML, а `innerHTML` в клиенте запрещён (CLAUDE.md).
Дешёвый вариант — вынести поле из `<form>` — не трогает ничего из этого: `textarea` остаётся `textarea`.
## Решение
- `<form class="compose">``<div class="compose" role="form">`. `role="form"` — тот же ориентир для скринридера, что и элемент `<form>`, без вызывающих панель heuristics WebKit.
- Кнопка отправки — `type="button"` с явным `click`, вместо `type="submit"` и события `submit` на форме.
- `autocomplete="off"` на самом поле — на случай, если панель зависит ещё и от него, а не только от `<form>`.
- `textarea`, `maxLength`, `field-sizing: content`, placeholder — без изменений.
Остальные формы (вход, `#/new`, участники, настройки) не тронуты: там несколько полей в форме, панель навигации между ними — по крайней мере, не чистый минус, и незачем менять то, что не жаловались.
## Следствия
- Проверить можно только на реальном устройстве — эмуляции панели WebKit нет; headless-Chromium её и не показывал никогда, так что автотест здесь не поставить.
- Если панель не уйдёт (вдруг триггер — не `<form>`, а что-то ещё в эвристике Safari), следующий шаг — `contenteditable`, со всей его ценой из «Контекста».
- `Enter` на десктопе и кнопка «>» на мобильном по-прежнему отправляют — обработчики `keydown` и `click` делают то же, что раньше `submit`.