Next.js TypeScript Input 태그 커스텀 라디오

HYEONGWOO IM·2023년 10월 17일

FE

목록 보기
1/5

작성이유

과제 진행 중 게임 모드(일반모드, 스페셜모드)를 나눌 필요가 있었고 div로 만들려다가 input태그를 써보자는 느낌으로 만들었고, 정리하기 위해 작성.

- input태그 장점

  • 의미론적: 라디오 버튼은 선택 사항을 나타내며, 사용자에게 선택을 할 수 있는 방법을 제공합니다. div는 단순한 컨테이너로 사용되며 의미를 가지지 않습니다. HTML은 의미론적으로 마크업하는 것이 중요하며, 라디오 버튼은 그 목적에 부합

  • 웹 접근성: 라디오 버튼은 웹 접근성을 높이는 데 도움이 됩니다. 스크린 리더 및 다른 보조 기술은 라디오 버튼을 올바르게 해석하고 사용자에게 선택 사항을 알려줄 수 있습니다. div로 구현할 경우, 추가적인 ARIA (Accessible Rich Internet Applications) 속성 및 스크립트로 접근성을 확보해야 합니다.

  • 브라우저 호환성: 라디오 버튼은 거의 모든 웹 브라우저에서 일반적으로 지원됩니다. 반면, 일부 브라우저는 CSS 스타일링이나 JavaScript로 구현된 사용자 정의 라디오 버튼과 같은 커스텀 컨트롤을 다르게 해석할 수 있습니다.

코드

      <section className={styles.btn}>
              <section className={styles.inputRadio}>
        <input
          type="radio"
          value="normal"
          name="gameModeGroup"
          id="normal"
          onChange={selectGameMode}
          checked={gameMode == 'normal'}
        />
        <label htmlFor="normal">
          {gameMode == 'normal' ? (
            <span className={styles.selectNormalText}>
              <Image
                src={selectnormalBtn}
                alt={'prvBtn'}
                className={styles.selectNormalBtn}
                width={40}
              />{' '}
              Normal
            </span>
          ) : (
            <span className={styles.normalText}>
              <Image
                src={normalBtn}
                alt={'prvBtn'}
                className={styles.normalBtn}
                width={40}
              />{' '}
              Normal
            </span>
          )}
        </label>
        <input
          type="radio"
          value="special"
          name="gameModeGroup"
          id="special"
          onChange={selectGameMode}
        />
        <label htmlFor="special">
          {gameMode == 'special' ? (
            <span className={styles.selectSpecialText}>
              <Image
                src={selectSpecialBtn}
                alt={'prvBtn'}
                className={styles.selectSpecialBtn}
                width={40}
              />
              Special
            </span>
          ) : (
            <span className={styles.specialText}>
              <Image
                src={specialBtn}
                alt={'prvBtn'}
                className={styles.SpecialBtn}
                width={40}
              />
              Special
            </span>
          )}
        </label>

부분 별 설명

input 태그

        <input
          type="radio"
          value="normal"
          name="gameModeGroup"
          id="normal"
          onChange={selectGameMode}
          checked={gameMode == 'normal'}
        />

type = 라디오
value = normal
name = gameModeGroup -> name으로 다른 input태그와 연동?연결?시킬 수 있음 다른 태그를 클릭 시 해당 태그는 체크가 해제됨.

onChanhe = {selectGameMode} ->해당 인풋 클릭 시 selectGameMode가 호출됨.

  const selectGameMode = (e: React.ChangeEvent<HTMLInputElement>) => {
    setGameMode(e.target.value)
  }

selectGameMode 는 해당 이벤트의 value "normal"을 가져와 setGameMode의 인자로 넣어줌
checked = {gameMode == 'normal'} 해당 인풋 라디오태그의 선택조건은 gamemode가 normal일 때 체크된다. 는 의미!

label태그

        <label htmlFor="normal">
          {gameMode == 'normal' ? (
            <span className={styles.selectNormalText}>
              <Image
                src={selectnormalBtn}
                alt={'prvBtn'}
                className={styles.selectNormalBtn}
                width={40}
              />{' '}
              Normal
            </span>
          ) : (
            <span className={styles.normalText}>
              <Image
                src={normalBtn}
                alt={'prvBtn'}
                className={styles.normalBtn}
                width={40}
              />{' '}
              Normal
            </span>
          )}
        </label>

label 태그가 클릭되어도 체크박스가 클릭된 것 처럼 하기 위해 htmlFor="normal"로 지정
gameMode의 벨류에 따라 선택이 되고 안되고가 나뉘어 지기 때문에 해당 3항연산자를 이용하여 분기를 해주었음.

Css

.inputRadio{
  display: flex;
  font-family: 'Pretendard-regular';
  gap: 40px;
  font-size: 24px;
  input[type="radio"] {
    display: none; /* 또는 visibility: hidden; */
  }
}

.selectnormalText{
  color: black;
}

.normalText{
  color: #D7D8E0;
}

.selectSpecialText{
  color: black
}

.specialText{
  color: #D7D8E0;
}

결과

0개의 댓글