diff --git a/.storybook/preview-body.html b/.storybook/preview-body.html
new file mode 100644
index 0000000..6322ef7
--- /dev/null
+++ b/.storybook/preview-body.html
@@ -0,0 +1,2 @@
+
+
diff --git a/README.md b/README.md
index a456d1e..542296b 100644
--- a/README.md
+++ b/README.md
@@ -36,24 +36,27 @@ import FunEatProvider from '@fun-eat/design-system';
### Props
-| props | value | description |
-| --------- | ----------------------------------------------------- | -------------------------------------------- |
-| element | p, span (default: span) | Badge 컴포넌트의 element 타입입니다. |
-| color | CSSProperties['color'] | Badge 컴포넌트 내부 색상입니다. |
-| textColor | CSSProperties['color'] | Badge 컴포넌트에 들어갈 텍스트의 색상입니다. |
-| size? | `xs` , `sm`, `md` , `lg` , `xl`
(default: `sm`) | Badge 컴포넌트에 들어갈 텍스트의 크기입니다. |
-| css? | CSSProp | Badge 컴포넌트에 적용할 CSS 스타일입니다. |
+| props | value | description |
+| --------- | -------------------------------------- | -------------------------------------------- |
+| element | p, span
(default: span) | Badge 컴포넌트의 element 타입입니다. |
+| color | CSSProperties['color'] | Badge 컴포넌트 내부 색상입니다. |
+| textColor | CSSProperties['color'] | Badge 컴포넌트에 들어갈 텍스트의 색상입니다. |
+| size? | xs, sm, md, lg, xl
(default: sm) | Badge 컴포넌트에 들어갈 텍스트의 크기입니다. |
+| css? | CSSProp | Badge 컴포넌트에 적용할 CSS 스타일입니다. |
### Example
-```jsx
+```tsx
뱃지
뱃지
```
+
+
## BottomSheet
아래에서 위로 올라오는 바텀시트 컴포넌트입니다.
+
@fun-eat/design-system에서 제공하는 useBottomSheet와 사용해야 합니다.
### Props
@@ -85,22 +88,24 @@ const Parent = () => {
};
```
+
+
## Button
버튼 컴포넌트입니다.
### Props
-| props | value | description |
-| ------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
-| customWidth? | string
(default: 120px) | Button 컴포넌트의 넓이입니다. |
-| customHeight? | string
(default: 40px) | Button 컴포넌트의 높이입니다. |
-| color? | color
(default: `primary`) | Button 컴포넌트의 색상입니다. |
-| textColor? | color
(default: `default`) | Button 컴포넌트의 텍스트 색상입니다. |
-| size? | `xs`, `sm`, `md`, `lg`, `xl`
(default: `md`) | Button 컴포넌트의 폰트 크기입니다. |
-| weight? | `light`, `regular`, `bold`
(default: `bold`) | Button 컴포넌트의 폰트 가중치입니다. |
-| variant? | `outlined`, `filled`, `transparent`
(default: `filled`) | Button 컴포넌트의 스타일로 배경색 없이 아웃라인이 있는지, 배경색이 있고 아웃라인이 없는지, 투명 배경인지 설정할 수 있습니다. |
-| css? | CSSProp | Button 컴포넌트에 적용할 CSS 스타일입니다. |
+| props | value | description |
+| ------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
+| customWidth? | string
(default: 120px) | Button 컴포넌트의 넓이입니다. |
+| customHeight? | string
(default: 40px) | Button 컴포넌트의 높이입니다. |
+| color? | color
(default: primary) | Button 컴포넌트의 색상입니다. |
+| textColor? | color
(default: default) | Button 컴포넌트의 텍스트 색상입니다. |
+| size? | xs, sm, md, lg, xl
(default: md) | Button 컴포넌트의 폰트 크기입니다. |
+| weight? | light, regular, bold
(default: bold) | Button 컴포넌트의 폰트 가중치입니다. |
+| variant? | outlined, filled, transparent
(default: filled) | Button 컴포넌트의 스타일로 배경색 없이 아웃라인이 있는지, 배경색이 있고 아웃라인이 없는지, 투명 배경인지 설정할 수 있습니다. |
+| css? | CSSProp | Button 컴포넌트에 적용할 CSS 스타일입니다. |
### Example
@@ -109,18 +114,20 @@ const Parent = () => {
```
-## Checkbox
+
+
+## **Checkbox**
체크박스 컴포넌트입니다.
### Props
-| props | value | description |
-| --------- | --------------------------------------------------- | ---------------------------------------- |
-| size? | `xs`, `sm`, `md`, `lg`, `xl`
(default: `md`) | Checkbox 컴포넌트의 체크박스 크기입니다. |
-| fontSize? | `xs`, `sm`, `md`, `lg`, `xl`
(default: `md`) | Checkbox 컴포넌트의 폰트 크기입니다. |
-| weight? | `light`, `regular`, `bold`
(default: `bold`) | Checkbox 컴포넌트의 폰트 가중치입니다. |
-| tabIndex? | `-1`, `0`, `1`
| Checkbox 컴포넌트의 tabIndex입니다. |
+| props | value | description |
+| --------- | ------------------------------------------ | ---------------------------------------- |
+| size? | xs, sm, md, lg, xl
(default: md) | Checkbox 컴포넌트의 체크박스 크기입니다. |
+| fontSize? | xs, sm, md, lg, xl
(default: md) | Checkbox 컴포넌트의 폰트 크기입니다. |
+| weight? | light, regular, bold
(default: bold) | Checkbox 컴포넌트의 폰트 가중치입니다. |
+| tabIndex? | -1, 0, 1 | Checkbox 컴포넌트의 tabIndex입니다. |
### Example
@@ -130,40 +137,43 @@ const Parent = () => {
재구매 의사가 있으신가요?
```
+
+
## Divider
화면 구역을 나누는 선 컴포넌트입니다.
### Props
-| props | value | description |
-| ------------- | ----------------------------------------------------- | ----------------------------------------------------------- |
-| variant? | default , strong , disabled
(default: default) | Divider 컴포넌트의 종류입니다. 강조의 정도 차이가 있습니다. |
-| customWidth? | string
(default: 100%) | Divider 컴포넌트의 길이입니다. |
-| customHeight? | string
(default: 1px) | Divider 컴포넌트의 두께입니다. |
-| css? | CSSProp | Divider 컴포넌트에 적용할 CSS 스타일입니다. |
+| props | value | description |
+| ------------- | ---------------------------------------------------- | ----------------------------------------------------------- |
+| variant? | default , strong , disabled
(default: default) | Divider 컴포넌트의 종류입니다. 강조의 정도 차이가 있습니다. |
+| customWidth? | string
(default: 100%) | Divider 컴포넌트의 길이입니다. |
+| customHeight? | string
(default: 1px) | Divider 컴포넌트의 두께입니다. |
+| css? | CSSProp | Divider 컴포넌트에 적용할 CSS 스타일입니다. |
### Example
```jsx
-
+
```
+
+
## Heading
HTML heading 태그를 사용하는 컴포넌트입니다.
### Props
-| props | value | description |
-| --------- | ------------------------------------- | ------------------------------------------- |
-| children? | ReactNode | Heading 컴포넌트의 자식 컴포넌트입니다. |
-| size? | `xs`, `sm`, `md`, `lg`, `xl` | Heading 컴포넌트의 폰트 크기입니다. |
-| weight? | `light`, `regular`, `bold` | Heading 컴포넌트의 폰트 가중치입니다. |
-| css? | CSSProp | Heading 컴포넌트에 적용할 CSS 스타일입니다. |
-| as? | `h1` ,`h2`, `h3`
(default: `h1`) | Heading 컴포넌트의 HTML 태그입니다. |
-| css? | CSSProp | Heading 컴포넌트에 적용할 CSS 스타일입니다. |
+| props | value | description |
+| --------- | ----------------------------- | ------------------------------------------- |
+| children? | ReactNode | Heading 컴포넌트의 자식 컴포넌트입니다. |
+| as? | h1 ,h2, h3
(default: h1) | Heading 컴포넌트의 HTML 태그입니다. |
+| size? | xs, sm, md, lg, xl | Heading 컴포넌트의 폰트 크기입니다. |
+| weight? | light, regular, bold | Heading 컴포넌트의 폰트 가중치입니다. |
+| css? | CSSProp | Heading 컴포넌트에 적용할 CSS 스타일입니다. |
### Example
@@ -174,20 +184,53 @@ HTML heading 태그를 사용하는 컴포넌트입니다.
로망오우타해황
```
+
+
+## Input
+
+인풋 컴포넌트입니다.
+
+### Props
+
+| props | value | description |
+| ------------- | --------- | --------------------------------------------- |
+| customWidth? | string | Input 컴포넌트의 너비값입니다. |
+| minWidth? | string | Input 컴포넌트의 최소 너비값입니다. |
+| isError? | boolean | Input value에 에러가 있는지 여부입니다. |
+| rightIcon? | ReactNode | Input 컴포넌트 오른쪽에 위치할 아이콘입니다. |
+| errorMessage? | string | isError가 true일 때 보여줄 에러 메시지입니다. |
+
+### Example
+
+```jsx
+
+
+
+
+ }
+/>
+```
+
+
+
## Link
-다른 URL로 연결하는 컴포넌트입니다.
-`react-router-dom`과 함께 사용할 수 있습니다.
+다른 URL로 연결하는 컴포넌트입니다. `react-router-dom`과 함께 사용할 수 있습니다.
### Props
-| props | value | description |
-| ----------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
-| isExternal? | boolean
(default: false) | Link 컴포넌트의 링크 클릭 시 새로운 탭으로 열도록 선택할 수 있습니다. |
-| block | boolean
(default: false) | Link 컴포넌트의 디스플레이 속성이 block인지 선택할 수 있습니다. |
-| css? | CSSProp | Link 컴포넌트에 적용할 CSS 스타일입니다. |
-| as? | `a` ,`Link(react-router-dom의 Link)`, `NavLink(react-router-dom의 NavLink)`
(default: `a`) | Link 컴포넌트로 사용할 HTML 태그 또는 외부 링크 컴포넌트입니다. |
-| css? | CSSProp | Link 컴포넌트에 적용할 CSS 스타일입니다. |
+| props | value | description |
+| ----------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
+| as? | a, Link(react-router-dom의 Link), NavLink(react-router-dom의 NavLink)
(default: a) | Link 컴포넌트로 사용할 HTML 태그 또는 외부 링크 컴포넌트입니다. |
+| isExternal? | boolean
(default: false) | Link 컴포넌트의 링크 클릭 시 새로운 탭으로 열도록 선택할 수 있습니다. |
+| block | boolean
(default: false) | Link 컴포넌트의 디스플레이 속성이 block인지 선택할 수 있습니다. |
+| css? | CSSProp | Link 컴포넌트에 적용할 CSS 스타일입니다. |
### Example
@@ -203,16 +246,18 @@ import {Link as RouterLink, NavLink} from 'react-router-dom'
링크로 이동합니다.
```
+
+
## Spacing
화면 구역을 나누는 여백 컴포넌트입니다.
### Props
-| props | value | description |
-| ---------- | ---------------------------------------------------- | ------------------------------ |
-| direction? | `vertical`, `horizontal`
(default: `vertical`) | Spacing 컴포넌트의 방향입니다. |
-| size | number | Spacing 컴포넌트의 크기입니다. |
+| props | value | description |
+| ---------- | ---------------------------------------------- | ------------------------------ |
+| direction? | vertical, horizontal
(default: vertical) | Spacing 컴포넌트의 방향입니다. |
+| size | number | Spacing 컴포넌트의 크기입니다. |
### Example
@@ -221,22 +266,24 @@ import {Link as RouterLink, NavLink} from 'react-router-dom'
```
+
+
## Text
텍스트 컴포넌트입니다.
### Props
-| props | value | description |
-| ----------- | -------------------------------------------------- | ---------------------------------------- |
-| children? | ReactNode | Text 컴포넌트의 자식 컴포넌트입니다. |
-| size? | `xs`, `sm`, `md`, `lg`, `xl`
(default: `md`) | Text 컴포넌트의 폰트 크기입니다. |
-| weight? | `light`, `regular`, `bold`
(default: regular) | Text 컴포넌트의 폰트 가중치입니다. |
-| lineHeight? | `xs`,`sm`, `md`, `xl`
(default: `md`) | Text 컴포넌트의 텍스트 높이입니다. |
-| color? | CSSProperties['color']
(default: ‘#232527’) | Text 컴포넌트의 텍스트 색상입니다. |
-| align? | `left`, `center`, `right`
(default: `left`) | Text 컴포넌트의 텍스트 정렬입니다. |
-| css? | CSSProp | Text 컴포넌트에 적용할 CSS 스타일입니다. |
-| as? | `p` ,`span`
(default: `p`) | Text 컴포넌트의 HTML 태그입니다. |
+| props | value | description |
+| ----------- | ------------------------------------------------- | ---------------------------------------- |
+| children? | ReactNode | Text 컴포넌트의 자식 컴포넌트입니다. |
+| as? | p, span
(default: p) | Text 컴포넌트의 HTML 태그입니다. |
+| size? | xs, sm, md, lg, xl
(default: md) | Text 컴포넌트의 폰트 크기입니다. |
+| weight? | light, regular, bold
(default: regular) | Text 컴포넌트의 폰트 가중치입니다. |
+| lineHeight? | xs, sm, md, lg, xl
(default: md) | Text 컴포넌트의 텍스트 높이입니다. |
+| color? | CSSProperties['color']
(default: ‘#232527’) | Text 컴포넌트의 텍스트 색상입니다. |
+| align? | left, center, right
(default: left) | Text 컴포넌트의 텍스트 정렬입니다. |
+| css? | CSSProp | Text 컴포넌트에 적용할 CSS 스타일입니다. |
### Example
@@ -247,15 +294,17 @@ import {Link as RouterLink, NavLink} from 'react-router-dom'
로망오우타해황
```
+
+
## Textarea
멀티라인 텍스트 입력 컴포넌트입니다.
### Props
-| props | value | description |
-| ------- | ----------------------------------------------------------------- | ------------------------------------------------ |
-| resize? | `both`, `horizontal`, `vertical`, `none`
(default: `both`) | Textarea 컴포넌트의 크기 재조정 방향 설정입니다. |
+| props | value | description |
+| ------- | ------------------------------------------------------ | ------------------------------------------------ |
+| resize? | both, horizontal, vertical, none
(default: both) | Textarea 컴포넌트의 크기 재조정 방향 설정입니다. |
### Example
diff --git a/src/Input/Input.stories.tsx b/src/Input/Input.stories.tsx
new file mode 100644
index 0000000..eca0da5
--- /dev/null
+++ b/src/Input/Input.stories.tsx
@@ -0,0 +1,49 @@
+import type { Meta, StoryObj } from '@storybook/react';
+
+import Input from './Input';
+
+const meta: Meta = {
+ title: 'Input',
+ component: Input,
+ argTypes: {
+ rightIcon: {
+ control: { type: 'boolean' },
+ mapping: { false: '', true: '🔎' },
+ },
+ },
+ args: {
+ customWidth: '300px',
+ isError: false,
+ rightIcon: false,
+ errorMessage: '',
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const WithPlaceholder: Story = {
+ args: {
+ placeholder: '상품 이름을 검색하세요.',
+ },
+};
+
+export const WithIcon: Story = {
+ args: {
+ placeholder: '상품 이름을 검색하세요.',
+ rightIcon: true,
+ },
+};
+
+export const Error: Story = {
+ args: {
+ isError: true,
+ errorMessage: '10글자 이내로 입력해주세요.',
+ },
+};
+
+export const Disabled: Story = {
+ render: () => ,
+};
diff --git a/src/Input/Input.tsx b/src/Input/Input.tsx
new file mode 100644
index 0000000..0d361a2
--- /dev/null
+++ b/src/Input/Input.tsx
@@ -0,0 +1,98 @@
+import type { ComponentPropsWithRef, ForwardedRef, ReactNode } from 'react';
+import { forwardRef } from 'react';
+import styled from 'styled-components';
+
+import Text from '../Text';
+
+export interface InputProps extends ComponentPropsWithRef<'input'> {
+ /**
+ * Input 컴포넌트의 너비값입니다.
+ */
+ customWidth?: string;
+ /**
+ * Input 컴포넌트의 최소 너비값입니다.
+ */
+ minWidth?: string;
+ /**
+ * Input value에 에러가 있는지 여부입니다.
+ */
+ isError?: boolean;
+ /**
+ * Input 컴포넌트 오른쪽에 위치할 아이콘입니다.
+ */
+ rightIcon?: ReactNode;
+ /**
+ * isError가 true일 때 보여줄 에러 메시지입니다.
+ */
+ errorMessage?: string;
+}
+
+const Input = forwardRef(
+ (
+ { customWidth = '300px', minWidth, isError = false, rightIcon, errorMessage, ...props }: InputProps,
+ ref: ForwardedRef
+ ) => {
+ return (
+ <>
+
+
+ {rightIcon && {rightIcon}}
+
+ {isError && {errorMessage}}
+ >
+ );
+ }
+);
+
+Input.displayName = 'Input';
+
+export default Input;
+
+type InputContainerStyleProps = Pick;
+type CustomInputStyleProps = Pick;
+
+const InputContainer = styled.div`
+ position: relative;
+ min-width: ${({ minWidth }) => minWidth ?? 0};
+ max-width: ${({ customWidth }) => customWidth};
+ text-align: center;
+`;
+
+const CustomInput = styled.input`
+ width: 100%;
+ height: 40px;
+ padding: 10px 0 10px 12px;
+ color: ${({ isError, theme }) => (isError ? theme.colors.error : theme.textColors.default)};
+ border: 1px solid ${({ isError, theme }) => (isError ? theme.colors.error : theme.borderColors.default)};
+ border-radius: 5px;
+
+ &:focus {
+ border: 2px solid ${({ isError, theme }) => (isError ? theme.colors.error : theme.borderColors.strong)};
+ outline: none;
+ }
+
+ &:disabled {
+ border: 1px solid ${({ theme }) => theme.borderColors.disabled};
+ background: ${({ theme }) => theme.colors.gray1};
+ }
+
+ &::placeholder {
+ color: ${({ theme }) => theme.textColors.disabled};
+ font-size: ${({ theme }) => theme.fontSizes.sm};
+ }
+`;
+
+const IconWrapper = styled.div`
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ margin-right: 8px;
+`;
+
+const ErrorMessage = styled(Text)`
+ color: ${({ theme }) => theme.colors.error};
+ font-size: ${({ theme }) => theme.fontSizes.xs};
+`;
diff --git a/src/Input/index.ts b/src/Input/index.ts
new file mode 100644
index 0000000..c90e5ad
--- /dev/null
+++ b/src/Input/index.ts
@@ -0,0 +1,5 @@
+import Input from './Input';
+
+export type { InputProps } from './Input';
+
+export default Input;
diff --git a/src/index.ts b/src/index.ts
index c847503..cac763d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -14,3 +14,4 @@ export { default as Link } from './Link';
export { default as Spacing } from './Spacing';
export { default as Text } from './Text';
export { default as Textarea } from './Textarea';
+export { default as Input } from './Input';