Skip to content

Commit

Permalink
wip: textarea 개선 작업 중
Browse files Browse the repository at this point in the history
  • Loading branch information
gxxrxn committed Apr 15, 2024
1 parent be1238a commit 30e2ec0
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 12 deletions.
60 changes: 55 additions & 5 deletions src/stories/base/Textarea.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,65 @@
import { Meta, StoryObj } from '@storybook/react';
import Textarea from '@/v1/base/Textarea';
import { SubmitHandler, useForm } from 'react-hook-form';
import CountTextarea, { Textarea } from '@/v1/base/Textarea';
import Button from '@/v1/base/Button';

const meta: Meta<typeof Textarea> = {
title: 'Base/Textarea',
component: Textarea,
const meta: Meta<typeof CountTextarea> = {
title: 'Base/CountTextarea',
component: CountTextarea,
};

export default meta;

type Story = StoryObj<typeof Textarea>;
type Story = StoryObj<typeof CountTextarea>;

export const Default: Story = {
args: { placeholder: '어떤 이야기를 모임에서 나누면 좋을까요?' },
};

export const OnlyTextarea: Story = {
render: () => <Textarea />,
};

type FormValue = {
content: string;
};

const TextareaWithForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormValue>({ mode: 'all' });

const handleTextareaSubmit: SubmitHandler<FormValue> = value => {
alert(value.content);
};

return (
<form onSubmit={handleSubmit(handleTextareaSubmit)}>
<CountTextarea
error={!!errors.content}
errorMessage={errors.content?.message}
{...register('content', {
maxLength: { value: 3, message: '최대 3자' },
})}
/>

{/* <Textarea
{...register('content', {
maxLength: { value: 3, message: '300자 최대' },
})}
>
<Textarea.Error />
</Textarea> */}

<Button type="submit" size="full">
submit
</Button>
</form>
);
};

export const UseWithForm: Story = {
render: () => <TextareaWithForm />,
};
74 changes: 67 additions & 7 deletions src/v1/base/Textarea.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,75 @@
import { ForwardedRef, forwardRef, TextareaHTMLAttributes } from 'react';
import {
ChangeEventHandler,
ForwardedRef,
forwardRef,
TextareaHTMLAttributes,
useCallback,
useState,
} from 'react';
import ErrorMessage from './ErrorMessage';
import InputLength from './InputLength';

interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
isError?: boolean;
isCount?: boolean;
error?: boolean;
errorMessage?: string;
// count?: boolean;
}

const Textarea = (
{ placeholder, isError, ...props }: TextareaProps,
const CountTextArea = (
{
error = false,
onChange,
maxLength = 500,
errorMessage,
...props
}: TextareaProps,
ref: ForwardedRef<HTMLTextAreaElement>
) => {
const borderColor = isError
const [value, setValue] = useState('');

const handleChange: ChangeEventHandler<HTMLTextAreaElement> = useCallback(
e => {
setValue(e.target.value);
onChange?.(e);
},
[setValue, onChange]
);

return (
<div>
<Textarea
onChange={handleChange}
maxLength={maxLength}
error={error}
ref={ref}
{...props}
/>
<div className="flex flex-row-reverse justify-between gap-[0.4rem]">
<InputLength
currentLength={value.length}
isError={error}
maxLength={10}
/>
{error && <ErrorMessage>{errorMessage}</ErrorMessage>}
</div>
{/* <p>
{value.length} / {maxLength}
</p> */}
</div>
);
};

export default forwardRef(CountTextArea);

interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
error?: boolean;
}

const _Textarea = (
{ placeholder, error, ...props }: TextareaProps,
ref: ForwardedRef<HTMLTextAreaElement>
) => {
const borderColor = error
? 'border-warning-800 focus:border-warning-800'
: 'border-black-400 focus:border-main-900';

Expand All @@ -23,4 +83,4 @@ const Textarea = (
);
};

export default forwardRef(Textarea);
export const Textarea = forwardRef(_Textarea);

0 comments on commit 30e2ec0

Please sign in to comment.