Files
bare/docs/decisions/076-ios-input-accessory-is-system.md
T

4.6 KiB
Raw Blame History

ADR-076: Панель ввода iOS системная, строка сообщения — textarea

Пересматривает ADR-064, ADR-069 и ADR-071. Уточняет docs/ui.md, «Чат» и «Доступность».

Контекст

В v1.1 строка сообщения прошла два варианта: textarea вынесли из <form>, затем заменили на contenteditable="plaintext-only". Оба решения исходили из предположения, что системная полоса iOS со стрелками и «готово» появляется только у поля формы.

Проверка v1.1 на реальном iPhone опровергла предположение: полоса осталась и у contenteditable. Это часть клавиатурного интерфейса WebKit, а не узел страницы. Web API для её отключения нет. В нативной оболочке внешний вид клавиатуры может менять хост iOS; установленная PWA остаётся веб-страницей и такого доступа не получает.

contenteditable при этом стоил клиенту ручной реализации подсказки, предела, вставки без разметки, переноса строки, disabled, счётчика, работы IME и запасного пути для браузеров без plaintext-only. Главное следствие ADR-069 не наступило, а цена осталась.

Решение

  • Строка сообщения снова становится textarea с нативными placeholder, maxLength, disabled, выделением, вставкой и отменой. Число rows считается по фактической высоте текста от одной до семи: это сохраняет автовысоту в Safari без поддержки field-sizing. Доступное имя повторяет подсказку через aria-label, кнопка > объявляется как «отправить»; autocapitalize, autocorrect и enterkeyhint остаются прежними.
  • Контейнер div role="form" и кнопка type="button" остаются. Они не убирают системную панель, но и не создают отдельного поведения; менять их ещё раз без причины незачем.
  • Системная панель iOS принимается как ограничение веб-клиента. inputmode="none" и собственная экранная клавиатура не используются: убрать вместе с панелью системную клавиатуру означает потерять обычный набор, раскладки, диктовку и доступность.
  • Нативная iOS-оболочка не добавляется в Bare. Если абсолютное управление панелью станет требованием, это отдельный продуктовый и архитектурный выбор.
  • Тап по неинтерактивному месту истории вызывает blur() строки сообщения и закрывает клавиатуру. Кнопки и ссылки в ленте сохраняют своё действие.

Следствия

  • Строка сообщения снова опирается на браузерное текстовое поле и стала заметно проще. Лишнее не проходит через maxLength; ручная обработка beforeinput, вставки, IME и текстовых узлов удалена.
  • Полоса со стрелками и «готово» на iPhone остаётся. Код и документация больше не обещают веб-странице контроль над системным UI.
  • Тап по истории возвращает место ленте без нажатия системной кнопки «готово».
  • Проверка самой панели по-прежнему требует реального iPhone; поведение textarea, отправки и снятия фокуса проверяется в обычном браузере.