Tabs
Bir sahifadagi bo'limlar orasida almashish: underline, pills va segmented ko'rinishlar.
'use client';
import { Tabs } from '@akhatmirzo/ui';
export default function TabsVariants() {
return (
<div className="flex w-full flex-col gap-8">
{(['underline', 'pills', 'segmented'] as const).map((variant) => (
<Tabs key={variant} defaultValue="info" variant={variant}>
<Tabs.List aria-label={`Mijoz (${variant})`}>
<Tabs.Trigger value="info">Ma'lumot</Tabs.Trigger>
<Tabs.Trigger value="orders" badge={12}>
Buyurtmalar
</Tabs.Trigger>
<Tabs.Trigger value="reviews">Sharhlar</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="info" className="text-text-muted">
Ism, telefon va yetkazib berish manzili.
</Tabs.Content>
<Tabs.Content value="orders" className="text-text-muted">
Oxirgi 12 ta buyurtma ro'yxati.
</Tabs.Content>
<Tabs.Content value="reviews" className="text-text-muted">
Mijoz hali sharh qoldirmagan.
</Tabs.Content>
</Tabs>
))}
</div>
);
}
Import
import { Tabs } from '@akhatmirzo/ui';Qachon ishlatish
- Bir mavzuning bir nechta ko'rinishi — mijoz kartasida "Ma'lumot", "Buyurtmalar", "Sharhlar". Foydalanuvchi bir vaqtda faqat bittasini ko'radi.
- Davr yoki filtrni almashtirish —
segmented("Kun / Hafta / Oy") ixcham va tushunarli. - Sahifalar orasida o'tish uchun emas. Har bir bo'lim alohida URL bo'lishi kerak bo'lsa, havolali navigatsiya yasang.
- Bo'limlarni solishtirish kerak bo'lsa — tablar noqulay: hammasini birdan ko'rsating yoki
Accordiondan foydalaning. - Tablar soni 2–7 ta bo'lgani ma'qul. Ko'p bo'lsa ham ishlaydi (gorizontal scroll), lekin ko'rinmay qolganlarini topish qiyinroq.
Tuzilishi
| Qism | Vazifasi |
|---|---|
Tabs | Holat (value, defaultValue), variant, size, orientation |
Tabs.List | Tablar qatori va siljuvchi indikator |
Tabs.Trigger | Bitta tab: value, ixtiyoriy badge, disabled |
Tabs.Content | Tabga mos panel (value bo'yicha bog'lanadi) |
<Tabs defaultValue="info">
<Tabs.List aria-label="Mijoz">
<Tabs.Trigger value="info">Ma'lumot</Tabs.Trigger>
<Tabs.Trigger value="orders" badge={12}>
Buyurtmalar
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="info">...</Tabs.Content>
<Tabs.Content value="orders">...</Tabs.Content>
</Tabs>Variantlar
| Variant | Ko'rinish |
|---|---|
underline | Faol tab ostida 2px chiziq; chiziq tabdan tabga siljib o'tadi (standart) |
pills | Faol tab yumaloq primary-soft fonda |
segmented | Kulrang konteyner ichida faol tab "kartochka" bo'lib ajraladi |
Indikator bir tabdan ikkinchisiga 200ms davomida siljiydi.
O'lchamlar
size — sm (32px) yoki md (40px, standart). segmented da ichki tab balandligi 28 / 32px.
'use client';
import { Tabs } from '@akhatmirzo/ui';
export default function TabsSizes() {
return (
<div className="flex flex-col items-start gap-4">
{(['underline', 'pills', 'segmented'] as const).map((variant) => (
<Tabs key={variant} defaultValue="all" variant={variant} size="sm">
<Tabs.List aria-label="Holat bo'yicha">
<Tabs.Trigger value="all">Hammasi</Tabs.Trigger>
<Tabs.Trigger value="active">Faol</Tabs.Trigger>
<Tabs.Trigger value="archive">Arxiv</Tabs.Trigger>
</Tabs.List>
</Tabs>
))}
</div>
);
}
Vertikal
orientation="vertical" — tablar chapda ustun bo'lib turadi, kontent o'ngda. Sozlamalar sahifalari
uchun qulay. Klaviaturada ↑ ↓ ishlaydi.
'use client';
import { Tabs } from '@akhatmirzo/ui';
export default function TabsVertical() {
return (
<Tabs defaultValue="profile" orientation="vertical" variant="pills" className="w-full">
<Tabs.List aria-label="Sozlamalar" className="w-44">
<Tabs.Trigger value="profile">Profil</Tabs.Trigger>
<Tabs.Trigger value="security">Xavfsizlik</Tabs.Trigger>
<Tabs.Trigger value="notifications" badge={3}>
Bildirishnomalar
</Tabs.Trigger>
<Tabs.Trigger value="billing" disabled>
To'lovlar
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="profile" className="text-text-muted">
Ism, familiya va profil rasmi.
</Tabs.Content>
<Tabs.Content value="security" className="text-text-muted">
Parol va ikki bosqichli tasdiqlash.
</Tabs.Content>
<Tabs.Content value="notifications" className="text-text-muted">
SMS, email va Telegram orqali bildirishnomalar.
</Tabs.Content>
</Tabs>
);
}
Ko'p tablar
Tablar sig'masa, qator gorizontal suriladi, chetlarida yumshoq "fade" paydo bo'ladi — qolgan
tablar borligini ko'rsatadi. Buni o'chirish uchun Tabs.List ga scrollable={false} bering.
'use client';
import { Tabs } from '@akhatmirzo/ui';
const months = [
'Yanvar',
'Fevral',
'Mart',
'Aprel',
'May',
'Iyun',
'Iyul',
'Avgust',
'Sentabr',
'Oktabr',
'Noyabr',
'Dekabr',
];
export default function TabsScrollable() {
return (
<div className="w-full max-w-md">
<Tabs defaultValue="Mart">
<Tabs.List aria-label="Oylar">
{months.map((m) => (
<Tabs.Trigger key={m} value={m}>
{m}
</Tabs.Trigger>
))}
</Tabs.List>
{months.map((m) => (
<Tabs.Content key={m} value={m} className="text-text-muted">
{m} oyi bo'yicha savdo hisoboti.
</Tabs.Content>
))}
</Tabs>
</div>
);
}
Hisoblagich va o'chirilgan tab
badge — tab yonidagi hisoblagich: raqam yoki istalgan ReactNode (masalan,
Badge). disabled tab bosilmaydi va klaviatura uni o'tkazib yuboradi.
'use client';
import { Badge, Tabs } from '@akhatmirzo/ui';
export default function TabsBadges() {
return (
<Tabs defaultValue="new">
<Tabs.List aria-label="Buyurtmalar holati">
<Tabs.Trigger value="new" badge={4}>
Yangi
</Tabs.Trigger>
<Tabs.Trigger
value="paid"
badge={
<Badge color="success" size="sm">
+2
</Badge>
}
>
To'langan
</Tabs.Trigger>
<Tabs.Trigger value="canceled" disabled>
Bekor qilingan
</Tabs.Trigger>
</Tabs.List>
</Tabs>
);
}
Boshqariladigan rejim
value + onValueChange — faol tabni o'zingiz saqlaysiz. Tabs.Content siz, faqat tanlagich
sifatida ham ishlatish mumkin.
Savdo: 8 740 000 so'm
'use client';
import { Tabs } from '@akhatmirzo/ui';
import { useState } from 'react';
const totals: Record<string, string> = {
day: "1 250 000 so'm",
week: "8 740 000 so'm",
month: "36 900 000 so'm",
year: "412 500 000 so'm",
};
export default function TabsControlled() {
const [period, setPeriod] = useState('week');
return (
<div className="flex flex-col items-start gap-3">
<Tabs value={period} onValueChange={setPeriod} variant="segmented">
<Tabs.List aria-label="Davr">
<Tabs.Trigger value="day">Kun</Tabs.Trigger>
<Tabs.Trigger value="week">Hafta</Tabs.Trigger>
<Tabs.Trigger value="month">Oy</Tabs.Trigger>
<Tabs.Trigger value="year">Yil</Tabs.Trigger>
</Tabs.List>
</Tabs>
<p className="m-0 text-sm text-text-muted">
Savdo: <span className="font-semibold text-text">{totals[period]}</span>
</p>
</div>
);
}
Props
Tabs
Qolgan <div> atributlari va Radix Root prop'lari (activationMode, dir) ham qabul qilinadi.
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
value | string | — | Faol tab (boshqariladigan rejim) |
defaultValue | string | — | Boshlang'ich faol tab |
onValueChange | (value: string) => void | — | Faol tab almashganda |
variant | 'underline' | 'pills' | 'segmented' | 'underline' | Ko'rinish |
size | 'sm' | 'md' | 'md' | Balandlik: 32 / 40px |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Tablar yo'nalishi |
Tabs.List
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
scrollable | boolean | true | Sig'masa — gorizontal scroll va chetlarda fade |
aria-label | string | — | Tablar guruhining nomi (tavsiya etiladi) |
loop | boolean | true | Strelkalar oxiridan boshiga aylanadi |
Tabs.Trigger
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
valuemajburiy | string | — | Tab qiymati |
badge | ReactNode | — | Yonidagi hisoblagich, masalan 12 |
disabled | boolean | — | Tabni o'chiradi |
Tabs.Content
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
valuemajburiy | string | — | Qaysi tabga tegishli |
forceMount | true | — | Yashirin paytda ham DOM'da qoldiradi |
Data atributlari
| Atribut | Qayerda | Qiymat |
|---|---|---|
data-variant | ildiz, ro'yxat | underline · pills · segmented |
data-size | ildiz, ro'yxat | sm · md |
data-orientation | barcha qismlar | horizontal · vertical |
data-state | tab, panel | active · inactive |
data-disabled | tab | o'chirilganda mavjud |
data-tabs-indicator | indikator | siljuvchi chiziq yoki fon |
Klaviatura
| Tugma | Harakat |
|---|---|
← / → (vertikalda ↑ / ↓) | Tablar bo'ylab yurish; fokus olgan tab darhol faollashadi |
Home / End | Birinchi / oxirgi tab |
Tab | Tablar qatoridan faol panelga o'tish |
Accessibility
- Rollar. Ro'yxat —
role="tablist"(aria-orientationbilan), tab —role="tab"(aria-selected,aria-controls), panel —role="tabpanel"(aria-labelledby). Asosida Radix Tabs. - Nom.
Tabs.Listgaaria-labelbering ("Mijoz", "Davr") — ekran o'quvchi guruhni shu nom bilan e'lon qiladi. - Roving focus. Tablar qatori
Tabuchun bitta to'xtash joyi; ichida strelkalar bilan yuriladi. - Fokus halqasi scroll konteyneri ichida kesilib qolmasligi uchun tab ichiga chiziladi.
- Indikator bezak —
aria-hidden.prefers-reduced-motionda u siljimasdan o'tadi.