Поле с токенами TokenInput

Поле с токенами — это поле ввода со списком подсказок. Оно похоже на комбобокс, но используется в случаях, когда нужно указать сразу много однородных элементов — токенов.

Когда использовать

Поле с токенами используют для выбора нескольких значений из справочника и для добавления своих значений.

Виды полей

С выбором из справочника

Если в поле можно ввести только значения из справочника, и пользователь не может добавлять свои, то при вводе в поле появляются подсказки.

Если в справочнике нет подходящего значения, добавить элемент нельзя.

С возможностью добавления в справочник

Если пользователь может вводить любые значения в поле, в конце списка появляется подсказка об этом и пункт «Добавить».

Добавление в справочник и в поле происходит если выбрать этот пункт в списке мышью, переместив на него фокус стрелками с клавиатуры и нажав Enter, а также если ввести разделитель — запятую или пробел.

Не корректно реализовано в библиотеке React UI — #1860 и #1878

Без справочника

Пользователь может вводить любые значения в поле, они не привязаны к справочнику, и нет подсказок. Пользователь просто вводит значения через разделитель или добавляет их по нажатию на Enter.

Описание работы

Состояние по умолчанию

Плейсхолдер подсказывает, что в поле можно ввести несколько значений:

Фокус по пустому полю

При получении фокуса плейсхолдер становится чуть светлее, появляется синяя рамка у поля, сразу открывается список вариантов:

Когда курсор находится над списком, скроллинг страницы блокируется.

Если список большой, показывайте сначала наиболее релевантные варианты:

Начало ввода

При вводе символов список фильтруется. Первый пункт в списке подсвечивается:

Не реализовано в библиотеке React UI — #1878

Если значений соответствующих введенной строке много, показывайте только часть из них:

Если в справочнике нет элементов, удовлетворяющих поиску, и можно добавлять свои, отображается только один пункт — «Добавить»:

Выбор пункта из списка

При выборе значения мышью или клавишей Enter фокус остается в поле, выпадающий список перемещается в новую позицию рядом с текстовым курсором.

Уже выбранные элементы не отображаются в выпадающем списке.

Фокус по заполненному полю

Если курсор был над одним из токенов, токен выбирается, появляется синяя рамка у поля.

Если начать в этот момент набирать текст — выделение с выбранного токена снимается, появляется выпадающий список.

Не реализовано в библиотеке React UI — #1879

Если курсор был не над токеном, или поле получило фокус после нажатия Tab на клавиатуре — в поле ставится текстовый курсор, появляется синяя рамка у поля, и список с подсказками.

Если в поле введено произвольное значение не из справочника и поле получило фокус после нажатия Tab на клавиатуре, введенное значение выделяется:

Размер поля

Если пользователь ввел токенов больше чем входит по ширине, поле увеличивается по высоте и ведет себя как текстовая область.

Маска

Чтобы упростить форматирование, можно использовать маску.

Не реализовано в библиотеке React UI

Цвет

В обычных случаях токен бесцветный. В случаях, если вводимые значения будут на одной странице в нескольких экземплярах и их нужно визуально связывать или различать (например, теги), можно использовать цветные токены.

Цвета должны быть разные по оттенку, но близкие по насыщенности.

Разделитель элементов

Введенный текст превращается в токен при выборе значения из списка или при вводе разделителя. В общем случае в качестве разделителя используется запятая. Разделитель следует выбирать в зависимости от формата данных.

Не корректно реализовано в библиотеке React UI — #1860

Например, при вводе электронной почты, в качестве разделителя уместно использовать запятую и пробел, поскольку эти символы в ней не встречаются. В случае с телефоном пробел нельзя использовать, поскольку пользователь может сам ввести его для удобочитаемости или скопировать его из места, где он уже был.

Работа с клавиатурой

В режиме ввода или редактирования токена

В режиме ввода токена клавиатура работает как в обычном поле — стрелки вправо и влево управляют перемещением текстового курсора между символами, а стрелки вверх и вниз перемещают выделение в выпадающем списке. Backspace стирает введенные символы.

В обычном режиме

Когда пользователь нажимает Backspace в поле, в котором нет введенного текста сначала выделяется предыдущий токен, а второе нажатие Backspace удаляет его.

При нажатии стрелок на клавиатуре курсор перемещается между токенами, а не между буквами внутри него. В поле работают все те же горячие клавиши и клавиши-модификаторы, что и в обычном поле. Например, нажатие стрелок с зажатой клавишей Shift выделяют токены по одному, а Ctrl+A выделяет все сразу.

Токены можно копировать и вставлять. Если вставить токен в обычное поле, он вставится в виде обычного текста.

Редактирование элементов

Чтобы отредактировать токен, нужно дважды кликнуть на него мышью или выделить и нажать Enter. В этом случае токен превратится в текст, список появится непосредственно под курсором, а не под всем полем, а повторное нажатие на Enter превратит текст обратно в токен.

Не реализовано в библиотеке React UI — #2112

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

В момент перехода в режим редактирования и обратно все остальные токены должны оставаться на своих местах.

Если во время ввода нового значения длина токена увеличивается, он сдвигает все идущие за ним токены, а если они не входят — переносит их на следующую строку:

Если длина токена становится больше ширины поля ввода, редактируемый текст переносится на следующую строку:

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

По нажатию на Enter или запятую текст снова становится токеном. Выделение остаётся на нем:

Валидация

Если текст не подходит по формату, то токен не формируется. В этом случае при потере фокуса валидируется все поле целиком.

После того, как пользователь исправит неправильно введенное значение, оно превратится в токен по нажатию Enter или добавлению разделителя.

Каждый токен может валидироваться отдельно. Пример — валидация значения при отправке формы.