Chuyển đến nội dung chính

Thành phần hộp tổ hợp

Cập nhật lần cuối:

Hộp tổ hợp CSS Tailwind chỉ có CSS ​​với tính năng lọc tìm kiếm trực tiếp và danh sách thả xuống có thể truy cập. Điều hướng bàn phím, các biến thể màu sắc. WCAG AA có thể truy cập được, hoạt động với Django, HTMX, Laravel, React và bất kỳ ngăn xếp nào.

Combobox kết hợp kiểu nhập văn bản với danh sách thả xuống. Sử dụng thành phần input cho trường - các biến thể kích thước, màu sắc và trạng thái bắt nguồn từ đó. Tiện ích combobox-* chỉ xử lý danh sách thả xuống, các mục và trạng thái mở.

Chỉ CSS, không cần JavaScript. WCAG AA có thể truy cập và không phụ thuộc vào khung — hoạt động với Django, HTMX, Laravel, React và bất kỳ ngăn xếp nào.

Lớp học Kiểu Sự miêu tả
combobox-listCăn cứDropdown list container for combobox options
combobox-itemCông cụ sửa đổiIndividual option inside the dropdown list
combobox-openCông cụ sửa đổiShows the dropdown list when applied to the wrapper
combobox-primaryMàu sắcPrimary theme color highlight for items
combobox-secondaryMàu sắcSecondary theme color highlight for items
combobox-accentMàu sắcAccent theme color highlight for items
combobox-infoMàu sắcInfo semantic color highlight
combobox-successMàu sắcSuccess semantic color highlight
combobox-warningMàu sắcWarning semantic color highlight
combobox-errorMàu sắcError semantic color highlight

Cách sử dụng cơ bản

Gói inputcombobox-list trong vùng chứa relative. Thêm combobox-open vào trình bao bọc để hiển thị danh sách — chuyển đổi danh sách đó qua JS hoặc :focus-within.

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>
  )
}

Open on Focus

Sử dụng focus-within:combobox-open trên trình bao bọc để mở danh sách khi đầu vào được tập trung — không cần JavaScript.

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>

Sizes

Use input-sm, input-lg, etc. on the input field. The dropdown adapts naturally.

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>

Colors

Use input-primary etc. on the input for the field color. Add the matching combobox-primary to the wrapper to tint the active item highlight.

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>

Disabled

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

With Button

Compose with join to attach a search icon or trigger button.

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>

combobox-item hoạt động trên mọi phần tử — <li>, <a> hoặc <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 & React Helper

Use createCombobox from frutjam/js or useCombobox from frutjam/react to get filtering, keyboard navigation (↑ ↓ Enter Escape), and full aria-* wiring out of the box. Listen for the fj:select event to handle selection.

 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>
  )
}

Using Claude Code, Cursor, or another AI editor?

Cherry MCP cung cấp cho trình soạn thảo AI của bạn tên và cấu trúc lớp Hộp tổ hợp chính xác theo yêu cầu. Không còn những lớp học ảo giác nữa.

Try Cherry MCP