TagInput
Вільний ввід міток з підказками — з пакетною вставкою і Backspace, який не з'їдає теги мовчки.
Мітки клієнта, галузі, теги задачі. На відміну від
UiMultiSelect, тут значення не обмежені
готовим списком: користувач вводить своє.
- vip
- терміново
Збережеться як: vip, терміново
Backspace не має з'їдати мітки мовчки
Найдорожча помилка такого поля — видалення однією клавішею. Користувач швидко набирає, промахується Backspace на порожньому полі, і остання мітка зникає без сліду. Помічають це вже після збереження форми.
Тому перше натискання лише зводить останню мітку: вона отримує видимий
стан «зараз зникне». Друге видаляє. І кожне видалення оголошується в
aria-live — інакше для скрінрідера нічого не відбувається взагалі, бо
фокус лишається в тому самому полі.
Пакетна вставка
Вставка a, b, a, c у поле, де вже є a, з max: 3 має додати b,
спинитися на межі й повідомити про це один раз. Логіка «на кожне
натискання» тут не працює: вона дала б чотири події і напівзастосований
масив.
Тому весь список проходить через одну функцію, яка перевіряє пакет проти
робочої копії й емітить update:modelValue рівно раз. Причина відмови
приходить у reject — рішення, чи це помилка й якими словами, лишається
за формою, а не за полем.
Підказки
- Логістика
З непорожнім suggestions поле стає справжнім ARIA-комбобоксом:
aria-expanded, aria-controls, aria-activedescendant, стрілки й Enter
— так само, як у UiCombobox. Вільний ввід
при цьому лишається: підказки допомагають, а не обмежують.
Панель переприв'язується не лише на прокрутку й зміну розміру вікна, а й
через ResizeObserver на самому полі. Причина конкретна: поле росте —
мітки переносяться на новий рядок, висота змінюється, і панель відклеїлася
б від нього тієї ж миті.
API
Props
| Назва | Тип | Типово | Опис |
|---|---|---|---|
modelValue* | string[] | — | Мітки. Використовуйте через `v-model`. |
suggestions | string[] | [] | Підказки для панелі. Порожньо — панелі немає взагалі, лишається чистий вільний ввід. |
max | number | — | Максимальна кількість міток. Досягнувши межі, поле блокує ввід. |
maxLength | number | — | Максимальна довжина однієї мітки. |
delimiters | string[] | [",", ";"] | Символи, що завершують мітку і ділять вставлений текст. Enter завершує мітку завжди й у цей список не входить. |
normalize | (raw: string) => string | — | Нормалізація перед додаванням — обрізання, нижній регістр, зняття «#». Порожній результат скасовує додавання. |
size | FieldSize | "md" | Висота поля. На мобільному кожен розмір вищий за десктопний. |
error | string | — | Текст помилки. Стан помилки вмикає САМА наявність тексту. |
hint | string | — | Підказка під полем. Ховається, коли показано помилку. |
label | string | — | — |
placeholder | string | — | — |
id | string | — | — |
name | string | — | — |
allowDuplicates | boolean | false | Дозволити однакові мітки. Типово дублікат відхиляється через `reject`. |
addOnBlur | boolean | true | Додавати недописану мітку при втраті фокуса. |
disabled | boolean | — | — |
required | boolean | — | — |
Події
| Назва | Payload | Опис |
|---|---|---|
update:modelValue | [value: string[]] | Новий список міток. Використовуйте через `v-model`. |
add | [tag: string] | Мітку додано. Приходить уже нормалізоване значення. |
remove | [tag: string, index: number] | Мітку видалено. Приходять саме значення і його колишній індекс. |
reject | [tag: string, reason: "length" | "max" | "duplicate" | "empty"] | Мітку відхилено. Другим аргументом — причина - duplicate, max, length або empty. |
Слоти
| Назва | Опис |
|---|---|
tag | Власний рендер мітки. `remove` прибирає саме цю мітку. |
suggestion | Власний рендер підказки в панелі. |
empty | Показується, коли під запит немає підказок. |
Доступно через ref
| Назва | Тип | Опис |
|---|---|---|
focus | () => void | Ставить фокус на поле вводу. |
clear | () => void | Прибирає всі мітки одним оновленням моделі. |
Коли використовувати
- Мітки й теги, де список значень заздалегідь невідомий.
- Отримувачі листа, ключові слова, довільні категорії.
- Поля, куди значення часто вставляють із буфера списком.
Коли НЕ використовувати
- Коли значення обмежені готовим набором — це
UiMultiSelectз чекбоксами й «вибрати все». - Для одного значення з підказками —
UiCombobox. - Для довгого тексту, який лише виглядає як список —
UiTextarea.
Доступність
Мітки — це <ul> уже ухвалених значень, а не role="listbox". Дві
причини. По-перше, кожна мітка містить кнопку видалення, а role="option"
забороняє інтерактивних нащадків — кнопка стала б недосяжною в режимі
читання. По-друге, з підказками в одному віджеті було б два listbox, а
aria-controls на полі може вказувати лише на один.
Кнопка видалення кожної мітки має власне ім'я «Видалити ‹мітка›».
Додавання, видалення й досягнення межі оголошуються через
aria-live="polite".
aria-describedby вказує рівно на один опис: помилка перекриває підказку,
а не додається до неї.