Bu eski versiya hujjati
Siz v0.2 hujjatini o'qiyapsiz. Eng so'nggi versiya — v0.3.
DropdownMenu
Amallar menyusi: ikonkalar, klaviatura yorliqlari, belgilash elementlari va ichki menyular.
'use client';
import { Button, DropdownMenu, toast } from '@akhatmirzo/ui';
import { Archive, ChevronDown, Copy, Pencil, Trash2 } from 'lucide-react';
export default function DropdownMenuBasic() {
return (
<DropdownMenu>
<DropdownMenu.Trigger asChild>
<Button variant="outline" rightIcon={<ChevronDown />}>
Amallar
</Button>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item
icon={<Pencil />}
shortcut={['mod', 'E']}
onSelect={() => toast('Tahrirlash')}
>
Tahrirlash
</DropdownMenu.Item>
<DropdownMenu.Item
icon={<Copy />}
shortcut={['mod', 'D']}
onSelect={() => toast('Nusxa olindi')}
>
Nusxa olish
</DropdownMenu.Item>
<DropdownMenu.Item icon={<Archive />} onSelect={() => toast('Arxivlandi')}>
Arxivlash
</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={<Trash2 />} variant="danger" onSelect={() => toast("O'chirildi")}>
O'chirish
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}
Import
import { DropdownMenu } from '@akhatmirzo/ui';Qachon ishlatish
- Bir obyekt ustidagi amallar — jadval qatoridagi "⋯" tugmasi, kartochka menyusi, profil menyusi.
- Ko'rinish sozlamalari —
CheckboxItem(qaysi ustunlar ko'rinsin) vaRadioGroup(saralash tartibi). - Qiymat tanlash uchun emas. Forma maydoni kerak bo'lsa —
SelectyokiCombobox: ular qiymatni saqlaydi va formaga yuboradi. - Xavfli amal (
variant="danger") menyuning oxirida, ajratgichdan keyin tursin; kerak bo'lsa,confirm()bilan tasdiqlating. - Ichki menyuni bir darajadan chuqur qilmang — klaviatura bilan ham, telefonda ham noqulay.
Tuzilishi
| Qism | Vazifasi |
|---|---|
DropdownMenu | Holat: open, defaultOpen, onOpenChange |
DropdownMenu.Trigger | Ochuvchi. asChild siz — outline tugma ko'rinishida |
DropdownMenu.Content | Panel: portal, joylashuv, aylanma navigatsiya |
DropdownMenu.Item | Amal: icon, shortcut, variant, onSelect |
DropdownMenu.CheckboxItem | Yoqib-o'chiriladigan element (✓) |
DropdownMenu.RadioGroup / RadioItem | Bir nechtadan bittasini tanlash (●) |
DropdownMenu.Label | Guruh sarlavhasi |
DropdownMenu.Group | Elementlarni mantiqiy guruhlash |
DropdownMenu.Separator | Ajratgich chiziq |
DropdownMenu.Sub / SubTrigger / SubContent | Ichki menyu |
Belgilash elementlari
CheckboxItem — checked / onCheckedChange, RadioGroup — value / onValueChange
(yoki boshqarilmaydigan defaultValue). Tanlovdan keyin menyu yopiladi; bir nechtasini ketma-ket
belgilash uchun onSelect ichida e.preventDefault() chaqiring.
'use client';
import { DropdownMenu } from '@akhatmirzo/ui';
import { useState } from 'react';
export default function DropdownMenuCheckboxRadio() {
const [columns, setColumns] = useState({ price: true, stock: true, sku: false });
const [sort, setSort] = useState('new');
return (
<div className="flex flex-wrap items-center gap-3">
<DropdownMenu>
<DropdownMenu.Trigger>Ustunlar</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Label>Jadvalda ko'rsatish</DropdownMenu.Label>
{(
[
['price', 'Narx'],
['stock', 'Ombordagi soni'],
['sku', 'Artikul'],
] as const
).map(([key, label]) => (
<DropdownMenu.CheckboxItem
key={key}
checked={columns[key]}
onCheckedChange={(on) => setColumns((c) => ({ ...c, [key]: on }))}
// Menyu yopilmasin — bir nechtasini ketma-ket belgilash uchun
onSelect={(e) => e.preventDefault()}
>
{label}
</DropdownMenu.CheckboxItem>
))}
</DropdownMenu.Content>
</DropdownMenu>
<DropdownMenu>
<DropdownMenu.Trigger>Saralash</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Label>Tartib</DropdownMenu.Label>
<DropdownMenu.RadioGroup value={sort} onValueChange={setSort}>
<DropdownMenu.RadioItem value="new">Avval yangilari</DropdownMenu.RadioItem>
<DropdownMenu.RadioItem value="cheap">Avval arzonlari</DropdownMenu.RadioItem>
<DropdownMenu.RadioItem value="expensive">Avval qimmatlari</DropdownMenu.RadioItem>
<DropdownMenu.RadioItem value="popular" disabled>
Ommabop (tez orada)
</DropdownMenu.RadioItem>
</DropdownMenu.RadioGroup>
</DropdownMenu.Content>
</DropdownMenu>
<span className="text-sm text-text-muted">Saralash: {sort}</span>
</div>
);
}
Ichki menyu
Sub ichida SubTrigger va SubContent. Sichqoncha bilan ustiga borganda, klaviatura bilan
→ bosganda ochiladi.
'use client';
import { DropdownMenu, IconButton } from '@akhatmirzo/ui';
import { Archive, Ellipsis, Pencil, Share2, Trash2 } from 'lucide-react';
export default function DropdownMenuSubmenu() {
return (
<DropdownMenu>
<DropdownMenu.Trigger asChild>
<IconButton variant="outline" aria-label="Ko'proq amallar">
<Ellipsis />
</IconButton>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item icon={<Pencil />}>Nomini o'zgartirish</DropdownMenu.Item>
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger icon={<Share2 />}>Ulashish</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Item>Telegram</DropdownMenu.Item>
<DropdownMenu.Item>Email orqali</DropdownMenu.Item>
<DropdownMenu.Item shortcut={['mod', 'L']}>Havolani nusxalash</DropdownMenu.Item>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger icon={<Archive />}>Ko'chirish</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Item>Kiruvchi</DropdownMenu.Item>
<DropdownMenu.Item>Arxiv</DropdownMenu.Item>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={<Trash2 />} variant="danger">
O'chirish
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}
Profil menyusi: Label, Group va havola
Label va Group menyuni bo'limlarga ajratadi. Item ga asChild berib, <a> (yoki Next.js
Link) ni element sifatida ishlatasiz — ikonka va yorliq havolaning ichiga qo'shiladi.
align="end" panelni triggerning o'ng chetiga tekislaydi.
'use client';
import { Button, DropdownMenu } from '@akhatmirzo/ui';
import { LogOut, Send, Settings, User } from 'lucide-react';
export default function DropdownMenuProfile() {
return (
<DropdownMenu>
<DropdownMenu.Trigger asChild>
<Button variant="ghost" leftIcon={<User />}>
Akmal Karimov
</Button>
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end" className="w-56">
<DropdownMenu.Label>akmal@misol.uz</DropdownMenu.Label>
<DropdownMenu.Group>
<DropdownMenu.Item icon={<User />} shortcut={['mod', 'P']}>
Profil
</DropdownMenu.Item>
<DropdownMenu.Item icon={<Settings />} shortcut={['mod', ',']}>
Sozlamalar
</DropdownMenu.Item>
<DropdownMenu.Item asChild icon={<Send />}>
<a href="https://github.com/Akhatmirzo/akhatmirzo-toolkit">Loyiha GitHub'da</a>
</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={<LogOut />} variant="danger">
Chiqish
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
}
<DropdownMenu.Item asChild icon={<Settings />}>
<Link href="/sozlamalar">Sozlamalar</Link>
</DropdownMenu.Item>shortcut — faqat yorliq
shortcut={['mod', 'E']} menyuda ⌘E (Windows'da Ctrl E) ko'rsatadi va aria-keyshortcuts
qo'yadi, lekin tugma bosilishini ushlamaydi. Qisqa yo'lning o'zini
useHotkeys bilan ulang.
Holatlar
disabled element bosilmaydi va klaviatura navigatsiyasida o'tkazib yuboriladi. Trigger ham
disabled bo'lishi mumkin. open + onOpenChange bilan menyuni koddan ochasiz.
'use client';
import { Button, DropdownMenu } from '@akhatmirzo/ui';
import { Copy, Pencil, Trash2 } from 'lucide-react';
import { useState } from 'react';
export default function DropdownMenuStates() {
const [open, setOpen] = useState(false);
return (
<div className="flex flex-wrap items-center gap-3">
<DropdownMenu>
<DropdownMenu.Trigger>O'chirilgan elementlar</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item icon={<Pencil />}>Tahrirlash</DropdownMenu.Item>
<DropdownMenu.Item icon={<Copy />} disabled>
Nusxa olish (ruxsat yo'q)
</DropdownMenu.Item>
<DropdownMenu.Item icon={<Trash2 />} variant="danger" disabled>
O'chirish (ruxsat yo'q)
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
<DropdownMenu open={open} onOpenChange={setOpen}>
<DropdownMenu.Trigger>Boshqariladigan</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Item>Birinchi</DropdownMenu.Item>
<DropdownMenu.Item>Ikkinchi</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
<Button variant="ghost" onClick={() => setOpen(true)}>
Tashqaridan ochish
</Button>
</div>
);
}
Props
DropdownMenu
Radix DropdownMenu Root prop'larini qabul qiladi: open, defaultOpen, onOpenChange,
modal (standart — true), dir.
DropdownMenu.Content
Radix Content ning qolgan prop'lari (alignOffset, onCloseAutoFocus, onEscapeKeyDown ...)
va <div> atributlari ham qabul qilinadi.
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
side | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | Qaysi tomonda ochiladi |
align | 'start' | 'center' | 'end' | 'start' | Trigger bo'ylab tekislash |
sideOffset | number | 6 | Triggerdan masofa, px |
collisionPadding | number | 8 | Ekran chetidan minimal masofa, px |
loop | boolean | true | ↑ ↓ oxiridan boshiga aylanadi |
container | HTMLElement | null | — | Portal konteyneri (standart — document.body) |
DropdownMenu.Item
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
icon | ReactNode | — | Chapdagi ikonka (16px) |
shortcut | string[] | — | O'ngdagi Kbd yorlig'i, masalan ['mod', 'E'] |
variant | 'default' | 'danger' | 'default' | danger — qizil matn va fon |
onSelect | (event: Event) => void | — | Tanlanganda. preventDefault() — menyu ochiq qoladi |
disabled | boolean | — | Elementni o'chiradi |
textValue | string | — | Typeahead uchun matn (children matn bo'lmasa) |
asChild | boolean | false | Bolani (masalan, <a>) element sifatida chizadi |
CheckboxItem, RadioGroup, RadioItem
| Prop | Tip | Standart | Tavsif |
|---|---|---|---|
checked | boolean | 'indeterminate' | — | CheckboxItem: belgilanganmi |
onCheckedChange | (checked: boolean) => void | — | CheckboxItem: o'zgarganda |
value | string | — | RadioGroup: tanlangan qiymat; RadioItem: qiymati |
defaultValue | string | — | RadioGroup: boshlang'ich qiymat |
onValueChange | (value: string) => void | — | RadioGroup: o'zgarganda |
shortcut | string[] | — | CheckboxItem va RadioItem: o'ngdagi Kbd |
disabled | boolean | — | CheckboxItem va RadioItem: o'chiradi |
Sub, SubTrigger, SubContent
Sub — open, defaultOpen, onOpenChange. SubTrigger — icon va disabled.
SubContent — sideOffset (standart 8), alignOffset (-6), collisionPadding (8),
loop (true) va container.
Data atributlari
| Atribut | Qayerda | Qiymat |
|---|---|---|
data-state | trigger, panel | open · closed |
data-variant | element | default · danger |
data-highlighted | element | klaviatura yoki sichqoncha ustida |
data-disabled | element | o'chirilganda mavjud |
data-state | Checkbox/RadioItem | checked · unchecked |
data-side | panel | top · right · bottom · left |
Klaviatura
| Tugma | Harakat |
|---|---|
Enter / Space / ↓ | Trigger fokusda — ochadi, fokus birinchi elementga |
↓ / ↑ | Elementlar bo'ylab yurish (aylanma) |
Home / End | Birinchi / oxirgi element |
| Harf | Shu harf bilan boshlanadigan elementga sakrash |
→ / ← | Ichki menyuni ochish / yopish |
Enter / Space | Tanlash va yopish |
Esc | Yopish, fokus triggerga qaytadi |
Accessibility
- Rollar. Panel —
role="menu", elementlar —menuitem,menuitemcheckbox,menuitemradio; triggeraria-haspopup="menu"vaaria-expandedoladi. Asosida Radix DropdownMenu. - Qisqa yo'llar.
shortcutberilsa, elementgaaria-keyshortcutsqo'yiladi (mod— macOS'daMeta, boshqa tizimlardaControl). Ko'rinadiganKbdesa ekran o'quvchidan yashirin. - Ikonkalar
aria-hidden. - Ikonka trigger.
IconButtontrigger bo'lsa,aria-labelyozing ("Ko'proq amallar"). - Fokus. Ochilganda fokus menyuga o'tadi, yopilgach triggerga qaytadi.