이전에 올린 포스팅에서의 인풋 애니메이션에는 문제가 2가지가 있었다.
일단 이전에는 onFocus
와 onBlur
를 사용해 거기에 True
/ False
값으로
각각에 따른 스타일을 주었는데
첫번째 문제는 같은 useState
를 사용하면 이메일 부분이Focus
되어도 다른 인풋들 모두 같이 애니메이션이 변한다는 점이고
두번째 문제는 Input 안에 값이 있을때는 동작을 하지않아 Label
이 Input value
값을 가려버리는 문제였다.
그래서 첫번째 문제를 해결하기 위해 각각의 인풋에 다른 useState
값을 주었고 그러다보니 같은 동작을 하는 함수임에도 쓸데없이 많아졌다.
이런식으로...
그리고 두번째 문제가 Input 안에 값이 있을때는 조건식으로 된 Css 값이 동작을 안해서 Label이 Input 값을 가려버린다는 건데 ...
이 두가지 문제를 해결할 수 있는 방법이 있었고 의외로 간단했다 !ㅇ!
peer
는 바로 뒤 형제 요소에Css
를 입힐 때 사용한다. 셀렉터에서~
의 역할이다.
peer를 사용함으로써 label
이 Input
에 일어난 event
를 감지하고 그에 맞는 스타일을 입혀주는 것이다!!
나는 peer-focus
와 peer-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 만들면 더 간결해질텐데 나중에 리팩토링해야겠당