Поиск

  • Навигация и поиск
  • 3 мин
  • компонентов: 8
  • пар: 3

Три формы поиска и одна вещь, которую портят почти все — экран, показанный, когда ничего не нашлось.

Ревизия 2026-09-05

На этой странице

Что решает

Поиск — не одно, а три. «Найди мне запись», «выбери из слишком многих вариантов» и «выполни команду, название которой я знаю» выглядят похоже и ведут себя по-разному: другой ввод, другие результаты, другой отказ.

Отказ — там, где разница перестаёт иметь значение: у каждой из трёх форм есть состояние «ничего не нашлось», и это наименее продуманный экран в большинстве продуктов.

Анатомия

Три формы, и условие для каждой записано в библиотеке:

  1. Вводится строка — GrInput. Обычный поиск по странице или списку, где результаты появляются в другом месте, а поле только собирает запрос.
  2. Вариантов слишком много для списка — GrAutocomplete. Комбобокс: подбор по мере ввода, асинхронная загрузка, выбор в конце. Результат — значение, а не страница.
  3. Команд много и они разбросаны — GrCommandPalette. ⌘K по тому, что умеет приложение, — для того, кто знает название и не хочет искать кнопку.

Вокруг всех трёх — одни и те же четыре:

  • фильтры — GrChipGroup для строки фильтров, GrSegmented для переключения вида одних и тех же результатов;
  • ожидание — GrSkeleton, пока первые результаты в пути;
  • ничего не нашлось — GrEmptyState, и это другой экран, чем «пусто с самого начала»; о нём ниже;
  • слишком много — GrPagination.

Пример

Так и не так

Так — Сказать, что искали и сколько нашли

«7 результатов по запросу select» делает две работы: подтверждает, что запрос дошёл неискажённым, и задаёт ожидание до того, как глаз пошёл по списку. И то и другое важнее всего, когда число маленькое.

Так не надо — Пустой список как ответ «ничего не нашлось»

Пустая область под строкой поиска неотличима от сломанного поиска. Человек не может понять, это «нет совпадений», «ещё грузится» или «всё упало», — а реакции на все три разные.

Так — Предложить следующий шаг, когда не нашлось

«Ничего не нашлось» — вопрос, а не точка: покажите запрос, предложите снять фильтр, дайте ближайшее. GrEmptyState существует ровно ради этого экрана, и экран заслуживает той же заботы, что и результаты.

Так не надо — Один экран на «пусто» и «не нашлось»

«Здесь пока ничего нет — создайте первое» верно для нового аккаунта и неверно после поиска: ничего не создано не потому, что не создавали, а потому что не совпало, и кнопка предлагает не то. Два состояния — два текста.

Так — Отпускать фокус по Tab

В GrAutocomplete Tab закрывает панель и отдаёт фокус дальше по документу. Человек, заполняющий форму, идёт по полям, и поиск — одно из них, а не место, где его держат.

Так не надо — Искать на каждое нажатие без узды

Запрос на символ — это четыре запроса на «sele» и три ответа, приходящих не по порядку. Придержите ввод и отменяйте обогнанное, иначе список покажет ответ на запрос, который человек уже дописал.

Доступность

Комбобокс — паттерн с именем. GrAutocomplete его реализует: стрелки ходят по вариантам, активный вариант объявляется активным, а не только подсвечивается, и фокус остаётся в поле, пока по списку идут.

Число результатов надо объявить. Зрячий видит, что список появился; скринридеру нужно сказать — живая область с «7 результатов» и есть всё устройство, а без неё поиск нем.

Загрузка — состояние, а не украшение. Между последним нажатием и первым результатом есть промежуток, когда ответ неизвестен, и он должен восприниматься: GrSkeleton резервирует форму, а текст говорит, что происходит.

Портал меряет собственный поиск так же, как советует: доля запросов, не давших ничего, — отслеживаемое число, и оно питает контент-роадмап. Поиск, ничего не нашедший, — не поломка поиска, а страница, которой ещё нет.

Компоненты паттерна

Список строится из frontmatter, а не из ссылок в тексте: переименование слага здесь не теряется.

Клавиатура

Контракты приходят из библиотеки. Паттерн их не пересказывает — он на них ссылается.