SegmentedControl
Bir nechta variantdan bittasini tanlash: suriluvchi indikator, ikonkalar, Button bilan bir xil o'lchamlar.
'use client';
import { SegmentedControl } from '@akhatmirzo/ui';
export default function SegmentedControlBasic() {
return (
<SegmentedControl defaultValue="month" aria-label="Davr">
<SegmentedControl.Item value="day">Kun</SegmentedControl.Item>
<SegmentedControl.Item value="week">Hafta</SegmentedControl.Item>
<SegmentedControl.Item value="month">Oy</SegmentedControl.Item>
<SegmentedControl.Item value="year">Yil</SegmentedControl.Item>
</SegmentedControl>
);
}
Import
import { SegmentedControl } from '@akhatmirzo/ui';Qachon ishlatish
- Ko'rinish rejimi — "Katakli / Ro'yxat / Xarita". Tanlov darhol qo'llanadi.
- Filtr yoki davr — "Kun / Hafta / Oy", "Hammasi / To'langan / Qarz".
- Variantlar 2–5 ta va qisqa bo'lsin. Ko'p yoki uzun bo'lsa —
SelectyokiRadioGroup. - Yoqish/o'chirish uchun emas — ikki holatli sozlamaga
Switchmos.
Tabs'dan farqi
Ikkalasi ham bir xil ko'rinishi mumkin, lekin vazifasi boshqa:
Tabs | SegmentedControl | |
|---|---|---|
| Nima qiladi | Kontent panellarini almashtiradi | Qiymat tanlaydi (filtr, rejim, davr) |
| Semantika | tablist / tab / tabpanel | radiogroup / radio |
| Natija | Sahifaning boshqa bo'limi ko'rinadi | Mavjud kontent qayta filtrlanadi yoki chiziladi |
| Forma | Yo'q | name bilan forma qiymati bo'ladi |
Qoida: tanlovdan keyin boshqa kontent paydo bo'lsa — Tabs; o'sha kontent
boshqacha ko'rinsa yoki filtrlansa — SegmentedControl.
O'lchamlar
size — sm (32px), md (40px, standart), lg (48px). Balandliklar Button va
Input bilan bir xil, shuning uchun bir qatorda tekis turadi.
'use client';
import { Button, SegmentedControl } from '@akhatmirzo/ui';
const sizes = ['sm', 'md', 'lg'] as const;
export default function SegmentedControlSizes() {
return (
<div className="flex flex-col items-start gap-4">
{sizes.map((size) => (
<div key={size} className="flex items-center gap-3">
<SegmentedControl size={size} defaultValue="all" aria-label={`Holat, ${size}`}>
<SegmentedControl.Item value="all">Hammasi</SegmentedControl.Item>
<SegmentedControl.Item value="paid">To'langan</SegmentedControl.Item>
<SegmentedControl.Item value="debt">Qarz</SegmentedControl.Item>
</SegmentedControl>
<Button size={size} variant="outline">
Eksport
</Button>
</div>
))}
</div>
);
}
Ikonkalar
icon — matn oldidagi ikonka. Faqat ikonkali elementda aria-label majburiy — TypeScript
uni talab qiladi.
'use client';
import { SegmentedControl } from '@akhatmirzo/ui';
import { LayoutGrid, List, MapIcon } from 'lucide-react';
export default function SegmentedControlIcons() {
return (
<div className="flex flex-wrap items-center gap-4">
<SegmentedControl defaultValue="grid" aria-label="Ko'rinish">
<SegmentedControl.Item value="grid" icon={<LayoutGrid />} aria-label="Katakli" />
<SegmentedControl.Item value="list" icon={<List />} aria-label="Ro'yxat" />
<SegmentedControl.Item value="map" icon={<MapIcon />} aria-label="Xarita" />
</SegmentedControl>
<SegmentedControl defaultValue="list" aria-label="Ko'rinish">
<SegmentedControl.Item value="grid" icon={<LayoutGrid />}>
Katakli
</SegmentedControl.Item>
<SegmentedControl.Item value="list" icon={<List />}>
Ro'yxat
</SegmentedControl.Item>
</SegmentedControl>
</div>
);
}
To'liq kenglik
fullWidth — konteyner kengligini egallaydi, elementlar teng bo'linadi. Mobil formalarda qulay.
'use client';
import { SegmentedControl } from '@akhatmirzo/ui';
export default function SegmentedControlFullWidth() {
return (
<div className="w-full max-w-sm">
<SegmentedControl fullWidth defaultValue="delivery" aria-label="Olib ketish usuli">
<SegmentedControl.Item value="delivery">Yetkazib berish</SegmentedControl.Item>
<SegmentedControl.Item value="pickup">Olib ketish</SegmentedControl.Item>
</SegmentedControl>
</div>
);
}
Boshqariladigan rejim
value + onValueChange — tanlovni o'zingiz saqlaysiz. Tanlangan elementni qayta bosish
tanlovni bekor qilmaydi — doim bitta qiymat tanlangan bo'ladi.
Savdo: 8 740 000 so'm
'use client';
import { SegmentedControl } 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",
};
export default function SegmentedControlControlled() {
const [period, setPeriod] = useState('week');
return (
<div className="flex flex-col items-start gap-3">
<SegmentedControl value={period} onValueChange={setPeriod} aria-label="Davr">
<SegmentedControl.Item value="day">Kun</SegmentedControl.Item>
<SegmentedControl.Item value="week">Hafta</SegmentedControl.Item>
<SegmentedControl.Item value="month">Oy</SegmentedControl.Item>
</SegmentedControl>
<p className="m-0 text-sm text-text-muted">
Savdo: <span className="font-semibold text-text">{totals[period]}</span>
</p>
</div>
);
}
O'chirilgan holat
disabled butun guruhga yoki bitta SegmentedControl.Item ga beriladi. O'chirilgan element
bosilmaydi va klaviatura uni o'tkazib yuboradi.
'use client';
import { SegmentedControl } from '@akhatmirzo/ui';
export default function SegmentedControlDisabled() {
return (
<div className="flex flex-col items-start gap-4">
<SegmentedControl defaultValue="card" aria-label="To'lov usuli">
<SegmentedControl.Item value="cash">Naqd</SegmentedControl.Item>
<SegmentedControl.Item value="card">Karta</SegmentedControl.Item>
<SegmentedControl.Item value="credit" disabled>
Nasiya
</SegmentedControl.Item>
</SegmentedControl>
<SegmentedControl defaultValue="uz" disabled aria-label="Til">
<SegmentedControl.Item value="uz">O'zbekcha</SegmentedControl.Item>
<SegmentedControl.Item value="ru">Ruscha</SegmentedControl.Item>
</SegmentedControl>
</div>
);
}
Props
SegmentedControl
Qolgan <div> atributlari va Radix RadioGroup prop'lari (name, required, loop, dir) ham
qabul qilinadi; ref ildiz elementga tushadi.
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
value | string | — | Tanlangan qiymat (boshqariladigan rejim) |
defaultValue | string | — | Boshlang'ich qiymat |
onValueChange | (value: string) => void | — | Tanlov almashganda |
size | 'sm' | 'md' | 'lg' | 'md' | Balandlik: 32 / 40 / 48px |
fullWidth | boolean | false | Kenglikni egallaydi, elementlar teng bo'linadi |
disabled | boolean | — | Butun guruhni o'chiradi |
name | string | — | Forma uchun (yashirin radio input) |
aria-label | string | — | Guruh nomi (masalan, Davr yoki Ko'rinish) |
SegmentedControl.Item
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
valuemajburiy | string | — | Element qiymati |
icon | ReactNode | — | Matn oldidagi ikonka |
disabled | boolean | — | Elementni o'chiradi |
aria-label | string | — | Faqat ikonkali elementda majburiy |
Data atributlari
| Atribut | Qayerda | Qiymat |
|---|---|---|
data-size | ildiz | sm · md · lg |
data-full-width | ildiz | fullWidth da mavjud |
data-disabled | ildiz, element | o'chirilganda mavjud |
data-state | element | checked · unchecked |
data-slot | indikator | segmented-control-indicator |
Klaviatura
| Tugma | Harakat |
|---|---|
Tab | Guruhga kirish (tanlangan elementga) va guruhdan chiqish |
← ↑ / → ↓ | Oldingi / keyingi element — fokus bilan birga darhol tanlanadi |
Accessibility
- Rollar. Ildiz —
role="radiogroup", element —role="radio"(aria-checked). Asosida Radix RadioGroup: bitta tanlov, roving focus — guruhTabuchun bitta to'xtash joyi. - Nom. Guruhga
aria-labelbering ("Davr").Fieldichida label guruh nomiga aylanadi, izoharia-describedbyga ulanadi. - Faqat ikonkali element —
aria-labelmajburiy (TypeScript tekshiradi). - Indikator bezak —
aria-hidden. U tanlangan element o'lchamini o'qib, 200ms davomida siljiydi; o'lcham o'zgarsa (oyna kengligi, shrift yuklanishi) qayta hisoblanadi.prefers-reduced-motionda sakrab o'tadi.