Input Animation (Label 을 Placeholder 처럼 사용하기)

시도·2023년 5월 2일
0

React

목록 보기
6/7

로그인과 회원가입 인풋에 들어갈 애니메이션의 최종 버전이다.

🔥 문제


이전에 올린 포스팅에서의 인풋 애니메이션에는 문제가 2가지가 있었다.

일단 이전에는 onFocusonBlur 를 사용해 거기에 True / False 값으로
각각에 따른 스타일을 주었는데

첫번째 문제는 같은 useState를 사용하면 이메일 부분이Focus 되어도 다른 인풋들 모두 같이 애니메이션이 변한다는 점이고

두번째 문제는 Input 안에 값이 있을때는 동작을 하지않아 LabelInput value 값을 가려버리는 문제였다.


그래서 첫번째 문제를 해결하기 위해 각각의 인풋에 다른 useState 값을 주었고 그러다보니 같은 동작을 하는 함수임에도 쓸데없이 많아졌다.

이런식으로...


그리고 두번째 문제가 Input 안에 값이 있을때는 조건식으로 된 Css 값이 동작을 안해서 Label이 Input 값을 가려버린다는 건데 ...

이 두가지 문제를 해결할 수 있는 방법이 있었고 의외로 간단했다 !ㅇ!


🔥 문제 해결

Peer

peer는 바로 뒤 형제 요소에 Css를 입힐 때 사용한다. 셀렉터에서 ~의 역할이다.

peer를 사용함으로써 labelInput에 일어난 event를 감지하고 그에 맞는 스타일을 입혀주는 것이다!!

나는 peer-focuspeer-valid를 이용해 스타일을 주었다.

  • peer-focus : peer 요소가 focus 되었을때 스타일을 지정
  • peer-valid : peer 요소에 값이 있을때 스타일을 지정

그리고 많은 css때메 값을 넣기도 불편하고 다른곳에서 Input을 만들때도 불편하여 css를 따로 빼주고 다른곳에서도 사용할수 있게 export 해주었다.

❗️참고로 input 에 꼭 required 속성이 있어야지 동작함

import React from "react";
import Button from "../Button/Button";
import { FcGoogle } from "react-icons/fc";
import { googleLogin } from "../../api/firebase";

export const INPUT_CSS = `border border-gray-600 w-full rounded-[4px] h-14 pt-4 pl-3 mb-1 peer transition
         `;
export const LABEL_CSS = `text-md absolute font-gray-600 transition ease-in-out left-3 top-4
         peer-focus:-translate-x-2 peer-focus:scale-75 peer-focus:-translate-y-3  peer-valid:scale-75 peer-valid:-translate-x-2 peer-valid:-translate-y-3`;

const LoginInput = () => {
  const handleLogin = () => {};
  const handleGoogleLogin = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    googleLogin();
  };

  return (
    <form className=" w-72 mx-auto flex flex-col justify-center">
      <div className="relative">
        <input type="text" id="email" name="email" className={`${INPUT_CSS}`} required />
        <label
          htmlFor="email"
          className={`${LABEL_CSS}
         `}
        >
          이메일
        </label>
      </div>
      <div className="relative">
        <input type="text" id="pw" name="pw" className={`${INPUT_CSS}`} required />
        <label htmlFor="pw" className={`${LABEL_CSS}`}>
          비밀번호
        </label>
      </div>
      <Button onClick={handleLogin} label="로그인" textStyle="text-white" bgStyle="bg-blue-600" />
      <Button onClick={handleGoogleLogin} label="Google 로그인" icon={FcGoogle} textStyle="text-blue-600" bgStyle="bg-white" borderStyle="border border-blue-600" />
    </form>
  );
};

export default LoginInput;

Tailwind peer-[] 공식문서
https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-sibling-state


덕분에 코드가 줄어들고 가독성도 해결되서 속이 너무 시원하다 😿
(Tailwind 최고!) 근데 그냥 Input Component 만들면 더 간결해질텐데 나중에 리팩토링해야겠당

profile
나의 성장일지 💫

0개의 댓글