[React] Material UI의 TextField 만들어보기
워낙 유명한 MUI의 TextField 컴포넌트다.
깔끔하고 직관적이다. 번잡하지 않은 애니메이션으로 UX도 상당히 좋다고 생각한다.
css만으로 해당 컴포넌트를 만들어보자.
구조는 아래처럼 input 태그와 label 태그를 감싸는 컨테이너 div 태그하나로 구성하였다.
//TextField.tsx
import { useState } from "react";
import "./style.css";
interface TextFieldProps {
label: string;
}
const TextField = (props: TextFieldProps) => {
const { label } = props;
const [value, setValue] = useState<string>("");
return (
<div className="container">
<input
className="input"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<label className="label">{label}</label>
</div>
);
};
export default TextField;
여기에 기본적인 css를 적용시켜주면...
.container {
position: relative;
}
.input {
padding: 0 10px;
height: 50px;
outline: none;
border: 1px solid;
border-radius: 4px;
border-color: gray;
transition: border 0.2s ease-in-out;
}
.input:focus {
border-color: blue;
}
이제 라벨 쪽에 css를 적용시켜보자.
라벨 쪽에 적용된 css를 간략히 설명해 보면, 컨테이너 요소 안에서 절대적인 위치를 가지도록 하고 세로로 중앙 정렬을 해준다.
top: 50%는 부모 요소 높이의 50%를 뜻하고, 거기서 translateY(-50%)로 자신의 높이의 절반만큼 다시 위로 올려주면
세로로 중앙 정렬이 된다.
그리고 Input이 focus 상태가 될때 라벨의 높이를 0%로, 폰트 사이즈와 컬러를 바꿔주면 얼추 비슷한 동작을 한다.
.input:focus + label {
font-size: 0.8rem;
top: 0%;
color: blue;
}
.label {
position: absolute;
pointer-events: none;
left: 5px;
padding: 0 5px;
top: 50%;
color: gray;
background-color: white;
transform: translateY(-50%);
transition: top 0.2s ease-in-out, font-size 0.2s ease-in-out,
color 0.2s ease-in-out;
}
동작은 비슷하게 하는데 input 태그 안에 value가 있음에도 label이 그 위를 덮어버리는 모습이다.
value가 비어있을 때가 아니면, label이 위에 붙어있도록 해보자.
.input:not([value=""]) + label {
font-size: 0.8rem;
top: 0%;
}
원하는 데로 동작한다. 이제 input 태그에 placeholder가 있는 경우만 해결하면 되는데,
mui에선 라벨이 우선적으로 보이고 input 태그가 focus된 순간에 placeholder가 보이기 때문에, 그에 맞게 css를 수정하자.
placeholder의 투명도를 0으로 낮추고, Input이 focus되면 opacity를 1로 올려보면..!
.input::placeholder {
opacity: 0;
transition: opacity 0.2s ease-in-out;
}
.input:focus::placeholder {
opacity: 1;
}
기능적인 면이나 퀄리티 면에서 훨씬 떨어지지만, mui의 TextField를 그럴싸하게 구현해 보았다.
이렇게 css만으로도 다양한 인터랙션을 만들어낼 수 있으니 잘 만들어진 요소들을 어떻게 구현했을까 상상하며
따라 만들어 보는 것도 프론트엔드 개발자의 역량을 높이는 데 도움이 될 것 같다.