Ana içeriğe atla

CSS-only Tailwind CSS combobox with live search filtering and accessible dropdown list. Keyboard navigation, color variants. WCAG AA accessible, works with Django, HTMX, Laravel, React, and any stack.

Combobox, bir metin girişini bir açılır listeyle birleştirir. Alan için input bileşenini kullanın; boyut, renk ve durum değişkenleri buradan gelir. combobox-* yardımcı programları yalnızca açılır listeyi, öğeleri ve açık durumu yönetir.

Yalnızca CSS, JavaScript gerekmez. WCAG AA erişilebilir ve çerçeveden bağımsız — Django, HTMX, Laravel, React ve tüm yığınlarla çalışır.

Sınıf Tip Tanım
combobox-listTemelBirleşik giriş kutusu seçenekleri için açılır liste kapsayıcısı
combobox-itemDeğiştiriciAçılır listedeki bireysel seçenek
combobox-openDeğiştiriciPaketleyiciye uygulandığında açılır listeyi gösterir
combobox-primaryRenkÖğeler için birincil tema rengi vurgusu
combobox-secondaryRenkÖğeler için ikincil tema rengi vurgusu
combobox-accentRenkÖğeler için vurgulu tema rengi vurgusu
combobox-infoRenkBilgi anlamsal renk vurgusu
combobox-successRenkBaşarı anlamsal renk vurgusu
combobox-warningRenkUyarı anlamsal renk vurgusu
combobox-errorRenkAnlamsal renk vurgulama hatası

Temel Kullanım

Bir giriş ve bir combobox-list'i göreli kapsayıcıya sarın. Listeyi göstermek için sarıcıya combobox-open ekleyin; JS veya :focus-with aracılığıyla değiştirin.

  • React
  • Vue
  • Angular
  • Svelte
1
2
3
4
5
6
7
8
9
<div class="relative w-64 combobox-open">
  <input type="text" class="input w-full" placeholder="Search or select...">
  <ul class="combobox-list">
    <li class="combobox-item">React</li>
    <li class="combobox-item combobox-item-active">Vue</li>
    <li class="combobox-item">Angular</li>
    <li class="combobox-item">Svelte</li>
  </ul>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { useCombobox } from 'frutjam/react'

const frameworks = ['React', 'Vue', 'Angular', 'Svelte']

export default function ComboboxDemo() {
  const combo = useCombobox({ items: frameworks })
  return (
    <div {...combo.containerProps} className="relative w-64">
      <input {...combo.inputProps} className="input w-full" placeholder="Search or select..." />
      <ul className="combobox-list" role="listbox">
        {combo.filtered.map((item, i) => (
          <li key={item} {...combo.optionProps(item, i)} className="combobox-item">{item}</li>
        ))}
      </ul>
    </div>
  )
}

Odaklandığında Aç

Giriş odaklandığında listeyi açmak için sarmalayıcıda focus-within:combobox-open komutunu kullanın; JavaScript gerekmez.

  • React
  • Vue
  • Angular
  • Svelte
html
1
2
3
4
5
6
7
8
9
<div class="relative w-64 focus-within:combobox-open">
  <input type="text" class="input w-full" placeholder="Focus to open...">
  <ul class="combobox-list">
    <li class="combobox-item">React</li>
    <li class="combobox-item">Vue</li>
    <li class="combobox-item">Angular</li>
    <li class="combobox-item">Svelte</li>
  </ul>
</div>

Boyutlar

Giriş alanında input-sm, input-lg vb.'yi kullanın. Açılır menü doğal olarak uyum sağlar.

  • Banana
  • Mango
  • Papaya
  • Banana
  • Mango
  • Papaya
html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<div class="relative w-64 combobox-open">
  <input type="text" class="input input-sm w-full" placeholder="Small">
  <ul class="combobox-list">
    <li class="combobox-item">Banana</li>
    <li class="combobox-item combobox-item-active">Mango</li>
    <li class="combobox-item">Papaya</li>
  </ul>
</div>
<div class="relative w-64 combobox-open">
  <input type="text" class="input input-lg w-full" placeholder="Large">
  <ul class="combobox-list">
    <li class="combobox-item">Banana</li>
    <li class="combobox-item combobox-item-active">Mango</li>
    <li class="combobox-item">Papaya</li>
  </ul>
</div>

Renkler

Alan renginin girişinde input-primary vb. kullanın. Etkin öğe vurgusunu renklendirmek için eşleşen combobox-primary'i sarmalayıcıya ekleyin.

  • React
  • Vue
  • Angular
  • React
  • Vue
  • Angular
html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<div class="relative w-64 combobox-open combobox-primary">
  <input type="text" class="input input-primary w-full" placeholder="Primary">
  <ul class="combobox-list">
    <li class="combobox-item">React</li>
    <li class="combobox-item combobox-item-active">Vue</li>
    <li class="combobox-item">Angular</li>
  </ul>
</div>
<div class="relative w-64 combobox-open combobox-error">
  <input type="text" class="input input-error w-full" placeholder="Error">
  <ul class="combobox-list">
    <li class="combobox-item">React</li>
    <li class="combobox-item combobox-item-active">Vue</li>
    <li class="combobox-item">Angular</li>
  </ul>
</div>

Engelli

html
1
2
3
<div class="relative w-64">
  <input type="text" class="input w-full" placeholder="Disabled" disabled>
</div>

Düğmeli

Bir arama simgesi veya tetikleme düğmesi eklemek için join ile oluşturun.

🔍
  • React
  • Vue
  • Angular
  • Svelte
html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<div class="relative w-64 combobox-open">
  <div class="join w-full">
    <span class="join-item btn btn-soft">🔍</span>
    <input type="text" class="input join-item" placeholder="Search...">
  </div>
  <ul class="combobox-list">
    <li class="combobox-item">React</li>
    <li class="combobox-item combobox-item-active">Vue</li>
    <li class="combobox-item">Angular</li>
    <li class="combobox-item">Svelte</li>
  </ul>
</div>

Bağlantı veya Düğme Olarak Öğeler

combobox-item herhangi bir öğe üzerinde çalışır — <li>, <a> veya <button>.

html
1
2
3
4
5
6
7
8
<div class="relative w-64 combobox-open">
  <input type="text" class="input w-full" placeholder="Search pages...">
  <ul class="combobox-list">
    <a href="#" class="combobox-item">Home</a>
    <a href="#" class="combobox-item combobox-item-active">About</a>
    <button class="combobox-item">Contact</button>
  </ul>
</div>

JS ve Tepki Yardımcısı

Filtreleme, klavye navigasyonu (↑ ↓ Enter Escape) ve tam aria-* kablolamayı kutudan çıkarmak için frutjam/js'den createCombobox'u veya frutjam/react'tan useCombobox'u kullanın. Seçimi işlemek için fj:select olayını dinleyin.

  • React
  • Vue
  • Angular
  • Svelte
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<div class="relative w-64" id="js-combobox">
  <input type="text" class="input w-full" placeholder="Search frameworks...">
  <ul class="combobox-list">
    <li class="combobox-option" data-value="react">React</li>
    <li class="combobox-option" data-value="vue">Vue</li>
    <li class="combobox-option" data-value="angular">Angular</li>
    <li class="combobox-option" data-value="svelte">Svelte</li>
  </ul>
</div>
<script type="module">
  import { createCombobox } from 'frutjam/js'
  const combo = createCombobox(document.getElementById('js-combobox'))
  document.getElementById('js-combobox').addEventListener('fj:select', (e) => {
    console.log('Selected:', e.detail.value)
  })
</script>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { useCombobox } from 'frutjam/react'

const frameworks = [
  { label: 'React', value: 'react' },
  { label: 'Vue', value: 'vue' },
  { label: 'Angular', value: 'angular' },
  { label: 'Svelte', value: 'svelte' },
]

export default function ComboboxDemo() {
  const combo = useCombobox({ items: frameworks })
  return (
    <div {...combo.containerProps} className="relative w-64">
      <input {...combo.inputProps} className="input w-full" placeholder="Search frameworks..." />
      <ul {...combo.listboxProps} className="combobox-list">
        {combo.filtered.map((item, i) => (
          <li key={item.value} {...combo.optionProps(item, i)}>{item.label}</li>
        ))}
      </ul>
    </div>
  )
}