From a756a3604048162f7a215a98ee0de4dbadfd5fbc Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Fri, 19 Apr 2024 03:23:51 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Textarea=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=B0=8F=20=EC=8A=A4=ED=86=A0=EB=A6=AC=EB=B6=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Textarea/Textarea.tsx | 30 +++++++++++++ src/stories/Textarea.stories.tsx | 67 ++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/components/Textarea/Textarea.tsx create mode 100644 src/stories/Textarea.stories.tsx diff --git a/src/components/Textarea/Textarea.tsx b/src/components/Textarea/Textarea.tsx new file mode 100644 index 0000000..4b43fb4 --- /dev/null +++ b/src/components/Textarea/Textarea.tsx @@ -0,0 +1,30 @@ +import styled from '@emotion/styled'; +import { HTMLAttributes } from 'react'; + +import { convertCSS } from '../../utils/convertCSS'; + +interface Props extends HTMLAttributes { + width?: string | number; + height?: string | number; + padding?: string; +} + +const TextArea = styled.textarea` + box-sizing: border-box; + width: ${({ width }) => (width && convertCSS(width)) || '100%'}; + height: ${({ height }) => (height && convertCSS(height)) || '100px'}; + border-radius: 6px; + padding: ${({ padding }) => padding || '11px 16px'}; + font-size: ${({ theme }) => theme.font.suit14r.fontSize}px; + font-weight: ${({ theme }) => theme.font.suit14r.fontWeight}; + border: 1px solid ${({ theme }) => theme.color.l2}; + outline: none; + color: ${({ theme }) => theme.color.b4}; + background: ${({ theme }) => theme.color.w1}; + + &:focus { + border-color: ${({ theme }) => theme.color.c1}; + } +`; + +export default TextArea; diff --git a/src/stories/Textarea.stories.tsx b/src/stories/Textarea.stories.tsx new file mode 100644 index 0000000..8a2835e --- /dev/null +++ b/src/stories/Textarea.stories.tsx @@ -0,0 +1,67 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import Textarea from '../components/Textarea/Textarea'; +import { ChangeEvent, useEffect, useState } from 'react'; + +const meta = { + title: 'Components/Textarea', + component: Textarea, + tags: ['autodocs'], + argTypes: { + width: { + control: 'text', + description: 'Textarea 컴포넌트의 넓이를 지정합니다.', + }, + height: { + control: 'text', + description: 'Textarea 컴포넌트의 높이를 지정합니다.', + }, + padding: { + control: 'text', + description: 'Textarea 컴포넌트 padding을 설정합니다.', + }, + value: { + control: 'text', + description: 'Textarea 컴포넌트의 텍스트를 나타내는 값입니다.', + }, + onChange: { + control: false, + description: + 'Textarea 컴포넌트의 value를 변경할 수 있는 onChange 함수입니다.', + }, + }, +} as Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + width: '100%', + height: '100px', + padding: '11px 16px', + value: 'textarea', + }, + render: ({ value, width, height, padding }) => { + const userInput = value as string; + const [textarea, setTextarea] = useState(userInput); + + useEffect(() => { + setTextarea(userInput); + }, [userInput]); + + return ( + <> +