TagInput
Teglar, kalit so'zlar va email ro'yxatini kiritish: Enter yoki vergul bilan qo'shish, paste, takliflar, tekshiruv va joyida tahrirlash.
- React
- TypeScript
'use client';
import { TagInput } from '@akhatmirzo/ui';
export default function TagInputBasic() {
return (
<div className="w-full max-w-md">
<TagInput
defaultValue={['React', 'TypeScript']}
placeholder="Teg qo'shing"
aria-label="Teglar"
/>
</div>
);
}
Import
import { TagInput } from '@akhatmirzo/ui';Qachon ishlatish
- Erkin qiymatlar ro'yxati — teglar, kalit so'zlar, ko'nikmalar, bir nechta email yoki telefon.
- Variantlar oldindan ma'lum bo'lsa —
suggestionsbering: foydalanuvchi yozishni boshlaganda ro'yxat chiqadi, lekin o'z qiymatini ham qo'sha oladi. - Faqat ro'yxatdagi variantlardan tanlash kerak bo'lsa —
Combobox(multiple) to'g'riroq: u yangi qiymat yaratishga yo'l qo'ymaydi. - Bitta qiymat uchun oddiy
Inputishlating.
Field bilan
Field ichida label ichki <input> ga ulanadi, izoh va xato aria-describedby ga
tushadi. value + onValueChange — boshqariladigan rejim, defaultValue — boshqarilmaydigan.
Enter yoki vergul bilan qo'shing
- dizayn
- frontend
Qiymat: ["dizayn","frontend"]
'use client';
import { Field, TagInput } from '@akhatmirzo/ui';
import { useState } from 'react';
export default function TagInputWithField() {
const [tags, setTags] = useState(['dizayn', 'frontend']);
return (
<div className="flex w-full max-w-md flex-col gap-3">
<Field label="Kalit so'zlar" description="Enter yoki vergul bilan qo'shing">
<TagInput value={tags} onValueChange={setTags} placeholder="Kalit so'z" />
</Field>
<p className="m-0 text-sm text-text-muted">
Qiymat: <span className="font-mono text-text">{JSON.stringify(tags)}</span>
</p>
</div>
);
}
Qo'shish va o'chirish
Enteryoki,— yozilgan matn tegga aylanadi (delimitersbilan o'zgartiriladi, masalan['Enter', ',', 'Tab']). Bo'sh inputdaEnterformani odatdagidek yuboradi.- Paste:
"a, b, c"→ 3 teg. Bir belgili ajratuvchilar va (Enterbo'lsa) yangi qatorlar bo'yicha bo'linadi. - Takror teglar qo'shilmaydi — taqqoslash katta-kichik harfga qaramaydi (
allowDuplicatesbilan ruxsat beriladi). transform— matnni tegga aylantirish (standart —trim).- Teg ustiga ikki marta bosing (yoki fokusda
Enter/F2) — joyida tahrirlanadi:Entersaqlaydi,Escbekor qiladi, matnni o'chirsangiz teg olib tashlanadi.
Takliflar
suggestions berilsa, yozish paytida mos variantlar ro'yxati chiqadi. Qidiruv
normalizeUz bilan ishlaydi: kirill va lotin, apostrof variantlari farq qilmaydi — «тош» deb
yozsangiz «Toshkent» topiladi. Allaqachon qo'shilgan teglar ro'yxatda ko'rinmaydi. ↓ / ↑ bilan
tanlang, Enter qo'shadi; hech narsa ajratilmagan bo'lsa Enter yozilgan matnning o'zini qo'shadi.
maxTags — eng ko'p teglar soni. Chegaraga yetganda input yashiriladi va konteynerda data-full
paydo bo'ladi.
Ko'pi bilan 4 ta. «тош» deb yozib ko'ring
'use client';
import { Field, TagInput } from '@akhatmirzo/ui';
const cities = ['Toshkent', 'Samarqand', 'Buxoro', "Farg'ona", 'Namangan', 'Andijon', 'Xiva'];
export default function TagInputSuggestions() {
return (
<div className="w-full max-w-md">
<Field label="Shaharlar" description="Ko'pi bilan 4 ta. «тош» deb yozib ko'ring">
<TagInput suggestions={cities} maxTags={4} placeholder="Shahar yozing" />
</Field>
</div>
);
}
Tekshiruv
validate har bir yangi teg uchun chaqiriladi: true — qabul, false — standart xato
(labels.invalid), matn — o'sha xato. Rad etilgan teg qo'shilmaydi, matn inputda qoladi, xato
input ostida ko'rinadi va ekran o'quvchiga o'qiladi; input aria-invalid bo'ladi. Keyingi
o'zgarishda xato yo'qoladi.
Bir nechta emailni vergul bilan qo'ying
'use client';
import { isValidEmail } from '@akhatmirzo/core';
import { Field, TagInput } from '@akhatmirzo/ui';
export default function TagInputValidate() {
return (
<div className="w-full max-w-md">
<Field label="Qabul qiluvchilar" description="Bir nechta emailni vergul bilan qo'ying">
<TagInput
validate={(email) => isValidEmail(email) || "Email noto'g'ri"}
transform={(raw) => raw.trim().toLowerCase()}
placeholder="Email qo'shing"
/>
</Field>
</div>
);
}
Tekshiruv xatosi Field ning error prop'idan alohida — u TagInput'ning o'zida ko'rsatiladi.
Forma darajasidagi xatolarni (masalan "Kamida bitta teg kerak") Field error orqali bering.
O'lchamlar va holatlar
size — sm, md (standart), lg: Input bilan bir xil minimal balandlik (32 / 40 / 48px),
teglar ko'paysa konteyner o'sadi. disabled va readOnly holatlarida ✕ tugmalari yo'qoladi.
- sm
- md
- lg
- O'chirilgan
'use client';
import { TagInput } from '@akhatmirzo/ui';
export default function TagInputSizes() {
return (
<div className="flex w-full max-w-md flex-col gap-3">
<TagInput size="sm" defaultValue={['sm']} aria-label="Kichik" />
<TagInput defaultValue={['md']} aria-label="O'rtacha" />
<TagInput size="lg" defaultValue={['lg']} aria-label="Katta" />
<TagInput disabled defaultValue={["O'chirilgan"]} aria-label="O'chirilgan" />
</div>
);
}
Forma
name berilsa, har bir teg uchun shu nomli yashirin <input> yaratiladi:
new FormData(form).getAll('tags') → ['React', 'Vue']. PHP uslubidagi massiv kerak bo'lsa —
name="tags[]".
Props
className ildiz konteynerga, ref va qolgan <input> atributlari (placeholder, autoFocus,
onBlur ...) ichki input'ga tushadi.
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
value | string[] | — | Teglar (boshqariladigan rejim) |
defaultValue | string[] | [] | Boshlang'ich teglar |
onValueChange | (value: string[]) => void | — | Ro'yxat o'zgarganda |
delimiters | string[] | ['Enter', ','] | Tegni yakunlovchi tugmalar va belgilar ('Tab' ham mumkin) |
maxTags | number | — | Eng ko'p teglar soni |
allowDuplicates | boolean | false | Takror teglar (katta-kichik harf farqsiz taqqoslanadi) |
validate | (tag: string) => boolean | string | — | false yoki matn — teg qo'shilmaydi, xato ko'rsatiladi |
transform | (raw: string) => string | trim | Kiritilgan matnni tegga aylantirish |
suggestions | string[] | — | Yozishda chiqadigan takliflar (kirill/lotin farqsiz) |
size | 'sm' | 'md' | 'lg' | 'md' | Minimal balandlik 32 / 40 / 48px |
disabled | boolean | — | O'chirilgan holat |
readOnly | boolean | — | Faqat o'qish: qo'shish va o'chirish yo'q |
invalid | boolean | — | Xato holati (Field ichida avtomatik) |
name | string | — | Har bir tegga shu nomli yashirin input |
labels | { remove?; suggestions?; added?; removed?; invalid?; duplicate? } | — | Ichki matnlar (o'zbekcha standart) — quyidagi jadval |
inputClassName | string | — | Ichki `<input>` klassi |
labels
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
remove | (tag: string) => string | `${tag} ni olib tashlash` | ✕ tugmasining nomi |
suggestions | string | 'Takliflar' | Takliflar ro'yxatining nomi |
added | (tag: string) => string | `${tag} qo'shildi` | Ekran o'quvchi uchun e'lon |
removed | (tag: string) => string | `${tag} olib tashlandi` | Ekran o'quvchi uchun e'lon |
invalid | (tag: string) => string | `«${tag}» qabul qilinmadi` | `validate` false qaytarganda |
duplicate | (tag: string) => string | `«${tag}» allaqachon qo'shilgan` | Takror teg |
Data atributlari
| Atribut | Qayerda | Qiymat |
|---|---|---|
data-size | konteyner | sm · md · lg |
data-full | konteyner | maxTags ga yetganda mavjud |
data-invalid | konteyner | xato (yoki tekshiruv xatosi) |
data-disabled | konteyner | o'chirilganda mavjud |
data-readonly | konteyner | readOnly da mavjud |
data-slot | qismlar | tag-input · tag-input-root |
Klaviatura
| Tugma | Harakat |
|---|---|
Enter / , | Yozilgan matnni teg qilish |
Backspace (bo'sh inputda) | Oxirgi tegni tanlash; yana bosish — o'chirish |
← (input boshida) | Oxirgi tegga o'tish |
← / → (tegda) | Teglar orasida yurish; oxirgisidan → — input'ga |
Backspace / Delete (tegda) | Tegni o'chirish |
Enter / F2 (tegda) | Tegni tahrirlash |
Esc (tegda) | Input'ga qaytish |
↓ / ↑ | Takliflar orasida yurish (suggestions bo'lsa) |
Esc | Takliflar ro'yxatini yopish |
Accessibility
- Ro'yxat. Teglar
<ul role="list">ichida — ekran o'quvchi teglar sonini aytadi. - E'lonlar. Qo'shish va o'chirish
aria-live="polite"ko'rinmas hududda e'lon qilinadi ("React qo'shildi", "React olib tashlandi"); matnlarlabels.added/labels.removed. - Xato. Tekshiruv xatosi ko'rinadigan matn,
aria-livehududda; input'gaaria-invalidvaaria-describedbyorqali ulanadi. - Takliflar.
suggestionsbo'lsa inputrole="combobox"(aria-expanded,aria-controls,aria-activedescendant), ro'yxat —role="listbox". Fokus doim input'da qoladi. - ✕ tugmalari —
aria-label="React ni olib tashlash", bosish maydoni kamida 40px. - Teglar strelkalar bilan fokuslanadi (
tabIndex={-1}); ✕ tugmalarigaTabbilan ham o'tish mumkin.