Files
bare/docs/decisions/064-composer-not-form.md

4.6 KiB
Raw Permalink Blame History

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

Пересмотрен ADR-076: ни контейнер, ни вид редактируемого элемента не дают веб-странице управления системной панелью iOS; поле снова стало textarea, контейнер div оставлен как безвредная деталь реализации.

Уточняет docs/ui.md, «Доступность»: form в списке семантики держит role="form", а не элемент <form>, — для строки ввода чата.

Пересмотрен ADR-069. Диагноз здесь неверен: полосу помощника форм iOS рисует не из-за <form>, а для любых input и textarea, — вынос поля из формы её не убрал. Контейнер div с role="form" и кнопка type="button" остаются, textarea заменён редактируемым блоком — тем самым «следующим шагом», который записан ниже в «Следствиях».

Контекст

Тест с реальными пользователями (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 оставались без изменений; актуальное состояние строки ввода задаёт пересмотревший это решение ADR-076.

Остальные формы (вход, #/new, участники, настройки) не тронуты: там несколько полей в форме, панель навигации между ними — по крайней мере, не чистый минус, и незачем менять то, что не жаловались.

Следствия

  • Проверить можно только на реальном устройстве — эмуляции панели WebKit нет; headless-Chromium её и не показывал никогда, так что автотест здесь не поставить.
  • Если панель не уйдёт (вдруг триггер — не <form>, а что-то ещё в эвристике Safari), следующий шаг — contenteditable, со всей его ценой из «Контекста».
  • Enter на десктопе и кнопка «>» на мобильном по-прежнему отправляют — обработчики keydown и click делают то же, что раньше submit.