ComboBox

Molecule

Searchable autocomplete single-select with keyboard navigation, described options, and a clearable button.

Default

Preview

Start typing to filter.

Code
<%- include('modules/ui/ComboBox', {
  label: 'Country',
  placeholder: 'Search countries…',
  hint: 'Start typing to filter.',
  options: [
    { value: 'tr', label: 'Türkiye',       description: 'TR · +90' },
    { value: 'de', label: 'Germany',       description: 'DE · +49' },
    { value: 'us', label: 'United States', description: 'US · +1'  },
  ]
}) %>

With selected value

Preview
Code
<%- include('modules/ui/ComboBox', {
  label: 'Country',
  value: 'tr',
  options: COUNTRIES
}) %>

Open with highlight

Preview
  • Next.js
  • Nuxt
  • Remix
  • Astro
  • SvelteKit
Code
<%- include('modules/ui/ComboBox', {
  label: 'Framework',
  value: 'next',
  options: FRAMEWORKS
}) %>

Error state

Preview
Code
<%- include('modules/ui/ComboBox', {
  label: 'Country',
  required: true,
  error: 'Please select a country.',
  options: COUNTRIES
}) %>

Async loading (debounced)

Preview

Debounced 300ms, AbortController cancels in-flight, 5-min cache.

Code
<%- include('modules/ui/ComboBox', {
  id: 'cb-async',
  label: 'Search',
  options: [],
  placeholder: 'Type to search…',
  hint: 'Debounced 300ms, AbortController cancels in-flight.'
}) %>

<script>
  // Wire an async resolver to the combobox root.
  var root = document.getElementById('cb-async');
  ComboBoxAsync.register(root, async function (query, signal) {
    var res = await fetch('/api/suggest?q=' + encodeURIComponent(query), { signal });
    var data = await res.json();
    // Render <li data-combobox-option> nodes into root.querySelector('[data-combobox-list]')
    return data;
  });
</script>

Disabled

Preview
Code
<%- include('modules/ui/ComboBox', {
  label: 'Country',
  value: 'de',
  disabled: true,
  options: COUNTRIES
}) %>
Source modules/ui/ComboBox/ComboBox.ejs