Motile UI

Input

다양한 기능을 제공하는 Input 컴포넌트입니다. outlined 스타일과 밑줄 스타일을 지원하며, 에러 상태, 아이콘, 클리어 버튼, 글자 수 제한 등의 기능을 제공합니다. Floating label을 지원하여 더 나은 UX를 제공합니다.

미리보기

사용법

1"use client";
2
3import { useState } from "react";
4import { Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function PreviewExample() {
9  const [value, setValue] = useState("");
10
11  const handleChange: InputChangeHandler = (e) => {
12    setValue(e.target.value);
13  };
14
15  return (
16    <Input
17      placeholder="텍스트를 입력하세요..."
18      value={value}
19      onChange={handleChange}
20    />
21  );
22}

API 레퍼런스

Input

Input 컴포넌트

속성타입기본값설명
variant"outlined" | "underline""outlined"Input 스타일
labelstring-Floating label (포커스 또는 값이 있을 때 위로 이동)
placeholderstring-Placeholder 텍스트
valuestring-Input 값
isErrorbooleanfalse에러 상태
errorMessagestring-에러 메시지 (설정 시 자동으로 에러 상태로 표시)
disabledbooleanfalse비활성화 여부
maxLengthnumber-최대 글자 수 (입력 제한 및 카운터 표시)
leftIconReact.ReactNode-왼쪽 아이콘
rightIconReact.ReactNode-오른쪽 아이콘
onClear() => void-Clear 버튼 클릭 핸들러 (설정 시 Clear 버튼 표시)
colorstring-Input 테두리/포커스 색상
autoFocusbooleanfalse자동 포커스 여부
autoSelectbooleanfalse자동 텍스트 선택 여부 (autoFocus와 함께 사용)

기본 <code>input</code> HTML 속성을 모두 사용할 수 있습니다.

예제

Floating Label

1"use client";
2
3import { useState } from "react";
4import { Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function WithLabelExample() {
9  const [value, setValue] = useState("");
10
11  const handleChange: InputChangeHandler = (e) => {
12    setValue(e.target.value);
13  };
14
15  return (
16    <Input
17      label="이메일"
18      placeholder="이메일을 입력하세요"
19      value={value}
20      onChange={handleChange}
21    />
22  );
23}

에러 상태

1"use client";
2
3import { useState } from "react";
4import { Button, Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function WithErrorExample() {
9  const [value, setValue] = useState("");
10  const [error, setError] = useState("");
11
12  const handleChange: InputChangeHandler = (e) => {
13    setValue(e.target.value);
14    if (error) setError("");
15  };
16
17  const handleValidate = () => {
18    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
19    if (!value) {
20      setError("이메일을 입력해주세요");
21    } else if (!emailRegex.test(value)) {
22      setError("올바른 이메일 형식이 아닙니다");
23    } else {
24      setError("");
25    }
26  };
27
28  return (
29    <div style={{ display: "flex", flexDirection: "column", gap: "12px" }}>
30      <Input
31        label="이메일"
32        value={value}
33        onChange={handleChange}
34        errorMessage={error}
35      />
36      <Button onClick={handleValidate} variant="primary" size="small">
37        확인
38      </Button>
39    </div>
40  );
41}

아이콘

1"use client";
2
3import { useState } from "react";
4import { Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function WithIconExample() {
9  const [value, setValue] = useState("");
10
11  const handleChange: InputChangeHandler = (e) => {
12    setValue(e.target.value);
13  };
14
15  return (
16    <Input
17      placeholder="검색..."
18      value={value}
19      onChange={handleChange}
20      leftIcon={
21        <svg width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="2">
22          <path d="M9 17A8 8 0 1 0 9 1a8 8 0 0 0 0 16Z" />
23          <path d="m19 19-4.35-4.35" />
24        </svg>
25      }
26    />
27  );
28}

Clear 버튼

1"use client";
2
3import { useState } from "react";
4import { Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function WithClearExample() {
9  const [value, setValue] = useState("Clear me");
10
11  const handleChange: InputChangeHandler = (e) => {
12    setValue(e.target.value);
13  };
14
15  const handleClear = () => {
16    setValue("");
17  };
18
19  return (
20    <Input
21      placeholder="텍스트를 입력하세요..."
22      value={value}
23      onChange={handleChange}
24      onClear={handleClear}
25    />
26  );
27}

글자 수 제한

0/50
1"use client";
2
3import { useState } from "react";
4import { Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function WithCounterExample() {
9  const [value, setValue] = useState("");
10
11  const handleChange: InputChangeHandler = (e) => {
12    setValue(e.target.value);
13  };
14
15  return (
16    <Input
17      label="자기소개"
18      placeholder="50자 이내로 작성하세요"
19      value={value}
20      onChange={handleChange}
21      maxLength={50}
22    />
23  );
24}

Underline 스타일

0/50
1"use client";
2
3import { useState } from "react";
4import { Input } from "motile-ui";
5
6type InputChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;
7
8export default function UnderlineExample() {
9  const [value, setValue] = useState("");
10
11  const handleChange: InputChangeHandler = (e) => {
12    setValue(e.target.value);
13  };
14
15  const handleClear = () => {
16    setValue("");
17  };
18
19  return (
20    <Input
21      variant="underline"
22      label="검색어"
23      placeholder="검색..."
24      value={value}
25      onChange={handleChange}
26      onClear={handleClear}
27      maxLength={50}
28      leftIcon={
29        <svg width="18" height="18" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="2">
30          <path d="M9 17A8 8 0 1 0 9 1a8 8 0 0 0 0 16Z" />
31          <path d="m19 19-4.35-4.35" />
32        </svg>
33      }
34    />
35  );
36}

비활성화

1"use client";
2
3import { Input } from "motile-ui";
4
5export default function DisabledExample() {
6  return <Input placeholder="비활성화된 Input" disabled value="" />;
7}
Input | Motile UI