


type Picked = "onChange" | "placeholder" | "value" | "type";
interface InputProps extends Pick<ComponentProps<"input">, Picked> {
variant?: "static" | "move";
label?: string;
errorMessage?: string;
isSuccess?: boolean;
rightElement?: ReactNode;
onRightElementClick?: VoidFunction;
}
const TextInput = forwardRef<HTMLInputElement, InputProps>(
(
{
variant = "move",
errorMessage,
isSuccess = false,
label,
rightElement = null,
onRightElementClick,
...props
},
ref
) => {
variant: static → placeholder 고정variant: move → placeholder 위로 이동&:focus + label.move,
&:valid + label.move {
top: -10px;
font-size: 0.75rem;
}
rightElement → 우측 아이콘onRightElementClick → 우측 아이콘 이벤트 핸들러forwardRef → 외부에서 인풋 ref 에 접근할 수 있도록 하기 위함 (사용하는 곳에서 인풋 value 조작가능){errorMessage && <S.ErrorMessage>{errorMessage}</S.ErrorMessage>}다양한 상황에 공통으로 사용할 수 있는 인풋을 제작하는 것이 좀처럼 쉬운 일이 아니었다. 실제로 이렇게 만들어 두고 작업하면서 서너번 수정이 되었다. 다행히 유효성 검사를 원활하게 하기 위해 react-hook-form을 연결하는 과정에서 input props를 모두 받아놓게 type을 지정해 놓은 덕분에 큰 무리없이 연결할 수 있었다.
이번에는 시간이 많지 않아 딱 정해진 몇 가지 상황에 대응할 인풋을 제작하게 되었는데, 기회가 된다면 디자인 시스템을 정교하게 구축하는 경험을 가져보고 싶다.