Ir al contenido principal

Componente de cuadro combinado

Última actualización:

Cuadro combinado CSS Tailwind solo para CSS con filtrado de búsqueda en vivo y lista desplegable accesible. Navegación por teclado, variantes de color. Accesible a WCAG AA, funciona con Django, HTMX, Laravel, React y cualquier pila.

Combobox combina una entrada de texto con una lista desplegable. Utilice el componente input para el campo: las variantes de tamaño, color y estado provienen de allí. Las utilidades combobox-* manejan solo la lista desplegable, los elementos y el estado abierto.

Solo CSS, no se requiere JavaScript. WCAG AA accesible e independiente del marco: funciona con Django, HTMX, Laravel, React y cualquier pila.

Clase Tipo Descripción
combobox-listBaseContenedor de lista desplegable para opciones de cuadro combinado
combobox-itemModificadorOpción individual dentro de la lista desplegable
combobox-openModificadorMuestra la lista desplegable cuando se aplica al contenedor
combobox-primaryColorResaltado de color del tema principal para elementos
combobox-secondaryColorResaltado de color del tema secundario para elementos
combobox-accentColorResaltado de color del tema de acento para artículos
combobox-infoColorResaltado de color semántico de información
combobox-successColorResaltado de color semántico de éxito
combobox-warningColorResaltado de color semántico de advertencia
combobox-errorColorResaltado de color semántico de error

Uso básico

Envuelva una input y una combobox-list en un contenedor relative. Agregue combobox-open al contenedor para mostrar la lista; alterne mediante JS o :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>
  )
}

Abrir en foco

Utilice focus-within:combobox-open en el contenedor para abrir la lista cuando la entrada esté enfocada; no se necesita 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>

Tallas

Utilice input-sm, input-lg, etc. en el campo de entrada. El menú desplegable se adapta de forma natural.

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>

Bandera

Utilice input-primary, etc. en la entrada para el color del campo. Agregue el combobox-primary coincidente al contenedor para teñir el resaltado del elemento activo.

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>

Desactivado

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

Con botón

Redacte con join para adjuntar un icono de búsqueda o un botón de activación.

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 funciona en cualquier elemento: <li>, <a> o <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>

Ayudante de JS y React

Utilice createCombobox de frutjam/js o useCombobox de frutjam/react para obtener filtrado, navegación con el teclado ( ↑ ↓ Enter Escape) y cableado aria-* completo listo para usar. Escuche el evento fj:select para manejar la selección.

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

¿Usando Claude Code, Cursor u otro editor de IA?

Cherry MCP le brinda a su editor de IA la estructura y los nombres exactos de las clases cuadro combinado según sea necesario. No más clases alucinadas.

Pruebe Cherry MCP