Component

Select Dropdown

Enhanced select dropdown with icons, descriptions, and smooth arrow rotation animation.

  • Component
  • Tailwind
  • HTML
  • MIT

Preview

Live component

Interactive preview
Open preview
9:41 100%
devsnips.dev/library/tailwind/components/dropdowns/select-dropdown/
fluid · no fixed width 100%
No dependencies Production-ready

Install

Add to your project

terminal
npx devsnips add Tailwind/Components/Dropdowns/select-dropdown
registry path: Tailwind/Components/Dropdowns/select-dropdown

Source

Implementation

code.html
<!-- Select Dropdown -->
<div class="relative">
  <label class="block text-sm font-medium text-gray-700 mb-2">Select Category</label>
  
  <button
    id="select-button"
    class="relative w-full px-4 py-3 text-left bg-white border border-gray-300 rounded-lg hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-colors"
    aria-expanded="true"
    aria-haspopup="listbox"
    onclick="toggleDropdown('select-menu')"
  >
    <div class="flex items-center justify-between">
      <div id="select-value" class="flex items-center gap-3">
        <span class="text-gray-400">Choose an option...</span>
      </div>
      <svg class="w-5 h-5 text-gray-400 transition-transform" id="select-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
      </svg>
    </div>
  </button>

  <div
    id="select-menu"
    class="hidden absolute z-10 w-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg overflow-hidden"
  >
    <ul class="py-1 max-h-60 overflow-auto" role="listbox">
      <li
        class="select-option px-4 py-3 text-gray-700 cursor-pointer hover:bg-blue-50 hover:text-blue-600 transition-colors flex items-center gap-3"
        data-value="design"
        data-label="Design"
        onclick="selectOption(this)"
      >
        <span class="w-8 h-8 rounded-lg bg-pink-100 flex items-center justify-center">
          <svg class="w-4 h-4 text-pink-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"></path>
          </svg>
        </span>
        <div>
          <p class="font-medium">Design</p>
          <p class="text-xs text-gray-500">UI/UX, graphics, branding</p>
        </div>
      </li>
      
      <li
        class="select-option px-4 py-3 text-gray-700 cursor-pointer hover:bg-blue-50 hover:text-blue-600 transition-colors flex items-center gap-3"
        data-value="development"
        data-label="Development"
        onclick="selectOption(this)"
      >
        <span class="w-8 h-8 rounded-lg bg-blue-100 flex items-center justify-center">
          <svg class="w-4 h-4 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path>
          </svg>
        </span>
        <div>
          <p class="font-medium">Development</p>
          <p class="text-xs text-gray-500">Web, mobile, backend</p>
        </div>
      </li>
      
      <li
        class="select-option px-4 py-3 text-gray-700 cursor-pointer hover:bg-blue-50 hover:text-blue-600 transition-colors flex items-center gap-3"
        data-value="marketing"
        data-label="Marketing"
        onclick="selectOption(this)"
      >
        <span class="w-8 h-8 rounded-lg bg-green-100 flex items-center justify-center">
          <svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z"></path>
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z"></path>
          </svg>
        </span>
        <div>
          <p class="font-medium">Marketing</p>
          <p class="text-xs text-gray-500">SEO, content, social media</p>
        </div>
      </li>
      
      <li
        class="select-option px-4 py-3 text-gray-700 cursor-pointer hover:bg-blue-50 hover:text-blue-600 transition-colors flex items-center gap-3"
        data-value="analytics"
        data-label="Analytics"
        onclick="selectOption(this)"
      >
        <span class="w-8 h-8 rounded-lg bg-purple-100 flex items-center justify-center">
          <svg class="w-4 h-4 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
          </svg>
        </span>
        <div>
          <p class="font-medium">Analytics</p>
          <p class="text-xs text-gray-500">Data, reports, insights</p>
        </div>
      </li>
      
      <li
        class="select-option px-4 py-3 text-gray-700 cursor-pointer hover:bg-blue-50 hover:text-blue-600 transition-colors flex items-center gap-3"
        data-value="support"
        data-label="Support"
        onclick="selectOption(this)"
      >
        <span class="w-8 h-8 rounded-lg bg-amber-100 flex items-center justify-center">
          <svg class="w-4 h-4 text-amber-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z"></path>
          </svg>
        </span>
        <div>
          <p class="font-medium">Support</p>
          <p class="text-xs text-gray-500">Help desk, tickets</p>
        </div>
      </li>
    </ul>
  </div>
</div>

<script>
  function toggleDropdown(id) {
    const menu = document.getElementById(id);
    const arrow = document.getElementById('select-arrow');
    menu.classList.toggle('hidden');
    arrow.classList.toggle('rotate-180');
    const button = document.getElementById('select-button');
    const isExpanded = button.getAttribute('aria-expanded') === 'true';
    button.setAttribute('aria-expanded', !isExpanded);
  }

  function selectOption(element) {
    const value = element.getAttribute('data-value');
    const label = element.getAttribute('data-label');
    const selectValue = document.getElementById('select-value');
    
    // Update selected state visually
    document.querySelectorAll('.select-option').forEach(opt => {
      opt.classList.remove('bg-blue-50', 'text-blue-600');
    });
    element.classList.add('bg-blue-50', 'text-blue-600');
    
    // Update display value
    selectValue.innerHTML = `
      <span class="w-8 h-8 rounded-lg bg-blue-100 flex items-center justify-center">
        ${element.querySelector('span').innerHTML}
      </span>
      <span class="font-medium">${label}</span>
    `;
    
    toggleDropdown('select-menu');
  }

  document.addEventListener('click', function(event) {
    const dropdown = document.querySelector('.relative');
    const button = document.getElementById('select-button');
    const menu = document.getElementById('select-menu');
    if (!dropdown.contains(event.target)) {
      menu.classList.add('hidden');
      document.getElementById('select-arrow').classList.remove('rotate-180');
      button.setAttribute('aria-expanded', 'false');
    }
  });
</script>
159 lines UTF-8 · LF · Spaces: 2

AI-ready

Available to your agent.

This component is reachable through the DevSnips CLI, MCP server and Skills integrations — one registry, one resource path.

Resource path

devsnips://components/dropdowns/select-dropdown

Continue browsing

View all