Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 스터디 생성 페이지 재작성, 구조 재정의 #154

Merged
merged 115 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 109 commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
95c39e3
feat: 스터디 생성 페이지 재작성, 구조 재정의
abiriadev Apr 11, 2024
1926dfd
feat: 스터디 생성 폼을 위한 범용 SelectBox 컴포넌트 추가
abiriadev Apr 11, 2024
5af9ab4
fix: SelectBox가 `label`, `values` prop을 가지지 않더라도 에러가 나지 않도록 허용
abiriadev Apr 11, 2024
92e8db3
fix: 스터디 생성 타입 정의 및 RHF 바인딩
abiriadev Apr 11, 2024
b17110b
fix: select 필드 빠진 스타일 적용
abiriadev Apr 11, 2024
11a17d7
feat: <form> 요소 스타일 추가, 하위 섹션 요소 컴포넌트로 분리
abiriadev Apr 11, 2024
d59fb3d
fix: SelectBox의 label 방향을 세로로 교정
abiriadev Apr 11, 2024
cce8acb
feat: SelectBox의 기본값 추가
abiriadev Apr 11, 2024
28e2fc0
feat: 기본값 추가
abiriadev Apr 11, 2024
d9cddbc
feat: 구분선 추가 및 스타일 반영
abiriadev Apr 11, 2024
384255e
Merge branch 'dev' into feat/create-study
abiriadev Apr 15, 2024
581a205
feat: 스터디 생성을 위한 API 정의
abiriadev Apr 15, 2024
a0493dd
feat: 카테고리 생성시 사용할 타입 정의 추가
abiriadev Apr 15, 2024
7207c68
feat: 새로 정의한 스터디 생성용 타입을 인자로 허용
abiriadev Apr 15, 2024
65d6789
fix: 스터디 생성 페이지로의 라우터 다시 복구
abiriadev Apr 15, 2024
9c3bbf5
fix: 수정된 Pretendard600 폰트 사용 및 스타일 수정
abiriadev Apr 15, 2024
0b451ef
fix: 오타 수정
abiriadev Apr 15, 2024
5de8921
feat: 수정 가능한 드롭다운 아이콘 허용
abiriadev Apr 15, 2024
081d495
style: 셀렉트 박스 기본 화살표 스타일 제거
hyosin-Jang Apr 10, 2024
6872bd3
feat: Heading 컴포넌트 추가 (WIP)
hyosin-Jang Apr 10, 2024
6e5586b
feat: Stack 컴포넌트 정의
abiriadev Apr 15, 2024
c592cb1
refactor: 사전 등록된 버튼 컴포넌트 사용
abiriadev Apr 15, 2024
bb873b9
refactor: 패딩을 `<PageWrapper />` 컴포넌트로 대체
abiriadev Apr 15, 2024
860ec46
feat: 디자인 시스템에서 미구현된 `<BoldDivider />` 구현
abiriadev Apr 15, 2024
e189cd6
feat: shared에서 정의된 선택지 적용
abiriadev Apr 15, 2024
f52d3b7
fix: 중복된 '카테고리'를 온/오프라인으로 정정
abiriadev Apr 15, 2024
5604948
fix: placeholder 색 수정
abiriadev Apr 16, 2024
b33dee5
feat: <Stack> 컴포넌트가 구분자를 받을 수 있도록 정의
abiriadev Apr 16, 2024
61d1117
refactor: <Stack> 컴포넌트가 자식을 받지 않아도 되도록 허용
abiriadev Apr 16, 2024
a0440ce
refactor: <Stack> 컴포넌트로 반복 제거
abiriadev Apr 16, 2024
8bc1f59
feat: gap 속성 허용
abiriadev Apr 16, 2024
3839e56
fix: gap 단위를 px로 지정, flex 방향을 세로로 변경
abiriadev Apr 16, 2024
75c1754
fix: 숫자를 자동으로 px로 변환하도록 수정
abiriadev Apr 16, 2024
994650a
fix: 입력 양식 내부 gap과 버튼과의 gap을 분리
abiriadev Apr 16, 2024
bbc3ccc
refactor: <Heading> 컴포넌트 재사용
abiriadev Apr 16, 2024
e6b8388
refactor: <SelectBox />에서 label 분리
abiriadev Apr 16, 2024
936f3e4
feat: `<Labeled>` 컴포넌트 정의
abiriadev Apr 16, 2024
6b519ff
refactor: <Labeled> 적용
abiriadev Apr 16, 2024
86dc326
fix: 빠진 에러 메세지 색상 추가
abiriadev Apr 16, 2024
ad6ed4a
chore: 스터디 최대 인원 최대 10명 제한 (WIP)
abiriadev Apr 16, 2024
901b277
fix: 선택을 해도 색상이 placeholder와 달라지지 않는 이슈 해결
abiriadev Apr 16, 2024
891ab04
feat: error prop으로 에러 메세지 삽입 허용
abiriadev Apr 16, 2024
6b8cef3
fix: RHF에서 검증을 진행하기 위해 required 삭제
abiriadev Apr 16, 2024
aafd878
feat: `<Labeled />`별 검증 로직 추가 및 에러 메세지 삽입
abiriadev Apr 16, 2024
92d4341
chore: 에러 문구 수정
abiriadev Apr 16, 2024
f35892e
fix: 에러 메세지 원인을 필드별로 분리
abiriadev Apr 16, 2024
1d8bf82
chpre: 제목 필드에 대한 에러 메세지와 placeholder 메세지 추가
abiriadev Apr 16, 2024
ed522d3
refactor: `forwardRef` 타입 재정의
abiriadev Apr 16, 2024
7068388
fix: 카테고리 필드에 바인딩된 `title` 속성을 제목 필드로 이동
abiriadev Apr 16, 2024
47d7d39
refactor: `currentLength` prop을 외부 상태에서 수집
abiriadev Apr 16, 2024
fe1bd82
feat: `currentLength` 렌더링 로직 추가
abiriadev Apr 16, 2024
73fe2bd
refactor: `maxLength`를 prop으로 받을 수 있도록 개선
abiriadev Apr 16, 2024
13a56cd
feat: 생성 페이지에서 maxLength 넘겨주도록 수정
abiriadev Apr 16, 2024
0f4cb83
chore:
abiriadev Apr 17, 2024
c5c30f0
Merge branch 'dev' into feat/create-study
abiriadev Apr 24, 2024
505f156
Merge branch 'setup-storybook' into feat/create-study
abiriadev Apr 30, 2024
5a661aa
feat: Atomic한 타입만 따로 정의하기 위한 파일 생성
abiriadev Apr 30, 2024
c284dc2
feat: <DateRange /> 구현 완료
abiriadev Apr 30, 2024
43d2d3b
refactor: 콜백 함수 등을 `Partial<T>` 로 옵셔널화
abiriadev Apr 30, 2024
69cab71
docs: `<ProgressPeriod />` 컴포넌트를 위한 스토리 문서 추가
abiriadev Apr 30, 2024
14be7ba
perf: 팀원 배열을 매 렌더링시마다 반복하지 않도록 분리
abiriadev Apr 30, 2024
20eb437
fix: `iindex.ts` 파일 수정 반영
abiriadev Apr 30, 2024
d3a0778
feat: 요구사항에 맞게 타입 추가
abiriadev Apr 30, 2024
80085db
style: <CalendarButton> 스타일 수정
hyosin-Jang Apr 18, 2024
76b31dc
fix: 필드명 변경
abiriadev Apr 30, 2024
4f80308
feat: 스터디 진행 기간을 <ProgressPeriod /> 컴포넌트로 수정
abiriadev Apr 30, 2024
437cc4f
refactor: validation 메세지를 `register`함수 호출시 입력하도록 리팩토링
abiriadev Apr 30, 2024
146bae2
fix: `?.` 로 에러 메시지를 옵셔널로 전달
abiriadev Apr 30, 2024
2743ae6
feat: <CustomSelect> 멀티셀렉트 기능 추가
hyosin-Jang Apr 28, 2024
b8972ea
feat: react-select를 위한 카테고리 목록 정의
abiriadev Apr 30, 2024
f3c42a5
chore: RecruitFormSelect 타입 수정 반영
hyosin-Jang Apr 30, 2024
37216d5
feat: 라벨이 부착된 폼 UI <LabelForm> 컴포넌트로 분리
hyosin-Jang Apr 28, 2024
10387be
chore: RecruitFormSelect 타입 수정 반영
hyosin-Jang Apr 30, 2024
86560c1
style: theme color > input negative 색상 추가
hyosin-Jang Apr 10, 2024
a68f480
docs: nagative 색상 문서화
abiriadev Apr 30, 2024
8b3fe6f
refactor: LabelForm을 제네릭화
abiriadev Apr 30, 2024
ecae190
refactor: 카테고리 입력을 `LabelForm`, `CustomSelect`를 사용하도록 업데이트
abiriadev Apr 30, 2024
ef4d6ae
refactor: 스터디 최대 인원 수정
abiriadev Apr 30, 2024
2a0fbe9
feat: 프로젝트 진행 방식을 React-select에서 사용할 수 있도록 재정의
abiriadev Apr 30, 2024
b83ec1b
refactor: 스터디 진행 방식 폼 업데이트
abiriadev Apr 30, 2024
2dc60df
feat: react-select용 플랫폼 옵션 재정의
abiriadev Apr 30, 2024
f240d19
refactor: 플랫폼 선택 폼 업데이트
abiriadev Apr 30, 2024
315078c
chore: 문구 수정
abiriadev Apr 30, 2024
2d21a85
refactor: 진행기간 선택 폼에 `LabelFrom` 사용
abiriadev Apr 30, 2024
e50d1ed
fix: 모든 폼에 validation 추가 확인
abiriadev Apr 30, 2024
920090f
chore: <InputText> label props 추가
hyosin-Jang Apr 28, 2024
8331d60
style: <Heading>, <EndDate> 스타일 수정
hyosin-Jang Apr 18, 2024
3e6d635
feat: InputText 수정 반영
abiriadev Apr 30, 2024
544c12e
feat: 진행 플랫폼 필드 추가
abiriadev Apr 30, 2024
6968e8b
chore: 80% 오류 수정
abiriadev Apr 30, 2024
fd5e5d5
feat: Grid 컴포넌트 재사용 가능하게 분리
abiriadev Apr 30, 2024
c846cdc
feat: `<Grid />`로 길어진 폼 항목들을 wrapping
abiriadev Apr 30, 2024
db1be97
feat: react-select를 위한 포지션 데이터 재정의
abiriadev Apr 30, 2024
f0cf70b
feat: 포지션 입력 필드 추가
abiriadev Apr 30, 2024
2d70c38
chore: 등록 버튼 텍스트 수정
abiriadev Apr 30, 2024
0523265
refactor: `saveTemporary` 함수를 컴포넌트에서 분리
abiriadev Apr 24, 2024
08e0407
chore: RecruitFormSelect 타입 수정 반영
hyosin-Jang Apr 30, 2024
c507132
feat: 임시저장 목록에서 클릭된 카드 key 스토어에 저장
hyosin-Jang Apr 20, 2024
28b6cde
feat: 임시저장시 페이지 전환 기능 구현
abiriadev May 2, 2024
b6737a5
feat: react-select를 `yarn.lock`에 업데이트
abiriadev May 2, 2024
c75e71e
feat: 스터디 생성 `mutation` 정의
abiriadev May 2, 2024
7b89775
feat: `useMutation`으로 새 스터디 생성하기
abiriadev May 2, 2024
414060b
feat: 생성시 에러가 발생할 경우, `<ErrorBoundary />` 를 표시하기
abiriadev May 2, 2024
d44b15f
fix: 로케일 설정 경고 해결
abiriadev May 2, 2024
41cc043
test: 스터디 생성에 대한 Mock 추가
abiriadev May 2, 2024
46baa52
feat: 스터디 수정 API 정의
abiriadev May 2, 2024
3acd2e2
feat: 스터디 수정을 위한 mutation 훅 정의
abiriadev May 2, 2024
9591c14
feat: 스터디 수정 페이지 추가
abiriadev May 2, 2024
f3009a6
fix: 라우터 수정, 생성 및 수정 페이지의 export 수정
abiriadev May 2, 2024
5f5f1c1
refactor: 쿼리를 받을 수 있게 prop을 리팩토링
abiriadev May 2, 2024
2eaa479
feat: 스터디 수정 페이지에서 `defaultValue` 를 가져오게 구현
abiriadev May 2, 2024
e0a03cb
refactor: 중복된 기능을 하는 `<Labeled />`컴포넌트 제거
abiriadev May 7, 2024
fd295a8
Merge branch 'dev' into feat/create-study
abiriadev May 7, 2024
19b5d49
fix: `<Stack />` 컴포넌트 머지
abiriadev May 7, 2024
1a2da7f
tempfix: 스터디 아이디를 고정함으로써 `saveTemporary`호환 문제 해결
abiriadev May 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Apis/recruitment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const getPopularRecruitments = (count: number = 6): Promise<{ data: { dat
httpClient.get(API_END_POINT.POPULAR_RECRUITMENTS, { params: { count } });

export const getRecruitments = (
filterOptions: Pick<FilterOptionParams, 'categoryId' | 'positionId' | 'progressMethod' | 'stackId'>,
filterOptions: Pick<FilterOptionParams, 'categoryId' | 'positionId' | 'progressMethod' | 'stackIds'>,
count?: number,
last?: number,
): Promise<{ data: { data: Recruitments } }> => {
Expand Down
4 changes: 3 additions & 1 deletion src/Apis/study.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { httpClient } from '@/utils/axios';
import { API_END_POINT } from '@/Constants/api';
import { ApplicantsDetail, MyPageInfo, StudyDetail } from '@/Types/study';
import { ApplicantsDetail, MyPageInfo, StudyCreate, StudyDetail } from '@/Types/study';

export const getStudyDetail = (studyId: number): Promise<{ data: { data: StudyDetail } }> =>
httpClient.get(API_END_POINT.STUDY(studyId));
Expand All @@ -10,6 +10,8 @@ export const getMyPageInfo = (): Promise<{ data: { data: MyPageInfo } }> => http
export const getApplicantsDetail = (studyId: number): Promise<{ data: { data: ApplicantsDetail } }> =>
httpClient.get(API_END_POINT.APPLICANTS(studyId));

export const createStudy = async (data: StudyCreate) => httpClient.post(API_END_POINT.CREATE_STUDY, { ...data });

export const applyStudy = async (studyId: number, recruitmentId: number, data: { positionId: number }) =>
httpClient.post(API_END_POINT.APPLY(studyId, recruitmentId), { ...data });

Expand Down
14 changes: 14 additions & 0 deletions src/Assets/icons/study.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/Assets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export { default as Create } from './icons/createstudy.svg?react';
export { default as Loading } from './icons/lodaing.svg?react';
export { default as Logout } from './icons/logout.svg?react';
export { default as Article } from './icons/article.svg?react';
export { default as Study } from './icons/study.svg?react';

// Logo
export { default as BlankLogo } from './images/blank-logo.png';
Expand Down
18 changes: 18 additions & 0 deletions src/Components/Calendar/ProgressPeriod.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ProgressPeriod } from './ProgressPeriod';

const meta = {
component: ProgressPeriod,
parameters: {
docs: {
story: {
height: '300px',
},
},
},
} satisfies Meta<typeof ProgressPeriod>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {};
116 changes: 56 additions & 60 deletions src/Components/Calendar/ProgressPeriod.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,74 @@
// react-datepicker를 사용해서 진행기간 구현 328px, 24px, ex) 24.01.23 - 24.03.23
import DatePicker from 'react-datepicker';
import { useState } from 'react';
import 'react-datepicker/dist/react-datepicker.css';
import { forwardRef, useState } from 'react';
import styled from 'styled-components';
import { OptionalCreates } from '@/Pages/Studies/CreateStudy';
import { Creates } from '@/Types/studies';
import { DateRange } from '@/Types/atoms';
import { ControllerRenderProps } from 'react-hook-form';
import 'react-datepicker/dist/react-datepicker.css';

export type Props = {
onClick?: () => void;
children?: React.ReactNode;
// onChange?: (event: string) => void;
setForm: (any: OptionalCreates) => void;
useForm: Creates;
value?: string;
type?: string;
export interface ProgressPeriodProps {
/** input 요소가 가질 폼 필드 이름 속성 */
name?: string;
maxlength?: number;
id?: string;
formData?: number | string;
ref?: string;
};
}

interface IProgressPeriodForm {
progressPeriod: DateRange;
}

export const ProgressPeriod = ({ useForm }: Props) => {
const [startDateTime, setForms] = useState(new Date());
const [endDateTime, setFormss] = useState(new Date());
// const StartHandler = (event: ChangeEvent<HTMLSelectElement>) => {
// setForm({ startDateTime: event.target.value });
// };
/**
* 특정한 범위의 기간을 입력받는 데 사용되는 컴포넌트입니다.
*
* 사용처는 다음과 같습니다:
* - 스터디 기간 설정
* - 기간으로 스터디 조회 등
*/
export const ProgressPeriod = forwardRef<
DatePicker,
ProgressPeriodProps & Partial<ControllerRenderProps<IProgressPeriodForm, 'progressPeriod'>>
>(({ name, onChange, onBlur }, ref) => {
const now = new Date();

const [startDate, setStartDate] = useState(now);
const [endDate, setEndDate] = useState(null);

return (
<>
<DateContainer
selected={startDateTime}
value={(useForm.startDateTime = startDateTime.toISOString().slice(0, -5))}
name="startDateTime"
onChange={(date: Date) => setForms(date)}
// onChange={StartHandler}
selectsStart
startDate={startDateTime}
// endDate={endDateTime}
dateFormat="yyyy-MM-dd'T'HH:mm:ss"
/>
<Slash>-</Slash>
<DateContainer
selected={endDateTime}
value={(useForm.endDateTime = endDateTime.toISOString().slice(0, -5))}
name="endDateTime"
onChange={(date: any) => setFormss(date)}
selectsEnd
endDate={endDateTime}
minDate={startDateTime}
dateFormat="yyyy-MM-dd'T'HH:mm:ss"
/>
</>
<DateContainer
ref={ref}
name={name}
locale="ko"
// 기본값은 오늘부터 시작하는 것으로 가정
selected={startDate}
onBlur={onBlur}
onChange={([start, end]: [Date, Date]) => {
setStartDate(start);
setEndDate(end);
onChange([start, end]);
}}
// 시작일은 오늘 이후로 선택할 수 없다
minDate={now}
startDate={startDate}
endDate={endDate}
placeholderText="ex) 24.01.23 - 24.03.23"
// 범위 선택
selectsRange
shouldCloseOnSelect
showDisabledMonthNavigation
// 한국인에게 익숙한 날짜 순서
dateFormat="yy.MM.dd"
/>
);
};
});

// TODO: ./EndDate.tsx 랑 똑같은 Styled Component인데 한쪽으로 빼서 공용 컴포넌트로 사용하기
const DateContainer = styled(DatePicker)`
width: 145px;
width: 328px;
height: 24px;
background-color: ${(props) => props.theme.color.gray3};
align-items: center;
align-self: stretch;
border: 1px solid #cbcdd1;
border-width: 0;
background: ${(props) => props.theme.color.gray1};
resize: none;
flex: 1 0 0;
margin-top: 10px;
padding-bottom: 10px;
padding-right: 16px;
padding-left: 16px;
`;

const Slash = styled.p`
padding-right: 20px;
&::placeholder {
color: ${(props) => props.theme.color.black2};
}
`;
5 changes: 5 additions & 0 deletions src/Components/Colors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ import { color } from '@/Styles/theme';
'gray5': color.gray5,
}}
/>
<ColorItem
title="Negative"
subtitle="theme.color.negative"
colors={[color.negative]}
/>
<ColorItem
title="Naver"
subtitle="theme.color.naver"
Expand Down
7 changes: 7 additions & 0 deletions src/Components/Common/Divider/BoldDivider/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styled from 'styled-components';

export const BoldDivider = styled.div<{ rowHeight: number }>`
width: 100%;
height: ${(props) => `${props.rowHeight}px`};
background-color: ${(props) => props.theme.color.gray1};
`;
8 changes: 8 additions & 0 deletions src/Components/Common/Grid/index.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grid까지 Common 컴포넌트화 하셨네요!! 세심함에 감탄하고 갑니다👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원본은 클레어님이 제작하신 코드입니다...
잘 보시면 Co-Authored-By: hyosin Jang <[email protected]> 가 있습니다.

image

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import styled from 'styled-components';

export const Grid = styled.div`
display: grid;
grid-template-columns: repeat(3, minmax(392px, 1fr));
gap: 24px;
margin-top: 24px;
`;
7 changes: 7 additions & 0 deletions src/Components/Common/InputText/InputText.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,10 @@ export const Member: Story = {
placeholder: '멤버를 입력하세요',
},
};

export const Label: Story = {
args: {
label: '포지션',
placeholder: '포지션을 입력하세요',
},
};
68 changes: 61 additions & 7 deletions src/Components/Common/InputText/index.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,88 @@
import React, { ForwardedRef } from 'react';
import { ComponentProps, ForwardedRef, forwardRef, useState } from 'react';
import styled from 'styled-components';

interface InputTextProps extends React.InputHTMLAttributes<HTMLInputElement> {
placeholder?: string;
inputType?: 'text' | 'email' | 'password' | 'member';
defaultValue?: string;
currentLength?: number;
maxLength?: number;
label?: string;
}

const InputText = React.forwardRef(
({ placeholder, inputType, onChange, ...props }: InputTextProps, ref: ForwardedRef<HTMLInputElement>) => {
return <InputWrapper placeholder={placeholder} ref={ref} type={inputType} onChange={onChange} {...props} />;
const InputText = forwardRef<HTMLInputElement, ComponentProps<'input'> & InputTextProps>(
(
{ name, placeholder, defaultValue, inputType, onChange, maxLength, currentLength, label, ...props }: InputTextProps,
ref: ForwardedRef<HTMLInputElement>,
) => {
return (
<Box>
{label && <Label>{label}</Label>}
<InputWrapper
placeholder={placeholder}
defaultValue={defaultValue}
name={name}
ref={ref}
type={inputType ?? 'text'}
onChange={onChange}
autoComplete="off"
{...props}
/>
{maxLength && (
<LengthIndicator>
{currentLength} / {maxLength}
</LengthIndicator>
)}
</Box>
);
},
);

export const Label = styled.div`
font-size: 18px;
line-height: 24px;
color: #000000f2;
margin-bottom: 12px;
`;

const InputWrapper = styled.input`
width: 100%;
padding: 10px 16px;
border: 1px solid ${({ theme }) => theme.color.black1};
border-radius: ${({ theme }) => theme.borderRadius.small};
font-size: ${({ theme }) => theme.font.medium};
font-size: ${({ theme }) => theme.font.small};
line-height: 1.5;
color: ${({ theme }) => theme.color.black};
text-overflow: ellipsis;
display: block;
white-space: nowrap;
overflow: hidden;

::placeholder {
&::placeholder {
color: ${({ theme }) => theme.color.black2};
font-family: 'Pretendard400';
font-size: ${({ theme }) => theme.font.medium};
font-size: ${({ theme }) => theme.font.small};
font-style: normal;
font-weight: 400;
line-height: 28px;
}
`;

const Box = styled.div`
position: relative;
display: flex;
flex-direction: column;
`;

const LengthIndicator = styled.div`
position: absolute;
bottom: 13px;
right: 16px;
color: #00000073;
font-family: Pretendard400;
font-weight: 400;
font-size: 14px;
line-height: 20px;
`;

export default InputText;
26 changes: 26 additions & 0 deletions src/Components/Common/LabelForm/LabelForm.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Meta, StoryObj } from '@storybook/react';
import React from 'react';
import { LabelForm } from '.';

const meta = {
component: LabelForm,
args: {
label: '포지션',
children: React.createElement('input', { placeholder: 'input' }, null),
},
} satisfies Meta<typeof LabelForm>;

export default meta;
type Story = StoryObj<typeof meta>;

/** 유효하지 않을 경우, 에러메시지를 표시합니다. */
export const Errors: Story = {
args: {
errors: {
positionIds: {
message: '포지션을 선택해주세요.',
},
},
name: 'positionIds',
},
};
Loading