Select

Professional dropdown selection component with search, multi-select, and custom styling options.

Select Variants

Standard Select

Basic dropdown selection

Option 1
Option 2
Option 3
Option 4

Select with Search

Filterable dropdown list

Germany
France
United States
United Kingdom
Japan
Australia

Disabled Options

Select with disabled items

Active
Pending (unavailable)
Completed
Archived (unavailable)

Select Sizes

Different size variants

Option 1
Option 1
Option 1

Multi-Select

Select multiple options with checkboxes

Parking
Gym
Swimming Pool
Balcony
Garden
Elevator

Multi-Select with Tags

Display selected items as removable tags

Munich Berlin
Hamburg
Frankfurt
Stuttgart
Cologne

Real Estate Use Cases

Property Type

Apartment
House
Villa
Studio

Price Range

€0 - €500,000
€500,000 - €1,000,000
€1,000,000 - €2,000,000
€2,000,000+

Implementation Guide

HTML Structure

<!-- Standard Select -->
<div class="lyd-select">
    <button class="lyd-select-trigger" >
        <span>Choose an option</span>
        <svg class="lyd-select-icon" width="20" height="20" viewBox="0 0 24 24">
            <path d="M6 9l6 6 6-6" />
        </svg>
    </button>
    <div class="lyd-select-dropdown">
        <div class="lyd-select-option">Option 1</div>
        <div class="lyd-select-option">Option 2</div>
        <div class="lyd-select-option">Option 3</div>
    </div>
</div>

<!-- Select with Search -->
<div class="lyd-select">
    <button class="lyd-select-trigger">
        <span>Select item</span>
        <svg class="lyd-select-icon">...</svg>
    </button>
    <div class="lyd-select-dropdown">
        <div class="lyd-select-search">
            <input type="text" placeholder="Search...">
        </div>
        <div class="lyd-select-option">Item 1</div>
        <div class="lyd-select-option">Item 2</div>
    </div>
</div>

JavaScript for Dropdown Toggle

// Toggle dropdown
function toggleSelect(trigger) {
    const dropdown = trigger.nextElementSibling;
    const isOpen = trigger.classList.contains('active');
    
    // Close all other dropdowns
    document.querySelectorAll('.lyd-select-trigger').forEach(t => {
        t.classList.remove('active');
        t.nextElementSibling.classList.remove('show');
    });
    
    if (!isOpen) {
        trigger.classList.add('active');
        dropdown.classList.add('show');
    }
}

// Select option
function selectOption(option, value) {
    if (option.classList.contains('disabled')) return;
    
    const select = option.closest('.lyd-select');
    const trigger = select.querySelector('.lyd-select-trigger span');
    const dropdown = select.querySelector('.lyd-select-dropdown');
    
    // Update selected state
    dropdown.querySelectorAll('.lyd-select-option').forEach(opt => {
        opt.classList.remove('selected');
    });
    option.classList.add('selected');
    
    // Update trigger text
    trigger.textContent = value;
    
    // Close dropdown
    select.querySelector('.lyd-select-trigger').classList.remove('active');
    dropdown.classList.remove('show');
}

// Filter options
function filterOptions(input) {
    const filter = input.value.toLowerCase();
    const options = input.closest('.lyd-select-dropdown')
        .querySelectorAll('.lyd-select-option');
    
    options.forEach(option => {
        const text = option.textContent.toLowerCase();
        option.style.display = text.includes(filter) ? '' : 'none';
    });
}

// Close on outside click
document.addEventListener('click', (e) => {
    if (!e.target.closest('.lyd-select')) {
        document.querySelectorAll('.lyd-select-trigger').forEach(trigger => {
            trigger.classList.remove('active');
            trigger.nextElementSibling.classList.remove('show');
        });
    }
});

React/Next.js Component

// components/Select.tsx
import { useState, useRef, useEffect } from 'react';

interface Option {
  value: string;
  label: string;
  disabled?: boolean;
}

interface SelectProps {
  options: Option[];
  placeholder?: string;
  searchable?: boolean;
  size?: 'small' | 'medium' | 'large';
  value?: string;
  onChange?: (value: string) => void;
}

export const Select = ({
  options,
  placeholder = 'Select an option',
  searchable = false,
  size = 'medium',
  value,
  onChange
}: SelectProps) => {
  const [isOpen, setIsOpen] = useState(false);
  const [search, setSearch] = useState('');
  const [selected, setSelected] = useState(value);
  const selectRef = useRef<HTMLDivElement>(null);

  const filteredOptions = searchable
    ? options.filter(opt => 
        opt.label.toLowerCase().includes(search.toLowerCase())
      )
    : options;
  
  const handleSelect = (option: Option) => {
    if (option.disabled) return;
    setSelected(option.value);
      setIsOpen(false);
    setSearch('');
    onChange?.(option.value);
  };
  
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (selectRef.current && !selectRef.current.contains(e.target as Node)) {
        setIsOpen(false);
      }
    };
    
    document.addEventListener('click', handleClickOutside);
    return () => document.removeEventListener('click', handleClickOutside);
  }, []);

      return (
    <div ref={selectRef} className={`lyd-select ${size}`}>
      <button
        className={`lyd-select-trigger ${isOpen ? 'active' : ''}`}
        onClick={() => setIsOpen(!isOpen)}
      >
        <span>
          {selected
            ? options.find(o => o.value === selected)?.label
            : placeholder}
        </span>
        <svg className="lyd-select-icon" width="20" height="20">
          <path d="M6 9l6 6 6-6" />
        </svg>
      </button>
      
      <div className={`lyd-select-dropdown ${isOpen ? 'show' : ''}`}>
        {searchable && (
          <div className="lyd-select-search">
          <input
            type="text"
              placeholder="Search..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
          />
          </div>
        )}
        
        {filteredOptions.map(option => (
              <div
                key={option.value}
            className={`lyd-select-option ${
              option.disabled ? 'disabled' : ''
            } ${selected === option.value ? 'selected' : ''}`}
            onClick={() => handleSelect(option)}
          >
            {option.label}
                </div>
        ))}
              </div>
    </div>
  );
};

API Reference

Class Description
.lyd-select Main select container
.lyd-select-trigger Clickable trigger button
.lyd-select-dropdown Dropdown options container
.lyd-select-option Individual option item
.lyd-select-search Search input container
.lyd-select-icon Dropdown arrow icon
.small Small size variant
.large Large size variant
.active Active/open state
.selected Selected option state
.disabled Disabled option state
.multi Multi-select variant

Accessibility & Best Practices

Keyboard Navigation

  • Enter/Space to open dropdown
  • Arrow keys to navigate options
  • Enter to select option
  • Escape to close dropdown

Screen Reader Support

  • Use aria-expanded for dropdown state
  • Announce selected value
  • Provide clear labels
  • Role="listbox" for options

Best Practices

  • Provide a default/placeholder
  • Show selected state clearly
  • Handle long option lists with scroll
  • Consider search for 10+ options

Visual Feedback

  • Clear hover states
  • Focus indicators
  • Disabled state styling
  • Loading states when needed