Select
Stilli bir listeden tek bir seçenek seç.
import { Select } from "@merid/react";
export function Example() {
return (
<>
<span id="region-label">Bölge</span>
<Select.Root defaultValue="eu-west" name="region" placeholder="Seç…">
<Select.Trigger aria-labelledby="region-label" />
<Select.Content>
<Select.Item value="us-east">ABD Doğu</Select.Item>
<Select.Item value="us-west">ABD Batı</Select.Item>
<Select.Item value="eu-west">AB Batı</Select.Item>
<Select.Item value="ap-south" disabled>
Asya Pasifik (yakında)
</Select.Item>
</Select.Content>
</Select.Root>
</>
);
}Import
import { Select } from "@merid/react";Anatomi
<Select.Root>
<Select.Trigger />
<Select.Content>
<Select.Item value="a">A</Select.Item>
</Select.Content>
</Select.Root>- Root değeri ve açık state'ini tutar;
nameverildiğinde gizli bir<input>render'lar. - Trigger,
role="combobox"butonudur. Seçili etiketi ya da placeholder'ı gösterir. - Content, portal ile render'lanan
role="listbox"elemanıdır. Seçenekler etiketlerini bildirebilsin diye (gizli olarak) mount'lu kalır. - Item, tek bir
role="option"elemanıdır. Metin children'ı etikettir; tetikleyicide gösterilir ve yazarak arama (typeahead) için kullanılır.
Örnekler
Controlled
value ve onValueChange ver. Boş string hiçbir şeyin seçili olmadığı anlamına gelir ve placeholder gösterilir.
const [plan, setPlan] = useState("");
<Select.Root value={plan} onValueChange={setPlan} placeholder="Paket seç">
<Select.Trigger aria-label="Paket" invalid={plan === ""} />
<Select.Content>
<Select.Item value="starter">Başlangıç</Select.Item>
<Select.Item value="team">Ekip</Select.Item>
<Select.Item value="enterprise">Kurumsal</Select.Item>
</Select.Content>
</Select.Root>Boyutlar ve devre dışı
<Select.Trigger size="sm" aria-label="Sıklık" />
<Select.Trigger size="md" aria-label="Sıklık" />
<Select.Trigger size="lg" aria-label="Sıklık" />
<Select.Root disabled placeholder="Devre dışı">
<Select.Trigger aria-label="Devre dışı select" />
<Select.Content>
<Select.Item value="x">Kullanılamıyor</Select.Item>
</Select.Content>
</Select.Root>Form içinde
Root'a name (istersen required ve form da) ver. Gönderimde değeri gizli bir input taşır.
<form>
<Select.Root name="region" required>
<Select.Trigger aria-label="Bölge" />
<Select.Content>…</Select.Content>
</Select.Root>
</form>API referansı
Root
| Prop | Tip | Varsayılan | Açıklama |
|---|---|---|---|
value | string | – | Controlled seçili değer ("" hiçbir şeyin seçili olmadığı anlamına gelir). |
defaultValue | string | "" | Uncontrolled kullanımda başlangıç değeri. |
onValueChange | (value: string) => void | – | Yeni seçilen değerle çağrılır. |
open | boolean | – | Controlled açık state'i. |
defaultOpen | boolean | false | Uncontrolled kullanımda başlangıçtaki açık state'i. |
onOpenChange | (open: boolean) => void | – | Açık state'i değişmesi gerektiğinde çağrılır. |
name | string | – | Form alanı adı; değeri taşıyan gizli bir input render'lar. |
required | boolean | – | Gizli input'u zorunlu olarak işaretler. |
disabled | boolean | false | Select'in tamamını devre dışı bırakır. |
placeholder | ReactNode | "Select…" | Değer seçilmemişken tetikleyicide gösterilir. Türkçe arayüzde Türkçe bir değer ver, örneğin "Seç…". |
form | string | – | Gizli input'u id ile bir forma bağlar. |
children | ReactNode | – | Trigger ve Content. |
Trigger
value dışındaki tüm <button> attribute'larını kabul eder. Children verilirse gösterilen etiketin yerine geçer. Verdiğin id korunur (böylece <label htmlFor> çalışır) ve listbox bu id ile etiketlenmeye devam eder. Bir Field içinde tetikleyici, her Merid kontrolü gibi bağlantıları devralır: field'ın id'si ve etiketi (aria-labelledby), açıklama ve hata için aria-describedby, aria-invalid + data-invalid, aria-required ve disabled. Açıkça verilen prop'lar önceliklidir.
| Prop | Tip | Varsayılan | Açıklama |
|---|---|---|---|
size | "sm" | "md" | "lg" | "md" | Kontrol boyutu. |
invalid | boolean | – | Alanı geçersiz olarak işaretler: anlam için `aria-invalid`, danger kenarlığı için `data-invalid`. Field içindeyse onun error değerinden türetilir. |
ref | Ref<HTMLButtonElement> | – | Combobox butonuna iletilen ref. |
Content
Tüm <div> attribute'larını kabul eder. Listbox, tetikleyicinin genişliğini alır.
| Prop | Tip | Varsayılan | Açıklama |
|---|---|---|---|
placement | Placement | "bottom-start" | Tercih edilen konum. |
sideOffset | number | 6 | Tetikleyiciye px cinsinden uzaklık. |
container | Element | null | document.body | Portal hedefi. `undefined` verilirse `document.body` kullanılır; `null` verilirse hedef oluşana kadar hiçbir şey render'lanmaz. |
ref | Ref<HTMLDivElement> | – | Listbox'a iletilen ref. |
Item
children dışındaki tüm <div> attribute'larını kabul eder. Senin onClick ve onPointerMove handler'ların önce çalışır; seçeneği seçmeyi ya da vurgulamayı atlamak için içlerinde event.preventDefault() çağır.
| Prop | Tip | Varsayılan | Açıklama |
|---|---|---|---|
valueZorunlu | string | – | Form ile gönderilen ve onValueChange ile bildirilen değer. |
childrenZorunlu | string | – | Görünür etiket. Tetikleyicide ve yazarak aramada da kullanılır. |
disabled | boolean | false | Seçeneği devre dışı bırakır. |
Stil verme
| Sınıf | Eleman |
|---|---|
.mrd-select__trigger | Trigger |
.mrd-select__value, .mrd-select__icon | Tetikleyici etiketi ve chevron |
.mrd-select__content | Listbox |
.mrd-select__item, .mrd-select__item-text, .mrd-select__check | Seçenek, metni, seçili işareti |
| Attribute | Nerede | Değerler |
|---|---|---|
data-state | Trigger, Content | open, closed |
data-size | Trigger | sm, md, lg |
data-placeholder | Trigger | değer seçilmemişken bulunur |
data-invalid | Trigger | geçersizken bulunur (danger kenarlığını sağlar) |
data-active | Item | klavye ya da işaretçiyle vurgulanan seçenekte bulunur |
data-disabled | Item | devre dışıyken bulunur |
aria-selected="true" | Item | seçili seçenek |
Tetikleyici yüksekliği, data-size değerine göre ayarlanan --mrd-select-height değişkeninden gelir.
Erişilebilirlik
WAI-ARIA Select-Only Combobox desenini izler. Focus tetikleyicide kalır; vurgulanan seçenek aria-activedescendant ile bildirilir. Tetikleyiciye aria-label, aria-labelledby ya da bir <label htmlFor> tarafından gösterilen bir id ile erişilebilir bir ad ver.
| Tuş | Ne yapar |
|---|---|
| Enter | Açar ya da vurgulanan seçeneği seçip kapatır. |
| Space | Açar ya da vurgulanan seçeneği seçip kapatır. |
| ArrowDown | Açar ya da sonraki seçeneği vurgular. |
| ArrowUp | Açar ya da önceki seçeneği vurgular. |
| Home | İlk seçeneği vurgular. |
| End | Son seçeneği vurgular. |
| A–Z | Yazarak arama. Kapalıyken eşleşeni doğrudan seçer. |
| Tab | Vurgulanan seçeneği seçer, kapatır ve focus'u sonrakine taşır. |
| Escape | Değeri değiştirmeden kapatır. |
Kullanım ilkeleri
Yap
Select'i, listenin kendisinin tanıdık olduğu 5–15 seçenek için kullan (ülkeler, bölgeler, paketler).
Kaçın
İki üç seçenek için Select kullanmak. Onları Radio ya da bir SegmentedControl olarak göster.
Yap
Tetikleyiciyi her zaman görünür bir etiketle birlikte kullan.
Kaçın
Tek etiket olarak placeholder'a güvenmek; bir değer seçildiği anda kaybolur.
İlgili sayfalar
- NativeSelect: platformun
<select>elemanı; mobilde ve uzun listelerde en iyisi. - DropdownMenu: değerler için değil, aksiyonlar için.
- Field: bir kontrolün çevresinde etiket, ipucu ve hata.