프로젝트

Input 컴포넌트

나는시화 2023. 12. 5. 16:44
.inputbox{
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.inputbox-laber{
  color:rgba(0, 0, 0, 0.7);
  font-size: 14px;
  font-weight: 400;
  line-height: 140%;
}
.inputbox-container{
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
  padding: 11px 16px 11px 0px;
  display: flex;
  align-items: center;
}
.inputbox-container-error{
  border-bottom: 1px solid rgba(255, 0, 0, 0.7);
  padding: 11px 16px 11px 0px;
  background-color: rgba(250, 250, 250, 1);
  display: flex;
  align-items: center;
}
.input{
  border: none;
  background: none;
  outline: none;

  flex:1;

  color: rgba(0, 0, 0, 0.7);
  font-size: 14px;
  font-weight: 400;
  line-height: 140%;
}
.inputbox-message{
  color: rgba(255, 0, 0, 0.7);

  font-size: 10px;
  font-weight: 400;
  line-height: 140%;
}​
import React, { ChangeEvent,KeyboardEvent, forwardRef } from 'react';
import './style.css';

// interface: Input Box 컴포넌트 Properties
interface Props{
  label: string;
  type: 'text' | 'password';
  placeholder: string;
  value: string;
  setValue: React.Dispatch<React.SetStateAction<string>>;
  error: boolean;

  icon?: string ;
  onButtonClick?: ()=>void;

  message?: string;

  onKeyDown?:(event:KeyboardEvent<HTMLInputElement>)=>void;
}

// component: Input Box 컴포넌트
const InputBox = forwardRef<HTMLInputElement, Props>((props: Props, ref) =>{

  // state: properties
  const {label,type,error,placeholder,value,icon,message} = props;
  const {setValue,onButtonClick,onKeyDown} = props;

  // event handler : input 값 변경 이벤트 처리 함수 
  const onChangeHandler = (event: ChangeEvent<HTMLInputElement>) =>{
    const {value} = event.target;
    setValue(value);
  }

  // event handler : input 키 이벤트 처리 함수 
  const onKeyDownHandler = (event: KeyboardEvent<HTMLInputElement>) =>{
    if(!onKeyDown) return;
    onKeyDown(event);
  }

  // render: Input Box 컴포넌트
  return (
    <div className='inputbox'>
      <div className='inputbox-label'>{label}</div>
      <div className={error ? 'inputbox-container-error' : 'inputbox-container'}>
        <input ref={ref} type={type} className='input' placeholder={placeholder} value={value} onChange={onChangeHandler} onKeyDown={onKeyDownHandler}/>
        {onButtonClick !== undefined &&
          <div className='icon-button'>
            {icon !== undefined && <div className={`icon ${icon}`}></div>}
          </div>
        }
        <div className='icon-button'>
          <div className='icon eye-light-off-icon'></div>
        </div>
      </div>
      {message!==undefined &&<div className='inputbox-message'>{message}</div>}
      
    </div>
  );
});

export default InputBox;

 

어려웠던 점 : Ref, forwordRef(부모->자식 html element )

강의를 들으면서 내가 이전에 했던 프로젝트는 매우 부족하다는 걸 다시 한번 느꼈다. 

무엇을 만들고 싶은지, 어떤 기능들이 필요한지 등 계획을 제대로 세우고 해야지 나중에 코드 중복, 코드 수정 등 불필요한 행동들을 줄일 수가 있을 거 같다.

타입 스크립트를 처음 사용해보는데 문법을 완전히 익히고 사용하는 것이 아니라 모르는 것들이 많은데, 이 부분들을 따로 공부하는 시간이 많이 들고 있다. 

재밌다..