Skip to content

Soracom

Design System
Home Design System Elements Autocomplete

Autocomplete

A container for an input and menu used as an autocomplete/type-ahead for the input.

This component requires Javascript for certain functionality, and implementing W3C WAI-ARIA accessibility recommendations

Overview 

The autocomplete component is a container for a ds-input and ds-menu used as the menu. This component only provides styling and does not provide any javascript required to implement auto-complete functionality.

Options 

Basic usage 

Non ARIA version 

The following structure uses html hover and focus states to hide/reveal the list menu

Basic usage
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
    <li>Squirtle</li>
    <li>Venusaur</li>
    <li>Wartortle</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
  • Squirtle
  • Venusaur
  • Wartortle
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
    <li>Squirtle</li>
    <li>Venusaur</li>
    <li>Wartortle</li>
  </ul>
</div>

With ARIA attributes 

The following structure uses role="combobox" and aria-expanded to hide/reveal the list menu. hover and focus will be ignored.

To show the list menu, set aria-expanded="true", to hide the list menu, set aria-expanded="false", aria-expanded="" or aria-expanded.

Basic usage
<!-- Click links to toggle aria-expanded state -->
<div class="ds-cols">
  <a href="#" onClick="document.getElementById('example-combobox').setAttribute('aria-expanded', true); return false;"><code>aria-expanded="true"</code></a>
  <a href="#" onClick="document.getElementById('example-combobox').setAttribute('aria-expanded', false); return false;"><code>aria-expanded="false"</code></a>
</div>

<!-- Autocomplete menu -->
<div class="ds-autocomplete">
  <div
    class="ds-input"
    id="example-combobox"
    role="combobox"
    aria-autocomplete="list"
    aria-controls="example-listbox"
    aria-expanded="false"
    aria-activedescendant=""
  >
    <input
      type="text"
      aria-label="Enter a Pokemon name"
      autocomplete="off"
    >
  </div>
  <ul class="ds-menu"
    id="example-listbox"
    role="listbox"
  >
    <li role="option">Anorith</li>
    <li role="option">Arbok</li>
    <li role="option">Arcanine</li>
    <li role="option">Bulbasaur</li>
    <li role="option">Butterfree</li>
    <li role="option">Caterpie</li>
    <li role="option">Charizard</li>
    <li role="option">Charmander</li>
    <li role="option">Charmeleon</li>
    <li role="option">Squirtle</li>
    <li role="option">Venusaur</li>
    <li role="option">Wartortle</li>
  </ul>
</div>

Click links to toggle aria-expanded state

Autocomplete menu

  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
  • Squirtle
  • Venusaur
  • Wartortle
<!-- Click links to toggle aria-expanded state -->
<div class="ds-cols">
  <a href="#" onClick="document.getElementById('example-combobox').setAttribute('aria-expanded', true); return false;"><code>aria-expanded="true"</code></a>
  <a href="#" onClick="document.getElementById('example-combobox').setAttribute('aria-expanded', false); return false;"><code>aria-expanded="false"</code></a>
</div>

<!-- Autocomplete menu -->
<div class="ds-autocomplete">
  <div
    class="ds-input"
    id="example-combobox"
    role="combobox"
    aria-autocomplete="list"
    aria-controls="example-listbox"
    aria-expanded="false"
    aria-activedescendant=""
  >
    <input
      type="text"
      aria-label="Enter a Pokemon name"
      autocomplete="off"
    >
  </div>
  <ul class="ds-menu"
    id="example-listbox"
    role="listbox"
  >
    <li role="option">Anorith</li>
    <li role="option">Arbok</li>
    <li role="option">Arcanine</li>
    <li role="option">Bulbasaur</li>
    <li role="option">Butterfree</li>
    <li role="option">Caterpie</li>
    <li role="option">Charizard</li>
    <li role="option">Charmander</li>
    <li role="option">Charmeleon</li>
    <li role="option">Squirtle</li>
    <li role="option">Venusaur</li>
    <li role="option">Wartortle</li>
  </ul>
</div>
Alternate usage with simple ds-input and ds-button
<!-- Click links to toggle aria-expanded state -->
<div class="ds-cols">
  <a href="#" onClick="document.getElementById('example-combobox-2').setAttribute('aria-expanded', true); return false;"><code>aria-expanded="true"</code></a>
  <a href="#" onClick="document.getElementById('example-combobox-2').setAttribute('aria-expanded', false); return false;"><code>aria-expanded="false"</code></a>
</div>

<!-- Autocomplete menu -->
<div class="ds-autocomplete">
  <input
    type="text"
    aria-label="Enter a Pokemon name"
    autocomplete="off"
    class="ds-input"
    id="example-combobox-2"
    role="combobox"
    aria-autocomplete="list"
    aria-controls="example-listbox"
    aria-expanded="false"
    aria-activedescendant=""
  >
  <button class="ds-button --plain --addon --icon-ui-arrow-down"></button>
  <ul class="ds-menu"
    id="example-listbox"
    role="listbox"
  >
    <li role="option">Anorith</li>
    <li role="option">Arbok</li>
    <li role="option">Arcanine</li>
    <li role="option">Bulbasaur</li>
    <li role="option">Butterfree</li>
    <li role="option">Caterpie</li>
    <li role="option">Charizard</li>
    <li role="option">Charmander</li>
    <li role="option">Charmeleon</li>
    <li role="option">Squirtle</li>
    <li role="option">Venusaur</li>
    <li role="option">Wartortle</li>
  </ul>
</div>

Click links to toggle aria-expanded state

Autocomplete menu

  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
  • Squirtle
  • Venusaur
  • Wartortle
<!-- Click links to toggle aria-expanded state -->
<div class="ds-cols">
  <a href="#" onClick="document.getElementById('example-combobox-2').setAttribute('aria-expanded', true); return false;"><code>aria-expanded="true"</code></a>
  <a href="#" onClick="document.getElementById('example-combobox-2').setAttribute('aria-expanded', false); return false;"><code>aria-expanded="false"</code></a>
</div>

<!-- Autocomplete menu -->
<div class="ds-autocomplete">
  <input
    type="text"
    aria-label="Enter a Pokemon name"
    autocomplete="off"
    class="ds-input"
    id="example-combobox-2"
    role="combobox"
    aria-autocomplete="list"
    aria-controls="example-listbox"
    aria-expanded="false"
    aria-activedescendant=""
  >
  <button class="ds-button --plain --addon --icon-ui-arrow-down"></button>
  <ul class="ds-menu"
    id="example-listbox"
    role="listbox"
  >
    <li role="option">Anorith</li>
    <li role="option">Arbok</li>
    <li role="option">Arcanine</li>
    <li role="option">Bulbasaur</li>
    <li role="option">Butterfree</li>
    <li role="option">Caterpie</li>
    <li role="option">Charizard</li>
    <li role="option">Charmander</li>
    <li role="option">Charmeleon</li>
    <li role="option">Squirtle</li>
    <li role="option">Venusaur</li>
    <li role="option">Wartortle</li>
  </ul>
</div>

Height 

By default the autocomplete will be the height of the menu contents. You can also restrict the overall height of the menu and cause the contents to scroll. If the menu can scroll, a shadow will be added at the bottom/top of the menu to indicate the menu is scrollable.

There are two ways to restrict the height.

Restrict the height to the viewport 

Adding the class --viewport to the menu will restrict the height to 100vh - --ds-header-height (usually 100vh - 60px) and force the menu to scroll.

Using viewport height - if the browser height is less than the menu height, the menu will scroll
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --viewport">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
    <li>Squirtle</li>
    <li>Venusaur</li>
    <li>Wartortle</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
  • Squirtle
  • Venusaur
  • Wartortle

Restrict the height to a specific size 

You can restrict the height by changing the --ds-menu-height value (either in a css file, inline style tag or via javascript).

Setting a height using javascript
let myCustomMenu = document.getElementById("customMenu")
myCustomMenu.style.setProperty('--ds-menu-height', "400px")
Setting a height using inline style tag
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu" style="--ds-menu-height: 200px;">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
    <li>Squirtle</li>
    <li>Venusaur</li>
    <li>Wartortle</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
  • Squirtle
  • Venusaur
  • Wartortle

Loading state 

A details can be triggered to display a loading state - where the details contents are hidden, and the replaced by a centered spinning loading icon – without affecting the dimensions of the details.

Additional options are available using Message state

Default
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
Alternative loading-refresh icon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading --loading-refresh">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading --loading-refresh">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
Custom icon by adding any icon class
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading --icon-radar">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading --icon-radar">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>

Message state 

Message state extends and can be used with Loading state. If a details has a data-attribute data-ds-message the details contents are hidden, and replaced by an icon and the text of the data-ds-message.

<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
Loading state with a message
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
You can set a custom icon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --icon-rocket" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --icon-rocket" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
You can set a custom icon, with the loading state animation
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading --icon-compass" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu --loading --icon-compass" data-ds-message="Message text">
    <li>Anorith</li>
    <li>Arbok</li>
    <li>Arcanine</li>
    <li>Bulbasaur</li>
    <li>Butterfree</li>
    <li>Caterpie</li>
    <li>Charizard</li>
    <li>Charmander</li>
    <li>Charmeleon</li>
  </ul>
</div>

Input Icons 

See ds-input icons.

List icons 

See ds-menu icons.

List descriptions 

See ds-menu descriptions

Accessibility 

Role and ARIA attributes 

Recommendations for implementing ds-autocomplete to meet W3C WAI-ARIA guidelines are as follows:

Autocomplete container (div) 

<div class="ds-autocomplete">
  ...
</div>

Autocomplete combobox (div) 

<div class="ds-input"
  role="combobox"
  aria-autocomplete="list"
  aria-controls="[ID]"
  aria-expanded="[true|false]"
  aria-activedescendant="[ID]"
>
  ...
</div>
Element Attribute Required Type Description
<div> role="combobox" Required Static Indicates the div is a combobox
aria-autocomplete="list" Required Static Indicates the combobox is an autocomplete list
aria-controls="[ID]" Required Static Refers to the ID of the autocomplete list
aria-expanded="[true|false]" Required Dynamic 1. Set to true when the list is open
2. Removed or set to false when the list is closed
aria-activedescendant="[ID]" Required Static Refers to the ID of the focused item in the autocomplete list

Autocomplete textbox (input) 

<div class="ds-input">
  <input type="text"
    aria-label="[string]"
    autocomplete="off"
  >
</div>
Element Attribute Required Type Description
<input type="text"> aria-label="[string]" Required Static Descriptive label
autocomplete="off" Recommended Static Disable default browser autocomplete

Autocomplete list (ul) 

<ul class="ds-menu"
  id="[ID]"
  role="listbox"
>
  <li
    id="[ID]"
    role="option"
    aria-selected="[true|false]">
    ...
  </li>
</ul>
Element Attribute Required Type Description
<ul> id="[ID]" Required Static 1. Unique ID
2. Related to the combobox aria-controls
role="listbox" Required Static Indicates the element is an autocomplete list
<li> id="[ID]" Required Static 1. Unique ID
2. Related to the combobox aria-activedescendant
role="option" Required Static Indicates the element is an autocomplete list option
aria-selected="[true|false]" Required Dynamic Indicates when the option is selected

Keyboard access 

The following keyboard controls must be implemented to provide accessible keyboard access.

Autocomplete textbox (input): 

Default browser support for entering and editing text inputs applies, such as delete, left/right arrow.

Key Required Support Description
Enter Required Javascript 1. If a list item is selected, sets the value of the textbox to the selected option.
2. Closes the autocomplete list.
Escape Required Javascript 1. Closes the autocomplete list.
2. Clears the textbox.
Down Arrow Required Javascript 1. If no list item is focused, moves focus to the first list item.
2. If a list item is focused, moves to the next item.
3. If the last item is focused, moves to the first list item.
Up Arrow Required Javascript 1. If no list item is focused, moves focus to the last list item.
2. If a list item is focused, moves to the previous item.
3. If the first item is focused, moves to the last list item.
Printable Characters Required Javascript 1. Types the character in the textbox.
2. Filters the items in the Autocomplete list.
3. Selects the first matching item.

Autocomplete list (ul): 

Key Required Support Description
Enter Required Javascript 1. If a list item is selected, sets the value of the textbox to the selected option.
2. Closes the autocomplete list.
3. Move focus to the textbox.
Escape Required Javascript 1. Closes the autocomplete list.
2. Clears the textbox.
3. Sets focus to the textbox.
Down Arrow Required Javascript 1. Moves to the next item.
2. If the last item is selected, moves to the first list item.
Up Arrow Required Javascript 1. Moves to the previous item.
2. If the first item is selected, moves to the last list item.
Left Arrow Required Javascript 1. Move focus to the textbox.
2. Moves cursor one character to left.
Right Arrow Required Javascript 1. Move focus to the textbox.
2. Moves cursor one character to right.
Home Required Javascript 1. Move focus to the textbox.
2. Moves cursor to beginning of the textbox.
end Required Javascript 1. Move focus to the textbox.
2. Moves cursor to end of the textbox.
Printable Characters Required Javascript 1. Move focus to the textbox.
2. Types the character in the textbox.

Examples 

Autocomplete list 

Used within ds-field, with label and --addon
<div class="ds-field">
  <label for="example-1" class="ds-text --label">Field test</label>
  <div class="ds-autocomplete" role="combobox" aria-haspopup="listbox" aria-owns="example-1-list">
    <div class="ds-input">
      <input type="text" name="example-1-input" id="example-1-input" aria-autocomplete="list" aria-controls="example-1-list">
    </div>
    <ul id="example-1-list" class="ds-menu">
      <li role="option" id="option-anorith">Anorith</li>
      <li role="option" id="option-arbok">Arbok</li>
      <li role="option" id="option-arcanine">Arcanine</li>
      <li role="option" id="option-bulbasaur">Bulbasaur</li>
      <li role="option" id="option-butterfree">Butterfree</li>
      <li role="option" id="option-caterpie">Caterpie</li>
      <li role="option" id="option-charizard">Charizard</li>
      <li role="option" id="option-charmander">Charmander</li>
      <li role="option" id="option-charmeleon">Charmeleon</li>
      <li role="option" id="option-squirtle">Squirtle</li>
      <li role="option" id="option-venusaur">Venusaur</li>
      <li role="option" id="option-wartortle">Wartortle</li>
    </ul>
  </div>
</div>
  • Anorith
  • Arbok
  • Arcanine
  • Bulbasaur
  • Butterfree
  • Caterpie
  • Charizard
  • Charmander
  • Charmeleon
  • Squirtle
  • Venusaur
  • Wartortle
<div class="ds-field">
  <label for="example-1" class="ds-text --label">Field test</label>
  <div class="ds-autocomplete" role="combobox" aria-haspopup="listbox" aria-owns="example-1-list">
    <div class="ds-input">
      <input type="text" name="example-1-input" id="example-1-input" aria-autocomplete="list" aria-controls="example-1-list">
    </div>
    <ul id="example-1-list" class="ds-menu">
      <li role="option" id="option-anorith">Anorith</li>
      <li role="option" id="option-arbok">Arbok</li>
      <li role="option" id="option-arcanine">Arcanine</li>
      <li role="option" id="option-bulbasaur">Bulbasaur</li>
      <li role="option" id="option-butterfree">Butterfree</li>
      <li role="option" id="option-caterpie">Caterpie</li>
      <li role="option" id="option-charizard">Charizard</li>
      <li role="option" id="option-charmander">Charmander</li>
      <li role="option" id="option-charmeleon">Charmeleon</li>
      <li role="option" id="option-squirtle">Squirtle</li>
      <li role="option" id="option-venusaur">Venusaur</li>
      <li role="option" id="option-wartortle">Wartortle</li>
    </ul>
  </div>
</div>

Autocomplete list with grid content 

Autocomplete list with rich content
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu">
    <li data-ds-value="019281919281">
      <dl class="ds-details--vertical">
        <dt>Sim ID: 019281919281</dt>
        <dd>
          <div>My SIM</div>
          <div class="ds-text --small --success --icon-online">Online</div>
        </dd>
      </dl>
    </li>
    <li data-ds-value="9381273784832">
      <dl class="ds-details--vertical">
        <dt>Sim ID: 9381273784832</dt>
        <dd>
          <div>My Other SIM</div>
          <div class="ds-text --small --alert --icon-online">Offline</div>
        </dd>
      </dl>
    </li>
    <li data-ds-value="9381273784719">
      <dl class="ds-details--vertical">
        <dt>Sim ID: 9381273784719</dt>
        <dd>
          <div>My Other SIM</div>
          <div class="ds-text --small --alert --icon-online">Offline</div>
        </dd>
      </dl>
    </li>
  </ul>
</div>
  • Sim ID: 019281919281
    My SIM
    Online
  • Sim ID: 9381273784832
    My Other SIM
    Offline
  • Sim ID: 9381273784719
    My Other SIM
    Offline
<div class="ds-autocomplete">
  <div class="ds-input">
    <input type="text" name="test-field">
  </div>
  <ul class="ds-menu">
    <li data-ds-value="019281919281">
      <dl class="ds-details--vertical">
        <dt>Sim ID: 019281919281</dt>
        <dd>
          <div>My SIM</div>
          <div class="ds-text --small --success --icon-online">Online</div>
        </dd>
      </dl>
    </li>
    <li data-ds-value="9381273784832">
      <dl class="ds-details--vertical">
        <dt>Sim ID: 9381273784832</dt>
        <dd>
          <div>My Other SIM</div>
          <div class="ds-text --small --alert --icon-online">Offline</div>
        </dd>
      </dl>
    </li>
    <li data-ds-value="9381273784719">
      <dl class="ds-details--vertical">
        <dt>Sim ID: 9381273784719</dt>
        <dd>
          <div>My Other SIM</div>
          <div class="ds-text --small --alert --icon-online">Offline</div>
        </dd>
      </dl>
    </li>
  </ul>
</div>

Autocomplete with grid content and preview 

This implementation is based on the ARIA Editable Combobox with Grid Popup

Autocomplete list with grid content
  <div class="ds-field">
    <!-- Label -->
    <label class="ds-text --label" for="autocomplete-filter">API</label>
    <!-- Autocomplete -->
    <div class="ds-autocomplete">
      <!-- Optional: This should only show the currently selected option data -->
      <dl class="ds-details --vertical">
        <dt class="--no-case">{{ selected-option-name }}</dt>
        <dd>
          <div class="ds-text --small">{{ selected-option-description }}</div>
        </dd>
        <dd>
          <div class="ds-cols --middle --spaced --indent-small">
            <div class="ds-tag --outline --color-blue">
              <span>{{ selected-option-method }}</span>
            </div>
            <div class="ds-text --code --small --color-blue">{{ selected-option-url }}</div>
          </div>
        </dd>
      </dl>
      <!-- Filter -->
      <div class="ds-input --icon-search">
        <input
          type="text"
          id="autocomplete-filter"
          role="combobox"
          aria-autocomplete="list"
          aria-activedescendant="{{ active descendant id }}"
          aria-controls="autocomplete-listbox"
          aria-expanded="{{ true|false }}"
          aria-haspopup="grid"
        />
      </div>
      <!-- Button -->
      <button
        class="ds-button --plain --addon --icon-ui-arrow-down --hide-label --top-left"
        aria-controls="autocomplete-listbox"
        aria-expanded="{{ true|false }}"
        aria-label="Show API options"
      >
        <span>Show API options</span>
      </button>
      <!-- Grid -->
      <div
        class="ds-menu"
        id="autocomplete-listbox"
        role="grid"
        aria-hidden="{{ true|false }}"
        style="--ds-menu-max-height: 420px"
      >
        <ul
          role="group"
          aria-labelledby="{{ group-id }}"
        >
          <li role="presentation" class="ds-text --bold" id="{{ group-id }}">
            {{ option name }}
          </li>
          <li
            role="row"
            id="{{ option-id }}"
            aria-selected="{{ true|false }}"
            class="{{ if --focused }}"
          >
            <dl class="ds-details --vertical">
              <dt
                class="--no-case"
                role="gridcell"
              >{{ option-name }}</dt>
              <dd>
                <div
                  class="ds-text --small"
                  role="gridcell"
                >{{ option-description }}</div>
              </dd>
              <dd>
                <div class="ds-cols --middle --spaced --indent-small">
                  <div
                    class="ds-tag --outline --color-blue"
                    role="gridcell"
                  >
                    <span>{{ option-method }}</span>
                  </div>
                  <div
                    class="ds-text --code --small --color-blue"
                    role="gridcell"
                  >{{ option-url }}</div>
                </div>
              </dd>
            </dl>
          </li>
        </ul>
      </div>
    </div>
  </div>

References