[ React ] SelectBox 컴포넌트 키보드 이벤트 추가 | onKeyDown

2024. 7. 11. 09:47· React
목차
  1. 1. tabIndex 속성 설정
  2. 2. onKeyDown 이벤트 핸들러
  3. 3. hover한 item에 focus 할당
  4. 4. 옵션 리스트 다시 열리면 focus 값 초기화
  5. 5. Enter 시 선택
  6. 6. 선택된 값이 있으면 해당 값에 focus
728x90

키보드 이벤트 타입은 총 3가지가 있다. 

 

[ 모던 자바스크립트 ] 40. 이벤트

1) 이벤트 드리븐 프로그래밍이벤트가 발생했을 때 호출될 함수를 이벤트 핸들러라 하고, 이벤트가 발생했을 때 브라우저에게 이벤트 핸들러의 호출을 위임하는 것을 이벤트 핸들러 등록이라

zodev.tistory.com

[ 모던 자바스크립트 ] 40. 이벤트

 

 

그 중에서도 가장 keydown 이벤트를 활용하여 키보드 방향키 + Enter 키로 옵션을 선택하는 기능을 구현할 것이다.

 


 

 

1. tabIndex 속성 설정

이벤트를 받으려는 HTML 요소에 tabIndex 속성을 설정하고, (그래야 div 요소가 포커스를 받을 수 있다.)

SelectorBox 컴포넌트에 keydown 이벤트를 바인딩한다.

  • tabIndex : 요소가 포커스 가능함을 의미
  • SelectorBox는 div(비 대화형 콘텐츠)이기 때문에 tabindex = -1 이 기본값이다.
  • 이를 키보드 탐색으로도 접근 가능하도록 tabindex = 0 으로 변경해준다.

 

 

 

2. onKeyDown 이벤트 핸들러

  • 아래 방향키
    • 한 칸 아래 요소로 이동
    • 맨 마지막 요소일 경우 가장 처음으로 이동
  • 위 방향키
    • 한 칸 위 요소로 이동
    • 맨 처음 요소일 경우 가장 마지막으로 이동
  const findIndexDown = (prevIndex: number | null) => {
    // prevIndex가 없거나 마지막 요소일 때 처음 항목을 focus
    if (prevIndex === null || prevIndex === options.length - 1) return 0;
    else return prevIndex + 1;
  };

  const findIndexUp = (prevIndex: number | null) => {
    // prevIndex가 없거나 첫 번째 요소일 때 마지막 항목을 focus
    if (prevIndex === null || prevIndex === 0) return options.length - 1;
    else return prevIndex - 1;
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
    switch (e.key) {
      case "ArrowDown":
        setFocusedIndex((prevIndex) => findIndexDown(prevIndex));
        return;
      case "ArrowUp":
        setFocusedIndex((prevIndex) => findIndexUp(prevIndex));
        return;
      case "Enter":
        console.log("Enter~");
        return;
    }
  };

 

 

 

3. hover한 item에 focus 할당

OptionItem 컴포넌트에 onMouseOver 이벤트 핸들러를 바인딩해서 hover한 item도 키보드 방향키로 선택한 아이템처럼 focus 스타일링을 해준다.

<CommonOptionItem
  key={idx}
  onClick={() => handleClick(option)}
  onMouseOver={() => setFocusedIndex(idx)}
>

 

 

 

4. 옵션 리스트 다시 열리면 focus 값 초기화

handlePopup 함수에서 팝업 열릴 때 초기화를 실행해준다. 

 

 

 

5. Enter 시 선택

case "Enter":
  if (typeof focusedIndex === "number") {
    onChange(options[focusedIndex]);
    handlePopup();
  }
  return;

조건을 if (focusedIndex) 로 할 경우, 인덱스가 0일 때도 false를 가지게 되므로 fucusedIndex의 타입과 비교를 해줬다.

 

 

 

6. 선택된 값이 있으면 해당 값에 focus

// 선택된 아이템이 있을 경우 해당 아이템 focus
const selectedIndex = () => {
const newIndex = options.findIndex((option) => option === item);
if (newIndex !== -1) setFocusedIndex(newIndex);
};

 

 

 

 

제법 SelectBox 같아지는 중....!

 

 

 

 

728x90

'React' 카테고리의 다른 글

[ React ] CommonTable 컴포넌트 기본 구현 (정렬, 체크박스, 스크롤 등)  (0) 2024.07.16
[ React ] DatePicker, SelectBox의 팝업을 createPortal로 변경  (0) 2024.07.12
[ React ] input 태그의 placeholder로 icon 사용하기  (0) 2024.07.10
[ React ] 검색 가능한 SelectBox 컴포넌트 구현  (0) 2024.07.04
[ React ] 기본 SelectBox 컴포넌트 구현  (1) 2024.07.03
  1. 1. tabIndex 속성 설정
  2. 2. onKeyDown 이벤트 핸들러
  3. 3. hover한 item에 focus 할당
  4. 4. 옵션 리스트 다시 열리면 focus 값 초기화
  5. 5. Enter 시 선택
  6. 6. 선택된 값이 있으면 해당 값에 focus
'React' 카테고리의 다른 글
  • [ React ] CommonTable 컴포넌트 기본 구현 (정렬, 체크박스, 스크롤 등)
  • [ React ] DatePicker, SelectBox의 팝업을 createPortal로 변경
  • [ React ] input 태그의 placeholder로 icon 사용하기
  • [ React ] 검색 가능한 SelectBox 컴포넌트 구현
ZoD
ZoD
바쁘게 굴러가는 ZoD의 하루~
ZoD
como siempre
ZoD
  • 분류 전체보기 (173)
    • Daily (0)
    • Javascript (16)
      • 모던 자바스크립트 (46)
    • Typescript (8)
    • FrontEnd (7)
    • React (21)
      • tanstack query (1)
      • 라이브러리 (3)
    • Vue (33)
      • Nuxt (11)
      • Quasar (6)
    • CSS (12)
    • Storybook (8)
    • Figma (3)
    • CS 지식 (5)
    • Network (5)
    • 알고리즘 (2)
    • 사이드 프로젝트 (4)
      • ddangkong (4)
      • boncierge (0)
    • 개발, 근데 이제 헛소리를 곁들인 (1)
    • ETC (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.v4.2.2
ZoD
[ React ] SelectBox 컴포넌트 키보드 이벤트 추가 | onKeyDown
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.