Skip to content

Commit 51e4027

Browse files
authored
Merge pull request #21 from Leets-Official/14-feat/TextField-컴포넌트-제작
[Feat] TextField 컴포넌트 제작
2 parents 11c8cd5 + b112e0b commit 51e4027

10 files changed

Lines changed: 738 additions & 0 deletions

File tree

src/pages/playground.tsx

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Checkbox } from '@shared/ui/Checkbox/Checkbox';
44
import { Header } from '@shared/ui/Header/Header';
55
import { Profile } from '@shared/ui/Profile/Profile';
66
import { RadioButton } from '@shared/ui/RadioButton/RadioButton';
7+
import { TextField } from '@shared/ui/TextField/TextField';
78

89
export default function Playground() {
910
return (
@@ -104,6 +105,124 @@ export default function Playground() {
104105
dateText="1일 전"
105106
/>
106107
</section>
108+
109+
{/* TextField 예시 */}
110+
<section className="flex flex-col gap-4">
111+
<h2 className="typo-body-1">TextField</h2>
112+
113+
<div className="flex flex-wrap gap-10">
114+
{/* Char Field */}
115+
<div className="flex flex-col gap-4">
116+
<h3 className="typo-caption-1 font-semibold">Char Field</h3>
117+
118+
<div className="w-127.25">
119+
<TextField
120+
type="char"
121+
label="Char Field"
122+
placeholder="Enter your username"
123+
showCharacterCount
124+
helperText="Default"
125+
/>
126+
</div>
127+
128+
<div className="w-127.25">
129+
<TextField
130+
type="char"
131+
label="Char Field"
132+
placeholder="Enter your username"
133+
showCharacterCount
134+
error
135+
helperText="Error"
136+
/>
137+
</div>
138+
139+
<div className="w-127.25">
140+
<TextField
141+
type="char"
142+
label="Char Field"
143+
placeholder="Enter your username"
144+
showCharacterCount
145+
disabled
146+
helperText="Disabled"
147+
/>
148+
</div>
149+
</div>
150+
151+
{/* TextArea Field */}
152+
<div className="flex flex-col gap-4">
153+
<h3 className="typo-caption-1 font-semibold">TextArea Field</h3>
154+
155+
<div className="w-127.25">
156+
<TextField
157+
type="textarea"
158+
label="TextArea Field"
159+
placeholder="Enter a description"
160+
showCharacterCount
161+
helperText="Default"
162+
/>
163+
</div>
164+
165+
<div className="w-127.25">
166+
<TextField
167+
type="textarea"
168+
label="TextArea Field"
169+
placeholder="Enter a description"
170+
showCharacterCount
171+
error
172+
helperText="Error"
173+
/>
174+
</div>
175+
176+
<div className="w-127.25">
177+
<TextField
178+
type="textarea"
179+
label="TextArea Field"
180+
placeholder="Enter a description"
181+
showCharacterCount
182+
disabled
183+
helperText="Disabled"
184+
/>
185+
</div>
186+
</div>
187+
188+
{/* Price Field */}
189+
<div className="flex flex-col gap-4">
190+
<h3 className="typo-caption-1 font-semibold">Price Field</h3>
191+
192+
<div className="w-127.25">
193+
<TextField
194+
type="price"
195+
label="Price Field"
196+
placeholder="Enter price"
197+
defaultValue="10000"
198+
helperText="Default"
199+
/>
200+
</div>
201+
202+
<div className="w-127.25">
203+
<TextField
204+
type="price"
205+
label="Price Field"
206+
placeholder="Enter price"
207+
defaultValue="10000"
208+
error
209+
helperText="Error"
210+
/>
211+
</div>
212+
213+
<div className="w-127.25">
214+
<TextField
215+
type="price"
216+
label="Price Field"
217+
placeholder="Enter price"
218+
defaultValue="10000"
219+
disabled
220+
helperText="Disabled"
221+
/>
222+
</div>
223+
</div>
224+
</div>
225+
</section>
107226
</div>
108227
);
109228
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { TextField } from '@shared/ui/TextField/TextField';
2+
import type { CharFieldProps } from '@shared/ui/TextField/TextField.types';
3+
4+
export const CharField = (props: CharFieldProps) => <TextField type="char" {...props} />;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { TextField } from '@shared/ui/TextField/TextField';
2+
import type { PriceFieldProps } from '@shared/ui/TextField/TextField.types';
3+
4+
export const PriceField = (props: PriceFieldProps) => <TextField type="price" {...props} />;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { TextField } from '@shared/ui/TextField/TextField';
2+
import type { TextAreaFieldProps } from '@shared/ui/TextField/TextField.types';
3+
4+
export const TextAreaField = (props: TextAreaFieldProps) => (
5+
<TextField type="textarea" {...props} />
6+
);
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import { TextField } from '@shared/ui/TextField/TextField';
2+
import type { Meta, StoryObj } from '@storybook/react-vite';
3+
4+
const meta = {
5+
title: 'Shared/UI/TextField',
6+
component: TextField,
7+
parameters: {
8+
layout: 'centered',
9+
},
10+
tags: ['autodocs'],
11+
argTypes: {
12+
type: {
13+
control: 'select',
14+
options: ['text', 'char', 'textarea', 'price'],
15+
description: 'TextField type',
16+
},
17+
label: { control: 'text' },
18+
placeholder: { control: 'text' },
19+
disabled: { control: 'boolean' },
20+
error: { control: 'boolean' },
21+
helperText: { control: 'text' },
22+
showCharacterCount: { control: 'boolean' },
23+
value: { control: 'text' },
24+
defaultValue: { control: 'text' },
25+
},
26+
} satisfies Meta<typeof TextField>;
27+
28+
export default meta;
29+
type Story = StoryObj<typeof meta>;
30+
31+
export const Showcase: Story = {
32+
name: 'Playground Showcase (9)',
33+
render: () => (
34+
<div className="flex flex-wrap gap-10">
35+
{/* Char Field */}
36+
<div className="flex flex-col gap-4">
37+
<h3 className="typo-caption-1 font-semibold">Char Field</h3>
38+
39+
<div className="w-127.25">
40+
<TextField
41+
type="char"
42+
label="Char Field"
43+
placeholder="Enter your username"
44+
showCharacterCount
45+
helperText="Default"
46+
/>
47+
</div>
48+
49+
<div className="w-127.25">
50+
<TextField
51+
type="char"
52+
label="Char Field"
53+
placeholder="Enter your username"
54+
showCharacterCount
55+
error
56+
helperText="Error"
57+
/>
58+
</div>
59+
60+
<div className="w-127.25">
61+
<TextField
62+
type="char"
63+
label="Char Field"
64+
placeholder="Enter your username"
65+
showCharacterCount
66+
disabled
67+
helperText="Disabled"
68+
/>
69+
</div>
70+
</div>
71+
72+
{/* TextArea Field */}
73+
<div className="flex flex-col gap-4">
74+
<h3 className="typo-caption-1 font-semibold">TextArea Field</h3>
75+
76+
<div className="w-127.25">
77+
<TextField
78+
type="textarea"
79+
label="TextArea Field"
80+
placeholder="Enter a description"
81+
showCharacterCount
82+
helperText="Default"
83+
/>
84+
</div>
85+
86+
<div className="w-127.25">
87+
<TextField
88+
type="textarea"
89+
label="TextArea Field"
90+
placeholder="Enter a description"
91+
showCharacterCount
92+
error
93+
helperText="Error"
94+
/>
95+
</div>
96+
97+
<div className="w-127.25">
98+
<TextField
99+
type="textarea"
100+
label="TextArea Field"
101+
placeholder="Enter a description"
102+
showCharacterCount
103+
disabled
104+
helperText="Disabled"
105+
/>
106+
</div>
107+
</div>
108+
109+
{/* Price Field */}
110+
<div className="flex flex-col gap-4">
111+
<h3 className="typo-caption-1 font-semibold">Price Field</h3>
112+
113+
<div className="w-127.25">
114+
<TextField
115+
type="price"
116+
label="Price Field"
117+
placeholder="Enter price"
118+
defaultValue="10000"
119+
helperText="Default"
120+
/>
121+
</div>
122+
123+
<div className="w-127.25">
124+
<TextField
125+
type="price"
126+
label="Price Field"
127+
placeholder="Enter price"
128+
defaultValue="10000"
129+
error
130+
helperText="Error"
131+
/>
132+
</div>
133+
134+
<div className="w-127.25">
135+
<TextField
136+
type="price"
137+
label="Price Field"
138+
placeholder="Enter price"
139+
defaultValue="10000"
140+
disabled
141+
helperText="Disabled"
142+
/>
143+
</div>
144+
</div>
145+
</div>
146+
),
147+
};
148+
149+
/**
150+
* (옵션) 단일 스토리들도 기본적인 확인용으로 남겨두고 싶으면 최소만 유지
151+
*/
152+
export const CharDefault: Story = {
153+
args: {
154+
type: 'char',
155+
label: 'Char Field',
156+
placeholder: 'Enter your username',
157+
showCharacterCount: true,
158+
helperText: 'Default',
159+
},
160+
};
161+
162+
export const TextareaDefault: Story = {
163+
args: {
164+
type: 'textarea',
165+
label: 'TextArea Field',
166+
placeholder: 'Enter a description',
167+
showCharacterCount: true,
168+
helperText: 'Default',
169+
},
170+
};
171+
172+
export const PriceDefault: Story = {
173+
args: {
174+
type: 'price',
175+
label: 'Price Field',
176+
placeholder: 'Enter price',
177+
defaultValue: '10000',
178+
helperText: 'Default',
179+
},
180+
};

0 commit comments

Comments
 (0)