Перейти до вмісту
tatetUI

TagInput

Вільний ввід міток з підказками — з пакетною вставкою і Backspace, який не з'їдає теги мовчки.

Мітки клієнта, галузі, теги задачі. На відміну від UiMultiSelect, тут значення не обмежені готовим списком: користувач вводить своє.

  • vip
  • терміново

Enter або кома завершують мітку. Backspace двічі — видаляє останню.

Збережеться як: 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`.
suggestionsstring[][]Підказки для панелі. Порожньо — панелі немає взагалі, лишається чистий вільний ввід.
maxnumberМаксимальна кількість міток. Досягнувши межі, поле блокує ввід.
maxLengthnumberМаксимальна довжина однієї мітки.
delimitersstring[][",", ";"]Символи, що завершують мітку і ділять вставлений текст. Enter завершує мітку завжди й у цей список не входить.
normalize(raw: string) => stringНормалізація перед додаванням — обрізання, нижній регістр, зняття «#». Порожній результат скасовує додавання.
sizeFieldSize"md"Висота поля. На мобільному кожен розмір вищий за десктопний.
errorstringТекст помилки. Стан помилки вмикає САМА наявність тексту.
hintstringПідказка під полем. Ховається, коли показано помилку.
labelstring
placeholderstring
idstring
namestring
allowDuplicatesbooleanfalseДозволити однакові мітки. Типово дублікат відхиляється через `reject`.
addOnBlurbooleantrueДодавати недописану мітку при втраті фокуса.
disabledboolean
requiredboolean

Події

Назва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 вказує рівно на один опис: помилка перекриває підказку, а не додається до неї.