accessible dropdown component in javascript

To make dropdowns accessible in JavaScript, you can follow these general steps:

  1. Set the dropdown element as a role of "combobox" and add an aria-expanded="false" attribute to indicate the initial state of the dropdown.
  2. Make it so that when the dropdown is opened, you update the aria-expanded attribute to "true".
  3. When an option is selected, update the text of the combobox (the visible input field) to display the selected option and update the aria-activedescendant attribute to the ID of the selected option.
  4. If the dropdown is closed without selecting an option, restore the original text of the combobox.

Here's an example with basic functionality:

<label for="my-dropdown">Select an option:</label>
<div role="combobox" aria-haspopup="listbox" aria-expanded="false" aria-owns="dropdown-list" id="my-dropdown">
  <input type="text" placeholder="Select an option">
  <ul id="dropdown-list">
    <li id="option1">Option 1</li>
    <li id="option2">Option 2</li>
    <li id="option3">Option 3</li>
  </ul>
</div>

<script>
  var dropdown = document.getElementById('my-dropdown');
  var input = dropdown.querySelector('input');
  var list = dropdown.querySelector('ul');
  var options = dropdown.querySelectorAll('li');

  // When combobox is clicked, toggle aria-expanded attribute
  dropdown.addEventListener('click', function() {
    var expanded = dropdown.getAttribute('aria-expanded') === 'true';
    dropdown.setAttribute('aria-expanded', !expanded);
    if (!expanded) {
      input.focus(); // Set focus on input field when dropdown is opened
    }
  });

  // When option is clicked, update text of input and aria-activedescendant attribute
  options.forEach(function(option) {
    option.addEventListener('click', function() {
      input.value = option.textContent;
      dropdown.setAttribute('aria-activedescendant', option.id);
      closeDropdown();
    });
  });

  // When Escape or Tab key is pressed while dropdown is open, close dropdown
  input.addEventListener('keydown', function(event) {
    if (event.keyCode === 27 || event.keyCode === 9) {
      event.preventDefault();
      closeDropdown();
    }
  });

  // Helper function to close dropdown and update aria-expanded attribute
  function closeDropdown() {
    dropdown.setAttribute('aria-expanded', 'false');
    input.focus();
  }
</script>
1670 chars
49 lines

Note that this is just a basic example and there are many more considerations to make for full accessibility compliance.

gistlibby LogSnag