minyoung

공통 컴포넌트 - NicknameInput 본문

React/Makery

공통 컴포넌트 - NicknameInput

stylish-code 2024. 8. 28. 21:17

figma 디자인

  공통 컴포넌트 NicknameInput 개발 과정

NicknameInput 컴포넌트 구현
  • src/components/common/NicknameInput.jsx
import styled from "styled-components";

const NicknameInput = ({ type, placeholder, value, onChange, status }) => {
    return (
        <Input
            type={type}
            placeholder={placeholder}
            value={value}
            onChange={onChange}
            $status={status} // styled-components에 상태 전달, transient props
        />
    );
};

const Input = styled.input`
    background-color: transparent; // 기본 배경색 제거 (투명하게 설정)
    border: none; // 기본 테두리 제거
    outline: none; // 클릭했을 때 outline 제거
    width: 350px;
    height: 40px;

    // status prop에 따른 스타일 적용
    border-bottom: 1px solid
        ${({ $status, theme }) =>
            $status === "typing"
                ? theme.colors.main
                : $status === "duplicate"
                  ? theme.colors.sub
                  : theme.colors.gray_500};

    color: ${({ $status, theme }) =>
        $status === "typing"
            ? theme.colors.main
            : $status === "duplicate"
              ? theme.colors.sub
              : theme.colors.gray_400};

    &::placeholder {
        color: ${({ $status, theme }) =>
            $status === "typing"
                ? theme.colors.main
                : $status === "duplicate"
                  ? theme.colors.sub
                  : theme.colors.gray_400};
    }
`;

export default NicknameInput;
'NicknameInput' 컴포넌트는 사용자로부터 아이디(닉네임)을 입력받은 인풋 필드이다.
'styled-components'를 사용해 스타일링되어 있으며, 입력 상태에 따라 동적으로 스타일이 변경된다.
'status'는 transient props('$status')로 사용되어 스타일을 결정한다.
transient props는 직접 DOM에 전달되지 않으며, styled-components에서만 사용된다.
'status' prop 값에 따라 스타일 변경
'status' 값에 따라 'border-bottom', 'color', 'placeholder'의 색상이 다르게 적용된다.

✔️ status === "typing"
: 입력 중인 상태로, 메인 색상(theme.colors.main)이 적용된다.

✔️status === "duplicate"
: 입력한 값이 중복되었을 때, 서브 색상(theme.colors.sub)이 적용된다.

✔️ 그 외 -> deault
: 기본 상태로, 회색(theme.colors.gray_500 또는 theme.colors.gray_400)이 적용된다.

 

모듈 관리
  • src/components/common/index.js
export { default as LoginButton } from "../common/LoginButton";
export { default as NicknameInput } from "../common/NicknameInput";

 

테스트 코드
  • src/routes/Example.jsx
이 컴포넌트에서는 useState 훅을 사용해 입력 값(value)과 입력 상태(status)를 관리한다.
onChange 이벤트 핸들러에서 사용자가 입력한 값에 따라 status를 업데이트한다.

✔️ 중복 검사: newValue가 "test"일 때, 상태는 "duplicate"로 설정
✔️입력 중: newValue의 길이가 0보다 클 때, 상태는 "typing"으로 설정
✔️기본 상태: 입력이 없을 때, 상태는 "default"로 설정

 

// 'Example' 컴포넌트에서 입력 상태 관리
import styled from "styled-components";
import { NicknameInput } from "../components/common";
import { useState } from "react";

function Example() {
    const [value, setValue] = useState("");
    const [status, setStatus] = useState("default"); // "default", "typing", "duplicate"

    const onChange = (event) => {
        const newValue = event.target.value;
        setValue(newValue);

        // status
        if (newValue === "test") {
            setStatus("duplicate");
        } else if (newValue.length > 0) {
            setStatus("typing");
        } else {
            setStatus("default");
        }
    };

    return (
        <InputConatiner>
            <NicknameInput
                type="text"
                placeholder="id를 입력하세요."
                value={value}
                onChange={onChange}
                status={status}
            />
        </InputConatiner>
    );
}

const InputConatiner = styled.div`
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
`;

export default Example;