Skip to content

Commit 4b04dc1

Browse files
committed
feat(#52): TextField 컴포넌트 생성
1 parent 1b608e4 commit 4b04dc1

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { style } from "@vanilla-extract/css";
2+
import { recipe } from "@vanilla-extract/recipes";
3+
4+
import { radius, semantic, typography } from "@/styles";
5+
6+
export const wrapper = style({
7+
display: "flex",
8+
flexDirection: "column",
9+
gap: "8px",
10+
});
11+
12+
export const title = style({
13+
...typography.label1,
14+
fontWeight: 600,
15+
color: semantic.text.alternative,
16+
});
17+
18+
export const input = recipe({
19+
base: {
20+
width: "100%",
21+
height: "52px",
22+
padding: "14px 12px",
23+
...typography.body1,
24+
fontWeight: "500",
25+
border: "none",
26+
borderRadius: radius[160],
27+
outline: "none",
28+
},
29+
variants: {
30+
status: {
31+
inactive: {
32+
backgroundColor: semantic.surface.gray,
33+
color: semantic.text.disabled,
34+
35+
selectors: {
36+
"&:focus": {
37+
backgroundColor: semantic.surface.white,
38+
color: semantic.text.normal,
39+
caretColor: semantic.border.pressed,
40+
border: `1px solid ${semantic.border.pressed}`,
41+
outline: "none",
42+
},
43+
"&:disabled": {
44+
backgroundColor: semantic.surface.disabled,
45+
color: semantic.text.disabled,
46+
cursor: "not-allowed",
47+
},
48+
"&:not(:placeholder-shown):not(:focus)": {
49+
backgroundColor: semantic.surface.gray,
50+
color: semantic.text.normal,
51+
},
52+
},
53+
},
54+
negative: {
55+
backgroundColor: semantic.surface.white,
56+
color: semantic.text.normal,
57+
border: `1px solid ${semantic.status.negative}`,
58+
},
59+
},
60+
},
61+
defaultVariants: {
62+
status: "inactive",
63+
},
64+
});
65+
66+
export const helperText = recipe({
67+
base: {
68+
...typography.caption1,
69+
fontWeight: "500",
70+
color: semantic.text.alternative,
71+
},
72+
variants: {
73+
status: {
74+
inactive: {},
75+
focus: {},
76+
filled: {},
77+
disabled: {},
78+
negative: { color: semantic.status.negative },
79+
},
80+
},
81+
defaultVariants: {
82+
status: "inactive",
83+
},
84+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { type ComponentProps } from "react";
2+
3+
import * as styles from "./TextField.css";
4+
5+
type Status = "inactive" | "negative";
6+
7+
type TextFieldProps = {
8+
title?: string;
9+
helperText?: string;
10+
status?: Status;
11+
} & ComponentProps<"input">;
12+
13+
export function TextField({
14+
title,
15+
helperText,
16+
status = "inactive",
17+
ref,
18+
...props
19+
}: TextFieldProps) {
20+
return (
21+
<div className={styles.wrapper}>
22+
{title && <p className={styles.title}>{title}</p>}
23+
<input ref={ref} className={styles.input({ status })} {...props} />
24+
{helperText && (
25+
<p className={styles.helperText({ status })}>{helperText}</p>
26+
)}
27+
</div>
28+
);
29+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { TextField } from "./TextField";

0 commit comments

Comments
 (0)