next js 드롭다운 예제

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

interface SortOption {
  value: string;
  label: string;
}

interface SortDropdownProps {
  options: SortOption[];
  defaultValue: string;
  onChange: (value: string) => void;
}

const SortDropdown = ({ options, defaultValue, onChange }: SortDropdownProps) => {
  const [isOpen, setIsOpen] = useState(false);
  const [selectedValue, setSelectedValue] = useState(defaultValue);
  const dropdownRef = useRef<HTMLSpanElement>(null);
  const firstOptionRef = useRef<HTMLSpanElement>(null);

  const handleDropdownClick = () => {
    setIsOpen(!isOpen);
    
    if (!isOpen) {
      setTimeout(() => {
        firstOptionRef.current?.focus();
      }, 500);
    }
  };

  const handleOptionSelect = (value: string) => {
    setSelectedValue(value);
    onChange(value);
    setIsOpen(false);
    dropdownRef.current?.focus();
  };

  return (
    <div className="sort-dropdown">
      <span
        ref={dropdownRef}
        role="button"
        tabIndex={0}
        aria-haspopup="listbox"
        aria-expanded={isOpen}
        onClick={handleDropdownClick}
      >
        {options.find(opt => opt.value === selectedValue)?.label}
      </span>

      {isOpen && (
        <div 
          role="radiogroup"
          aria-label="정렬 옵션"
          className="dropdown-options"
        >
          {options.map((option, index) => (
            <span
              key={option.value}
              ref={index === 0 ? firstOptionRef : null}
              role="radio"
              tabIndex={0}
              aria-checked={selectedValue === option.value}
              onClick={() => handleOptionSelect(option.value)}
            >
              {option.label}
            </span>
          ))}
        </div>
      )}
    </div>
  );
};

export default SortDropdown;

Comments

답글 남기기