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 스타일 |
label | string | - | Floating label (포커스 또는 값이 있을 때 위로 이동) |
placeholder | string | - | Placeholder 텍스트 |
value | string | - | Input 값 |
isError | boolean | false | 에러 상태 |
errorMessage | string | - | 에러 메시지 (설정 시 자동으로 에러 상태로 표시) |
disabled | boolean | false | 비활성화 여부 |
maxLength | number | - | 최대 글자 수 (입력 제한 및 카운터 표시) |
leftIcon | React.ReactNode | - | 왼쪽 아이콘 |
rightIcon | React.ReactNode | - | 오른쪽 아이콘 |
onClear | () => void | - | Clear 버튼 클릭 핸들러 (설정 시 Clear 버튼 표시) |
color | string | - | Input 테두리/포커스 색상 |
autoFocus | boolean | false | 자동 포커스 여부 |
autoSelect | boolean | false | 자동 텍스트 선택 여부 (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}